From ef88c53f60e30247566e7c3a11c32a1db0697fa7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=BB=84=E6=B6=9B?= Date: Fri, 8 Nov 2013 21:34:05 +0800 Subject: [PATCH] rk: revert 20f3d0b+v3.0.66 to v3.0 --- Documentation/HOWTO | 34 +- Documentation/android.txt | 121 - Documentation/cgroups/cgroups.txt | 9 - Documentation/cgroups/cpuacct.txt | 7 - Documentation/cpu-freq/governors.txt | 75 - Documentation/development-process/5.Posting | 8 +- Documentation/dvb/get_dvb_firmware | 2 +- Documentation/feature-removal-schedule.txt | 8 + Documentation/hid/uhid.txt | 169 - Documentation/hwmon/jc42 | 26 +- Documentation/hwspinlock.txt | 18 +- Documentation/kernel-parameters.txt | 5 - Documentation/networking/ifenslave.c | 2 - Documentation/networking/ip-sysctl.txt | 9 +- Documentation/power/runtime_pm.txt | 11 - Documentation/stable_kernel_rules.txt | 31 +- .../postprocess/trace-vmscan-postprocess.pl | 8 +- Documentation/usb/usbmon.txt | 14 +- Documentation/virtual/lguest/lguest.c | 3 - MAINTAINERS | 31 +- Makefile | 2 +- arch/alpha/include/asm/atomic.h | 4 +- arch/alpha/include/asm/futex.h | 2 +- arch/alpha/include/asm/socket.h | 2 - arch/alpha/kernel/time.c | 2 +- arch/arm/Kconfig | 48 +- arch/arm/boot/compressed/head.S | 4 - arch/arm/common/Kconfig | 50 - arch/arm/common/Makefile | 2 - arch/arm/common/fiq_debugger.c | 1196 --- arch/arm/common/fiq_debugger_ringbuf.h | 94 - arch/arm/common/fiq_glue.S | 111 - arch/arm/common/fiq_glue_setup.c | 100 - arch/arm/configs/ezx_defconfig | 2 +- arch/arm/configs/imote2_defconfig | 2 +- arch/arm/configs/magician_defconfig | 2 +- arch/arm/configs/mxs_defconfig | 1 + arch/arm/configs/zeus_defconfig | 2 +- arch/arm/include/asm/assembler.h | 5 - arch/arm/include/asm/cacheflush.h | 10 +- arch/arm/include/asm/fiq_debugger.h | 64 - arch/arm/include/asm/fiq_glue.h | 30 - arch/arm/include/asm/futex.h | 34 +- arch/arm/include/asm/hardirq.h | 2 +- arch/arm/include/asm/hardware/cache-l2x0.h | 5 +- arch/arm/include/asm/hardware/coresight.h | 26 +- arch/arm/include/asm/hwcap.h | 3 +- arch/arm/include/asm/irq.h | 3 - arch/arm/include/asm/mach/mmc.h | 28 - arch/arm/include/asm/mutex.h | 119 +- arch/arm/include/asm/pgtable.h | 40 +- arch/arm/include/asm/smp.h | 2 - arch/arm/include/asm/tls.h | 4 - arch/arm/include/asm/vfpmacros.h | 12 +- arch/arm/kernel/entry-armv.S | 2 +- arch/arm/kernel/etm.c | 473 +- arch/arm/kernel/head.S | 2 +- arch/arm/kernel/leds.c | 27 +- arch/arm/kernel/perf_event_v7.c | 4 +- arch/arm/kernel/process.c | 132 +- arch/arm/kernel/ptrace.c | 8 +- arch/arm/kernel/signal.c | 5 +- arch/arm/kernel/smp.c | 109 +- arch/arm/kernel/smp_scu.c | 10 - arch/arm/kernel/swp_emulate.c | 2 - arch/arm/kernel/sys_arm.c | 2 +- arch/arm/kernel/traps.c | 4 +- arch/arm/mach-at91/at91rm9200_devices.c | 2 +- arch/arm/mach-at91/at91sam9260.c | 6 +- arch/arm/mach-at91/at91sam9260_devices.c | 2 +- arch/arm/mach-at91/at91sam9261_devices.c | 2 +- arch/arm/mach-at91/at91sam9263_devices.c | 2 +- arch/arm/mach-at91/at91sam9rl_devices.c | 2 +- arch/arm/mach-davinci/board-da850-evm.c | 30 +- arch/arm/mach-davinci/board-dm646x-evm.c | 6 +- arch/arm/mach-davinci/sleep.S | 6 +- arch/arm/mach-dove/common.c | 5 +- arch/arm/mach-dove/include/mach/pm.h | 2 +- arch/arm/mach-dove/irq.c | 14 +- arch/arm/mach-imx/mach-mx21ads.c | 2 +- arch/arm/mach-integrator/integrator_ap.c | 6 +- arch/arm/mach-kirkwood/common.c | 3 +- arch/arm/mach-kirkwood/mpp.h | 320 +- arch/arm/mach-lpc32xx/include/mach/irqs.h | 2 +- arch/arm/mach-lpc32xx/irq.c | 25 +- arch/arm/mach-lpc32xx/serial.c | 20 +- arch/arm/mach-mv78xx0/common.c | 3 +- arch/arm/mach-mv78xx0/mpp.h | 226 +- arch/arm/mach-mxs/clock-mx28.c | 2 +- arch/arm/mach-mxs/include/mach/mxs.h | 1 - arch/arm/mach-omap2/Kconfig | 1 - arch/arm/mach-omap2/board-4430sdp.c | 31 +- arch/arm/mach-omap2/board-omap4panda.c | 22 +- arch/arm/mach-omap2/board-rx51-peripherals.c | 2 +- arch/arm/mach-omap2/gpmc.c | 6 - arch/arm/mach-omap2/opp.c | 3 +- arch/arm/mach-omap2/smartreflex.c | 2 +- arch/arm/mach-orion5x/common.c | 4 +- arch/arm/mach-orion5x/mpp.h | 4 +- arch/arm/mach-pxa/balloon3.c | 2 +- arch/arm/mach-pxa/cm-x300.c | 8 +- arch/arm/mach-pxa/colibri-pxa320.c | 2 +- arch/arm/mach-pxa/gumstix.c | 2 +- arch/arm/mach-pxa/include/mach/palm27x.h | 4 +- arch/arm/mach-pxa/palm27x.c | 4 +- arch/arm/mach-pxa/palmtc.c | 2 +- arch/arm/mach-pxa/vpac270.c | 2 +- arch/arm/mach-ux500/Kconfig | 2 - arch/arm/mach-ux500/cpu.c | 25 +- arch/arm/mm/cache-l2x0.c | 66 +- arch/arm/mm/cache-v6.S | 17 - arch/arm/mm/cache-v7.S | 29 - arch/arm/mm/dma-mapping.c | 20 +- arch/arm/mm/fault.c | 4 +- arch/arm/mm/flush.c | 2 + arch/arm/mm/init.c | 7 - arch/arm/mm/mmu.c | 2 +- arch/arm/mm/proc-v7.S | 22 +- arch/arm/mm/tlb-v7.S | 12 - arch/arm/oprofile/common.c | 2 +- arch/arm/plat-mxc/include/mach/iomux-v3.h | 12 +- arch/arm/plat-mxc/pwm.c | 16 +- arch/arm/plat-orion/common.c | 9 +- arch/arm/plat-orion/include/plat/common.h | 3 +- arch/arm/plat-orion/mpp.c | 3 +- arch/arm/plat-s3c24xx/dma.c | 4 +- arch/arm/plat-samsung/adc.c | 8 +- arch/arm/vfp/entry.S | 3 +- arch/arm/vfp/vfphw.S | 20 +- arch/arm/vfp/vfpmodule.c | 51 +- arch/avr32/Kconfig | 1 - arch/cris/arch-v10/drivers/sync_serial.c | 6 +- arch/cris/arch-v10/kernel/irq.c | 3 - arch/cris/include/asm/io.h | 39 +- arch/cris/include/asm/thread_info.h | 6 +- arch/ia64/include/asm/atomic.h | 4 +- arch/ia64/include/asm/futex.h | 9 +- arch/ia64/include/asm/unistd.h | 3 +- arch/ia64/kernel/acpi.c | 10 +- arch/ia64/kernel/entry.S | 3 - arch/ia64/kernel/irq_ia64.c | 1 + arch/m68k/include/asm/entry_mm.h | 4 +- arch/m68k/include/asm/signal.h | 6 +- arch/m68k/kernel/sys_m68k.c | 8 +- arch/m68k/mac/config.c | 3 - arch/mips/Makefile | 2 +- arch/mips/include/asm/thread_info.h | 4 +- arch/mips/jz4740/gpio.c | 52 +- arch/mips/kernel/Makefile | 2 +- arch/mips/kernel/kgdb.c | 9 - arch/mips/kernel/vmlinux.lds.S | 3 +- arch/mn10300/Makefile | 2 +- arch/parisc/include/asm/atomic.h | 8 +- arch/parisc/include/asm/futex.h | 66 +- arch/parisc/include/asm/prefetch.h | 7 +- arch/parisc/include/asm/unistd.h | 3 +- arch/parisc/kernel/entry.S | 28 +- arch/parisc/kernel/pacache.S | 38 +- arch/parisc/kernel/signal32.c | 6 +- arch/parisc/kernel/sys_parisc.c | 2 - arch/parisc/kernel/syscall_table.S | 1 - arch/parisc/kernel/vmlinux.lds.S | 6 +- arch/powerpc/include/asm/cputime.h | 6 +- arch/powerpc/include/asm/reg.h | 3 +- arch/powerpc/include/asm/sections.h | 2 +- arch/powerpc/include/asm/sparsemem.h | 2 +- arch/powerpc/include/asm/synch.h | 1 - arch/powerpc/include/asm/time.h | 2 - arch/powerpc/kernel/asm-offsets.c | 1 - arch/powerpc/kernel/crash.c | 6 +- arch/powerpc/kernel/entry_64.S | 23 +- arch/powerpc/kernel/ftrace.c | 12 +- arch/powerpc/kernel/head_64.S | 2 +- arch/powerpc/kernel/irq.c | 15 +- arch/powerpc/kernel/kvm.c | 1 + arch/powerpc/kernel/module_32.c | 11 +- arch/powerpc/kernel/perf_event.c | 8 +- arch/powerpc/kernel/process.c | 12 +- arch/powerpc/kernel/prom_init.c | 6 +- arch/powerpc/kernel/ptrace.c | 18 +- arch/powerpc/kernel/setup_32.c | 2 - arch/powerpc/kernel/setup_64.c | 1 - arch/powerpc/kernel/sysfs.c | 10 - arch/powerpc/kernel/time.c | 26 +- arch/powerpc/kernel/traps.c | 3 +- arch/powerpc/kvm/44x_emulate.c | 2 - arch/powerpc/lib/feature-fixups.c | 23 - arch/powerpc/mm/gup.c | 12 + arch/powerpc/mm/hash_utils_64.c | 6 +- arch/powerpc/mm/hugetlbpage.c | 21 +- arch/powerpc/mm/mem.c | 3 +- arch/powerpc/mm/mmu_context_hash64.c | 12 +- arch/powerpc/mm/numa.c | 3 +- arch/powerpc/platforms/embedded6xx/wii.c | 6 +- arch/powerpc/platforms/powermac/smp.c | 2 +- arch/powerpc/platforms/ps3/interrupt.c | 23 +- arch/powerpc/platforms/ps3/platform.h | 1 - arch/powerpc/platforms/ps3/smp.c | 2 - arch/powerpc/platforms/pseries/dlpar.c | 4 - arch/powerpc/platforms/pseries/dtl.c | 2 +- arch/powerpc/platforms/pseries/eeh.c | 2 +- arch/powerpc/platforms/pseries/hvCall_inst.c | 4 +- arch/powerpc/platforms/pseries/hvconsole.c | 2 +- arch/powerpc/platforms/pseries/kexec.c | 11 - arch/powerpc/platforms/pseries/lpar.c | 4 +- .../platforms/pseries/plpar_wrappers.h | 4 +- arch/powerpc/sysdev/fsl_rio.c | 5 +- arch/powerpc/xmon/xmon.c | 2 +- arch/s390/Kconfig | 4 +- arch/s390/include/asm/compat.h | 7 + arch/s390/include/asm/pgalloc.h | 3 + arch/s390/include/asm/timex.h | 28 - arch/s390/include/asm/tlb.h | 22 +- arch/s390/kernel/compat_linux.c | 2 + arch/s390/kernel/process.c | 1 + arch/s390/kernel/ptrace.c | 50 +- arch/s390/kernel/setup.c | 1 - arch/s390/kernel/time.c | 2 +- arch/s390/kvm/interrupt.c | 2 +- arch/s390/kvm/kvm-s390.c | 14 +- arch/s390/mm/fault.c | 15 +- arch/s390/mm/gup.c | 16 +- arch/s390/mm/mmap.c | 2 +- arch/s390/mm/pgtable.c | 68 +- arch/s390/oprofile/init.c | 2 +- arch/score/kernel/entry.S | 2 +- arch/sh/include/asm/elf.h | 4 +- arch/sh/include/asm/page.h | 5 - arch/sh/oprofile/common.c | 4 +- arch/sparc/Kconfig | 4 - arch/sparc/Makefile | 2 +- arch/sparc/include/asm/bitops_64.h | 49 +- arch/sparc/include/asm/elf_64.h | 63 +- arch/sparc/include/asm/hugetlb.h | 10 +- arch/sparc/include/asm/hypervisor.h | 14 - arch/sparc/include/asm/pgtable_32.h | 20 +- arch/sparc/include/asm/pgtable_64.h | 20 +- arch/sparc/include/asm/sigcontext.h | 14 - arch/sparc/include/asm/spinlock_32.h | 11 +- arch/sparc/include/asm/spinlock_64.h | 6 + arch/sparc/include/asm/spitfire.h | 1 - arch/sparc/include/asm/tsb.h | 51 +- arch/sparc/include/asm/xor_64.h | 3 +- arch/sparc/kernel/Makefile | 1 - arch/sparc/kernel/central.c | 2 +- arch/sparc/kernel/cpu.c | 8 - arch/sparc/kernel/cpumap.c | 1 - arch/sparc/kernel/ds.c | 33 +- arch/sparc/kernel/entry.h | 21 - arch/sparc/kernel/head_64.S | 33 +- arch/sparc/kernel/hvapi.c | 7 - arch/sparc/kernel/hvcalls.S | 7 - arch/sparc/kernel/irq.h | 2 +- arch/sparc/kernel/kernel.h | 15 - arch/sparc/kernel/ktlb.S | 24 +- arch/sparc/kernel/mdesc.c | 30 +- arch/sparc/kernel/module.c | 27 - arch/sparc/kernel/pci_sun4v.c | 4 +- arch/sparc/kernel/pcic.c | 4 +- arch/sparc/kernel/pcr.c | 11 +- arch/sparc/kernel/perf_event.c | 18 +- arch/sparc/kernel/rtrap_64.S | 7 + arch/sparc/kernel/setup_64.c | 240 +- arch/sparc/kernel/signal32.c | 202 +- arch/sparc/kernel/signal_32.c | 202 +- arch/sparc/kernel/signal_64.c | 154 +- arch/sparc/kernel/sigutil.h | 9 - arch/sparc/kernel/sigutil_32.c | 120 - arch/sparc/kernel/sigutil_64.c | 93 - arch/sparc/kernel/sparc_ksyms_64.c | 11 - arch/sparc/kernel/sstate.c | 9 +- arch/sparc/kernel/sys_sparc_64.c | 10 +- arch/sparc/kernel/syscalls.S | 32 +- arch/sparc/kernel/systbls_64.S | 2 +- arch/sparc/kernel/unaligned_64.c | 15 +- arch/sparc/kernel/visemul.c | 32 +- arch/sparc/kernel/vmlinux.lds.S | 21 +- arch/sparc/lib/Makefile | 4 +- arch/sparc/lib/NG2page.S | 61 + arch/sparc/lib/NGpage.S | 114 +- arch/sparc/lib/ffs.S | 84 - arch/sparc/lib/hweight.S | 51 - arch/sparc/lib/memcpy.S | 804 +- arch/sparc/mm/Makefile | 1 + arch/sparc/mm/btfixup.c | 3 +- arch/sparc/mm/generic_32.c | 98 + arch/sparc/mm/generic_64.c | 164 + arch/sparc/mm/init_64.c | 75 +- arch/sparc/mm/ultra.S | 6 +- arch/tile/Kconfig | 1 - arch/tile/Makefile | 4 - arch/tile/include/asm/bitops.h | 12 +- arch/tile/kernel/compat_signal.c | 12 +- arch/um/drivers/ubd_kern.c | 31 +- arch/um/include/asm/pgtable.h | 10 +- arch/x86/Kconfig | 9 - arch/x86/crypto/aesni-intel_asm.S | 6 +- arch/x86/ia32/ia32entry.S | 4 +- arch/x86/include/asm/amd_nb.h | 2 - arch/x86/include/asm/apic.h | 2 +- arch/x86/include/asm/archrandom.h | 75 - arch/x86/include/asm/cpufeature.h | 2 +- arch/x86/include/asm/i387.h | 284 +- arch/x86/include/asm/idle.h | 7 + arch/x86/include/asm/kvm_emulate.h | 16 - arch/x86/include/asm/msr-index.h | 3 - arch/x86/include/asm/pgtable-3level.h | 50 - arch/x86/include/asm/pgtable.h | 16 +- arch/x86/include/asm/processor.h | 3 +- arch/x86/include/asm/ptrace.h | 15 +- arch/x86/include/asm/system.h | 7 + arch/x86/include/asm/thread_info.h | 2 + arch/x86/include/asm/timer.h | 19 +- arch/x86/include/asm/traps.h | 26 - arch/x86/include/asm/uv/uv_bau.h | 1 - arch/x86/include/asm/uv/uv_hub.h | 39 +- arch/x86/include/asm/xen/page.h | 4 +- arch/x86/kernel/acpi/boot.c | 27 +- arch/x86/kernel/alternative.c | 4 +- arch/x86/kernel/amd_iommu.c | 20 +- arch/x86/kernel/amd_iommu_init.c | 24 +- arch/x86/kernel/amd_nb.c | 39 +- arch/x86/kernel/apic/apic.c | 34 +- arch/x86/kernel/apic/bigsmp_32.c | 20 +- arch/x86/kernel/apic/probe_32.c | 10 +- arch/x86/kernel/apic/x2apic_uv_x.c | 15 +- arch/x86/kernel/cpu/Makefile | 1 - arch/x86/kernel/cpu/amd.c | 30 +- arch/x86/kernel/cpu/common.c | 7 +- arch/x86/kernel/cpu/intel.c | 20 +- arch/x86/kernel/cpu/intel_cacheinfo.c | 44 +- arch/x86/kernel/cpu/mcheck/mce-severity.c | 16 +- arch/x86/kernel/cpu/mcheck/mce.c | 11 +- arch/x86/kernel/cpu/mcheck/mce_amd.c | 60 +- arch/x86/kernel/cpu/mcheck/therm_throt.c | 29 +- arch/x86/kernel/cpu/mtrr/main.c | 23 - arch/x86/kernel/cpu/perf_event.c | 3 - arch/x86/kernel/cpu/perf_event_amd.c | 11 +- arch/x86/kernel/cpu/perf_event_intel.c | 1 - arch/x86/kernel/cpu/perf_event_intel_ds.c | 6 +- arch/x86/kernel/cpu/proc.c | 4 +- arch/x86/kernel/cpu/rdrand.c | 73 - arch/x86/kernel/cpu/scattered.c | 2 +- arch/x86/kernel/entry_32.S | 26 +- arch/x86/kernel/entry_64.S | 2 +- arch/x86/kernel/hpet.c | 25 +- arch/x86/kernel/kgdb.c | 60 - arch/x86/kernel/kprobes.c | 4 +- arch/x86/kernel/microcode_amd.c | 28 +- arch/x86/kernel/microcode_core.c | 31 +- arch/x86/kernel/mpparse.c | 2 +- arch/x86/kernel/msr.c | 3 - arch/x86/kernel/process.c | 24 + arch/x86/kernel/process_32.c | 27 +- arch/x86/kernel/process_64.c | 47 +- arch/x86/kernel/ptrace.c | 30 - arch/x86/kernel/reboot.c | 21 +- arch/x86/kernel/relocate_kernel_32.S | 2 - arch/x86/kernel/relocate_kernel_64.S | 2 - arch/x86/kernel/setup.c | 97 +- arch/x86/kernel/setup_percpu.c | 14 +- arch/x86/kernel/tls.c | 4 +- arch/x86/kernel/traps.c | 41 +- arch/x86/kernel/tsc.c | 13 +- arch/x86/kernel/vm86_32.c | 2 - arch/x86/kernel/xsave.c | 12 +- arch/x86/kvm/emulate.c | 51 - arch/x86/kvm/vmx.c | 2 +- arch/x86/kvm/x86.c | 23 - arch/x86/lib/delay.c | 4 +- arch/x86/mm/gup.c | 12 +- arch/x86/mm/highmem_32.c | 2 - arch/x86/mm/hugetlbpage.c | 21 +- arch/x86/mm/init.c | 72 +- arch/x86/mm/init_64.c | 3 - arch/x86/mm/mmap.c | 4 +- arch/x86/mm/srat.c | 4 - arch/x86/net/bpf_jit_comp.c | 50 +- arch/x86/oprofile/backtrace.c | 56 +- arch/x86/oprofile/init.c | 7 +- arch/x86/oprofile/nmi_int.c | 2 +- arch/x86/pci/Makefile | 3 +- arch/x86/pci/acpi.c | 39 +- arch/x86/pci/amd_bus.c | 42 +- arch/x86/pci/fixup.c | 17 - arch/x86/pci/xen.c | 2 +- arch/x86/platform/efi/efi_64.c | 22 +- arch/x86/platform/mrst/mrst.c | 24 +- arch/x86/platform/olpc/olpc.c | 4 +- arch/x86/platform/uv/tlb_uv.c | 30 +- arch/x86/vdso/vdso32/sysenter.S | 2 +- arch/x86/xen/Makefile | 2 +- arch/x86/xen/enlighten.c | 48 +- arch/x86/xen/mmu.c | 19 +- arch/x86/xen/p2m.c | 36 - arch/x86/xen/setup.c | 37 - arch/x86/xen/smp.c | 29 +- arch/x86/xen/vga.c | 67 - arch/x86/xen/xen-asm.S | 2 +- arch/x86/xen/xen-asm_32.S | 20 +- arch/x86/xen/xen-ops.h | 11 - arch/xtensa/kernel/ptrace.c | 3 - block/blk-cgroup.c | 37 +- block/blk-core.c | 30 +- block/blk-exec.c | 7 - block/blk-map.c | 7 +- block/blk-sysfs.c | 5 - block/bsg.c | 3 +- block/cfq-iosched.c | 16 +- block/genhd.c | 77 +- block/scsi_ioctl.c | 55 - crypto/cryptd.c | 13 +- crypto/ghash-generic.c | 6 - crypto/md5.c | 92 +- crypto/sha512_generic.c | 61 +- drivers/Kconfig | 2 - drivers/Makefile | 1 - drivers/acpi/ac.c | 4 +- drivers/acpi/acpi_pad.c | 7 +- drivers/acpi/acpica/acconfig.h | 2 +- drivers/acpi/acpica/aclocal.h | 1 - drivers/acpi/acpica/acobject.h | 1 - drivers/acpi/acpica/dsargs.c | 26 +- drivers/acpi/acpica/excreate.c | 6 - drivers/acpi/acpica/nspredef.c | 1 - drivers/acpi/acpica/nsrepair2.c | 15 - drivers/acpi/acpica/tbfadt.c | 8 +- drivers/acpi/acpica/tbxface.c | 1 - drivers/acpi/atomicio.c | 2 +- drivers/acpi/battery.c | 87 +- drivers/acpi/bus.c | 8 +- drivers/acpi/ec.c | 30 +- drivers/acpi/numa.c | 6 - drivers/acpi/pci_root.c | 7 - drivers/acpi/processor_core.c | 28 +- drivers/acpi/processor_driver.c | 1 - drivers/acpi/processor_idle.c | 3 - drivers/acpi/processor_thermal.c | 45 +- drivers/acpi/scan.c | 9 +- drivers/acpi/sleep.c | 24 - drivers/acpi/sysfs.c | 4 +- drivers/acpi/video.c | 19 +- drivers/ata/ahci.c | 23 - drivers/ata/ata_piix.c | 37 +- drivers/ata/libata-core.c | 2 - drivers/ata/libata-eh.c | 4 +- drivers/ata/libata-scsi.c | 6 +- drivers/ata/pata_legacy.c | 3 +- drivers/ata/pata_via.c | 18 - drivers/ata/sata_promise.c | 15 +- drivers/ata/sata_svw.c | 35 - drivers/atm/iphase.h | 146 +- drivers/atm/solos-pci.c | 9 +- drivers/base/Kconfig | 26 - drivers/base/Makefile | 3 - drivers/base/core.c | 5 - drivers/base/firmware_class.c | 25 +- drivers/base/memory.c | 58 +- drivers/base/node.c | 14 +- drivers/base/power/main.c | 46 - drivers/base/power/runtime.c | 32 +- drivers/base/sw_sync.c | 256 - drivers/base/sync.c | 801 -- drivers/bcma/main.c | 5 +- drivers/block/DAC960.c | 18 +- drivers/block/aoe/aoe.h | 2 +- drivers/block/aoe/aoeblk.c | 5 + drivers/block/aoe/aoecmd.c | 1 - drivers/block/cciss.c | 13 +- drivers/block/cciss.h | 2 +- drivers/block/cciss_scsi.c | 15 +- drivers/block/drbd/drbd_req.c | 1 - drivers/block/floppy.c | 45 +- drivers/block/loop.c | 6 +- drivers/block/sx8.c | 2 +- drivers/block/ub.c | 3 +- drivers/block/umem.c | 40 - drivers/block/virtio_blk.c | 4 +- drivers/block/xen-blkback/blkback.c | 2 +- drivers/block/xen-blkfront.c | 6 +- drivers/bluetooth/ath3k.c | 20 - drivers/bluetooth/btusb.c | 52 +- drivers/bluetooth/hci_ldisc.c | 4 +- drivers/cdrom/cdrom.c | 11 +- drivers/char/Kconfig | 17 - drivers/char/Makefile | 1 - drivers/char/agp/intel-agp.c | 1 - drivers/char/agp/intel-agp.h | 1 - drivers/char/dcc_tty.c | 326 - drivers/char/mem.c | 17 - drivers/char/mspec.c | 2 +- drivers/char/random.c | 708 +- drivers/char/tpm/tpm.c | 30 +- drivers/char/ttyprintk.c | 2 +- drivers/char/virtio_console.c | 3 +- drivers/cpufreq/Kconfig | 27 - drivers/cpufreq/Makefile | 1 - drivers/cpufreq/cpufreq_interactive.c | 1066 -- drivers/cpufreq/cpufreq_stats.c | 25 - drivers/cpufreq/pcc-cpufreq.c | 3 - drivers/cpufreq/powernow-k8.c | 86 +- drivers/cpuidle/governors/menu.c | 7 +- drivers/crypto/Kconfig | 1 - drivers/crypto/mv_cesa.c | 13 +- drivers/dma/Kconfig | 13 +- drivers/dma/at_hdmac.c | 21 +- drivers/dma/at_hdmac_regs.h | 17 +- drivers/dma/ioat/dma_v3.c | 2 +- drivers/dma/pch_dma.c | 137 +- drivers/edac/amd64_edac.c | 11 +- drivers/edac/edac_pci_sysfs.c | 2 +- drivers/edac/i7core_edac.c | 4 +- drivers/firewire/core-cdev.c | 44 +- drivers/firewire/core-device.c | 15 +- drivers/firewire/net.c | 13 +- drivers/firewire/ohci.c | 14 +- drivers/firewire/sbp2.c | 4 - drivers/firmware/dmi_scan.c | 81 +- drivers/firmware/efivars.c | 239 +- drivers/firmware/iscsi_ibft.c | 42 +- drivers/firmware/iscsi_ibft_find.c | 26 +- drivers/firmware/pcdp.c | 4 +- drivers/firmware/sigma.c | 84 +- drivers/gpio/Kconfig | 11 +- drivers/gpio/pca953x.c | 6 +- drivers/gpio/pch_gpio.c | 1 - drivers/gpu/Makefile | 2 +- drivers/gpu/drm/drm_auth.c | 6 +- drivers/gpu/drm/drm_crtc.c | 4 - drivers/gpu/drm/drm_edid.c | 26 +- drivers/gpu/drm/drm_fb_helper.c | 8 +- drivers/gpu/drm/drm_fops.c | 10 +- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- drivers/gpu/drm/i915/i915_dma.c | 16 +- drivers/gpu/drm/i915/i915_drv.c | 9 - drivers/gpu/drm/i915/i915_drv.h | 4 - drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 29 +- drivers/gpu/drm/i915/i915_irq.c | 26 +- drivers/gpu/drm/i915/i915_reg.h | 54 - drivers/gpu/drm/i915/i915_suspend.c | 13 +- drivers/gpu/drm/i915/intel_bios.c | 23 +- drivers/gpu/drm/i915/intel_display.c | 127 +- drivers/gpu/drm/i915/intel_dp.c | 32 +- drivers/gpu/drm/i915/intel_drv.h | 4 +- drivers/gpu/drm/i915/intel_fb.c | 10 - drivers/gpu/drm/i915/intel_hdmi.c | 8 +- drivers/gpu/drm/i915/intel_lvds.c | 32 - drivers/gpu/drm/i915/intel_overlay.c | 14 +- drivers/gpu/drm/i915/intel_panel.c | 25 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 12 +- drivers/gpu/drm/i915/intel_sdvo.c | 113 +- drivers/gpu/drm/i915/intel_sdvo_regs.h | 7 - drivers/gpu/drm/i915/intel_tv.c | 21 +- drivers/gpu/drm/nouveau/nouveau_bo.c | 2 +- drivers/gpu/drm/nouveau/nouveau_channel.c | 1 - drivers/gpu/drm/nouveau/nouveau_fbcon.c | 2 +- drivers/gpu/drm/nouveau/nouveau_fence.c | 2 + drivers/gpu/drm/nouveau/nouveau_gem.c | 23 +- drivers/gpu/drm/nouveau/nouveau_sgdma.c | 5 +- drivers/gpu/drm/nouveau/nv04_dac.c | 8 +- drivers/gpu/drm/nouveau/nv04_dfp.c | 6 +- drivers/gpu/drm/nouveau/nv04_tv.c | 4 +- drivers/gpu/drm/radeon/atom.c | 30 +- drivers/gpu/drm/radeon/atom.h | 2 - drivers/gpu/drm/radeon/atombios_crtc.c | 4 +- drivers/gpu/drm/radeon/atombios_dp.c | 85 +- drivers/gpu/drm/radeon/evergreen.c | 174 +- drivers/gpu/drm/radeon/evergreend.h | 1 - drivers/gpu/drm/radeon/ni.c | 48 +- drivers/gpu/drm/radeon/r100.c | 39 +- drivers/gpu/drm/radeon/r200.c | 4 +- drivers/gpu/drm/radeon/r600.c | 33 +- drivers/gpu/drm/radeon/r600_blit_shaders.c | 8 - drivers/gpu/drm/radeon/r600_hdmi.c | 7 - drivers/gpu/drm/radeon/radeon.h | 8 +- drivers/gpu/drm/radeon/radeon_agp.c | 5 +- drivers/gpu/drm/radeon/radeon_asic.h | 16 +- drivers/gpu/drm/radeon/radeon_atombios.c | 48 +- drivers/gpu/drm/radeon/radeon_clocks.c | 3 - drivers/gpu/drm/radeon/radeon_combios.c | 23 +- drivers/gpu/drm/radeon/radeon_connectors.c | 140 +- drivers/gpu/drm/radeon/radeon_cursor.c | 33 +- drivers/gpu/drm/radeon/radeon_device.c | 14 +- drivers/gpu/drm/radeon/radeon_display.c | 13 +- drivers/gpu/drm/radeon/radeon_drv.c | 4 - drivers/gpu/drm/radeon/radeon_encoders.c | 21 +- drivers/gpu/drm/radeon/radeon_i2c.c | 36 +- drivers/gpu/drm/radeon/radeon_irq_kms.c | 70 +- .../gpu/drm/radeon/radeon_legacy_encoders.c | 15 +- drivers/gpu/drm/radeon/radeon_mode.h | 8 +- drivers/gpu/drm/radeon/radeon_object.c | 18 +- drivers/gpu/drm/radeon/radeon_object.h | 2 - drivers/gpu/drm/radeon/radeon_pm.c | 11 +- drivers/gpu/drm/radeon/radeon_ttm.c | 7 +- drivers/gpu/drm/radeon/rs600.c | 16 +- drivers/gpu/drm/radeon/rv515.c | 13 + drivers/gpu/drm/radeon/rv770.c | 60 +- drivers/gpu/drm/radeon/rv770d.h | 1 - drivers/gpu/drm/ttm/ttm_bo.c | 16 +- drivers/gpu/drm/ttm/ttm_bo_util.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 6 - drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 +- drivers/gpu/ion/Kconfig | 12 - drivers/gpu/ion/Makefile | 2 - drivers/gpu/ion/ion.c | 1186 --- drivers/gpu/ion/ion_carveout_heap.c | 162 - drivers/gpu/ion/ion_heap.c | 72 - drivers/gpu/ion/ion_priv.h | 184 - drivers/gpu/ion/ion_system_heap.c | 198 - drivers/gpu/ion/ion_system_mapper.c | 114 - drivers/gpu/ion/tegra/Makefile | 1 - drivers/gpu/ion/tegra/tegra_ion.c | 96 - drivers/hid/Kconfig | 24 +- drivers/hid/Makefile | 1 - drivers/hid/hid-apple.c | 27 - drivers/hid/hid-chicony.c | 7 - drivers/hid/hid-core.c | 34 +- drivers/hid/hid-debug.c | 5 - drivers/hid/hid-ids.h | 40 +- drivers/hid/hid-input.c | 7 - drivers/hid/hid-magicmouse.c | 23 +- drivers/hid/hid-multitouch.c | 47 +- drivers/hid/uhid.c | 572 -- drivers/hid/usbhid/hid-quirks.c | 3 - drivers/hwmon/Kconfig | 5 +- drivers/hwmon/ads1015.c | 3 +- drivers/hwmon/ads7871.c | 9 - drivers/hwmon/applesmc.c | 4 +- drivers/hwmon/asus_atk0110.c | 6 - drivers/hwmon/coretemp.c | 18 +- drivers/hwmon/ds620.c | 2 +- drivers/hwmon/f71805f.c | 10 +- drivers/hwmon/f75375s.c | 9 +- drivers/hwmon/fam15h_power.c | 67 +- drivers/hwmon/ibmaem.c | 15 +- drivers/hwmon/it87.c | 2 +- drivers/hwmon/jc42.c | 30 +- drivers/hwmon/jz4740-hwmon.c | 2 +- drivers/hwmon/max16065.c | 2 +- drivers/hwmon/max6639.c | 22 +- drivers/hwmon/pmbus_core.c | 3 +- drivers/hwmon/sht15.c | 3 +- drivers/hwmon/twl4030-madc-hwmon.c | 9 +- drivers/hwmon/w83627ehf.c | 74 +- drivers/hwspinlock/hwspinlock_core.c | 45 +- drivers/i2c/algos/i2c-algo-bit.c | 12 +- drivers/i2c/busses/i2c-ali1535.c | 11 +- drivers/i2c/busses/i2c-davinci.c | 2 +- drivers/i2c/busses/i2c-eg20t.c | 2 +- drivers/i2c/busses/i2c-mxs.c | 13 +- drivers/i2c/busses/i2c-nforce2.c | 2 +- drivers/i2c/busses/i2c-omap.c | 2 +- drivers/i2c/busses/i2c-pnx.c | 3 +- drivers/i2c/busses/i2c-sis5595.c | 4 +- drivers/i2c/busses/i2c-sis630.c | 6 +- drivers/i2c/busses/i2c-viapro.c | 7 +- drivers/ide/ide-disk.c | 7 +- drivers/ide/ide-floppy_ioctl.c | 3 +- drivers/idle/intel_idle.c | 9 +- drivers/infiniband/core/addr.c | 16 +- drivers/infiniband/core/netlink.c | 2 +- drivers/infiniband/hw/cxgb3/iwch_cm.c | 26 +- drivers/infiniband/hw/cxgb4/cm.c | 52 +- drivers/infiniband/hw/mlx4/mad.c | 7 +- drivers/infiniband/hw/mlx4/qp.c | 2 +- drivers/infiniband/hw/nes/nes.h | 1 - drivers/infiniband/hw/nes/nes_cm.c | 8 +- drivers/infiniband/hw/nes/nes_hw.c | 9 +- drivers/infiniband/hw/nes/nes_verbs.c | 9 +- drivers/infiniband/hw/qib/qib_iba6120.c | 4 +- drivers/infiniband/hw/qib/qib_iba7220.c | 4 +- drivers/infiniband/hw/qib/qib_iba7322.c | 6 +- drivers/infiniband/ulp/ipoib/ipoib.h | 6 +- drivers/infiniband/ulp/ipoib/ipoib_main.c | 102 +- .../infiniband/ulp/ipoib/ipoib_multicast.c | 42 +- drivers/infiniband/ulp/iser/iscsi_iser.c | 18 +- drivers/infiniband/ulp/iser/iscsi_iser.h | 1 - drivers/infiniband/ulp/iser/iser_initiator.c | 30 +- drivers/infiniband/ulp/srp/ib_srp.c | 90 +- drivers/input/Kconfig | 9 - drivers/input/Makefile | 1 - drivers/input/evdev.c | 78 +- drivers/input/joystick/walkera0701.c | 7 +- drivers/input/joystick/xpad.c | 1 - drivers/input/keyreset.c | 239 - drivers/input/misc/Kconfig | 16 - drivers/input/misc/Makefile | 2 - drivers/input/misc/gpio_axis.c | 192 - drivers/input/misc/gpio_event.c | 260 - drivers/input/misc/gpio_input.c | 376 - drivers/input/misc/gpio_matrix.c | 441 - drivers/input/misc/gpio_output.c | 97 - drivers/input/misc/keychord.c | 387 - drivers/input/mouse/alps.c | 7 +- drivers/input/mouse/bcm5974.c | 3 - drivers/input/mouse/synaptics.c | 11 - drivers/input/serio/i8042-x86ia64io.h | 29 - drivers/input/tablet/wacom_wac.c | 2 +- drivers/input/touchscreen/Kconfig | 6 - drivers/input/touchscreen/Makefile | 1 - drivers/input/touchscreen/synaptics_i2c_rmi.c | 675 -- drivers/isdn/gigaset/bas-gigaset.c | 19 +- drivers/isdn/gigaset/capi.c | 24 +- drivers/isdn/i4l/isdn_net.c | 3 - drivers/isdn/isdnloop/isdnloop.c | 12 + drivers/leds/Kconfig | 6 - drivers/leds/Makefile | 1 - drivers/leds/led-class.c | 2 - drivers/leds/ledtrig-sleep.c | 80 - drivers/leds/ledtrig-timer.c | 2 - drivers/md/bitmap.c | 4 - drivers/md/dm-crypt.c | 38 +- drivers/md/dm-exception-store.c | 2 +- drivers/md/dm-flakey.c | 11 +- drivers/md/dm-io.c | 52 +- drivers/md/dm-ioctl.c | 8 - drivers/md/dm-linear.c | 12 +- drivers/md/dm-mpath.c | 11 - drivers/md/dm-raid.c | 1 - drivers/md/dm-raid1.c | 2 +- drivers/md/dm-region-hash.c | 5 +- drivers/md/dm-snap-persistent.c | 2 +- drivers/md/dm-table.c | 13 +- drivers/md/dm.c | 74 +- drivers/md/linear.h | 2 +- drivers/md/md.c | 41 +- drivers/md/md.h | 2 +- drivers/md/multipath.c | 3 +- drivers/md/raid1.c | 20 +- drivers/md/raid10.c | 28 +- drivers/md/raid5.c | 50 +- drivers/media/dvb/dvb-core/dvbdev.c | 1 - drivers/media/dvb/dvb-usb/dib0700_core.c | 81 +- drivers/media/dvb/dvb-usb/vp7045.c | 26 +- drivers/media/dvb/frontends/dib0070.c | 37 +- drivers/media/dvb/frontends/dib0090.c | 70 +- drivers/media/dvb/frontends/dib7000m.c | 27 +- drivers/media/dvb/frontends/dib7000p.c | 32 +- drivers/media/dvb/frontends/dib8000.c | 72 +- drivers/media/dvb/frontends/dib9000.c | 164 +- drivers/media/dvb/frontends/dibx000_common.c | 76 +- drivers/media/dvb/frontends/dibx000_common.h | 1 - drivers/media/dvb/frontends/lgdt330x.c | 6 +- drivers/media/dvb/siano/smsusb.c | 6 +- drivers/media/rc/ene_ir.c | 32 +- drivers/media/rc/fintek-cir.c | 20 +- drivers/media/rc/ite-cir.c | 22 +- drivers/media/rc/nuvoton-cir.c | 81 +- drivers/media/rc/nuvoton-cir.h | 1 + drivers/media/rc/rc-main.c | 5 +- drivers/media/rc/winbond-cir.c | 79 +- drivers/media/video/au0828/au0828-video.c | 12 +- drivers/media/video/cx23885/cx23885-dvb.c | 2 +- drivers/media/video/gspca/spca506.c | 2 +- drivers/media/video/hdpvr/hdpvr-video.c | 3 +- drivers/media/video/pvrusb2/pvrusb2-devattr.c | 10 - drivers/media/video/s5p-fimc/fimc-core.c | 2 +- drivers/media/video/saa7164/saa7164-cards.c | 66 - drivers/media/video/saa7164/saa7164-dvb.c | 1 - drivers/media/video/saa7164/saa7164.h | 1 - drivers/media/video/uvc/uvc_driver.c | 2 +- drivers/media/video/uvc/uvc_entity.c | 2 +- drivers/media/video/uvc/uvc_v4l2.c | 11 +- drivers/media/video/uvc/uvc_video.c | 10 +- drivers/media/video/uvc/uvcvideo.h | 3 +- drivers/media/video/v4l2-ioctl.c | 4 - drivers/mfd/ab3100-core.c | 5 + drivers/mfd/ab3550-core.c | 2 + drivers/mfd/cs5535-mfd.c | 6 +- drivers/mfd/ezx-pcap.c | 2 +- drivers/mfd/mfd-core.c | 17 +- drivers/mfd/omap-usb-host.c | 1 + drivers/mfd/tps65910-irq.c | 2 - drivers/mfd/twl-core.c | 16 +- drivers/mfd/twl4030-madc.c | 35 +- drivers/mfd/twl6030-irq.c | 13 +- drivers/mfd/wm831x-otp.c | 8 - drivers/misc/Kconfig | 53 +- drivers/misc/Makefile | 4 - drivers/misc/akm8975.c | 732 -- drivers/misc/apanic.c | 606 -- drivers/misc/cb710/core.c | 1 - drivers/misc/cs5535-mfgpt.c | 2 +- drivers/misc/kgdbts.c | 160 +- drivers/misc/lis3lv02d/lis3lv02d.c | 14 +- drivers/misc/pch_phub.c | 84 +- drivers/misc/sgi-xp/xpc_main.c | 34 +- drivers/misc/sgi-xp/xpc_uv.c | 84 +- drivers/misc/spear13xx_pcie_gadget.c | 2 +- drivers/misc/uid_stat.c | 156 - drivers/misc/wl127x-rfkill.c | 121 - drivers/mmc/card/Kconfig | 9 - drivers/mmc/card/block.c | 390 +- drivers/mmc/core/Kconfig | 17 - drivers/mmc/core/bus.c | 24 +- drivers/mmc/core/core.c | 139 +- drivers/mmc/core/core.h | 1 - drivers/mmc/core/host.c | 22 +- drivers/mmc/core/host.h | 8 +- drivers/mmc/core/mmc.c | 5 +- drivers/mmc/core/sd.c | 93 +- drivers/mmc/core/sdio.c | 151 +- drivers/mmc/core/sdio_bus.c | 13 +- drivers/mmc/core/sdio_io.c | 33 - drivers/mmc/core/sdio_irq.c | 11 +- drivers/mmc/host/atmel-mci.c | 9 +- drivers/mmc/host/mmci.c | 14 +- drivers/mmc/host/mxcmmc.c | 1 - drivers/mmc/host/mxs-mmc.c | 34 +- drivers/mmc/host/sdhci-esdhc-imx.c | 10 +- drivers/mmc/host/sdhci-esdhc.h | 6 +- drivers/mmc/host/sdhci-pci.c | 1 - drivers/mmc/host/sdhci-s3c.c | 4 +- drivers/mmc/host/sdhci.c | 16 +- drivers/mmc/host/vub300.c | 2 +- drivers/mtd/devices/block2mtd.c | 1 - drivers/mtd/devices/lart.c | 1 - drivers/mtd/devices/m25p80.c | 1 - drivers/mtd/devices/slram.c | 2 +- drivers/mtd/devices/sst25l.c | 1 - drivers/mtd/maps/autcpu12-nvram.c | 19 +- drivers/mtd/mtd_blkdevs.c | 3 +- drivers/mtd/mtdchar.c | 1 - drivers/mtd/mtdoops.c | 5 +- drivers/mtd/nand/Kconfig | 24 - drivers/mtd/nand/cafe_nand.c | 2 +- drivers/mtd/nand/nand_base.c | 66 +- drivers/mtd/nand/nand_bbt.c | 3 +- drivers/mtd/nand/nandsim.c | 13 +- drivers/mtd/nand/omap2.c | 3 +- drivers/mtd/nand/pxa3xx_nand.c | 14 +- drivers/mtd/redboot.c | 3 - drivers/mtd/sm_ftl.c | 2 +- drivers/mtd/tests/mtd_stresstest.c | 7 - drivers/mtd/ubi/build.c | 5 - drivers/mtd/ubi/cdev.c | 3 - drivers/mtd/ubi/debug.h | 5 +- drivers/mtd/ubi/eba.c | 6 +- drivers/mtd/ubi/scan.c | 8 +- drivers/mtd/ubi/ubi.h | 2 - drivers/mtd/ubi/vtbl.c | 4 +- drivers/mtd/ubi/wl.c | 22 +- drivers/net/3c59x.c | 2 +- drivers/net/8139cp.c | 10 +- drivers/net/Kconfig | 28 +- drivers/net/Makefile | 3 - drivers/net/atl1c/atl1c_main.c | 4 + drivers/net/atlx/atl1.c | 12 +- drivers/net/atlx/atl1.h | 3 +- drivers/net/atlx/atlx.c | 2 +- drivers/net/benet/be_main.c | 5 +- drivers/net/bnx2.c | 13 +- drivers/net/bnx2x/bnx2x_dcb.c | 1 - drivers/net/bnx2x/bnx2x_main.c | 6 +- drivers/net/bnx2x/bnx2x_reg.h | 12 - drivers/net/bonding/bond_alb.c | 27 +- drivers/net/bonding/bond_main.c | 44 +- drivers/net/bonding/bond_sysfs.c | 135 +- drivers/net/caif/caif_serial.c | 3 - drivers/net/can/c_can/c_can.c | 24 +- drivers/net/can/c_can/c_can.h | 1 - drivers/net/can/dev.c | 3 +- drivers/net/can/janz-ican3.c | 4 +- drivers/net/can/mcp251x.c | 11 +- drivers/net/can/mscan/mpc5xxx_can.c | 4 +- drivers/net/can/pch_can.c | 2 +- drivers/net/can/ti_hecc.c | 6 +- drivers/net/cnic.c | 57 +- drivers/net/cxgb3/cxgb3_offload.c | 31 +- drivers/net/cxgb3/l2t.c | 15 +- drivers/net/cxgb3/l2t.h | 16 +- drivers/net/davinci_cpdma.c | 1 - drivers/net/davinci_emac.c | 6 +- drivers/net/davinci_mdio.c | 5 - drivers/net/dummy.c | 11 +- drivers/net/e1000/e1000.h | 2 - drivers/net/e1000/e1000_hw.c | 6 - drivers/net/e1000/e1000_main.c | 18 +- drivers/net/e1000e/82571.c | 10 +- drivers/net/e1000e/e1000.h | 1 - drivers/net/e1000e/ich8lan.c | 19 +- drivers/net/e1000e/lib.c | 3 +- drivers/net/e1000e/netdev.c | 23 +- drivers/net/enic/enic_main.c | 8 +- drivers/net/gianfar_ptp.c | 9 +- drivers/net/ibmveth.c | 31 +- drivers/net/ifb.c | 2 +- drivers/net/igb/e1000_82575.c | 1 - drivers/net/igb/igb_main.c | 10 +- drivers/net/irda/sir_dev.c | 2 +- drivers/net/irda/smsc-ircc2.c | 2 +- drivers/net/ixgbe/ixgbe_82599.c | 2 - drivers/net/ixgbe/ixgbe_common.c | 1 - drivers/net/ixgbe/ixgbe_main.c | 10 +- drivers/net/ixgbe/ixgbe_type.h | 3 - drivers/net/jme.c | 30 +- drivers/net/jme.h | 2 +- drivers/net/ks8851_mll.c | 2 +- drivers/net/ksz884x.c | 2 +- drivers/net/loopback.c | 5 - drivers/net/macvlan.c | 6 +- drivers/net/ne.c | 1 - drivers/net/netconsole.c | 6 +- drivers/net/netxen/netxen_nic_main.c | 4 - drivers/net/niu.c | 4 +- drivers/net/pch_gbe/pch_gbe_main.c | 50 +- drivers/net/pch_gbe/pch_gbe_param.c | 15 +- drivers/net/phy/dp83640.c | 14 +- drivers/net/phy/mdio-gpio.c | 2 +- drivers/net/ppp_generic.c | 26 +- drivers/net/pppoe.c | 2 +- drivers/net/pppolac.c | 449 - drivers/net/pppopns.c | 428 - drivers/net/pptp.c | 4 +- drivers/net/r8169.c | 454 +- drivers/net/rionet.c | 27 +- drivers/net/sfc/efx.c | 24 +- drivers/net/sfc/efx.h | 14 +- drivers/net/sfc/ethtool.c | 16 +- drivers/net/sfc/io.h | 15 +- drivers/net/sfc/mcdi.c | 46 +- drivers/net/sfc/nic.c | 7 + drivers/net/sfc/nic.h | 7 +- drivers/net/sfc/rx.c | 4 +- drivers/net/sfc/siena.c | 25 +- drivers/net/sfc/tx.c | 19 - drivers/net/sfc/workarounds.h | 2 + drivers/net/sis190.c | 12 +- drivers/net/skge.c | 7 - drivers/net/sky2.c | 56 +- drivers/net/sky2.h | 1 + drivers/net/smsc911x.c | 14 +- drivers/net/sungem.c | 2 +- drivers/net/tg3.c | 127 +- drivers/net/tun.c | 13 +- drivers/net/usb/asix.c | 29 +- drivers/net/usb/cdc_eem.c | 1 - drivers/net/usb/cdc_ether.c | 37 +- drivers/net/usb/cdc_ncm.c | 191 +- drivers/net/usb/ipheth.c | 20 - drivers/net/usb/kaweth.c | 2 +- drivers/net/usb/rtl8150.c | 1 + drivers/net/usb/sierra_net.c | 16 +- drivers/net/usb/smsc75xx.c | 1 - drivers/net/usb/smsc95xx.c | 2 +- drivers/net/usb/usbnet.c | 69 +- drivers/net/usb/zaurus.c | 12 - drivers/net/veth.c | 6 +- drivers/net/via-velocity.c | 3 + drivers/net/vmxnet3/vmxnet3_drv.c | 7 +- drivers/net/vmxnet3/vmxnet3_int.h | 4 +- drivers/net/wan/hdlc_fr.c | 5 +- drivers/net/wan/ixp4xx_hss.c | 1 - drivers/net/wimax/i2400m/i2400m-usb.h | 3 - drivers/net/wimax/i2400m/netdev.c | 3 +- drivers/net/wimax/i2400m/usb.c | 6 - drivers/net/wireless/Kconfig | 7 - drivers/net/wireless/Makefile | 3 - drivers/net/wireless/airo.c | 1 - drivers/net/wireless/ath/ath5k/base.c | 23 +- drivers/net/wireless/ath/ath9k/ani.c | 5 + drivers/net/wireless/ath/ath9k/ar5008_phy.c | 25 +- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 3 +- drivers/net/wireless/ath/ath9k/ar9002_hw.c | 25 +- .../wireless/ath/ath9k/ar9003_2p2_initvals.h | 174 +- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 3 +- .../net/wireless/ath/ath9k/ar9003_eeprom.c | 8 +- .../net/wireless/ath/ath9k/ar9003_eeprom.h | 6 +- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 6 +- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 7 +- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 14 +- .../net/wireless/ath/ath9k/ar9485_initvals.h | 10 +- drivers/net/wireless/ath/ath9k/beacon.c | 1 - drivers/net/wireless/ath/ath9k/calib.c | 5 +- drivers/net/wireless/ath/ath9k/hif_usb.c | 1 - drivers/net/wireless/ath/ath9k/htc_hst.c | 2 - drivers/net/wireless/ath/ath9k/hw.c | 31 +- drivers/net/wireless/ath/ath9k/hw.h | 4 +- drivers/net/wireless/ath/ath9k/init.c | 2 - drivers/net/wireless/ath/ath9k/mac.c | 3 +- drivers/net/wireless/ath/ath9k/main.c | 16 - drivers/net/wireless/ath/ath9k/pci.c | 27 - drivers/net/wireless/ath/ath9k/rc.c | 6 +- drivers/net/wireless/ath/ath9k/recv.c | 7 +- drivers/net/wireless/ath/ath9k/xmit.c | 2 - drivers/net/wireless/ath/carl9170/main.c | 4 +- drivers/net/wireless/ath/carl9170/tx.c | 1 - drivers/net/wireless/b43/main.c | 10 +- drivers/net/wireless/b43legacy/main.c | 2 - drivers/net/wireless/bcm4329/Kconfig | 27 - drivers/net/wireless/bcm4329/Makefile | 21 - drivers/net/wireless/bcm4329/aiutils.c | 686 -- drivers/net/wireless/bcm4329/bcmpcispi.c | 630 -- drivers/net/wireless/bcm4329/bcmsdh.c | 652 -- drivers/net/wireless/bcm4329/bcmsdh_linux.c | 735 -- drivers/net/wireless/bcm4329/bcmsdh_sdmmc.c | 1304 --- .../net/wireless/bcm4329/bcmsdh_sdmmc_linux.c | 269 - drivers/net/wireless/bcm4329/bcmsdspi.c | 1596 --- drivers/net/wireless/bcm4329/bcmsdspi_linux.c | 252 - drivers/net/wireless/bcm4329/bcmsdstd.c | 3127 ------ drivers/net/wireless/bcm4329/bcmsdstd_linux.c | 251 - drivers/net/wireless/bcm4329/bcmutils.c | 1838 ---- drivers/net/wireless/bcm4329/bcmwifi.c | 199 - drivers/net/wireless/bcm4329/dhd.h | 465 - drivers/net/wireless/bcm4329/dhd_bus.h | 93 - drivers/net/wireless/bcm4329/dhd_cdc.c | 535 - drivers/net/wireless/bcm4329/dhd_common.c | 2461 ----- .../net/wireless/bcm4329/dhd_custom_gpio.c | 272 - drivers/net/wireless/bcm4329/dhd_dbg.h | 100 - drivers/net/wireless/bcm4329/dhd_linux.c | 3442 ------- .../net/wireless/bcm4329/dhd_linux_sched.c | 38 - drivers/net/wireless/bcm4329/dhd_proto.h | 102 - drivers/net/wireless/bcm4329/dhd_sdio.c | 5824 ----------- drivers/net/wireless/bcm4329/dngl_stats.h | 43 - drivers/net/wireless/bcm4329/hndpmu.c | 131 - drivers/net/wireless/bcm4329/include/Makefile | 21 - drivers/net/wireless/bcm4329/include/aidmp.h | 368 - drivers/net/wireless/bcm4329/include/bcmcdc.h | 100 - .../net/wireless/bcm4329/include/bcmdefs.h | 114 - .../net/wireless/bcm4329/include/bcmdevs.h | 124 - .../net/wireless/bcm4329/include/bcmendian.h | 205 - .../net/wireless/bcm4329/include/bcmpcispi.h | 205 - .../net/wireless/bcm4329/include/bcmperf.h | 36 - .../net/wireless/bcm4329/include/bcmsdbus.h | 117 - drivers/net/wireless/bcm4329/include/bcmsdh.h | 208 - .../wireless/bcm4329/include/bcmsdh_sdmmc.h | 122 - .../net/wireless/bcm4329/include/bcmsdpcm.h | 263 - .../net/wireless/bcm4329/include/bcmsdspi.h | 131 - .../net/wireless/bcm4329/include/bcmsdstd.h | 223 - drivers/net/wireless/bcm4329/include/bcmspi.h | 36 - .../net/wireless/bcm4329/include/bcmutils.h | 637 -- .../net/wireless/bcm4329/include/bcmwifi.h | 154 - .../net/wireless/bcm4329/include/dhdioctl.h | 123 - .../net/wireless/bcm4329/include/epivers.h | 48 - drivers/net/wireless/bcm4329/include/hndpmu.h | 34 - .../wireless/bcm4329/include/hndrte_armtrap.h | 88 - .../wireless/bcm4329/include/hndrte_cons.h | 63 - drivers/net/wireless/bcm4329/include/hndsoc.h | 195 - .../net/wireless/bcm4329/include/linux_osl.h | 322 - .../net/wireless/bcm4329/include/linuxver.h | 447 - .../net/wireless/bcm4329/include/miniopt.h | 77 - .../net/wireless/bcm4329/include/msgtrace.h | 72 - drivers/net/wireless/bcm4329/include/osl.h | 55 - .../bcm4329/include/packed_section_end.h | 54 - .../bcm4329/include/packed_section_start.h | 61 - drivers/net/wireless/bcm4329/include/pcicfg.h | 52 - .../wireless/bcm4329/include/proto/802.11.h | 1433 --- .../wireless/bcm4329/include/proto/802.11e.h | 131 - .../wireless/bcm4329/include/proto/802.1d.h | 49 - .../wireless/bcm4329/include/proto/bcmeth.h | 83 - .../wireless/bcm4329/include/proto/bcmevent.h | 212 - .../wireless/bcm4329/include/proto/bcmip.h | 157 - .../wireless/bcm4329/include/proto/eapol.h | 172 - .../wireless/bcm4329/include/proto/ethernet.h | 148 - .../wireless/bcm4329/include/proto/sdspi.h | 71 - .../net/wireless/bcm4329/include/proto/vlan.h | 63 - .../net/wireless/bcm4329/include/proto/wpa.h | 159 - .../net/wireless/bcm4329/include/sbchipc.h | 1026 -- .../net/wireless/bcm4329/include/sbconfig.h | 276 - .../net/wireless/bcm4329/include/sbhnddma.h | 294 - .../net/wireless/bcm4329/include/sbpcmcia.h | 109 - drivers/net/wireless/bcm4329/include/sbsdio.h | 166 - .../net/wireless/bcm4329/include/sbsdpcmdev.h | 288 - .../net/wireless/bcm4329/include/sbsocram.h | 150 - drivers/net/wireless/bcm4329/include/sdio.h | 566 -- drivers/net/wireless/bcm4329/include/sdioh.h | 299 - .../net/wireless/bcm4329/include/sdiovar.h | 58 - .../net/wireless/bcm4329/include/siutils.h | 235 - drivers/net/wireless/bcm4329/include/trxhdr.h | 46 - .../net/wireless/bcm4329/include/typedefs.h | 303 - .../net/wireless/bcm4329/include/wlioctl.h | 1673 ---- drivers/net/wireless/bcm4329/linux_osl.c | 625 -- drivers/net/wireless/bcm4329/miniopt.c | 163 - drivers/net/wireless/bcm4329/sbutils.c | 1004 -- drivers/net/wireless/bcm4329/siutils.c | 1527 --- drivers/net/wireless/bcm4329/siutils_priv.h | 213 - drivers/net/wireless/bcm4329/wl_iw.c | 8455 ---------------- drivers/net/wireless/bcm4329/wl_iw.h | 309 - drivers/net/wireless/bcmdhd/Kconfig | 54 - drivers/net/wireless/bcmdhd/Makefile | 40 - drivers/net/wireless/bcmdhd/aiutils.c | 675 -- drivers/net/wireless/bcmdhd/bcmevent.c | 127 - drivers/net/wireless/bcmdhd/bcmsdh.c | 691 -- drivers/net/wireless/bcmdhd/bcmsdh_linux.c | 736 -- drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c | 1421 --- .../net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c | 366 - drivers/net/wireless/bcmdhd/bcmutils.c | 1965 ---- drivers/net/wireless/bcmdhd/bcmwifi.c | 274 - drivers/net/wireless/bcmdhd/dhd.h | 788 -- drivers/net/wireless/bcmdhd/dhd_bta.c | 335 - drivers/net/wireless/bcmdhd/dhd_bta.h | 39 - drivers/net/wireless/bcmdhd/dhd_bus.h | 99 - drivers/net/wireless/bcmdhd/dhd_cdc.c | 2534 ----- drivers/net/wireless/bcmdhd/dhd_cfg80211.c | 660 -- drivers/net/wireless/bcmdhd/dhd_cfg80211.h | 45 - drivers/net/wireless/bcmdhd/dhd_common.c | 2471 ----- drivers/net/wireless/bcmdhd/dhd_custom_gpio.c | 293 - drivers/net/wireless/bcmdhd/dhd_dbg.h | 105 - drivers/net/wireless/bcmdhd/dhd_linux.c | 5486 ---------- drivers/net/wireless/bcmdhd/dhd_linux_sched.c | 39 - drivers/net/wireless/bcmdhd/dhd_proto.h | 105 - drivers/net/wireless/bcmdhd/dhd_sdio.c | 6361 ------------ drivers/net/wireless/bcmdhd/dhd_wlfc.h | 276 - drivers/net/wireless/bcmdhd/dngl_stats.h | 43 - drivers/net/wireless/bcmdhd/dngl_wlhdr.h | 40 - drivers/net/wireless/bcmdhd/hndpmu.c | 196 - drivers/net/wireless/bcmdhd/include/Makefile | 53 - drivers/net/wireless/bcmdhd/include/aidmp.h | 377 - drivers/net/wireless/bcmdhd/include/bcmcdc.h | 121 - drivers/net/wireless/bcmdhd/include/bcmdefs.h | 231 - drivers/net/wireless/bcmdhd/include/bcmdevs.h | 747 -- .../net/wireless/bcmdhd/include/bcmendian.h | 279 - .../net/wireless/bcmdhd/include/bcmpcispi.h | 181 - drivers/net/wireless/bcmdhd/include/bcmperf.h | 36 - .../net/wireless/bcmdhd/include/bcmsdbus.h | 128 - drivers/net/wireless/bcmdhd/include/bcmsdh.h | 219 - .../wireless/bcmdhd/include/bcmsdh_sdmmc.h | 123 - .../net/wireless/bcmdhd/include/bcmsdpcm.h | 274 - .../net/wireless/bcmdhd/include/bcmsdspi.h | 135 - .../net/wireless/bcmdhd/include/bcmsdstd.h | 248 - drivers/net/wireless/bcmdhd/include/bcmspi.h | 40 - .../net/wireless/bcmdhd/include/bcmutils.h | 722 -- drivers/net/wireless/bcmdhd/include/bcmwifi.h | 165 - .../net/wireless/bcmdhd/include/dhdioctl.h | 131 - drivers/net/wireless/bcmdhd/include/epivers.h | 49 - drivers/net/wireless/bcmdhd/include/hndpmu.h | 37 - .../wireless/bcmdhd/include/hndrte_armtrap.h | 88 - .../net/wireless/bcmdhd/include/hndrte_cons.h | 68 - drivers/net/wireless/bcmdhd/include/hndsoc.h | 207 - drivers/net/wireless/bcmdhd/include/htsf.h | 74 - .../net/wireless/bcmdhd/include/linux_osl.h | 431 - .../net/wireless/bcmdhd/include/linuxver.h | 614 -- drivers/net/wireless/bcmdhd/include/miniopt.h | 77 - .../net/wireless/bcmdhd/include/msgtrace.h | 74 - drivers/net/wireless/bcmdhd/include/osl.h | 66 - .../bcmdhd/include/packed_section_end.h | 54 - .../bcmdhd/include/packed_section_start.h | 61 - drivers/net/wireless/bcmdhd/include/pcicfg.h | 78 - .../wireless/bcmdhd/include/proto/802.11.h | 2032 ---- .../bcmdhd/include/proto/802.11_bta.h | 45 - .../wireless/bcmdhd/include/proto/802.11e.h | 131 - .../wireless/bcmdhd/include/proto/802.1d.h | 49 - .../wireless/bcmdhd/include/proto/bcmeth.h | 83 - .../wireless/bcmdhd/include/proto/bcmevent.h | 317 - .../net/wireless/bcmdhd/include/proto/bcmip.h | 154 - .../bcmdhd/include/proto/bt_amp_hci.h | 442 - .../net/wireless/bcmdhd/include/proto/eapol.h | 173 - .../wireless/bcmdhd/include/proto/ethernet.h | 163 - .../net/wireless/bcmdhd/include/proto/p2p.h | 512 - .../net/wireless/bcmdhd/include/proto/sdspi.h | 76 - .../net/wireless/bcmdhd/include/proto/vlan.h | 70 - .../net/wireless/bcmdhd/include/proto/wpa.h | 168 - drivers/net/wireless/bcmdhd/include/sbchipc.h | 1783 ---- .../net/wireless/bcmdhd/include/sbconfig.h | 276 - .../net/wireless/bcmdhd/include/sbhnddma.h | 327 - .../net/wireless/bcmdhd/include/sbpcmcia.h | 109 - drivers/net/wireless/bcmdhd/include/sbsdio.h | 166 - .../net/wireless/bcmdhd/include/sbsdpcmdev.h | 293 - .../net/wireless/bcmdhd/include/sbsocram.h | 186 - drivers/net/wireless/bcmdhd/include/sdio.h | 612 -- drivers/net/wireless/bcmdhd/include/sdioh.h | 446 - drivers/net/wireless/bcmdhd/include/sdiovar.h | 58 - drivers/net/wireless/bcmdhd/include/siutils.h | 277 - drivers/net/wireless/bcmdhd/include/trxhdr.h | 53 - .../net/wireless/bcmdhd/include/typedefs.h | 312 - .../net/wireless/bcmdhd/include/wlfc_proto.h | 198 - drivers/net/wireless/bcmdhd/include/wlioctl.h | 2763 ----- drivers/net/wireless/bcmdhd/linux_osl.c | 924 -- drivers/net/wireless/bcmdhd/sbutils.c | 992 -- drivers/net/wireless/bcmdhd/siutils.c | 1915 ---- drivers/net/wireless/bcmdhd/siutils_priv.h | 235 - drivers/net/wireless/bcmdhd/uamp_api.h | 176 - drivers/net/wireless/bcmdhd/wl_android.c | 858 -- drivers/net/wireless/bcmdhd/wl_android.h | 57 - drivers/net/wireless/bcmdhd/wl_cfg80211.c | 7885 --------------- drivers/net/wireless/bcmdhd/wl_cfg80211.h | 693 -- drivers/net/wireless/bcmdhd/wl_cfgp2p.c | 2033 ---- drivers/net/wireless/bcmdhd/wl_cfgp2p.h | 288 - drivers/net/wireless/bcmdhd/wl_dbg.h | 49 - drivers/net/wireless/bcmdhd/wl_iw.c | 8894 ----------------- drivers/net/wireless/bcmdhd/wl_iw.h | 319 - drivers/net/wireless/bcmdhd/wl_linux_mon.c | 409 - drivers/net/wireless/bcmdhd/wldev_common.c | 424 - drivers/net/wireless/bcmdhd/wldev_common.h | 113 - drivers/net/wireless/hostap/hostap_main.c | 1 - drivers/net/wireless/ipw2x00/ipw2200.c | 13 +- drivers/net/wireless/iwlegacy/iwl-3945-rs.c | 13 +- drivers/net/wireless/iwlegacy/iwl-3945.c | 13 +- drivers/net/wireless/iwlegacy/iwl-4965.c | 8 +- drivers/net/wireless/iwlegacy/iwl-core.c | 4 +- drivers/net/wireless/iwlegacy/iwl-hcmd.c | 2 +- drivers/net/wireless/iwlegacy/iwl-tx.c | 4 +- drivers/net/wireless/iwlegacy/iwl3945-base.c | 19 +- drivers/net/wireless/iwlegacy/iwl4965-base.c | 10 +- drivers/net/wireless/iwlwifi/iwl-5000.c | 1 - drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 1 - drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 1 - drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 39 +- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 10 +- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 9 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 25 +- drivers/net/wireless/iwlwifi/iwl-agn.h | 2 - drivers/net/wireless/iwlwifi/iwl-core.c | 4 +- drivers/net/wireless/iwlwifi/iwl-core.h | 2 - drivers/net/wireless/iwlwifi/iwl-hcmd.c | 2 +- drivers/net/wireless/iwlwifi/iwl-power.c | 3 +- drivers/net/wireless/iwlwifi/iwl-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-scan.c | 30 +- drivers/net/wireless/iwlwifi/iwl-tx.c | 4 +- drivers/net/wireless/libertas/if_spi.c | 1 - drivers/net/wireless/mwifiex/11n_rxreorder.c | 5 +- drivers/net/wireless/mwifiex/11n_rxreorder.h | 7 - drivers/net/wireless/mwifiex/sdio.c | 11 +- drivers/net/wireless/mwifiex/wmm.c | 2 - drivers/net/wireless/p54/p54spi.c | 19 +- drivers/net/wireless/p54/p54usb.c | 6 +- drivers/net/wireless/rt2x00/rt2400pci.c | 9 - drivers/net/wireless/rt2x00/rt2400pci.h | 1 - drivers/net/wireless/rt2x00/rt2500pci.c | 9 - drivers/net/wireless/rt2x00/rt2500usb.c | 11 +- drivers/net/wireless/rt2x00/rt2500usb.h | 17 +- drivers/net/wireless/rt2x00/rt2800lib.c | 69 +- drivers/net/wireless/rt2x00/rt2800pci.c | 38 +- drivers/net/wireless/rt2x00/rt2800usb.c | 52 +- drivers/net/wireless/rt2x00/rt2x00.h | 1 - drivers/net/wireless/rt2x00/rt2x00dev.c | 28 +- drivers/net/wireless/rt2x00/rt2x00mac.c | 14 +- drivers/net/wireless/rt2x00/rt2x00queue.c | 24 +- drivers/net/wireless/rt2x00/rt2x00queue.h | 2 - drivers/net/wireless/rt2x00/rt2x00usb.c | 33 +- drivers/net/wireless/rt2x00/rt61pci.c | 12 +- drivers/net/wireless/rt2x00/rt61pci.h | 1 - drivers/net/wireless/rt2x00/rt73usb.c | 9 - drivers/net/wireless/rt2x00/rt73usb.h | 3 - drivers/net/wireless/rtl818x/rtl8187/dev.c | 2 +- drivers/net/wireless/rtl818x/rtl8187/leds.c | 2 +- drivers/net/wireless/rtlwifi/core.c | 8 - drivers/net/wireless/rtlwifi/pci.c | 44 +- .../net/wireless/rtlwifi/rtl8192c/dm_common.c | 15 +- drivers/net/wireless/rtlwifi/rtl8192cu/rf.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 1 - drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 11 +- drivers/net/wireless/rtlwifi/rtl8192se/fw.c | 4 - drivers/net/wireless/rtlwifi/usb.c | 5 +- drivers/net/wireless/wl1251/main.c | 1 - drivers/net/wireless/wl1251/sdio.c | 4 +- drivers/net/wireless/wl1251/spi.c | 3 +- drivers/net/wireless/wl12xx/boot.c | 14 - drivers/net/wireless/wl12xx/cmd.c | 22 - drivers/net/wireless/wl12xx/scan.c | 19 +- drivers/net/xen-netback/common.h | 3 - drivers/net/xen-netback/interface.c | 27 +- drivers/net/xen-netback/netback.c | 117 +- drivers/oprofile/oprof.c | 29 +- drivers/oprofile/oprofile_files.c | 7 +- drivers/oprofile/oprofile_perf.c | 2 +- drivers/oprofile/oprofilefs.c | 11 +- drivers/oprofile/timer_int.c | 1 - drivers/pci/dmar.c | 2 +- drivers/pci/hotplug/acpiphp_glue.c | 7 +- drivers/pci/hotplug/shpchp_core.c | 4 +- drivers/pci/hotplug/shpchp_hpc.c | 4 +- drivers/pci/intel-iommu.c | 86 +- drivers/pci/msi.c | 10 - drivers/pci/pci-acpi.c | 1 + drivers/pci/pci-driver.c | 19 - drivers/pci/pci.c | 7 +- drivers/pci/pcie/aspm.c | 71 +- drivers/pci/probe.c | 11 +- drivers/pci/quirks.c | 60 - drivers/pci/remove.c | 2 - drivers/pci/setup-bus.c | 57 +- drivers/pci/setup-res.c | 155 +- drivers/pci/xen-pcifront.c | 5 +- drivers/pcmcia/ds.c | 4 +- drivers/pcmcia/pxa2xx_sharpsl.c | 2 +- drivers/platform/x86/acer-wmi.c | 123 +- drivers/platform/x86/asus-laptop.c | 8 +- drivers/platform/x86/asus-nb-wmi.c | 4 - drivers/platform/x86/asus-wmi.c | 17 +- drivers/platform/x86/intel_ips.c | 22 - drivers/platform/x86/samsung-laptop.c | 49 +- drivers/platform/x86/sony-laptop.c | 2 +- drivers/platform/x86/wmi.c | 6 +- drivers/pnp/pnpacpi/core.c | 12 +- drivers/pnp/quirks.c | 42 - drivers/power/ds2780_battery.c | 86 +- drivers/power/pda_power.c | 71 +- drivers/power/power_supply_core.c | 30 +- drivers/ptp/ptp_clock.c | 4 +- drivers/rapidio/rio-scan.c | 3 +- drivers/regulator/88pm8607.c | 6 +- drivers/regulator/max8997.c | 2 +- drivers/regulator/tps6524x-regulator.c | 2 +- drivers/regulator/tps65910-regulator.c | 7 - drivers/rtc/Kconfig | 18 - drivers/rtc/Makefile | 2 - drivers/rtc/alarm-dev.c | 286 - drivers/rtc/alarm.c | 590 -- drivers/rtc/class.c | 69 +- drivers/rtc/interface.c | 74 +- drivers/rtc/rtc-imxdi.c | 2 - drivers/rtc/rtc-isl1208.c | 3 - drivers/rtc/rtc-m41t80.c | 9 - drivers/rtc/rtc-mxc.c | 5 +- drivers/rtc/rtc-pl031.c | 21 +- drivers/rtc/rtc-rs5c348.c | 7 +- drivers/rtc/rtc-tegra.c | 2 +- drivers/rtc/rtc-twl.c | 5 - drivers/rtc/rtc-vt8500.c | 11 +- drivers/rtc/rtc-wm831x.c | 24 +- drivers/s390/block/dasd_eckd.c | 2 +- drivers/s390/block/dasd_ioctl.c | 1 - drivers/s390/char/fs3270.c | 1 - drivers/s390/char/vmcp.c | 1 - drivers/s390/cio/ccwgroup.c | 42 +- drivers/s390/cio/chsc_sch.c | 1 - drivers/s390/cio/device_pgid.c | 10 +- drivers/s390/cio/qdio_thinint.c | 15 +- drivers/s390/net/qeth_l3_main.c | 25 +- drivers/s390/scsi/zfcp_aux.c | 1 - drivers/s390/scsi/zfcp_ccw.c | 73 +- drivers/s390/scsi/zfcp_cfdc.c | 3 +- drivers/s390/scsi/zfcp_dbf.c | 20 - drivers/s390/scsi/zfcp_dbf.h | 1 - drivers/s390/scsi/zfcp_def.h | 2 - drivers/s390/scsi/zfcp_ext.h | 2 - drivers/s390/scsi/zfcp_fsf.c | 23 +- drivers/s390/scsi/zfcp_scsi.c | 4 - drivers/s390/scsi/zfcp_sysfs.c | 18 +- drivers/s390/scsi/zfcp_unit.c | 36 +- drivers/scsi/3w-9xxx.c | 2 - drivers/scsi/Makefile | 2 +- drivers/scsi/aacraid/commsup.c | 2 - drivers/scsi/aacraid/linit.c | 4 - drivers/scsi/atp870u.c | 11 +- drivers/scsi/bnx2fc/bnx2fc.h | 8 +- drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 28 +- drivers/scsi/bnx2fc/bnx2fc_hwi.c | 24 +- drivers/scsi/bnx2fc/bnx2fc_io.c | 2 +- drivers/scsi/bnx2i/bnx2i_hwi.c | 3 - drivers/scsi/cxgbi/cxgb3i/cxgb3i.c | 4 +- drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 2 +- drivers/scsi/cxgbi/libcxgbi.c | 4 +- drivers/scsi/device_handler/scsi_dh.c | 10 +- drivers/scsi/device_handler/scsi_dh_alua.c | 3 +- drivers/scsi/fcoe/fcoe.c | 20 +- drivers/scsi/hosts.c | 9 +- drivers/scsi/hpsa.c | 112 +- drivers/scsi/hpsa.h | 2 +- drivers/scsi/ibmvscsi/ibmvscsi.c | 3 - drivers/scsi/ipr.c | 2 +- drivers/scsi/isci/host.c | 3 - drivers/scsi/isci/init.c | 3 +- drivers/scsi/isci/isci.h | 2 +- drivers/scsi/isci/phy.c | 13 - drivers/scsi/isci/port_config.c | 2 +- drivers/scsi/isci/probe_roms.c | 1 + drivers/scsi/isci/registers.h | 12 - drivers/scsi/isci/request.c | 81 +- drivers/scsi/isci/request.h | 3 + drivers/scsi/isci/sas.h | 2 + drivers/scsi/isci/unsolicited_frame_control.c | 2 +- drivers/scsi/isci/unsolicited_frame_control.h | 2 +- drivers/scsi/iscsi_tcp.c | 61 +- drivers/scsi/libfc/fc_rport.c | 14 - drivers/scsi/libiscsi_tcp.c | 14 +- drivers/scsi/libsas/sas_expander.c | 90 +- drivers/scsi/lpfc/lpfc.h | 8 +- drivers/scsi/lpfc/lpfc_attr.c | 147 +- drivers/scsi/lpfc/lpfc_bsg.c | 52 +- drivers/scsi/lpfc/lpfc_crtn.h | 2 - drivers/scsi/lpfc/lpfc_els.c | 103 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 2 +- drivers/scsi/lpfc/lpfc_hw.h | 7 +- drivers/scsi/lpfc/lpfc_hw4.h | 30 +- drivers/scsi/lpfc/lpfc_init.c | 82 +- drivers/scsi/lpfc/lpfc_mbox.c | 2 +- drivers/scsi/lpfc/lpfc_scsi.c | 97 +- drivers/scsi/lpfc/lpfc_sli.c | 106 +- drivers/scsi/lpfc/lpfc_sli4.h | 2 - drivers/scsi/megaraid/megaraid_sas_base.c | 6 +- drivers/scsi/mpt2sas/mpt2sas_base.c | 252 +- drivers/scsi/mpt2sas/mpt2sas_base.h | 60 +- drivers/scsi/mpt2sas/mpt2sas_ctl.c | 10 +- drivers/scsi/mpt2sas/mpt2sas_debug.h | 2 +- drivers/scsi/mpt2sas/mpt2sas_scsih.c | 44 +- drivers/scsi/mpt2sas/mpt2sas_transport.c | 24 +- drivers/scsi/mvsas/mv_94xx.h | 14 +- drivers/scsi/mvsas/mv_sas.h | 2 +- drivers/scsi/osd/osd_uld.c | 4 +- drivers/scsi/pmcraid.c | 3 - drivers/scsi/qla2xxx/qla_init.c | 3 + drivers/scsi/qla2xxx/qla_isr.c | 1 + drivers/scsi/qla2xxx/qla_os.c | 13 +- drivers/scsi/scsi_devinfo.c | 2 - drivers/scsi/scsi_error.c | 24 - drivers/scsi/scsi_lib.c | 36 +- drivers/scsi/scsi_pm.c | 16 - drivers/scsi/scsi_priv.h | 1 - drivers/scsi/scsi_scan.c | 22 +- drivers/scsi/scsi_sysfs.c | 39 +- drivers/scsi/scsi_wait_scan.c | 2 +- drivers/scsi/sd.c | 26 +- drivers/scsi/ses.c | 6 +- drivers/scsi/sr.c | 46 +- drivers/scsi/sr.h | 7 - drivers/scsi/st.c | 4 +- drivers/scsi/sym53c8xx_2/sym_glue.c | 4 - drivers/spi/spi.c | 2 +- drivers/spi/spi_fsl_spi.c | 6 +- drivers/ssb/driver_pcicore.c | 8 +- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/android/Kconfig | 95 - drivers/staging/android/Makefile | 6 - drivers/staging/android/binder.c | 3600 ------- drivers/staging/android/binder.h | 330 - drivers/staging/android/logger.c | 761 -- drivers/staging/android/logger.h | 70 - drivers/staging/android/lowmemorykiller.c | 213 - drivers/staging/android/ram_console.c | 443 - drivers/staging/android/timed_gpio.c | 176 - drivers/staging/android/timed_gpio.h | 33 - drivers/staging/android/timed_output.c | 123 - drivers/staging/android/timed_output.h | 37 - drivers/staging/asus_oled/asus_oled.c | 13 +- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 50 +- drivers/staging/ath6kl/os/linux/cfg80211.c | 31 +- .../ath6kl/os/linux/include/ar6000_drv.h | 9 - .../staging/brcm80211/brcmsmac/wl_mac80211.c | 5 + drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 3 +- drivers/staging/brcm80211/brcmsmac/wlc_bmac.h | 1 - drivers/staging/brcm80211/brcmsmac/wlc_main.c | 8 - drivers/staging/comedi/Kconfig | 1 - drivers/staging/comedi/comedi_fops.c | 126 +- drivers/staging/comedi/comedidev.h | 1 - drivers/staging/comedi/drivers.c | 34 +- drivers/staging/comedi/drivers/amplc_pc236.c | 2 +- drivers/staging/comedi/drivers/comedi_test.c | 2 +- drivers/staging/comedi/drivers/das08.c | 2 +- drivers/staging/comedi/drivers/jr3_pci.c | 2 +- drivers/staging/comedi/drivers/s626.c | 2 +- drivers/staging/comedi/internal.h | 1 - drivers/staging/hv/channel.c | 2 +- drivers/staging/hv/channel_mgmt.c | 2 +- drivers/staging/hv/connection.c | 2 +- drivers/staging/hv/hyperv_storage.h | 1 - drivers/staging/hv/netvsc.c | 4 +- drivers/staging/hv/rndis_filter.c | 6 +- drivers/staging/hv/storvsc.c | 8 +- drivers/staging/hv/storvsc_drv.c | 4 +- drivers/staging/iio/magnetometer/hmc5843.c | 4 +- drivers/staging/lirc/lirc_serial.c | 100 +- drivers/staging/lirc/lirc_sir.c | 60 +- drivers/staging/quatech_usb2/quatech_usb2.c | 9 +- drivers/staging/rtl8192e/r8192E_core.c | 6 - drivers/staging/rtl8192u/r819xU_firmware.c | 9 +- drivers/staging/rtl8712/recv_linux.c | 7 +- drivers/staging/rtl8712/usb_intf.c | 4 - drivers/staging/serqt_usb2/serqt_usb2.c | 3 + drivers/staging/speakup/main.c | 2 +- drivers/staging/speakup/speakup_soft.c | 13 +- drivers/staging/speakup/synth.c | 4 +- drivers/staging/usbip/usbip_common.c | 11 +- drivers/staging/usbip/usbip_common.h | 2 +- drivers/staging/usbip/vhci_hcd.c | 4 +- drivers/staging/usbip/vhci_rx.c | 13 +- drivers/staging/vt6656/bssdb.h | 1 + drivers/staging/vt6656/dpc.c | 6 +- drivers/staging/vt6656/int.h | 1 + drivers/staging/vt6656/iocmd.h | 33 +- drivers/staging/vt6656/iowpa.h | 8 +- drivers/staging/vt6656/key.c | 53 +- drivers/staging/vt6656/key.h | 8 +- drivers/staging/vt6656/mac.c | 6 +- drivers/staging/vt6656/main_usb.c | 2 +- drivers/staging/vt6656/rf.c | 3 - drivers/staging/vt6656/rxtx.c | 56 +- drivers/staging/vt6656/ttype.h | 16 +- drivers/staging/vt6656/wcmd.c | 20 +- drivers/staging/vt6656/wpa2.h | 4 +- drivers/staging/winbond/wbusb.c | 2 +- drivers/switch/Kconfig | 15 - drivers/switch/Makefile | 4 - drivers/switch/switch_class.c | 179 - drivers/switch/switch_gpio.c | 172 - drivers/target/loopback/tcm_loop.c | 24 - drivers/target/target_core_alua.c | 27 +- drivers/target/target_core_cdb.c | 14 +- drivers/target/target_core_configfs.c | 3 +- drivers/target/target_core_pr.c | 5 +- drivers/target/target_core_transport.c | 40 +- drivers/target/tcm_fc/tfc_cmd.c | 6 +- drivers/target/tcm_fc/tfc_sess.c | 17 +- drivers/telephony/ixj.c | 24 +- drivers/tty/amiserial.c | 4 +- drivers/tty/hvc/hvc_console.c | 8 +- drivers/tty/hvc/hvc_dcc.c | 2 - drivers/tty/moxa.c | 2 +- drivers/tty/n_gsm.c | 19 +- drivers/tty/n_tty.c | 3 +- drivers/tty/pty.c | 43 +- drivers/tty/serial/8250.c | 12 +- drivers/tty/serial/8250_pci.c | 25 +- drivers/tty/serial/8250_pnp.c | 3 - drivers/tty/serial/Kconfig | 16 +- drivers/tty/serial/altera_uart.c | 4 +- drivers/tty/serial/amba-pl011.c | 44 +- drivers/tty/serial/atmel_serial.c | 5 +- drivers/tty/serial/clps711x.c | 14 +- drivers/tty/serial/crisv10.c | 4 +- drivers/tty/serial/ifx6x60.c | 1 - drivers/tty/serial/jsm/jsm.h | 7 + drivers/tty/serial/jsm/jsm_driver.c | 2 +- drivers/tty/serial/jsm/jsm_neo.c | 29 +- drivers/tty/serial/jsm/jsm_tty.c | 94 +- drivers/tty/serial/max3107-aava.c | 2 +- drivers/tty/serial/max3107.c | 2 +- drivers/tty/serial/mrst_max3110.c | 2 +- drivers/tty/serial/mxs-auart.c | 2 - drivers/tty/serial/omap-serial.c | 3 +- drivers/tty/serial/pch_uart.c | 41 +- drivers/tty/serial/pxa.c | 20 - drivers/tty/serial/serial_core.c | 6 - drivers/tty/serial/sh-sci.c | 15 +- drivers/tty/tty_io.c | 51 +- drivers/tty/tty_ldisc.c | 30 +- drivers/tty/tty_port.c | 12 +- drivers/tty/vt/consolemap.c | 51 +- drivers/tty/vt/vt_ioctl.c | 1 + drivers/usb/class/cdc-acm.c | 74 +- drivers/usb/class/cdc-wdm.c | 83 +- drivers/usb/class/usbtmc.c | 2 +- drivers/usb/core/config.c | 11 +- drivers/usb/core/devices.c | 2 +- drivers/usb/core/devio.c | 70 +- drivers/usb/core/driver.c | 7 +- drivers/usb/core/hcd-pci.c | 5 +- drivers/usb/core/hcd.c | 19 +- drivers/usb/core/hub.c | 67 +- drivers/usb/core/message.c | 73 +- drivers/usb/core/quirks.c | 61 - drivers/usb/early/ehci-dbgp.c | 2 +- drivers/usb/gadget/Kconfig | 15 +- drivers/usb/gadget/Makefile | 2 - drivers/usb/gadget/android.c | 1349 --- drivers/usb/gadget/composite.c | 62 +- drivers/usb/gadget/dummy_hcd.c | 9 +- drivers/usb/gadget/f_accessory.c | 1176 --- drivers/usb/gadget/f_acm.c | 21 +- drivers/usb/gadget/f_adb.c | 614 -- drivers/usb/gadget/f_audio_source.c | 821 -- drivers/usb/gadget/f_fs.c | 2 +- drivers/usb/gadget/f_loopback.c | 2 +- drivers/usb/gadget/f_mass_storage.c | 4 +- drivers/usb/gadget/f_mtp.c | 1267 --- drivers/usb/gadget/f_phonet.c | 8 +- drivers/usb/gadget/f_rndis.c | 46 +- drivers/usb/gadget/file_storage.c | 2 +- drivers/usb/gadget/fsl_udc_core.c | 20 +- drivers/usb/gadget/hid.c | 6 +- drivers/usb/gadget/inode.c | 2 - drivers/usb/gadget/pch_udc.c | 97 +- drivers/usb/gadget/printer.c | 2 +- drivers/usb/gadget/rndis.c | 11 - drivers/usb/gadget/storage_common.c | 6 - drivers/usb/gadget/u_ether.c | 35 +- drivers/usb/gadget/u_ether.h | 9 +- drivers/usb/gadget/u_serial.c | 6 +- drivers/usb/gadget/uvc.h | 2 +- drivers/usb/gadget/uvc_v4l2.c | 2 +- drivers/usb/host/ehci-dbg.c | 2 +- drivers/usb/host/ehci-fsl.c | 6 +- drivers/usb/host/ehci-fsl.h | 1 - drivers/usb/host/ehci-hcd.c | 49 +- drivers/usb/host/ehci-hub.c | 22 +- drivers/usb/host/ehci-pci.c | 10 +- drivers/usb/host/ehci-q.c | 117 +- drivers/usb/host/ehci-s5p.c | 1 - drivers/usb/host/ehci-sched.c | 54 +- drivers/usb/host/ehci.h | 38 +- drivers/usb/host/fhci-sched.c | 19 +- drivers/usb/host/isp1760-hcd.c | 3 - drivers/usb/host/ohci-hcd.c | 15 +- drivers/usb/host/ohci-hub.c | 5 +- drivers/usb/host/ohci-pci.c | 26 + drivers/usb/host/ohci-q.c | 19 - drivers/usb/host/ohci.h | 1 + drivers/usb/host/pci-quirks.c | 189 +- drivers/usb/host/pci-quirks.h | 2 - drivers/usb/host/uhci-hcd.c | 15 +- drivers/usb/host/uhci-q.c | 2 +- drivers/usb/host/whci/qset.c | 6 +- drivers/usb/host/xhci-ext-caps.h | 5 +- drivers/usb/host/xhci-hub.c | 43 +- drivers/usb/host/xhci-mem.c | 121 +- drivers/usb/host/xhci-pci.c | 24 +- drivers/usb/host/xhci-ring.c | 560 +- drivers/usb/host/xhci.c | 161 +- drivers/usb/host/xhci.h | 33 +- drivers/usb/misc/emi62.c | 2 +- drivers/usb/misc/isight_firmware.c | 6 +- drivers/usb/misc/usbsevseg.c | 2 +- drivers/usb/misc/usbtest.c | 17 +- drivers/usb/misc/yurex.c | 10 +- drivers/usb/mon/mon_bin.c | 2 +- drivers/usb/musb/cppi_dma.c | 26 +- drivers/usb/musb/musb_core.c | 3 +- drivers/usb/musb/musb_gadget.c | 23 - drivers/usb/musb/omap2430.c | 9 +- drivers/usb/otg/Kconfig | 8 - drivers/usb/otg/Makefile | 2 - drivers/usb/otg/otg-wakelock.c | 169 - drivers/usb/otg/otg_id.c | 205 - drivers/usb/serial/ark3116.c | 10 +- drivers/usb/serial/cp210x.c | 170 +- drivers/usb/serial/ftdi_sio.c | 115 +- drivers/usb/serial/ftdi_sio.h | 3 +- drivers/usb/serial/ftdi_sio_ids.h | 118 +- drivers/usb/serial/generic.c | 4 +- drivers/usb/serial/io_ti.c | 10 +- drivers/usb/serial/mct_u232.c | 27 +- drivers/usb/serial/mos7840.c | 125 +- drivers/usb/serial/omninet.c | 2 +- drivers/usb/serial/opticon.c | 11 +- drivers/usb/serial/option.c | 842 +- drivers/usb/serial/pl2303.c | 29 +- drivers/usb/serial/pl2303.h | 5 - drivers/usb/serial/qcaux.c | 5 +- drivers/usb/serial/qcserial.c | 116 +- drivers/usb/serial/sierra.c | 35 +- drivers/usb/serial/ti_usb_3410_5052.c | 8 +- drivers/usb/serial/ti_usb_3410_5052.h | 5 - drivers/usb/serial/usb-serial.c | 20 +- drivers/usb/serial/whiteheat.c | 1 - drivers/usb/storage/Kconfig | 2 +- drivers/usb/storage/initializers.c | 76 +- drivers/usb/storage/initializers.h | 4 +- drivers/usb/storage/protocol.c | 7 +- drivers/usb/storage/transport.c | 34 +- drivers/usb/storage/unusual_devs.h | 359 +- drivers/usb/storage/usb.c | 92 +- drivers/usb/storage/usb.h | 7 +- drivers/usb/storage/usual-tables.c | 15 - drivers/uwb/hwa-rc.c | 3 +- drivers/uwb/neh.c | 12 +- drivers/vhost/net.c | 3 +- drivers/vhost/vhost.c | 2 - drivers/video/Kconfig | 2 - drivers/video/atmel_lcdfb.c | 2 +- drivers/video/backlight/tosa_lcd.c | 2 +- drivers/video/carminefb.c | 6 +- drivers/video/console/fbcon.c | 9 +- drivers/video/fbmem.c | 21 +- drivers/video/fbsysfs.c | 3 - drivers/video/mxsfb.c | 3 +- drivers/video/offb.c | 52 +- drivers/video/omap2/dss/hdmi.c | 86 +- drivers/video/riva/fbdev.c | 5 +- drivers/video/savage/savagefb.h | 2 +- drivers/video/sh_mobile_hdmi.c | 47 +- drivers/video/udlfb.c | 4 +- drivers/video/uvesafb.c | 11 +- drivers/video/via/share.h | 4 +- drivers/video/via/via_clock.c | 19 - drivers/video/via/via_modesetting.h | 5 - drivers/video/via/viafbdev.c | 16 +- drivers/virtio/virtio_pci.c | 11 +- drivers/virtio/virtio_ring.c | 7 - drivers/w1/slaves/w1_ds2780.c | 48 +- drivers/w1/slaves/w1_ds2780.h | 2 - drivers/watchdog/hpwdt.c | 9 +- drivers/watchdog/shwdt.c | 2 +- drivers/xen/events.c | 2 +- drivers/xen/gntalloc.c | 4 +- drivers/xen/gntdev.c | 2 +- drivers/xen/swiotlb-xen.c | 9 +- drivers/xen/xenbus/xenbus_probe_frontend.c | 69 +- drivers/xen/xenbus/xenbus_xs.c | 6 - drivers/zorro/zorro.c | 7 +- fs/9p/acl.c | 22 +- fs/9p/acl.h | 6 +- fs/9p/cache.c | 20 +- fs/9p/cache.h | 9 + fs/9p/v9fs.c | 45 +- fs/9p/v9fs.h | 29 +- fs/9p/v9fs_vfs.h | 6 +- fs/9p/vfs_file.c | 36 +- fs/9p/vfs_inode.c | 177 +- fs/9p/vfs_inode_dotl.c | 162 +- fs/9p/vfs_super.c | 2 +- fs/Kconfig | 4 - fs/Makefile | 3 - fs/afs/internal.h | 2 +- fs/afs/rxrpc.c | 3 - fs/aio.c | 52 +- fs/autofs4/autofs_i.h | 11 - fs/autofs4/dev-ioctl.c | 2 +- fs/autofs4/inode.c | 2 +- fs/autofs4/root.c | 6 +- fs/autofs4/waitq.c | 2 +- fs/befs/linuxvfs.c | 23 +- fs/binfmt_elf.c | 32 +- fs/binfmt_misc.c | 5 +- fs/binfmt_script.c | 4 +- fs/block_dev.c | 42 +- fs/btrfs/async-thread.c | 9 +- fs/btrfs/ctree.h | 2 +- fs/btrfs/disk-io.c | 5 +- fs/btrfs/extent-tree.c | 12 +- fs/btrfs/inode.c | 5 +- fs/btrfs/tree-log.c | 34 +- fs/btrfs/volumes.c | 17 - fs/btrfs/volumes.h | 2 - fs/buffer.c | 50 +- fs/ceph/export.c | 18 +- fs/cifs/cifs_dfs_ref.c | 2 - fs/cifs/cifsfs.c | 6 - fs/cifs/cifsglob.h | 1 - fs/cifs/cifssmb.c | 3 +- fs/cifs/connect.c | 14 +- fs/cifs/dir.c | 26 +- fs/cifs/file.c | 57 +- fs/cifs/inode.c | 33 +- fs/cifs/readdir.c | 7 +- fs/cifs/sess.c | 7 +- fs/cifs/transport.c | 2 - fs/compat.c | 10 +- fs/compat_ioctl.c | 2 - fs/dcache.c | 98 +- fs/ecryptfs/crypto.c | 53 +- fs/ecryptfs/file.c | 23 +- fs/ecryptfs/inode.c | 56 +- fs/ecryptfs/keystore.c | 47 +- fs/ecryptfs/kthread.c | 2 +- fs/ecryptfs/main.c | 46 +- fs/ecryptfs/miscdev.c | 104 +- fs/ecryptfs/read_write.c | 41 +- fs/eventpoll.c | 315 +- fs/exec.c | 17 - fs/ext3/ialloc.c | 8 +- fs/ext3/inode.c | 41 +- fs/ext3/namei.c | 6 +- fs/ext3/xattr.c | 12 +- fs/ext4/acl.c | 6 +- fs/ext4/balloc.c | 3 +- fs/ext4/bitmap.c | 8 +- fs/ext4/ext4.h | 7 +- fs/ext4/ext4_jbd2.h | 56 +- fs/ext4/extents.c | 37 +- fs/ext4/ialloc.c | 11 +- fs/ext4/inode.c | 100 +- fs/ext4/ioctl.c | 13 +- fs/ext4/mballoc.c | 8 +- fs/ext4/move_extent.c | 7 +- fs/ext4/namei.c | 16 +- fs/ext4/page-io.c | 36 +- fs/ext4/super.c | 34 +- fs/ext4/xattr.c | 13 +- fs/fat/dir.c | 9 - fs/fat/fat.h | 1 - fs/fat/inode.c | 9 - fs/fifo.c | 9 +- fs/fs-writeback.c | 28 +- fs/fuse/dev.c | 26 +- fs/fuse/dir.c | 1 - fs/fuse/file.c | 2 +- fs/fuse/fuse_i.h | 3 - fs/fuse/inode.c | 17 +- fs/gfs2/export.c | 4 - fs/gfs2/lops.c | 18 +- fs/gfs2/ops_fstype.c | 4 +- fs/gfs2/trans.c | 8 - fs/hfs/btree.c | 20 +- fs/hfs/trans.c | 2 - fs/hfsplus/catalog.c | 4 - fs/hfsplus/dir.c | 11 - fs/hfsplus/hfsplus_fs.h | 16 +- fs/hfsplus/part_tbl.c | 32 +- fs/hfsplus/super.c | 16 +- fs/hfsplus/wrapper.c | 87 +- fs/hppfs/hppfs.c | 1 - fs/hugetlbfs/inode.c | 28 +- fs/isofs/export.c | 2 +- fs/jbd/commit.c | 45 +- fs/jbd/journal.c | 8 - fs/jbd/transaction.c | 66 +- fs/jbd2/commit.c | 4 +- fs/jbd2/journal.c | 8 - fs/jbd2/transaction.c | 5 +- fs/jffs2/gc.c | 2 +- fs/jffs2/nodemgmt.c | 6 +- fs/lockd/clnt4xdr.c | 2 +- fs/lockd/clntxdr.c | 4 +- fs/lockd/svc.c | 2 +- fs/lockd/svcproc.c | 3 +- fs/locks.c | 6 +- fs/namei.c | 61 +- fs/namespace.c | 26 +- fs/nfs/callback.h | 2 +- fs/nfs/callback_proc.c | 27 +- fs/nfs/callback_xdr.c | 24 +- fs/nfs/client.c | 3 +- fs/nfs/delegation.c | 27 +- fs/nfs/delegation.h | 1 - fs/nfs/dir.c | 73 +- fs/nfs/dns_resolve.c | 5 +- fs/nfs/file.c | 39 +- fs/nfs/inode.c | 4 +- fs/nfs/internal.h | 7 +- fs/nfs/mount_clnt.c | 2 +- fs/nfs/namespace.c | 19 +- fs/nfs/nfs3proc.c | 5 +- fs/nfs/nfs4_fs.h | 3 - fs/nfs/nfs4filelayout.c | 10 +- fs/nfs/nfs4namespace.c | 3 +- fs/nfs/nfs4proc.c | 82 +- fs/nfs/nfs4state.c | 35 +- fs/nfs/nfs4xdr.c | 5 +- fs/nfs/objlayout/objio_osd.c | 31 +- fs/nfs/objlayout/objlayout.c | 10 +- fs/nfs/objlayout/pnfs_osd_xdr_cli.c | 3 - fs/nfs/pnfs.c | 78 +- fs/nfs/pnfs.h | 7 +- fs/nfs/proc.c | 1 - fs/nfs/super.c | 61 +- fs/nfs/write.c | 45 +- fs/nfsd/export.c | 8 +- fs/nfsd/nfs3xdr.c | 22 +- fs/nfsd/nfs4proc.c | 13 +- fs/nfsd/nfs4recover.c | 2 +- fs/nfsd/nfs4state.c | 115 +- fs/nfsd/nfs4xdr.c | 25 +- fs/nfsd/state.h | 6 + fs/nfsd/vfs.c | 3 +- fs/nfsd/vfs.h | 1 - fs/nilfs2/gcinode.c | 2 - fs/nilfs2/ioctl.c | 22 +- fs/nilfs2/segment.c | 2 - fs/nilfs2/super.c | 3 - fs/nilfs2/the_nilfs.c | 2 - fs/nilfs2/the_nilfs.h | 2 - fs/notify/fanotify/fanotify.c | 1 - fs/notify/mark.c | 8 +- fs/ocfs2/alloc.c | 2 +- fs/ocfs2/refcounttree.c | 12 +- fs/ocfs2/suballoc.c | 4 +- fs/open.c | 13 +- fs/partitions/check.c | 59 +- fs/pipe.c | 31 +- fs/proc/base.c | 294 +- fs/proc/meminfo.c | 7 +- fs/proc/namespaces.c | 2 +- fs/proc/task_mmu.c | 95 +- fs/proc/uptime.c | 9 +- fs/quota/quota.c | 2 +- fs/ramfs/file-nommu.c | 1 - fs/reiserfs/inode.c | 16 +- fs/reiserfs/stree.c | 4 - fs/reiserfs/super.c | 87 +- fs/seq_file.c | 6 +- fs/signalfd.c | 15 - fs/splice.c | 7 +- fs/squashfs/super.c | 2 +- fs/stat.c | 7 +- fs/statfs.c | 2 +- fs/super.c | 2 - fs/sysfs/dir.c | 16 +- fs/sysfs/inode.c | 11 +- fs/ubifs/debug.h | 17 +- fs/ubifs/find.c | 12 +- fs/ubifs/lprops.c | 6 - fs/ubifs/sb.c | 8 +- fs/ubifs/ubifs.h | 3 - fs/udf/file.c | 43 +- fs/udf/inode.c | 32 +- fs/udf/super.c | 109 +- fs/xfs/linux-2.6/xfs_acl.c | 4 +- fs/xfs/linux-2.6/xfs_buf.h | 1 + fs/xfs/linux-2.6/xfs_discard.c | 4 +- fs/xfs/linux-2.6/xfs_export.c | 11 +- fs/xfs/linux-2.6/xfs_file.c | 34 +- fs/xfs/linux-2.6/xfs_iops.c | 16 +- fs/xfs/linux-2.6/xfs_linux.h | 2 - fs/xfs/linux-2.6/xfs_super.c | 102 +- fs/xfs/linux-2.6/xfs_sync.c | 48 - fs/xfs/linux-2.6/xfs_sync.h | 2 - fs/xfs/quota/xfs_dquot_item.c | 10 +- fs/xfs/quota/xfs_qm.c | 3 +- fs/xfs/xfs_attr.c | 14 +- fs/xfs/xfs_attr_leaf.c | 64 +- fs/xfs/xfs_bmap.c | 10 +- fs/xfs/xfs_buf_item.c | 4 +- fs/xfs/xfs_iget.c | 18 +- fs/xfs/xfs_inode.c | 29 +- fs/xfs/xfs_inode.h | 1 - fs/xfs/xfs_inode_item.c | 10 +- fs/xfs/xfs_log_recover.c | 35 +- fs/xfs/xfs_mount.c | 29 +- fs/xfs/xfs_trans.c | 27 +- fs/xfs/xfs_trans.h | 2 +- fs/xfs/xfs_trans_ail.c | 192 +- fs/xfs/xfs_trans_priv.h | 18 +- fs/xfs/xfs_vnodeops.c | 15 +- fs/yaffs2/Kconfig | 161 - fs/yaffs2/Makefile | 17 - fs/yaffs2/yaffs_allocator.c | 396 - fs/yaffs2/yaffs_allocator.h | 30 - fs/yaffs2/yaffs_attribs.c | 124 - fs/yaffs2/yaffs_attribs.h | 28 - fs/yaffs2/yaffs_bitmap.c | 98 - fs/yaffs2/yaffs_bitmap.h | 33 - fs/yaffs2/yaffs_checkptrw.c | 415 - fs/yaffs2/yaffs_checkptrw.h | 33 - fs/yaffs2/yaffs_ecc.c | 298 - fs/yaffs2/yaffs_ecc.h | 44 - fs/yaffs2/yaffs_getblockinfo.h | 35 - fs/yaffs2/yaffs_guts.c | 5164 ---------- fs/yaffs2/yaffs_guts.h | 915 -- fs/yaffs2/yaffs_linux.h | 41 - fs/yaffs2/yaffs_mtdif.c | 54 - fs/yaffs2/yaffs_mtdif.h | 23 - fs/yaffs2/yaffs_mtdif1.c | 330 - fs/yaffs2/yaffs_mtdif1.h | 29 - fs/yaffs2/yaffs_mtdif2.c | 225 - fs/yaffs2/yaffs_mtdif2.h | 29 - fs/yaffs2/yaffs_nameval.c | 201 - fs/yaffs2/yaffs_nameval.h | 28 - fs/yaffs2/yaffs_nand.c | 127 - fs/yaffs2/yaffs_nand.h | 38 - fs/yaffs2/yaffs_packedtags1.c | 53 - fs/yaffs2/yaffs_packedtags1.h | 39 - fs/yaffs2/yaffs_packedtags2.c | 196 - fs/yaffs2/yaffs_packedtags2.h | 47 - fs/yaffs2/yaffs_tagscompat.c | 422 - fs/yaffs2/yaffs_tagscompat.h | 36 - fs/yaffs2/yaffs_tagsvalidity.c | 27 - fs/yaffs2/yaffs_tagsvalidity.h | 23 - fs/yaffs2/yaffs_trace.h | 57 - fs/yaffs2/yaffs_verify.c | 535 - fs/yaffs2/yaffs_verify.h | 43 - fs/yaffs2/yaffs_vfs.c | 2792 ------ fs/yaffs2/yaffs_yaffs1.c | 433 - fs/yaffs2/yaffs_yaffs1.h | 22 - fs/yaffs2/yaffs_yaffs2.c | 1598 --- fs/yaffs2/yaffs_yaffs2.h | 39 - fs/yaffs2/yportenv.h | 70 - include/acpi/acpi_numa.h | 1 - include/asm-generic/mutex-xchg.h | 11 +- include/asm-generic/pgtable.h | 79 - include/asm-generic/poll.h | 2 - include/asm-generic/statfs.h | 2 +- include/asm-generic/tlb.h | 9 - include/asm-generic/unistd.h | 2 +- include/drm/drmP.h | 1 - include/drm/drm_crtc.h | 1 - include/drm/drm_dp_helper.h | 3 - include/drm/drm_mode.h | 2 - include/drm/drm_pciids.h | 22 - include/drm/i915_drm.h | 2 +- include/linux/Kbuild | 1 - include/linux/akm8975.h | 87 - include/linux/amba/mmci.h | 12 - include/linux/android_aid.h | 28 - include/linux/android_alarm.h | 106 - include/linux/ashmem.h | 48 - include/linux/binfmts.h | 1 - include/linux/bitops.h | 20 - include/linux/blkdev.h | 6 +- include/linux/cgroup.h | 14 +- include/linux/compat.h | 4 - include/linux/compiler-gcc.h | 5 - include/linux/cpu.h | 12 +- include/linux/cpuacct.h | 43 - include/linux/cpufreq.h | 3 - include/linux/cpuset.h | 47 +- include/linux/cryptohash.h | 5 - include/linux/dcache.h | 6 +- include/linux/earlysuspend.h | 56 - include/linux/efi.h | 13 +- include/linux/eventpoll.h | 1 - include/linux/ext2_fs.h | 4 +- include/linux/ext3_fs.h | 4 +- include/linux/fb.h | 1 - include/linux/firewire-cdev.h | 3 - include/linux/fs.h | 14 +- include/linux/ftrace.h | 7 +- include/linux/genhd.h | 7 +- include/linux/gpio_event.h | 170 - include/linux/hid.h | 4 - include/linux/hrtimer.h | 10 +- include/linux/i2c/twl4030-madc.h | 4 - include/linux/if.h | 2 - include/linux/if_link.h | 1 - include/linux/if_pppolac.h | 33 - include/linux/if_pppopns.h | 32 - include/linux/if_pppox.h | 27 +- include/linux/init_task.h | 20 +- include/linux/input.h | 3 - include/linux/interrupt.h | 3 - include/linux/io-mapping.h | 4 - include/linux/ion.h | 344 - include/linux/irqdesc.h | 1 + include/linux/jiffies.h | 2 +- include/linux/kernel.h | 16 - include/linux/keychord.h | 52 - include/linux/keyreset.h | 28 - include/linux/kgdb.h | 7 +- include/linux/kobject.h | 2 +- include/linux/ktime.h | 7 + include/linux/kvm_host.h | 6 - include/linux/lglock.h | 36 +- include/linux/log2.h | 1 + include/linux/math64.h | 4 - include/linux/memcontrol.h | 9 +- include/linux/memory.h | 2 +- include/linux/mempolicy.h | 18 +- include/linux/mfd/ezx-pcap.h | 1 - include/linux/mfd/wm8994/pdata.h | 2 +- include/linux/migrate.h | 23 +- include/linux/mm.h | 78 +- include/linux/mm_types.h | 22 +- include/linux/mmc/host.h | 37 - include/linux/mmc/mmc.h | 10 - include/linux/mmc/pm.h | 1 - include/linux/mmc/sdio_func.h | 10 - include/linux/mmzone.h | 16 +- include/linux/msdos_fs.h | 12 - include/linux/namei.h | 2 - include/linux/netdevice.h | 16 +- include/linux/netfilter/xt_IDLETIMER.h | 8 - include/linux/netfilter/xt_qtaguid.h | 13 - include/linux/netfilter/xt_quota2.h | 25 - include/linux/netfilter/xt_socket.h | 6 - include/linux/netlink.h | 7 +- include/linux/nfs_fs.h | 11 +- include/linux/nfs_xdr.h | 3 +- include/linux/nl80211.h | 310 +- include/linux/page-flags.h | 8 +- include/linux/pci-aspm.h | 4 +- include/linux/pci.h | 1 - include/linux/pci_ids.h | 4 +- include/linux/pci_regs.h | 2 +- include/linux/pda_power.h | 2 - include/linux/perf_event.h | 2 +- include/linux/personality.h | 1 - include/linux/phy.h | 2 +- include/linux/pipe_fs_i.h | 1 - include/linux/platform_data/ram_console.h | 22 - include/linux/plist.h | 55 +- include/linux/power_supply.h | 4 - include/linux/proportions.h | 4 - include/linux/ptp_classify.h | 13 +- include/linux/random.h | 30 +- include/linux/regset.h | 10 +- include/linux/rio_regs.h | 18 +- include/linux/rtc.h | 3 - include/linux/rtmutex.h | 4 +- include/linux/rtnetlink.h | 3 - include/linux/sched.h | 11 +- include/linux/seqlock.h | 2 +- include/linux/serial_core.h | 1 - include/linux/sigma.h | 13 +- include/linux/signalfd.h | 5 +- include/linux/skbuff.h | 19 +- include/linux/snmp.h | 3 +- include/linux/socket.h | 2 +- include/linux/sockios.h | 1 - include/linux/stop_machine.h | 2 - include/linux/sunrpc/cache.h | 16 - include/linux/sunrpc/svcsock.h | 2 +- include/linux/sw_sync.h | 58 - include/linux/swap.h | 7 +- include/linux/switch.h | 53 - include/linux/synaptics_i2c_rmi.h | 55 - include/linux/sync.h | 390 - include/linux/syslog.h | 6 - include/linux/time.h | 29 +- include/linux/timex.h | 2 +- include/linux/tty.h | 6 +- include/linux/tty_driver.h | 3 - include/linux/uhid.h | 104 - include/linux/uid_stat.h | 29 - include/linux/usb.h | 22 - include/linux/usb/ch11.h | 10 +- include/linux/usb/ch9.h | 20 +- include/linux/usb/composite.h | 3 - include/linux/usb/f_accessory.h | 146 - include/linux/usb/f_mtp.h | 75 - include/linux/usb/hcd.h | 2 +- include/linux/usb/otg_id.h | 58 - include/linux/usb/usbnet.h | 3 +- include/linux/videodev2.h | 1 - include/linux/vmalloc.h | 1 - include/linux/wakelock.h | 91 - include/linux/wifi_tiwlan.h | 27 - include/linux/wl127x-rfkill.h | 35 - include/linux/wlan_plat.h | 27 - include/linux/workqueue.h | 4 - include/linux/writeback.h | 1 - include/linux/xfrm.h | 2 - include/net/9p/9p.h | 29 - include/net/activity_stats.h | 25 - include/net/addrconf.h | 2 +- include/net/arp.h | 1 - include/net/bluetooth/bluetooth.h | 27 +- include/net/bluetooth/hci.h | 87 +- include/net/bluetooth/hci_core.h | 101 +- include/net/bluetooth/l2cap.h | 121 +- include/net/bluetooth/mgmt.h | 12 - include/net/bluetooth/rfcomm.h | 9 +- include/net/bluetooth/sco.h | 4 +- include/net/bluetooth/smp.h | 47 - include/net/cfg80211.h | 186 +- include/net/cipso_ipv4.h | 29 +- include/net/dst.h | 28 +- include/net/flow.h | 35 +- include/net/if_inet6.h | 1 - include/net/inet_sock.h | 2 - include/net/ip_vs.h | 2 +- include/net/ipv6.h | 12 +- include/net/netfilter/nf_conntrack_ecache.h | 1 - include/net/netns/generic.h | 1 - include/net/route.h | 4 - include/net/rtnetlink.h | 7 +- include/net/sch_generic.h | 12 +- include/net/sctp/sctp.h | 13 - include/net/sctp/structs.h | 4 - include/net/secure_seq.h | 20 - include/net/sock.h | 2 - include/net/tcp.h | 3 - include/net/transp_v6.h | 2 - include/net/xfrm.h | 3 - include/sound/core.h | 3 - include/target/target_core_base.h | 1 - include/trace/events/cpufreq_interactive.h | 112 - include/trace/events/kmem.h | 4 +- include/trace/events/random.h | 134 - include/trace/events/vmscan.h | 85 +- include/trace/events/writeback.h | 5 +- include/video/omapdss.h | 5 - include/xen/interface/io/xs_wire.h | 3 - include/xen/interface/xen.h | 39 - init/Kconfig | 15 - init/do_mounts.c | 37 +- init/main.c | 7 +- ipc/mqueue.c | 125 +- ipc/sem.c | 13 +- kernel/async.c | 13 +- kernel/audit_tree.c | 11 +- kernel/cgroup.c | 228 +- kernel/cgroup_freezer.c | 11 +- kernel/compat.c | 63 +- kernel/cpu.c | 94 - kernel/cpuset.c | 66 +- kernel/cred.c | 2 - kernel/debug/debug_core.c | 53 +- kernel/events/core.c | 69 +- kernel/exit.c | 25 +- kernel/fork.c | 29 +- kernel/futex.c | 205 +- kernel/futex_compat.c | 36 +- kernel/hrtimer.c | 59 +- kernel/hung_task.c | 14 +- kernel/irq/autoprobe.c | 4 +- kernel/irq/chip.c | 47 +- kernel/irq/generic-chip.c | 4 +- kernel/irq/handle.c | 7 +- kernel/irq/internals.h | 2 +- kernel/irq/manage.c | 93 +- kernel/irq/migration.c | 10 +- kernel/irq/pm.c | 55 +- kernel/irq/spurious.c | 6 +- kernel/jump_label.c | 3 +- kernel/kmod.c | 4 +- kernel/kprobes.c | 8 +- kernel/module.c | 7 +- kernel/panic.c | 25 +- kernel/pm_qos_params.c | 6 +- kernel/posix-cpu-timers.c | 12 +- kernel/power/Kconfig | 74 - kernel/power/Makefile | 6 - kernel/power/consoleearlysuspend.c | 78 - kernel/power/earlysuspend.c | 187 - kernel/power/fbearlysuspend.c | 153 - kernel/power/hibernate.c | 13 +- kernel/power/main.c | 20 - kernel/power/power.h | 24 - kernel/power/process.c | 27 +- kernel/power/suspend.c | 8 +- kernel/power/suspend_time.c | 111 - kernel/power/userwakelock.c | 219 - kernel/power/wakelock.c | 634 -- kernel/printk.c | 77 +- kernel/rcutree.c | 4 +- kernel/relay.c | 10 +- kernel/resource.c | 57 +- kernel/rtmutex.c | 2 +- kernel/sched.c | 300 +- kernel/sched_autogroup.c | 4 + kernel/sched_autogroup.h | 5 + kernel/sched_rt.c | 9 +- kernel/signal.c | 4 +- kernel/smp.c | 13 +- kernel/stop_machine.c | 2 +- kernel/sys.c | 41 - kernel/sysctl.c | 16 +- kernel/sysctl_binary.c | 2 +- kernel/taskstats.c | 1 - kernel/time.c | 2 +- kernel/time/Makefile | 2 +- kernel/time/alarmtimer.c | 20 +- kernel/time/clocksource.c | 4 +- kernel/time/ntp.c | 130 +- kernel/time/tick-broadcast.c | 2 +- kernel/time/tick-sched.c | 4 +- kernel/time/timekeeping.c | 157 +- kernel/timer.c | 10 +- kernel/trace/ftrace.c | 122 +- kernel/trace/ring_buffer.c | 2 - kernel/trace/trace.c | 6 +- kernel/trace/trace.h | 1 - kernel/trace/trace_entries.h | 16 +- kernel/trace/trace_events.c | 112 +- kernel/trace/trace_events_filter.c | 12 +- kernel/trace/trace_export.c | 2 +- kernel/trace/trace_functions.c | 3 +- kernel/watchdog.c | 4 +- kernel/workqueue.c | 105 +- lib/Kconfig.debug | 3 +- lib/Makefile | 2 +- lib/btree.c | 4 +- lib/gcd.c | 3 - lib/genalloc.c | 2 +- lib/kobject_uevent.c | 21 +- lib/md5.c | 95 - lib/nlattr.c | 1 - lib/plist.c | 7 +- lib/xz/xz_dec_bcj.c | 27 +- lib/xz/xz_private.h | 2 +- mm/Makefile | 1 - mm/ashmem.c | 748 -- mm/backing-dev.c | 9 - mm/bootmem.c | 5 +- mm/compaction.c | 61 +- mm/dmapool.c | 31 +- mm/filemap.c | 44 +- mm/filemap_xip.c | 7 +- mm/huge_memory.c | 50 +- mm/hugetlb.c | 75 +- mm/internal.h | 46 - mm/madvise.c | 16 +- mm/memcontrol.c | 67 +- mm/memory-failure.c | 14 +- mm/memory.c | 99 +- mm/memory_hotplug.c | 18 +- mm/mempolicy.c | 236 +- mm/migrate.c | 248 +- mm/mincore.c | 2 +- mm/mmu_notifier.c | 45 +- mm/nobootmem.c | 3 +- mm/nommu.c | 9 +- mm/oom_kill.c | 6 +- mm/page-writeback.c | 4 +- mm/page_alloc.c | 226 +- mm/pagewalk.c | 2 +- mm/percpu-vm.c | 12 +- mm/percpu.c | 50 +- mm/rmap.c | 21 +- mm/shmem.c | 43 +- mm/slab.c | 13 +- mm/slub.c | 49 +- mm/sparse.c | 40 +- mm/swap.c | 85 +- mm/swap_state.c | 2 +- mm/swapfile.c | 4 +- mm/truncate.c | 3 +- mm/vmalloc.c | 93 +- mm/vmscan.c | 327 +- mm/vmstat.c | 2 +- net/8021q/vlan_core.c | 5 +- net/8021q/vlan_dev.c | 4 +- net/9p/client.c | 13 +- net/9p/trans_virtio.c | 17 +- net/Kconfig | 16 +- net/Makefile | 1 - net/activity_stats.c | 115 - net/atm/br2684.c | 9 +- net/atm/clip.c | 16 +- net/atm/common.c | 1 - net/atm/pvc.c | 1 - net/ax25/af_ax25.c | 9 +- net/bluetooth/Kconfig | 9 - net/bluetooth/Makefile | 2 +- net/bluetooth/af_bluetooth.c | 44 +- net/bluetooth/bnep/bnep.h | 1 - net/bluetooth/bnep/core.c | 13 +- net/bluetooth/bnep/netdev.c | 1 - net/bluetooth/cmtp/capi.c | 3 +- net/bluetooth/hci_conn.c | 136 +- net/bluetooth/hci_core.c | 275 +- net/bluetooth/hci_event.c | 330 +- net/bluetooth/hci_sock.c | 72 +- net/bluetooth/hidp/core.c | 21 +- net/bluetooth/l2cap_core.c | 1043 +- net/bluetooth/l2cap_sock.c | 473 +- net/bluetooth/lib.c | 23 +- net/bluetooth/mgmt.c | 283 +- net/bluetooth/rfcomm/core.c | 18 +- net/bluetooth/rfcomm/sock.c | 34 +- net/bluetooth/rfcomm/tty.c | 2 +- net/bluetooth/sco.c | 86 +- net/bluetooth/smp.c | 702 -- net/bridge/br_device.c | 14 +- net/bridge/br_if.c | 16 +- net/bridge/br_multicast.c | 109 +- net/bridge/br_netfilter.c | 9 +- net/bridge/br_netlink.c | 18 +- net/bridge/br_private.h | 7 +- net/bridge/br_stp.c | 4 +- net/caif/caif_dev.c | 16 +- net/caif/cfcnfg.c | 1 + net/can/bcm.c | 56 +- net/core/Makefile | 2 +- net/core/dev.c | 105 +- net/core/dev_addr_lists.c | 3 +- net/core/drop_monitor.c | 113 +- net/core/dst.c | 15 +- net/core/ethtool.c | 5 +- net/core/fib_rules.c | 10 +- net/core/flow.c | 31 +- net/core/link_watch.c | 2 +- net/core/neighbour.c | 46 +- net/core/net_namespace.c | 68 +- net/core/netpoll.c | 13 +- net/core/pktgen.c | 29 +- net/core/rtnetlink.c | 136 +- net/core/scm.c | 2 +- net/core/secure_seq.c | 184 - net/core/skbuff.c | 4 +- net/core/sock.c | 12 +- net/core/timestamping.c | 12 +- net/dcb/dcbnl.c | 4 +- net/dccp/ccid.h | 4 +- net/dccp/ccids/ccid3.c | 1 - net/dccp/ipv4.c | 1 - net/dccp/ipv6.c | 9 +- net/decnet/dn_dev.c | 6 +- net/decnet/dn_fib.c | 4 +- net/decnet/dn_neigh.c | 8 +- net/decnet/dn_route.c | 23 +- net/ethernet/eth.c | 1 - net/ipv4/Makefile | 1 - net/ipv4/af_inet.c | 18 - net/ipv4/ah4.c | 8 +- net/ipv4/arp.c | 31 +- net/ipv4/cipso_ipv4.c | 6 +- net/ipv4/devinet.c | 35 +- net/ipv4/esp4.c | 24 +- net/ipv4/fib_frontend.c | 6 +- net/ipv4/fib_semantics.c | 22 +- net/ipv4/fib_trie.c | 2 - net/ipv4/gre.c | 21 +- net/ipv4/icmp.c | 14 +- net/ipv4/igmp.c | 6 +- net/ipv4/inet_diag.c | 2 +- net/ipv4/inet_hashtables.c | 1 - net/ipv4/inetpeer.c | 1 - net/ipv4/ip_forward.c | 2 +- net/ipv4/ip_gre.c | 2 +- net/ipv4/ip_options.c | 4 +- net/ipv4/ip_output.c | 28 +- net/ipv4/ip_sockglue.c | 35 +- net/ipv4/ipconfig.c | 4 - net/ipv4/ipip.c | 7 +- net/ipv4/ipmr.c | 19 +- net/ipv4/netfilter.c | 18 +- net/ipv4/netfilter/Kconfig | 12 - net/ipv4/netfilter/ipt_REJECT.c | 8 - .../netfilter/nf_conntrack_l3proto_ipv4.c | 8 - net/ipv4/netfilter/nf_nat_proto_common.c | 1 - net/ipv4/netfilter/nf_nat_sip.c | 10 +- net/ipv4/netfilter/nf_nat_standalone.c | 6 +- net/ipv4/proc.c | 3 +- net/ipv4/raw.c | 14 +- net/ipv4/route.c | 238 +- net/ipv4/syncookies.c | 32 +- net/ipv4/sysctl_net_ipv4.c | 7 - net/ipv4/sysfs_net_ipv4.c | 88 - net/ipv4/tcp.c | 162 +- net/ipv4/tcp_cong.c | 3 +- net/ipv4/tcp_illinois.c | 8 +- net/ipv4/tcp_input.c | 172 +- net/ipv4/tcp_ipv4.c | 30 +- net/ipv4/tcp_output.c | 27 +- net/ipv4/xfrm4_mode_beet.c | 5 +- net/ipv4/xfrm4_mode_tunnel.c | 6 +- net/ipv4/xfrm4_policy.c | 14 +- net/ipv6/addrconf.c | 95 +- net/ipv6/addrlabel.c | 9 +- net/ipv6/af_inet6.c | 36 - net/ipv6/ah6.c | 8 +- net/ipv6/esp6.c | 18 +- net/ipv6/inet6_hashtables.c | 1 - net/ipv6/ip6_fib.c | 5 +- net/ipv6/ip6_output.c | 148 +- net/ipv6/ip6_tunnel.c | 8 +- net/ipv6/ip6mr.c | 11 +- net/ipv6/ipv6_sockglue.c | 10 +- net/ipv6/mcast.c | 5 +- net/ipv6/mip6.c | 20 +- net/ipv6/ndisc.c | 7 +- net/ipv6/netfilter/Kconfig | 12 - net/ipv6/netfilter/ip6_tables.c | 14 +- net/ipv6/netfilter/ip6t_REJECT.c | 9 - net/ipv6/raw.c | 21 +- net/ipv6/route.c | 130 +- net/ipv6/sit.c | 11 +- net/ipv6/syncookies.c | 2 +- net/ipv6/tcp_ipv6.c | 21 +- net/ipv6/udp.c | 4 +- net/ipv6/xfrm6_mode_beet.c | 6 +- net/ipv6/xfrm6_mode_tunnel.c | 6 +- net/l2tp/l2tp_core.c | 7 +- net/l2tp/l2tp_core.h | 1 - net/l2tp/l2tp_eth.c | 7 +- net/l2tp/l2tp_ip.c | 38 +- net/l2tp/l2tp_ppp.c | 2 +- net/llc/af_llc.c | 17 +- net/mac80211/agg-rx.c | 3 +- net/mac80211/agg-tx.c | 127 +- net/mac80211/cfg.c | 2 +- net/mac80211/ibss.c | 10 +- net/mac80211/ieee80211_i.h | 8 +- net/mac80211/iface.c | 13 - net/mac80211/main.c | 4 +- net/mac80211/mesh.c | 1 - net/mac80211/mlme.c | 21 +- net/mac80211/offchannel.c | 33 +- net/mac80211/rate.c | 2 +- net/mac80211/rx.c | 32 +- net/mac80211/scan.c | 6 +- net/mac80211/sta_info.c | 5 +- net/mac80211/status.c | 2 +- net/mac80211/tx.c | 3 +- net/mac80211/util.c | 16 +- net/mac80211/work.c | 17 +- net/mac80211/wpa.c | 3 +- net/netfilter/Kconfig | 42 - net/netfilter/Makefile | 2 - net/netfilter/ipset/ip_set_core.c | 2 +- net/netfilter/ipvs/ip_vs_core.c | 2 +- net/netfilter/ipvs/ip_vs_ctl.c | 7 +- net/netfilter/nf_conntrack_core.c | 16 +- net/netfilter/nf_conntrack_expect.c | 29 +- net/netfilter/nf_conntrack_netlink.c | 4 +- net/netfilter/nf_conntrack_proto_tcp.c | 29 +- net/netfilter/xt_IDLETIMER.c | 79 +- net/netfilter/xt_hashlimit.c | 8 +- net/netfilter/xt_limit.c | 13 +- net/netfilter/xt_qtaguid.c | 2990 ------ net/netfilter/xt_qtaguid_internal.h | 352 - net/netfilter/xt_qtaguid_print.c | 566 -- net/netfilter/xt_qtaguid_print.h | 120 - net/netfilter/xt_quota2.c | 381 - net/netfilter/xt_socket.c | 70 +- net/netlink/af_netlink.c | 64 +- net/netlink/genetlink.c | 2 +- net/netrom/af_netrom.c | 7 +- net/packet/af_packet.c | 16 +- net/phonet/pep.c | 3 - net/phonet/pn_netlink.c | 13 +- net/rds/af_rds.c | 20 +- net/rds/recv.c | 3 - net/rds/send.c | 3 +- net/rfkill/Kconfig | 5 - net/rfkill/core.c | 4 - net/rose/rose_dev.c | 4 +- net/sched/act_api.c | 7 +- net/sched/act_gact.c | 14 +- net/sched/cls_api.c | 6 +- net/sched/sch_api.c | 12 +- net/sched/sch_cbq.c | 5 +- net/sched/sch_choke.c | 3 +- net/sched/sch_gred.c | 9 +- net/sched/sch_htb.c | 2 +- net/sched/sch_mqprio.c | 2 +- net/sched/sch_netem.c | 13 +- net/sched/sch_prio.c | 2 +- net/sched/sch_qfq.c | 5 +- net/sched/sch_sfb.c | 5 +- net/sched/sch_sfq.c | 7 +- net/sched/sch_teql.c | 31 +- net/sctp/associola.c | 2 +- net/sctp/chunk.c | 20 +- net/sctp/endpointola.c | 5 - net/sctp/input.c | 7 +- net/sctp/output.c | 33 +- net/sctp/outqueue.c | 18 +- net/sctp/protocol.c | 3 - net/sctp/sm_sideeffect.c | 3 +- net/sctp/socket.c | 25 +- net/sctp/sysctl.c | 13 - net/sctp/transport.c | 17 + net/socket.c | 82 +- net/sunrpc/auth_unix.c | 3 - net/sunrpc/cache.c | 6 +- net/sunrpc/rpcb_clnt.c | 4 +- net/sunrpc/sched.c | 44 +- net/sunrpc/svc.c | 23 +- net/sunrpc/svc_xprt.c | 62 +- net/sunrpc/svcsock.c | 2 +- net/sunrpc/xprtrdma/transport.c | 3 +- net/sunrpc/xprtsock.c | 75 +- net/wanrouter/wanmain.c | 51 +- net/wireless/Kconfig | 11 - net/wireless/core.c | 16 +- net/wireless/core.h | 3 - net/wireless/mlme.c | 38 - net/wireless/nl80211.c | 657 +- net/wireless/nl80211.h | 11 - net/wireless/reg.c | 88 +- net/wireless/scan.c | 2 +- net/wireless/sme.c | 6 - net/wireless/util.c | 39 +- net/x25/af_x25.c | 3 +- net/xfrm/xfrm_algo.c | 4 +- net/xfrm/xfrm_input.c | 5 - net/xfrm/xfrm_policy.c | 17 +- net/xfrm/xfrm_replay.c | 21 +- net/xfrm/xfrm_user.c | 60 +- samples/uhid/Makefile | 10 - samples/uhid/uhid-example.c | 381 - scripts/Kbuild.include | 14 +- scripts/gcc-version.sh | 6 +- scripts/gcc-x86_32-has-stack-protector.sh | 2 +- scripts/gcc-x86_64-has-stack-protector.sh | 2 +- scripts/kconfig/check.sh | 2 +- scripts/kconfig/lxdialog/check-lxdialog.sh | 2 +- scripts/kconfig/menu.c | 7 +- scripts/kconfig/streamline_config.pl | 52 +- scripts/mod/file2alias.c | 4 - scripts/mod/modpost.c | 36 +- scripts/mod/modpost.h | 1 - scripts/package/builddeb | 12 +- scripts/recordmcount.h | 2 +- security/apparmor/domain.c | 2 +- security/apparmor/lsm.c | 2 +- security/apparmor/path.c | 65 +- security/commoncap.c | 15 - security/integrity/ima/ima_api.c | 4 +- security/integrity/ima/ima_queue.c | 17 +- security/keys/user_defined.c | 3 +- security/selinux/netnode.c | 3 +- security/selinux/netport.c | 4 +- security/selinux/selinuxfs.c | 1 - security/tomoyo/mount.c | 38 +- security/tomoyo/realpath.c | 9 +- sound/arm/pxa2xx-ac97-lib.c | 8 +- sound/core/control.c | 5 - sound/core/hwdep.c | 12 +- sound/core/init.c | 50 +- sound/core/oss/mixer_oss.c | 11 +- sound/core/oss/pcm_oss.c | 7 - sound/core/pcm.c | 13 +- sound/core/pcm_compat.c | 2 +- sound/core/pcm_lib.c | 33 +- sound/core/pcm_native.c | 35 +- sound/core/rawmidi.c | 26 +- sound/core/sound.c | 11 +- sound/core/sound_oss.c | 10 +- sound/core/timer.c | 2 - sound/drivers/aloop.c | 6 - sound/drivers/mpu401/mpu401_uart.c | 1 - sound/pci/ac97/ac97_codec.c | 2 - sound/pci/ac97/ac97_patch.c | 1 - sound/pci/echoaudio/echoaudio_dsp.c | 2 +- sound/pci/emu10k1/emu10k1_main.c | 9 - sound/pci/fm801.c | 15 +- sound/pci/hda/hda_codec.c | 70 +- sound/pci/hda/hda_codec.h | 3 - sound/pci/hda/hda_intel.c | 7 +- sound/pci/hda/hda_local.h | 7 +- sound/pci/hda/hda_proc.c | 4 +- sound/pci/hda/patch_analog.c | 1 - sound/pci/hda/patch_cirrus.c | 4 +- sound/pci/hda/patch_conexant.c | 73 +- sound/pci/hda/patch_realtek.c | 53 +- sound/pci/hda/patch_sigmatel.c | 68 +- sound/pci/ice1712/amp.c | 7 +- sound/pci/ice1712/prodigy_hifi.c | 3 +- sound/pci/intel8x0.c | 6 - sound/pci/lx6464es/lx_core.c | 16 +- sound/pci/oxygen/xonar_pcm179x.c | 5 +- sound/pci/oxygen/xonar_wm87x6.c | 1 - sound/pci/sis7019.c | 64 +- sound/pcmcia/pdaudiocf/pdaudiocf.c | 2 +- sound/pcmcia/vx/vxpocket.c | 2 +- sound/soc/blackfin/bf5xx-ad193x.c | 4 +- sound/soc/codecs/ad193x.c | 3 +- sound/soc/codecs/ad193x.h | 5 +- sound/soc/codecs/ak4535.c | 10 +- sound/soc/codecs/ak4642.c | 24 +- sound/soc/codecs/sgtl5000.c | 128 +- sound/soc/codecs/ssm2602.c | 3 +- sound/soc/codecs/tlv320aic3x.c | 4 +- sound/soc/codecs/tlv320aic3x.h | 1 - sound/soc/codecs/wm2000.c | 4 +- sound/soc/codecs/wm8711.c | 4 +- sound/soc/codecs/wm8731.c | 1 - sound/soc/codecs/wm8741.c | 4 +- sound/soc/codecs/wm8753.c | 7 +- sound/soc/codecs/wm8904.c | 2 +- sound/soc/codecs/wm8940.c | 2 - sound/soc/codecs/wm8962.c | 49 +- sound/soc/codecs/wm8978.c | 2 +- sound/soc/codecs/wm8994.c | 6 +- sound/soc/codecs/wm9712.c | 21 +- sound/soc/codecs/wm_hubs.c | 18 +- sound/soc/davinci/davinci-vcif.c | 9 +- sound/soc/fsl/fsl_ssi.c | 1 - sound/soc/fsl/mpc5200_dma.c | 6 +- sound/soc/imx/imx-ssi.c | 2 +- sound/soc/omap/omap-mcbsp.c | 6 - sound/soc/pxa/pxa-ssp.c | 61 +- sound/soc/pxa/zylonite.c | 8 +- sound/soc/samsung/jive_wm8750.c | 2 +- sound/soc/samsung/neo1973_wm8753.c | 4 +- sound/soc/soc-core.c | 38 +- sound/soc/soc-dapm.c | 16 +- sound/soc/soc-jack.c | 4 +- sound/soc/soc-utils.c | 31 +- sound/soc/tegra/tegra_pcm.c | 9 +- sound/soc/tegra/tegra_wm8903.c | 15 +- sound/usb/caiaq/audio.c | 37 +- sound/usb/caiaq/device.h | 1 - sound/usb/caiaq/input.c | 2 +- sound/usb/card.c | 21 +- sound/usb/card.h | 1 - sound/usb/clock.c | 3 +- sound/usb/endpoint.c | 2 +- sound/usb/midi.c | 87 +- sound/usb/misc/ua101.c | 28 +- sound/usb/mixer.c | 237 +- sound/usb/mixer.h | 1 - sound/usb/mixer_quirks.c | 37 +- sound/usb/pcm.c | 38 +- sound/usb/proc.c | 4 +- sound/usb/quirks-table.h | 53 - sound/usb/urb.c | 9 +- sound/usb/usbaudio.h | 2 +- sound/usb/usx2y/usb_stream.c | 6 +- tools/perf/Makefile | 5 +- tools/perf/bench/mem-memcpy-x86-64-asm.S | 6 - tools/perf/util/config.c | 7 + tools/perf/util/evsel.c | 1 - tools/perf/util/header.c | 5 +- tools/perf/util/hist.c | 12 - tools/perf/util/probe-event.c | 4 +- tools/perf/util/session.c | 30 +- tools/perf/util/session.h | 1 - tools/perf/util/sort.c | 3 - tools/perf/util/symbol.c | 2 - tools/perf/util/trace-event-parse.c | 4 - tools/usb/ffs-test.c | 2 +- usr/gen_init_cpio.c | 43 +- virt/kvm/iommu.c | 12 +- virt/kvm/kvm_main.c | 5 +- 2671 files changed, 17599 insertions(+), 209994 deletions(-) delete mode 100644 Documentation/android.txt delete mode 100644 Documentation/hid/uhid.txt delete mode 100644 arch/arm/common/fiq_debugger.c delete mode 100644 arch/arm/common/fiq_debugger_ringbuf.h delete mode 100644 arch/arm/common/fiq_glue.S delete mode 100644 arch/arm/common/fiq_glue_setup.c delete mode 100644 arch/arm/include/asm/fiq_debugger.h delete mode 100644 arch/arm/include/asm/fiq_glue.h delete mode 100644 arch/arm/include/asm/mach/mmc.h delete mode 100644 arch/sparc/kernel/sigutil.h delete mode 100644 arch/sparc/kernel/sigutil_32.c delete mode 100644 arch/sparc/kernel/sigutil_64.c create mode 100644 arch/sparc/lib/NG2page.S delete mode 100644 arch/sparc/lib/ffs.S delete mode 100644 arch/sparc/lib/hweight.S create mode 100644 arch/sparc/mm/generic_32.c create mode 100644 arch/sparc/mm/generic_64.c delete mode 100644 arch/x86/include/asm/archrandom.h delete mode 100644 arch/x86/kernel/cpu/rdrand.c delete mode 100644 arch/x86/xen/vga.c delete mode 100644 drivers/base/sw_sync.c delete mode 100644 drivers/base/sync.c delete mode 100644 drivers/char/dcc_tty.c delete mode 100644 drivers/cpufreq/cpufreq_interactive.c delete mode 100644 drivers/gpu/ion/Kconfig delete mode 100644 drivers/gpu/ion/Makefile delete mode 100644 drivers/gpu/ion/ion.c delete mode 100644 drivers/gpu/ion/ion_carveout_heap.c delete mode 100644 drivers/gpu/ion/ion_heap.c delete mode 100644 drivers/gpu/ion/ion_priv.h delete mode 100644 drivers/gpu/ion/ion_system_heap.c delete mode 100644 drivers/gpu/ion/ion_system_mapper.c delete mode 100644 drivers/gpu/ion/tegra/Makefile delete mode 100644 drivers/gpu/ion/tegra/tegra_ion.c delete mode 100644 drivers/hid/uhid.c delete mode 100644 drivers/input/keyreset.c delete mode 100644 drivers/input/misc/gpio_axis.c delete mode 100644 drivers/input/misc/gpio_event.c delete mode 100644 drivers/input/misc/gpio_input.c delete mode 100644 drivers/input/misc/gpio_matrix.c delete mode 100644 drivers/input/misc/gpio_output.c delete mode 100644 drivers/input/misc/keychord.c delete mode 100644 drivers/input/touchscreen/synaptics_i2c_rmi.c delete mode 100644 drivers/leds/ledtrig-sleep.c delete mode 100644 drivers/misc/akm8975.c delete mode 100644 drivers/misc/apanic.c delete mode 100644 drivers/misc/uid_stat.c delete mode 100644 drivers/misc/wl127x-rfkill.c mode change 100755 => 100644 drivers/mmc/core/sdio_io.c delete mode 100644 drivers/net/pppolac.c delete mode 100644 drivers/net/pppopns.c delete mode 100644 drivers/net/wireless/bcm4329/Kconfig delete mode 100644 drivers/net/wireless/bcm4329/Makefile delete mode 100644 drivers/net/wireless/bcm4329/aiutils.c delete mode 100644 drivers/net/wireless/bcm4329/bcmpcispi.c delete mode 100644 drivers/net/wireless/bcm4329/bcmsdh.c delete mode 100644 drivers/net/wireless/bcm4329/bcmsdh_linux.c delete mode 100644 drivers/net/wireless/bcm4329/bcmsdh_sdmmc.c delete mode 100644 drivers/net/wireless/bcm4329/bcmsdh_sdmmc_linux.c delete mode 100644 drivers/net/wireless/bcm4329/bcmsdspi.c delete mode 100644 drivers/net/wireless/bcm4329/bcmsdspi_linux.c delete mode 100644 drivers/net/wireless/bcm4329/bcmsdstd.c delete mode 100644 drivers/net/wireless/bcm4329/bcmsdstd_linux.c delete mode 100644 drivers/net/wireless/bcm4329/bcmutils.c delete mode 100644 drivers/net/wireless/bcm4329/bcmwifi.c delete mode 100644 drivers/net/wireless/bcm4329/dhd.h delete mode 100644 drivers/net/wireless/bcm4329/dhd_bus.h delete mode 100644 drivers/net/wireless/bcm4329/dhd_cdc.c delete mode 100644 drivers/net/wireless/bcm4329/dhd_common.c delete mode 100644 drivers/net/wireless/bcm4329/dhd_custom_gpio.c delete mode 100644 drivers/net/wireless/bcm4329/dhd_dbg.h delete mode 100644 drivers/net/wireless/bcm4329/dhd_linux.c delete mode 100644 drivers/net/wireless/bcm4329/dhd_linux_sched.c delete mode 100644 drivers/net/wireless/bcm4329/dhd_proto.h delete mode 100644 drivers/net/wireless/bcm4329/dhd_sdio.c delete mode 100644 drivers/net/wireless/bcm4329/dngl_stats.h delete mode 100644 drivers/net/wireless/bcm4329/hndpmu.c delete mode 100644 drivers/net/wireless/bcm4329/include/Makefile delete mode 100644 drivers/net/wireless/bcm4329/include/aidmp.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmcdc.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmdefs.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmdevs.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmendian.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmpcispi.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmperf.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmsdbus.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmsdh.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmsdh_sdmmc.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmsdpcm.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmsdspi.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmsdstd.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmspi.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmutils.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmwifi.h delete mode 100644 drivers/net/wireless/bcm4329/include/dhdioctl.h delete mode 100644 drivers/net/wireless/bcm4329/include/epivers.h delete mode 100644 drivers/net/wireless/bcm4329/include/hndpmu.h delete mode 100644 drivers/net/wireless/bcm4329/include/hndrte_armtrap.h delete mode 100644 drivers/net/wireless/bcm4329/include/hndrte_cons.h delete mode 100644 drivers/net/wireless/bcm4329/include/hndsoc.h delete mode 100644 drivers/net/wireless/bcm4329/include/linux_osl.h delete mode 100644 drivers/net/wireless/bcm4329/include/linuxver.h delete mode 100644 drivers/net/wireless/bcm4329/include/miniopt.h delete mode 100644 drivers/net/wireless/bcm4329/include/msgtrace.h delete mode 100644 drivers/net/wireless/bcm4329/include/osl.h delete mode 100644 drivers/net/wireless/bcm4329/include/packed_section_end.h delete mode 100644 drivers/net/wireless/bcm4329/include/packed_section_start.h delete mode 100644 drivers/net/wireless/bcm4329/include/pcicfg.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/802.11.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/802.11e.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/802.1d.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/bcmeth.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/bcmevent.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/bcmip.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/eapol.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/ethernet.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/sdspi.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/vlan.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/wpa.h delete mode 100644 drivers/net/wireless/bcm4329/include/sbchipc.h delete mode 100644 drivers/net/wireless/bcm4329/include/sbconfig.h delete mode 100644 drivers/net/wireless/bcm4329/include/sbhnddma.h delete mode 100644 drivers/net/wireless/bcm4329/include/sbpcmcia.h delete mode 100644 drivers/net/wireless/bcm4329/include/sbsdio.h delete mode 100644 drivers/net/wireless/bcm4329/include/sbsdpcmdev.h delete mode 100644 drivers/net/wireless/bcm4329/include/sbsocram.h delete mode 100644 drivers/net/wireless/bcm4329/include/sdio.h delete mode 100644 drivers/net/wireless/bcm4329/include/sdioh.h delete mode 100644 drivers/net/wireless/bcm4329/include/sdiovar.h delete mode 100644 drivers/net/wireless/bcm4329/include/siutils.h delete mode 100644 drivers/net/wireless/bcm4329/include/trxhdr.h delete mode 100644 drivers/net/wireless/bcm4329/include/typedefs.h delete mode 100644 drivers/net/wireless/bcm4329/include/wlioctl.h delete mode 100644 drivers/net/wireless/bcm4329/linux_osl.c delete mode 100644 drivers/net/wireless/bcm4329/miniopt.c delete mode 100644 drivers/net/wireless/bcm4329/sbutils.c delete mode 100644 drivers/net/wireless/bcm4329/siutils.c delete mode 100644 drivers/net/wireless/bcm4329/siutils_priv.h delete mode 100644 drivers/net/wireless/bcm4329/wl_iw.c delete mode 100644 drivers/net/wireless/bcm4329/wl_iw.h delete mode 100644 drivers/net/wireless/bcmdhd/Kconfig delete mode 100644 drivers/net/wireless/bcmdhd/Makefile delete mode 100644 drivers/net/wireless/bcmdhd/aiutils.c delete mode 100644 drivers/net/wireless/bcmdhd/bcmevent.c delete mode 100644 drivers/net/wireless/bcmdhd/bcmsdh.c delete mode 100644 drivers/net/wireless/bcmdhd/bcmsdh_linux.c delete mode 100644 drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c delete mode 100644 drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c delete mode 100644 drivers/net/wireless/bcmdhd/bcmutils.c delete mode 100644 drivers/net/wireless/bcmdhd/bcmwifi.c delete mode 100644 drivers/net/wireless/bcmdhd/dhd.h delete mode 100644 drivers/net/wireless/bcmdhd/dhd_bta.c delete mode 100644 drivers/net/wireless/bcmdhd/dhd_bta.h delete mode 100644 drivers/net/wireless/bcmdhd/dhd_bus.h delete mode 100644 drivers/net/wireless/bcmdhd/dhd_cdc.c delete mode 100644 drivers/net/wireless/bcmdhd/dhd_cfg80211.c delete mode 100644 drivers/net/wireless/bcmdhd/dhd_cfg80211.h delete mode 100644 drivers/net/wireless/bcmdhd/dhd_common.c delete mode 100644 drivers/net/wireless/bcmdhd/dhd_custom_gpio.c delete mode 100644 drivers/net/wireless/bcmdhd/dhd_dbg.h delete mode 100644 drivers/net/wireless/bcmdhd/dhd_linux.c delete mode 100644 drivers/net/wireless/bcmdhd/dhd_linux_sched.c delete mode 100644 drivers/net/wireless/bcmdhd/dhd_proto.h delete mode 100644 drivers/net/wireless/bcmdhd/dhd_sdio.c delete mode 100644 drivers/net/wireless/bcmdhd/dhd_wlfc.h delete mode 100644 drivers/net/wireless/bcmdhd/dngl_stats.h delete mode 100644 drivers/net/wireless/bcmdhd/dngl_wlhdr.h delete mode 100644 drivers/net/wireless/bcmdhd/hndpmu.c delete mode 100644 drivers/net/wireless/bcmdhd/include/Makefile delete mode 100644 drivers/net/wireless/bcmdhd/include/aidmp.h delete mode 100644 drivers/net/wireless/bcmdhd/include/bcmcdc.h delete mode 100644 drivers/net/wireless/bcmdhd/include/bcmdefs.h delete mode 100644 drivers/net/wireless/bcmdhd/include/bcmdevs.h delete mode 100644 drivers/net/wireless/bcmdhd/include/bcmendian.h delete mode 100644 drivers/net/wireless/bcmdhd/include/bcmpcispi.h delete mode 100644 drivers/net/wireless/bcmdhd/include/bcmperf.h delete mode 100644 drivers/net/wireless/bcmdhd/include/bcmsdbus.h delete mode 100644 drivers/net/wireless/bcmdhd/include/bcmsdh.h delete mode 100644 drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h delete mode 100644 drivers/net/wireless/bcmdhd/include/bcmsdpcm.h delete mode 100644 drivers/net/wireless/bcmdhd/include/bcmsdspi.h delete mode 100644 drivers/net/wireless/bcmdhd/include/bcmsdstd.h delete mode 100644 drivers/net/wireless/bcmdhd/include/bcmspi.h delete mode 100644 drivers/net/wireless/bcmdhd/include/bcmutils.h delete mode 100644 drivers/net/wireless/bcmdhd/include/bcmwifi.h delete mode 100644 drivers/net/wireless/bcmdhd/include/dhdioctl.h delete mode 100644 drivers/net/wireless/bcmdhd/include/epivers.h delete mode 100644 drivers/net/wireless/bcmdhd/include/hndpmu.h delete mode 100644 drivers/net/wireless/bcmdhd/include/hndrte_armtrap.h delete mode 100644 drivers/net/wireless/bcmdhd/include/hndrte_cons.h delete mode 100644 drivers/net/wireless/bcmdhd/include/hndsoc.h delete mode 100644 drivers/net/wireless/bcmdhd/include/htsf.h delete mode 100644 drivers/net/wireless/bcmdhd/include/linux_osl.h delete mode 100644 drivers/net/wireless/bcmdhd/include/linuxver.h delete mode 100644 drivers/net/wireless/bcmdhd/include/miniopt.h delete mode 100644 drivers/net/wireless/bcmdhd/include/msgtrace.h delete mode 100644 drivers/net/wireless/bcmdhd/include/osl.h delete mode 100644 drivers/net/wireless/bcmdhd/include/packed_section_end.h delete mode 100644 drivers/net/wireless/bcmdhd/include/packed_section_start.h delete mode 100644 drivers/net/wireless/bcmdhd/include/pcicfg.h delete mode 100644 drivers/net/wireless/bcmdhd/include/proto/802.11.h delete mode 100644 drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h delete mode 100644 drivers/net/wireless/bcmdhd/include/proto/802.11e.h delete mode 100644 drivers/net/wireless/bcmdhd/include/proto/802.1d.h delete mode 100644 drivers/net/wireless/bcmdhd/include/proto/bcmeth.h delete mode 100644 drivers/net/wireless/bcmdhd/include/proto/bcmevent.h delete mode 100644 drivers/net/wireless/bcmdhd/include/proto/bcmip.h delete mode 100644 drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h delete mode 100644 drivers/net/wireless/bcmdhd/include/proto/eapol.h delete mode 100644 drivers/net/wireless/bcmdhd/include/proto/ethernet.h delete mode 100644 drivers/net/wireless/bcmdhd/include/proto/p2p.h delete mode 100644 drivers/net/wireless/bcmdhd/include/proto/sdspi.h delete mode 100644 drivers/net/wireless/bcmdhd/include/proto/vlan.h delete mode 100644 drivers/net/wireless/bcmdhd/include/proto/wpa.h delete mode 100644 drivers/net/wireless/bcmdhd/include/sbchipc.h delete mode 100644 drivers/net/wireless/bcmdhd/include/sbconfig.h delete mode 100644 drivers/net/wireless/bcmdhd/include/sbhnddma.h delete mode 100644 drivers/net/wireless/bcmdhd/include/sbpcmcia.h delete mode 100644 drivers/net/wireless/bcmdhd/include/sbsdio.h delete mode 100644 drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h delete mode 100644 drivers/net/wireless/bcmdhd/include/sbsocram.h delete mode 100644 drivers/net/wireless/bcmdhd/include/sdio.h delete mode 100644 drivers/net/wireless/bcmdhd/include/sdioh.h delete mode 100644 drivers/net/wireless/bcmdhd/include/sdiovar.h delete mode 100644 drivers/net/wireless/bcmdhd/include/siutils.h delete mode 100644 drivers/net/wireless/bcmdhd/include/trxhdr.h delete mode 100644 drivers/net/wireless/bcmdhd/include/typedefs.h delete mode 100644 drivers/net/wireless/bcmdhd/include/wlfc_proto.h delete mode 100644 drivers/net/wireless/bcmdhd/include/wlioctl.h delete mode 100644 drivers/net/wireless/bcmdhd/linux_osl.c delete mode 100644 drivers/net/wireless/bcmdhd/sbutils.c delete mode 100644 drivers/net/wireless/bcmdhd/siutils.c delete mode 100644 drivers/net/wireless/bcmdhd/siutils_priv.h delete mode 100644 drivers/net/wireless/bcmdhd/uamp_api.h delete mode 100644 drivers/net/wireless/bcmdhd/wl_android.c delete mode 100644 drivers/net/wireless/bcmdhd/wl_android.h delete mode 100644 drivers/net/wireless/bcmdhd/wl_cfg80211.c delete mode 100644 drivers/net/wireless/bcmdhd/wl_cfg80211.h delete mode 100644 drivers/net/wireless/bcmdhd/wl_cfgp2p.c delete mode 100644 drivers/net/wireless/bcmdhd/wl_cfgp2p.h delete mode 100644 drivers/net/wireless/bcmdhd/wl_dbg.h delete mode 100644 drivers/net/wireless/bcmdhd/wl_iw.c delete mode 100644 drivers/net/wireless/bcmdhd/wl_iw.h delete mode 100644 drivers/net/wireless/bcmdhd/wl_linux_mon.c delete mode 100644 drivers/net/wireless/bcmdhd/wldev_common.c delete mode 100644 drivers/net/wireless/bcmdhd/wldev_common.h delete mode 100644 drivers/rtc/alarm-dev.c delete mode 100644 drivers/rtc/alarm.c delete mode 100644 drivers/staging/android/Kconfig delete mode 100644 drivers/staging/android/Makefile delete mode 100644 drivers/staging/android/binder.c delete mode 100644 drivers/staging/android/binder.h delete mode 100644 drivers/staging/android/logger.c delete mode 100644 drivers/staging/android/logger.h delete mode 100644 drivers/staging/android/lowmemorykiller.c delete mode 100644 drivers/staging/android/ram_console.c delete mode 100644 drivers/staging/android/timed_gpio.c delete mode 100644 drivers/staging/android/timed_gpio.h delete mode 100644 drivers/staging/android/timed_output.c delete mode 100644 drivers/staging/android/timed_output.h delete mode 100644 drivers/switch/Kconfig delete mode 100644 drivers/switch/Makefile delete mode 100644 drivers/switch/switch_class.c delete mode 100644 drivers/switch/switch_gpio.c delete mode 100644 drivers/usb/gadget/android.c delete mode 100644 drivers/usb/gadget/f_accessory.c delete mode 100644 drivers/usb/gadget/f_adb.c delete mode 100644 drivers/usb/gadget/f_audio_source.c delete mode 100644 drivers/usb/gadget/f_mtp.c delete mode 100644 drivers/usb/otg/otg-wakelock.c delete mode 100644 drivers/usb/otg/otg_id.c delete mode 100644 fs/yaffs2/Kconfig delete mode 100644 fs/yaffs2/Makefile delete mode 100644 fs/yaffs2/yaffs_allocator.c delete mode 100644 fs/yaffs2/yaffs_allocator.h delete mode 100644 fs/yaffs2/yaffs_attribs.c delete mode 100644 fs/yaffs2/yaffs_attribs.h delete mode 100644 fs/yaffs2/yaffs_bitmap.c delete mode 100644 fs/yaffs2/yaffs_bitmap.h delete mode 100644 fs/yaffs2/yaffs_checkptrw.c delete mode 100644 fs/yaffs2/yaffs_checkptrw.h delete mode 100644 fs/yaffs2/yaffs_ecc.c delete mode 100644 fs/yaffs2/yaffs_ecc.h delete mode 100644 fs/yaffs2/yaffs_getblockinfo.h delete mode 100644 fs/yaffs2/yaffs_guts.c delete mode 100644 fs/yaffs2/yaffs_guts.h delete mode 100644 fs/yaffs2/yaffs_linux.h delete mode 100644 fs/yaffs2/yaffs_mtdif.c delete mode 100644 fs/yaffs2/yaffs_mtdif.h delete mode 100644 fs/yaffs2/yaffs_mtdif1.c delete mode 100644 fs/yaffs2/yaffs_mtdif1.h delete mode 100644 fs/yaffs2/yaffs_mtdif2.c delete mode 100644 fs/yaffs2/yaffs_mtdif2.h delete mode 100644 fs/yaffs2/yaffs_nameval.c delete mode 100644 fs/yaffs2/yaffs_nameval.h delete mode 100644 fs/yaffs2/yaffs_nand.c delete mode 100644 fs/yaffs2/yaffs_nand.h delete mode 100644 fs/yaffs2/yaffs_packedtags1.c delete mode 100644 fs/yaffs2/yaffs_packedtags1.h delete mode 100644 fs/yaffs2/yaffs_packedtags2.c delete mode 100644 fs/yaffs2/yaffs_packedtags2.h delete mode 100644 fs/yaffs2/yaffs_tagscompat.c delete mode 100644 fs/yaffs2/yaffs_tagscompat.h delete mode 100644 fs/yaffs2/yaffs_tagsvalidity.c delete mode 100644 fs/yaffs2/yaffs_tagsvalidity.h delete mode 100644 fs/yaffs2/yaffs_trace.h delete mode 100644 fs/yaffs2/yaffs_verify.c delete mode 100644 fs/yaffs2/yaffs_verify.h delete mode 100644 fs/yaffs2/yaffs_vfs.c delete mode 100644 fs/yaffs2/yaffs_yaffs1.c delete mode 100644 fs/yaffs2/yaffs_yaffs1.h delete mode 100644 fs/yaffs2/yaffs_yaffs2.c delete mode 100644 fs/yaffs2/yaffs_yaffs2.h delete mode 100644 fs/yaffs2/yportenv.h delete mode 100644 include/linux/akm8975.h delete mode 100644 include/linux/android_aid.h delete mode 100644 include/linux/android_alarm.h delete mode 100644 include/linux/ashmem.h delete mode 100644 include/linux/cpuacct.h delete mode 100755 include/linux/earlysuspend.h delete mode 100644 include/linux/gpio_event.h delete mode 100644 include/linux/if_pppolac.h delete mode 100644 include/linux/if_pppopns.h delete mode 100644 include/linux/ion.h delete mode 100644 include/linux/keychord.h delete mode 100644 include/linux/keyreset.h mode change 100755 => 100644 include/linux/mmc/sdio_func.h delete mode 100644 include/linux/netfilter/xt_qtaguid.h delete mode 100644 include/linux/netfilter/xt_quota2.h delete mode 100644 include/linux/platform_data/ram_console.h delete mode 100644 include/linux/sw_sync.h delete mode 100644 include/linux/switch.h delete mode 100644 include/linux/synaptics_i2c_rmi.h delete mode 100644 include/linux/sync.h delete mode 100644 include/linux/uhid.h delete mode 100644 include/linux/uid_stat.h delete mode 100644 include/linux/usb/f_accessory.h delete mode 100644 include/linux/usb/f_mtp.h delete mode 100644 include/linux/usb/otg_id.h delete mode 100755 include/linux/wakelock.h delete mode 100644 include/linux/wifi_tiwlan.h delete mode 100644 include/linux/wl127x-rfkill.h delete mode 100644 include/linux/wlan_plat.h delete mode 100644 include/net/activity_stats.h delete mode 100644 include/net/secure_seq.h delete mode 100644 include/trace/events/cpufreq_interactive.h delete mode 100644 include/trace/events/random.h delete mode 100644 kernel/power/consoleearlysuspend.c delete mode 100644 kernel/power/earlysuspend.c delete mode 100644 kernel/power/fbearlysuspend.c delete mode 100644 kernel/power/suspend_time.c delete mode 100644 kernel/power/userwakelock.c delete mode 100644 kernel/power/wakelock.c delete mode 100644 lib/md5.c delete mode 100644 mm/ashmem.c delete mode 100644 net/activity_stats.c mode change 100755 => 100644 net/bluetooth/hci_event.c delete mode 100644 net/bluetooth/smp.c delete mode 100644 net/core/secure_seq.c delete mode 100644 net/ipv4/sysfs_net_ipv4.c delete mode 100644 net/netfilter/xt_qtaguid.c delete mode 100644 net/netfilter/xt_qtaguid_internal.h delete mode 100644 net/netfilter/xt_qtaguid_print.c delete mode 100644 net/netfilter/xt_qtaguid_print.h delete mode 100644 net/netfilter/xt_quota2.c delete mode 100644 samples/uhid/Makefile delete mode 100644 samples/uhid/uhid-example.c diff --git a/Documentation/HOWTO b/Documentation/HOWTO index 59c080f084ef..81bc1a9ab9d8 100644 --- a/Documentation/HOWTO +++ b/Documentation/HOWTO @@ -218,16 +218,16 @@ The development process Linux kernel development process currently consists of a few different main kernel "branches" and lots of different subsystem-specific kernel branches. These different branches are: - - main 3.x kernel tree - - 3.x.y -stable kernel tree - - 3.x -git kernel patches + - main 2.6.x kernel tree + - 2.6.x.y -stable kernel tree + - 2.6.x -git kernel patches - subsystem specific kernel trees and patches - - the 3.x -next kernel tree for integration tests + - the 2.6.x -next kernel tree for integration tests -3.x kernel tree +2.6.x kernel tree ----------------- -3.x kernels are maintained by Linus Torvalds, and can be found on -kernel.org in the pub/linux/kernel/v3.x/ directory. Its development +2.6.x kernels are maintained by Linus Torvalds, and can be found on +kernel.org in the pub/linux/kernel/v2.6/ directory. Its development process is as follows: - As soon as a new kernel is released a two weeks window is open, during this period of time maintainers can submit big diffs to @@ -262,21 +262,21 @@ mailing list about kernel releases: released according to perceived bug status, not according to a preconceived timeline." -3.x.y -stable kernel tree +2.6.x.y -stable kernel tree --------------------------- -Kernels with 3-part versions are -stable kernels. They contain +Kernels with 4-part versions are -stable kernels. They contain relatively small and critical fixes for security problems or significant -regressions discovered in a given 3.x kernel. +regressions discovered in a given 2.6.x kernel. This is the recommended branch for users who want the most recent stable kernel and are not interested in helping test development/experimental versions. -If no 3.x.y kernel is available, then the highest numbered 3.x +If no 2.6.x.y kernel is available, then the highest numbered 2.6.x kernel is the current stable kernel. -3.x.y are maintained by the "stable" team , and -are released as needs dictate. The normal release period is approximately +2.6.x.y are maintained by the "stable" team , and are +released as needs dictate. The normal release period is approximately two weeks, but it can be longer if there are no pressing problems. A security-related problem, instead, can cause a release to happen almost instantly. @@ -285,7 +285,7 @@ The file Documentation/stable_kernel_rules.txt in the kernel tree documents what kinds of changes are acceptable for the -stable tree, and how the release process works. -3.x -git patches +2.6.x -git patches ------------------ These are daily snapshots of Linus' kernel tree which are managed in a git repository (hence the name.) These patches are usually released @@ -317,13 +317,13 @@ revisions to it, and maintainers can mark patches as under review, accepted, or rejected. Most of these patchwork sites are listed at http://patchwork.kernel.org/. -3.x -next kernel tree for integration tests +2.6.x -next kernel tree for integration tests --------------------------------------------- -Before updates from subsystem trees are merged into the mainline 3.x +Before updates from subsystem trees are merged into the mainline 2.6.x tree, they need to be integration-tested. For this purpose, a special testing repository exists into which virtually all subsystem trees are pulled on an almost daily basis: - http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git + http://git.kernel.org/?p=linux/kernel/git/sfr/linux-next.git http://linux.f-seidel.de/linux-next/pmwiki/ This way, the -next kernel gives a summary outlook onto what will be diff --git a/Documentation/android.txt b/Documentation/android.txt deleted file mode 100644 index 72a62afdf202..000000000000 --- a/Documentation/android.txt +++ /dev/null @@ -1,121 +0,0 @@ - ============= - A N D R O I D - ============= - -Copyright (C) 2009 Google, Inc. -Written by Mike Chan - -CONTENTS: ---------- - -1. Android - 1.1 Required enabled config options - 1.2 Required disabled config options - 1.3 Recommended enabled config options -2. Contact - - -1. Android -========== - -Android (www.android.com) is an open source operating system for mobile devices. -This document describes configurations needed to run the Android framework on -top of the Linux kernel. - -To see a working defconfig look at msm_defconfig or goldfish_defconfig -which can be found at http://android.git.kernel.org in kernel/common.git -and kernel/msm.git - - -1.1 Required enabled config options ------------------------------------ -After building a standard defconfig, ensure that these options are enabled in -your .config or defconfig if they are not already. Based off the msm_defconfig. -You should keep the rest of the default options enabled in the defconfig -unless you know what you are doing. - -ANDROID_PARANOID_NETWORK -ASHMEM -CONFIG_FB_MODE_HELPERS -CONFIG_FONT_8x16 -CONFIG_FONT_8x8 -CONFIG_YAFFS_SHORT_NAMES_IN_RAM -DAB -EARLYSUSPEND -FB -FB_CFB_COPYAREA -FB_CFB_FILLRECT -FB_CFB_IMAGEBLIT -FB_DEFERRED_IO -FB_TILEBLITTING -HIGH_RES_TIMERS -INOTIFY -INOTIFY_USER -INPUT_EVDEV -INPUT_GPIO -INPUT_MISC -LEDS_CLASS -LEDS_GPIO -LOCK_KERNEL -LkOGGER -LOW_MEMORY_KILLER -MISC_DEVICES -NEW_LEDS -NO_HZ -POWER_SUPPLY -PREEMPT -RAMFS -RTC_CLASS -RTC_LIB -SWITCH -SWITCH_GPIO -TMPFS -UID_STAT -UID16 -USB_FUNCTION -USB_FUNCTION_ADB -USER_WAKELOCK -VIDEO_OUTPUT_CONTROL -WAKELOCK -YAFFS_AUTO_YAFFS2 -YAFFS_FS -YAFFS_YAFFS1 -YAFFS_YAFFS2 - - -1.2 Required disabled config options ------------------------------------- -CONFIG_YAFFS_DISABLE_LAZY_LOAD -DNOTIFY - - -1.3 Recommended enabled config options ------------------------------- -ANDROID_PMEM -ANDROID_RAM_CONSOLE -ANDROID_RAM_CONSOLE_ERROR_CORRECTION -SCHEDSTATS -DEBUG_PREEMPT -DEBUG_MUTEXES -DEBUG_SPINLOCK_SLEEP -DEBUG_INFO -FRAME_POINTER -CPU_FREQ -CPU_FREQ_TABLE -CPU_FREQ_DEFAULT_GOV_ONDEMAND -CPU_FREQ_GOV_ONDEMAND -CRC_CCITT -EMBEDDED -INPUT_TOUCHSCREEN -I2C -I2C_BOARDINFO -LOG_BUF_SHIFT=17 -SERIAL_CORE -SERIAL_CORE_CONSOLE - - -2. Contact -========== -website: http://android.git.kernel.org - -mailing-lists: android-kernel@googlegroups.com diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt index 60d82e1e498d..cd67e90003c0 100644 --- a/Documentation/cgroups/cgroups.txt +++ b/Documentation/cgroups/cgroups.txt @@ -593,15 +593,6 @@ there are not tasks in the cgroup. If pre_destroy() returns error code, rmdir() will fail with it. From this behavior, pre_destroy() can be called multiple times against a cgroup. -int allow_attach(struct cgroup *cgrp, struct task_struct *task) -(cgroup_mutex held by caller) - -Called prior to moving a task into a cgroup; if the subsystem -returns an error, this will abort the attach operation. Used -to extend the permission checks - if all subsystems in a cgroup -return 0, the attach will be allowed to proceed, even if the -default permission check (root or same user) fails. - int can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, struct task_struct *task) (cgroup_mutex held by caller) diff --git a/Documentation/cgroups/cpuacct.txt b/Documentation/cgroups/cpuacct.txt index 34197079f188..9ad85df4b983 100644 --- a/Documentation/cgroups/cpuacct.txt +++ b/Documentation/cgroups/cpuacct.txt @@ -39,13 +39,6 @@ system: Time spent by tasks of the cgroup in kernel mode. user and system are in USER_HZ unit. -cpuacct.cpufreq file gives CPU time (in nanoseconds) spent at each CPU -frequency. Platform hooks must be implemented inorder to properly track -time at each CPU frequency. - -cpuacct.power file gives CPU power consumed (in milliWatt seconds). Platform -must provide and implement power callback functions. - cpuacct controller uses percpu_counter interface to collect user and system times. This has two side effects: diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt index 1eebdbfcd776..e74d0a2eb1cf 100644 --- a/Documentation/cpu-freq/governors.txt +++ b/Documentation/cpu-freq/governors.txt @@ -28,7 +28,6 @@ Contents: 2.3 Userspace 2.4 Ondemand 2.5 Conservative -2.6 Interactive 3. The Governor Interface in the CPUfreq Core @@ -194,80 +193,6 @@ governor but for the opposite direction. For example when set to its default value of '20' it means that if the CPU usage needs to be below 20% between samples to have the frequency decreased. - -2.6 Interactive ---------------- - -The CPUfreq governor "interactive" is designed for latency-sensitive, -interactive workloads. This governor sets the CPU speed depending on -usage, similar to "ondemand" and "conservative" governors, but with a -different set of configurable behaviors. - -The tuneable values for this governor are: - -target_loads: CPU load values used to adjust speed to influence the -current CPU load toward that value. In general, the lower the target -load, the more often the governor will raise CPU speeds to bring load -below the target. The format is a single target load, optionally -followed by pairs of CPU speeds and CPU loads to target at or above -those speeds. Colons can be used between the speeds and associated -target loads for readability. For example: - - 85 1000000:90 1700000:99 - -targets CPU load 85% below speed 1GHz, 90% at or above 1GHz, until -1.7GHz and above, at which load 99% is targeted. If speeds are -specified these must appear in ascending order. Higher target load -values are typically specified for higher speeds, that is, target load -values also usually appear in an ascending order. The default is -target load 90% for all speeds. - -min_sample_time: The minimum amount of time to spend at the current -frequency before ramping down. Default is 80000 uS. - -hispeed_freq: An intermediate "hi speed" at which to initially ramp -when CPU load hits the value specified in go_hispeed_load. If load -stays high for the amount of time specified in above_hispeed_delay, -then speed may be bumped higher. Default is the maximum speed -allowed by the policy at governor initialization time. - -go_hispeed_load: The CPU load at which to ramp to hispeed_freq. -Default is 99%. - -above_hispeed_delay: When speed is at or above hispeed_freq, wait for -this long before raising speed in response to continued high load. -Default is 20000 uS. - -timer_rate: Sample rate for reevaluating CPU load when the CPU is not -idle. A deferrable timer is used, such that the CPU will not be woken -from idle to service this timer until something else needs to run. -(The maximum time to allow deferring this timer when not running at -minimum speed is configurable via timer_slack.) Default is 20000 uS. - -timer_slack: Maximum additional time to defer handling the governor -sampling timer beyond timer_rate when running at speeds above the -minimum. For platforms that consume additional power at idle when -CPUs are running at speeds greater than minimum, this places an upper -bound on how long the timer will be deferred prior to re-evaluating -load and dropping speed. For example, if timer_rate is 20000uS and -timer_slack is 10000uS then timers will be deferred for up to 30msec -when not at lowest speed. A value of -1 means defer timers -indefinitely at all speeds. Default is 80000 uS. - -boost: If non-zero, immediately boost speed of all CPUs to at least -hispeed_freq until zero is written to this attribute. If zero, allow -CPU speeds to drop below hispeed_freq according to load as usual. -Default is zero. - -boostpulse: On each write, immediately boost speed of all CPUs to -hispeed_freq for at least the period of time specified by -boostpulse_duration, after which speeds are allowed to drop below -hispeed_freq according to load as usual. - -boostpulse_duration: Length of time to hold CPU speed at hispeed_freq -on a write to boostpulse, before allowing speed to drop according to -load as usual. Default is 80000 uS. - 3. The Governor Interface in the CPUfreq Core ============================================= diff --git a/Documentation/development-process/5.Posting b/Documentation/development-process/5.Posting index 8a48c9b62864..903a2546f138 100644 --- a/Documentation/development-process/5.Posting +++ b/Documentation/development-process/5.Posting @@ -271,10 +271,10 @@ copies should go to: the linux-kernel list. - If you are fixing a bug, think about whether the fix should go into the - next stable update. If so, stable@vger.kernel.org should get a copy of - the patch. Also add a "Cc: stable@vger.kernel.org" to the tags within - the patch itself; that will cause the stable team to get a notification - when your fix goes into the mainline. + next stable update. If so, stable@kernel.org should get a copy of the + patch. Also add a "Cc: stable@kernel.org" to the tags within the patch + itself; that will cause the stable team to get a notification when your + fix goes into the mainline. When selecting recipients for a patch, it is good to have an idea of who you think will eventually accept the patch and get it merged. While it diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware index 511dd4df04c0..3348d313fbe0 100644 --- a/Documentation/dvb/get_dvb_firmware +++ b/Documentation/dvb/get_dvb_firmware @@ -114,7 +114,7 @@ sub tda10045 { sub tda10046 { my $sourcefile = "TT_PCI_2.19h_28_11_2006.zip"; - my $url = "http://technotrend.com.ua/download/software/219/$sourcefile"; + my $url = "http://www.tt-download.com/download/updates/219/$sourcefile"; my $hash = "6a7e1e2f2644b162ff0502367553c72d"; my $outfile = "dvb-fe-tda10046.fw"; my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 6ff5af4499c8..b1c921c27519 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -6,6 +6,14 @@ be removed from this file. --------------------------- +What: x86 floppy disable_hlt +When: 2012 +Why: ancient workaround of dubious utility clutters the + code used by everybody else. +Who: Len Brown + +--------------------------- + What: CONFIG_APM_CPU_IDLE, and its ability to call APM BIOS in idle When: 2012 Why: This optional sub-feature of APM is of dubious reliability, diff --git a/Documentation/hid/uhid.txt b/Documentation/hid/uhid.txt deleted file mode 100644 index 4627c4241ece..000000000000 --- a/Documentation/hid/uhid.txt +++ /dev/null @@ -1,169 +0,0 @@ - UHID - User-space I/O driver support for HID subsystem - ======================================================== - -The HID subsystem needs two kinds of drivers. In this document we call them: - - 1. The "HID I/O Driver" is the driver that performs raw data I/O to the - low-level device. Internally, they register an hid_ll_driver structure with - the HID core. They perform device setup, read raw data from the device and - push it into the HID subsystem and they provide a callback so the HID - subsystem can send data to the device. - - 2. The "HID Device Driver" is the driver that parses HID reports and reacts on - them. There are generic drivers like "generic-usb" and "generic-bluetooth" - which adhere to the HID specification and provide the standardizes features. - But there may be special drivers and quirks for each non-standard device out - there. Internally, they use the hid_driver structure. - -Historically, the USB stack was the first subsystem to provide an HID I/O -Driver. However, other standards like Bluetooth have adopted the HID specs and -may provide HID I/O Drivers, too. The UHID driver allows to implement HID I/O -Drivers in user-space and feed the data into the kernel HID-subsystem. - -This allows user-space to operate on the same level as USB-HID, Bluetooth-HID -and similar. It does not provide a way to write HID Device Drivers, though. Use -hidraw for this purpose. - -There is an example user-space application in ./samples/uhid/uhid-example.c - -The UHID API ------------- - -UHID is accessed through a character misc-device. The minor-number is allocated -dynamically so you need to rely on udev (or similar) to create the device node. -This is /dev/uhid by default. - -If a new device is detected by your HID I/O Driver and you want to register this -device with the HID subsystem, then you need to open /dev/uhid once for each -device you want to register. All further communication is done by read()'ing or -write()'ing "struct uhid_event" objects. Non-blocking operations are supported -by setting O_NONBLOCK. - -struct uhid_event { - __u32 type; - union { - struct uhid_create_req create; - struct uhid_data_req data; - ... - } u; -}; - -The "type" field contains the ID of the event. Depending on the ID different -payloads are sent. You must not split a single event across multiple read()'s or -multiple write()'s. A single event must always be sent as a whole. Furthermore, -only a single event can be sent per read() or write(). Pending data is ignored. -If you want to handle multiple events in a single syscall, then use vectored -I/O with readv()/writev(). - -The first thing you should do is sending an UHID_CREATE event. This will -register the device. UHID will respond with an UHID_START event. You can now -start sending data to and reading data from UHID. However, unless UHID sends the -UHID_OPEN event, the internally attached HID Device Driver has no user attached. -That is, you might put your device asleep unless you receive the UHID_OPEN -event. If you receive the UHID_OPEN event, you should start I/O. If the last -user closes the HID device, you will receive an UHID_CLOSE event. This may be -followed by an UHID_OPEN event again and so on. There is no need to perform -reference-counting in user-space. That is, you will never receive multiple -UHID_OPEN events without an UHID_CLOSE event. The HID subsystem performs -ref-counting for you. -You may decide to ignore UHID_OPEN/UHID_CLOSE, though. I/O is allowed even -though the device may have no users. - -If you want to send data to the HID subsystem, you send an HID_INPUT event with -your raw data payload. If the kernel wants to send data to the device, you will -read an UHID_OUTPUT or UHID_OUTPUT_EV event. - -If your device disconnects, you should send an UHID_DESTROY event. This will -unregister the device. You can now send UHID_CREATE again to register a new -device. -If you close() the fd, the device is automatically unregistered and destroyed -internally. - -write() -------- -write() allows you to modify the state of the device and feed input data into -the kernel. The following types are supported: UHID_CREATE, UHID_DESTROY and -UHID_INPUT. The kernel will parse the event immediately and if the event ID is -not supported, it will return -EOPNOTSUPP. If the payload is invalid, then --EINVAL is returned, otherwise, the amount of data that was read is returned and -the request was handled successfully. - - UHID_CREATE: - This creates the internal HID device. No I/O is possible until you send this - event to the kernel. The payload is of type struct uhid_create_req and - contains information about your device. You can start I/O now. - - UHID_DESTROY: - This destroys the internal HID device. No further I/O will be accepted. There - may still be pending messages that you can receive with read() but no further - UHID_INPUT events can be sent to the kernel. - You can create a new device by sending UHID_CREATE again. There is no need to - reopen the character device. - - UHID_INPUT: - You must send UHID_CREATE before sending input to the kernel! This event - contains a data-payload. This is the raw data that you read from your device. - The kernel will parse the HID reports and react on it. - - UHID_FEATURE_ANSWER: - If you receive a UHID_FEATURE request you must answer with this request. You - must copy the "id" field from the request into the answer. Set the "err" field - to 0 if no error occured or to EIO if an I/O error occurred. - If "err" is 0 then you should fill the buffer of the answer with the results - of the feature request and set "size" correspondingly. - -read() ------- -read() will return a queued ouput report. These output reports can be of type -UHID_START, UHID_STOP, UHID_OPEN, UHID_CLOSE, UHID_OUTPUT or UHID_OUTPUT_EV. No -reaction is required to any of them but you should handle them according to your -needs. Only UHID_OUTPUT and UHID_OUTPUT_EV have payloads. - - UHID_START: - This is sent when the HID device is started. Consider this as an answer to - UHID_CREATE. This is always the first event that is sent. - - UHID_STOP: - This is sent when the HID device is stopped. Consider this as an answer to - UHID_DESTROY. - If the kernel HID device driver closes the device manually (that is, you - didn't send UHID_DESTROY) then you should consider this device closed and send - an UHID_DESTROY event. You may want to reregister your device, though. This is - always the last message that is sent to you unless you reopen the device with - UHID_CREATE. - - UHID_OPEN: - This is sent when the HID device is opened. That is, the data that the HID - device provides is read by some other process. You may ignore this event but - it is useful for power-management. As long as you haven't received this event - there is actually no other process that reads your data so there is no need to - send UHID_INPUT events to the kernel. - - UHID_CLOSE: - This is sent when there are no more processes which read the HID data. It is - the counterpart of UHID_OPEN and you may as well ignore this event. - - UHID_OUTPUT: - This is sent if the HID device driver wants to send raw data to the I/O - device. You should read the payload and forward it to the device. The payload - is of type "struct uhid_data_req". - This may be received even though you haven't received UHID_OPEN, yet. - - UHID_OUTPUT_EV: - Same as UHID_OUTPUT but this contains a "struct input_event" as payload. This - is called for force-feedback, LED or similar events which are received through - an input device by the HID subsystem. You should convert this into raw reports - and send them to your device similar to events of type UHID_OUTPUT. - - UHID_FEATURE: - This event is sent if the kernel driver wants to perform a feature request as - described in the HID specs. The report-type and report-number are available in - the payload. - The kernel serializes feature requests so there will never be two in parallel. - However, if you fail to respond with a UHID_FEATURE_ANSWER in a time-span of 5 - seconds, then the requests will be dropped and a new one might be sent. - Therefore, the payload also contains an "id" field that identifies every - request. - -Document by: - David Herrmann diff --git a/Documentation/hwmon/jc42 b/Documentation/hwmon/jc42 index 52729a756c1b..a22ecf48f255 100644 --- a/Documentation/hwmon/jc42 +++ b/Documentation/hwmon/jc42 @@ -7,29 +7,21 @@ Supported chips: Addresses scanned: I2C 0x18 - 0x1f Datasheets: http://www.analog.com/static/imported-files/data_sheets/ADT7408.pdf - * Atmel AT30TS00 - Prefix: 'at30ts00' + * IDT TSE2002B3, TS3000B3 + Prefix: 'tse2002b3', 'ts3000b3' Addresses scanned: I2C 0x18 - 0x1f Datasheets: - http://www.atmel.com/Images/doc8585.pdf - * IDT TSE2002B3, TSE2002GB2, TS3000B3, TS3000GB2 - Prefix: 'tse2002', 'ts3000' - Addresses scanned: I2C 0x18 - 0x1f - Datasheets: - http://www.idt.com/sites/default/files/documents/IDT_TSE2002B3C_DST_20100512_120303152056.pdf - http://www.idt.com/sites/default/files/documents/IDT_TSE2002GB2A1_DST_20111107_120303145914.pdf - http://www.idt.com/sites/default/files/documents/IDT_TS3000B3A_DST_20101129_120303152013.pdf - http://www.idt.com/sites/default/files/documents/IDT_TS3000GB2A1_DST_20111104_120303151012.pdf + http://www.idt.com/products/getdoc.cfm?docid=18715691 + http://www.idt.com/products/getdoc.cfm?docid=18715692 * Maxim MAX6604 Prefix: 'max6604' Addresses scanned: I2C 0x18 - 0x1f Datasheets: http://datasheets.maxim-ic.com/en/ds/MAX6604.pdf - * Microchip MCP9804, MCP9805, MCP98242, MCP98243, MCP9843 - Prefixes: 'mcp9804', 'mcp9805', 'mcp98242', 'mcp98243', 'mcp9843' + * Microchip MCP9805, MCP98242, MCP98243, MCP9843 + Prefixes: 'mcp9805', 'mcp98242', 'mcp98243', 'mcp9843' Addresses scanned: I2C 0x18 - 0x1f Datasheets: - http://ww1.microchip.com/downloads/en/DeviceDoc/22203C.pdf http://ww1.microchip.com/downloads/en/DeviceDoc/21977b.pdf http://ww1.microchip.com/downloads/en/DeviceDoc/21996a.pdf http://ww1.microchip.com/downloads/en/DeviceDoc/22153c.pdf @@ -56,12 +48,6 @@ Supported chips: Datasheets: http://www.st.com/stonline/products/literature/ds/13447/stts424.pdf http://www.st.com/stonline/products/literature/ds/13448/stts424e02.pdf - * ST Microelectronics STTS2002, STTS3000 - Prefix: 'stts2002', 'stts3000' - Addresses scanned: I2C 0x18 - 0x1f - Datasheets: - http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00225278.pdf - http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATA_BRIEF/CD00270920.pdf * JEDEC JC 42.4 compliant temperature sensor chips Prefix: 'jc42' Addresses scanned: I2C 0x18 - 0x1f diff --git a/Documentation/hwspinlock.txt b/Documentation/hwspinlock.txt index 69966813d594..7dcd1a4e726c 100644 --- a/Documentation/hwspinlock.txt +++ b/Documentation/hwspinlock.txt @@ -39,20 +39,23 @@ independent, drivers. in case an unused hwspinlock isn't available. Users of this API will usually want to communicate the lock's id to the remote core before it can be used to achieve synchronization. - Should be called from a process context (might sleep). + Can be called from an atomic context (this function will not sleep) but + not from within interrupt context. struct hwspinlock *hwspin_lock_request_specific(unsigned int id); - assign a specific hwspinlock id and return its address, or NULL if that hwspinlock is already in use. Usually board code will be calling this function in order to reserve specific hwspinlock ids for predefined purposes. - Should be called from a process context (might sleep). + Can be called from an atomic context (this function will not sleep) but + not from within interrupt context. int hwspin_lock_free(struct hwspinlock *hwlock); - free a previously-assigned hwspinlock; returns 0 on success, or an appropriate error code on failure (e.g. -EINVAL if the hwspinlock is already free). - Should be called from a process context (might sleep). + Can be called from an atomic context (this function will not sleep) but + not from within interrupt context. int hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int timeout); - lock a previously-assigned hwspinlock with a timeout limit (specified in @@ -229,14 +232,15 @@ int hwspinlock_example2(void) int hwspin_lock_register(struct hwspinlock *hwlock); - to be called from the underlying platform-specific implementation, in - order to register a new hwspinlock instance. Should be called from - a process context (this function might sleep). - Returns 0 on success, or appropriate error code on failure. + order to register a new hwspinlock instance. Can be called from an atomic + context (this function will not sleep) but not from within interrupt + context. Returns 0 on success, or appropriate error code on failure. struct hwspinlock *hwspin_lock_unregister(unsigned int id); - to be called from the underlying vendor-specific implementation, in order to unregister an existing (and unused) hwspinlock instance. - Should be called from a process context (this function might sleep). + Can be called from an atomic context (will not sleep) but not from + within interrupt context. Returns the address of hwspinlock on success, or NULL on error (e.g. if the hwspinlock is sill in use). diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 397ee05132a3..aa47be71df4c 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1764,11 +1764,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. noresidual [PPC] Don't use residual data on PReP machines. - nordrand [X86] Disable the direct use of the RDRAND - instruction even if it is supported by the - processor. RDRAND is still available to user - space applications. - noresume [SWSUSP] Disables resume and restores original swap space. diff --git a/Documentation/networking/ifenslave.c b/Documentation/networking/ifenslave.c index 50f1dc49f481..2bac9618c345 100644 --- a/Documentation/networking/ifenslave.c +++ b/Documentation/networking/ifenslave.c @@ -539,14 +539,12 @@ static int if_getconfig(char *ifname) metric = 0; } else metric = ifr.ifr_metric; - printf("The result of SIOCGIFMETRIC is %d\n", metric); strcpy(ifr.ifr_name, ifname); if (ioctl(skfd, SIOCGIFMTU, &ifr) < 0) mtu = 0; else mtu = ifr.ifr_mtu; - printf("The result of SIOCGIFMTU is %d\n", mtu); strcpy(ifr.ifr_name, ifname); if (ioctl(skfd, SIOCGIFDSTADDR, &ifr) < 0) { diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 890fce9b3683..bfe924217f24 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -147,7 +147,7 @@ tcp_adv_win_scale - INTEGER (if tcp_adv_win_scale > 0) or bytes-bytes/2^(-tcp_adv_win_scale), if it is <= 0. Possible values are [-31, 31], inclusive. - Default: 1 + Default: 2 tcp_allowed_congestion_control - STRING Show/set the congestion control choices available to non-privileged @@ -407,7 +407,7 @@ tcp_rmem - vector of 3 INTEGERs: min, default, max net.core.rmem_max. Calling setsockopt() with SO_RCVBUF disables automatic tuning of that socket's receive buffer size, in which case this value is ignored. - Default: between 87380B and 6MB, depending on RAM size. + Default: between 87380B and 4MB, depending on RAM size. tcp_sack - BOOLEAN Enable select acknowledgments (SACKS). @@ -534,11 +534,6 @@ tcp_thin_dupack - BOOLEAN Documentation/networking/tcp-thin.txt Default: 0 -tcp_challenge_ack_limit - INTEGER - Limits number of Challenge ACK sent per second, as recommended - in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks) - Default: 100 - UDP variables: udp_mem - vector of 3 INTEGERs: min, pressure, max diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index a6b34307dec8..b24875b1ced5 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt @@ -469,7 +469,6 @@ pm_runtime_autosuspend() pm_runtime_resume() pm_runtime_get_sync() pm_runtime_put_sync_suspend() -pm_runtime_put_sync_autosuspend() 5. Run-time PM Initialization, Device Probing and Removal @@ -709,16 +708,6 @@ will behave normally, not taking the autosuspend delay into account. Similarly, if the power.use_autosuspend field isn't set then the autosuspend helper functions will behave just like the non-autosuspend counterparts. -Under some circumstances a driver or subsystem may want to prevent a device -from autosuspending immediately, even though the usage counter is zero and the -autosuspend delay time has expired. If the ->runtime_suspend() callback -returns -EAGAIN or -EBUSY, and if the next autosuspend delay expiration time is -in the future (as it normally would be if the callback invoked -pm_runtime_mark_last_busy()), the PM core will automatically reschedule the -autosuspend. The ->runtime_suspend() callback can't do this rescheduling -itself because no suspend requests of any kind are accepted while the device is -suspending (i.e., while the callback is running). - The implementation is well suited for asynchronous use in interrupt contexts. However such use inevitably involves races, because the PM core can't synchronize ->runtime_suspend() callbacks with the arrival of I/O requests. diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt index 22bf11b846cc..e213f45cf9d7 100644 --- a/Documentation/stable_kernel_rules.txt +++ b/Documentation/stable_kernel_rules.txt @@ -1,4 +1,4 @@ -Everything you ever wanted to know about Linux -stable releases. +Everything you ever wanted to know about Linux 2.6 -stable releases. Rules on what kind of patches are accepted, and which ones are not, into the "-stable" tree: @@ -12,12 +12,6 @@ Rules on what kind of patches are accepted, and which ones are not, into the marked CONFIG_BROKEN), an oops, a hang, data corruption, a real security issue, or some "oh, that's not good" issue. In short, something critical. - - Serious issues as reported by a user of a distribution kernel may also - be considered if they fix a notable performance or interactivity issue. - As these fixes are not as obvious and have a higher risk of a subtle - regression they should only be submitted by a distribution kernel - maintainer and include an addendum linking to a bugzilla entry if it - exists and additional information on the user-visible impact. - New device IDs and quirks are also accepted. - No "theoretical race condition" issues, unless an explanation of how the race can be exploited is also provided. @@ -30,10 +24,10 @@ Rules on what kind of patches are accepted, and which ones are not, into the Procedure for submitting patches to the -stable tree: - Send the patch, after verifying that it follows the above rules, to - stable@vger.kernel.org. You must note the upstream commit ID in the - changelog of your submission. + stable@kernel.org. You must note the upstream commit ID in the changelog + of your submission. - To have the patch automatically included in the stable tree, add the tag - Cc: stable@vger.kernel.org + Cc: stable@kernel.org in the sign-off area. Once the patch is merged it will be applied to the stable tree without anything else needing to be done by the author or subsystem maintainer. @@ -41,10 +35,10 @@ Procedure for submitting patches to the -stable tree: cherry-picked than this can be specified in the following format in the sign-off area: - Cc: # 3.3.x: a1f84a3: sched: Check for idle - Cc: # 3.3.x: 1b9508f: sched: Rate-limit newidle - Cc: # 3.3.x: fd21073: sched: Fix affinity logic - Cc: # 3.3.x + Cc: # .32.x: a1f84a3: sched: Check for idle + Cc: # .32.x: 1b9508f: sched: Rate-limit newidle + Cc: # .32.x: fd21073: sched: Fix affinity logic + Cc: # .32.x Signed-off-by: Ingo Molnar The tag sequence has the meaning of: @@ -78,15 +72,6 @@ Review cycle: security kernel team, and not go through the normal review cycle. Contact the kernel security team for more details on this procedure. -Trees: - - - The queues of patches, for both completed versions and in progress - versions can be found at: - http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git - - The finalized and tagged releases of all stable kernels can be found - in separate branches per version at: - http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git - Review committee: diff --git a/Documentation/trace/postprocess/trace-vmscan-postprocess.pl b/Documentation/trace/postprocess/trace-vmscan-postprocess.pl index 4a37c4759cd2..12cecc83cd91 100644 --- a/Documentation/trace/postprocess/trace-vmscan-postprocess.pl +++ b/Documentation/trace/postprocess/trace-vmscan-postprocess.pl @@ -379,10 +379,10 @@ EVENT_PROCESS: # To closer match vmstat scanning statistics, only count isolate_both # and isolate_inactive as scanning. isolate_active is rotation - # isolate_inactive == 1 - # isolate_active == 2 - # isolate_both == 3 - if ($isolate_mode != 2) { + # isolate_inactive == 0 + # isolate_active == 1 + # isolate_both == 2 + if ($isolate_mode != 1) { $perprocesspid{$process_pid}->{HIGH_NR_SCANNED} += $nr_scanned; } $perprocesspid{$process_pid}->{HIGH_NR_CONTIG_DIRTY} += $nr_contig_dirty; diff --git a/Documentation/usb/usbmon.txt b/Documentation/usb/usbmon.txt index 5335fa8b06eb..a4efa0462f05 100644 --- a/Documentation/usb/usbmon.txt +++ b/Documentation/usb/usbmon.txt @@ -47,11 +47,10 @@ This allows to filter away annoying devices that talk continuously. 2. Find which bus connects to the desired device -Run "cat /sys/kernel/debug/usb/devices", and find the T-line which corresponds -to the device. Usually you do it by looking for the vendor string. If you have -many similar devices, unplug one and compare the two -/sys/kernel/debug/usb/devices outputs. The T-line will have a bus number. -Example: +Run "cat /proc/bus/usb/devices", and find the T-line which corresponds to +the device. Usually you do it by looking for the vendor string. If you have +many similar devices, unplug one and compare two /proc/bus/usb/devices outputs. +The T-line will have a bus number. Example: T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 @@ -59,10 +58,7 @@ P: Vendor=0557 ProdID=2004 Rev= 1.00 S: Manufacturer=ATEN S: Product=UC100KM V2.00 -"Bus=03" means it's bus 3. Alternatively, you can look at the output from -"lsusb" and get the bus number from the appropriate line. Example: - -Bus 003 Device 002: ID 0557:2004 ATEN UC100KM V2.00 +Bus=03 means it's bus 3. 3. Start 'cat' diff --git a/Documentation/virtual/lguest/lguest.c b/Documentation/virtual/lguest/lguest.c index aec80e53c2d7..cd9d6af61d07 100644 --- a/Documentation/virtual/lguest/lguest.c +++ b/Documentation/virtual/lguest/lguest.c @@ -2008,9 +2008,6 @@ int main(int argc, char *argv[]) /* We use a simple helper to copy the arguments separated by spaces. */ concat((char *)(boot + 1), argv+optind+2); - /* Set kernel alignment to 16M (CONFIG_PHYSICAL_ALIGN) */ - boot->hdr.kernel_alignment = 0x1000000; - /* Boot protocol version: 2.07 supports the fields for lguest. */ boot->hdr.version = 0x207; diff --git a/MAINTAINERS b/MAINTAINERS index 105683a48f98..187282da9213 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1221,7 +1221,7 @@ F: Documentation/aoe/ F: drivers/block/aoe/ ATHEROS ATH GENERIC UTILITIES -M: "Luis R. Rodriguez" +M: "Luis R. Rodriguez" L: linux-wireless@vger.kernel.org S: Supported F: drivers/net/wireless/ath/* @@ -1229,7 +1229,7 @@ F: drivers/net/wireless/ath/* ATHEROS ATH5K WIRELESS DRIVER M: Jiri Slaby M: Nick Kossifidis -M: "Luis R. Rodriguez" +M: "Luis R. Rodriguez" M: Bob Copeland L: linux-wireless@vger.kernel.org L: ath5k-devel@lists.ath5k.org @@ -1238,10 +1238,10 @@ S: Maintained F: drivers/net/wireless/ath/ath5k/ ATHEROS ATH9K WIRELESS DRIVER -M: "Luis R. Rodriguez" -M: Jouni Malinen -M: Vasanthakumar Thiagarajan -M: Senthil Balasubramanian +M: "Luis R. Rodriguez" +M: Jouni Malinen +M: Vasanthakumar Thiagarajan +M: Senthil Balasubramanian L: linux-wireless@vger.kernel.org L: ath9k-devel@lists.ath9k.org W: http://wireless.kernel.org/en/users/Drivers/ath9k @@ -1269,7 +1269,7 @@ F: drivers/input/misc/ati_remote2.c ATLX ETHERNET DRIVERS M: Jay Cliburn M: Chris Snook -M: Jie Yang +M: Jie Yang L: netdev@vger.kernel.org W: http://sourceforge.net/projects/atl1 W: http://atl1.sourceforge.net @@ -2491,7 +2491,7 @@ S: Maintained F: drivers/net/eexpress.* ETHERNET BRIDGE -M: Stephen Hemminger +M: Stephen Hemminger L: bridge@lists.linux-foundation.org L: netdev@vger.kernel.org W: http://www.linuxfoundation.org/en/Net:Bridge @@ -4327,7 +4327,7 @@ S: Supported F: drivers/infiniband/hw/nes/ NETEM NETWORK EMULATOR -M: Stephen Hemminger +M: Stephen Hemminger L: netem@lists.linux-foundation.org S: Maintained F: net/sched/sch_netem.c @@ -5247,7 +5247,7 @@ F: Documentation/blockdev/ramdisk.txt F: drivers/block/brd.c RANDOM NUMBER DRIVER -M: Theodore Ts'o" +M: Matt Mackall S: Maintained F: drivers/char/random.c @@ -5779,7 +5779,7 @@ S: Maintained F: drivers/usb/misc/sisusbvga/ SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS -M: Stephen Hemminger +M: Stephen Hemminger L: netdev@vger.kernel.org S: Maintained F: drivers/net/skge.* @@ -6039,7 +6039,7 @@ F: arch/alpha/kernel/srm_env.c STABLE BRANCH M: Greg Kroah-Hartman -L: stable@vger.kernel.org +L: stable@kernel.org S: Maintained STAGING SUBSYSTEM @@ -6358,13 +6358,6 @@ S: Maintained F: Documentation/filesystems/ufs.txt F: fs/ufs/ -UHID USERSPACE HID IO DRIVER: -M: David Herrmann -L: linux-input@vger.kernel.org -S: Maintained -F: drivers/hid/uhid.c -F: include/linux/uhid.h - ULTRA-WIDEBAND (UWB) SUBSYSTEM: L: linux-usb@vger.kernel.org S: Orphan diff --git a/Makefile b/Makefile index da3ff219cf07..6a5bdad524af 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 3 PATCHLEVEL = 0 -SUBLEVEL = 66 +SUBLEVEL = 0 EXTRAVERSION = NAME = Sneaky Weasel diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h index b15162fedccc..e756d04b6cd5 100644 --- a/arch/alpha/include/asm/atomic.h +++ b/arch/alpha/include/asm/atomic.h @@ -14,8 +14,8 @@ */ -#define ATOMIC_INIT(i) { (i) } -#define ATOMIC64_INIT(i) { (i) } +#define ATOMIC_INIT(i) ( (atomic_t) { (i) } ) +#define ATOMIC64_INIT(i) ( (atomic64_t) { (i) } ) #define atomic_read(v) (*(volatile int *)&(v)->counter) #define atomic64_read(v) (*(volatile long *)&(v)->counter) diff --git a/arch/alpha/include/asm/futex.h b/arch/alpha/include/asm/futex.h index f939794363ac..e8a761aee088 100644 --- a/arch/alpha/include/asm/futex.h +++ b/arch/alpha/include/asm/futex.h @@ -108,7 +108,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, " lda $31,3b-2b(%0)\n" " .previous\n" : "+r"(ret), "=&r"(prev), "=&r"(cmp) - : "r"(uaddr), "r"((long)(int)oldval), "r"(newval) + : "r"(uaddr), "r"((long)oldval), "r"(newval) : "memory"); *uval = prev; diff --git a/arch/alpha/include/asm/socket.h b/arch/alpha/include/asm/socket.h index 3eeb47c50189..06edfefc3373 100644 --- a/arch/alpha/include/asm/socket.h +++ b/arch/alpha/include/asm/socket.h @@ -69,11 +69,9 @@ #define SO_RXQ_OVFL 40 -#ifdef __KERNEL__ /* O_NONBLOCK clashes with the bits used for socket types. Therefore we * have to define SOCK_NONBLOCK to a different value here. */ #define SOCK_NONBLOCK 0x40000000 -#endif /* __KERNEL__ */ #endif /* _ASM_SOCKET_H */ diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index f20d1b5396b8..818e74ed45dc 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -91,7 +91,7 @@ DEFINE_PER_CPU(u8, irq_work_pending); #define test_irq_work_pending() __get_cpu_var(irq_work_pending) #define clear_irq_work_pending() __get_cpu_var(irq_work_pending) = 0 -void arch_irq_work_raise(void) +void set_irq_work_pending(void) { set_irq_work_pending_flag(); } diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b9d60775cb8b..9adc278a22ab 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1179,7 +1179,7 @@ config ARM_ERRATA_743622 depends on CPU_V7 help This option enables the workaround for the 743622 Cortex-A9 - (r2p*) erratum. Under very rare conditions, a faulty + (r2p0..r2p2) erratum. Under very rare conditions, a faulty optimisation in the Cortex-A9 Store Buffer may lead to data corruption. This workaround sets a specific bit in the diagnostic register of the Cortex-A9 which disables the Store Buffer @@ -1234,42 +1234,6 @@ config ARM_ERRATA_754327 This workaround defines cpu_relax() as smp_mb(), preventing correctly written polling loops from denying visibility of updates to memory. -config ARM_ERRATA_764369 - bool "ARM errata: Data cache line maintenance operation by MVA may not succeed" - depends on CPU_V7 && SMP - help - This option enables the workaround for erratum 764369 - affecting Cortex-A9 MPCore with two or more processors (all - current revisions). Under certain timing circumstances, a data - cache line maintenance operation by MVA targeting an Inner - Shareable memory region may fail to proceed up to either the - Point of Coherency or to the Point of Unification of the - system. This workaround adds a DSB instruction before the - relevant cache maintenance functions and sets a specific bit - in the diagnostic control register of the SCU. - -config PL310_ERRATA_769419 - bool "PL310 errata: no automatic Store Buffer drain" - depends on CACHE_L2X0 - help - On revisions of the PL310 prior to r3p2, the Store Buffer does - not automatically drain. This can cause normal, non-cacheable - writes to be retained when the memory system is idle, leading - to suboptimal I/O performance for drivers using coherent DMA. - This option adds a write barrier to the cpu_idle loop so that, - on systems with an outer cache, the store buffer is drained - explicitly. - -config ARM_ERRATA_775420 - bool "ARM errata: A data cache maintenance operation which aborts, might lead to deadlock" - depends on CPU_V7 - help - This option enables the workaround for the 775420 Cortex-A9 (r2p2, - r2p6,r2p8,r2p10,r3p0) erratum. In case a date cache maintenance - operation aborts with MMU exception, it might cause the processor - to deadlock. This workaround puts DSB before executing ISB if - an abort may occur on cache maintenance. - endmenu source "arch/arm/common/Kconfig" @@ -1707,15 +1671,6 @@ config DEPRECATED_PARAM_STRUCT This was deprecated in 2001 and announced to live on for 5 years. Some old boot loaders still use this way. -config ARM_FLUSH_CONSOLE_ON_RESTART - bool "Force flush the console on restart" - help - If the console is locked while the system is rebooted, the messages - in the temporary logbuffer would not have propogated to all the - console drivers. This option forces the console lock to be - released if it failed to be acquired, which will cause all the - pending messages to be flushed. - endmenu menu "Boot options" @@ -1894,7 +1849,6 @@ source "drivers/cpufreq/Kconfig" config CPU_FREQ_IMX tristate "CPUfreq driver for i.MX CPUs" depends on ARCH_MXC && CPU_FREQ - select CPU_FREQ_TABLE help This enables the CPUfreq driver for i.MX CPUs. diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index caddb9d35b73..940b20178107 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -539,7 +539,6 @@ __armv7_mmu_cache_on: mcrne p15, 0, r0, c8, c7, 0 @ flush I,D TLBs #endif mrc p15, 0, r0, c1, c0, 0 @ read control reg - bic r0, r0, #1 << 28 @ clear SCTLR.TRE orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement orr r0, r0, #0x003c @ write buffer #ifdef CONFIG_MMU @@ -657,8 +656,6 @@ proc_types: @ b __arm6_mmu_cache_off @ b __armv3_mmu_cache_flush -#if !defined(CONFIG_CPU_V7) - /* This collides with some V7 IDs, preventing correct detection */ .word 0x00000000 @ old ARM ID .word 0x0000f000 mov pc, lr @@ -667,7 +664,6 @@ proc_types: THUMB( nop ) mov pc, lr THUMB( nop ) -#endif .word 0x41007000 @ ARM7/710 .word 0xfff8fe00 diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 638256600ffe..4b71766fb21d 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -39,53 +39,3 @@ config SHARP_PARAM config SHARP_SCOOP bool - -config FIQ_GLUE - bool - select FIQ - -config FIQ_DEBUGGER - bool "FIQ Mode Serial Debugger" - select FIQ - select FIQ_GLUE - default n - help - The FIQ serial debugger can accept commands even when the - kernel is unresponsive due to being stuck with interrupts - disabled. - - -config FIQ_DEBUGGER_NO_SLEEP - bool "Keep serial debugger active" - depends on FIQ_DEBUGGER - default n - help - Enables the serial debugger at boot. Passing - fiq_debugger.no_sleep on the kernel commandline will - override this config option. - -config FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON - bool "Don't disable wakeup IRQ when debugger is active" - depends on FIQ_DEBUGGER - default n - help - Don't disable the wakeup irq when enabling the uart clock. This will - cause extra interrupts, but it makes the serial debugger usable with - on some MSM radio builds that ignore the uart clock request in power - collapse. - -config FIQ_DEBUGGER_CONSOLE - bool "Console on FIQ Serial Debugger port" - depends on FIQ_DEBUGGER - default n - help - Enables a console so that printk messages are displayed on - the debugger serial port as the occur. - -config FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE - bool "Put the FIQ debugger into console mode by default" - depends on FIQ_DEBUGGER_CONSOLE - default n - help - If enabled, this puts the fiq debugger into console mode by default. - Otherwise, the fiq debugger will start out in debug mode. diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index 3ab5d765fedd..6ea9b6f3607a 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -17,5 +17,3 @@ obj-$(CONFIG_ARCH_IXP2000) += uengine.o obj-$(CONFIG_ARCH_IXP23XX) += uengine.o obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o -obj-$(CONFIG_FIQ_GLUE) += fiq_glue.o fiq_glue_setup.o -obj-$(CONFIG_FIQ_DEBUGGER) += fiq_debugger.o diff --git a/arch/arm/common/fiq_debugger.c b/arch/arm/common/fiq_debugger.c deleted file mode 100644 index 3ed18ae2ed80..000000000000 --- a/arch/arm/common/fiq_debugger.c +++ /dev/null @@ -1,1196 +0,0 @@ -/* - * arch/arm/common/fiq_debugger.c - * - * Serial Debugger Interface accessed through an FIQ interrupt. - * - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include - -#include "fiq_debugger_ringbuf.h" - -#define DEBUG_MAX 64 -#define MAX_UNHANDLED_FIQ_COUNT 1000000 - -#define THREAD_INFO(sp) ((struct thread_info *) \ - ((unsigned long)(sp) & ~(THREAD_SIZE - 1))) - -struct fiq_debugger_state { - struct fiq_glue_handler handler; - - int fiq; - int uart_irq; - int signal_irq; - int wakeup_irq; - bool wakeup_irq_no_set_wake; - struct clk *clk; - struct fiq_debugger_pdata *pdata; - struct platform_device *pdev; - - char debug_cmd[DEBUG_MAX]; - int debug_busy; - int debug_abort; - - char debug_buf[DEBUG_MAX]; - int debug_count; - - bool no_sleep; - bool debug_enable; - bool ignore_next_wakeup_irq; - struct timer_list sleep_timer; - spinlock_t sleep_timer_lock; - bool uart_enabled; - struct wake_lock debugger_wake_lock; - bool console_enable; - int current_cpu; - atomic_t unhandled_fiq_count; - bool in_fiq; - -#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE - struct console console; - struct tty_driver *tty_driver; - struct tty_struct *tty; - int tty_open_count; - struct fiq_debugger_ringbuf *tty_rbuf; - bool syslog_dumping; -#endif - - unsigned int last_irqs[NR_IRQS]; - unsigned int last_local_timer_irqs[NR_CPUS]; -}; - -#ifdef CONFIG_FIQ_DEBUGGER_NO_SLEEP -static bool initial_no_sleep = true; -#else -static bool initial_no_sleep; -#endif - -#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE -static bool initial_debug_enable = true; -static bool initial_console_enable = true; -#else -static bool initial_debug_enable; -static bool initial_console_enable; -#endif - -module_param_named(no_sleep, initial_no_sleep, bool, 0644); -module_param_named(debug_enable, initial_debug_enable, bool, 0644); -module_param_named(console_enable, initial_console_enable, bool, 0644); - -#ifdef CONFIG_FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON -static inline void enable_wakeup_irq(struct fiq_debugger_state *state) {} -static inline void disable_wakeup_irq(struct fiq_debugger_state *state) {} -#else -static inline void enable_wakeup_irq(struct fiq_debugger_state *state) -{ - if (state->wakeup_irq < 0) - return; - enable_irq(state->wakeup_irq); - if (!state->wakeup_irq_no_set_wake) - enable_irq_wake(state->wakeup_irq); -} -static inline void disable_wakeup_irq(struct fiq_debugger_state *state) -{ - if (state->wakeup_irq < 0) - return; - disable_irq_nosync(state->wakeup_irq); - if (!state->wakeup_irq_no_set_wake) - disable_irq_wake(state->wakeup_irq); -} -#endif - -static bool inline debug_have_fiq(struct fiq_debugger_state *state) -{ - return (state->fiq >= 0); -} - -static void debug_force_irq(struct fiq_debugger_state *state) -{ - unsigned int irq = state->signal_irq; - - if (WARN_ON(!debug_have_fiq(state))) - return; - if (state->pdata->force_irq) { - state->pdata->force_irq(state->pdev, irq); - } else { - struct irq_chip *chip = irq_get_chip(irq); - if (chip && chip->irq_retrigger) - chip->irq_retrigger(irq_get_irq_data(irq)); - } -} - -static void debug_uart_enable(struct fiq_debugger_state *state) -{ - if (state->clk) - clk_enable(state->clk); - if (state->pdata->uart_enable) - state->pdata->uart_enable(state->pdev); -} - -static void debug_uart_disable(struct fiq_debugger_state *state) -{ - if (state->pdata->uart_disable) - state->pdata->uart_disable(state->pdev); - if (state->clk) - clk_disable(state->clk); -} - -static void debug_uart_flush(struct fiq_debugger_state *state) -{ - if (state->pdata->uart_flush) - state->pdata->uart_flush(state->pdev); -} - -static void debug_puts(struct fiq_debugger_state *state, char *s) -{ - unsigned c; - while ((c = *s++)) { - if (c == '\n') - state->pdata->uart_putc(state->pdev, '\r'); - state->pdata->uart_putc(state->pdev, c); - } -} - -static void debug_prompt(struct fiq_debugger_state *state) -{ - debug_puts(state, "debug> "); -} - -int log_buf_copy(char *dest, int idx, int len); -static void dump_kernel_log(struct fiq_debugger_state *state) -{ - char buf[1024]; - int idx = 0; - int ret; - int saved_oip; - - /* setting oops_in_progress prevents log_buf_copy() - * from trying to take a spinlock which will make it - * very unhappy in some cases... - */ - saved_oip = oops_in_progress; - oops_in_progress = 1; - for (;;) { - ret = log_buf_copy(buf, idx, 1023); - if (ret <= 0) - break; - buf[ret] = 0; - debug_puts(state, buf); - idx += ret; - } - oops_in_progress = saved_oip; -} - -static char *mode_name(unsigned cpsr) -{ - switch (cpsr & MODE_MASK) { - case USR_MODE: return "USR"; - case FIQ_MODE: return "FIQ"; - case IRQ_MODE: return "IRQ"; - case SVC_MODE: return "SVC"; - case ABT_MODE: return "ABT"; - case UND_MODE: return "UND"; - case SYSTEM_MODE: return "SYS"; - default: return "???"; - } -} - -static int debug_printf(void *cookie, const char *fmt, ...) -{ - struct fiq_debugger_state *state = cookie; - char buf[256]; - va_list ap; - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - - debug_puts(state, buf); - return state->debug_abort; -} - -/* Safe outside fiq context */ -static int debug_printf_nfiq(void *cookie, const char *fmt, ...) -{ - struct fiq_debugger_state *state = cookie; - char buf[256]; - va_list ap; - unsigned long irq_flags; - - va_start(ap, fmt); - vsnprintf(buf, 128, fmt, ap); - va_end(ap); - - local_irq_save(irq_flags); - debug_puts(state, buf); - debug_uart_flush(state); - local_irq_restore(irq_flags); - return state->debug_abort; -} - -static void dump_regs(struct fiq_debugger_state *state, unsigned *regs) -{ - debug_printf(state, " r0 %08x r1 %08x r2 %08x r3 %08x\n", - regs[0], regs[1], regs[2], regs[3]); - debug_printf(state, " r4 %08x r5 %08x r6 %08x r7 %08x\n", - regs[4], regs[5], regs[6], regs[7]); - debug_printf(state, " r8 %08x r9 %08x r10 %08x r11 %08x mode %s\n", - regs[8], regs[9], regs[10], regs[11], - mode_name(regs[16])); - if ((regs[16] & MODE_MASK) == USR_MODE) - debug_printf(state, " ip %08x sp %08x lr %08x pc %08x " - "cpsr %08x\n", regs[12], regs[13], regs[14], - regs[15], regs[16]); - else - debug_printf(state, " ip %08x sp %08x lr %08x pc %08x " - "cpsr %08x spsr %08x\n", regs[12], regs[13], - regs[14], regs[15], regs[16], regs[17]); -} - -struct mode_regs { - unsigned long sp_svc; - unsigned long lr_svc; - unsigned long spsr_svc; - - unsigned long sp_abt; - unsigned long lr_abt; - unsigned long spsr_abt; - - unsigned long sp_und; - unsigned long lr_und; - unsigned long spsr_und; - - unsigned long sp_irq; - unsigned long lr_irq; - unsigned long spsr_irq; - - unsigned long r8_fiq; - unsigned long r9_fiq; - unsigned long r10_fiq; - unsigned long r11_fiq; - unsigned long r12_fiq; - unsigned long sp_fiq; - unsigned long lr_fiq; - unsigned long spsr_fiq; -}; - -void __naked get_mode_regs(struct mode_regs *regs) -{ - asm volatile ( - "mrs r1, cpsr\n" - "msr cpsr_c, #0xd3 @(SVC_MODE | PSR_I_BIT | PSR_F_BIT)\n" - "stmia r0!, {r13 - r14}\n" - "mrs r2, spsr\n" - "msr cpsr_c, #0xd7 @(ABT_MODE | PSR_I_BIT | PSR_F_BIT)\n" - "stmia r0!, {r2, r13 - r14}\n" - "mrs r2, spsr\n" - "msr cpsr_c, #0xdb @(UND_MODE | PSR_I_BIT | PSR_F_BIT)\n" - "stmia r0!, {r2, r13 - r14}\n" - "mrs r2, spsr\n" - "msr cpsr_c, #0xd2 @(IRQ_MODE | PSR_I_BIT | PSR_F_BIT)\n" - "stmia r0!, {r2, r13 - r14}\n" - "mrs r2, spsr\n" - "msr cpsr_c, #0xd1 @(FIQ_MODE | PSR_I_BIT | PSR_F_BIT)\n" - "stmia r0!, {r2, r8 - r14}\n" - "mrs r2, spsr\n" - "stmia r0!, {r2}\n" - "msr cpsr_c, r1\n" - "bx lr\n"); -} - - -static void dump_allregs(struct fiq_debugger_state *state, unsigned *regs) -{ - struct mode_regs mode_regs; - dump_regs(state, regs); - get_mode_regs(&mode_regs); - debug_printf(state, " svc: sp %08x lr %08x spsr %08x\n", - mode_regs.sp_svc, mode_regs.lr_svc, mode_regs.spsr_svc); - debug_printf(state, " abt: sp %08x lr %08x spsr %08x\n", - mode_regs.sp_abt, mode_regs.lr_abt, mode_regs.spsr_abt); - debug_printf(state, " und: sp %08x lr %08x spsr %08x\n", - mode_regs.sp_und, mode_regs.lr_und, mode_regs.spsr_und); - debug_printf(state, " irq: sp %08x lr %08x spsr %08x\n", - mode_regs.sp_irq, mode_regs.lr_irq, mode_regs.spsr_irq); - debug_printf(state, " fiq: r8 %08x r9 %08x r10 %08x r11 %08x " - "r12 %08x\n", - mode_regs.r8_fiq, mode_regs.r9_fiq, mode_regs.r10_fiq, - mode_regs.r11_fiq, mode_regs.r12_fiq); - debug_printf(state, " fiq: sp %08x lr %08x spsr %08x\n", - mode_regs.sp_fiq, mode_regs.lr_fiq, mode_regs.spsr_fiq); -} - -static void dump_irqs(struct fiq_debugger_state *state) -{ - int n; - unsigned int cpu; - - debug_printf(state, "irqnr total since-last status name\n"); - for (n = 0; n < NR_IRQS; n++) { - struct irqaction *act = irq_desc[n].action; - if (!act && !kstat_irqs(n)) - continue; - debug_printf(state, "%5d: %10u %11u %8x %s\n", n, - kstat_irqs(n), - kstat_irqs(n) - state->last_irqs[n], - irq_desc[n].status_use_accessors, - (act && act->name) ? act->name : "???"); - state->last_irqs[n] = kstat_irqs(n); - } - - for (cpu = 0; cpu < NR_CPUS; cpu++) { - - debug_printf(state, "LOC %d: %10u %11u\n", cpu, - __IRQ_STAT(cpu, local_timer_irqs), - __IRQ_STAT(cpu, local_timer_irqs) - - state->last_local_timer_irqs[cpu]); - state->last_local_timer_irqs[cpu] = - __IRQ_STAT(cpu, local_timer_irqs); - } -} - -struct stacktrace_state { - struct fiq_debugger_state *state; - unsigned int depth; -}; - -static int report_trace(struct stackframe *frame, void *d) -{ - struct stacktrace_state *sts = d; - - if (sts->depth) { - debug_printf(sts->state, - " pc: %p (%pF), lr %p (%pF), sp %p, fp %p\n", - frame->pc, frame->pc, frame->lr, frame->lr, - frame->sp, frame->fp); - sts->depth--; - return 0; - } - debug_printf(sts->state, " ...\n"); - - return sts->depth == 0; -} - -struct frame_tail { - struct frame_tail *fp; - unsigned long sp; - unsigned long lr; -} __attribute__((packed)); - -static struct frame_tail *user_backtrace(struct fiq_debugger_state *state, - struct frame_tail *tail) -{ - struct frame_tail buftail[2]; - - /* Also check accessibility of one struct frame_tail beyond */ - if (!access_ok(VERIFY_READ, tail, sizeof(buftail))) { - debug_printf(state, " invalid frame pointer %p\n", tail); - return NULL; - } - if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail))) { - debug_printf(state, - " failed to copy frame pointer %p\n", tail); - return NULL; - } - - debug_printf(state, " %p\n", buftail[0].lr); - - /* frame pointers should strictly progress back up the stack - * (towards higher addresses) */ - if (tail >= buftail[0].fp) - return NULL; - - return buftail[0].fp-1; -} - -void dump_stacktrace(struct fiq_debugger_state *state, - struct pt_regs * const regs, unsigned int depth, void *ssp) -{ - struct frame_tail *tail; - struct thread_info *real_thread_info = THREAD_INFO(ssp); - struct stacktrace_state sts; - - sts.depth = depth; - sts.state = state; - *current_thread_info() = *real_thread_info; - - if (!current) - debug_printf(state, "current NULL\n"); - else - debug_printf(state, "pid: %d comm: %s\n", - current->pid, current->comm); - dump_regs(state, (unsigned *)regs); - - if (!user_mode(regs)) { - struct stackframe frame; - frame.fp = regs->ARM_fp; - frame.sp = regs->ARM_sp; - frame.lr = regs->ARM_lr; - frame.pc = regs->ARM_pc; - debug_printf(state, - " pc: %p (%pF), lr %p (%pF), sp %p, fp %p\n", - regs->ARM_pc, regs->ARM_pc, regs->ARM_lr, regs->ARM_lr, - regs->ARM_sp, regs->ARM_fp); - walk_stackframe(&frame, report_trace, &sts); - return; - } - - tail = ((struct frame_tail *) regs->ARM_fp) - 1; - while (depth-- && tail && !((unsigned long) tail & 3)) - tail = user_backtrace(state, tail); -} - -static void do_ps(struct fiq_debugger_state *state) -{ - struct task_struct *g; - struct task_struct *p; - unsigned task_state; - static const char stat_nam[] = "RSDTtZX"; - - debug_printf(state, "pid ppid prio task pc\n"); - read_lock(&tasklist_lock); - do_each_thread(g, p) { - task_state = p->state ? __ffs(p->state) + 1 : 0; - debug_printf(state, - "%5d %5d %4d ", p->pid, p->parent->pid, p->prio); - debug_printf(state, "%-13.13s %c", p->comm, - task_state >= sizeof(stat_nam) ? '?' : stat_nam[task_state]); - if (task_state == TASK_RUNNING) - debug_printf(state, " running\n"); - else - debug_printf(state, " %08lx\n", thread_saved_pc(p)); - } while_each_thread(g, p); - read_unlock(&tasklist_lock); -} - -#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE -static void begin_syslog_dump(struct fiq_debugger_state *state) -{ - state->syslog_dumping = true; -} - -static void end_syslog_dump(struct fiq_debugger_state *state) -{ - state->syslog_dumping = false; -} -#else -extern int do_syslog(int type, char __user *bug, int count); -static void begin_syslog_dump(struct fiq_debugger_state *state) -{ - do_syslog(5 /* clear */, NULL, 0); -} - -static void end_syslog_dump(struct fiq_debugger_state *state) -{ - char buf[128]; - int ret; - int idx = 0; - - while (1) { - ret = log_buf_copy(buf, idx, sizeof(buf) - 1); - if (ret <= 0) - break; - buf[ret] = 0; - debug_printf(state, "%s", buf); - idx += ret; - } -} -#endif - -static void do_sysrq(struct fiq_debugger_state *state, char rq) -{ - begin_syslog_dump(state); - handle_sysrq(rq); - end_syslog_dump(state); -} - -/* This function CANNOT be called in FIQ context */ -static void debug_irq_exec(struct fiq_debugger_state *state, char *cmd) -{ - if (!strcmp(cmd, "ps")) - do_ps(state); - if (!strcmp(cmd, "sysrq")) - do_sysrq(state, 'h'); - if (!strncmp(cmd, "sysrq ", 6)) - do_sysrq(state, cmd[6]); -} - -static void debug_help(struct fiq_debugger_state *state) -{ - debug_printf(state, "FIQ Debugger commands:\n" - " pc PC status\n" - " regs Register dump\n" - " allregs Extended Register dump\n" - " bt Stack trace\n" - " reboot Reboot\n" - " irqs Interupt status\n" - " kmsg Kernel log\n" - " version Kernel version\n"); - debug_printf(state, " sleep Allow sleep while in FIQ\n" - " nosleep Disable sleep while in FIQ\n" - " console Switch terminal to console\n" - " cpu Current CPU\n" - " cpu Switch to CPU\n"); - debug_printf(state, " ps Process list\n" - " sysrq sysrq options\n" - " sysrq Execute sysrq with \n"); -} - -static void take_affinity(void *info) -{ - struct fiq_debugger_state *state = info; - struct cpumask cpumask; - - cpumask_clear(&cpumask); - cpumask_set_cpu(get_cpu(), &cpumask); - - irq_set_affinity(state->uart_irq, &cpumask); -} - -static void switch_cpu(struct fiq_debugger_state *state, int cpu) -{ - if (!debug_have_fiq(state)) - smp_call_function_single(cpu, take_affinity, state, false); - state->current_cpu = cpu; -} - -static bool debug_fiq_exec(struct fiq_debugger_state *state, - const char *cmd, unsigned *regs, void *svc_sp) -{ - bool signal_helper = false; - - if (!strcmp(cmd, "help") || !strcmp(cmd, "?")) { - debug_help(state); - } else if (!strcmp(cmd, "pc")) { - debug_printf(state, " pc %08x cpsr %08x mode %s\n", - regs[15], regs[16], mode_name(regs[16])); - } else if (!strcmp(cmd, "regs")) { - dump_regs(state, regs); - } else if (!strcmp(cmd, "allregs")) { - dump_allregs(state, regs); - } else if (!strcmp(cmd, "bt")) { - dump_stacktrace(state, (struct pt_regs *)regs, 100, svc_sp); - } else if (!strcmp(cmd, "reboot")) { - arch_reset(0, 0); - } else if (!strcmp(cmd, "irqs")) { - dump_irqs(state); - } else if (!strcmp(cmd, "kmsg")) { - dump_kernel_log(state); - } else if (!strcmp(cmd, "version")) { - debug_printf(state, "%s\n", linux_banner); - } else if (!strcmp(cmd, "sleep")) { - state->no_sleep = false; - debug_printf(state, "enabling sleep\n"); - } else if (!strcmp(cmd, "nosleep")) { - state->no_sleep = true; - debug_printf(state, "disabling sleep\n"); - } else if (!strcmp(cmd, "console")) { - state->console_enable = true; - debug_printf(state, "console mode\n"); - } else if (!strcmp(cmd, "cpu")) { - debug_printf(state, "cpu %d\n", state->current_cpu); - } else if (!strncmp(cmd, "cpu ", 4)) { - unsigned long cpu = 0; - if (strict_strtoul(cmd + 4, 10, &cpu) == 0) - switch_cpu(state, cpu); - else - debug_printf(state, "invalid cpu\n"); - debug_printf(state, "cpu %d\n", state->current_cpu); - } else { - if (state->debug_busy) { - debug_printf(state, - "command processor busy. trying to abort.\n"); - state->debug_abort = -1; - } else { - strcpy(state->debug_cmd, cmd); - state->debug_busy = 1; - } - - return true; - } - if (!state->console_enable) - debug_prompt(state); - - return signal_helper; -} - -static void sleep_timer_expired(unsigned long data) -{ - struct fiq_debugger_state *state = (struct fiq_debugger_state *)data; - unsigned long flags; - - spin_lock_irqsave(&state->sleep_timer_lock, flags); - if (state->uart_enabled && !state->no_sleep) { - if (state->debug_enable && !state->console_enable) { - state->debug_enable = false; - debug_printf_nfiq(state, "suspending fiq debugger\n"); - } - state->ignore_next_wakeup_irq = true; - debug_uart_disable(state); - state->uart_enabled = false; - enable_wakeup_irq(state); - } - wake_unlock(&state->debugger_wake_lock); - spin_unlock_irqrestore(&state->sleep_timer_lock, flags); -} - -static void handle_wakeup(struct fiq_debugger_state *state) -{ - unsigned long flags; - - spin_lock_irqsave(&state->sleep_timer_lock, flags); - if (state->wakeup_irq >= 0 && state->ignore_next_wakeup_irq) { - state->ignore_next_wakeup_irq = false; - } else if (!state->uart_enabled) { - wake_lock(&state->debugger_wake_lock); - debug_uart_enable(state); - state->uart_enabled = true; - disable_wakeup_irq(state); - mod_timer(&state->sleep_timer, jiffies + HZ / 2); - } - spin_unlock_irqrestore(&state->sleep_timer_lock, flags); -} - -static irqreturn_t wakeup_irq_handler(int irq, void *dev) -{ - struct fiq_debugger_state *state = dev; - - if (!state->no_sleep) - debug_puts(state, "WAKEUP\n"); - handle_wakeup(state); - - return IRQ_HANDLED; -} - - -static void debug_handle_irq_context(struct fiq_debugger_state *state) -{ - if (!state->no_sleep) { - unsigned long flags; - - spin_lock_irqsave(&state->sleep_timer_lock, flags); - wake_lock(&state->debugger_wake_lock); - mod_timer(&state->sleep_timer, jiffies + HZ * 5); - spin_unlock_irqrestore(&state->sleep_timer_lock, flags); - } -#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE) - if (state->tty) { - int i; - int count = fiq_debugger_ringbuf_level(state->tty_rbuf); - for (i = 0; i < count; i++) { - int c = fiq_debugger_ringbuf_peek(state->tty_rbuf, 0); - tty_insert_flip_char(state->tty, c, TTY_NORMAL); - if (!fiq_debugger_ringbuf_consume(state->tty_rbuf, 1)) - pr_warn("fiq tty failed to consume byte\n"); - } - tty_flip_buffer_push(state->tty); - } -#endif - if (state->debug_busy) { - debug_irq_exec(state, state->debug_cmd); - debug_prompt(state); - state->debug_busy = 0; - } -} - -static int debug_getc(struct fiq_debugger_state *state) -{ - return state->pdata->uart_getc(state->pdev); -} - -static bool debug_handle_uart_interrupt(struct fiq_debugger_state *state, - int this_cpu, void *regs, void *svc_sp) -{ - int c; - static int last_c; - int count = 0; - bool signal_helper = false; - - if (this_cpu != state->current_cpu) { - if (state->in_fiq) - return false; - - if (atomic_inc_return(&state->unhandled_fiq_count) != - MAX_UNHANDLED_FIQ_COUNT) - return false; - - debug_printf(state, "fiq_debugger: cpu %d not responding, " - "reverting to cpu %d\n", state->current_cpu, - this_cpu); - - atomic_set(&state->unhandled_fiq_count, 0); - switch_cpu(state, this_cpu); - return false; - } - - state->in_fiq = true; - - while ((c = debug_getc(state)) != FIQ_DEBUGGER_NO_CHAR) { - count++; - if (!state->debug_enable) { - if ((c == 13) || (c == 10)) { - state->debug_enable = true; - state->debug_count = 0; - debug_prompt(state); - } - } else if (c == FIQ_DEBUGGER_BREAK) { - state->console_enable = false; - debug_puts(state, "fiq debugger mode\n"); - state->debug_count = 0; - debug_prompt(state); -#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE - } else if (state->console_enable && state->tty_rbuf) { - fiq_debugger_ringbuf_push(state->tty_rbuf, c); - signal_helper = true; -#endif - } else if ((c >= ' ') && (c < 127)) { - if (state->debug_count < (DEBUG_MAX - 1)) { - state->debug_buf[state->debug_count++] = c; - state->pdata->uart_putc(state->pdev, c); - } - } else if ((c == 8) || (c == 127)) { - if (state->debug_count > 0) { - state->debug_count--; - state->pdata->uart_putc(state->pdev, 8); - state->pdata->uart_putc(state->pdev, ' '); - state->pdata->uart_putc(state->pdev, 8); - } - } else if ((c == 13) || (c == 10)) { - if (c == '\r' || (c == '\n' && last_c != '\r')) { - state->pdata->uart_putc(state->pdev, '\r'); - state->pdata->uart_putc(state->pdev, '\n'); - } - if (state->debug_count) { - state->debug_buf[state->debug_count] = 0; - state->debug_count = 0; - signal_helper |= - debug_fiq_exec(state, state->debug_buf, - regs, svc_sp); - } else { - debug_prompt(state); - } - } - last_c = c; - } - debug_uart_flush(state); - if (state->pdata->fiq_ack) - state->pdata->fiq_ack(state->pdev, state->fiq); - - /* poke sleep timer if necessary */ - if (state->debug_enable && !state->no_sleep) - signal_helper = true; - - atomic_set(&state->unhandled_fiq_count, 0); - state->in_fiq = false; - - return signal_helper; -} - -static void debug_fiq(struct fiq_glue_handler *h, void *regs, void *svc_sp) -{ - struct fiq_debugger_state *state = - container_of(h, struct fiq_debugger_state, handler); - unsigned int this_cpu = THREAD_INFO(svc_sp)->cpu; - bool need_irq; - - need_irq = debug_handle_uart_interrupt(state, this_cpu, regs, svc_sp); - if (need_irq) - debug_force_irq(state); -} - -/* - * When not using FIQs, we only use this single interrupt as an entry point. - * This just effectively takes over the UART interrupt and does all the work - * in this context. - */ -static irqreturn_t debug_uart_irq(int irq, void *dev) -{ - struct fiq_debugger_state *state = dev; - bool not_done; - - handle_wakeup(state); - - /* handle the debugger irq in regular context */ - not_done = debug_handle_uart_interrupt(state, smp_processor_id(), - get_irq_regs(), - current_thread_info()); - if (not_done) - debug_handle_irq_context(state); - - return IRQ_HANDLED; -} - -/* - * If FIQs are used, not everything can happen in fiq context. - * FIQ handler does what it can and then signals this interrupt to finish the - * job in irq context. - */ -static irqreturn_t debug_signal_irq(int irq, void *dev) -{ - struct fiq_debugger_state *state = dev; - - if (state->pdata->force_irq_ack) - state->pdata->force_irq_ack(state->pdev, state->signal_irq); - - debug_handle_irq_context(state); - - return IRQ_HANDLED; -} - -static void debug_resume(struct fiq_glue_handler *h) -{ - struct fiq_debugger_state *state = - container_of(h, struct fiq_debugger_state, handler); - if (state->pdata->uart_resume) - state->pdata->uart_resume(state->pdev); -} - -#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE) -struct tty_driver *debug_console_device(struct console *co, int *index) -{ - struct fiq_debugger_state *state; - state = container_of(co, struct fiq_debugger_state, console); - *index = 0; - return state->tty_driver; -} - -static void debug_console_write(struct console *co, - const char *s, unsigned int count) -{ - struct fiq_debugger_state *state; - - state = container_of(co, struct fiq_debugger_state, console); - - if (!state->console_enable && !state->syslog_dumping) - return; - - debug_uart_enable(state); - while (count--) { - if (*s == '\n') - state->pdata->uart_putc(state->pdev, '\r'); - state->pdata->uart_putc(state->pdev, *s++); - } - debug_uart_flush(state); - debug_uart_disable(state); -} - -static struct console fiq_debugger_console = { - .name = "ttyFIQ", - .device = debug_console_device, - .write = debug_console_write, - .flags = CON_PRINTBUFFER | CON_ANYTIME | CON_ENABLED, -}; - -int fiq_tty_open(struct tty_struct *tty, struct file *filp) -{ - struct fiq_debugger_state *state = tty->driver->driver_state; - if (state->tty_open_count++) - return 0; - - tty->driver_data = state; - state->tty = tty; - return 0; -} - -void fiq_tty_close(struct tty_struct *tty, struct file *filp) -{ - struct fiq_debugger_state *state = tty->driver_data; - if (--state->tty_open_count) - return; - state->tty = NULL; -} - -int fiq_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) -{ - int i; - struct fiq_debugger_state *state = tty->driver_data; - - if (!state->console_enable) - return count; - - debug_uart_enable(state); - for (i = 0; i < count; i++) - state->pdata->uart_putc(state->pdev, *buf++); - debug_uart_disable(state); - - return count; -} - -int fiq_tty_write_room(struct tty_struct *tty) -{ - return 1024; -} - -static const struct tty_operations fiq_tty_driver_ops = { - .write = fiq_tty_write, - .write_room = fiq_tty_write_room, - .open = fiq_tty_open, - .close = fiq_tty_close, -}; - -static int fiq_debugger_tty_init(struct fiq_debugger_state *state) -{ - int ret = -EINVAL; - - state->tty_driver = alloc_tty_driver(1); - if (!state->tty_driver) { - pr_err("Failed to allocate fiq debugger tty\n"); - return -ENOMEM; - } - - state->tty_driver->owner = THIS_MODULE; - state->tty_driver->driver_name = "fiq-debugger"; - state->tty_driver->name = "ttyFIQ"; - state->tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - state->tty_driver->subtype = SERIAL_TYPE_NORMAL; - state->tty_driver->init_termios = tty_std_termios; - state->tty_driver->init_termios.c_cflag = - B115200 | CS8 | CREAD | HUPCL | CLOCAL; - state->tty_driver->init_termios.c_ispeed = - state->tty_driver->init_termios.c_ospeed = 115200; - state->tty_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(state->tty_driver, &fiq_tty_driver_ops); - state->tty_driver->driver_state = state; - - ret = tty_register_driver(state->tty_driver); - if (ret) { - pr_err("Failed to register fiq tty: %d\n", ret); - goto err; - } - - state->tty_rbuf = fiq_debugger_ringbuf_alloc(1024); - if (!state->tty_rbuf) { - pr_err("Failed to allocate fiq debugger ringbuf\n"); - ret = -ENOMEM; - goto err; - } - - pr_info("Registered FIQ tty driver %p\n", state->tty_driver); - return 0; - -err: - fiq_debugger_ringbuf_free(state->tty_rbuf); - state->tty_rbuf = NULL; - put_tty_driver(state->tty_driver); - return ret; -} -#endif - -static int fiq_debugger_dev_suspend(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct fiq_debugger_state *state = platform_get_drvdata(pdev); - - if (state->pdata->uart_dev_suspend) - return state->pdata->uart_dev_suspend(pdev); - return 0; -} - -static int fiq_debugger_dev_resume(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct fiq_debugger_state *state = platform_get_drvdata(pdev); - - if (state->pdata->uart_dev_resume) - return state->pdata->uart_dev_resume(pdev); - return 0; -} - -static int fiq_debugger_probe(struct platform_device *pdev) -{ - int ret; - struct fiq_debugger_pdata *pdata = dev_get_platdata(&pdev->dev); - struct fiq_debugger_state *state; - int fiq; - int uart_irq; - - if (!pdata->uart_getc || !pdata->uart_putc) - return -EINVAL; - if ((pdata->uart_enable && !pdata->uart_disable) || - (!pdata->uart_enable && pdata->uart_disable)) - return -EINVAL; - - fiq = platform_get_irq_byname(pdev, "fiq"); - uart_irq = platform_get_irq_byname(pdev, "uart_irq"); - - /* uart_irq mode and fiq mode are mutually exclusive, but one of them - * is required */ - if ((uart_irq < 0 && fiq < 0) || (uart_irq >= 0 && fiq >= 0)) - return -EINVAL; - if (fiq >= 0 && !pdata->fiq_enable) - return -EINVAL; - - state = kzalloc(sizeof(*state), GFP_KERNEL); - setup_timer(&state->sleep_timer, sleep_timer_expired, - (unsigned long)state); - state->pdata = pdata; - state->pdev = pdev; - state->no_sleep = initial_no_sleep; - state->debug_enable = initial_debug_enable; - state->console_enable = initial_console_enable; - - state->fiq = fiq; - state->uart_irq = uart_irq; - state->signal_irq = platform_get_irq_byname(pdev, "signal"); - state->wakeup_irq = platform_get_irq_byname(pdev, "wakeup"); - - platform_set_drvdata(pdev, state); - - spin_lock_init(&state->sleep_timer_lock); - - if (state->wakeup_irq < 0 && debug_have_fiq(state)) - state->no_sleep = true; - state->ignore_next_wakeup_irq = !state->no_sleep; - - wake_lock_init(&state->debugger_wake_lock, - WAKE_LOCK_SUSPEND, "serial-debug"); - - state->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(state->clk)) - state->clk = NULL; - - /* do not call pdata->uart_enable here since uart_init may still - * need to do some initialization before uart_enable can work. - * So, only try to manage the clock during init. - */ - if (state->clk) - clk_enable(state->clk); - - if (pdata->uart_init) { - ret = pdata->uart_init(pdev); - if (ret) - goto err_uart_init; - } - - debug_printf_nfiq(state, "\n", - state->no_sleep ? "" : "twice "); - - if (debug_have_fiq(state)) { - state->handler.fiq = debug_fiq; - state->handler.resume = debug_resume; - ret = fiq_glue_register_handler(&state->handler); - if (ret) { - pr_err("%s: could not install fiq handler\n", __func__); - goto err_register_fiq; - } - - pdata->fiq_enable(pdev, state->fiq, 1); - } else { - ret = request_irq(state->uart_irq, debug_uart_irq, - IRQF_NO_SUSPEND, "debug", state); - if (ret) { - pr_err("%s: could not install irq handler\n", __func__); - goto err_register_irq; - } - - /* for irq-only mode, we want this irq to wake us up, if it - * can. - */ - enable_irq_wake(state->uart_irq); - } - - if (state->clk) - clk_disable(state->clk); - - if (state->signal_irq >= 0) { - ret = request_irq(state->signal_irq, debug_signal_irq, - IRQF_TRIGGER_RISING, "debug-signal", state); - if (ret) - pr_err("serial_debugger: could not install signal_irq"); - } - - if (state->wakeup_irq >= 0) { - ret = request_irq(state->wakeup_irq, wakeup_irq_handler, - IRQF_TRIGGER_FALLING | IRQF_DISABLED, - "debug-wakeup", state); - if (ret) { - pr_err("serial_debugger: " - "could not install wakeup irq\n"); - state->wakeup_irq = -1; - } else { - ret = enable_irq_wake(state->wakeup_irq); - if (ret) { - pr_err("serial_debugger: " - "could not enable wakeup\n"); - state->wakeup_irq_no_set_wake = true; - } - } - } - if (state->no_sleep) - handle_wakeup(state); - -#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE) - state->console = fiq_debugger_console; - register_console(&state->console); - fiq_debugger_tty_init(state); -#endif - return 0; - -err_register_irq: -err_register_fiq: - if (pdata->uart_free) - pdata->uart_free(pdev); -err_uart_init: - if (state->clk) - clk_disable(state->clk); - if (state->clk) - clk_put(state->clk); - wake_lock_destroy(&state->debugger_wake_lock); - platform_set_drvdata(pdev, NULL); - kfree(state); - return ret; -} - -static const struct dev_pm_ops fiq_debugger_dev_pm_ops = { - .suspend = fiq_debugger_dev_suspend, - .resume = fiq_debugger_dev_resume, -}; - -static struct platform_driver fiq_debugger_driver = { - .probe = fiq_debugger_probe, - .driver = { - .name = "fiq_debugger", - .pm = &fiq_debugger_dev_pm_ops, - }, -}; - -static int __init fiq_debugger_init(void) -{ - return platform_driver_register(&fiq_debugger_driver); -} - -postcore_initcall(fiq_debugger_init); diff --git a/arch/arm/common/fiq_debugger_ringbuf.h b/arch/arm/common/fiq_debugger_ringbuf.h deleted file mode 100644 index 2649b5581088..000000000000 --- a/arch/arm/common/fiq_debugger_ringbuf.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * arch/arm/common/fiq_debugger_ringbuf.c - * - * simple lockless ringbuffer - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include - -struct fiq_debugger_ringbuf { - int len; - int head; - int tail; - u8 buf[]; -}; - - -static inline struct fiq_debugger_ringbuf *fiq_debugger_ringbuf_alloc(int len) -{ - struct fiq_debugger_ringbuf *rbuf; - - rbuf = kzalloc(sizeof(*rbuf) + len, GFP_KERNEL); - if (rbuf == NULL) - return NULL; - - rbuf->len = len; - rbuf->head = 0; - rbuf->tail = 0; - smp_mb(); - - return rbuf; -} - -static inline void fiq_debugger_ringbuf_free(struct fiq_debugger_ringbuf *rbuf) -{ - kfree(rbuf); -} - -static inline int fiq_debugger_ringbuf_level(struct fiq_debugger_ringbuf *rbuf) -{ - int level = rbuf->head - rbuf->tail; - - if (level < 0) - level = rbuf->len + level; - - return level; -} - -static inline int fiq_debugger_ringbuf_room(struct fiq_debugger_ringbuf *rbuf) -{ - return rbuf->len - fiq_debugger_ringbuf_level(rbuf) - 1; -} - -static inline u8 -fiq_debugger_ringbuf_peek(struct fiq_debugger_ringbuf *rbuf, int i) -{ - return rbuf->buf[(rbuf->tail + i) % rbuf->len]; -} - -static inline int -fiq_debugger_ringbuf_consume(struct fiq_debugger_ringbuf *rbuf, int count) -{ - count = min(count, fiq_debugger_ringbuf_level(rbuf)); - - rbuf->tail = (rbuf->tail + count) % rbuf->len; - smp_mb(); - - return count; -} - -static inline int -fiq_debugger_ringbuf_push(struct fiq_debugger_ringbuf *rbuf, u8 datum) -{ - if (fiq_debugger_ringbuf_room(rbuf) == 0) - return 0; - - rbuf->buf[rbuf->head] = datum; - smp_mb(); - rbuf->head = (rbuf->head + 1) % rbuf->len; - smp_mb(); - - return 1; -} diff --git a/arch/arm/common/fiq_glue.S b/arch/arm/common/fiq_glue.S deleted file mode 100644 index 9e3455a09f8f..000000000000 --- a/arch/arm/common/fiq_glue.S +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include - - .text - - .global fiq_glue_end - - /* fiq stack: r0-r15,cpsr,spsr of interrupted mode */ - -ENTRY(fiq_glue) - /* store pc, cpsr from previous mode */ - mrs r12, spsr - sub r11, lr, #4 - subs r10, #1 - bne nested_fiq - - stmfd sp!, {r11-r12, lr} - - /* store r8-r14 from previous mode */ - sub sp, sp, #(7 * 4) - stmia sp, {r8-r14}^ - nop - - /* store r0-r7 from previous mode */ - stmfd sp!, {r0-r7} - - /* setup func(data,regs) arguments */ - mov r0, r9 - mov r1, sp - mov r3, r8 - - mov r7, sp - - /* Get sp and lr from non-user modes */ - and r4, r12, #MODE_MASK - cmp r4, #USR_MODE - beq fiq_from_usr_mode - - mov r7, sp - orr r4, r4, #(PSR_I_BIT | PSR_F_BIT) - msr cpsr_c, r4 - str sp, [r7, #(4 * 13)] - str lr, [r7, #(4 * 14)] - mrs r5, spsr - str r5, [r7, #(4 * 17)] - - cmp r4, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT) - /* use fiq stack if we reenter this mode */ - subne sp, r7, #(4 * 3) - -fiq_from_usr_mode: - msr cpsr_c, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT) - mov r2, sp - sub sp, r7, #12 - stmfd sp!, {r2, ip, lr} - /* call func(data,regs) */ - blx r3 - ldmfd sp, {r2, ip, lr} - mov sp, r2 - - /* restore/discard saved state */ - cmp r4, #USR_MODE - beq fiq_from_usr_mode_exit - - msr cpsr_c, r4 - ldr sp, [r7, #(4 * 13)] - ldr lr, [r7, #(4 * 14)] - msr spsr_cxsf, r5 - -fiq_from_usr_mode_exit: - msr cpsr_c, #(FIQ_MODE | PSR_I_BIT | PSR_F_BIT) - - ldmfd sp!, {r0-r7} - add sp, sp, #(7 * 4) - ldmfd sp!, {r11-r12, lr} -exit_fiq: - msr spsr_cxsf, r12 - add r10, #1 - movs pc, r11 - -nested_fiq: - orr r12, r12, #(PSR_F_BIT) - b exit_fiq - -fiq_glue_end: - -ENTRY(fiq_glue_setup) /* func, data, sp */ - mrs r3, cpsr - msr cpsr_c, #(FIQ_MODE | PSR_I_BIT | PSR_F_BIT) - movs r8, r0 - mov r9, r1 - mov sp, r2 - moveq r10, #0 - movne r10, #1 - msr cpsr_c, r3 - bx lr - diff --git a/arch/arm/common/fiq_glue_setup.c b/arch/arm/common/fiq_glue_setup.c deleted file mode 100644 index 4044c7db95c8..000000000000 --- a/arch/arm/common/fiq_glue_setup.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include - -extern unsigned char fiq_glue, fiq_glue_end; -extern void fiq_glue_setup(void *func, void *data, void *sp); - -static struct fiq_handler fiq_debbuger_fiq_handler = { - .name = "fiq_glue", -}; -DEFINE_PER_CPU(void *, fiq_stack); -static struct fiq_glue_handler *current_handler; -static DEFINE_MUTEX(fiq_glue_lock); - -static void fiq_glue_setup_helper(void *info) -{ - struct fiq_glue_handler *handler = info; - fiq_glue_setup(handler->fiq, handler, - __get_cpu_var(fiq_stack) + THREAD_START_SP); -} - -int fiq_glue_register_handler(struct fiq_glue_handler *handler) -{ - int ret; - int cpu; - - if (!handler || !handler->fiq) - return -EINVAL; - - mutex_lock(&fiq_glue_lock); - if (fiq_stack) { - ret = -EBUSY; - goto err_busy; - } - - for_each_possible_cpu(cpu) { - void *stack; - stack = (void *)__get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER); - if (WARN_ON(!stack)) { - ret = -ENOMEM; - goto err_alloc_fiq_stack; - } - per_cpu(fiq_stack, cpu) = stack; - } - - ret = claim_fiq(&fiq_debbuger_fiq_handler); - if (WARN_ON(ret)) - goto err_claim_fiq; - - current_handler = handler; - on_each_cpu(fiq_glue_setup_helper, handler, true); - set_fiq_handler(&fiq_glue, &fiq_glue_end - &fiq_glue); - - mutex_unlock(&fiq_glue_lock); - return 0; - -err_claim_fiq: -err_alloc_fiq_stack: - for_each_possible_cpu(cpu) { - __free_pages(per_cpu(fiq_stack, cpu), THREAD_SIZE_ORDER); - per_cpu(fiq_stack, cpu) = NULL; - } -err_busy: - mutex_unlock(&fiq_glue_lock); - return ret; -} - -/** - * fiq_glue_resume - Restore fiqs after suspend or low power idle states - * - * This must be called before calling local_fiq_enable after returning from a - * power state where the fiq mode registers were lost. If a driver provided - * a resume hook when it registered the handler it will be called. - */ - -void fiq_glue_resume(void) -{ - if (!current_handler) - return; - fiq_glue_setup(current_handler->fiq, current_handler, - __get_cpu_var(fiq_stack) + THREAD_START_SP); - if (current_handler->resume) - current_handler->resume(current_handler); -} - diff --git a/arch/arm/configs/ezx_defconfig b/arch/arm/configs/ezx_defconfig index d95763d5f0d8..227a477346ed 100644 --- a/arch/arm/configs/ezx_defconfig +++ b/arch/arm/configs/ezx_defconfig @@ -287,7 +287,7 @@ CONFIG_USB=y # CONFIG_USB_DEVICE_CLASS is not set CONFIG_USB_OHCI_HCD=y CONFIG_USB_GADGET=y -CONFIG_USB_PXA27X=y +CONFIG_USB_GADGET_PXA27X=y CONFIG_USB_ETH=m # CONFIG_USB_ETH_RNDIS is not set CONFIG_MMC=y diff --git a/arch/arm/configs/imote2_defconfig b/arch/arm/configs/imote2_defconfig index fd996bb13022..176ec22af034 100644 --- a/arch/arm/configs/imote2_defconfig +++ b/arch/arm/configs/imote2_defconfig @@ -263,7 +263,7 @@ CONFIG_USB=y # CONFIG_USB_DEVICE_CLASS is not set CONFIG_USB_OHCI_HCD=y CONFIG_USB_GADGET=y -CONFIG_USB_PXA27X=y +CONFIG_USB_GADGET_PXA27X=y CONFIG_USB_ETH=m # CONFIG_USB_ETH_RNDIS is not set CONFIG_MMC=y diff --git a/arch/arm/configs/magician_defconfig b/arch/arm/configs/magician_defconfig index 443675d317e6..a88e64d4e9a5 100644 --- a/arch/arm/configs/magician_defconfig +++ b/arch/arm/configs/magician_defconfig @@ -132,7 +132,7 @@ CONFIG_USB_MON=m CONFIG_USB_OHCI_HCD=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_VBUS_DRAW=500 -CONFIG_USB_PXA27X=y +CONFIG_USB_GADGET_PXA27X=y CONFIG_USB_ETH=m # CONFIG_USB_ETH_RNDIS is not set CONFIG_USB_GADGETFS=m diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index 166d6aa97c4d..2bf224310fb4 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig @@ -29,6 +29,7 @@ CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_PREEMPT_VOLUNTARY=y CONFIG_AEABI=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 CONFIG_AUTO_ZRELADDR=y CONFIG_FPE_NWFPE=y CONFIG_NET=y diff --git a/arch/arm/configs/zeus_defconfig b/arch/arm/configs/zeus_defconfig index 547a3c1e59db..59577ad3f4ef 100644 --- a/arch/arm/configs/zeus_defconfig +++ b/arch/arm/configs/zeus_defconfig @@ -140,7 +140,7 @@ CONFIG_USB_SERIAL=m CONFIG_USB_SERIAL_GENERIC=y CONFIG_USB_SERIAL_MCT_U232=m CONFIG_USB_GADGET=m -CONFIG_USB_PXA27X=y +CONFIG_USB_GADGET_PXA27X=y CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m CONFIG_USB_FILE_STORAGE=m diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 4e25f1888356..65c3f2474f5e 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -137,11 +137,6 @@ disable_irq .endm - .macro save_and_disable_irqs_notrace, oldcpsr - mrs \oldcpsr, cpsr - disable_irq_notrace - .endm - /* * Restore interrupt state previously stored in a register. We don't * guarantee that this will preserve the flags. diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 42dec04f6170..d5d8d5c72682 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -215,9 +215,7 @@ static inline void vivt_flush_cache_mm(struct mm_struct *mm) static inline void vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { - struct mm_struct *mm = vma->vm_mm; - - if (!mm || cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) + if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end), vma->vm_flags); } @@ -225,9 +223,7 @@ vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned static inline void vivt_flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn) { - struct mm_struct *mm = vma->vm_mm; - - if (!mm || cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) { + if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { unsigned long addr = user_addr & PAGE_MASK; __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags); } @@ -253,7 +249,7 @@ extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr * Harvard caches are synchronised for the user space address range. * This is used for the ARM private sys_cacheflush system call. */ -#define flush_cache_user_range(start,end) \ +#define flush_cache_user_range(vma,start,end) \ __cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end)) /* diff --git a/arch/arm/include/asm/fiq_debugger.h b/arch/arm/include/asm/fiq_debugger.h deleted file mode 100644 index 4d274883ba6a..000000000000 --- a/arch/arm/include/asm/fiq_debugger.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * arch/arm/include/asm/fiq_debugger.h - * - * Copyright (C) 2010 Google, Inc. - * Author: Colin Cross - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _ARCH_ARM_MACH_TEGRA_FIQ_DEBUGGER_H_ -#define _ARCH_ARM_MACH_TEGRA_FIQ_DEBUGGER_H_ - -#include - -#define FIQ_DEBUGGER_NO_CHAR NO_POLL_CHAR -#define FIQ_DEBUGGER_BREAK 0x00ff0100 - -#define FIQ_DEBUGGER_FIQ_IRQ_NAME "fiq" -#define FIQ_DEBUGGER_SIGNAL_IRQ_NAME "signal" -#define FIQ_DEBUGGER_WAKEUP_IRQ_NAME "wakeup" - -/** - * struct fiq_debugger_pdata - fiq debugger platform data - * @uart_resume: used to restore uart state right before enabling - * the fiq. - * @uart_enable: Do the work necessary to communicate with the uart - * hw (enable clocks, etc.). This must be ref-counted. - * @uart_disable: Do the work necessary to disable the uart hw - * (disable clocks, etc.). This must be ref-counted. - * @uart_dev_suspend: called during PM suspend, generally not needed - * for real fiq mode debugger. - * @uart_dev_resume: called during PM resume, generally not needed - * for real fiq mode debugger. - */ -struct fiq_debugger_pdata { - int (*uart_init)(struct platform_device *pdev); - void (*uart_free)(struct platform_device *pdev); - int (*uart_resume)(struct platform_device *pdev); - int (*uart_getc)(struct platform_device *pdev); - void (*uart_putc)(struct platform_device *pdev, unsigned int c); - void (*uart_flush)(struct platform_device *pdev); - void (*uart_enable)(struct platform_device *pdev); - void (*uart_disable)(struct platform_device *pdev); - - int (*uart_dev_suspend)(struct platform_device *pdev); - int (*uart_dev_resume)(struct platform_device *pdev); - - void (*fiq_enable)(struct platform_device *pdev, unsigned int fiq, - bool enable); - void (*fiq_ack)(struct platform_device *pdev, unsigned int fiq); - - void (*force_irq)(struct platform_device *pdev, unsigned int irq); - void (*force_irq_ack)(struct platform_device *pdev, unsigned int irq); -}; - -#endif diff --git a/arch/arm/include/asm/fiq_glue.h b/arch/arm/include/asm/fiq_glue.h deleted file mode 100644 index d54c29db97a8..000000000000 --- a/arch/arm/include/asm/fiq_glue.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __ASM_FIQ_GLUE_H -#define __ASM_FIQ_GLUE_H - -struct fiq_glue_handler { - void (*fiq)(struct fiq_glue_handler *h, void *regs, void *svc_sp); - void (*resume)(struct fiq_glue_handler *h); -}; - -int fiq_glue_register_handler(struct fiq_glue_handler *handler); - -#ifdef CONFIG_FIQ_GLUE -void fiq_glue_resume(void); -#else -static inline void fiq_glue_resume(void) {} -#endif - -#endif diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h index 253cc86318bf..8c73900da9ed 100644 --- a/arch/arm/include/asm/futex.h +++ b/arch/arm/include/asm/futex.h @@ -25,17 +25,17 @@ #ifdef CONFIG_SMP -#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \ +#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ smp_mb(); \ __asm__ __volatile__( \ - "1: ldrex %1, [%3]\n" \ + "1: ldrex %1, [%2]\n" \ " " insn "\n" \ - "2: strex %2, %0, [%3]\n" \ - " teq %2, #0\n" \ + "2: strex %1, %0, [%2]\n" \ + " teq %1, #0\n" \ " bne 1b\n" \ " mov %0, #0\n" \ - __futex_atomic_ex_table("%5") \ - : "=&r" (ret), "=&r" (oldval), "=&r" (tmp) \ + __futex_atomic_ex_table("%4") \ + : "=&r" (ret), "=&r" (oldval) \ : "r" (uaddr), "r" (oparg), "Ir" (-EFAULT) \ : "cc", "memory") @@ -73,14 +73,14 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, #include #include -#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \ +#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ __asm__ __volatile__( \ - "1: " T(ldr) " %1, [%3]\n" \ + "1: " T(ldr) " %1, [%2]\n" \ " " insn "\n" \ - "2: " T(str) " %0, [%3]\n" \ + "2: " T(str) " %0, [%2]\n" \ " mov %0, #0\n" \ - __futex_atomic_ex_table("%5") \ - : "=&r" (ret), "=&r" (oldval), "=&r" (tmp) \ + __futex_atomic_ex_table("%4") \ + : "=&r" (ret), "=&r" (oldval) \ : "r" (uaddr), "r" (oparg), "Ir" (-EFAULT) \ : "cc", "memory") @@ -117,7 +117,7 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) int cmp = (encoded_op >> 24) & 15; int oparg = (encoded_op << 8) >> 20; int cmparg = (encoded_op << 20) >> 20; - int oldval = 0, ret, tmp; + int oldval = 0, ret; if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) oparg = 1 << oparg; @@ -129,19 +129,19 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) switch (op) { case FUTEX_OP_SET: - __futex_atomic_op("mov %0, %4", ret, oldval, tmp, uaddr, oparg); + __futex_atomic_op("mov %0, %3", ret, oldval, uaddr, oparg); break; case FUTEX_OP_ADD: - __futex_atomic_op("add %0, %1, %4", ret, oldval, tmp, uaddr, oparg); + __futex_atomic_op("add %0, %1, %3", ret, oldval, uaddr, oparg); break; case FUTEX_OP_OR: - __futex_atomic_op("orr %0, %1, %4", ret, oldval, tmp, uaddr, oparg); + __futex_atomic_op("orr %0, %1, %3", ret, oldval, uaddr, oparg); break; case FUTEX_OP_ANDN: - __futex_atomic_op("and %0, %1, %4", ret, oldval, tmp, uaddr, ~oparg); + __futex_atomic_op("and %0, %1, %3", ret, oldval, uaddr, ~oparg); break; case FUTEX_OP_XOR: - __futex_atomic_op("eor %0, %1, %4", ret, oldval, tmp, uaddr, oparg); + __futex_atomic_op("eor %0, %1, %3", ret, oldval, uaddr, oparg); break; default: ret = -ENOSYS; diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h index 2635c8b5bf59..89ad1805e579 100644 --- a/arch/arm/include/asm/hardirq.h +++ b/arch/arm/include/asm/hardirq.h @@ -5,7 +5,7 @@ #include #include -#define NR_IPI 6 +#define NR_IPI 5 typedef struct { unsigned int __softirq_pending; diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h index 2a20876ee3dd..16bd48031583 100644 --- a/arch/arm/include/asm/hardware/cache-l2x0.h +++ b/arch/arm/include/asm/hardware/cache-l2x0.h @@ -57,7 +57,6 @@ #define L2X0_STNDBY_MODE_EN (1 << 0) /* Registers shifts and masks */ -#define L2X0_CACHE_ID_REV_MASK (0x3f) #define L2X0_CACHE_ID_PART_MASK (0xf << 6) #define L2X0_CACHE_ID_PART_L210 (1 << 6) #define L2X0_CACHE_ID_PART_L310 (3 << 6) @@ -65,7 +64,7 @@ #define L2X0_AUX_CTRL_MASK 0xc0000fff #define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT 16 #define L2X0_AUX_CTRL_WAY_SIZE_SHIFT 17 -#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x7 << 17) +#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x3 << 17) #define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT 22 #define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT 26 #define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT 27 @@ -73,8 +72,6 @@ #define L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT 29 #define L2X0_AUX_CTRL_EARLY_BRESP_SHIFT 30 -#define REV_PL310_R2P0 4 - #ifndef __ASSEMBLY__ extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask); #endif diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h index 6643d6c4f35e..7ecd793b8f5a 100644 --- a/arch/arm/include/asm/hardware/coresight.h +++ b/arch/arm/include/asm/hardware/coresight.h @@ -17,17 +17,15 @@ #define TRACER_ACCESSED_BIT 0 #define TRACER_RUNNING_BIT 1 #define TRACER_CYCLE_ACC_BIT 2 -#define TRACER_TRACE_DATA_BIT 3 #define TRACER_ACCESSED BIT(TRACER_ACCESSED_BIT) #define TRACER_RUNNING BIT(TRACER_RUNNING_BIT) #define TRACER_CYCLE_ACC BIT(TRACER_CYCLE_ACC_BIT) -#define TRACER_TRACE_DATA BIT(TRACER_TRACE_DATA_BIT) #define TRACER_TIMEOUT 10000 -#define etm_writel(t, id, v, x) \ - (__raw_writel((v), (t)->etm_regs[(id)] + (x))) -#define etm_readl(t, id, x) (__raw_readl((t)->etm_regs[(id)] + (x))) +#define etm_writel(t, v, x) \ + (__raw_writel((v), (t)->etm_regs + (x))) +#define etm_readl(t, x) (__raw_readl((t)->etm_regs + (x))) /* CoreSight Management Registers */ #define CSMR_LOCKACCESS 0xfb0 @@ -115,19 +113,11 @@ #define ETMR_TRACEENCTRL 0x24 #define ETMTE_INCLEXCL BIT(24) #define ETMR_TRACEENEVT 0x20 - -#define ETMR_VIEWDATAEVT 0x30 -#define ETMR_VIEWDATACTRL1 0x34 -#define ETMR_VIEWDATACTRL2 0x38 -#define ETMR_VIEWDATACTRL3 0x3c -#define ETMVDC3_EXCLONLY BIT(16) - #define ETMCTRL_OPTS (ETMCTRL_DO_CPRT | \ + ETMCTRL_DATA_DO_ADDR | \ ETMCTRL_BRANCH_OUTPUT | \ ETMCTRL_DO_CONTEXTID) -#define ETMR_TRACEIDR 0x200 - /* ETM management registers, "ETM Architecture", 3.5.24 */ #define ETMMR_OSLAR 0x300 #define ETMMR_OSLSR 0x304 @@ -150,16 +140,14 @@ #define ETBFF_TRIGIN BIT(8) #define ETBFF_TRIGEVT BIT(9) #define ETBFF_TRIGFL BIT(10) -#define ETBFF_STOPFL BIT(12) #define etb_writel(t, v, x) \ (__raw_writel((v), (t)->etb_regs + (x))) #define etb_readl(t, x) (__raw_readl((t)->etb_regs + (x))) -#define etm_lock(t, id) \ - do { etm_writel((t), (id), 0, CSMR_LOCKACCESS); } while (0) -#define etm_unlock(t, id) \ - do { etm_writel((t), (id), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0) +#define etm_lock(t) do { etm_writel((t), 0, CSMR_LOCKACCESS); } while (0) +#define etm_unlock(t) \ + do { etm_writel((t), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0) #define etb_lock(t) do { etb_writel((t), 0, CSMR_LOCKACCESS); } while (0) #define etb_unlock(t) \ diff --git a/arch/arm/include/asm/hwcap.h b/arch/arm/include/asm/hwcap.h index 1e3f30f535f5..c1062c317103 100644 --- a/arch/arm/include/asm/hwcap.h +++ b/arch/arm/include/asm/hwcap.h @@ -18,9 +18,8 @@ #define HWCAP_THUMBEE 2048 #define HWCAP_NEON 4096 #define HWCAP_VFPv3 8192 -#define HWCAP_VFPv3D16 (1 << 14) /* also set for VFPv4-D16 */ +#define HWCAP_VFPv3D16 16384 #define HWCAP_TLS 32768 -#define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */ #if defined(__KERNEL__) && !defined(__ASSEMBLY__) /* diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h index 28810c6be9d4..2721a5814cb9 100644 --- a/arch/arm/include/asm/irq.h +++ b/arch/arm/include/asm/irq.h @@ -25,9 +25,6 @@ extern void migrate_irqs(void); extern void asm_do_IRQ(unsigned int, struct pt_regs *); void init_IRQ(void); -void arch_trigger_all_cpu_backtrace(void); -#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace - #endif #endif diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h deleted file mode 100644 index bca864ac945f..000000000000 --- a/arch/arm/include/asm/mach/mmc.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * arch/arm/include/asm/mach/mmc.h - */ -#ifndef ASMARM_MACH_MMC_H -#define ASMARM_MACH_MMC_H - -#include -#include -#include - -struct embedded_sdio_data { - struct sdio_cis cis; - struct sdio_cccr cccr; - struct sdio_embedded_func *funcs; - int num_funcs; -}; - -struct mmc_platform_data { - unsigned int ocr_mask; /* available voltages */ - int built_in; /* built-in device flag */ - int card_present; /* card detect state */ - u32 (*translate_vdd)(struct device *, unsigned int); - unsigned int (*status)(struct device *); - struct embedded_sdio_data *embedded_sdio; - int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id); -}; - -#endif diff --git a/arch/arm/include/asm/mutex.h b/arch/arm/include/asm/mutex.h index b1479fd04a95..93226cf23ae0 100644 --- a/arch/arm/include/asm/mutex.h +++ b/arch/arm/include/asm/mutex.h @@ -7,10 +7,121 @@ */ #ifndef _ASM_MUTEX_H #define _ASM_MUTEX_H + +#if __LINUX_ARM_ARCH__ < 6 +/* On pre-ARMv6 hardware the swp based implementation is the most efficient. */ +# include +#else + /* - * On pre-ARMv6 hardware this results in a swp-based implementation, - * which is the most efficient. For ARMv6+, we emit a pair of exclusive - * accesses instead. + * Attempting to lock a mutex on ARMv6+ can be done with a bastardized + * atomic decrement (it is not a reliable atomic decrement but it satisfies + * the defined semantics for our purpose, while being smaller and faster + * than a real atomic decrement or atomic swap. The idea is to attempt + * decrementing the lock value only once. If once decremented it isn't zero, + * or if its store-back fails due to a dispute on the exclusive store, we + * simply bail out immediately through the slow path where the lock will be + * reattempted until it succeeds. */ -#include +static inline void +__mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *)) +{ + int __ex_flag, __res; + + __asm__ ( + + "ldrex %0, [%2] \n\t" + "sub %0, %0, #1 \n\t" + "strex %1, %0, [%2] " + + : "=&r" (__res), "=&r" (__ex_flag) + : "r" (&(count)->counter) + : "cc","memory" ); + + __res |= __ex_flag; + if (unlikely(__res != 0)) + fail_fn(count); +} + +static inline int +__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) +{ + int __ex_flag, __res; + + __asm__ ( + + "ldrex %0, [%2] \n\t" + "sub %0, %0, #1 \n\t" + "strex %1, %0, [%2] " + + : "=&r" (__res), "=&r" (__ex_flag) + : "r" (&(count)->counter) + : "cc","memory" ); + + __res |= __ex_flag; + if (unlikely(__res != 0)) + __res = fail_fn(count); + return __res; +} + +/* + * Same trick is used for the unlock fast path. However the original value, + * rather than the result, is used to test for success in order to have + * better generated assembly. + */ +static inline void +__mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *)) +{ + int __ex_flag, __res, __orig; + + __asm__ ( + + "ldrex %0, [%3] \n\t" + "add %1, %0, #1 \n\t" + "strex %2, %1, [%3] " + + : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) + : "r" (&(count)->counter) + : "cc","memory" ); + + __orig |= __ex_flag; + if (unlikely(__orig != 0)) + fail_fn(count); +} + +/* + * If the unlock was done on a contended lock, or if the unlock simply fails + * then the mutex remains locked. + */ +#define __mutex_slowpath_needs_to_unlock() 1 + +/* + * For __mutex_fastpath_trylock we use another construct which could be + * described as a "single value cmpxchg". + * + * This provides the needed trylock semantics like cmpxchg would, but it is + * lighter and less generic than a true cmpxchg implementation. + */ +static inline int +__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *)) +{ + int __ex_flag, __res, __orig; + + __asm__ ( + + "1: ldrex %0, [%3] \n\t" + "subs %1, %0, #1 \n\t" + "strexeq %2, %1, [%3] \n\t" + "movlt %0, #0 \n\t" + "cmpeq %2, #0 \n\t" + "bgt 1b " + + : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) + : "r" (&count->counter) + : "cc", "memory" ); + + return __orig; +} + +#endif #endif diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 6afd081be23f..5750704e0271 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -360,18 +360,6 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd) #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) #define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) -#define pte_none(pte) (!pte_val(pte)) -#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT) -#define pte_write(pte) (!(pte_val(pte) & L_PTE_RDONLY)) -#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) -#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) -#define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN)) -#define pte_special(pte) (0) - -#define pte_present_user(pte) \ - ((pte_val(pte) & (L_PTE_PRESENT | L_PTE_USER)) == \ - (L_PTE_PRESENT | L_PTE_USER)) - #if __LINUX_ARM_ARCH__ < 6 static inline void __sync_icache_dcache(pte_t pteval) { @@ -383,16 +371,26 @@ extern void __sync_icache_dcache(pte_t pteval); static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval) { - unsigned long ext = 0; - - if (addr < TASK_SIZE && pte_present_user(pteval)) { + if (addr >= TASK_SIZE) + set_pte_ext(ptep, pteval, 0); + else { __sync_icache_dcache(pteval); - ext |= PTE_EXT_NG; + set_pte_ext(ptep, pteval, PTE_EXT_NG); } - - set_pte_ext(ptep, pteval, ext); } +#define pte_none(pte) (!pte_val(pte)) +#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT) +#define pte_write(pte) (!(pte_val(pte) & L_PTE_RDONLY)) +#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) +#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) +#define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN)) +#define pte_special(pte) (0) + +#define pte_present_user(pte) \ + ((pte_val(pte) & (L_PTE_PRESENT | L_PTE_USER)) == \ + (L_PTE_PRESENT | L_PTE_USER)) + #define PTE_BIT_FUNC(fn,op) \ static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } @@ -418,13 +416,13 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) * * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * <--------------- offset ----------------------> < type -> 0 0 0 + * <--------------- offset --------------------> <- type --> 0 0 0 * - * This gives us up to 31 swap files and 64GB per swap file. Note that + * This gives us up to 63 swap files and 32GB per swap file. Note that * the offset field is always non-zero. */ #define __SWP_TYPE_SHIFT 3 -#define __SWP_TYPE_BITS 5 +#define __SWP_TYPE_BITS 6 #define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1) #define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT) diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h index 74f288f4802c..e42d96a45d3e 100644 --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h @@ -93,6 +93,4 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); */ extern void show_local_irqs(struct seq_file *, int); -extern void smp_send_all_cpu_backtrace(void); - #endif /* ifndef __ASM_ARM_SMP_H */ diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h index 73409e6c0251..60843eb0f61c 100644 --- a/arch/arm/include/asm/tls.h +++ b/arch/arm/include/asm/tls.h @@ -7,8 +7,6 @@ .macro set_tls_v6k, tp, tmp1, tmp2 mcr p15, 0, \tp, c13, c0, 3 @ set TLS register - mov \tmp1, #0 - mcr p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register .endm .macro set_tls_v6, tp, tmp1, tmp2 @@ -17,8 +15,6 @@ mov \tmp2, #0xffff0fff tst \tmp1, #HWCAP_TLS @ hardware TLS available? mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register - movne \tmp1, #0 - mcrne p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0 .endm diff --git a/arch/arm/include/asm/vfpmacros.h b/arch/arm/include/asm/vfpmacros.h index c49c8f778b5d..3d5fc41ae8d3 100644 --- a/arch/arm/include/asm/vfpmacros.h +++ b/arch/arm/include/asm/vfpmacros.h @@ -27,9 +27,9 @@ #if __LINUX_ARM_ARCH__ <= 6 ldr \tmp, =elf_hwcap @ may not have MVFR regs ldr \tmp, [\tmp, #0] - tst \tmp, #HWCAP_VFPD32 - ldcnel p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} - addeq \base, \base, #32*4 @ step over unused register space + tst \tmp, #HWCAP_VFPv3D16 + ldceq p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} + addne \base, \base, #32*4 @ step over unused register space #else VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field @@ -51,9 +51,9 @@ #if __LINUX_ARM_ARCH__ <= 6 ldr \tmp, =elf_hwcap @ may not have MVFR regs ldr \tmp, [\tmp, #0] - tst \tmp, #HWCAP_VFPD32 - stcnel p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} - addeq \base, \base, #32*4 @ step over unused register space + tst \tmp, #HWCAP_VFPv3D16 + stceq p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} + addne \base, \base, #32*4 @ step over unused register space #else VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 2cd00764016d..90c62cd51ca9 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -496,7 +496,7 @@ __und_usr: blo __und_usr_unknown 3: ldrht r0, [r4] add r2, r2, #2 @ r2 is PC + 2, make it PC + 4 - orr r0, r0, r5, lsl #16 + orr r0, r0, r5, lsl #16 #else b __und_usr_unknown #endif diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c index 496b8b84e455..1bec8b5f22f0 100644 --- a/arch/arm/kernel/etm.c +++ b/arch/arm/kernel/etm.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -37,36 +36,26 @@ MODULE_AUTHOR("Alexander Shishkin"); struct tracectx { unsigned int etb_bufsz; void __iomem *etb_regs; - void __iomem **etm_regs; - int etm_regs_count; + void __iomem *etm_regs; unsigned long flags; int ncmppairs; int etm_portsz; - u32 etb_fc; - unsigned long range_start; - unsigned long range_end; - unsigned long data_range_start; - unsigned long data_range_end; - bool dump_initial_etb; struct device *dev; struct clk *emu_clk; struct mutex mutex; }; -static struct tracectx tracer = { - .range_start = (unsigned long)_stext, - .range_end = (unsigned long)_etext, -}; +static struct tracectx tracer; static inline bool trace_isrunning(struct tracectx *t) { return !!(t->flags & TRACER_RUNNING); } -static int etm_setup_address_range(struct tracectx *t, int id, int n, +static int etm_setup_address_range(struct tracectx *t, int n, unsigned long start, unsigned long end, int exclude, int data) { - u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_IGNSECURITY | + u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_NSONLY | \ ETMAAT_NOVALCMP; if (n < 1 || n > t->ncmppairs) @@ -82,155 +71,95 @@ static int etm_setup_address_range(struct tracectx *t, int id, int n, flags |= ETMAAT_IEXEC; /* first comparator for the range */ - etm_writel(t, id, flags, ETMR_COMP_ACC_TYPE(n * 2)); - etm_writel(t, id, start, ETMR_COMP_VAL(n * 2)); + etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2)); + etm_writel(t, start, ETMR_COMP_VAL(n * 2)); /* second comparator is right next to it */ - etm_writel(t, id, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1)); - etm_writel(t, id, end, ETMR_COMP_VAL(n * 2 + 1)); - - if (data) { - flags = exclude ? ETMVDC3_EXCLONLY : 0; - if (exclude) - n += 8; - etm_writel(t, id, flags | BIT(n), ETMR_VIEWDATACTRL3); - } else { - flags = exclude ? ETMTE_INCLEXCL : 0; - etm_writel(t, id, flags | (1 << n), ETMR_TRACEENCTRL); - } + etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1)); + etm_writel(t, end, ETMR_COMP_VAL(n * 2 + 1)); + + flags = exclude ? ETMTE_INCLEXCL : 0; + etm_writel(t, flags | (1 << n), ETMR_TRACEENCTRL); return 0; } -static int trace_start_etm(struct tracectx *t, int id) +static int trace_start(struct tracectx *t) { u32 v; unsigned long timeout = TRACER_TIMEOUT; + etb_unlock(t); + + etb_writel(t, 0, ETBR_FORMATTERCTRL); + etb_writel(t, 1, ETBR_CTRL); + + etb_lock(t); + + /* configure etm */ v = ETMCTRL_OPTS | ETMCTRL_PROGRAM | ETMCTRL_PORTSIZE(t->etm_portsz); if (t->flags & TRACER_CYCLE_ACC) v |= ETMCTRL_CYCLEACCURATE; - if (t->flags & TRACER_TRACE_DATA) - v |= ETMCTRL_DATA_DO_ADDR; - - etm_unlock(t, id); + etm_unlock(t); - etm_writel(t, id, v, ETMR_CTRL); + etm_writel(t, v, ETMR_CTRL); - while (!(etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout) + while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout) ; if (!timeout) { dev_dbg(t->dev, "Waiting for progbit to assert timed out\n"); - etm_lock(t, id); + etm_lock(t); return -EFAULT; } - if (t->range_start || t->range_end) - etm_setup_address_range(t, id, 1, - t->range_start, t->range_end, 0, 0); - else - etm_writel(t, id, ETMTE_INCLEXCL, ETMR_TRACEENCTRL); - - etm_writel(t, id, 0, ETMR_TRACEENCTRL2); - etm_writel(t, id, 0, ETMR_TRACESSCTRL); - etm_writel(t, id, 0x6f, ETMR_TRACEENEVT); - - etm_writel(t, id, 0, ETMR_VIEWDATACTRL1); - etm_writel(t, id, 0, ETMR_VIEWDATACTRL2); - - if (t->data_range_start || t->data_range_end) - etm_setup_address_range(t, id, 2, t->data_range_start, - t->data_range_end, 0, 1); - else - etm_writel(t, id, ETMVDC3_EXCLONLY, ETMR_VIEWDATACTRL3); - - etm_writel(t, id, 0x6f, ETMR_VIEWDATAEVT); + etm_setup_address_range(t, 1, (unsigned long)_stext, + (unsigned long)_etext, 0, 0); + etm_writel(t, 0, ETMR_TRACEENCTRL2); + etm_writel(t, 0, ETMR_TRACESSCTRL); + etm_writel(t, 0x6f, ETMR_TRACEENEVT); v &= ~ETMCTRL_PROGRAM; v |= ETMCTRL_PORTSEL; - etm_writel(t, id, v, ETMR_CTRL); + etm_writel(t, v, ETMR_CTRL); timeout = TRACER_TIMEOUT; - while (etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM && --timeout) + while (etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM && --timeout) ; if (!timeout) { dev_dbg(t->dev, "Waiting for progbit to deassert timed out\n"); - etm_lock(t, id); + etm_lock(t); return -EFAULT; } - etm_lock(t, id); - return 0; -} - -static int trace_start(struct tracectx *t) -{ - int ret; - int id; - u32 etb_fc = t->etb_fc; - - etb_unlock(t); - - t->dump_initial_etb = false; - etb_writel(t, 0, ETBR_WRITEADDR); - etb_writel(t, etb_fc, ETBR_FORMATTERCTRL); - etb_writel(t, 1, ETBR_CTRL); - - etb_lock(t); - - /* configure etm(s) */ - for (id = 0; id < t->etm_regs_count; id++) { - ret = trace_start_etm(t, id); - if (ret) - return ret; - } + etm_lock(t); t->flags |= TRACER_RUNNING; return 0; } -static int trace_stop_etm(struct tracectx *t, int id) +static int trace_stop(struct tracectx *t) { unsigned long timeout = TRACER_TIMEOUT; - etm_unlock(t, id); + etm_unlock(t); - etm_writel(t, id, 0x441, ETMR_CTRL); - while (!(etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout) + etm_writel(t, 0x440, ETMR_CTRL); + while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout) ; if (!timeout) { dev_dbg(t->dev, "Waiting for progbit to assert timed out\n"); - etm_lock(t, id); + etm_lock(t); return -EFAULT; } - etm_lock(t, id); - return 0; -} - -static int trace_stop(struct tracectx *t) -{ - int id; - int ret; - unsigned long timeout = TRACER_TIMEOUT; - u32 etb_fc = t->etb_fc; - - for (id = 0; id < t->etm_regs_count; id++) { - ret = trace_stop_etm(t, id); - if (ret) - return ret; - } + etm_lock(t); etb_unlock(t); - if (etb_fc) { - etb_fc |= ETBFF_STOPFL; - etb_writel(t, t->etb_fc, ETBR_FORMATTERCTRL); - } - etb_writel(t, etb_fc | ETBFF_MANUAL_FLUSH, ETBR_FORMATTERCTRL); + etb_writel(t, ETBFF_MANUAL_FLUSH, ETBR_FORMATTERCTRL); timeout = TRACER_TIMEOUT; while (etb_readl(t, ETBR_FORMATTERCTRL) & @@ -255,15 +184,24 @@ static int trace_stop(struct tracectx *t) static int etb_getdatalen(struct tracectx *t) { u32 v; - int wp; + int rp, wp; v = etb_readl(t, ETBR_STATUS); if (v & 1) return t->etb_bufsz; + rp = etb_readl(t, ETBR_READADDR); wp = etb_readl(t, ETBR_WRITEADDR); - return wp; + + if (rp > wp) { + etb_writel(t, 0, ETBR_READADDR); + etb_writel(t, 0, ETBR_WRITEADDR); + + return 0; + } + + return wp - rp; } /* sysrq+v will always stop the running trace and leave it at that */ @@ -296,18 +234,21 @@ static void etm_dump(void) printk("%08x", cpu_to_be32(etb_readl(t, ETBR_READMEM))); printk(KERN_INFO "\n--- ETB buffer end ---\n"); + /* deassert the overflow bit */ + etb_writel(t, 1, ETBR_CTRL); + etb_writel(t, 0, ETBR_CTRL); + + etb_writel(t, 0, ETBR_TRIGGERCOUNT); + etb_writel(t, 0, ETBR_READADDR); + etb_writel(t, 0, ETBR_WRITEADDR); + etb_lock(t); } static void sysrq_etm_dump(int key) { - if (!mutex_trylock(&tracer.mutex)) { - printk(KERN_INFO "Tracing hardware busy\n"); - return; - } dev_dbg(tracer.dev, "Dumping ETB buffer\n"); etm_dump(); - mutex_unlock(&tracer.mutex); } static struct sysrq_key_op sysrq_etm_op = { @@ -334,10 +275,6 @@ static ssize_t etb_read(struct file *file, char __user *data, struct tracectx *t = file->private_data; u32 first = 0; u32 *buf; - int wpos; - int skip; - long wlength; - loff_t pos = *ppos; mutex_lock(&t->mutex); @@ -349,39 +286,31 @@ static ssize_t etb_read(struct file *file, char __user *data, etb_unlock(t); total = etb_getdatalen(t); - if (total == 0 && t->dump_initial_etb) - total = t->etb_bufsz; if (total == t->etb_bufsz) first = etb_readl(t, ETBR_WRITEADDR); - if (pos > total * 4) { - skip = 0; - wpos = total; - } else { - skip = (int)pos % 4; - wpos = (int)pos / 4; - } - total -= wpos; - first = (first + wpos) % t->etb_bufsz; - etb_writel(t, first, ETBR_READADDR); - wlength = min(total, DIV_ROUND_UP(skip + (int)len, 4)); - length = min(total * 4 - skip, (int)len); - buf = vmalloc(wlength * 4); + length = min(total * 4, (int)len); + buf = vmalloc(length); - dev_dbg(t->dev, "ETB read %ld bytes to %lld from %ld words at %d\n", - length, pos, wlength, first); - dev_dbg(t->dev, "ETB buffer length: %d\n", total + wpos); + dev_dbg(t->dev, "ETB buffer length: %d\n", total); dev_dbg(t->dev, "ETB status reg: %x\n", etb_readl(t, ETBR_STATUS)); - for (i = 0; i < wlength; i++) + for (i = 0; i < length / 4; i++) buf[i] = etb_readl(t, ETBR_READMEM); + /* the only way to deassert overflow bit in ETB status is this */ + etb_writel(t, 1, ETBR_CTRL); + etb_writel(t, 0, ETBR_CTRL); + + etb_writel(t, 0, ETBR_WRITEADDR); + etb_writel(t, 0, ETBR_READADDR); + etb_writel(t, 0, ETBR_TRIGGERCOUNT); + etb_lock(t); - length -= copy_to_user(data, (u8 *)buf + skip, length); + length -= copy_to_user(data, buf, length); vfree(buf); - *ppos = pos + length; out: mutex_unlock(&t->mutex); @@ -418,39 +347,36 @@ static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id if (ret) goto out; - mutex_lock(&t->mutex); t->etb_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res)); if (!t->etb_regs) { ret = -ENOMEM; goto out_release; } - t->dev = &dev->dev; - t->dump_initial_etb = true; amba_set_drvdata(dev, t); - etb_unlock(t); - t->etb_bufsz = etb_readl(t, ETBR_DEPTH); - dev_dbg(&dev->dev, "Size: %x\n", t->etb_bufsz); - - /* make sure trace capture is disabled */ - etb_writel(t, 0, ETBR_CTRL); - etb_writel(t, 0x1000, ETBR_FORMATTERCTRL); - etb_lock(t); - mutex_unlock(&t->mutex); - etb_miscdev.parent = &dev->dev; ret = misc_register(&etb_miscdev); if (ret) goto out_unmap; - /* Get optional clock. Currently used to select clock source on omap3 */ t->emu_clk = clk_get(&dev->dev, "emu_src_ck"); - if (IS_ERR(t->emu_clk)) + if (IS_ERR(t->emu_clk)) { dev_dbg(&dev->dev, "Failed to obtain emu_src_ck.\n"); - else - clk_enable(t->emu_clk); + return -EFAULT; + } + + clk_enable(t->emu_clk); + + etb_unlock(t); + t->etb_bufsz = etb_readl(t, ETBR_DEPTH); + dev_dbg(&dev->dev, "Size: %x\n", t->etb_bufsz); + + /* make sure trace capture is disabled */ + etb_writel(t, 0, ETBR_CTRL); + etb_writel(t, 0x1000, ETBR_FORMATTERCTRL); + etb_lock(t); dev_dbg(&dev->dev, "ETB AMBA driver initialized.\n"); @@ -458,13 +384,10 @@ out: return ret; out_unmap: - mutex_lock(&t->mutex); amba_set_drvdata(dev, NULL); iounmap(t->etb_regs); - t->etb_regs = NULL; out_release: - mutex_unlock(&t->mutex); amba_release_regions(dev); return ret; @@ -479,10 +402,8 @@ static int etb_remove(struct amba_device *dev) iounmap(t->etb_regs); t->etb_regs = NULL; - if (!IS_ERR(t->emu_clk)) { - clk_disable(t->emu_clk); - clk_put(t->emu_clk); - } + clk_disable(t->emu_clk); + clk_put(t->emu_clk); amba_release_regions(dev); @@ -526,10 +447,7 @@ static ssize_t trace_running_store(struct kobject *kobj, return -EINVAL; mutex_lock(&tracer.mutex); - if (!tracer.etb_regs) - ret = -ENODEV; - else - ret = value ? trace_start(&tracer) : trace_stop(&tracer); + ret = value ? trace_start(&tracer) : trace_stop(&tracer); mutex_unlock(&tracer.mutex); return ret ? : n; @@ -544,50 +462,36 @@ static ssize_t trace_info_show(struct kobject *kobj, { u32 etb_wa, etb_ra, etb_st, etb_fc, etm_ctrl, etm_st; int datalen; - int id; - int ret; - mutex_lock(&tracer.mutex); - if (tracer.etb_regs) { - etb_unlock(&tracer); - datalen = etb_getdatalen(&tracer); - etb_wa = etb_readl(&tracer, ETBR_WRITEADDR); - etb_ra = etb_readl(&tracer, ETBR_READADDR); - etb_st = etb_readl(&tracer, ETBR_STATUS); - etb_fc = etb_readl(&tracer, ETBR_FORMATTERCTRL); - etb_lock(&tracer); - } else { - etb_wa = etb_ra = etb_st = etb_fc = ~0; - datalen = -1; - } + etb_unlock(&tracer); + datalen = etb_getdatalen(&tracer); + etb_wa = etb_readl(&tracer, ETBR_WRITEADDR); + etb_ra = etb_readl(&tracer, ETBR_READADDR); + etb_st = etb_readl(&tracer, ETBR_STATUS); + etb_fc = etb_readl(&tracer, ETBR_FORMATTERCTRL); + etb_lock(&tracer); + + etm_unlock(&tracer); + etm_ctrl = etm_readl(&tracer, ETMR_CTRL); + etm_st = etm_readl(&tracer, ETMR_STATUS); + etm_lock(&tracer); - ret = sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n" + return sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n" "ETBR_WRITEADDR:\t%08x\n" "ETBR_READADDR:\t%08x\n" "ETBR_STATUS:\t%08x\n" - "ETBR_FORMATTERCTRL:\t%08x\n", + "ETBR_FORMATTERCTRL:\t%08x\n" + "ETMR_CTRL:\t%08x\n" + "ETMR_STATUS:\t%08x\n", datalen, tracer.ncmppairs, etb_wa, etb_ra, etb_st, - etb_fc - ); - - for (id = 0; id < tracer.etm_regs_count; id++) { - etm_unlock(&tracer, id); - etm_ctrl = etm_readl(&tracer, id, ETMR_CTRL); - etm_st = etm_readl(&tracer, id, ETMR_STATUS); - etm_lock(&tracer, id); - ret += sprintf(buf + ret, "ETMR_CTRL:\t%08x\n" - "ETMR_STATUS:\t%08x\n", + etb_fc, etm_ctrl, etm_st ); - } - mutex_unlock(&tracer.mutex); - - return ret; } static struct kobj_attribute trace_info_attr = @@ -626,121 +530,42 @@ static ssize_t trace_mode_store(struct kobject *kobj, static struct kobj_attribute trace_mode_attr = __ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store); -static ssize_t trace_range_show(struct kobject *kobj, - struct kobj_attribute *attr, - char *buf) -{ - return sprintf(buf, "%08lx %08lx\n", - tracer.range_start, tracer.range_end); -} - -static ssize_t trace_range_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t n) -{ - unsigned long range_start, range_end; - - if (sscanf(buf, "%lx %lx", &range_start, &range_end) != 2) - return -EINVAL; - - mutex_lock(&tracer.mutex); - tracer.range_start = range_start; - tracer.range_end = range_end; - mutex_unlock(&tracer.mutex); - - return n; -} - - -static struct kobj_attribute trace_range_attr = - __ATTR(trace_range, 0644, trace_range_show, trace_range_store); - -static ssize_t trace_data_range_show(struct kobject *kobj, - struct kobj_attribute *attr, - char *buf) -{ - unsigned long range_start; - u64 range_end; - mutex_lock(&tracer.mutex); - range_start = tracer.data_range_start; - range_end = tracer.data_range_end; - if (!range_end && (tracer.flags & TRACER_TRACE_DATA)) - range_end = 0x100000000ULL; - mutex_unlock(&tracer.mutex); - return sprintf(buf, "%08lx %08llx\n", range_start, range_end); -} - -static ssize_t trace_data_range_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t n) -{ - unsigned long range_start; - u64 range_end; - - if (sscanf(buf, "%lx %llx", &range_start, &range_end) != 2) - return -EINVAL; - - mutex_lock(&tracer.mutex); - tracer.data_range_start = range_start; - tracer.data_range_end = (unsigned long)range_end; - if (range_end) - tracer.flags |= TRACER_TRACE_DATA; - else - tracer.flags &= ~TRACER_TRACE_DATA; - mutex_unlock(&tracer.mutex); - - return n; -} - - -static struct kobj_attribute trace_data_range_attr = - __ATTR(trace_data_range, 0644, - trace_data_range_show, trace_data_range_store); - static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id) { struct tracectx *t = &tracer; int ret = 0; - void __iomem **new_regs; - int new_count; - mutex_lock(&t->mutex); - new_count = t->etm_regs_count + 1; - new_regs = krealloc(t->etm_regs, - sizeof(t->etm_regs[0]) * new_count, GFP_KERNEL); - - if (!new_regs) { - dev_dbg(&dev->dev, "Failed to allocate ETM register array\n"); - ret = -ENOMEM; + if (t->etm_regs) { + dev_dbg(&dev->dev, "ETM already initialized\n"); + ret = -EBUSY; goto out; } - t->etm_regs = new_regs; ret = amba_request_regions(dev, NULL); if (ret) goto out; - t->etm_regs[t->etm_regs_count] = - ioremap_nocache(dev->res.start, resource_size(&dev->res)); - if (!t->etm_regs[t->etm_regs_count]) { + t->etm_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res)); + if (!t->etm_regs) { ret = -ENOMEM; goto out_release; } - amba_set_drvdata(dev, t->etm_regs[t->etm_regs_count]); + amba_set_drvdata(dev, t); - t->flags = TRACER_CYCLE_ACC | TRACER_TRACE_DATA; + mutex_init(&t->mutex); + t->dev = &dev->dev; + t->flags = TRACER_CYCLE_ACC; t->etm_portsz = 1; - etm_unlock(t, t->etm_regs_count); - (void)etm_readl(t, t->etm_regs_count, ETMMR_PDSR); + etm_unlock(t); + (void)etm_readl(t, ETMMR_PDSR); /* dummy first read */ - (void)etm_readl(&tracer, t->etm_regs_count, ETMMR_OSSRR); + (void)etm_readl(&tracer, ETMMR_OSSRR); - t->ncmppairs = etm_readl(t, t->etm_regs_count, ETMR_CONFCODE) & 0xf; - etm_writel(t, t->etm_regs_count, 0x441, ETMR_CTRL); - etm_writel(t, t->etm_regs_count, new_count, ETMR_TRACEIDR); - etm_lock(t, t->etm_regs_count); + t->ncmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf; + etm_writel(t, 0x440, ETMR_CTRL); + etm_lock(t); ret = sysfs_create_file(&dev->dev.kobj, &trace_running_attr.attr); @@ -756,68 +581,36 @@ static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id if (ret) dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n"); - ret = sysfs_create_file(&dev->dev.kobj, &trace_range_attr.attr); - if (ret) - dev_dbg(&dev->dev, "Failed to create trace_range in sysfs\n"); - - ret = sysfs_create_file(&dev->dev.kobj, &trace_data_range_attr.attr); - if (ret) - dev_dbg(&dev->dev, - "Failed to create trace_data_range in sysfs\n"); - - dev_dbg(&dev->dev, "ETM AMBA driver initialized.\n"); - - /* Enable formatter if there are multiple trace sources */ - if (new_count > 1) - t->etb_fc = ETBFF_ENFCONT | ETBFF_ENFTC; - - t->etm_regs_count = new_count; + dev_dbg(t->dev, "ETM AMBA driver initialized.\n"); out: - mutex_unlock(&t->mutex); return ret; out_unmap: amba_set_drvdata(dev, NULL); - iounmap(t->etm_regs[t->etm_regs_count]); + iounmap(t->etm_regs); out_release: amba_release_regions(dev); - mutex_unlock(&t->mutex); return ret; } static int etm_remove(struct amba_device *dev) { - int i; - struct tracectx *t = &tracer; - void __iomem *etm_regs = amba_get_drvdata(dev); - - sysfs_remove_file(&dev->dev.kobj, &trace_running_attr.attr); - sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr); - sysfs_remove_file(&dev->dev.kobj, &trace_mode_attr.attr); - sysfs_remove_file(&dev->dev.kobj, &trace_range_attr.attr); - sysfs_remove_file(&dev->dev.kobj, &trace_data_range_attr.attr); + struct tracectx *t = amba_get_drvdata(dev); amba_set_drvdata(dev, NULL); - mutex_lock(&t->mutex); - for (i = 0; i < t->etm_regs_count; i++) - if (t->etm_regs[i] == etm_regs) - break; - for (; i < t->etm_regs_count - 1; i++) - t->etm_regs[i] = t->etm_regs[i + 1]; - t->etm_regs_count--; - if (!t->etm_regs_count) { - kfree(t->etm_regs); - t->etm_regs = NULL; - } - mutex_unlock(&t->mutex); + iounmap(t->etm_regs); + t->etm_regs = NULL; - iounmap(etm_regs); amba_release_regions(dev); + sysfs_remove_file(&dev->dev.kobj, &trace_running_attr.attr); + sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr); + sysfs_remove_file(&dev->dev.kobj, &trace_mode_attr.attr); + return 0; } @@ -826,10 +619,6 @@ static struct amba_id etm_ids[] = { .id = 0x0003b921, .mask = 0x0007ffff, }, - { - .id = 0x0003b950, - .mask = 0x0007ffff, - }, { 0, 0 }, }; @@ -847,8 +636,6 @@ static int __init etm_init(void) { int retval; - mutex_init(&tracer.mutex); - retval = amba_driver_register(&etb_driver); if (retval) { printk(KERN_ERR "Failed to register etb\n"); diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 673151c7f54b..278c1b0ebb2e 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -348,7 +348,7 @@ __secondary_data: * r13 = *virtual* address to jump to upon completion */ __enable_mmu: -#if defined(CONFIG_ALIGNMENT_TRAP) && __LINUX_ARM_ARCH__ < 6 +#ifdef CONFIG_ALIGNMENT_TRAP orr r0, r0, #CR_A #else bic r0, r0, #CR_A diff --git a/arch/arm/kernel/leds.c b/arch/arm/kernel/leds.c index 136e8376a3eb..0f107dcb0347 100644 --- a/arch/arm/kernel/leds.c +++ b/arch/arm/kernel/leds.c @@ -9,8 +9,6 @@ */ #include #include -#include -#include #include #include @@ -103,25 +101,6 @@ static struct syscore_ops leds_syscore_ops = { .resume = leds_resume, }; -static int leds_idle_notifier(struct notifier_block *nb, unsigned long val, - void *data) -{ - switch (val) { - case IDLE_START: - leds_event(led_idle_start); - break; - case IDLE_END: - leds_event(led_idle_end); - break; - } - - return 0; -} - -static struct notifier_block leds_idle_nb = { - .notifier_call = leds_idle_notifier, -}; - static int __init leds_init(void) { int ret; @@ -130,12 +109,8 @@ static int __init leds_init(void) ret = sysdev_register(&leds_device); if (ret == 0) ret = sysdev_create_file(&leds_device, &attr_event); - - if (ret == 0) { + if (ret == 0) register_syscore_ops(&leds_syscore_ops); - idle_notifier_register(&leds_idle_nb); - } - return ret; } diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index 43727630ae0f..4960686afb58 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c @@ -264,8 +264,8 @@ static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = { [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE, - [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_DCACHE_ACCESS, - [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_DCACHE_REFILL, + [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_COHERENT_LINE_HIT, + [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_COHERENT_LINE_MISS, [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE, [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES, diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index c132e8145754..5e1e54197227 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -30,9 +30,9 @@ #include #include #include -#include #include +#include #include #include #include @@ -62,18 +62,6 @@ static volatile int hlt_counter; #include -#ifdef CONFIG_SMP -void arch_trigger_all_cpu_backtrace(void) -{ - smp_send_all_cpu_backtrace(); -} -#else -void arch_trigger_all_cpu_backtrace(void) -{ - dump_stack(); -} -#endif - void disable_hlt(void) { hlt_counter++; @@ -103,37 +91,8 @@ static int __init hlt_setup(char *__unused) __setup("nohlt", nohlt_setup); __setup("hlt", hlt_setup); -#ifdef CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART -void arm_machine_flush_console(void) -{ - printk("\n"); - pr_emerg("Restarting %s\n", linux_banner); - if (console_trylock()) { - console_unlock(); - return; - } - - mdelay(50); - - local_irq_disable(); - if (!console_trylock()) - pr_emerg("arm_restart: Console was locked! Busting\n"); - else - pr_emerg("arm_restart: Console was locked!\n"); - console_unlock(); -} -#else -void arm_machine_flush_console(void) -{ -} -#endif - void arm_machine_restart(char mode, const char *cmd) { - /* Flush the console to make sure all the relevant messages make it - * out to the console drivers */ - arm_machine_flush_console(); - /* Disable interrupts first */ local_irq_disable(); local_fiq_disable(); @@ -223,8 +182,8 @@ void cpu_idle(void) /* endless idle loop with no priority at all */ while (1) { - idle_notifier_call_chain(IDLE_START); tick_nohz_stop_sched_tick(1); + leds_event(led_idle_start); while (!need_resched()) { #ifdef CONFIG_HOTPLUG_CPU if (cpu_is_offline(smp_processor_id())) @@ -232,9 +191,6 @@ void cpu_idle(void) #endif local_irq_disable(); -#ifdef CONFIG_PL310_ERRATA_769419 - wmb(); -#endif if (hlt_counter) { local_irq_enable(); cpu_relax(); @@ -251,8 +207,8 @@ void cpu_idle(void) local_irq_enable(); } } + leds_event(led_idle_end); tick_nohz_restart_sched_tick(); - idle_notifier_call_chain(IDLE_END); preempt_enable_no_resched(); schedule(); preempt_disable(); @@ -272,15 +228,6 @@ __setup("reboot=", reboot_setup); void machine_shutdown(void) { #ifdef CONFIG_SMP - /* - * Disable preemption so we're guaranteed to - * run to power off or reboot and prevent - * the possibility of switching to another - * thread that might wind up blocking on - * one of the stopped CPUs. - */ - preempt_disable(); - smp_send_stop(); #endif } @@ -304,77 +251,6 @@ void machine_restart(char *cmd) arm_pm_restart(reboot_mode, cmd); } -/* - * dump a block of kernel memory from around the given address - */ -static void show_data(unsigned long addr, int nbytes, const char *name) -{ - int i, j; - int nlines; - u32 *p; - - /* - * don't attempt to dump non-kernel addresses or - * values that are probably just small negative numbers - */ - if (addr < PAGE_OFFSET || addr > -256UL) - return; - - printk("\n%s: %#lx:\n", name, addr); - - /* - * round address down to a 32 bit boundary - * and always dump a multiple of 32 bytes - */ - p = (u32 *)(addr & ~(sizeof(u32) - 1)); - nbytes += (addr & (sizeof(u32) - 1)); - nlines = (nbytes + 31) / 32; - - - for (i = 0; i < nlines; i++) { - /* - * just display low 16 bits of address to keep - * each line of the dump < 80 characters - */ - printk("%04lx ", (unsigned long)p & 0xffff); - for (j = 0; j < 8; j++) { - u32 data; - if (probe_kernel_address(p, data)) { - printk(" ********"); - } else { - printk(" %08x", data); - } - ++p; - } - printk("\n"); - } -} - -static void show_extra_register_data(struct pt_regs *regs, int nbytes) -{ - mm_segment_t fs; - - fs = get_fs(); - set_fs(KERNEL_DS); - show_data(regs->ARM_pc - nbytes, nbytes * 2, "PC"); - show_data(regs->ARM_lr - nbytes, nbytes * 2, "LR"); - show_data(regs->ARM_sp - nbytes, nbytes * 2, "SP"); - show_data(regs->ARM_ip - nbytes, nbytes * 2, "IP"); - show_data(regs->ARM_fp - nbytes, nbytes * 2, "FP"); - show_data(regs->ARM_r0 - nbytes, nbytes * 2, "R0"); - show_data(regs->ARM_r1 - nbytes, nbytes * 2, "R1"); - show_data(regs->ARM_r2 - nbytes, nbytes * 2, "R2"); - show_data(regs->ARM_r3 - nbytes, nbytes * 2, "R3"); - show_data(regs->ARM_r4 - nbytes, nbytes * 2, "R4"); - show_data(regs->ARM_r5 - nbytes, nbytes * 2, "R5"); - show_data(regs->ARM_r6 - nbytes, nbytes * 2, "R6"); - show_data(regs->ARM_r7 - nbytes, nbytes * 2, "R7"); - show_data(regs->ARM_r8 - nbytes, nbytes * 2, "R8"); - show_data(regs->ARM_r9 - nbytes, nbytes * 2, "R9"); - show_data(regs->ARM_r10 - nbytes, nbytes * 2, "R10"); - set_fs(fs); -} - void __show_regs(struct pt_regs *regs) { unsigned long flags; @@ -434,8 +310,6 @@ void __show_regs(struct pt_regs *regs) printk("Control: %08x%s\n", ctrl, buf); } #endif - - show_extra_register_data(regs, 128); } void show_regs(struct pt_regs * regs) diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 172ae01c26e0..97260060bf26 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -719,13 +719,10 @@ static int vfp_set(struct task_struct *target, { int ret; struct thread_info *thread = task_thread_info(target); - struct vfp_hard_struct new_vfp; + struct vfp_hard_struct new_vfp = thread->vfpstate.hard; const size_t user_fpregs_offset = offsetof(struct user_vfp, fpregs); const size_t user_fpscr_offset = offsetof(struct user_vfp, fpscr); - vfp_sync_hwstate(thread); - new_vfp = thread->vfpstate.hard; - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &new_vfp.fpregs, user_fpregs_offset, @@ -746,8 +743,9 @@ static int vfp_set(struct task_struct *target, if (ret) return ret; - vfp_flush_hwstate(thread); + vfp_sync_hwstate(thread); thread->vfpstate.hard = new_vfp; + vfp_flush_hwstate(thread); return 0; } diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 9e617bd4a146..0340224cf73c 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -227,8 +227,6 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame) if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE) return -EINVAL; - vfp_flush_hwstate(thread); - /* * Copy the floating point registers. There can be unused * registers see asm/hwcap.h for details. @@ -253,6 +251,9 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame) __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); + if (!err) + vfp_flush_hwstate(thread); + return err ? -EFAULT : 0; } diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index e895f97ab008..e7f92a4321f3 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -53,7 +53,6 @@ enum ipi_msg_type { IPI_CALL_FUNC, IPI_CALL_FUNC_SINGLE, IPI_CPU_STOP, - IPI_CPU_BACKTRACE, }; int __cpuinit __cpu_up(unsigned int cpu) @@ -278,26 +277,20 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid) asmlinkage void __cpuinit secondary_start_kernel(void) { struct mm_struct *mm = &init_mm; - unsigned int cpu; + unsigned int cpu = smp_processor_id(); - /* - * The identity mapping is uncached (strongly ordered), so - * switch away from it before attempting any exclusive accesses. - */ - cpu_switch_mm(mm->pgd, mm); - enter_lazy_tlb(mm, current); - local_flush_tlb_all(); + printk("CPU%u: Booted secondary processor\n", cpu); /* * All kernel threads share the same mm context; grab a * reference and switch to it. */ - cpu = smp_processor_id(); atomic_inc(&mm->mm_count); current->active_mm = mm; cpumask_set_cpu(cpu, mm_cpumask(mm)); - - printk("CPU%u: Booted secondary processor\n", cpu); + cpu_switch_mm(mm->pgd, mm); + enter_lazy_tlb(mm, current); + local_flush_tlb_all(); cpu_init(); preempt_disable(); @@ -308,7 +301,17 @@ asmlinkage void __cpuinit secondary_start_kernel(void) */ platform_secondary_init(cpu); + /* + * Enable local interrupts. + */ notify_cpu_starting(cpu); + local_irq_enable(); + local_fiq_enable(); + + /* + * Setup the percpu timer for this CPU. + */ + percpu_timer_setup(); calibrate_delay(); @@ -320,22 +323,9 @@ asmlinkage void __cpuinit secondary_start_kernel(void) * before we continue. */ set_cpu_online(cpu, true); - - /* - * Setup the percpu timer for this CPU. - */ - percpu_timer_setup(); - while (!cpu_active(cpu)) cpu_relax(); - /* - * cpu_active bit is set, so it's safe to enable interrupts - * now. - */ - local_irq_enable(); - local_fiq_enable(); - /* * OK, it's off to the idle thread for us */ @@ -415,7 +405,6 @@ static const char *ipi_types[NR_IPI] = { S(IPI_CALL_FUNC, "Function call interrupts"), S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"), S(IPI_CPU_STOP, "CPU stop interrupts"), - S(IPI_CPU_BACKTRACE, "CPU backtrace"), }; void show_ipi_list(struct seq_file *p, int prec) @@ -456,7 +445,9 @@ static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent); static void ipi_timer(void) { struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent); + irq_enter(); evt->event_handler(evt); + irq_exit(); } #ifdef CONFIG_LOCAL_TIMERS @@ -467,9 +458,7 @@ asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs) if (local_timer_ack()) { __inc_irq_stat(cpu, local_timer_irqs); - irq_enter(); ipi_timer(); - irq_exit(); } set_irq_regs(old_regs); @@ -566,58 +555,6 @@ static void ipi_cpu_stop(unsigned int cpu) cpu_relax(); } -static cpumask_t backtrace_mask; -static DEFINE_RAW_SPINLOCK(backtrace_lock); - -/* "in progress" flag of arch_trigger_all_cpu_backtrace */ -static unsigned long backtrace_flag; - -void smp_send_all_cpu_backtrace(void) -{ - unsigned int this_cpu = smp_processor_id(); - int i; - - if (test_and_set_bit(0, &backtrace_flag)) - /* - * If there is already a trigger_all_cpu_backtrace() in progress - * (backtrace_flag == 1), don't output double cpu dump infos. - */ - return; - - cpumask_copy(&backtrace_mask, cpu_online_mask); - cpu_clear(this_cpu, backtrace_mask); - - pr_info("Backtrace for cpu %d (current):\n", this_cpu); - dump_stack(); - - pr_info("\nsending IPI to all other CPUs:\n"); - smp_cross_call(&backtrace_mask, IPI_CPU_BACKTRACE); - - /* Wait for up to 10 seconds for all other CPUs to do the backtrace */ - for (i = 0; i < 10 * 1000; i++) { - if (cpumask_empty(&backtrace_mask)) - break; - mdelay(1); - } - - clear_bit(0, &backtrace_flag); - smp_mb__after_clear_bit(); -} - -/* - * ipi_cpu_backtrace - handle IPI from smp_send_all_cpu_backtrace() - */ -static void ipi_cpu_backtrace(unsigned int cpu, struct pt_regs *regs) -{ - if (cpu_isset(cpu, backtrace_mask)) { - raw_spin_lock(&backtrace_lock); - pr_warning("IPI backtrace for cpu %d\n", cpu); - show_regs(regs); - raw_spin_unlock(&backtrace_lock); - cpu_clear(cpu, backtrace_mask); - } -} - /* * Main handler for inter-processor interrupts */ @@ -631,9 +568,7 @@ asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs) switch (ipinr) { case IPI_TIMER: - irq_enter(); ipi_timer(); - irq_exit(); break; case IPI_RESCHEDULE: @@ -641,25 +576,15 @@ asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs) break; case IPI_CALL_FUNC: - irq_enter(); generic_smp_call_function_interrupt(); - irq_exit(); break; case IPI_CALL_FUNC_SINGLE: - irq_enter(); generic_smp_call_function_single_interrupt(); - irq_exit(); break; case IPI_CPU_STOP: - irq_enter(); ipi_cpu_stop(cpu); - irq_exit(); - break; - - case IPI_CPU_BACKTRACE: - ipi_cpu_backtrace(cpu, regs); break; default: diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c index cb7dd40e0d3b..a1e757c3439b 100644 --- a/arch/arm/kernel/smp_scu.c +++ b/arch/arm/kernel/smp_scu.c @@ -13,7 +13,6 @@ #include #include -#include #define SCU_CTRL 0x00 #define SCU_CONFIG 0x04 @@ -37,15 +36,6 @@ void __init scu_enable(void __iomem *scu_base) { u32 scu_ctrl; -#ifdef CONFIG_ARM_ERRATA_764369 - /* Cortex-A9 only */ - if ((read_cpuid(CPUID_ID) & 0xff0ffff0) == 0x410fc090) { - scu_ctrl = __raw_readl(scu_base + 0x30); - if (!(scu_ctrl & 1)) - __raw_writel(scu_ctrl | 0x1, scu_base + 0x30); - } -#endif - scu_ctrl = __raw_readl(scu_base + SCU_CTRL); /* already enabled? */ if (scu_ctrl & 1) diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c index 0951a32493ae..40ee7e5045e4 100644 --- a/arch/arm/kernel/swp_emulate.c +++ b/arch/arm/kernel/swp_emulate.c @@ -108,12 +108,10 @@ static void set_segfault(struct pt_regs *regs, unsigned long addr) { siginfo_t info; - down_read(¤t->mm->mmap_sem); if (find_vma(current->mm, addr) == NULL) info.si_code = SEGV_MAPERR; else info.si_code = SEGV_ACCERR; - up_read(¤t->mm->mmap_sem); info.si_signo = SIGSEGV; info.si_errno = 0; diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index 0264ab433e9e..62e7c61d0342 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c @@ -115,7 +115,7 @@ int kernel_execve(const char *filename, "Ir" (THREAD_START_SP - sizeof(regs)), "r" (®s), "Ir" (sizeof(regs)) - : "r0", "r1", "r2", "r3", "r8", "r9", "ip", "lr", "memory"); + : "r0", "r1", "r2", "r3", "ip", "lr", "memory"); out: return ret; diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 56b2715355b1..6807cb1e76dd 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -451,9 +451,7 @@ do_cache_op(unsigned long start, unsigned long end, int flags) if (end > vma->vm_end) end = vma->vm_end; - up_read(&mm->mmap_sem); - flush_cache_user_range(start, end); - return; + flush_cache_user_range(vma, start, end); } up_read(&mm->mmap_sem); } diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 871a818e3dbb..7227755ffec6 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -454,7 +454,7 @@ static struct i2c_gpio_platform_data pdata = { static struct platform_device at91rm9200_twi_device = { .name = "i2c-gpio", - .id = 0, + .id = -1, .dev.platform_data = &pdata, }; diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index eeb947858855..7d606b04d313 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -237,9 +237,9 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), - CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk), - CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), - CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), + CLKDEV_CON_DEV_ID("t3_clk", "atmel_tcb.1", &tc3_clk), + CLKDEV_CON_DEV_ID("t4_clk", "atmel_tcb.1", &tc4_clk), + CLKDEV_CON_DEV_ID("t5_clk", "atmel_tcb.1", &tc5_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk), }; diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 89a8414d7e23..39f81f47b4ba 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -459,7 +459,7 @@ static struct i2c_gpio_platform_data pdata = { static struct platform_device at91sam9260_twi_device = { .name = "i2c-gpio", - .id = 0, + .id = -1, .dev.platform_data = &pdata, }; diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index 5d43cf452313..5004bf0a05f2 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -276,7 +276,7 @@ static struct i2c_gpio_platform_data pdata = { static struct platform_device at91sam9261_twi_device = { .name = "i2c-gpio", - .id = 0, + .id = -1, .dev.platform_data = &pdata, }; diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index 2bbd16301a0c..a050f41fc860 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -534,7 +534,7 @@ static struct i2c_gpio_platform_data pdata = { static struct platform_device at91sam9263_twi_device = { .name = "i2c-gpio", - .id = 0, + .id = -1, .dev.platform_data = &pdata, }; diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 659870e647f1..aacb19dc9225 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -319,7 +319,7 @@ static struct i2c_gpio_platform_data pdata = { static struct platform_device at91sam9rl_twi_device = { .name = "i2c-gpio", - .id = 0, + .id = -1, .dev.platform_data = &pdata, }; diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index f8936174ce81..a7b41bf505f1 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -115,32 +115,6 @@ static struct spi_board_info da850evm_spi_info[] = { }, }; -#ifdef CONFIG_MTD -static void da850_evm_m25p80_notify_add(struct mtd_info *mtd) -{ - char *mac_addr = davinci_soc_info.emac_pdata->mac_addr; - size_t retlen; - - if (!strcmp(mtd->name, "MAC-Address")) { - mtd->read(mtd, 0, ETH_ALEN, &retlen, mac_addr); - if (retlen == ETH_ALEN) - pr_info("Read MAC addr from SPI Flash: %pM\n", - mac_addr); - } -} - -static struct mtd_notifier da850evm_spi_notifier = { - .add = da850_evm_m25p80_notify_add, -}; - -static void da850_evm_setup_mac_addr(void) -{ - register_mtd_user(&da850evm_spi_notifier); -} -#else -static void da850_evm_setup_mac_addr(void) { } -#endif - static struct mtd_partition da850_evm_norflash_partition[] = { { .name = "bootloaders + env", @@ -748,7 +722,7 @@ static struct snd_platform_data da850_evm_snd_data = { .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), .tdm_slots = 2, .serial_dir = da850_iis_serializer_direction, - .asp_chan_q = EVENTQ_0, + .asp_chan_q = EVENTQ_1, .version = MCASP_VERSION_2, .txnumevt = 1, .rxnumevt = 1, @@ -1263,8 +1237,6 @@ static __init void da850_evm_init(void) if (ret) pr_warning("da850_evm_init: spi 1 registration failed: %d\n", ret); - - da850_evm_setup_mac_addr(); } #ifdef CONFIG_SERIAL_8250_CONSOLE diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 3cdd23787bd0..f6ac9ba74878 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -563,7 +563,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) int val; u32 value; - if (!vpif_vidclkctl_reg || !cpld_client) + if (!vpif_vsclkdis_reg || !cpld_client) return -ENXIO; val = i2c_smbus_read_byte(cpld_client); @@ -571,7 +571,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) return val; spin_lock_irqsave(&vpif_reg_lock, flags); - value = __raw_readl(vpif_vidclkctl_reg); + value = __raw_readl(vpif_vsclkdis_reg); if (mux_mode) { val &= VPIF_INPUT_TWO_CHANNEL; value |= VIDCH1CLK; @@ -579,7 +579,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) val |= VPIF_INPUT_ONE_CHANNEL; value &= ~VIDCH1CLK; } - __raw_writel(value, vpif_vidclkctl_reg); + __raw_writel(value, vpif_vsclkdis_reg); spin_unlock_irqrestore(&vpif_reg_lock, flags); err = i2c_smbus_write_byte(cpld_client, val); diff --git a/arch/arm/mach-davinci/sleep.S b/arch/arm/mach-davinci/sleep.S index 5f1e045a3ad1..fb5e72b532b0 100644 --- a/arch/arm/mach-davinci/sleep.S +++ b/arch/arm/mach-davinci/sleep.S @@ -217,11 +217,7 @@ ddr2clk_stop_done: ENDPROC(davinci_ddr_psc_config) CACHE_FLUSH: -#ifdef CONFIG_CPU_V6 - .word v6_flush_kern_cache_all -#else - .word arm926_flush_kern_cache_all -#endif + .word arm926_flush_kern_cache_all ENTRY(davinci_cpu_suspend_sz) .word . - davinci_cpu_suspend diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c index 46c044986294..5ed51b84c1b2 100644 --- a/arch/arm/mach-dove/common.c +++ b/arch/arm/mach-dove/common.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include "common.h" @@ -75,7 +74,7 @@ void __init dove_map_io(void) void __init dove_ehci0_init(void) { orion_ehci_init(&dove_mbus_dram_info, - DOVE_USB0_PHYS_BASE, IRQ_DOVE_USB0, EHCI_PHY_NA); + DOVE_USB0_PHYS_BASE, IRQ_DOVE_USB0); } /***************************************************************************** @@ -161,7 +160,7 @@ void __init dove_spi0_init(void) void __init dove_spi1_init(void) { - orion_spi_1_init(DOVE_SPI1_PHYS_BASE, get_tclk()); + orion_spi_init(DOVE_SPI1_PHYS_BASE, get_tclk()); } /***************************************************************************** diff --git a/arch/arm/mach-dove/include/mach/pm.h b/arch/arm/mach-dove/include/mach/pm.h index 11799c33475e..3ad9f946a9e8 100644 --- a/arch/arm/mach-dove/include/mach/pm.h +++ b/arch/arm/mach-dove/include/mach/pm.h @@ -45,7 +45,7 @@ static inline int pmu_to_irq(int pin) static inline int irq_to_pmu(int irq) { - if (IRQ_DOVE_PMU_START <= irq && irq < NR_IRQS) + if (IRQ_DOVE_PMU_START < irq && irq < NR_IRQS) return irq - IRQ_DOVE_PMU_START; return -EINVAL; diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c index 9f2fd1001746..f07fd16e0c9b 100644 --- a/arch/arm/mach-dove/irq.c +++ b/arch/arm/mach-dove/irq.c @@ -61,20 +61,8 @@ static void pmu_irq_ack(struct irq_data *d) int pin = irq_to_pmu(d->irq); u32 u; - /* - * The PMU mask register is not RW0C: it is RW. This means that - * the bits take whatever value is written to them; if you write - * a '1', you will set the interrupt. - * - * Unfortunately this means there is NO race free way to clear - * these interrupts. - * - * So, let's structure the code so that the window is as small as - * possible. - */ u = ~(1 << (pin & 31)); - u &= readl_relaxed(PMU_INTERRUPT_CAUSE); - writel_relaxed(u, PMU_INTERRUPT_CAUSE); + writel(u, PMU_INTERRUPT_CAUSE); } static struct irq_chip pmu_irq_chip = { diff --git a/arch/arm/mach-imx/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c index a37fe021d69f..74ac88978ddd 100644 --- a/arch/arm/mach-imx/mach-mx21ads.c +++ b/arch/arm/mach-imx/mach-mx21ads.c @@ -32,7 +32,7 @@ * Memory-mapped I/O on MX21ADS base board */ #define MX21ADS_MMIO_BASE_ADDR 0xf5000000 -#define MX21ADS_MMIO_SIZE 0xc00000 +#define MX21ADS_MMIO_SIZE SZ_16M #define MX21ADS_REG_ADDR(offset) (void __force __iomem *) \ (MX21ADS_MMIO_BASE_ADDR + (offset)) diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index fcf0ae95651f..2fbbdd5eac35 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -337,15 +337,15 @@ static unsigned long timer_reload; static void integrator_clocksource_init(u32 khz) { void __iomem *base = (void __iomem *)TIMER2_VA_BASE; - u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; + u32 ctrl = TIMER_CTRL_ENABLE; if (khz >= 1500) { khz /= 16; - ctrl |= TIMER_CTRL_DIV16; + ctrl = TIMER_CTRL_DIV16; } - writel(0xffff, base + TIMER_LOAD); writel(ctrl, base + TIMER_CTRL); + writel(0xffff, base + TIMER_LOAD); clocksource_mmio_init(base + TIMER_VALUE, "timer2", khz * 1000, 200, 16, clocksource_mmio_readl_down); diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index c5dbbb35e0b1..f3248cfbe51d 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include "common.h" @@ -75,7 +74,7 @@ void __init kirkwood_ehci_init(void) { kirkwood_clk_ctrl |= CGC_USB0; orion_ehci_init(&kirkwood_mbus_dram_info, - USB_PHYS_BASE, IRQ_KIRKWOOD_USB, EHCI_PHY_NA); + USB_PHYS_BASE, IRQ_KIRKWOOD_USB); } diff --git a/arch/arm/mach-kirkwood/mpp.h b/arch/arm/mach-kirkwood/mpp.h index 7afccf472205..ac787957e2d9 100644 --- a/arch/arm/mach-kirkwood/mpp.h +++ b/arch/arm/mach-kirkwood/mpp.h @@ -31,313 +31,313 @@ #define MPP_F6282_MASK MPP( 0, 0x0, 0, 0, 0, 0, 0, 0, 1 ) #define MPP0_GPIO MPP( 0, 0x0, 1, 1, 1, 1, 1, 1, 1 ) -#define MPP0_NF_IO2 MPP( 0, 0x1, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP0_SPI_SCn MPP( 0, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP0_NF_IO2 MPP( 0, 0x1, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP0_SPI_SCn MPP( 0, 0x2, 0, 1, 1, 1, 1, 1, 1 ) #define MPP1_GPO MPP( 1, 0x0, 0, 1, 1, 1, 1, 1, 1 ) -#define MPP1_NF_IO3 MPP( 1, 0x1, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP1_SPI_MOSI MPP( 1, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP1_NF_IO3 MPP( 1, 0x1, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP1_SPI_MOSI MPP( 1, 0x2, 0, 1, 1, 1, 1, 1, 1 ) #define MPP2_GPO MPP( 2, 0x0, 0, 1, 1, 1, 1, 1, 1 ) -#define MPP2_NF_IO4 MPP( 2, 0x1, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP2_SPI_SCK MPP( 2, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP2_NF_IO4 MPP( 2, 0x1, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP2_SPI_SCK MPP( 2, 0x2, 0, 1, 1, 1, 1, 1, 1 ) #define MPP3_GPO MPP( 3, 0x0, 0, 1, 1, 1, 1, 1, 1 ) -#define MPP3_NF_IO5 MPP( 3, 0x1, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP3_SPI_MISO MPP( 3, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP3_NF_IO5 MPP( 3, 0x1, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP3_SPI_MISO MPP( 3, 0x2, 1, 0, 1, 1, 1, 1, 1 ) #define MPP4_GPIO MPP( 4, 0x0, 1, 1, 1, 1, 1, 1, 1 ) -#define MPP4_NF_IO6 MPP( 4, 0x1, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP4_UART0_RXD MPP( 4, 0x2, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP4_SATA1_ACTn MPP( 4, 0x5, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP4_NF_IO6 MPP( 4, 0x1, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP4_UART0_RXD MPP( 4, 0x2, 1, 0, 1, 1, 1, 1, 1 ) +#define MPP4_SATA1_ACTn MPP( 4, 0x5, 0, 1, 0, 0, 1, 1, 1 ) #define MPP4_LCD_VGA_HSYNC MPP( 4, 0xb, 0, 0, 0, 0, 0, 0, 1 ) -#define MPP4_PTP_CLK MPP( 4, 0xd, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP4_PTP_CLK MPP( 4, 0xd, 1, 0, 1, 1, 1, 1, 0 ) #define MPP5_GPO MPP( 5, 0x0, 0, 1, 1, 1, 1, 1, 1 ) -#define MPP5_NF_IO7 MPP( 5, 0x1, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP5_UART0_TXD MPP( 5, 0x2, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP5_PTP_TRIG_GEN MPP( 5, 0x4, 0, 0, 1, 1, 1, 1, 0 ) -#define MPP5_SATA0_ACTn MPP( 5, 0x5, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP5_NF_IO7 MPP( 5, 0x1, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP5_UART0_TXD MPP( 5, 0x2, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP5_PTP_TRIG_GEN MPP( 5, 0x4, 0, 1, 1, 1, 1, 1, 0 ) +#define MPP5_SATA0_ACTn MPP( 5, 0x5, 0, 1, 0, 1, 1, 1, 1 ) #define MPP5_LCD_VGA_VSYNC MPP( 5, 0xb, 0, 0, 0, 0, 0, 0, 1 ) -#define MPP6_SYSRST_OUTn MPP( 6, 0x1, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP6_SPI_MOSI MPP( 6, 0x2, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP6_PTP_TRIG_GEN MPP( 6, 0x3, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP6_SYSRST_OUTn MPP( 6, 0x1, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP6_SPI_MOSI MPP( 6, 0x2, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP6_PTP_TRIG_GEN MPP( 6, 0x3, 0, 1, 1, 1, 1, 1, 0 ) #define MPP7_GPO MPP( 7, 0x0, 0, 1, 1, 1, 1, 1, 1 ) -#define MPP7_PEX_RST_OUTn MPP( 7, 0x1, 0, 0, 1, 1, 1, 1, 0 ) -#define MPP7_SPI_SCn MPP( 7, 0x2, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP7_PTP_TRIG_GEN MPP( 7, 0x3, 0, 0, 1, 1, 1, 1, 0 ) -#define MPP7_LCD_PWM MPP( 7, 0xb, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP7_PEX_RST_OUTn MPP( 7, 0x1, 0, 1, 1, 1, 1, 1, 0 ) +#define MPP7_SPI_SCn MPP( 7, 0x2, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP7_PTP_TRIG_GEN MPP( 7, 0x3, 0, 1, 1, 1, 1, 1, 0 ) +#define MPP7_LCD_PWM MPP( 7, 0xb, 0, 1, 0, 0, 0, 0, 1 ) #define MPP8_GPIO MPP( 8, 0x0, 1, 1, 1, 1, 1, 1, 1 ) -#define MPP8_TW0_SDA MPP( 8, 0x1, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP8_UART0_RTS MPP( 8, 0x2, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP8_UART1_RTS MPP( 8, 0x3, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP8_MII0_RXERR MPP( 8, 0x4, 0, 0, 0, 1, 1, 1, 1 ) -#define MPP8_SATA1_PRESENTn MPP( 8, 0x5, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP8_PTP_CLK MPP( 8, 0xc, 0, 0, 1, 1, 1, 1, 0 ) -#define MPP8_MII0_COL MPP( 8, 0xd, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP8_TW0_SDA MPP( 8, 0x1, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP8_UART0_RTS MPP( 8, 0x2, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP8_UART1_RTS MPP( 8, 0x3, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP8_MII0_RXERR MPP( 8, 0x4, 1, 0, 0, 1, 1, 1, 1 ) +#define MPP8_SATA1_PRESENTn MPP( 8, 0x5, 0, 1, 0, 0, 1, 1, 1 ) +#define MPP8_PTP_CLK MPP( 8, 0xc, 1, 0, 1, 1, 1, 1, 0 ) +#define MPP8_MII0_COL MPP( 8, 0xd, 1, 0, 1, 1, 1, 1, 1 ) #define MPP9_GPIO MPP( 9, 0x0, 1, 1, 1, 1, 1, 1, 1 ) -#define MPP9_TW0_SCK MPP( 9, 0x1, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP9_UART0_CTS MPP( 9, 0x2, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP9_UART1_CTS MPP( 9, 0x3, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP9_SATA0_PRESENTn MPP( 9, 0x5, 0, 0, 0, 1, 1, 1, 1 ) -#define MPP9_PTP_EVENT_REQ MPP( 9, 0xc, 0, 0, 1, 1, 1, 1, 0 ) -#define MPP9_MII0_CRS MPP( 9, 0xd, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP9_TW0_SCK MPP( 9, 0x1, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP9_UART0_CTS MPP( 9, 0x2, 1, 0, 1, 1, 1, 1, 1 ) +#define MPP9_UART1_CTS MPP( 9, 0x3, 1, 0, 1, 1, 1, 1, 1 ) +#define MPP9_SATA0_PRESENTn MPP( 9, 0x5, 0, 1, 0, 1, 1, 1, 1 ) +#define MPP9_PTP_EVENT_REQ MPP( 9, 0xc, 1, 0, 1, 1, 1, 1, 0 ) +#define MPP9_MII0_CRS MPP( 9, 0xd, 1, 0, 1, 1, 1, 1, 1 ) #define MPP10_GPO MPP( 10, 0x0, 0, 1, 1, 1, 1, 1, 1 ) -#define MPP10_SPI_SCK MPP( 10, 0x2, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP10_UART0_TXD MPP( 10, 0X3, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP10_SATA1_ACTn MPP( 10, 0x5, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP10_PTP_TRIG_GEN MPP( 10, 0xc, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP10_SPI_SCK MPP( 10, 0x2, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP10_UART0_TXD MPP( 10, 0X3, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP10_SATA1_ACTn MPP( 10, 0x5, 0, 1, 0, 0, 1, 1, 1 ) +#define MPP10_PTP_TRIG_GEN MPP( 10, 0xc, 0, 1, 1, 1, 1, 1, 0 ) #define MPP11_GPIO MPP( 11, 0x0, 1, 1, 1, 1, 1, 1, 1 ) -#define MPP11_SPI_MISO MPP( 11, 0x2, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP11_UART0_RXD MPP( 11, 0x3, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP11_PTP_EVENT_REQ MPP( 11, 0x4, 0, 0, 1, 1, 1, 1, 0 ) -#define MPP11_PTP_TRIG_GEN MPP( 11, 0xc, 0, 0, 1, 1, 1, 1, 0 ) -#define MPP11_PTP_CLK MPP( 11, 0xd, 0, 0, 1, 1, 1, 1, 0 ) -#define MPP11_SATA0_ACTn MPP( 11, 0x5, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP11_SPI_MISO MPP( 11, 0x2, 1, 0, 1, 1, 1, 1, 1 ) +#define MPP11_UART0_RXD MPP( 11, 0x3, 1, 0, 1, 1, 1, 1, 1 ) +#define MPP11_PTP_EVENT_REQ MPP( 11, 0x4, 1, 0, 1, 1, 1, 1, 0 ) +#define MPP11_PTP_TRIG_GEN MPP( 11, 0xc, 0, 1, 1, 1, 1, 1, 0 ) +#define MPP11_PTP_CLK MPP( 11, 0xd, 1, 0, 1, 1, 1, 1, 0 ) +#define MPP11_SATA0_ACTn MPP( 11, 0x5, 0, 1, 0, 1, 1, 1, 1 ) #define MPP12_GPO MPP( 12, 0x0, 0, 1, 1, 1, 1, 1, 1 ) -#define MPP12_SD_CLK MPP( 12, 0x1, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP12_AU_SPDIF0 MPP( 12, 0xa, 0, 0, 0, 0, 0, 0, 1 ) -#define MPP12_SPI_MOSI MPP( 12, 0xb, 0, 0, 0, 0, 0, 0, 1 ) -#define MPP12_TW1_SDA MPP( 12, 0xd, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP12_SD_CLK MPP( 12, 0x1, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP12_AU_SPDIF0 MPP( 12, 0xa, 0, 1, 0, 0, 0, 0, 1 ) +#define MPP12_SPI_MOSI MPP( 12, 0xb, 0, 1, 0, 0, 0, 0, 1 ) +#define MPP12_TW1_SDA MPP( 12, 0xd, 1, 0, 0, 0, 0, 0, 1 ) #define MPP13_GPIO MPP( 13, 0x0, 1, 1, 1, 1, 1, 1, 1 ) -#define MPP13_SD_CMD MPP( 13, 0x1, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP13_UART1_TXD MPP( 13, 0x3, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP13_AU_SPDIFRMCLK MPP( 13, 0xa, 0, 0, 0, 0, 0, 0, 1 ) -#define MPP13_LCDPWM MPP( 13, 0xb, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP13_SD_CMD MPP( 13, 0x1, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP13_UART1_TXD MPP( 13, 0x3, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP13_AU_SPDIFRMCLK MPP( 13, 0xa, 0, 1, 0, 0, 0, 0, 1 ) +#define MPP13_LCDPWM MPP( 13, 0xb, 0, 1, 0, 0, 0, 0, 1 ) #define MPP14_GPIO MPP( 14, 0x0, 1, 1, 1, 1, 1, 1, 1 ) -#define MPP14_SD_D0 MPP( 14, 0x1, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP14_UART1_RXD MPP( 14, 0x3, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP14_SATA1_PRESENTn MPP( 14, 0x4, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP14_AU_SPDIFI MPP( 14, 0xa, 0, 0, 0, 0, 0, 0, 1 ) -#define MPP14_AU_I2SDI MPP( 14, 0xb, 0, 0, 0, 0, 0, 0, 1 ) -#define MPP14_MII0_COL MPP( 14, 0xd, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP14_SD_D0 MPP( 14, 0x1, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP14_UART1_RXD MPP( 14, 0x3, 1, 0, 1, 1, 1, 1, 1 ) +#define MPP14_SATA1_PRESENTn MPP( 14, 0x4, 0, 1, 0, 0, 1, 1, 1 ) +#define MPP14_AU_SPDIFI MPP( 14, 0xa, 1, 0, 0, 0, 0, 0, 1 ) +#define MPP14_AU_I2SDI MPP( 14, 0xb, 1, 0, 0, 0, 0, 0, 1 ) +#define MPP14_MII0_COL MPP( 14, 0xd, 1, 0, 1, 1, 1, 1, 1 ) #define MPP15_GPIO MPP( 15, 0x0, 1, 1, 1, 1, 1, 1, 1 ) -#define MPP15_SD_D1 MPP( 15, 0x1, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP15_UART0_RTS MPP( 15, 0x2, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP15_UART1_TXD MPP( 15, 0x3, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP15_SATA0_ACTn MPP( 15, 0x4, 0, 0, 0, 1, 1, 1, 1 ) -#define MPP15_SPI_CSn MPP( 15, 0xb, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP15_SD_D1 MPP( 15, 0x1, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP15_UART0_RTS MPP( 15, 0x2, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP15_UART1_TXD MPP( 15, 0x3, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP15_SATA0_ACTn MPP( 15, 0x4, 0, 1, 0, 1, 1, 1, 1 ) +#define MPP15_SPI_CSn MPP( 15, 0xb, 0, 1, 0, 0, 0, 0, 1 ) #define MPP16_GPIO MPP( 16, 0x0, 1, 1, 1, 1, 1, 1, 1 ) -#define MPP16_SD_D2 MPP( 16, 0x1, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP16_UART0_CTS MPP( 16, 0x2, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP16_UART1_RXD MPP( 16, 0x3, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP16_SATA1_ACTn MPP( 16, 0x4, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP16_LCD_EXT_REF_CLK MPP( 16, 0xb, 0, 0, 0, 0, 0, 0, 1 ) -#define MPP16_MII0_CRS MPP( 16, 0xd, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP16_SD_D2 MPP( 16, 0x1, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP16_UART0_CTS MPP( 16, 0x2, 1, 0, 1, 1, 1, 1, 1 ) +#define MPP16_UART1_RXD MPP( 16, 0x3, 1, 0, 1, 1, 1, 1, 1 ) +#define MPP16_SATA1_ACTn MPP( 16, 0x4, 0, 1, 0, 0, 1, 1, 1 ) +#define MPP16_LCD_EXT_REF_CLK MPP( 16, 0xb, 1, 0, 0, 0, 0, 0, 1 ) +#define MPP16_MII0_CRS MPP( 16, 0xd, 1, 0, 1, 1, 1, 1, 1 ) #define MPP17_GPIO MPP( 17, 0x0, 1, 1, 1, 1, 1, 1, 1 ) -#define MPP17_SD_D3 MPP( 17, 0x1, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP17_SATA0_PRESENTn MPP( 17, 0x4, 0, 0, 0, 1, 1, 1, 1 ) -#define MPP17_SATA1_ACTn MPP( 17, 0xa, 0, 0, 0, 0, 0, 0, 1 ) -#define MPP17_TW1_SCK MPP( 17, 0xd, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP17_SD_D3 MPP( 17, 0x1, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP17_SATA0_PRESENTn MPP( 17, 0x4, 0, 1, 0, 1, 1, 1, 1 ) +#define MPP17_SATA1_ACTn MPP( 17, 0xa, 0, 1, 0, 0, 0, 0, 1 ) +#define MPP17_TW1_SCK MPP( 17, 0xd, 1, 1, 0, 0, 0, 0, 1 ) #define MPP18_GPO MPP( 18, 0x0, 0, 1, 1, 1, 1, 1, 1 ) -#define MPP18_NF_IO0 MPP( 18, 0x1, 0, 0, 1, 1, 1, 1, 1 ) -#define MPP18_PEX0_CLKREQ MPP( 18, 0x2, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP18_NF_IO0 MPP( 18, 0x1, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP18_PEX0_CLKREQ MPP( 18, 0x2, 0, 1, 0, 0, 0, 0, 1 ) #define MPP19_GPO MPP( 19, 0x0, 0, 1, 1, 1, 1, 1, 1 ) -#define MPP19_NF_IO1 MPP( 19, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP19_NF_IO1 MPP( 19, 0x1, 1, 1, 1, 1, 1, 1, 1 ) #define MPP20_GPIO MPP( 20, 0x0, 1, 1, 0, 1, 1, 1, 1 ) -#define MPP20_TSMP0 MPP( 20, 0x1, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP20_TDM_CH0_TX_QL MPP( 20, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP20_TSMP0 MPP( 20, 0x1, 1, 1, 0, 0, 1, 1, 1 ) +#define MPP20_TDM_CH0_TX_QL MPP( 20, 0x2, 0, 1, 0, 0, 1, 1, 1 ) #define MPP20_GE1_TXD0 MPP( 20, 0x3, 0, 0, 0, 1, 1, 1, 1 ) -#define MPP20_AU_SPDIFI MPP( 20, 0x4, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP20_SATA1_ACTn MPP( 20, 0x5, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP20_AU_SPDIFI MPP( 20, 0x4, 1, 0, 0, 0, 1, 1, 1 ) +#define MPP20_SATA1_ACTn MPP( 20, 0x5, 0, 1, 0, 0, 1, 1, 1 ) #define MPP20_LCD_D0 MPP( 20, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP21_GPIO MPP( 21, 0x0, 1, 1, 0, 1, 1, 1, 1 ) -#define MPP21_TSMP1 MPP( 21, 0x1, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP21_TDM_CH0_RX_QL MPP( 21, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP21_TSMP1 MPP( 21, 0x1, 1, 1, 0, 0, 1, 1, 1 ) +#define MPP21_TDM_CH0_RX_QL MPP( 21, 0x2, 0, 1, 0, 0, 1, 1, 1 ) #define MPP21_GE1_TXD1 MPP( 21, 0x3, 0, 0, 0, 1, 1, 1, 1 ) -#define MPP21_AU_SPDIFO MPP( 21, 0x4, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP21_SATA0_ACTn MPP( 21, 0x5, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP21_AU_SPDIFO MPP( 21, 0x4, 0, 1, 0, 0, 1, 1, 1 ) +#define MPP21_SATA0_ACTn MPP( 21, 0x5, 0, 1, 0, 1, 1, 1, 1 ) #define MPP21_LCD_D1 MPP( 21, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP22_GPIO MPP( 22, 0x0, 1, 1, 0, 1, 1, 1, 1 ) -#define MPP22_TSMP2 MPP( 22, 0x1, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP22_TDM_CH2_TX_QL MPP( 22, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP22_TSMP2 MPP( 22, 0x1, 1, 1, 0, 0, 1, 1, 1 ) +#define MPP22_TDM_CH2_TX_QL MPP( 22, 0x2, 0, 1, 0, 0, 1, 1, 1 ) #define MPP22_GE1_TXD2 MPP( 22, 0x3, 0, 0, 0, 1, 1, 1, 1 ) -#define MPP22_AU_SPDIFRMKCLK MPP( 22, 0x4, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP22_SATA1_PRESENTn MPP( 22, 0x5, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP22_AU_SPDIFRMKCLK MPP( 22, 0x4, 0, 1, 0, 0, 1, 1, 1 ) +#define MPP22_SATA1_PRESENTn MPP( 22, 0x5, 0, 1, 0, 0, 1, 1, 1 ) #define MPP22_LCD_D2 MPP( 22, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP23_GPIO MPP( 23, 0x0, 1, 1, 0, 1, 1, 1, 1 ) -#define MPP23_TSMP3 MPP( 23, 0x1, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP23_TDM_CH2_RX_QL MPP( 23, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP23_TSMP3 MPP( 23, 0x1, 1, 1, 0, 0, 1, 1, 1 ) +#define MPP23_TDM_CH2_RX_QL MPP( 23, 0x2, 1, 0, 0, 0, 1, 1, 1 ) #define MPP23_GE1_TXD3 MPP( 23, 0x3, 0, 0, 0, 1, 1, 1, 1 ) -#define MPP23_AU_I2SBCLK MPP( 23, 0x4, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP23_SATA0_PRESENTn MPP( 23, 0x5, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP23_AU_I2SBCLK MPP( 23, 0x4, 0, 1, 0, 0, 1, 1, 1 ) +#define MPP23_SATA0_PRESENTn MPP( 23, 0x5, 0, 1, 0, 1, 1, 1, 1 ) #define MPP23_LCD_D3 MPP( 23, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP24_GPIO MPP( 24, 0x0, 1, 1, 0, 1, 1, 1, 1 ) -#define MPP24_TSMP4 MPP( 24, 0x1, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP24_TDM_SPI_CS0 MPP( 24, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP24_TSMP4 MPP( 24, 0x1, 1, 1, 0, 0, 1, 1, 1 ) +#define MPP24_TDM_SPI_CS0 MPP( 24, 0x2, 0, 1, 0, 0, 1, 1, 1 ) #define MPP24_GE1_RXD0 MPP( 24, 0x3, 0, 0, 0, 1, 1, 1, 1 ) -#define MPP24_AU_I2SDO MPP( 24, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP24_AU_I2SDO MPP( 24, 0x4, 0, 1, 0, 0, 1, 1, 1 ) #define MPP24_LCD_D4 MPP( 24, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP25_GPIO MPP( 25, 0x0, 1, 1, 0, 1, 1, 1, 1 ) -#define MPP25_TSMP5 MPP( 25, 0x1, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP25_TDM_SPI_SCK MPP( 25, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP25_TSMP5 MPP( 25, 0x1, 1, 1, 0, 0, 1, 1, 1 ) +#define MPP25_TDM_SPI_SCK MPP( 25, 0x2, 0, 1, 0, 0, 1, 1, 1 ) #define MPP25_GE1_RXD1 MPP( 25, 0x3, 0, 0, 0, 1, 1, 1, 1 ) -#define MPP25_AU_I2SLRCLK MPP( 25, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP25_AU_I2SLRCLK MPP( 25, 0x4, 0, 1, 0, 0, 1, 1, 1 ) #define MPP25_LCD_D5 MPP( 25, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP26_GPIO MPP( 26, 0x0, 1, 1, 0, 1, 1, 1, 1 ) -#define MPP26_TSMP6 MPP( 26, 0x1, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP26_TDM_SPI_MISO MPP( 26, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP26_TSMP6 MPP( 26, 0x1, 1, 1, 0, 0, 1, 1, 1 ) +#define MPP26_TDM_SPI_MISO MPP( 26, 0x2, 1, 0, 0, 0, 1, 1, 1 ) #define MPP26_GE1_RXD2 MPP( 26, 0x3, 0, 0, 0, 1, 1, 1, 1 ) -#define MPP26_AU_I2SMCLK MPP( 26, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP26_AU_I2SMCLK MPP( 26, 0x4, 0, 1, 0, 0, 1, 1, 1 ) #define MPP26_LCD_D6 MPP( 26, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP27_GPIO MPP( 27, 0x0, 1, 1, 0, 1, 1, 1, 1 ) -#define MPP27_TSMP7 MPP( 27, 0x1, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP27_TDM_SPI_MOSI MPP( 27, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP27_TSMP7 MPP( 27, 0x1, 1, 1, 0, 0, 1, 1, 1 ) +#define MPP27_TDM_SPI_MOSI MPP( 27, 0x2, 0, 1, 0, 0, 1, 1, 1 ) #define MPP27_GE1_RXD3 MPP( 27, 0x3, 0, 0, 0, 1, 1, 1, 1 ) -#define MPP27_AU_I2SDI MPP( 27, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP27_AU_I2SDI MPP( 27, 0x4, 1, 0, 0, 0, 1, 1, 1 ) #define MPP27_LCD_D7 MPP( 27, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP28_GPIO MPP( 28, 0x0, 1, 1, 0, 1, 1, 1, 1 ) -#define MPP28_TSMP8 MPP( 28, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP28_TSMP8 MPP( 28, 0x1, 1, 1, 0, 0, 1, 1, 1 ) #define MPP28_TDM_CODEC_INTn MPP( 28, 0x2, 0, 0, 0, 0, 1, 1, 1 ) #define MPP28_GE1_COL MPP( 28, 0x3, 0, 0, 0, 1, 1, 1, 1 ) -#define MPP28_AU_EXTCLK MPP( 28, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP28_AU_EXTCLK MPP( 28, 0x4, 1, 0, 0, 0, 1, 1, 1 ) #define MPP28_LCD_D8 MPP( 28, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP29_GPIO MPP( 29, 0x0, 1, 1, 0, 1, 1, 1, 1 ) -#define MPP29_TSMP9 MPP( 29, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP29_TSMP9 MPP( 29, 0x1, 1, 1, 0, 0, 1, 1, 1 ) #define MPP29_TDM_CODEC_RSTn MPP( 29, 0x2, 0, 0, 0, 0, 1, 1, 1 ) #define MPP29_GE1_TCLK MPP( 29, 0x3, 0, 0, 0, 1, 1, 1, 1 ) #define MPP29_LCD_D9 MPP( 29, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP30_GPIO MPP( 30, 0x0, 1, 1, 0, 1, 1, 1, 1 ) -#define MPP30_TSMP10 MPP( 30, 0x1, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP30_TDM_PCLK MPP( 30, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP30_TSMP10 MPP( 30, 0x1, 1, 1, 0, 0, 1, 1, 1 ) +#define MPP30_TDM_PCLK MPP( 30, 0x2, 1, 1, 0, 0, 1, 1, 1 ) #define MPP30_GE1_RXCTL MPP( 30, 0x3, 0, 0, 0, 1, 1, 1, 1 ) #define MPP30_LCD_D10 MPP( 30, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP31_GPIO MPP( 31, 0x0, 1, 1, 0, 1, 1, 1, 1 ) -#define MPP31_TSMP11 MPP( 31, 0x1, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP31_TDM_FS MPP( 31, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP31_TSMP11 MPP( 31, 0x1, 1, 1, 0, 0, 1, 1, 1 ) +#define MPP31_TDM_FS MPP( 31, 0x2, 1, 1, 0, 0, 1, 1, 1 ) #define MPP31_GE1_RXCLK MPP( 31, 0x3, 0, 0, 0, 1, 1, 1, 1 ) #define MPP31_LCD_D11 MPP( 31, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP32_GPIO MPP( 32, 0x0, 1, 1, 0, 1, 1, 1, 1 ) -#define MPP32_TSMP12 MPP( 32, 0x1, 0, 0, 0, 0, 1, 1, 1 ) -#define MPP32_TDM_DRX MPP( 32, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP32_TSMP12 MPP( 32, 0x1, 1, 1, 0, 0, 1, 1, 1 ) +#define MPP32_TDM_DRX MPP( 32, 0x2, 1, 0, 0, 0, 1, 1, 1 ) #define MPP32_GE1_TCLKOUT MPP( 32, 0x3, 0, 0, 0, 1, 1, 1, 1 ) #define MPP32_LCD_D12 MPP( 32, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP33_GPO MPP( 33, 0x0, 0, 1, 0, 1, 1, 1, 1 ) -#define MPP33_TDM_DTX MPP( 33, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP33_TDM_DTX MPP( 33, 0x2, 0, 1, 0, 0, 1, 1, 1 ) #define MPP33_GE1_TXCTL MPP( 33, 0x3, 0, 0, 0, 1, 1, 1, 1 ) #define MPP33_LCD_D13 MPP( 33, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP34_GPIO MPP( 34, 0x0, 1, 1, 0, 1, 1, 1, 1 ) -#define MPP34_TDM_SPI_CS1 MPP( 34, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP34_TDM_SPI_CS1 MPP( 34, 0x2, 0, 1, 0, 0, 1, 1, 1 ) #define MPP34_GE1_TXEN MPP( 34, 0x3, 0, 0, 0, 1, 1, 1, 1 ) -#define MPP34_SATA1_ACTn MPP( 34, 0x5, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP34_SATA1_ACTn MPP( 34, 0x5, 0, 1, 0, 0, 0, 1, 1 ) #define MPP34_LCD_D14 MPP( 34, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP35_GPIO MPP( 35, 0x0, 1, 1, 1, 1, 1, 1, 1 ) -#define MPP35_TDM_CH0_TX_QL MPP( 35, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP35_TDM_CH0_TX_QL MPP( 35, 0x2, 0, 1, 0, 0, 1, 1, 1 ) #define MPP35_GE1_RXERR MPP( 35, 0x3, 0, 0, 0, 1, 1, 1, 1 ) -#define MPP35_SATA0_ACTn MPP( 35, 0x5, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP35_SATA0_ACTn MPP( 35, 0x5, 0, 1, 0, 1, 1, 1, 1 ) #define MPP35_LCD_D15 MPP( 22, 0xb, 0, 0, 0, 0, 0, 0, 1 ) -#define MPP35_MII0_RXERR MPP( 35, 0xc, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP35_MII0_RXERR MPP( 35, 0xc, 1, 0, 1, 1, 1, 1, 1 ) #define MPP36_GPIO MPP( 36, 0x0, 1, 1, 1, 0, 0, 1, 1 ) -#define MPP36_TSMP0 MPP( 36, 0x1, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP36_TDM_SPI_CS1 MPP( 36, 0x2, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP36_AU_SPDIFI MPP( 36, 0x4, 0, 0, 1, 0, 0, 1, 1 ) -#define MPP36_TW1_SDA MPP( 36, 0xb, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP36_TSMP0 MPP( 36, 0x1, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP36_TDM_SPI_CS1 MPP( 36, 0x2, 0, 1, 0, 0, 0, 1, 1 ) +#define MPP36_AU_SPDIFI MPP( 36, 0x4, 1, 0, 1, 0, 0, 1, 1 ) +#define MPP36_TW1_SDA MPP( 36, 0xb, 1, 1, 0, 0, 0, 0, 1 ) #define MPP37_GPIO MPP( 37, 0x0, 1, 1, 1, 0, 0, 1, 1 ) -#define MPP37_TSMP1 MPP( 37, 0x1, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP37_TDM_CH2_TX_QL MPP( 37, 0x2, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP37_AU_SPDIFO MPP( 37, 0x4, 0, 0, 1, 0, 0, 1, 1 ) -#define MPP37_TW1_SCK MPP( 37, 0xb, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP37_TSMP1 MPP( 37, 0x1, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP37_TDM_CH2_TX_QL MPP( 37, 0x2, 0, 1, 0, 0, 0, 1, 1 ) +#define MPP37_AU_SPDIFO MPP( 37, 0x4, 0, 1, 1, 0, 0, 1, 1 ) +#define MPP37_TW1_SCK MPP( 37, 0xb, 1, 1, 0, 0, 0, 0, 1 ) #define MPP38_GPIO MPP( 38, 0x0, 1, 1, 1, 0, 0, 1, 1 ) -#define MPP38_TSMP2 MPP( 38, 0x1, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP38_TDM_CH2_RX_QL MPP( 38, 0x2, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP38_AU_SPDIFRMLCLK MPP( 38, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP38_TSMP2 MPP( 38, 0x1, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP38_TDM_CH2_RX_QL MPP( 38, 0x2, 0, 1, 0, 0, 0, 1, 1 ) +#define MPP38_AU_SPDIFRMLCLK MPP( 38, 0x4, 0, 1, 1, 0, 0, 1, 1 ) #define MPP38_LCD_D18 MPP( 38, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP39_GPIO MPP( 39, 0x0, 1, 1, 1, 0, 0, 1, 1 ) -#define MPP39_TSMP3 MPP( 39, 0x1, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP39_TDM_SPI_CS0 MPP( 39, 0x2, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP39_AU_I2SBCLK MPP( 39, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP39_TSMP3 MPP( 39, 0x1, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP39_TDM_SPI_CS0 MPP( 39, 0x2, 0, 1, 0, 0, 0, 1, 1 ) +#define MPP39_AU_I2SBCLK MPP( 39, 0x4, 0, 1, 1, 0, 0, 1, 1 ) #define MPP39_LCD_D19 MPP( 39, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP40_GPIO MPP( 40, 0x0, 1, 1, 1, 0, 0, 1, 1 ) -#define MPP40_TSMP4 MPP( 40, 0x1, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP40_TDM_SPI_SCK MPP( 40, 0x2, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP40_AU_I2SDO MPP( 40, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP40_TSMP4 MPP( 40, 0x1, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP40_TDM_SPI_SCK MPP( 40, 0x2, 0, 1, 0, 0, 0, 1, 1 ) +#define MPP40_AU_I2SDO MPP( 40, 0x4, 0, 1, 1, 0, 0, 1, 1 ) #define MPP40_LCD_D20 MPP( 40, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP41_GPIO MPP( 41, 0x0, 1, 1, 1, 0, 0, 1, 1 ) -#define MPP41_TSMP5 MPP( 41, 0x1, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP41_TDM_SPI_MISO MPP( 41, 0x2, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP41_AU_I2SLRCLK MPP( 41, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP41_TSMP5 MPP( 41, 0x1, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP41_TDM_SPI_MISO MPP( 41, 0x2, 1, 0, 0, 0, 0, 1, 1 ) +#define MPP41_AU_I2SLRCLK MPP( 41, 0x4, 0, 1, 1, 0, 0, 1, 1 ) #define MPP41_LCD_D21 MPP( 41, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP42_GPIO MPP( 42, 0x0, 1, 1, 1, 0, 0, 1, 1 ) -#define MPP42_TSMP6 MPP( 42, 0x1, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP42_TDM_SPI_MOSI MPP( 42, 0x2, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP42_AU_I2SMCLK MPP( 42, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP42_TSMP6 MPP( 42, 0x1, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP42_TDM_SPI_MOSI MPP( 42, 0x2, 0, 1, 0, 0, 0, 1, 1 ) +#define MPP42_AU_I2SMCLK MPP( 42, 0x4, 0, 1, 1, 0, 0, 1, 1 ) #define MPP42_LCD_D22 MPP( 42, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP43_GPIO MPP( 43, 0x0, 1, 1, 1, 0, 0, 1, 1 ) -#define MPP43_TSMP7 MPP( 43, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP43_TSMP7 MPP( 43, 0x1, 1, 1, 0, 0, 0, 1, 1 ) #define MPP43_TDM_CODEC_INTn MPP( 43, 0x2, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP43_AU_I2SDI MPP( 43, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP43_AU_I2SDI MPP( 43, 0x4, 1, 0, 1, 0, 0, 1, 1 ) #define MPP43_LCD_D23 MPP( 22, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP44_GPIO MPP( 44, 0x0, 1, 1, 1, 0, 0, 1, 1 ) -#define MPP44_TSMP8 MPP( 44, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP44_TSMP8 MPP( 44, 0x1, 1, 1, 0, 0, 0, 1, 1 ) #define MPP44_TDM_CODEC_RSTn MPP( 44, 0x2, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP44_AU_EXTCLK MPP( 44, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP44_AU_EXTCLK MPP( 44, 0x4, 1, 0, 1, 0, 0, 1, 1 ) #define MPP44_LCD_CLK MPP( 44, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP45_GPIO MPP( 45, 0x0, 1, 1, 0, 0, 0, 1, 1 ) -#define MPP45_TSMP9 MPP( 45, 0x1, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP45_TDM_PCLK MPP( 45, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP45_TSMP9 MPP( 45, 0x1, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP45_TDM_PCLK MPP( 45, 0x2, 1, 1, 0, 0, 0, 1, 1 ) #define MPP245_LCD_E MPP( 45, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP46_GPIO MPP( 46, 0x0, 1, 1, 0, 0, 0, 1, 1 ) -#define MPP46_TSMP10 MPP( 46, 0x1, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP46_TDM_FS MPP( 46, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP46_TSMP10 MPP( 46, 0x1, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP46_TDM_FS MPP( 46, 0x2, 1, 1, 0, 0, 0, 1, 1 ) #define MPP46_LCD_HSYNC MPP( 46, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP47_GPIO MPP( 47, 0x0, 1, 1, 0, 0, 0, 1, 1 ) -#define MPP47_TSMP11 MPP( 47, 0x1, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP47_TDM_DRX MPP( 47, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP47_TSMP11 MPP( 47, 0x1, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP47_TDM_DRX MPP( 47, 0x2, 1, 0, 0, 0, 0, 1, 1 ) #define MPP47_LCD_VSYNC MPP( 47, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP48_GPIO MPP( 48, 0x0, 1, 1, 0, 0, 0, 1, 1 ) -#define MPP48_TSMP12 MPP( 48, 0x1, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP48_TDM_DTX MPP( 48, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP48_TSMP12 MPP( 48, 0x1, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP48_TDM_DTX MPP( 48, 0x2, 0, 1, 0, 0, 0, 1, 1 ) #define MPP48_LCD_D16 MPP( 22, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP49_GPIO MPP( 49, 0x0, 1, 1, 0, 0, 0, 1, 0 ) #define MPP49_GPO MPP( 49, 0x0, 0, 1, 0, 0, 0, 0, 1 ) -#define MPP49_TSMP9 MPP( 49, 0x1, 0, 0, 0, 0, 0, 1, 0 ) -#define MPP49_TDM_CH0_RX_QL MPP( 49, 0x2, 0, 0, 0, 0, 0, 1, 1 ) -#define MPP49_PTP_CLK MPP( 49, 0x5, 0, 0, 0, 0, 0, 1, 0 ) -#define MPP49_PEX0_CLKREQ MPP( 49, 0xa, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP49_TSMP9 MPP( 49, 0x1, 1, 1, 0, 0, 0, 1, 0 ) +#define MPP49_TDM_CH0_RX_QL MPP( 49, 0x2, 0, 1, 0, 0, 0, 1, 1 ) +#define MPP49_PTP_CLK MPP( 49, 0x5, 1, 0, 0, 0, 0, 1, 0 ) +#define MPP49_PEX0_CLKREQ MPP( 49, 0xa, 0, 1, 0, 0, 0, 0, 1 ) #define MPP49_LCD_D17 MPP( 49, 0xb, 0, 0, 0, 0, 0, 0, 1 ) #define MPP_MAX 49 diff --git a/arch/arm/mach-lpc32xx/include/mach/irqs.h b/arch/arm/mach-lpc32xx/include/mach/irqs.h index 9e3b90df32e1..2667f52e3b04 100644 --- a/arch/arm/mach-lpc32xx/include/mach/irqs.h +++ b/arch/arm/mach-lpc32xx/include/mach/irqs.h @@ -61,7 +61,7 @@ */ #define IRQ_LPC32XX_JTAG_COMM_TX LPC32XX_SIC1_IRQ(1) #define IRQ_LPC32XX_JTAG_COMM_RX LPC32XX_SIC1_IRQ(2) -#define IRQ_LPC32XX_GPI_28 LPC32XX_SIC1_IRQ(4) +#define IRQ_LPC32XX_GPI_11 LPC32XX_SIC1_IRQ(4) #define IRQ_LPC32XX_TS_P LPC32XX_SIC1_IRQ(6) #define IRQ_LPC32XX_TS_IRQ LPC32XX_SIC1_IRQ(7) #define IRQ_LPC32XX_TS_AUX LPC32XX_SIC1_IRQ(8) diff --git a/arch/arm/mach-lpc32xx/irq.c b/arch/arm/mach-lpc32xx/irq.c index c74de01ab5b6..4eae566dfdc7 100644 --- a/arch/arm/mach-lpc32xx/irq.c +++ b/arch/arm/mach-lpc32xx/irq.c @@ -118,10 +118,6 @@ static const struct lpc32xx_event_info lpc32xx_events[NR_IRQS] = { .event_group = &lpc32xx_event_pin_regs, .mask = LPC32XX_CLKPWR_EXTSRC_GPI_06_BIT, }, - [IRQ_LPC32XX_GPI_28] = { - .event_group = &lpc32xx_event_pin_regs, - .mask = LPC32XX_CLKPWR_EXTSRC_GPI_28_BIT, - }, [IRQ_LPC32XX_GPIO_00] = { .event_group = &lpc32xx_event_int_regs, .mask = LPC32XX_CLKPWR_INTSRC_GPIO_00_BIT, @@ -309,18 +305,9 @@ static int lpc32xx_irq_wake(struct irq_data *d, unsigned int state) if (state) eventreg |= lpc32xx_events[d->irq].mask; - else { + else eventreg &= ~lpc32xx_events[d->irq].mask; - /* - * When disabling the wakeup, clear the latched - * event - */ - __raw_writel(lpc32xx_events[d->irq].mask, - lpc32xx_events[d->irq]. - event_group->rawstat_reg); - } - __raw_writel(eventreg, lpc32xx_events[d->irq].event_group->enab_reg); @@ -393,15 +380,13 @@ void __init lpc32xx_init_irq(void) /* Setup SIC1 */ __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC1_BASE)); - __raw_writel(SIC1_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC1_BASE)); - __raw_writel(SIC1_ATR_DEFAULT, - LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC1_BASE)); + __raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC1_BASE)); + __raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC1_BASE)); /* Setup SIC2 */ __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE)); - __raw_writel(SIC2_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC2_BASE)); - __raw_writel(SIC2_ATR_DEFAULT, - LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC2_BASE)); + __raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC2_BASE)); + __raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC2_BASE)); /* Configure supported IRQ's */ for (i = 0; i < NR_IRQS; i++) { diff --git a/arch/arm/mach-lpc32xx/serial.c b/arch/arm/mach-lpc32xx/serial.c index f2735281616a..429cfdbb2b3d 100644 --- a/arch/arm/mach-lpc32xx/serial.c +++ b/arch/arm/mach-lpc32xx/serial.c @@ -88,7 +88,6 @@ struct uartinit { char *uart_ck_name; u32 ck_mode_mask; void __iomem *pdiv_clk_reg; - resource_size_t mapbase; }; static struct uartinit uartinit_data[] __initdata = { @@ -98,7 +97,6 @@ static struct uartinit uartinit_data[] __initdata = { .ck_mode_mask = LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 5), .pdiv_clk_reg = LPC32XX_CLKPWR_UART5_CLK_CTRL, - .mapbase = LPC32XX_UART5_BASE, }, #endif #ifdef CONFIG_ARCH_LPC32XX_UART3_SELECT @@ -107,7 +105,6 @@ static struct uartinit uartinit_data[] __initdata = { .ck_mode_mask = LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 3), .pdiv_clk_reg = LPC32XX_CLKPWR_UART3_CLK_CTRL, - .mapbase = LPC32XX_UART3_BASE, }, #endif #ifdef CONFIG_ARCH_LPC32XX_UART4_SELECT @@ -116,7 +113,6 @@ static struct uartinit uartinit_data[] __initdata = { .ck_mode_mask = LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 4), .pdiv_clk_reg = LPC32XX_CLKPWR_UART4_CLK_CTRL, - .mapbase = LPC32XX_UART4_BASE, }, #endif #ifdef CONFIG_ARCH_LPC32XX_UART6_SELECT @@ -125,7 +121,6 @@ static struct uartinit uartinit_data[] __initdata = { .ck_mode_mask = LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 6), .pdiv_clk_reg = LPC32XX_CLKPWR_UART6_CLK_CTRL, - .mapbase = LPC32XX_UART6_BASE, }, #endif }; @@ -170,24 +165,11 @@ void __init lpc32xx_serial_init(void) /* pre-UART clock divider set to 1 */ __raw_writel(0x0101, uartinit_data[i].pdiv_clk_reg); - - /* - * Force a flush of the RX FIFOs to work around a - * HW bug - */ - puart = uartinit_data[i].mapbase; - __raw_writel(0xC1, LPC32XX_UART_IIR_FCR(puart)); - __raw_writel(0x00, LPC32XX_UART_DLL_FIFO(puart)); - j = LPC32XX_SUART_FIFO_SIZE; - while (j--) - tmp = __raw_readl( - LPC32XX_UART_DLL_FIFO(puart)); - __raw_writel(0, LPC32XX_UART_IIR_FCR(puart)); } /* This needs to be done after all UART clocks are setup */ __raw_writel(clkmodes, LPC32XX_UARTCTL_CLKMODE); - for (i = 0; i < ARRAY_SIZE(uartinit_data); i++) { + for (i = 0; i < ARRAY_SIZE(uartinit_data) - 1; i++) { /* Force a flush of the RX FIFOs to work around a HW bug */ puart = serial_std_platform_data[i].mapbase; __raw_writel(0xC1, LPC32XX_UART_IIR_FCR(puart)); diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c index d90e244e05e7..23d3980ef59d 100644 --- a/arch/arm/mach-mv78xx0/common.c +++ b/arch/arm/mach-mv78xx0/common.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -171,7 +170,7 @@ void __init mv78xx0_map_io(void) void __init mv78xx0_ehci0_init(void) { orion_ehci_init(&mv78xx0_mbus_dram_info, - USB0_PHYS_BASE, IRQ_MV78XX0_USB_0, EHCI_PHY_NA); + USB0_PHYS_BASE, IRQ_MV78XX0_USB_0); } diff --git a/arch/arm/mach-mv78xx0/mpp.h b/arch/arm/mach-mv78xx0/mpp.h index 3752302ae2ee..b61b50927123 100644 --- a/arch/arm/mach-mv78xx0/mpp.h +++ b/arch/arm/mach-mv78xx0/mpp.h @@ -24,296 +24,296 @@ #define MPP_78100_A0_MASK MPP(0, 0x0, 0, 0, 1) #define MPP0_GPIO MPP(0, 0x0, 1, 1, 1) -#define MPP0_GE0_COL MPP(0, 0x1, 0, 0, 1) -#define MPP0_GE1_TXCLK MPP(0, 0x2, 0, 0, 1) +#define MPP0_GE0_COL MPP(0, 0x1, 1, 0, 1) +#define MPP0_GE1_TXCLK MPP(0, 0x2, 0, 1, 1) #define MPP0_UNUSED MPP(0, 0x3, 0, 0, 1) #define MPP1_GPIO MPP(1, 0x0, 1, 1, 1) -#define MPP1_GE0_RXERR MPP(1, 0x1, 0, 0, 1) -#define MPP1_GE1_TXCTL MPP(1, 0x2, 0, 0, 1) +#define MPP1_GE0_RXERR MPP(1, 0x1, 1, 0, 1) +#define MPP1_GE1_TXCTL MPP(1, 0x2, 0, 1, 1) #define MPP1_UNUSED MPP(1, 0x3, 0, 0, 1) #define MPP2_GPIO MPP(2, 0x0, 1, 1, 1) -#define MPP2_GE0_CRS MPP(2, 0x1, 0, 0, 1) -#define MPP2_GE1_RXCTL MPP(2, 0x2, 0, 0, 1) +#define MPP2_GE0_CRS MPP(2, 0x1, 1, 0, 1) +#define MPP2_GE1_RXCTL MPP(2, 0x2, 1, 0, 1) #define MPP2_UNUSED MPP(2, 0x3, 0, 0, 1) #define MPP3_GPIO MPP(3, 0x0, 1, 1, 1) -#define MPP3_GE0_TXERR MPP(3, 0x1, 0, 0, 1) -#define MPP3_GE1_RXCLK MPP(3, 0x2, 0, 0, 1) +#define MPP3_GE0_TXERR MPP(3, 0x1, 0, 1, 1) +#define MPP3_GE1_RXCLK MPP(3, 0x2, 1, 0, 1) #define MPP3_UNUSED MPP(3, 0x3, 0, 0, 1) #define MPP4_GPIO MPP(4, 0x0, 1, 1, 1) -#define MPP4_GE0_TXD4 MPP(4, 0x1, 0, 0, 1) -#define MPP4_GE1_TXD0 MPP(4, 0x2, 0, 0, 1) +#define MPP4_GE0_TXD4 MPP(4, 0x1, 0, 1, 1) +#define MPP4_GE1_TXD0 MPP(4, 0x2, 0, 1, 1) #define MPP4_UNUSED MPP(4, 0x3, 0, 0, 1) #define MPP5_GPIO MPP(5, 0x0, 1, 1, 1) -#define MPP5_GE0_TXD5 MPP(5, 0x1, 0, 0, 1) -#define MPP5_GE1_TXD1 MPP(5, 0x2, 0, 0, 1) +#define MPP5_GE0_TXD5 MPP(5, 0x1, 0, 1, 1) +#define MPP5_GE1_TXD1 MPP(5, 0x2, 0, 1, 1) #define MPP5_UNUSED MPP(5, 0x3, 0, 0, 1) #define MPP6_GPIO MPP(6, 0x0, 1, 1, 1) -#define MPP6_GE0_TXD6 MPP(6, 0x1, 0, 0, 1) -#define MPP6_GE1_TXD2 MPP(6, 0x2, 0, 0, 1) +#define MPP6_GE0_TXD6 MPP(6, 0x1, 0, 1, 1) +#define MPP6_GE1_TXD2 MPP(6, 0x2, 0, 1, 1) #define MPP6_UNUSED MPP(6, 0x3, 0, 0, 1) #define MPP7_GPIO MPP(7, 0x0, 1, 1, 1) -#define MPP7_GE0_TXD7 MPP(7, 0x1, 0, 0, 1) -#define MPP7_GE1_TXD3 MPP(7, 0x2, 0, 0, 1) +#define MPP7_GE0_TXD7 MPP(7, 0x1, 0, 1, 1) +#define MPP7_GE1_TXD3 MPP(7, 0x2, 0, 1, 1) #define MPP7_UNUSED MPP(7, 0x3, 0, 0, 1) #define MPP8_GPIO MPP(8, 0x0, 1, 1, 1) -#define MPP8_GE0_RXD4 MPP(8, 0x1, 0, 0, 1) -#define MPP8_GE1_RXD0 MPP(8, 0x2, 0, 0, 1) +#define MPP8_GE0_RXD4 MPP(8, 0x1, 1, 0, 1) +#define MPP8_GE1_RXD0 MPP(8, 0x2, 1, 0, 1) #define MPP8_UNUSED MPP(8, 0x3, 0, 0, 1) #define MPP9_GPIO MPP(9, 0x0, 1, 1, 1) -#define MPP9_GE0_RXD5 MPP(9, 0x1, 0, 0, 1) -#define MPP9_GE1_RXD1 MPP(9, 0x2, 0, 0, 1) +#define MPP9_GE0_RXD5 MPP(9, 0x1, 1, 0, 1) +#define MPP9_GE1_RXD1 MPP(9, 0x2, 1, 0, 1) #define MPP9_UNUSED MPP(9, 0x3, 0, 0, 1) #define MPP10_GPIO MPP(10, 0x0, 1, 1, 1) -#define MPP10_GE0_RXD6 MPP(10, 0x1, 0, 0, 1) -#define MPP10_GE1_RXD2 MPP(10, 0x2, 0, 0, 1) +#define MPP10_GE0_RXD6 MPP(10, 0x1, 1, 0, 1) +#define MPP10_GE1_RXD2 MPP(10, 0x2, 1, 0, 1) #define MPP10_UNUSED MPP(10, 0x3, 0, 0, 1) #define MPP11_GPIO MPP(11, 0x0, 1, 1, 1) -#define MPP11_GE0_RXD7 MPP(11, 0x1, 0, 0, 1) -#define MPP11_GE1_RXD3 MPP(11, 0x2, 0, 0, 1) +#define MPP11_GE0_RXD7 MPP(11, 0x1, 1, 0, 1) +#define MPP11_GE1_RXD3 MPP(11, 0x2, 1, 0, 1) #define MPP11_UNUSED MPP(11, 0x3, 0, 0, 1) #define MPP12_GPIO MPP(12, 0x0, 1, 1, 1) -#define MPP12_M_BB MPP(12, 0x3, 0, 0, 1) -#define MPP12_UA0_CTSn MPP(12, 0x4, 0, 0, 1) -#define MPP12_NAND_FLASH_REn0 MPP(12, 0x5, 0, 0, 1) -#define MPP12_TDM0_SCSn MPP(12, 0X6, 0, 0, 1) +#define MPP12_M_BB MPP(12, 0x3, 1, 0, 1) +#define MPP12_UA0_CTSn MPP(12, 0x4, 1, 0, 1) +#define MPP12_NAND_FLASH_REn0 MPP(12, 0x5, 0, 1, 1) +#define MPP12_TDM0_SCSn MPP(12, 0X6, 0, 1, 1) #define MPP12_UNUSED MPP(12, 0x1, 0, 0, 1) #define MPP13_GPIO MPP(13, 0x0, 1, 1, 1) -#define MPP13_SYSRST_OUTn MPP(13, 0x3, 0, 0, 1) -#define MPP13_UA0_RTSn MPP(13, 0x4, 0, 0, 1) -#define MPP13_NAN_FLASH_WEn0 MPP(13, 0x5, 0, 0, 1) -#define MPP13_TDM_SCLK MPP(13, 0x6, 0, 0, 1) +#define MPP13_SYSRST_OUTn MPP(13, 0x3, 0, 1, 1) +#define MPP13_UA0_RTSn MPP(13, 0x4, 0, 1, 1) +#define MPP13_NAN_FLASH_WEn0 MPP(13, 0x5, 0, 1, 1) +#define MPP13_TDM_SCLK MPP(13, 0x6, 0, 1, 1) #define MPP13_UNUSED MPP(13, 0x1, 0, 0, 1) #define MPP14_GPIO MPP(14, 0x0, 1, 1, 1) -#define MPP14_SATA1_ACTn MPP(14, 0x3, 0, 0, 1) -#define MPP14_UA1_CTSn MPP(14, 0x4, 0, 0, 1) -#define MPP14_NAND_FLASH_REn1 MPP(14, 0x5, 0, 0, 1) -#define MPP14_TDM_SMOSI MPP(14, 0x6, 0, 0, 1) +#define MPP14_SATA1_ACTn MPP(14, 0x3, 0, 1, 1) +#define MPP14_UA1_CTSn MPP(14, 0x4, 1, 0, 1) +#define MPP14_NAND_FLASH_REn1 MPP(14, 0x5, 0, 1, 1) +#define MPP14_TDM_SMOSI MPP(14, 0x6, 0, 1, 1) #define MPP14_UNUSED MPP(14, 0x1, 0, 0, 1) #define MPP15_GPIO MPP(15, 0x0, 1, 1, 1) -#define MPP15_SATA0_ACTn MPP(15, 0x3, 0, 0, 1) -#define MPP15_UA1_RTSn MPP(15, 0x4, 0, 0, 1) -#define MPP15_NAND_FLASH_WEn1 MPP(15, 0x5, 0, 0, 1) -#define MPP15_TDM_SMISO MPP(15, 0x6, 0, 0, 1) +#define MPP15_SATA0_ACTn MPP(15, 0x3, 0, 1, 1) +#define MPP15_UA1_RTSn MPP(15, 0x4, 0, 1, 1) +#define MPP15_NAND_FLASH_WEn1 MPP(15, 0x5, 0, 1, 1) +#define MPP15_TDM_SMISO MPP(15, 0x6, 1, 0, 1) #define MPP15_UNUSED MPP(15, 0x1, 0, 0, 1) #define MPP16_GPIO MPP(16, 0x0, 1, 1, 1) -#define MPP16_SATA1_PRESENTn MPP(16, 0x3, 0, 0, 1) -#define MPP16_UA2_TXD MPP(16, 0x4, 0, 0, 1) -#define MPP16_NAND_FLASH_REn3 MPP(16, 0x5, 0, 0, 1) -#define MPP16_TDM_INTn MPP(16, 0x6, 0, 0, 1) +#define MPP16_SATA1_PRESENTn MPP(16, 0x3, 0, 1, 1) +#define MPP16_UA2_TXD MPP(16, 0x4, 0, 1, 1) +#define MPP16_NAND_FLASH_REn3 MPP(16, 0x5, 0, 1, 1) +#define MPP16_TDM_INTn MPP(16, 0x6, 1, 0, 1) #define MPP16_UNUSED MPP(16, 0x1, 0, 0, 1) #define MPP17_GPIO MPP(17, 0x0, 1, 1, 1) -#define MPP17_SATA0_PRESENTn MPP(17, 0x3, 0, 0, 1) -#define MPP17_UA2_RXD MPP(17, 0x4, 0, 0, 1) -#define MPP17_NAND_FLASH_WEn3 MPP(17, 0x5, 0, 0, 1) -#define MPP17_TDM_RSTn MPP(17, 0x6, 0, 0, 1) +#define MPP17_SATA0_PRESENTn MPP(17, 0x3, 0, 1, 1) +#define MPP17_UA2_RXD MPP(17, 0x4, 1, 0, 1) +#define MPP17_NAND_FLASH_WEn3 MPP(17, 0x5, 0, 1, 1) +#define MPP17_TDM_RSTn MPP(17, 0x6, 0, 1, 1) #define MPP17_UNUSED MPP(17, 0x1, 0, 0, 1) #define MPP18_GPIO MPP(18, 0x0, 1, 1, 1) -#define MPP18_UA0_CTSn MPP(18, 0x4, 0, 0, 1) -#define MPP18_BOOT_FLASH_REn MPP(18, 0x5, 0, 0, 1) +#define MPP18_UA0_CTSn MPP(18, 0x4, 1, 0, 1) +#define MPP18_BOOT_FLASH_REn MPP(18, 0x5, 0, 1, 1) #define MPP18_UNUSED MPP(18, 0x1, 0, 0, 1) #define MPP19_GPIO MPP(19, 0x0, 1, 1, 1) -#define MPP19_UA0_CTSn MPP(19, 0x4, 0, 0, 1) -#define MPP19_BOOT_FLASH_WEn MPP(19, 0x5, 0, 0, 1) +#define MPP19_UA0_CTSn MPP(19, 0x4, 0, 1, 1) +#define MPP19_BOOT_FLASH_WEn MPP(19, 0x5, 0, 1, 1) #define MPP19_UNUSED MPP(19, 0x1, 0, 0, 1) #define MPP20_GPIO MPP(20, 0x0, 1, 1, 1) -#define MPP20_UA1_CTSs MPP(20, 0x4, 0, 0, 1) -#define MPP20_TDM_PCLK MPP(20, 0x6, 0, 0, 0) +#define MPP20_UA1_CTSs MPP(20, 0x4, 1, 0, 1) +#define MPP20_TDM_PCLK MPP(20, 0x6, 1, 1, 0) #define MPP20_UNUSED MPP(20, 0x1, 0, 0, 1) #define MPP21_GPIO MPP(21, 0x0, 1, 1, 1) -#define MPP21_UA1_CTSs MPP(21, 0x4, 0, 0, 1) -#define MPP21_TDM_FSYNC MPP(21, 0x6, 0, 0, 0) +#define MPP21_UA1_CTSs MPP(21, 0x4, 0, 1, 1) +#define MPP21_TDM_FSYNC MPP(21, 0x6, 1, 1, 0) #define MPP21_UNUSED MPP(21, 0x1, 0, 0, 1) #define MPP22_GPIO MPP(22, 0x0, 1, 1, 1) -#define MPP22_UA3_TDX MPP(22, 0x4, 0, 0, 1) -#define MPP22_NAND_FLASH_REn2 MPP(22, 0x5, 0, 0, 1) -#define MPP22_TDM_DRX MPP(22, 0x6, 0, 0, 1) +#define MPP22_UA3_TDX MPP(22, 0x4, 0, 1, 1) +#define MPP22_NAND_FLASH_REn2 MPP(22, 0x5, 0, 1, 1) +#define MPP22_TDM_DRX MPP(22, 0x6, 1, 0, 1) #define MPP22_UNUSED MPP(22, 0x1, 0, 0, 1) #define MPP23_GPIO MPP(23, 0x0, 1, 1, 1) -#define MPP23_UA3_RDX MPP(23, 0x4, 0, 0, 1) -#define MPP23_NAND_FLASH_WEn2 MPP(23, 0x5, 0, 0, 1) -#define MPP23_TDM_DTX MPP(23, 0x6, 0, 0, 1) +#define MPP23_UA3_RDX MPP(23, 0x4, 1, 0, 1) +#define MPP23_NAND_FLASH_WEn2 MPP(23, 0x5, 0, 1, 1) +#define MPP23_TDM_DTX MPP(23, 0x6, 0, 1, 1) #define MPP23_UNUSED MPP(23, 0x1, 0, 0, 1) #define MPP24_GPIO MPP(24, 0x0, 1, 1, 1) -#define MPP24_UA2_TXD MPP(24, 0x4, 0, 0, 1) -#define MPP24_TDM_INTn MPP(24, 0x6, 0, 0, 1) +#define MPP24_UA2_TXD MPP(24, 0x4, 0, 1, 1) +#define MPP24_TDM_INTn MPP(24, 0x6, 1, 0, 1) #define MPP24_UNUSED MPP(24, 0x1, 0, 0, 1) #define MPP25_GPIO MPP(25, 0x0, 1, 1, 1) -#define MPP25_UA2_RXD MPP(25, 0x4, 0, 0, 1) -#define MPP25_TDM_RSTn MPP(25, 0x6, 0, 0, 1) +#define MPP25_UA2_RXD MPP(25, 0x4, 1, 0, 1) +#define MPP25_TDM_RSTn MPP(25, 0x6, 0, 1, 1) #define MPP25_UNUSED MPP(25, 0x1, 0, 0, 1) #define MPP26_GPIO MPP(26, 0x0, 1, 1, 1) -#define MPP26_UA2_CTSn MPP(26, 0x4, 0, 0, 1) -#define MPP26_TDM_PCLK MPP(26, 0x6, 0, 0, 1) +#define MPP26_UA2_CTSn MPP(26, 0x4, 1, 0, 1) +#define MPP26_TDM_PCLK MPP(26, 0x6, 1, 1, 1) #define MPP26_UNUSED MPP(26, 0x1, 0, 0, 1) #define MPP27_GPIO MPP(27, 0x0, 1, 1, 1) -#define MPP27_UA2_RTSn MPP(27, 0x4, 0, 0, 1) -#define MPP27_TDM_FSYNC MPP(27, 0x6, 0, 0, 1) +#define MPP27_UA2_RTSn MPP(27, 0x4, 0, 1, 1) +#define MPP27_TDM_FSYNC MPP(27, 0x6, 1, 1, 1) #define MPP27_UNUSED MPP(27, 0x1, 0, 0, 1) #define MPP28_GPIO MPP(28, 0x0, 1, 1, 1) -#define MPP28_UA3_TXD MPP(28, 0x4, 0, 0, 1) -#define MPP28_TDM_DRX MPP(28, 0x6, 0, 0, 1) +#define MPP28_UA3_TXD MPP(28, 0x4, 0, 1, 1) +#define MPP28_TDM_DRX MPP(28, 0x6, 1, 0, 1) #define MPP28_UNUSED MPP(28, 0x1, 0, 0, 1) #define MPP29_GPIO MPP(29, 0x0, 1, 1, 1) -#define MPP29_UA3_RXD MPP(29, 0x4, 0, 0, 1) -#define MPP29_SYSRST_OUTn MPP(29, 0x5, 0, 0, 1) -#define MPP29_TDM_DTX MPP(29, 0x6, 0, 0, 1) +#define MPP29_UA3_RXD MPP(29, 0x4, 1, 0, 1) +#define MPP29_SYSRST_OUTn MPP(29, 0x5, 0, 1, 1) +#define MPP29_TDM_DTX MPP(29, 0x6, 0, 1, 1) #define MPP29_UNUSED MPP(29, 0x1, 0, 0, 1) #define MPP30_GPIO MPP(30, 0x0, 1, 1, 1) -#define MPP30_UA3_CTSn MPP(30, 0x4, 0, 0, 1) +#define MPP30_UA3_CTSn MPP(30, 0x4, 1, 0, 1) #define MPP30_UNUSED MPP(30, 0x1, 0, 0, 1) #define MPP31_GPIO MPP(31, 0x0, 1, 1, 1) -#define MPP31_UA3_RTSn MPP(31, 0x4, 0, 0, 1) -#define MPP31_TDM1_SCSn MPP(31, 0x6, 0, 0, 1) +#define MPP31_UA3_RTSn MPP(31, 0x4, 0, 1, 1) +#define MPP31_TDM1_SCSn MPP(31, 0x6, 0, 1, 1) #define MPP31_UNUSED MPP(31, 0x1, 0, 0, 1) #define MPP32_GPIO MPP(32, 0x1, 1, 1, 1) -#define MPP32_UA3_TDX MPP(32, 0x4, 0, 0, 1) -#define MPP32_SYSRST_OUTn MPP(32, 0x5, 0, 0, 1) -#define MPP32_TDM0_RXQ MPP(32, 0x6, 0, 0, 1) +#define MPP32_UA3_TDX MPP(32, 0x4, 0, 1, 1) +#define MPP32_SYSRST_OUTn MPP(32, 0x5, 0, 1, 1) +#define MPP32_TDM0_RXQ MPP(32, 0x6, 0, 1, 1) #define MPP32_UNUSED MPP(32, 0x3, 0, 0, 1) #define MPP33_GPIO MPP(33, 0x1, 1, 1, 1) -#define MPP33_UA3_RDX MPP(33, 0x4, 0, 0, 1) -#define MPP33_TDM0_TXQ MPP(33, 0x6, 0, 0, 1) +#define MPP33_UA3_RDX MPP(33, 0x4, 1, 0, 1) +#define MPP33_TDM0_TXQ MPP(33, 0x6, 0, 1, 1) #define MPP33_UNUSED MPP(33, 0x3, 0, 0, 1) #define MPP34_GPIO MPP(34, 0x1, 1, 1, 1) -#define MPP34_UA2_TDX MPP(34, 0x4, 0, 0, 1) -#define MPP34_TDM1_RXQ MPP(34, 0x6, 0, 0, 1) +#define MPP34_UA2_TDX MPP(34, 0x4, 0, 1, 1) +#define MPP34_TDM1_RXQ MPP(34, 0x6, 0, 1, 1) #define MPP34_UNUSED MPP(34, 0x3, 0, 0, 1) #define MPP35_GPIO MPP(35, 0x1, 1, 1, 1) -#define MPP35_UA2_RDX MPP(35, 0x4, 0, 0, 1) -#define MPP35_TDM1_TXQ MPP(35, 0x6, 0, 0, 1) +#define MPP35_UA2_RDX MPP(35, 0x4, 1, 0, 1) +#define MPP35_TDM1_TXQ MPP(35, 0x6, 0, 1, 1) #define MPP35_UNUSED MPP(35, 0x3, 0, 0, 1) #define MPP36_GPIO MPP(36, 0x1, 1, 1, 1) -#define MPP36_UA0_CTSn MPP(36, 0x2, 0, 0, 1) -#define MPP36_UA2_TDX MPP(36, 0x4, 0, 0, 1) -#define MPP36_TDM0_SCSn MPP(36, 0x6, 0, 0, 1) +#define MPP36_UA0_CTSn MPP(36, 0x2, 1, 0, 1) +#define MPP36_UA2_TDX MPP(36, 0x4, 0, 1, 1) +#define MPP36_TDM0_SCSn MPP(36, 0x6, 0, 1, 1) #define MPP36_UNUSED MPP(36, 0x3, 0, 0, 1) #define MPP37_GPIO MPP(37, 0x1, 1, 1, 1) -#define MPP37_UA0_RTSn MPP(37, 0x2, 0, 0, 1) -#define MPP37_UA2_RXD MPP(37, 0x4, 0, 0, 1) -#define MPP37_SYSRST_OUTn MPP(37, 0x5, 0, 0, 1) -#define MPP37_TDM_SCLK MPP(37, 0x6, 0, 0, 1) +#define MPP37_UA0_RTSn MPP(37, 0x2, 0, 1, 1) +#define MPP37_UA2_RXD MPP(37, 0x4, 1, 0, 1) +#define MPP37_SYSRST_OUTn MPP(37, 0x5, 0, 1, 1) +#define MPP37_TDM_SCLK MPP(37, 0x6, 0, 1, 1) #define MPP37_UNUSED MPP(37, 0x3, 0, 0, 1) #define MPP38_GPIO MPP(38, 0x1, 1, 1, 1) -#define MPP38_UA1_CTSn MPP(38, 0x2, 0, 0, 1) -#define MPP38_UA3_TXD MPP(38, 0x4, 0, 0, 1) -#define MPP38_SYSRST_OUTn MPP(38, 0x5, 0, 0, 1) -#define MPP38_TDM_SMOSI MPP(38, 0x6, 0, 0, 1) +#define MPP38_UA1_CTSn MPP(38, 0x2, 1, 0, 1) +#define MPP38_UA3_TXD MPP(38, 0x4, 0, 1, 1) +#define MPP38_SYSRST_OUTn MPP(38, 0x5, 0, 1, 1) +#define MPP38_TDM_SMOSI MPP(38, 0x6, 0, 1, 1) #define MPP38_UNUSED MPP(38, 0x3, 0, 0, 1) #define MPP39_GPIO MPP(39, 0x1, 1, 1, 1) -#define MPP39_UA1_RTSn MPP(39, 0x2, 0, 0, 1) -#define MPP39_UA3_RXD MPP(39, 0x4, 0, 0, 1) -#define MPP39_SYSRST_OUTn MPP(39, 0x5, 0, 0, 1) -#define MPP39_TDM_SMISO MPP(39, 0x6, 0, 0, 1) +#define MPP39_UA1_RTSn MPP(39, 0x2, 0, 1, 1) +#define MPP39_UA3_RXD MPP(39, 0x4, 1, 0, 1) +#define MPP39_SYSRST_OUTn MPP(39, 0x5, 0, 1, 1) +#define MPP39_TDM_SMISO MPP(39, 0x6, 1, 0, 1) #define MPP39_UNUSED MPP(39, 0x3, 0, 0, 1) #define MPP40_GPIO MPP(40, 0x1, 1, 1, 1) -#define MPP40_TDM_INTn MPP(40, 0x6, 0, 0, 1) +#define MPP40_TDM_INTn MPP(40, 0x6, 1, 0, 1) #define MPP40_UNUSED MPP(40, 0x0, 0, 0, 1) #define MPP41_GPIO MPP(41, 0x1, 1, 1, 1) -#define MPP41_TDM_RSTn MPP(41, 0x6, 0, 0, 1) +#define MPP41_TDM_RSTn MPP(41, 0x6, 0, 1, 1) #define MPP41_UNUSED MPP(41, 0x0, 0, 0, 1) #define MPP42_GPIO MPP(42, 0x1, 1, 1, 1) -#define MPP42_TDM_PCLK MPP(42, 0x6, 0, 0, 1) +#define MPP42_TDM_PCLK MPP(42, 0x6, 1, 1, 1) #define MPP42_UNUSED MPP(42, 0x0, 0, 0, 1) #define MPP43_GPIO MPP(43, 0x1, 1, 1, 1) -#define MPP43_TDM_FSYNC MPP(43, 0x6, 0, 0, 1) +#define MPP43_TDM_FSYNC MPP(43, 0x6, 1, 1, 1) #define MPP43_UNUSED MPP(43, 0x0, 0, 0, 1) #define MPP44_GPIO MPP(44, 0x1, 1, 1, 1) -#define MPP44_TDM_DRX MPP(44, 0x6, 0, 0, 1) +#define MPP44_TDM_DRX MPP(44, 0x6, 1, 0, 1) #define MPP44_UNUSED MPP(44, 0x0, 0, 0, 1) #define MPP45_GPIO MPP(45, 0x1, 1, 1, 1) -#define MPP45_SATA0_ACTn MPP(45, 0x3, 0, 0, 1) -#define MPP45_TDM_DRX MPP(45, 0x6, 0, 0, 1) +#define MPP45_SATA0_ACTn MPP(45, 0x3, 0, 1, 1) +#define MPP45_TDM_DRX MPP(45, 0x6, 0, 1, 1) #define MPP45_UNUSED MPP(45, 0x0, 0, 0, 1) #define MPP46_GPIO MPP(46, 0x1, 1, 1, 1) -#define MPP46_TDM_SCSn MPP(46, 0x6, 0, 0, 1) +#define MPP46_TDM_SCSn MPP(46, 0x6, 0, 1, 1) #define MPP46_UNUSED MPP(46, 0x0, 0, 0, 1) @@ -323,14 +323,14 @@ #define MPP48_GPIO MPP(48, 0x1, 1, 1, 1) -#define MPP48_SATA1_ACTn MPP(48, 0x3, 0, 0, 1) +#define MPP48_SATA1_ACTn MPP(48, 0x3, 0, 1, 1) #define MPP48_UNUSED MPP(48, 0x2, 0, 0, 1) #define MPP49_GPIO MPP(49, 0x1, 1, 1, 1) -#define MPP49_SATA0_ACTn MPP(49, 0x3, 0, 0, 1) -#define MPP49_M_BB MPP(49, 0x4, 0, 0, 1) +#define MPP49_SATA0_ACTn MPP(49, 0x3, 0, 1, 1) +#define MPP49_M_BB MPP(49, 0x4, 1, 0, 1) #define MPP49_UNUSED MPP(49, 0x2, 0, 0, 1) diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c index b3a71245f385..5dcc59d5b9ec 100644 --- a/arch/arm/mach-mxs/clock-mx28.c +++ b/arch/arm/mach-mxs/clock-mx28.c @@ -404,7 +404,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \ reg &= ~BM_CLKCTRL_##dr##_DIV; \ reg |= div << BP_CLKCTRL_##dr##_DIV; \ - if (reg & (1 << clk->enable_shift)) { \ + if (reg | (1 << clk->enable_shift)) { \ pr_err("%s: clock is gated\n", __func__); \ return -EINVAL; \ } \ diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h index 1332f73c9ad0..35a89dd27242 100644 --- a/arch/arm/mach-mxs/include/mach/mxs.h +++ b/arch/arm/mach-mxs/include/mach/mxs.h @@ -30,7 +30,6 @@ */ #define cpu_is_mx23() ( \ machine_is_mx23evk() || \ - machine_is_stmp378x() || \ 0) #define cpu_is_mx28() ( \ machine_is_mx28evk() || \ diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 841ae21f520b..19d5891c48e3 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -326,7 +326,6 @@ config MACH_OMAP4_PANDA config OMAP3_EMU bool "OMAP3 debugging peripherals" depends on ARCH_OMAP3 - select ARM_AMBA select OC_ETM help Say Y here to enable debugging hardware of omap3 diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 14a5971d0d48..63de2d396e2d 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -49,9 +49,8 @@ #define ETH_KS8851_QUART 138 #define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184 #define OMAP4_SFH7741_ENABLE_GPIO 188 -#define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */ +#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */ #define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */ -#define HDMI_GPIO_HPD 63 /* Hotplug detect */ static const int sdp4430_keymap[] = { KEY(0, 0, KEY_E), @@ -579,8 +578,12 @@ static void __init omap_sfh7741prox_init(void) static void sdp4430_hdmi_mux_init(void) { + /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */ + omap_mux_init_signal("hdmi_hpd", + OMAP_PIN_INPUT_PULLUP); omap_mux_init_signal("hdmi_cec", OMAP_PIN_INPUT_PULLUP); + /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */ omap_mux_init_signal("hdmi_ddc_scl", OMAP_PIN_INPUT_PULLUP); omap_mux_init_signal("hdmi_ddc_sda", @@ -588,9 +591,8 @@ static void sdp4430_hdmi_mux_init(void) } static struct gpio sdp4430_hdmi_gpios[] = { - { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" }, + { HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd" }, { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" }, - { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" }, }; static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev) @@ -607,21 +609,26 @@ static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev) static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev) { - gpio_free_array(sdp4430_hdmi_gpios, ARRAY_SIZE(sdp4430_hdmi_gpios)); + gpio_free(HDMI_GPIO_LS_OE); + gpio_free(HDMI_GPIO_HPD); } -static struct omap_dss_hdmi_data sdp4430_hdmi_data = { - .hpd_gpio = HDMI_GPIO_HPD, -}; - static struct omap_dss_device sdp4430_hdmi_device = { .name = "hdmi", .driver_name = "hdmi_panel", .type = OMAP_DISPLAY_TYPE_HDMI, + .clocks = { + .dispc = { + .dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK, + }, + .hdmi = { + .regn = 15, + .regm2 = 1, + }, + }, .platform_enable = sdp4430_panel_enable_hdmi, .platform_disable = sdp4430_panel_disable_hdmi, .channel = OMAP_DSS_CHANNEL_DIGIT, - .data = &sdp4430_hdmi_data, }; static struct omap_dss_device *sdp4430_dss_devices[] = { @@ -638,10 +645,6 @@ void omap_4430sdp_display_init(void) { sdp4430_hdmi_mux_init(); omap_display_init(&sdp4430_dss_data); - - omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT); - omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT); - omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN); } #ifdef CONFIG_OMAP_MUX diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 107dfc377a8a..0cfe2005cb50 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -52,9 +52,8 @@ #define GPIO_HUB_NRESET 62 #define GPIO_WIFI_PMENA 43 #define GPIO_WIFI_IRQ 53 -#define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */ +#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */ #define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */ -#define HDMI_GPIO_HPD 63 /* Hotplug detect */ /* wl127x BT, FM, GPS connectivity chip */ static int wl1271_gpios[] = {46, -1, -1}; @@ -615,8 +614,12 @@ int __init omap4_panda_dvi_init(void) static void omap4_panda_hdmi_mux_init(void) { + /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */ + omap_mux_init_signal("hdmi_hpd", + OMAP_PIN_INPUT_PULLUP); omap_mux_init_signal("hdmi_cec", OMAP_PIN_INPUT_PULLUP); + /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */ omap_mux_init_signal("hdmi_ddc_scl", OMAP_PIN_INPUT_PULLUP); omap_mux_init_signal("hdmi_ddc_sda", @@ -624,9 +627,8 @@ static void omap4_panda_hdmi_mux_init(void) } static struct gpio panda_hdmi_gpios[] = { - { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" }, + { HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd" }, { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" }, - { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" }, }; static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev) @@ -643,13 +645,10 @@ static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev) static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev) { - gpio_free_array(panda_hdmi_gpios, ARRAY_SIZE(panda_hdmi_gpios)); + gpio_free(HDMI_GPIO_LS_OE); + gpio_free(HDMI_GPIO_HPD); } -static struct omap_dss_hdmi_data omap4_panda_hdmi_data = { - .hpd_gpio = HDMI_GPIO_HPD, -}; - static struct omap_dss_device omap4_panda_hdmi_device = { .name = "hdmi", .driver_name = "hdmi_panel", @@ -657,7 +656,6 @@ static struct omap_dss_device omap4_panda_hdmi_device = { .platform_enable = omap4_panda_panel_enable_hdmi, .platform_disable = omap4_panda_panel_disable_hdmi, .channel = OMAP_DSS_CHANNEL_DIGIT, - .data = &omap4_panda_hdmi_data, }; static struct omap_dss_device *omap4_panda_dss_devices[] = { @@ -681,10 +679,6 @@ void omap4_panda_display_init(void) omap4_panda_hdmi_mux_init(); omap_display_init(&omap4_panda_dss_data); - - omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT); - omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT); - omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN); } static void __init omap4_panda_init(void) diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index c56597172bfc..88bd6f7705f0 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -133,7 +133,7 @@ static struct platform_device rx51_charger_device = { static void __init rx51_charger_init(void) { WARN_ON(gpio_request_one(RX51_USB_TRANSCEIVER_RST_GPIO, - GPIOF_OUT_INIT_HIGH, "isp1704_reset")); + GPIOF_OUT_INIT_LOW, "isp1704_reset")); platform_device_register(&rx51_charger_device); } diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index dfffbbf4c009..130034bf01d5 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -528,13 +528,7 @@ int gpmc_cs_configure(int cs, int cmd, int wval) case GPMC_CONFIG_DEV_SIZE: regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); - - /* clear 2 target bits */ - regval &= ~GPMC_CONFIG1_DEVICESIZE(3); - - /* set the proper value */ regval |= GPMC_CONFIG1_DEVICESIZE(wval); - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); break; diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c index 062749483476..ab8b35b780b5 100644 --- a/arch/arm/mach-omap2/opp.c +++ b/arch/arm/mach-omap2/opp.c @@ -53,7 +53,7 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def, omap_table_init = 1; /* Lets now register with OPP library */ - for (i = 0; i < opp_def_size; i++, opp_def++) { + for (i = 0; i < opp_def_size; i++) { struct omap_hwmod *oh; struct device *dev; @@ -86,6 +86,7 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def, __func__, opp_def->freq, opp_def->hwmod_name, i, r); } + opp_def++; } return 0; diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index f5a6bc1250ce..fb7dc52394a8 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -137,7 +137,7 @@ static irqreturn_t sr_interrupt(int irq, void *data) sr_write_reg(sr_info, ERRCONFIG_V1, status); } else if (sr_info->ip_type == SR_TYPE_V2) { /* Read the status bits */ - status = sr_read_reg(sr_info, IRQSTATUS); + sr_read_reg(sr_info, IRQSTATUS); /* Clear them by writing back */ sr_write_reg(sr_info, IRQSTATUS, status); diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 8a98da0b3f8e..0ab531d047fc 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include "common.h" @@ -73,8 +72,7 @@ void __init orion5x_map_io(void) void __init orion5x_ehci0_init(void) { orion_ehci_init(&orion5x_mbus_dram_info, - ORION5X_USB0_PHYS_BASE, IRQ_ORION5X_USB0_CTRL, - EHCI_PHY_ORION); + ORION5X_USB0_PHYS_BASE, IRQ_ORION5X_USB0_CTRL); } diff --git a/arch/arm/mach-orion5x/mpp.h b/arch/arm/mach-orion5x/mpp.h index db70e79a1198..eac68978a2c2 100644 --- a/arch/arm/mach-orion5x/mpp.h +++ b/arch/arm/mach-orion5x/mpp.h @@ -65,8 +65,8 @@ #define MPP8_GIGE MPP(8, 0x1, 0, 0, 1, 1, 1) #define MPP9_UNUSED MPP(9, 0x0, 0, 0, 1, 1, 1) -#define MPP9_GPIO MPP(9, 0x0, 1, 1, 1, 1, 1) -#define MPP9_GIGE MPP(9, 0x1, 0, 0, 1, 1, 1) +#define MPP9_GPIO MPP(9, 0x0, 0, 0, 1, 1, 1) +#define MPP9_GIGE MPP(9, 0x1, 1, 1, 1, 1, 1) #define MPP10_UNUSED MPP(10, 0x0, 0, 0, 1, 1, 1) #define MPP10_GPIO MPP(10, 0x0, 1, 1, 1, 1, 1) diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c index 6ca327d956e9..810a982a66f8 100644 --- a/arch/arm/mach-pxa/balloon3.c +++ b/arch/arm/mach-pxa/balloon3.c @@ -307,7 +307,7 @@ static inline void balloon3_mmc_init(void) {} /****************************************************************************** * USB Gadget ******************************************************************************/ -#if defined(CONFIG_USB_PXA27X)||defined(CONFIG_USB_PXA27X_MODULE) +#if defined(CONFIG_USB_GADGET_PXA27X)||defined(CONFIG_USB_GADGET_PXA27X_MODULE) static void balloon3_udc_command(int cmd) { if (cmd == PXA2XX_UDC_CMD_CONNECT) diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index 8a034872ac77..b2248e76ec8b 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -161,10 +161,10 @@ static mfp_cfg_t cm_x3xx_mfp_cfg[] __initdata = { GPIO99_GPIO, /* Ethernet IRQ */ /* RTC GPIOs */ - GPIO95_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC CS */ - GPIO96_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC WR */ - GPIO97_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC RD */ - GPIO98_GPIO, /* RTC IO */ + GPIO95_GPIO, /* RTC CS */ + GPIO96_GPIO, /* RTC WR */ + GPIO97_GPIO, /* RTC RD */ + GPIO98_GPIO, /* RTC IO */ /* Standard I2C */ GPIO21_I2C_SCL, diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c index fdf611cdacc2..ff9ff5f4fc47 100644 --- a/arch/arm/mach-pxa/colibri-pxa320.c +++ b/arch/arm/mach-pxa/colibri-pxa320.c @@ -147,7 +147,7 @@ static void __init colibri_pxa320_init_eth(void) static inline void __init colibri_pxa320_init_eth(void) {} #endif /* CONFIG_AX88796 */ -#if defined(CONFIG_USB_PXA27X)||defined(CONFIG_USB_PXA27X_MODULE) +#if defined(CONFIG_USB_GADGET_PXA27X)||defined(CONFIG_USB_GADGET_PXA27X_MODULE) static struct gpio_vbus_mach_info colibri_pxa320_gpio_vbus_info = { .gpio_vbus = mfp_to_gpio(MFP_PIN_GPIO96), .gpio_pullup = -1, diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c index b9e8233ac48d..d65e4bde9b91 100644 --- a/arch/arm/mach-pxa/gumstix.c +++ b/arch/arm/mach-pxa/gumstix.c @@ -106,7 +106,7 @@ static void __init gumstix_mmc_init(void) } #endif -#ifdef CONFIG_USB_PXA25X +#ifdef CONFIG_USB_GADGET_PXA25X static struct gpio_vbus_mach_info gumstix_udc_info = { .gpio_vbus = GPIO_GUMSTIX_USB_GPIOn, .gpio_pullup = GPIO_GUMSTIX_USB_GPIOx, diff --git a/arch/arm/mach-pxa/include/mach/palm27x.h b/arch/arm/mach-pxa/include/mach/palm27x.h index 8d560437e6e5..0a5e5eadebf5 100644 --- a/arch/arm/mach-pxa/include/mach/palm27x.h +++ b/arch/arm/mach-pxa/include/mach/palm27x.h @@ -37,8 +37,8 @@ extern void __init palm27x_lcd_init(int power, static inline void palm27x_lcd_init(int power, struct pxafb_mode_info *mode) {} #endif -#if defined(CONFIG_USB_PXA27X) || \ - defined(CONFIG_USB_PXA27X_MODULE) +#if defined(CONFIG_USB_GADGET_PXA27X) || \ + defined(CONFIG_USB_GADGET_PXA27X_MODULE) extern void __init palm27x_udc_init(int vbus, int pullup, int vbus_inverted); #else diff --git a/arch/arm/mach-pxa/palm27x.c b/arch/arm/mach-pxa/palm27x.c index fbc10d7b95d1..325c245c0a0d 100644 --- a/arch/arm/mach-pxa/palm27x.c +++ b/arch/arm/mach-pxa/palm27x.c @@ -164,8 +164,8 @@ void __init palm27x_lcd_init(int power, struct pxafb_mode_info *mode) /****************************************************************************** * USB Gadget ******************************************************************************/ -#if defined(CONFIG_USB_PXA27X) || \ - defined(CONFIG_USB_PXA27X_MODULE) +#if defined(CONFIG_USB_GADGET_PXA27X) || \ + defined(CONFIG_USB_GADGET_PXA27X_MODULE) static struct gpio_vbus_mach_info palm27x_udc_info = { .gpio_vbus_inverted = 1, }; diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c index 5193ce27b929..fb06bd047272 100644 --- a/arch/arm/mach-pxa/palmtc.c +++ b/arch/arm/mach-pxa/palmtc.c @@ -339,7 +339,7 @@ static inline void palmtc_mkp_init(void) {} /****************************************************************************** * UDC ******************************************************************************/ -#if defined(CONFIG_USB_PXA25X)||defined(CONFIG_USB_PXA25X_MODULE) +#if defined(CONFIG_USB_GADGET_PXA25X)||defined(CONFIG_USB_GADGET_PXA25X_MODULE) static struct gpio_vbus_mach_info palmtc_udc_info = { .gpio_vbus = GPIO_NR_PALMTC_USB_DETECT_N, .gpio_vbus_inverted = 1, diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index 10b80d473930..67bd41488bf8 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -343,7 +343,7 @@ static inline void vpac270_uhc_init(void) {} /****************************************************************************** * USB Gadget ******************************************************************************/ -#if defined(CONFIG_USB_PXA27X)||defined(CONFIG_USB_PXA27X_MODULE) +#if defined(CONFIG_USB_GADGET_PXA27X)||defined(CONFIG_USB_GADGET_PXA27X_MODULE) static struct gpio_vbus_mach_info vpac270_gpio_vbus_info = { .gpio_vbus = GPIO41_VPAC270_UDC_DETECT, .gpio_pullup = -1, diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 6ebdb0d03828..f8b9392ee347 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -6,8 +6,6 @@ config UX500_SOC_COMMON select ARM_GIC select HAS_MTU select ARM_ERRATA_753970 - select ARM_ERRATA_754322 - select ARM_ERRATA_764369 menu "Ux500 SoC" diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index 8aa104a4711a..1da23bb87c16 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -99,27 +99,7 @@ static void ux500_l2x0_inv_all(void) ux500_cache_sync(); } -static int __init ux500_l2x0_unlock(void) -{ - int i; - - /* - * Unlock Data and Instruction Lock if locked. Ux500 U-Boot versions - * apparently locks both caches before jumping to the kernel. The - * l2x0 core will not touch the unlock registers if the l2x0 is - * already enabled, so we do it right here instead. The PL310 has - * 8 sets of registers, one per possible CPU. - */ - for (i = 0; i < 8; i++) { - writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_D_BASE + - i * L2X0_LOCKDOWN_STRIDE); - writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_I_BASE + - i * L2X0_LOCKDOWN_STRIDE); - } - return 0; -} - -static int __init ux500_l2x0_init(void) +static int ux500_l2x0_init(void) { if (cpu_is_u5500()) l2x0_base = __io_address(U5500_L2CC_BASE); @@ -128,9 +108,6 @@ static int __init ux500_l2x0_init(void) else ux500_unknown_soc(); - /* Unlock before init */ - ux500_l2x0_unlock(); - /* 64KB way size, 8 way associativity, force WA */ l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff); diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 6f6c1a6fe23c..44c086710d2b 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -29,16 +29,6 @@ static void __iomem *l2x0_base; static DEFINE_SPINLOCK(l2x0_lock); static uint32_t l2x0_way_mask; /* Bitmask of active ways */ static uint32_t l2x0_size; -static u32 l2x0_cache_id; -static unsigned int l2x0_sets; -static unsigned int l2x0_ways; - -static inline bool is_pl310_rev(int rev) -{ - return (l2x0_cache_id & - (L2X0_CACHE_ID_PART_MASK | L2X0_CACHE_ID_REV_MASK)) == - (L2X0_CACHE_ID_PART_L310 | rev); -} static inline void cache_wait_way(void __iomem *reg, unsigned long mask) { @@ -130,23 +120,6 @@ static void l2x0_cache_sync(void) spin_unlock_irqrestore(&l2x0_lock, flags); } -#ifdef CONFIG_PL310_ERRATA_727915 -static void l2x0_for_each_set_way(void __iomem *reg) -{ - int set; - int way; - unsigned long flags; - - for (way = 0; way < l2x0_ways; way++) { - spin_lock_irqsave(&l2x0_lock, flags); - for (set = 0; set < l2x0_sets; set++) - writel_relaxed((way << 28) | (set << 5), reg); - cache_sync(); - spin_unlock_irqrestore(&l2x0_lock, flags); - } -} -#endif - static void __l2x0_flush_all(void) { debug_writel(0x03); @@ -160,13 +133,6 @@ static void l2x0_flush_all(void) { unsigned long flags; -#ifdef CONFIG_PL310_ERRATA_727915 - if (is_pl310_rev(REV_PL310_R2P0)) { - l2x0_for_each_set_way(l2x0_base + L2X0_CLEAN_INV_LINE_IDX); - return; - } -#endif - /* clean all ways */ spin_lock_irqsave(&l2x0_lock, flags); __l2x0_flush_all(); @@ -177,20 +143,11 @@ static void l2x0_clean_all(void) { unsigned long flags; -#ifdef CONFIG_PL310_ERRATA_727915 - if (is_pl310_rev(REV_PL310_R2P0)) { - l2x0_for_each_set_way(l2x0_base + L2X0_CLEAN_LINE_IDX); - return; - } -#endif - /* clean all ways */ spin_lock_irqsave(&l2x0_lock, flags); - debug_writel(0x03); writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_WAY); cache_wait_way(l2x0_base + L2X0_CLEAN_WAY, l2x0_way_mask); cache_sync(); - debug_writel(0x00); spin_unlock_irqrestore(&l2x0_lock, flags); } @@ -323,46 +280,47 @@ static void l2x0_disable(void) void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) { __u32 aux; + __u32 cache_id; __u32 way_size = 0; + int ways; const char *type; l2x0_base = base; - l2x0_cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID); + cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID); aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL); aux &= aux_mask; aux |= aux_val; /* Determine the number of ways */ - switch (l2x0_cache_id & L2X0_CACHE_ID_PART_MASK) { + switch (cache_id & L2X0_CACHE_ID_PART_MASK) { case L2X0_CACHE_ID_PART_L310: if (aux & (1 << 16)) - l2x0_ways = 16; + ways = 16; else - l2x0_ways = 8; + ways = 8; type = "L310"; break; case L2X0_CACHE_ID_PART_L210: - l2x0_ways = (aux >> 13) & 0xf; + ways = (aux >> 13) & 0xf; type = "L210"; break; default: /* Assume unknown chips have 8 ways */ - l2x0_ways = 8; + ways = 8; type = "L2x0 series"; break; } - l2x0_way_mask = (1 << l2x0_ways) - 1; + l2x0_way_mask = (1 << ways) - 1; /* * L2 cache Size = Way size * Number of ways */ way_size = (aux & L2X0_AUX_CTRL_WAY_SIZE_MASK) >> 17; - way_size = SZ_1K << (way_size + 3); - l2x0_size = l2x0_ways * way_size; - l2x0_sets = way_size / CACHE_LINE_SIZE; + way_size = 1 << (way_size + 3); + l2x0_size = ways * way_size * SZ_1K; /* * Check if l2x0 controller is already enabled. @@ -391,5 +349,5 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) printk(KERN_INFO "%s cache controller enabled\n", type); printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n", - l2x0_ways, l2x0_cache_id, aux, l2x0_size); + ways, cache_id, aux, l2x0_size); } diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index 6b5441d737be..73b4a8b66a57 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S @@ -272,11 +272,6 @@ v6_dma_clean_range: * - end - virtual end address of region */ ENTRY(v6_dma_flush_range) -#ifdef CONFIG_CACHE_FLUSH_RANGE_LIMIT - sub r2, r1, r0 - cmp r2, #CONFIG_CACHE_FLUSH_RANGE_LIMIT - bhi v6_dma_flush_dcache_all -#endif #ifdef CONFIG_DMA_CACHE_RWFO ldrb r2, [r0] @ read for ownership strb r2, [r0] @ write for ownership @@ -299,18 +294,6 @@ ENTRY(v6_dma_flush_range) mcr p15, 0, r0, c7, c10, 4 @ drain write buffer mov pc, lr -#ifdef CONFIG_CACHE_FLUSH_RANGE_LIMIT -v6_dma_flush_dcache_all: - mov r0, #0 -#ifdef HARVARD_CACHE - mcr p15, 0, r0, c7, c14, 0 @ D cache clean+invalidate -#else - mcr p15, 0, r0, c7, c15, 0 @ Cache clean+invalidate -#endif - mcr p15, 0, r0, c7, c10, 4 @ drain write buffer - mov pc, lr -#endif - /* * dma_map_area(start, size, dir) * - start - kernel virtual start address diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index 428b2431c207..d32f02b61866 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S @@ -54,15 +54,9 @@ loop1: and r1, r1, #7 @ mask of the bits for current cache only cmp r1, #2 @ see what cache we have at this level blt skip @ skip if no cache, or just i-cache -#ifdef CONFIG_PREEMPT - save_and_disable_irqs_notrace r9 @ make cssr&csidr read atomic -#endif mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr isb @ isb to sych the new cssr&csidr mrc p15, 1, r1, c0, c0, 0 @ read the new csidr -#ifdef CONFIG_PREEMPT - restore_irqs_notrace r9 -#endif and r2, r1, #7 @ extract the length of the cache lines add r2, r2, #4 @ add 4 (line length offset) ldr r4, =0x3ff @@ -180,10 +174,6 @@ ENTRY(v7_coherent_user_range) dcache_line_size r2, r3 sub r3, r2, #1 bic r12, r0, r3 -#ifdef CONFIG_ARM_ERRATA_764369 - ALT_SMP(W(dsb)) - ALT_UP(W(nop)) -#endif 1: USER( mcr p15, 0, r12, c7, c11, 1 ) @ clean D line to the point of unification add r12, r12, r2 @@ -211,9 +201,6 @@ ENTRY(v7_coherent_user_range) * isn't mapped, just try the next page. */ 9001: -#ifdef CONFIG_ARM_ERRATA_775420 - dsb -#endif mov r12, r12, lsr #12 mov r12, r12, lsl #12 add r12, r12, #4096 @@ -236,10 +223,6 @@ ENTRY(v7_flush_kern_dcache_area) add r1, r0, r1 sub r3, r2, #1 bic r0, r0, r3 -#ifdef CONFIG_ARM_ERRATA_764369 - ALT_SMP(W(dsb)) - ALT_UP(W(nop)) -#endif 1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line / unified line add r0, r0, r2 @@ -264,10 +247,6 @@ v7_dma_inv_range: sub r3, r2, #1 tst r0, r3 bic r0, r0, r3 -#ifdef CONFIG_ARM_ERRATA_764369 - ALT_SMP(W(dsb)) - ALT_UP(W(nop)) -#endif mcrne p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line tst r1, r3 @@ -291,10 +270,6 @@ v7_dma_clean_range: dcache_line_size r2, r3 sub r3, r2, #1 bic r0, r0, r3 -#ifdef CONFIG_ARM_ERRATA_764369 - ALT_SMP(W(dsb)) - ALT_UP(W(nop)) -#endif 1: mcr p15, 0, r0, c7, c10, 1 @ clean D / U line add r0, r0, r2 @@ -313,10 +288,6 @@ ENTRY(v7_dma_flush_range) dcache_line_size r2, r3 sub r3, r2, #1 bic r0, r0, r3 -#ifdef CONFIG_ARM_ERRATA_764369 - ALT_SMP(W(dsb)) - ALT_UP(W(nop)) -#endif 1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line add r0, r0, r2 diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 56636504f7e0..82a093cee09a 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -322,8 +322,6 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, if (addr) *handle = pfn_to_dma(dev, page_to_pfn(page)); - else - __dma_free_buffer(page, size); return addr; } @@ -467,27 +465,25 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset, size_t size, enum dma_data_direction dir, void (*op)(const void *, size_t, int)) { - unsigned long pfn; - size_t left = size; - - pfn = page_to_pfn(page) + offset / PAGE_SIZE; - offset %= PAGE_SIZE; - /* * A single sg entry may refer to multiple physically contiguous * pages. But we still need to process highmem pages individually. * If highmem is not configured then the bulk of this loop gets * optimized out. */ + size_t left = size; do { size_t len = left; void *vaddr; - page = pfn_to_page(pfn); - if (PageHighMem(page)) { - if (len + offset > PAGE_SIZE) + if (len + offset > PAGE_SIZE) { + if (offset >= PAGE_SIZE) { + page += offset / PAGE_SIZE; + offset %= PAGE_SIZE; + } len = PAGE_SIZE - offset; + } vaddr = kmap_high_get(page); if (vaddr) { vaddr += offset; @@ -504,7 +500,7 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset, op(vaddr, len, dir); } offset = 0; - pfn++; + page++; left -= len; } while (left); } diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 8799eae5da9b..bc0e1d88fd3b 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -266,9 +266,7 @@ good_area: return fault; check_stack: - /* Don't allow expansion below FIRST_USER_ADDRESS */ - if (vma->vm_flags & VM_GROWSDOWN && - addr >= FIRST_USER_ADDRESS && !expand_stack(vma, addr)) + if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr)) goto good_area; out: return fault; diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 8fda9f70320e..1a8d4aa821be 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -236,6 +236,8 @@ void __sync_icache_dcache(pte_t pteval) struct page *page; struct address_space *mapping; + if (!pte_present_user(pteval)) + return; if (cache_is_vipt_nonaliasing() && !pte_exec(pteval)) /* only flush non-aliasing VIPT caches for exec mappings */ return; diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 4a4eba5192f3..c19571c40a21 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -473,13 +473,6 @@ static void __init free_unused_memmap(struct meminfo *mi) */ bank_start = min(bank_start, ALIGN(prev_bank_end, PAGES_PER_SECTION)); -#else - /* - * Align down here since the VM subsystem insists that the - * memmap entries are valid from the bank start aligned to - * MAX_ORDER_NR_PAGES. - */ - bank_start = round_down(bank_start, MAX_ORDER_NR_PAGES); #endif /* * If we had a previous bank, and there is a space diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 19d9369bd75c..594d677b92c8 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -467,7 +467,7 @@ static void __init build_mem_type_table(void) } for (i = 0; i < 16; i++) { - pteval_t v = pgprot_val(protection_map[i]); + unsigned long v = pgprot_val(protection_map[i]); protection_map[i] = __pgprot(v | user_pgprot); } diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 21cd29834076..089c0b5e454f 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -270,6 +270,10 @@ cpu_resume_l1_flags: * Initialise TLB, Caches, and MMU state ready to switch the MMU * on. Return in r0 the new CP15 C1 control register setting. * + * We automatically detect if we have a Harvard cache, and use the + * Harvard cache control instructions insead of the unified cache + * control instructions. + * * This should be able to cover all ARMv7 cores. * * It is assumed that: @@ -344,7 +348,9 @@ __v7_setup: mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register #endif #ifdef CONFIG_ARM_ERRATA_743622 - teq r5, #0x00200000 @ only present in r2p* + teq r6, #0x20 @ present in r2p0 + teqne r6, #0x21 @ present in r2p1 + teqne r6, #0x22 @ present in r2p2 mrceq p15, 0, r10, c15, c0, 1 @ read diagnostic register orreq r10, r10, #1 << 6 @ set bit #6 mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register @@ -357,7 +363,9 @@ __v7_setup: #endif 3: mov r10, #0 +#ifdef HARVARD_CACHE mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate +#endif dsb #ifdef CONFIG_MMU mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs @@ -371,18 +379,6 @@ __v7_setup: ldr r6, =NMRR @ NMRR mcr p15, 0, r5, c10, c2, 0 @ write PRRR mcr p15, 0, r6, c10, c2, 1 @ write NMRR -#endif -#ifndef CONFIG_ARM_THUMBEE - mrc p15, 0, r0, c0, c1, 0 @ read ID_PFR0 for ThumbEE - and r0, r0, #(0xf << 12) @ ThumbEE enabled field - teq r0, #(1 << 12) @ check if ThumbEE is present - bne 1f - mov r5, #0 - mcr p14, 6, r5, c1, c0, 0 @ Initialize TEEHBR to 0 - mrc p14, 6, r0, c0, c0, 0 @ load TEECR - orr r0, r0, #1 @ set the 1st bit in order to - mcr p14, 6, r0, c0, c0, 0 @ stop userspace TEEHBR access -1: #endif adr r5, v7_crval ldmia r5, {r5, r6} diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S index d7d0f7f7b085..53cd5b454673 100644 --- a/arch/arm/mm/tlb-v7.S +++ b/arch/arm/mm/tlb-v7.S @@ -39,18 +39,10 @@ ENTRY(v7wbi_flush_user_tlb_range) mov r0, r0, lsr #PAGE_SHIFT @ align address mov r1, r1, lsr #PAGE_SHIFT asid r3, r3 @ mask ASID -#ifdef CONFIG_ARM_ERRATA_720789 - ALT_SMP(W(mov) r3, #0 ) - ALT_UP(W(nop) ) -#endif orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA mov r1, r1, lsl #PAGE_SHIFT 1: -#ifdef CONFIG_ARM_ERRATA_720789 - ALT_SMP(mcr p15, 0, r0, c8, c3, 3) @ TLB invalidate U MVA all ASID (shareable) -#else ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable) -#endif ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA add r0, r0, #PAGE_SZ @@ -78,11 +70,7 @@ ENTRY(v7wbi_flush_kern_tlb_range) mov r0, r0, lsl #PAGE_SHIFT mov r1, r1, lsl #PAGE_SHIFT 1: -#ifdef CONFIG_ARM_ERRATA_720789 - ALT_SMP(mcr p15, 0, r0, c8, c3, 3) @ TLB invalidate U MVA all ASID (shareable) -#else ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable) -#endif ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA add r0, r0, #PAGE_SZ cmp r0, r1 diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index 4e0a371630b3..c074e66ad224 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c @@ -116,7 +116,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) return oprofile_perf_init(ops); } -void oprofile_arch_exit(void) +void __exit oprofile_arch_exit(void) { oprofile_perf_exit(); } diff --git a/arch/arm/plat-mxc/include/mach/iomux-v3.h b/arch/arm/plat-mxc/include/mach/iomux-v3.h index 45099566fecc..82620af1922f 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-v3.h +++ b/arch/arm/plat-mxc/include/mach/iomux-v3.h @@ -66,6 +66,7 @@ typedef u64 iomux_v3_cfg_t; #define MUX_MODE_MASK ((iomux_v3_cfg_t)0x1f << MUX_MODE_SHIFT) #define MUX_PAD_CTRL_SHIFT 41 #define MUX_PAD_CTRL_MASK ((iomux_v3_cfg_t)0x1ffff << MUX_PAD_CTRL_SHIFT) +#define NO_PAD_CTRL ((iomux_v3_cfg_t)1 << (MUX_PAD_CTRL_SHIFT + 16)) #define MUX_SEL_INPUT_SHIFT 58 #define MUX_SEL_INPUT_MASK ((iomux_v3_cfg_t)0xf << MUX_SEL_INPUT_SHIFT) @@ -84,16 +85,15 @@ typedef u64 iomux_v3_cfg_t; * Use to set PAD control */ -#define NO_PAD_CTRL (1 << 16) #define PAD_CTL_DVS (1 << 13) #define PAD_CTL_HYS (1 << 8) #define PAD_CTL_PKE (1 << 7) -#define PAD_CTL_PUE (1 << 6 | PAD_CTL_PKE) -#define PAD_CTL_PUS_100K_DOWN (0 << 4 | PAD_CTL_PUE) -#define PAD_CTL_PUS_47K_UP (1 << 4 | PAD_CTL_PUE) -#define PAD_CTL_PUS_100K_UP (2 << 4 | PAD_CTL_PUE) -#define PAD_CTL_PUS_22K_UP (3 << 4 | PAD_CTL_PUE) +#define PAD_CTL_PUE (1 << 6) +#define PAD_CTL_PUS_100K_DOWN (0 << 4) +#define PAD_CTL_PUS_47K_UP (1 << 4) +#define PAD_CTL_PUS_100K_UP (2 << 4) +#define PAD_CTL_PUS_22K_UP (3 << 4) #define PAD_CTL_ODE (1 << 3) diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c index f4b68beddbb3..7a61ef8f471a 100644 --- a/arch/arm/plat-mxc/pwm.c +++ b/arch/arm/plat-mxc/pwm.c @@ -32,9 +32,6 @@ #define MX3_PWMSAR 0x0C /* PWM Sample Register */ #define MX3_PWMPR 0x10 /* PWM Period Register */ #define MX3_PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4) -#define MX3_PWMCR_DOZEEN (1 << 24) -#define MX3_PWMCR_WAITEN (1 << 23) -#define MX3_PWMCR_DBGEN (1 << 22) #define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16) #define MX3_PWMCR_CLKSRC_IPG (1 << 16) #define MX3_PWMCR_EN (1 << 0) @@ -77,21 +74,10 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) do_div(c, period_ns); duty_cycles = c; - /* - * according to imx pwm RM, the real period value should be - * PERIOD value in PWMPR plus 2. - */ - if (period_cycles > 2) - period_cycles -= 2; - else - period_cycles = 0; - writel(duty_cycles, pwm->mmio_base + MX3_PWMSAR); writel(period_cycles, pwm->mmio_base + MX3_PWMPR); - cr = MX3_PWMCR_PRESCALER(prescale) | - MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN | - MX3_PWMCR_DBGEN | MX3_PWMCR_EN; + cr = MX3_PWMCR_PRESCALER(prescale) | MX3_PWMCR_EN; if (cpu_is_mx25()) cr |= MX3_PWMCR_CLKSRC_IPG; diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index 11dce87c2487..9e5451b3c8e3 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c @@ -806,7 +806,10 @@ void __init orion_xor1_init(unsigned long mapbase_low, /***************************************************************************** * EHCI ****************************************************************************/ -static struct orion_ehci_data orion_ehci_data; +static struct orion_ehci_data orion_ehci_data = { + .phy_version = EHCI_PHY_NA, +}; + static u64 ehci_dmamask = DMA_BIT_MASK(32); @@ -827,11 +830,9 @@ static struct platform_device orion_ehci = { void __init orion_ehci_init(struct mbus_dram_target_info *mbus_dram_info, unsigned long mapbase, - unsigned long irq, - enum orion_ehci_phy_ver phy_version) + unsigned long irq) { orion_ehci_data.dram = mbus_dram_info; - orion_ehci_data.phy_version = phy_version; fill_resources(&orion_ehci, orion_ehci_resources, mapbase, SZ_4K - 1, irq); diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h index a2c0e31ce0dc..a63c357e2ab1 100644 --- a/arch/arm/plat-orion/include/plat/common.h +++ b/arch/arm/plat-orion/include/plat/common.h @@ -95,8 +95,7 @@ void __init orion_xor1_init(unsigned long mapbase_low, void __init orion_ehci_init(struct mbus_dram_target_info *mbus_dram_info, unsigned long mapbase, - unsigned long irq, - enum orion_ehci_phy_ver phy_version); + unsigned long irq); void __init orion_ehci_1_init(struct mbus_dram_target_info *mbus_dram_info, unsigned long mapbase, diff --git a/arch/arm/plat-orion/mpp.c b/arch/arm/plat-orion/mpp.c index 3b1e17bd3d17..91553432711d 100644 --- a/arch/arm/plat-orion/mpp.c +++ b/arch/arm/plat-orion/mpp.c @@ -64,7 +64,8 @@ void __init orion_mpp_conf(unsigned int *mpp_list, unsigned int variant_mask, gpio_mode |= GPIO_INPUT_OK; if (*mpp_list & MPP_OUTPUT_MASK) gpio_mode |= GPIO_OUTPUT_OK; - + if (sel != 0) + gpio_mode = 0; orion_gpio_set_valid(num, gpio_mode); } diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 9f422ba5b1d2..539bd0e3defd 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -431,7 +431,7 @@ s3c2410_dma_canload(struct s3c2410_dma_chan *chan) * when necessary. */ -int s3c2410_dma_enqueue(enum dma_ch channel, void *id, +int s3c2410_dma_enqueue(unsigned int channel, void *id, dma_addr_t data, int size) { struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); @@ -1249,7 +1249,7 @@ static void s3c2410_dma_resume(void) struct s3c2410_dma_chan *cp = s3c2410_chans + dma_channels - 1; int channel; - for (channel = dma_channels - 1; channel >= 0; cp--, channel--) + for (channel = dma_channels - 1; channel >= 0; cp++, channel--) s3c2410_dma_resume_chan(cp); } diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c index df14954aa1cc..e8f2be2d67f2 100644 --- a/arch/arm/plat-samsung/adc.c +++ b/arch/arm/plat-samsung/adc.c @@ -143,12 +143,10 @@ int s3c_adc_start(struct s3c_adc_client *client, return -EINVAL; } - spin_lock_irqsave(&adc->lock, flags); - - if (client->is_ts && adc->ts_pend) { - spin_unlock_irqrestore(&adc->lock, flags); + if (client->is_ts && adc->ts_pend) return -EAGAIN; - } + + spin_lock_irqsave(&adc->lock, flags); client->channel = channel; client->nr_samples = nr_samples; diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S index c1a978402583..4fa9903b83cf 100644 --- a/arch/arm/vfp/entry.S +++ b/arch/arm/vfp/entry.S @@ -10,7 +10,7 @@ * * Basic entry code, called from the kernel's undefined instruction trap. * r0 = faulted instruction - * r2 = faulted PC+4 + * r5 = faulted PC+4 * r9 = successful return * r10 = thread_info structure * lr = failure return @@ -26,7 +26,6 @@ ENTRY(do_vfp) str r11, [r10, #TI_PREEMPT] #endif enable_irq - str r2, [sp, #S_PC] @ update regs->ARM_pc for Thumb 2 case ldr r4, .LCvfp ldr r11, [r10, #TI_CPU] @ CPU number add r10, r10, #TI_VFPSTATE @ r10 = workspace diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index 404538ae591d..9897dcfc16d6 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S @@ -77,12 +77,15 @@ ENTRY(vfp_support_entry) bne look_for_VFP_exceptions @ VFP is already enabled DBGSTR1 "enable %x", r10 - ldr r3, vfp_current_hw_state_address + ldr r3, last_VFP_context_address orr r1, r1, #FPEXC_EN @ user FPEXC has the enable bit set - ldr r4, [r3, r11, lsl #2] @ vfp_current_hw_state pointer + ldr r4, [r3, r11, lsl #2] @ last_VFP_context pointer bic r5, r1, #FPEXC_EX @ make sure exceptions are disabled - cmp r4, r10 @ this thread owns the hw context? - beq vfp_hw_state_valid + cmp r4, r10 + beq check_for_exception @ we are returning to the same + @ process, so the registers are + @ still there. In this case, we do + @ not want to drop a pending exception. VFPFMXR FPEXC, r5 @ enable VFP, disable any pending @ exceptions, so we can get at the @@ -113,7 +116,7 @@ ENTRY(vfp_support_entry) no_old_VFP_process: DBGSTR1 "load state %p", r10 - str r10, [r3, r11, lsl #2] @ update the vfp_current_hw_state pointer + str r10, [r3, r11, lsl #2] @ update the last_VFP_context pointer @ Load the saved state back into the VFP VFPFLDMIA r10, r5 @ reload the working registers while @ FPEXC is in a safe state @@ -129,8 +132,7 @@ no_old_VFP_process: #endif VFPFMXR FPSCR, r5 @ restore status -@ The context stored in the VFP hardware is up to date with this thread -vfp_hw_state_valid: +check_for_exception: tst r1, #FPEXC_EX bne process_exception @ might as well handle the pending @ exception before retrying branch @@ -205,8 +207,8 @@ ENTRY(vfp_save_state) ENDPROC(vfp_save_state) .align -vfp_current_hw_state_address: - .word vfp_current_hw_state +last_VFP_context_address: + .word last_VFP_context .macro tbl_branch, base, tmp, shift #ifdef CONFIG_THUMB2_KERNEL diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 192e9dd4c39b..f25e7ec89416 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -33,13 +33,7 @@ void vfp_support_entry(void); void vfp_null_entry(void); void (*vfp_vector)(void) = vfp_null_entry; - -/* - * The pointer to the vfpstate structure of the thread which currently - * owns the context held in the VFP hardware, or NULL if the hardware - * context is invalid. - */ -union vfp_state *vfp_current_hw_state[NR_CPUS]; +union vfp_state *last_VFP_context[NR_CPUS]; /* * Dual-use variable. @@ -63,12 +57,12 @@ static void vfp_thread_flush(struct thread_info *thread) /* * Disable VFP to ensure we initialize it first. We must ensure - * that the modification of vfp_current_hw_state[] and hardware disable + * that the modification of last_VFP_context[] and hardware disable * are done for the same CPU and without preemption. */ cpu = get_cpu(); - if (vfp_current_hw_state[cpu] == vfp) - vfp_current_hw_state[cpu] = NULL; + if (last_VFP_context[cpu] == vfp) + last_VFP_context[cpu] = NULL; fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); put_cpu(); } @@ -79,8 +73,8 @@ static void vfp_thread_exit(struct thread_info *thread) union vfp_state *vfp = &thread->vfpstate; unsigned int cpu = get_cpu(); - if (vfp_current_hw_state[cpu] == vfp) - vfp_current_hw_state[cpu] = NULL; + if (last_VFP_context[cpu] == vfp) + last_VFP_context[cpu] = NULL; put_cpu(); } @@ -135,9 +129,9 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) * case the thread migrates to a different CPU. The * restoring is done lazily. */ - if ((fpexc & FPEXC_EN) && vfp_current_hw_state[cpu]) { - vfp_save_state(vfp_current_hw_state[cpu], fpexc); - vfp_current_hw_state[cpu]->hard.cpu = cpu; + if ((fpexc & FPEXC_EN) && last_VFP_context[cpu]) { + vfp_save_state(last_VFP_context[cpu], fpexc); + last_VFP_context[cpu]->hard.cpu = cpu; } /* * Thread migration, just force the reloading of the @@ -145,7 +139,7 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) * contain stale data. */ if (thread->vfpstate.hard.cpu != cpu) - vfp_current_hw_state[cpu] = NULL; + last_VFP_context[cpu] = NULL; #endif /* @@ -418,16 +412,10 @@ static int vfp_pm_suspend(void) /* disable, just in case */ fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); - } else if (vfp_current_hw_state[ti->cpu]) { -#ifndef CONFIG_SMP - fmxr(FPEXC, fpexc | FPEXC_EN); - vfp_save_state(vfp_current_hw_state[ti->cpu], fpexc); - fmxr(FPEXC, fpexc); -#endif } /* clear any information we had about last context state */ - vfp_current_hw_state[ti->cpu] = NULL; + memset(last_VFP_context, 0, sizeof(last_VFP_context)); return 0; } @@ -463,7 +451,7 @@ void vfp_sync_hwstate(struct thread_info *thread) * If the thread we're interested in is the current owner of the * hardware VFP state, then we need to save its state. */ - if (vfp_current_hw_state[cpu] == &thread->vfpstate) { + if (last_VFP_context[cpu] == &thread->vfpstate) { u32 fpexc = fmrx(FPEXC); /* @@ -485,7 +473,7 @@ void vfp_flush_hwstate(struct thread_info *thread) * If the thread we're interested in is the current owner of the * hardware VFP state, then we need to save its state. */ - if (vfp_current_hw_state[cpu] == &thread->vfpstate) { + if (last_VFP_context[cpu] == &thread->vfpstate) { u32 fpexc = fmrx(FPEXC); fmxr(FPEXC, fpexc & ~FPEXC_EN); @@ -494,7 +482,7 @@ void vfp_flush_hwstate(struct thread_info *thread) * Set the context to NULL to force a reload the next time * the thread uses the VFP. */ - vfp_current_hw_state[cpu] = NULL; + last_VFP_context[cpu] = NULL; } #ifdef CONFIG_SMP @@ -526,7 +514,7 @@ static int vfp_hotplug(struct notifier_block *b, unsigned long action, { if (action == CPU_DYING || action == CPU_DYING_FROZEN) { unsigned int cpu = (long)hcpu; - vfp_current_hw_state[cpu] = NULL; + last_VFP_context[cpu] = NULL; } else if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) vfp_enable(NULL); return NOTIFY_OK; @@ -587,14 +575,11 @@ static int __init vfp_init(void) elf_hwcap |= HWCAP_VFPv3; /* - * Check for VFPv3 D16 and VFPv4 D16. CPUs in - * this configuration only have 16 x 64bit - * registers. + * Check for VFPv3 D16. CPUs in this configuration + * only have 16 x 64bit registers. */ if (((fmrx(MVFR0) & MVFR0_A_SIMD_MASK)) == 1) - elf_hwcap |= HWCAP_VFPv3D16; /* also v4-D16 */ - else - elf_hwcap |= HWCAP_VFPD32; + elf_hwcap |= HWCAP_VFPv3D16; } #endif #ifdef CONFIG_NEON diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig index c614484f0fca..e9d689b7c833 100644 --- a/arch/avr32/Kconfig +++ b/arch/avr32/Kconfig @@ -8,7 +8,6 @@ config AVR32 select HAVE_KPROBES select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_PROBE - select GENERIC_ATOMIC64 select HARDIRQS_SW_RESEND select GENERIC_IRQ_SHOW help diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c index 466af40c5822..850265373611 100644 --- a/arch/cris/arch-v10/drivers/sync_serial.c +++ b/arch/cris/arch-v10/drivers/sync_serial.c @@ -158,7 +158,7 @@ static int sync_serial_open(struct inode *inode, struct file *file); static int sync_serial_release(struct inode *inode, struct file *file); static unsigned int sync_serial_poll(struct file *filp, poll_table *wait); -static long sync_serial_ioctl(struct file *file, +static int sync_serial_ioctl(struct file *file, unsigned int cmd, unsigned long arg); static ssize_t sync_serial_write(struct file *file, const char *buf, size_t count, loff_t *ppos); @@ -625,11 +625,11 @@ static int sync_serial_open(struct inode *inode, struct file *file) *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; DEBUG(printk(KERN_DEBUG "sser%d rec started\n", dev)); } - err = 0; + ret = 0; out: mutex_unlock(&sync_serial_mutex); - return err; + return ret; } static int sync_serial_release(struct inode *inode, struct file *file) diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c index ba0e5965d6e3..907cfb5a873d 100644 --- a/arch/cris/arch-v10/kernel/irq.c +++ b/arch/cris/arch-v10/kernel/irq.c @@ -20,9 +20,6 @@ #define crisv10_mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr)); #define crisv10_unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr)); -extern void kgdb_init(void); -extern void breakpoint(void); - /* don't use set_int_vector, it bypasses the linux interrupt handlers. it is * global just so that the kernel gdb can use it. */ diff --git a/arch/cris/include/asm/io.h b/arch/cris/include/asm/io.h index ac12ae2b9286..32567bc2a421 100644 --- a/arch/cris/include/asm/io.h +++ b/arch/cris/include/asm/io.h @@ -133,39 +133,12 @@ static inline void writel(unsigned int b, volatile void __iomem *addr) #define insb(port,addr,count) (cris_iops ? cris_iops->read_io(port,addr,1,count) : 0) #define insw(port,addr,count) (cris_iops ? cris_iops->read_io(port,addr,2,count) : 0) #define insl(port,addr,count) (cris_iops ? cris_iops->read_io(port,addr,4,count) : 0) -static inline void outb(unsigned char data, unsigned int port) -{ - if (cris_iops) - cris_iops->write_io(port, (void *) &data, 1, 1); -} -static inline void outw(unsigned short data, unsigned int port) -{ - if (cris_iops) - cris_iops->write_io(port, (void *) &data, 2, 1); -} -static inline void outl(unsigned int data, unsigned int port) -{ - if (cris_iops) - cris_iops->write_io(port, (void *) &data, 4, 1); -} -static inline void outsb(unsigned int port, const void *addr, - unsigned long count) -{ - if (cris_iops) - cris_iops->write_io(port, (void *)addr, 1, count); -} -static inline void outsw(unsigned int port, const void *addr, - unsigned long count) -{ - if (cris_iops) - cris_iops->write_io(port, (void *)addr, 2, count); -} -static inline void outsl(unsigned int port, const void *addr, - unsigned long count) -{ - if (cris_iops) - cris_iops->write_io(port, (void *)addr, 4, count); -} +#define outb(data,port) if (cris_iops) cris_iops->write_io(port,(void*)(unsigned)data,1,1) +#define outw(data,port) if (cris_iops) cris_iops->write_io(port,(void*)(unsigned)data,2,1) +#define outl(data,port) if (cris_iops) cris_iops->write_io(port,(void*)(unsigned)data,4,1) +#define outsb(port,addr,count) if(cris_iops) cris_iops->write_io(port,(void*)addr,1,count) +#define outsw(port,addr,count) if(cris_iops) cris_iops->write_io(port,(void*)addr,2,count) +#define outsl(port,addr,count) if(cris_iops) cris_iops->write_io(port,(void*)addr,3,count) /* * Convert a physical pointer to a virtual kernel pointer for /dev/mem diff --git a/arch/cris/include/asm/thread_info.h b/arch/cris/include/asm/thread_info.h index 332f19c54557..29b74a105830 100644 --- a/arch/cris/include/asm/thread_info.h +++ b/arch/cris/include/asm/thread_info.h @@ -11,6 +11,8 @@ #ifdef __KERNEL__ +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + #ifndef __ASSEMBLY__ #include #include @@ -65,10 +67,8 @@ struct thread_info { #define init_thread_info (init_thread_union.thread_info) -#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR /* thread information allocation */ -#define alloc_thread_info_node(tsk, node) \ - ((struct thread_info *) __get_free_pages(GFP_KERNEL, 1)) +#define alloc_thread_info(tsk, node) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) #define free_thread_info(ti) free_pages((unsigned long) (ti), 1) #endif /* !__ASSEMBLY__ */ diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h index 6fcc9a081e4c..446881439675 100644 --- a/arch/ia64/include/asm/atomic.h +++ b/arch/ia64/include/asm/atomic.h @@ -18,8 +18,8 @@ #include -#define ATOMIC_INIT(i) { (i) } -#define ATOMIC64_INIT(i) { (i) } +#define ATOMIC_INIT(i) ((atomic_t) { (i) }) +#define ATOMIC64_INIT(i) ((atomic64_t) { (i) }) #define atomic_read(v) (*(volatile int *)&(v)->counter) #define atomic64_read(v) (*(volatile long *)&(v)->counter) diff --git a/arch/ia64/include/asm/futex.h b/arch/ia64/include/asm/futex.h index 21ab376465d5..8428525ddb22 100644 --- a/arch/ia64/include/asm/futex.h +++ b/arch/ia64/include/asm/futex.h @@ -107,16 +107,15 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, return -EFAULT; { - register unsigned long r8 __asm ("r8"); + register unsigned long r8 __asm ("r8") = 0; unsigned long prev; __asm__ __volatile__( " mf;; \n" - " mov %0=r0 \n" - " mov ar.ccv=%4;; \n" - "[1:] cmpxchg4.acq %1=[%2],%3,ar.ccv \n" + " mov ar.ccv=%3;; \n" + "[1:] cmpxchg4.acq %0=[%1],%2,ar.ccv \n" " .xdata4 \"__ex_table\", 1b-., 2f-. \n" "[2:]" - : "=r" (r8), "=r" (prev) + : "=r" (prev) : "r" (uaddr), "r" (newval), "rO" ((long) (unsigned) oldval) : "memory"); diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h index d8de1825b736..7c928da35b17 100644 --- a/arch/ia64/include/asm/unistd.h +++ b/arch/ia64/include/asm/unistd.h @@ -321,12 +321,11 @@ #define __NR_syncfs 1329 #define __NR_setns 1330 #define __NR_sendmmsg 1331 -#define __NR_accept4 1334 #ifdef __KERNEL__ -#define NR_syscalls 311 /* length of syscall table */ +#define NR_syscalls 308 /* length of syscall table */ /* * The following defines stop scripts/checksyscalls.sh from complaining about diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index f19de9f7f5f5..3be485a300b1 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -429,24 +429,22 @@ static u32 __devinitdata pxm_flag[PXM_FLAG_LEN]; static struct acpi_table_slit __initdata *slit_table; cpumask_t early_cpu_possible_map = CPU_MASK_NONE; -static int __init -get_processor_proximity_domain(struct acpi_srat_cpu_affinity *pa) +static int get_processor_proximity_domain(struct acpi_srat_cpu_affinity *pa) { int pxm; pxm = pa->proximity_domain_lo; - if (ia64_platform_is("sn2") || acpi_srat_revision >= 2) + if (ia64_platform_is("sn2")) pxm += pa->proximity_domain_hi[0] << 8; return pxm; } -static int __init -get_memory_proximity_domain(struct acpi_srat_mem_affinity *ma) +static int get_memory_proximity_domain(struct acpi_srat_mem_affinity *ma) { int pxm; pxm = ma->proximity_domain; - if (!ia64_platform_is("sn2") && acpi_srat_revision <= 1) + if (!ia64_platform_is("sn2")) pxm &= 0xff; return pxm; diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index df477f8c9d82..97dd2abdeb1a 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -1777,9 +1777,6 @@ sys_call_table: data8 sys_syncfs data8 sys_setns // 1330 data8 sys_sendmmsg - data8 sys_ni_syscall /* process_vm_readv */ - data8 sys_ni_syscall /* process_vm_writev */ - data8 sys_accept4 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */ diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 3540c5e80426..782c3a357f24 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -23,6 +23,7 @@ #include #include #include +#include /* for rand_initialize_irq() */ #include #include #include diff --git a/arch/m68k/include/asm/entry_mm.h b/arch/m68k/include/asm/entry_mm.h index bdace4bb29d8..73b8c8fbed9c 100644 --- a/arch/m68k/include/asm/entry_mm.h +++ b/arch/m68k/include/asm/entry_mm.h @@ -35,8 +35,8 @@ /* the following macro is used when enabling interrupts */ #if defined(MACH_ATARI_ONLY) - /* block out HSYNC = ipl 2 on the atari */ -#define ALLOWINT (~0x500) + /* block out HSYNC on the atari */ +#define ALLOWINT (~0x400) #define MAX_NOINT_IPL 3 #else /* portable version */ diff --git a/arch/m68k/include/asm/signal.h b/arch/m68k/include/asm/signal.h index 0b6b0e50f977..5bc09c787a11 100644 --- a/arch/m68k/include/asm/signal.h +++ b/arch/m68k/include/asm/signal.h @@ -156,7 +156,7 @@ typedef struct sigaltstack { static inline void sigaddset(sigset_t *set, int _sig) { asm ("bfset %0{%1,#1}" - : "+o" (*set) + : "+od" (*set) : "id" ((_sig - 1) ^ 31) : "cc"); } @@ -164,7 +164,7 @@ static inline void sigaddset(sigset_t *set, int _sig) static inline void sigdelset(sigset_t *set, int _sig) { asm ("bfclr %0{%1,#1}" - : "+o" (*set) + : "+od" (*set) : "id" ((_sig - 1) ^ 31) : "cc"); } @@ -180,7 +180,7 @@ static inline int __gen_sigismember(sigset_t *set, int _sig) int ret; asm ("bfextu %1{%2,#1},%0" : "=d" (ret) - : "o" (*set), "id" ((_sig-1) ^ 31) + : "od" (*set), "id" ((_sig-1) ^ 31) : "cc"); return ret; } diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index 9a5932ec3689..8623f8dc16f8 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c @@ -479,13 +479,9 @@ sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5, goto bad_access; } - /* - * No need to check for EFAULT; we know that the page is - * present and writable. - */ - __get_user(mem_value, mem); + mem_value = *mem; if (mem_value == oldval) - __put_user(newval, mem); + *mem = newval; pte_unmap_unlock(pte, ptl); up_read(&mm->mmap_sem); diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c index 1918d76aa06b..c247de02bc7e 100644 --- a/arch/m68k/mac/config.c +++ b/arch/m68k/mac/config.c @@ -950,9 +950,6 @@ int __init mac_platform_init(void) { u8 *swim_base; - if (!MACH_IS_MAC) - return -ENODEV; - /* * Serial devices */ diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 9aa60f640128..884819cd0607 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -236,7 +236,7 @@ KBUILD_CPPFLAGS += -D"DATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)" LDFLAGS += -m $(ld-emul) ifdef CONFIG_MIPS -CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ +CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -xc /dev/null | \ egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \ sed -e 's/^\#define /-D/' -e "s/ /='/" -e "s/$$/'/") ifdef CONFIG_64BIT diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index adda036bba17..97f8bf6639e7 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h @@ -60,8 +60,6 @@ struct thread_info { register struct thread_info *__current_thread_info __asm__("$28"); #define current_thread_info() __current_thread_info -#endif /* !__ASSEMBLY__ */ - /* thread information allocation */ #if defined(CONFIG_PAGE_SIZE_4KB) && defined(CONFIG_32BIT) #define THREAD_SIZE_ORDER (1) @@ -99,6 +97,8 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define free_thread_info(info) kfree(info) +#endif /* !__ASSEMBLY__ */ + #define PREEMPT_ACTIVE 0x10000000 /* diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c index 4397972949fa..73031f7fc827 100644 --- a/arch/mips/jz4740/gpio.c +++ b/arch/mips/jz4740/gpio.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include #include @@ -86,6 +86,7 @@ struct jz_gpio_chip { spinlock_t lock; struct gpio_chip gpio_chip; + struct sys_device sysdev; }; static struct jz_gpio_chip jz4740_gpio_chips[]; @@ -458,47 +459,49 @@ static struct jz_gpio_chip jz4740_gpio_chips[] = { JZ4740_GPIO_CHIP(D), }; -static void jz4740_gpio_suspend_chip(struct jz_gpio_chip *chip) +static inline struct jz_gpio_chip *sysdev_to_chip(struct sys_device *dev) { - chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK); - writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET); - writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR); + return container_of(dev, struct jz_gpio_chip, sysdev); } -static int jz4740_gpio_suspend(void) +static int jz4740_gpio_suspend(struct sys_device *dev, pm_message_t state) { - int i; + struct jz_gpio_chip *chip = sysdev_to_chip(dev); - for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); i++) - jz4740_gpio_suspend_chip(&jz4740_gpio_chips[i]); + chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK); + writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET); + writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR); return 0; } -static void jz4740_gpio_resume_chip(struct jz_gpio_chip *chip) +static int jz4740_gpio_resume(struct sys_device *dev) { + struct jz_gpio_chip *chip = sysdev_to_chip(dev); uint32_t mask = chip->suspend_mask; writel(~mask, chip->base + JZ_REG_GPIO_MASK_CLEAR); writel(mask, chip->base + JZ_REG_GPIO_MASK_SET); -} -static void jz4740_gpio_resume(void) -{ - int i; - - for (i = ARRAY_SIZE(jz4740_gpio_chips) - 1; i >= 0 ; i--) - jz4740_gpio_resume_chip(&jz4740_gpio_chips[i]); + return 0; } -static struct syscore_ops jz4740_gpio_syscore_ops = { +static struct sysdev_class jz4740_gpio_sysdev_class = { + .name = "gpio", .suspend = jz4740_gpio_suspend, .resume = jz4740_gpio_resume, }; -static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) +static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) { - int irq; + int ret, irq; + + chip->sysdev.id = id; + chip->sysdev.cls = &jz4740_gpio_sysdev_class; + ret = sysdev_register(&chip->sysdev); + + if (ret) + return ret; spin_lock_init(&chip->lock); @@ -516,17 +519,22 @@ static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) irq_set_chip_and_handler(irq, &jz_gpio_irq_chip, handle_level_irq); } + + return 0; } static int __init jz4740_gpio_init(void) { unsigned int i; + int ret; + + ret = sysdev_class_register(&jz4740_gpio_sysdev_class); + if (ret) + return ret; for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i) jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i); - register_syscore_ops(&jz4740_gpio_syscore_ops); - printk(KERN_INFO "JZ4740 GPIO initialized\n"); return 0; diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 8b3c62c66eba..83bba332bbfc 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -100,7 +100,7 @@ obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o obj-$(CONFIG_OF) += prom.o -CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -x c /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi) +CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi) obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT) += 8250-platform.o diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c index 23817a6e32b6..f4546e97c60d 100644 --- a/arch/mips/kernel/kgdb.c +++ b/arch/mips/kernel/kgdb.c @@ -283,15 +283,6 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd, struct pt_regs *regs = args->regs; int trap = (regs->cp0_cause & 0x7c) >> 2; -#ifdef CONFIG_KPROBES - /* - * Return immediately if the kprobes fault notifier has set - * DIE_PAGE_FAULT. - */ - if (cmd == DIE_PAGE_FAULT) - return NOTIFY_DONE; -#endif /* CONFIG_KPROBES */ - /* Userspace events, ignore. */ if (user_mode(regs)) return NOTIFY_DONE; diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index be281c69f6ca..a81176f44c74 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -1,6 +1,5 @@ #include #include -#include #include #undef mips @@ -74,7 +73,7 @@ SECTIONS .data : { /* Data */ . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ - INIT_TASK_DATA(THREAD_SIZE) + INIT_TASK_DATA(PAGE_SIZE) NOSAVE_DATA CACHELINE_ALIGNED_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) READ_MOSTLY_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) diff --git a/arch/mn10300/Makefile b/arch/mn10300/Makefile index 3eb4a52ff9a7..7120282bf0d8 100644 --- a/arch/mn10300/Makefile +++ b/arch/mn10300/Makefile @@ -26,7 +26,7 @@ CHECKFLAGS += PROCESSOR := unset UNIT := unset -KBUILD_CFLAGS += -mam33 -DCPU=AM33 $(call cc-option,-mmem-funcs,) +KBUILD_CFLAGS += -mam33 -mmem-funcs -DCPU=AM33 KBUILD_AFLAGS += -mam33 -DCPU=AM33 ifeq ($(CONFIG_MN10300_CURRENT_IN_E2),y) diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h index 3706cf04100c..f81955934aeb 100644 --- a/arch/parisc/include/asm/atomic.h +++ b/arch/parisc/include/asm/atomic.h @@ -248,7 +248,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) #define atomic_sub_and_test(i,v) (atomic_sub_return((i),(v)) == 0) -#define ATOMIC_INIT(i) { (i) } +#define ATOMIC_INIT(i) ((atomic_t) { (i) }) #define smp_mb__before_atomic_dec() smp_mb() #define smp_mb__after_atomic_dec() smp_mb() @@ -257,12 +257,12 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) #ifdef CONFIG_64BIT -#define ATOMIC64_INIT(i) { (i) } +#define ATOMIC64_INIT(i) ((atomic64_t) { (i) }) -static __inline__ s64 +static __inline__ int __atomic64_add_return(s64 i, atomic64_t *v) { - s64 ret; + int ret; unsigned long flags; _atomic_spin_lock_irqsave(v, flags); diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h index 2388bdb32832..67a33cc27ef2 100644 --- a/arch/parisc/include/asm/futex.h +++ b/arch/parisc/include/asm/futex.h @@ -5,14 +5,11 @@ #include #include -#include #include static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) { - unsigned long int flags; - u32 val; int op = (encoded_op >> 28) & 7; int cmp = (encoded_op >> 24) & 15; int oparg = (encoded_op << 8) >> 20; @@ -21,58 +18,21 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) oparg = 1 << oparg; - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr))) + if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) return -EFAULT; pagefault_disable(); - _atomic_spin_lock_irqsave(uaddr, flags); - switch (op) { case FUTEX_OP_SET: - /* *(int *)UADDR2 = OPARG; */ - ret = get_user(oldval, uaddr); - if (!ret) - ret = put_user(oparg, uaddr); - break; case FUTEX_OP_ADD: - /* *(int *)UADDR2 += OPARG; */ - ret = get_user(oldval, uaddr); - if (!ret) { - val = oldval + oparg; - ret = put_user(val, uaddr); - } - break; case FUTEX_OP_OR: - /* *(int *)UADDR2 |= OPARG; */ - ret = get_user(oldval, uaddr); - if (!ret) { - val = oldval | oparg; - ret = put_user(val, uaddr); - } - break; case FUTEX_OP_ANDN: - /* *(int *)UADDR2 &= ~OPARG; */ - ret = get_user(oldval, uaddr); - if (!ret) { - val = oldval & ~oparg; - ret = put_user(val, uaddr); - } - break; case FUTEX_OP_XOR: - /* *(int *)UADDR2 ^= OPARG; */ - ret = get_user(oldval, uaddr); - if (!ret) { - val = oldval ^ oparg; - ret = put_user(val, uaddr); - } - break; default: ret = -ENOSYS; } - _atomic_spin_unlock_irqrestore(uaddr, flags); - pagefault_enable(); if (!ret) { @@ -94,9 +54,7 @@ static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, u32 newval) { - int ret; u32 val; - unsigned long flags; /* futex.c wants to do a cmpxchg_inatomic on kernel NULL, which is * our gateway page, and causes no end of trouble... @@ -107,24 +65,12 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) return -EFAULT; - /* HPPA has no cmpxchg in hardware and therefore the - * best we can do here is use an array of locks. The - * lock selected is based on a hash of the userspace - * address. This should scale to a couple of CPUs. - */ - - _atomic_spin_lock_irqsave(uaddr, flags); - - ret = get_user(val, uaddr); - - if (!ret && val == oldval) - ret = put_user(newval, uaddr); - + if (get_user(val, uaddr)) + return -EFAULT; + if (val == oldval && put_user(newval, uaddr)) + return -EFAULT; *uval = val; - - _atomic_spin_unlock_irqrestore(uaddr, flags); - - return ret; + return 0; } #endif /*__KERNEL__*/ diff --git a/arch/parisc/include/asm/prefetch.h b/arch/parisc/include/asm/prefetch.h index 1ee7c82672c1..c5edc60c059f 100644 --- a/arch/parisc/include/asm/prefetch.h +++ b/arch/parisc/include/asm/prefetch.h @@ -21,12 +21,7 @@ #define ARCH_HAS_PREFETCH static inline void prefetch(const void *addr) { - __asm__( -#ifndef CONFIG_PA20 - /* Need to avoid prefetch of NULL on PA7300LC */ - " extrw,u,= %0,31,32,%%r0\n" -#endif - " ldw 0(%0), %%r0" : : "r" (addr)); + __asm__("ldw 0(%0), %%r0" : : "r" (addr)); } /* LDD is a PA2.0 addition. */ diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h index d61de64f990a..3392de3e7be0 100644 --- a/arch/parisc/include/asm/unistd.h +++ b/arch/parisc/include/asm/unistd.h @@ -821,9 +821,8 @@ #define __NR_open_by_handle_at (__NR_Linux + 326) #define __NR_syncfs (__NR_Linux + 327) #define __NR_setns (__NR_Linux + 328) -#define __NR_sendmmsg (__NR_Linux + 329) -#define __NR_Linux_syscalls (__NR_sendmmsg + 1) +#define __NR_Linux_syscalls (__NR_setns + 1) #define __IGNORE_select /* newselect */ diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 07ef351edd57..6f0594439143 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -552,7 +552,7 @@ * entry (identifying the physical page) and %r23 up with * the from tlb entry (or nothing if only a to entry---for * clear_user_page_asm) */ - .macro do_alias spc,tmp,tmp1,va,pte,prot,fault,patype + .macro do_alias spc,tmp,tmp1,va,pte,prot,fault cmpib,COND(<>),n 0,\spc,\fault ldil L%(TMPALIAS_MAP_START),\tmp #if defined(CONFIG_64BIT) && (TMPALIAS_MAP_START >= 0x80000000) @@ -581,15 +581,7 @@ */ cmpiclr,= 0x01,\tmp,%r0 ldi (_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot -.ifc \patype,20 depd,z \prot,8,7,\prot -.else -.ifc \patype,11 - depw,z \prot,8,7,\prot -.else - .error "undefined PA type to do_alias" -.endif -.endif /* * OK, it is in the temp alias region, check whether "from" or "to". * Check "subtle" note in pacache.S re: r23/r26. @@ -1193,7 +1185,7 @@ dtlb_miss_20w: nop dtlb_check_alias_20w: - do_alias spc,t0,t1,va,pte,prot,dtlb_fault,20 + do_alias spc,t0,t1,va,pte,prot,dtlb_fault idtlbt pte,prot @@ -1217,7 +1209,7 @@ nadtlb_miss_20w: nop nadtlb_check_alias_20w: - do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate,20 + do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate idtlbt pte,prot @@ -1249,7 +1241,7 @@ dtlb_miss_11: nop dtlb_check_alias_11: - do_alias spc,t0,t1,va,pte,prot,dtlb_fault,11 + do_alias spc,t0,t1,va,pte,prot,dtlb_fault idtlba pte,(va) idtlbp prot,(va) @@ -1281,7 +1273,7 @@ nadtlb_miss_11: nop nadtlb_check_alias_11: - do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate,11 + do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate idtlba pte,(va) idtlbp prot,(va) @@ -1308,7 +1300,7 @@ dtlb_miss_20: nop dtlb_check_alias_20: - do_alias spc,t0,t1,va,pte,prot,dtlb_fault,20 + do_alias spc,t0,t1,va,pte,prot,dtlb_fault idtlbt pte,prot @@ -1334,7 +1326,7 @@ nadtlb_miss_20: nop nadtlb_check_alias_20: - do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate,20 + do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate idtlbt pte,prot @@ -1461,7 +1453,7 @@ naitlb_miss_20w: nop naitlb_check_alias_20w: - do_alias spc,t0,t1,va,pte,prot,naitlb_fault,20 + do_alias spc,t0,t1,va,pte,prot,naitlb_fault iitlbt pte,prot @@ -1515,7 +1507,7 @@ naitlb_miss_11: nop naitlb_check_alias_11: - do_alias spc,t0,t1,va,pte,prot,itlb_fault,11 + do_alias spc,t0,t1,va,pte,prot,itlb_fault iitlba pte,(%sr0, va) iitlbp prot,(%sr0, va) @@ -1561,7 +1553,7 @@ naitlb_miss_20: nop naitlb_check_alias_20: - do_alias spc,t0,t1,va,pte,prot,naitlb_fault,20 + do_alias spc,t0,t1,va,pte,prot,naitlb_fault iitlbt pte,prot diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index 5d7218ad885c..93ff3d90edd1 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S @@ -692,7 +692,7 @@ ENTRY(flush_icache_page_asm) /* Purge any old translation */ - pitlb (%sr4,%r28) + pitlb (%sr0,%r28) ldil L%icache_stride, %r1 ldw R%icache_stride(%r1), %r1 @@ -706,29 +706,27 @@ ENTRY(flush_icache_page_asm) sub %r25, %r1, %r25 - /* fic only has the type 26 form on PA1.1, requiring an - * explicit space specification, so use %sr4 */ -1: fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) +1: fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) cmpb,COND(<<) %r28, %r25,1b - fic,m %r1(%sr4,%r28) + fic,m %r1(%r28) sync bv %r0(%r2) - pitlb (%sr4,%r25) + pitlb (%sr0,%r25) .exit .procend diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index d0ea054bd3d2..e14132430762 100644 --- a/arch/parisc/kernel/signal32.c +++ b/arch/parisc/kernel/signal32.c @@ -67,8 +67,7 @@ put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) { compat_sigset_t s; - if (sz != sizeof *set) - return -EINVAL; + if (sz != sizeof *set) panic("put_sigset32()"); sigset_64to32(&s, set); return copy_to_user(up, &s, sizeof s); @@ -80,8 +79,7 @@ get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) compat_sigset_t s; int r; - if (sz != sizeof *set) - return -EINVAL; + if (sz != sizeof *set) panic("put_sigset32()"); if ((r = copy_from_user(&s, up, sz)) == 0) { sigset_32to64(set, &s); diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 7ea75d14aa65..c9b932260f47 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -73,8 +73,6 @@ static unsigned long get_shared_area(struct address_space *mapping, struct vm_area_struct *vma; int offset = mapping ? get_offset(mapping) : 0; - offset = (offset + (pgoff << PAGE_SHIFT)) & 0x3FF000; - addr = DCACHE_ALIGN(addr - offset) + offset; for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index e66366fd2abc..34a4f5a2fffb 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -427,7 +427,6 @@ ENTRY_COMP(open_by_handle_at) ENTRY_SAME(syncfs) ENTRY_SAME(setns) - ENTRY_COMP(sendmmsg) /* Nothing yet */ diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index 64a999882e4f..fa6f2b8163e0 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S @@ -50,10 +50,8 @@ SECTIONS . = KERNEL_BINARY_TEXT_START; _text = .; /* Text and read-only data */ - .head ALIGN(16) : { - HEAD_TEXT - } = 0 .text ALIGN(16) : { + HEAD_TEXT TEXT_TEXT SCHED_TEXT LOCK_TEXT @@ -67,7 +65,7 @@ SECTIONS *(.fixup) *(.lock.text) /* out-of-line lock text */ *(.gnu.warning) - } + } = 0 /* End of text section */ _etext = .; diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h index 33a35801f7c9..1cf20bdfbeca 100644 --- a/arch/powerpc/include/asm/cputime.h +++ b/arch/powerpc/include/asm/cputime.h @@ -126,11 +126,11 @@ static inline u64 cputime64_to_jiffies64(const cputime_t ct) /* * Convert cputime <-> microseconds */ -extern u64 __cputime_usec_factor; +extern u64 __cputime_msec_factor; static inline unsigned long cputime_to_usecs(const cputime_t ct) { - return mulhdu(ct, __cputime_usec_factor); + return mulhdu(ct, __cputime_msec_factor) * USEC_PER_MSEC; } static inline cputime_t usecs_to_cputime(const unsigned long us) @@ -143,7 +143,7 @@ static inline cputime_t usecs_to_cputime(const unsigned long us) sec = us / 1000000; if (ct) { ct *= tb_ticks_per_sec; - do_div(ct, 1000000); + do_div(ct, 1000); } if (sec) ct += (cputime_t) sec * tb_ticks_per_sec; diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 764e99c750d9..c5cae0dd176c 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -1000,8 +1000,7 @@ /* Macros for setting and retrieving special purpose registers */ #ifndef __ASSEMBLY__ #define mfmsr() ({unsigned long rval; \ - asm volatile("mfmsr %0" : "=r" (rval) : \ - : "memory"); rval;}) + asm volatile("mfmsr %0" : "=r" (rval)); rval;}) #ifdef CONFIG_PPC_BOOK3S_64 #define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \ : : "r" (v) : "memory") diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h index a0f358d4a00c..6fbce725c710 100644 --- a/arch/powerpc/include/asm/sections.h +++ b/arch/powerpc/include/asm/sections.h @@ -8,7 +8,7 @@ #ifdef __powerpc64__ -extern char __end_interrupts[]; +extern char _end[]; static inline int in_kernel_text(unsigned long addr) { diff --git a/arch/powerpc/include/asm/sparsemem.h b/arch/powerpc/include/asm/sparsemem.h index 0c5fa3145615..54a47ea2c3aa 100644 --- a/arch/powerpc/include/asm/sparsemem.h +++ b/arch/powerpc/include/asm/sparsemem.h @@ -16,7 +16,7 @@ #endif /* CONFIG_SPARSEMEM */ #ifdef CONFIG_MEMORY_HOTPLUG -extern int create_section_mapping(unsigned long start, unsigned long end); +extern void create_section_mapping(unsigned long start, unsigned long end); extern int remove_section_mapping(unsigned long start, unsigned long end); #ifdef CONFIG_NUMA extern int hot_add_scn_to_nid(unsigned long scn_addr); diff --git a/arch/powerpc/include/asm/synch.h b/arch/powerpc/include/asm/synch.h index 87878c68d1c2..d7cab44643c5 100644 --- a/arch/powerpc/include/asm/synch.h +++ b/arch/powerpc/include/asm/synch.h @@ -13,7 +13,6 @@ extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup; extern void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end); -extern void do_final_fixups(void); static inline void eieio(void) { diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h index bc3c745cb906..fe6f7c2c9c68 100644 --- a/arch/powerpc/include/asm/time.h +++ b/arch/powerpc/include/asm/time.h @@ -219,7 +219,5 @@ DECLARE_PER_CPU(struct cpu_usage, cpu_usage_array); extern void secondary_cpu_time_init(void); extern void iSeries_time_init_early(void); -extern void decrementer_check_overflow(void); - #endif /* __KERNEL__ */ #endif /* __POWERPC_TIME_H */ diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 4c12a751beaa..36e1c8a29be8 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -75,7 +75,6 @@ int main(void) DEFINE(SIGSEGV, SIGSEGV); DEFINE(NMI_MASK, NMI_MASK); DEFINE(THREAD_DSCR, offsetof(struct thread_struct, dscr)); - DEFINE(THREAD_DSCR_INHERIT, offsetof(struct thread_struct, dscr_inherit)); #else DEFINE(THREAD_INFO, offsetof(struct task_struct, stack)); #endif /* CONFIG_PPC64 */ diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index cc6a9d5d69ab..4e6ee944495a 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c @@ -242,8 +242,12 @@ static void crash_kexec_wait_realmode(int cpu) while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) { barrier(); - if (!cpu_possible(i) || !cpu_online(i) || (msecs <= 0)) + if (!cpu_possible(i)) { break; + } + if (!cpu_online(i)) { + break; + } msecs--; mdelay(1); } diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 654fc535ed00..d834425186ae 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -380,12 +380,6 @@ _GLOBAL(ret_from_fork) li r3,0 b syscall_exit - .section ".toc","aw" -DSCR_DEFAULT: - .tc dscr_default[TC],dscr_default - - .section ".text" - /* * This routine switches between two different tasks. The process * state of one is saved on its kernel stack. Then the state @@ -525,6 +519,9 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) mr r1,r8 /* start using new stack pointer */ std r7,PACAKSAVE(r13) + ld r6,_CCR(r1) + mtcrf 0xFF,r6 + #ifdef CONFIG_ALTIVEC BEGIN_FTR_SECTION ld r0,THREAD_VRSAVE(r4) @@ -533,22 +530,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_PPC64 BEGIN_FTR_SECTION - lwz r6,THREAD_DSCR_INHERIT(r4) - ld r7,DSCR_DEFAULT@toc(2) ld r0,THREAD_DSCR(r4) - cmpwi r6,0 - bne 1f - ld r0,0(r7) -1: cmpd r0,r25 - beq 2f + cmpd r0,r25 + beq 1f mtspr SPRN_DSCR,r0 -2: +1: END_FTR_SECTION_IFSET(CPU_FTR_DSCR) #endif - ld r6,_CCR(r1) - mtcrf 0xFF,r6 - /* r3-r13 are destroyed -- Cort */ REST_8GPRS(14, r1) REST_10GPRS(22, r1) diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index 63240081133e..bf99cfa6bbfe 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c @@ -245,9 +245,9 @@ __ftrace_make_nop(struct module *mod, /* * On PPC32 the trampoline looks like: - * 0x3d, 0x80, 0x00, 0x00 lis r12,sym@ha - * 0x39, 0x8c, 0x00, 0x00 addi r12,r12,sym@l - * 0x7d, 0x89, 0x03, 0xa6 mtctr r12 + * 0x3d, 0x60, 0x00, 0x00 lis r11,sym@ha + * 0x39, 0x6b, 0x00, 0x00 addi r11,r11,sym@l + * 0x7d, 0x69, 0x03, 0xa6 mtctr r11 * 0x4e, 0x80, 0x04, 0x20 bctr */ @@ -262,9 +262,9 @@ __ftrace_make_nop(struct module *mod, pr_devel(" %08x %08x ", jmp[0], jmp[1]); /* verify that this is what we expect it to be */ - if (((jmp[0] & 0xffff0000) != 0x3d800000) || - ((jmp[1] & 0xffff0000) != 0x398c0000) || - (jmp[2] != 0x7d8903a6) || + if (((jmp[0] & 0xffff0000) != 0x3d600000) || + ((jmp[1] & 0xffff0000) != 0x396b0000) || + (jmp[2] != 0x7d6903a6) || (jmp[3] != 0x4e800420)) { printk(KERN_ERR "Not a trampoline\n"); return -EINVAL; diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index e8befeffb673..ba504099844a 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -425,7 +425,7 @@ _STATIC(__after_prom_start) tovirt(r6,r6) /* on booke, we already run at PAGE_OFFSET */ #endif -#ifdef CONFIG_RELOCATABLE +#ifdef CONFIG_CRASH_DUMP /* * Check if the kernel has to be running as relocatable kernel based on the * variable __run_at_load, if it is set the kernel is treated as relocatable diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index ca2987d939f5..5b428e308666 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -170,13 +170,16 @@ notrace void arch_local_irq_restore(unsigned long en) */ local_paca->hard_enabled = en; - /* - * Trigger the decrementer if we have a pending event. Some processors - * only trigger on edge transitions of the sign bit. We might also - * have disabled interrupts long enough that the decrementer wrapped - * to positive. +#ifndef CONFIG_BOOKE + /* On server, re-trigger the decrementer if it went negative since + * some processors only trigger on edge transitions of the sign bit. + * + * BookE has a level sensitive decrementer (latches in TSR) so we + * don't need that */ - decrementer_check_overflow(); + if ((int)mfspr(SPRN_DEC) < 0) + mtspr(SPRN_DEC, 1); +#endif /* CONFIG_BOOKE */ /* * Force the delivery of pending soft-disabled interrupts on PS3. diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c index ad892f7a7574..b06bdae04064 100644 --- a/arch/powerpc/kernel/kvm.c +++ b/arch/powerpc/kernel/kvm.c @@ -131,6 +131,7 @@ static void kvm_patch_ins_b(u32 *inst, int addr) /* On relocatable kernels interrupts handlers and our code can be in different regions, so we don't patch them */ + extern u32 __end_interrupts; if ((ulong)inst < (ulong)&__end_interrupts) return; #endif diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c index 449a7e053e67..f832773fc28e 100644 --- a/arch/powerpc/kernel/module_32.c +++ b/arch/powerpc/kernel/module_32.c @@ -187,8 +187,8 @@ int apply_relocate(Elf32_Shdr *sechdrs, static inline int entry_matches(struct ppc_plt_entry *entry, Elf32_Addr val) { - if (entry->jump[0] == 0x3d800000 + ((val + 0x8000) >> 16) - && entry->jump[1] == 0x398c0000 + (val & 0xffff)) + if (entry->jump[0] == 0x3d600000 + ((val + 0x8000) >> 16) + && entry->jump[1] == 0x396b0000 + (val & 0xffff)) return 1; return 0; } @@ -215,9 +215,10 @@ static uint32_t do_plt_call(void *location, entry++; } - entry->jump[0] = 0x3d800000+((val+0x8000)>>16); /* lis r12,sym@ha */ - entry->jump[1] = 0x398c0000 + (val&0xffff); /* addi r12,r12,sym@l*/ - entry->jump[2] = 0x7d8903a6; /* mtctr r12 */ + /* Stolen from Paul Mackerras as well... */ + entry->jump[0] = 0x3d600000+((val+0x8000)>>16); /* lis r11,sym@ha */ + entry->jump[1] = 0x396b0000 + (val&0xffff); /* addi r11,r11,sym@l*/ + entry->jump[2] = 0x7d6903a6; /* mtctr r11 */ entry->jump[3] = 0x4e800420; /* bctr */ DEBUGP("Initialized plt for 0x%x at %p\n", val, entry); diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c index 5793c4ba5a03..822f63008ae1 100644 --- a/arch/powerpc/kernel/perf_event.c +++ b/arch/powerpc/kernel/perf_event.c @@ -865,7 +865,6 @@ static void power_pmu_start(struct perf_event *event, int ef_flags) { unsigned long flags; s64 left; - unsigned long val; if (!event->hw.idx || !event->hw.sample_period) return; @@ -881,12 +880,7 @@ static void power_pmu_start(struct perf_event *event, int ef_flags) event->hw.state = 0; left = local64_read(&event->hw.period_left); - - val = 0; - if (left < 0x80000000L) - val = 0x80000000L - left; - - write_pmc(event->hw.idx, val); + write_pmc(event->hw.idx, left); perf_event_update_userpage(event); perf_pmu_enable(event->pmu); diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 5596397ce959..91e52df3d81d 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -794,8 +794,16 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, #endif /* CONFIG_PPC_STD_MMU_64 */ #ifdef CONFIG_PPC64 if (cpu_has_feature(CPU_FTR_DSCR)) { - p->thread.dscr_inherit = current->thread.dscr_inherit; - p->thread.dscr = current->thread.dscr; + if (current->thread.dscr_inherit) { + p->thread.dscr_inherit = 1; + p->thread.dscr = current->thread.dscr; + } else if (0 != dscr_default) { + p->thread.dscr_inherit = 1; + p->thread.dscr = dscr_default; + } else { + p->thread.dscr_inherit = 0; + p->thread.dscr = 0; + } } #endif diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 3b22142c40df..c016033ba78d 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -1020,7 +1020,7 @@ static unsigned long __init alloc_up(unsigned long size, unsigned long align) } if (addr == 0) return 0; - RELOC(alloc_bottom) = addr + size; + RELOC(alloc_bottom) = addr; prom_debug(" -> %x\n", addr); prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom)); @@ -1834,7 +1834,7 @@ static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end, chunk = alloc_up(room, 0); if (chunk == 0) prom_panic("No memory for flatten_device_tree (claim failed)"); - *mem_end = chunk + room; + *mem_end = RELOC(alloc_top); } ret = (void *)*mem_start; @@ -2053,7 +2053,7 @@ static void __init flatten_device_tree(void) mem_start = (unsigned long)alloc_up(room, PAGE_SIZE); if (mem_start == 0) prom_panic("Can't allocate initial device-tree chunk\n"); - mem_end = mem_start + room; + mem_end = RELOC(alloc_top); /* Get root of tree */ root = call_prom("peer", 1, 1, (phandle)0); diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 9321d0f4b6a2..cb22024f2b42 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -1497,14 +1497,9 @@ long arch_ptrace(struct task_struct *child, long request, if (index < PT_FPR0) { tmp = ptrace_get_reg(child, (int) index); } else { - unsigned int fpidx = index - PT_FPR0; - flush_fp_to_thread(child); - if (fpidx < (PT_FPSCR - PT_FPR0)) - tmp = ((unsigned long *)child->thread.fpr) - [fpidx * TS_FPRWIDTH]; - else - tmp = child->thread.fpscr.val; + tmp = ((unsigned long *)child->thread.fpr) + [TS_FPRWIDTH * (index - PT_FPR0)]; } ret = put_user(tmp, datalp); break; @@ -1530,14 +1525,9 @@ long arch_ptrace(struct task_struct *child, long request, if (index < PT_FPR0) { ret = ptrace_put_reg(child, index, data); } else { - unsigned int fpidx = index - PT_FPR0; - flush_fp_to_thread(child); - if (fpidx < (PT_FPSCR - PT_FPR0)) - ((unsigned long *)child->thread.fpr) - [fpidx * TS_FPRWIDTH] = data; - else - child->thread.fpscr.val = data; + ((unsigned long *)child->thread.fpr) + [TS_FPRWIDTH * (index - PT_FPR0)] = data; ret = 0; } break; diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index c7e7b8c718d4..620d792b52e4 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -107,8 +107,6 @@ notrace unsigned long __init early_init(unsigned long dt_ptr) PTRRELOC(&__start___lwsync_fixup), PTRRELOC(&__stop___lwsync_fixup)); - do_final_fixups(); - return KERNELBASE + offset; } diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 7867fd17a0de..a88bf2713d41 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -352,7 +352,6 @@ void __init setup_system(void) &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup); do_lwsync_fixups(cur_cpu_spec->cpu_features, &__start___lwsync_fixup, &__stop___lwsync_fixup); - do_final_fixups(); /* * Unflatten the device-tree passed by prom_init or kexec diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index cd51a5c71376..f0f2199e64e1 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -192,14 +192,6 @@ static ssize_t show_dscr_default(struct sysdev_class *class, return sprintf(buf, "%lx\n", dscr_default); } -static void update_dscr(void *dummy) -{ - if (!current->thread.dscr_inherit) { - current->thread.dscr = dscr_default; - mtspr(SPRN_DSCR, dscr_default); - } -} - static ssize_t __used store_dscr_default(struct sysdev_class *class, struct sysdev_class_attribute *attr, const char *buf, size_t count) @@ -212,8 +204,6 @@ static ssize_t __used store_dscr_default(struct sysdev_class *class, return -EINVAL; dscr_default = val; - on_each_cpu(update_dscr, NULL, 1); - return count; } diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 818d809e22fe..f33acfd872ad 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -168,13 +168,13 @@ EXPORT_SYMBOL_GPL(ppc_tb_freq); #ifdef CONFIG_VIRT_CPU_ACCOUNTING /* * Factors for converting from cputime_t (timebase ticks) to - * jiffies, microseconds, seconds, and clock_t (1/USER_HZ seconds). + * jiffies, milliseconds, seconds, and clock_t (1/USER_HZ seconds). * These are all stored as 0.64 fixed-point binary fractions. */ u64 __cputime_jiffies_factor; EXPORT_SYMBOL(__cputime_jiffies_factor); -u64 __cputime_usec_factor; -EXPORT_SYMBOL(__cputime_usec_factor); +u64 __cputime_msec_factor; +EXPORT_SYMBOL(__cputime_msec_factor); u64 __cputime_sec_factor; EXPORT_SYMBOL(__cputime_sec_factor); u64 __cputime_clockt_factor; @@ -192,8 +192,8 @@ static void calc_cputime_factors(void) div128_by_32(HZ, 0, tb_ticks_per_sec, &res); __cputime_jiffies_factor = res.result_low; - div128_by_32(1000000, 0, tb_ticks_per_sec, &res); - __cputime_usec_factor = res.result_low; + div128_by_32(1000, 0, tb_ticks_per_sec, &res); + __cputime_msec_factor = res.result_low; div128_by_32(1, 0, tb_ticks_per_sec, &res); __cputime_sec_factor = res.result_low; div128_by_32(USER_HZ, 0, tb_ticks_per_sec, &res); @@ -544,7 +544,7 @@ DEFINE_PER_CPU(u8, irq_work_pending); #endif /* 32 vs 64 bit */ -void arch_irq_work_raise(void) +void set_irq_work_pending(void) { preempt_disable(); set_irq_work_pending_flag(); @@ -859,8 +859,13 @@ void update_vsyscall(struct timespec *wall_time, struct timespec *wtm, void update_vsyscall_tz(void) { + /* Make userspace gettimeofday spin until we're done. */ + ++vdso_data->tb_update_count; + smp_mb(); vdso_data->tz_minuteswest = sys_tz.tz_minuteswest; vdso_data->tz_dsttime = sys_tz.tz_dsttime; + smp_mb(); + ++vdso_data->tb_update_count; } static void __init clocksource_init(void) @@ -884,15 +889,6 @@ static void __init clocksource_init(void) clock->name, clock->mult, clock->shift); } -void decrementer_check_overflow(void) -{ - u64 now = get_tb_or_rtc(); - struct decrementer_clock *decrementer = &__get_cpu_var(decrementers); - - if (now >= decrementer->next_tb) - set_dec(1); -} - static int decrementer_set_next_event(unsigned long evt, struct clock_event_device *dev) { diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 6889f2676a97..1a0141426cda 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -935,9 +935,8 @@ static int emulate_instruction(struct pt_regs *regs) cpu_has_feature(CPU_FTR_DSCR)) { PPC_WARN_EMULATED(mtdscr, regs); rd = (instword >> 21) & 0x1f; - current->thread.dscr = regs->gpr[rd]; + mtspr(SPRN_DSCR, regs->gpr[rd]); current->thread.dscr_inherit = 1; - mtspr(SPRN_DSCR, current->thread.dscr); return 0; } #endif diff --git a/arch/powerpc/kvm/44x_emulate.c b/arch/powerpc/kvm/44x_emulate.c index ded8a1a04264..549bb2c9a47a 100644 --- a/arch/powerpc/kvm/44x_emulate.c +++ b/arch/powerpc/kvm/44x_emulate.c @@ -79,7 +79,6 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, run->dcr.dcrn = dcrn; run->dcr.data = 0; run->dcr.is_write = 0; - vcpu->arch.dcr_is_write = 0; vcpu->arch.io_gpr = rt; vcpu->arch.dcr_needed = 1; kvmppc_account_exit(vcpu, DCR_EXITS); @@ -101,7 +100,6 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, run->dcr.dcrn = dcrn; run->dcr.data = kvmppc_get_gpr(vcpu, rs); run->dcr.is_write = 1; - vcpu->arch.dcr_is_write = 1; vcpu->arch.dcr_needed = 1; kvmppc_account_exit(vcpu, DCR_EXITS); emulated = EMULATE_DO_DCR; diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c index 7a8a7487cee8..0d08d0171392 100644 --- a/arch/powerpc/lib/feature-fixups.c +++ b/arch/powerpc/lib/feature-fixups.c @@ -18,8 +18,6 @@ #include #include #include -#include -#include struct fixup_entry { @@ -130,27 +128,6 @@ void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end) } } -void do_final_fixups(void) -{ -#if defined(CONFIG_PPC64) && defined(CONFIG_RELOCATABLE) - int *src, *dest; - unsigned long length; - - if (PHYSICAL_START == 0) - return; - - src = (int *)(KERNELBASE + PHYSICAL_START); - dest = (int *)KERNELBASE; - length = (__end_interrupts - _stext) / sizeof(int); - - while (length--) { - patch_instruction(dest, *src); - src++; - dest++; - } -#endif -} - #ifdef CONFIG_FTR_FIXUP_SELFTEST #define check(x) \ diff --git a/arch/powerpc/mm/gup.c b/arch/powerpc/mm/gup.c index d7efdbf640c7..fec13200868f 100644 --- a/arch/powerpc/mm/gup.c +++ b/arch/powerpc/mm/gup.c @@ -16,6 +16,16 @@ #ifdef __HAVE_ARCH_PTE_SPECIAL +static inline void get_huge_page_tail(struct page *page) +{ + /* + * __split_huge_page_refcount() cannot run + * from under us. + */ + VM_BUG_ON(atomic_read(&page->_count) < 0); + atomic_inc(&page->_count); +} + /* * The performance critical leaf functions are made noinline otherwise gcc * inlines everything into a single function which results in too much @@ -47,6 +57,8 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr, put_page(page); return 0; } + if (PageTail(page)) + get_huge_page_tail(page); pages[*nr] = page; (*nr)++; diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 07f9e9f0d871..26b2872b3d00 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -534,11 +534,11 @@ static unsigned long __init htab_get_table_size(void) } #ifdef CONFIG_MEMORY_HOTPLUG -int create_section_mapping(unsigned long start, unsigned long end) +void create_section_mapping(unsigned long start, unsigned long end) { - return htab_bolt_mapping(start, end, __pa(start), + BUG_ON(htab_bolt_mapping(start, end, __pa(start), pgprot_val(PAGE_KERNEL), mmu_linear_psize, - mmu_kernel_ssize); + mmu_kernel_ssize)); } int remove_section_mapping(unsigned long start, unsigned long end) diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index da5eb3885702..0b9a5c1901b9 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -390,7 +390,7 @@ static noinline int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long add { unsigned long mask; unsigned long pte_end; - struct page *head, *page, *tail; + struct page *head, *page; pte_t pte; int refs; @@ -413,7 +413,6 @@ static noinline int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long add head = pte_page(pte); page = head + ((addr & (sz-1)) >> PAGE_SHIFT); - tail = page; do { VM_BUG_ON(compound_head(page) != head); pages[*nr] = page; @@ -429,20 +428,10 @@ static noinline int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long add if (unlikely(pte_val(pte) != pte_val(*ptep))) { /* Could be optimized better */ - *nr -= refs; - while (refs--) - put_page(head); - return 0; - } - - /* - * Any tail page need their mapcount reference taken before we - * return. - */ - while (refs--) { - if (PageTail(tail)) - get_huge_page_tail(tail); - tail++; + while (*nr) { + put_page(page); + (*nr)--; + } } return 1; diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 278ec8ef4f62..29d4dde65c45 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -123,8 +123,7 @@ int arch_add_memory(int nid, u64 start, u64 size) pgdata = NODE_DATA(nid); start = (unsigned long)__va(start); - if (create_section_mapping(start, start + size)) - return -EINVAL; + create_section_mapping(start, start + size); /* this should work for most non-highmem platforms */ zone = pgdata->node_zones; diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c index 4ff587e38250..3bafc3deca6d 100644 --- a/arch/powerpc/mm/mmu_context_hash64.c +++ b/arch/powerpc/mm/mmu_context_hash64.c @@ -136,8 +136,8 @@ int use_cop(unsigned long acop, struct mm_struct *mm) if (!mm || !acop) return -EINVAL; - /* The page_table_lock ensures mm_users won't change under us */ - spin_lock(&mm->page_table_lock); + /* We need to make sure mm_users doesn't change */ + down_read(&mm->mmap_sem); spin_lock(mm->context.cop_lockp); if (mm->context.cop_pid == COP_PID_NONE) { @@ -164,7 +164,7 @@ int use_cop(unsigned long acop, struct mm_struct *mm) out: spin_unlock(mm->context.cop_lockp); - spin_unlock(&mm->page_table_lock); + up_read(&mm->mmap_sem); return ret; } @@ -185,8 +185,8 @@ void drop_cop(unsigned long acop, struct mm_struct *mm) if (WARN_ON_ONCE(!mm)) return; - /* The page_table_lock ensures mm_users won't change under us */ - spin_lock(&mm->page_table_lock); + /* We need to make sure mm_users doesn't change */ + down_read(&mm->mmap_sem); spin_lock(mm->context.cop_lockp); mm->context.acop &= ~acop; @@ -213,7 +213,7 @@ void drop_cop(unsigned long acop, struct mm_struct *mm) } spin_unlock(mm->context.cop_lockp); - spin_unlock(&mm->page_table_lock); + up_read(&mm->mmap_sem); } EXPORT_SYMBOL_GPL(drop_cop); diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 2c1ae7a5fb53..2164006fe170 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -1214,12 +1214,11 @@ int hot_add_node_scn_to_nid(unsigned long scn_addr) break; } + of_node_put(memory); if (nid >= 0) break; } - of_node_put(memory); - return nid; } diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c index daf793b1e94f..1b5dc1a2e145 100644 --- a/arch/powerpc/platforms/embedded6xx/wii.c +++ b/arch/powerpc/platforms/embedded6xx/wii.c @@ -85,11 +85,9 @@ void __init wii_memory_fixups(void) wii_hole_start = p[0].base + p[0].size; wii_hole_size = p[1].base - wii_hole_start; - pr_info("MEM1: <%08llx %08llx>\n", - (unsigned long long) p[0].base, (unsigned long long) p[0].size); + pr_info("MEM1: <%08llx %08llx>\n", p[0].base, p[0].size); pr_info("HOLE: <%08lx %08lx>\n", wii_hole_start, wii_hole_size); - pr_info("MEM2: <%08llx %08llx>\n", - (unsigned long long) p[1].base, (unsigned long long) p[1].size); + pr_info("MEM2: <%08llx %08llx>\n", p[1].base, p[1].size); p[0].size += wii_hole_size + p[1].size; diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index 53a6be7ebe3c..db092d7c4c5b 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -414,7 +414,7 @@ static struct irqaction psurge_irqaction = { static void __init smp_psurge_setup_cpu(int cpu_nr) { - if (cpu_nr != 0 || !psurge_start) + if (cpu_nr != 0) return; /* reset the entry point so if we get another intr we won't diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index 1aa478b97aac..600ed2c0ed59 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c @@ -88,7 +88,6 @@ struct ps3_private { struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN))); u64 ppe_id; u64 thread_id; - unsigned long ipi_mask; }; static DEFINE_PER_CPU(struct ps3_private, ps3_private); @@ -145,11 +144,7 @@ static void ps3_chip_unmask(struct irq_data *d) static void ps3_chip_eoi(struct irq_data *d) { const struct ps3_private *pd = irq_data_get_irq_chip_data(d); - - /* non-IPIs are EOIed here. */ - - if (!test_bit(63 - d->irq, &pd->ipi_mask)) - lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, d->irq); + lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, d->irq); } /** @@ -696,16 +691,6 @@ void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq) cpu, virq, pd->bmp.ipi_debug_brk_mask); } -void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq) -{ - struct ps3_private *pd = &per_cpu(ps3_private, cpu); - - set_bit(63 - virq, &pd->ipi_mask); - - DBG("%s:%d: cpu %u, virq %u, ipi_mask %lxh\n", __func__, __LINE__, - cpu, virq, pd->ipi_mask); -} - static unsigned int ps3_get_irq(void) { struct ps3_private *pd = &__get_cpu_var(ps3_private); @@ -735,12 +720,6 @@ static unsigned int ps3_get_irq(void) BUG(); } #endif - - /* IPIs are EOIed here. */ - - if (test_bit(63 - plug, &pd->ipi_mask)) - lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, plug); - return plug; } diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h index 1a633ed0fe98..9a196a88eda7 100644 --- a/arch/powerpc/platforms/ps3/platform.h +++ b/arch/powerpc/platforms/ps3/platform.h @@ -43,7 +43,6 @@ void ps3_mm_shutdown(void); void ps3_init_IRQ(void); void ps3_shutdown_IRQ(int cpu); void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq); -void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq); /* smp */ diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c index f609345b6c3a..4c44794faac0 100644 --- a/arch/powerpc/platforms/ps3/smp.c +++ b/arch/powerpc/platforms/ps3/smp.c @@ -94,8 +94,6 @@ static void __init ps3_smp_setup_cpu(int cpu) if (result) virqs[i] = NO_IRQ; - else - ps3_register_ipi_irq(cpu, virqs[i]); } ps3_register_ipi_debug_brk(cpu, virqs[PPC_MSG_DEBUGGER_BREAK]); diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 82766e5a79e5..57ceb92b2288 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -112,7 +112,6 @@ void dlpar_free_cc_nodes(struct device_node *dn) dlpar_free_one_cc_node(dn); } -#define COMPLETE 0 #define NEXT_SIBLING 1 #define NEXT_CHILD 2 #define NEXT_PROPERTY 3 @@ -159,9 +158,6 @@ struct device_node *dlpar_configure_connector(u32 drc_index) spin_unlock(&rtas_data_buf_lock); switch (rc) { - case COMPLETE: - break; - case NEXT_SIBLING: dn = dlpar_parse_cc_node(ccwa); if (!dn) diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c index 0e8656370063..e9190073bb97 100644 --- a/arch/powerpc/platforms/pseries/dtl.c +++ b/arch/powerpc/platforms/pseries/dtl.c @@ -181,7 +181,7 @@ static void dtl_stop(struct dtl *dtl) lppaca_of(dtl->cpu).dtl_enable_mask = 0x0; - unregister_dtl(hwcpu); + unregister_dtl(hwcpu, __pa(dtl->buf)); } static u64 dtl_current_index(struct dtl *dtl) diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 3608704554d3..46b55cf563e3 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c @@ -1338,7 +1338,7 @@ static const struct file_operations proc_eeh_operations = { static int __init eeh_init_proc(void) { if (machine_is(pseries)) - proc_create("powerpc/eeh", 0, NULL, &proc_eeh_operations); + proc_create("ppc64/eeh", 0, NULL, &proc_eeh_operations); return 0; } __initcall(eeh_init_proc); diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c index c9311cfdfcac..f106662f4381 100644 --- a/arch/powerpc/platforms/pseries/hvCall_inst.c +++ b/arch/powerpc/platforms/pseries/hvCall_inst.c @@ -109,7 +109,7 @@ static void probe_hcall_entry(void *ignored, unsigned long opcode, unsigned long if (opcode > MAX_HCALL_OPCODE) return; - h = &__get_cpu_var(hcall_stats)[opcode / 4]; + h = &get_cpu_var(hcall_stats)[opcode / 4]; h->tb_start = mftb(); h->purr_start = mfspr(SPRN_PURR); } @@ -126,6 +126,8 @@ static void probe_hcall_exit(void *ignored, unsigned long opcode, unsigned long h->num_calls++; h->tb_total += mftb() - h->tb_start; h->purr_total += mfspr(SPRN_PURR) - h->purr_start; + + put_cpu_var(hcall_stats); } static int __init hcall_inst_init(void) diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c index 041e87ca1893..3f6a89b09816 100644 --- a/arch/powerpc/platforms/pseries/hvconsole.c +++ b/arch/powerpc/platforms/pseries/hvconsole.c @@ -73,7 +73,7 @@ int hvc_put_chars(uint32_t vtermno, const char *buf, int count) if (ret == H_SUCCESS) return count; if (ret == H_BUSY) - return -EAGAIN; + return 0; return -EIO; } diff --git a/arch/powerpc/platforms/pseries/kexec.c b/arch/powerpc/platforms/pseries/kexec.c index 1118cb79f9e3..54cf3a4aa16b 100644 --- a/arch/powerpc/platforms/pseries/kexec.c +++ b/arch/powerpc/platforms/pseries/kexec.c @@ -26,17 +26,6 @@ static void pseries_kexec_cpu_down(int crash_shutdown, int secondary) /* Don't risk a hypervisor call if we're crashing */ if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) { unsigned long addr; - int ret; - - if (get_lppaca()->dtl_enable_mask) { - ret = unregister_dtl(hard_smp_processor_id()); - if (ret) { - pr_err("WARNING: DTL deregistration for cpu " - "%d (hw %d) failed with %d\n", - smp_processor_id(), - hard_smp_processor_id(), ret); - } - } addr = __pa(get_slb_shadow()); if (unregister_slb_shadow(hard_smp_processor_id(), addr)) diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 81e30d96f83f..39e6e0a7b2fa 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -395,7 +395,7 @@ static void pSeries_lpar_hptab_clear(void) unsigned long ptel; } ptes[4]; long lpar_rc; - unsigned long i, j; + int i, j; /* Read in batches of 4, * invalidate only valid entries not in the VRMA @@ -745,7 +745,6 @@ void __trace_hcall_entry(unsigned long opcode, unsigned long *args) goto out; (*depth)++; - preempt_disable(); trace_hcall_entry(opcode, args); (*depth)--; @@ -768,7 +767,6 @@ void __trace_hcall_exit(long opcode, unsigned long retval, (*depth)++; trace_hcall_exit(opcode, retval, retbuf); - preempt_enable(); (*depth)--; out: diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h index a6921aec2d6f..4bf21207d7d3 100644 --- a/arch/powerpc/platforms/pseries/plpar_wrappers.h +++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h @@ -73,9 +73,9 @@ static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa) return vpa_call(0x3, cpu, vpa); } -static inline long unregister_dtl(unsigned long cpu) +static inline long unregister_dtl(unsigned long cpu, unsigned long vpa) { - return vpa_call(0x6, cpu, 0); + return vpa_call(0x6, cpu, vpa); } static inline long register_dtl(unsigned long cpu, unsigned long vpa) diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index cdd765bb66ba..b3fd081d56f5 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -54,7 +54,6 @@ #define ODSR_CLEAR 0x1c00 #define LTLEECSR_ENABLE_ALL 0xFFC000FC #define ESCSR_CLEAR 0x07120204 -#define IECSR_CLEAR 0x80000000 #define RIO_PORT1_EDCSR 0x0640 #define RIO_PORT2_EDCSR 0x0680 @@ -1090,11 +1089,11 @@ static void port_error_handler(struct rio_mport *port, int offset) if (offset == 0) { out_be32((u32 *)(rio_regs_win + RIO_PORT1_EDCSR), 0); - out_be32((u32 *)(rio_regs_win + RIO_PORT1_IECSR), IECSR_CLEAR); + out_be32((u32 *)(rio_regs_win + RIO_PORT1_IECSR), 0); out_be32((u32 *)(rio_regs_win + RIO_ESCSR), ESCSR_CLEAR); } else { out_be32((u32 *)(rio_regs_win + RIO_PORT2_EDCSR), 0); - out_be32((u32 *)(rio_regs_win + RIO_PORT2_IECSR), IECSR_CLEAR); + out_be32((u32 *)(rio_regs_win + RIO_PORT2_IECSR), 0); out_be32((u32 *)(rio_regs_win + RIO_PORT2_ESCSR), ESCSR_CLEAR); } } diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index ace178441918..42541bbcc7fa 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -975,7 +975,7 @@ static int cpu_cmd(void) /* print cpus waiting or in xmon */ printf("cpus stopped:"); count = 0; - for_each_possible_cpu(cpu) { + for (cpu = 0; cpu < NR_CPUS; ++cpu) { if (cpumask_test_cpu(cpu, &cpus_in_xmon)) { if (count == 0) printf(" %x", cpu); diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index c395f713ce31..c03fef7a9c22 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -89,6 +89,7 @@ config S390 select HAVE_GET_USER_PAGES_FAST select HAVE_ARCH_MUTEX_CPU_RELAX select HAVE_ARCH_JUMP_LABEL if !MARCH_G5 + select HAVE_RCU_TABLE_FREE if SMP select ARCH_INLINE_SPIN_TRYLOCK select ARCH_INLINE_SPIN_TRYLOCK_BH select ARCH_INLINE_SPIN_LOCK @@ -227,9 +228,6 @@ config COMPAT config SYSVIPC_COMPAT def_bool y if COMPAT && SYSVIPC -config KEYS_COMPAT - def_bool y if COMPAT && KEYS - config AUDIT_ARCH def_bool y diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index f7b74bcce10c..da359ca6fe55 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h @@ -172,6 +172,13 @@ static inline int is_compat_task(void) return is_32bit_task(); } +#else + +static inline int is_compat_task(void) +{ + return 0; +} + #endif static inline void __user *arch_compat_alloc_user_space(long len) diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index e4b6609fe92a..38e71ebcd3c2 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h @@ -22,7 +22,10 @@ void crst_table_free(struct mm_struct *, unsigned long *); unsigned long *page_table_alloc(struct mm_struct *); void page_table_free(struct mm_struct *, unsigned long *); +#ifdef CONFIG_HAVE_RCU_TABLE_FREE void page_table_free_rcu(struct mmu_gather *, unsigned long *); +void __tlb_remove_table(void *_table); +#endif static inline void clear_table(unsigned long *s, unsigned long val, size_t n) { diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h index a4b8f6009c2e..88829a40af6f 100644 --- a/arch/s390/include/asm/timex.h +++ b/arch/s390/include/asm/timex.h @@ -126,32 +126,4 @@ static inline unsigned long long get_clock_monotonic(void) return get_clock_xt() - sched_clock_base_cc; } -/** - * tod_to_ns - convert a TOD format value to nanoseconds - * @todval: to be converted TOD format value - * Returns: number of nanoseconds that correspond to the TOD format value - * - * Converting a 64 Bit TOD format value to nanoseconds means that the value - * must be divided by 4.096. In order to achieve that we multiply with 125 - * and divide by 512: - * - * ns = (todval * 125) >> 9; - * - * In order to avoid an overflow with the multiplication we can rewrite this. - * With a split todval == 2^32 * th + tl (th upper 32 bits, tl lower 32 bits) - * we end up with - * - * ns = ((2^32 * th + tl) * 125 ) >> 9; - * -> ns = (2^23 * th * 125) + ((tl * 125) >> 9); - * - */ -static inline unsigned long long tod_to_ns(unsigned long long todval) -{ - unsigned long long ns; - - ns = ((todval >> 32) << 23) * 125; - ns += ((todval & 0xffffffff) * 125) >> 9; - return ns; -} - #endif diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h index 775a5eea8f9e..c687a2c83462 100644 --- a/arch/s390/include/asm/tlb.h +++ b/arch/s390/include/asm/tlb.h @@ -30,10 +30,14 @@ struct mmu_gather { struct mm_struct *mm; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE struct mmu_table_batch *batch; +#endif unsigned int fullmm; + unsigned int need_flush; }; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE struct mmu_table_batch { struct rcu_head rcu; unsigned int nr; @@ -45,6 +49,7 @@ struct mmu_table_batch { extern void tlb_table_flush(struct mmu_gather *tlb); extern void tlb_remove_table(struct mmu_gather *tlb, void *table); +#endif static inline void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, @@ -52,20 +57,29 @@ static inline void tlb_gather_mmu(struct mmu_gather *tlb, { tlb->mm = mm; tlb->fullmm = full_mm_flush; + tlb->need_flush = 0; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE tlb->batch = NULL; +#endif if (tlb->fullmm) __tlb_flush_mm(mm); } static inline void tlb_flush_mmu(struct mmu_gather *tlb) { + if (!tlb->need_flush) + return; + tlb->need_flush = 0; + __tlb_flush_mm(tlb->mm); +#ifdef CONFIG_HAVE_RCU_TABLE_FREE tlb_table_flush(tlb); +#endif } static inline void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) { - tlb_table_flush(tlb); + tlb_flush_mmu(tlb); } /* @@ -91,8 +105,10 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page) static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, unsigned long address) { +#ifdef CONFIG_HAVE_RCU_TABLE_FREE if (!tlb->fullmm) return page_table_free_rcu(tlb, (unsigned long *) pte); +#endif page_table_free(tlb->mm, (unsigned long *) pte); } @@ -109,8 +125,10 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, #ifdef __s390x__ if (tlb->mm->context.asce_limit <= (1UL << 31)) return; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE if (!tlb->fullmm) return tlb_remove_table(tlb, pmd); +#endif crst_table_free(tlb->mm, (unsigned long *) pmd); #endif } @@ -128,8 +146,10 @@ static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud, #ifdef __s390x__ if (tlb->mm->context.asce_limit <= (1UL << 42)) return; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE if (!tlb->fullmm) return tlb_remove_table(tlb, pud); +#endif crst_table_free(tlb->mm, (unsigned long *) pud); #endif } diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index f98af0309b0d..53acaa86dd94 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -631,6 +631,7 @@ asmlinkage unsigned long old32_mmap(struct mmap_arg_struct_emu31 __user *arg) return -EFAULT; if (a.offset & ~PAGE_MASK) return -EINVAL; + a.addr = (unsigned long) compat_ptr(a.addr); return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); } @@ -641,6 +642,7 @@ asmlinkage long sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg) if (copy_from_user(&a, arg, sizeof(a))) return -EFAULT; + a.addr = (unsigned long) compat_ptr(a.addr); return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); } diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index abdc2b1063ed..541a7509faeb 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "entry.h" diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 5c55466e78e6..ef86ad243986 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -20,8 +20,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -47,31 +47,29 @@ enum s390_regset { void update_per_regs(struct task_struct *task) { + static const struct per_regs per_single_step = { + .control = PER_EVENT_IFETCH, + .start = 0, + .end = PSW_ADDR_INSN, + }; struct pt_regs *regs = task_pt_regs(task); struct thread_struct *thread = &task->thread; - struct per_regs old, new; - - /* Copy user specified PER registers */ - new.control = thread->per_user.control; - new.start = thread->per_user.start; - new.end = thread->per_user.end; - - /* merge TIF_SINGLE_STEP into user specified PER registers. */ - if (test_tsk_thread_flag(task, TIF_SINGLE_STEP)) { - new.control |= PER_EVENT_IFETCH; - new.start = 0; - new.end = PSW_ADDR_INSN; - } + const struct per_regs *new; + struct per_regs old; + + /* TIF_SINGLE_STEP overrides the user specified PER registers. */ + new = test_tsk_thread_flag(task, TIF_SINGLE_STEP) ? + &per_single_step : &thread->per_user; /* Take care of the PER enablement bit in the PSW. */ - if (!(new.control & PER_EVENT_MASK)) { + if (!(new->control & PER_EVENT_MASK)) { regs->psw.mask &= ~PSW_MASK_PER; return; } regs->psw.mask |= PSW_MASK_PER; __ctl_store(old, 9, 11); - if (memcmp(&new, &old, sizeof(struct per_regs)) != 0) - __ctl_load(new, 9, 11); + if (memcmp(new, &old, sizeof(struct per_regs)) != 0) + __ctl_load(*new, 9, 11); } void user_enable_single_step(struct task_struct *task) @@ -897,14 +895,6 @@ static int s390_last_break_get(struct task_struct *target, return 0; } -static int s390_last_break_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - return 0; -} - #endif static const struct user_regset s390_regsets[] = { @@ -931,7 +921,6 @@ static const struct user_regset s390_regsets[] = { .size = sizeof(long), .align = sizeof(long), .get = s390_last_break_get, - .set = s390_last_break_set, }, #endif }; @@ -1089,14 +1078,6 @@ static int s390_compat_last_break_get(struct task_struct *target, return 0; } -static int s390_compat_last_break_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - return 0; -} - static const struct user_regset s390_compat_regsets[] = { [REGSET_GENERAL] = { .core_note_type = NT_PRSTATUS, @@ -1120,7 +1101,6 @@ static const struct user_regset s390_compat_regsets[] = { .size = sizeof(long), .align = sizeof(long), .get = s390_compat_last_break_get, - .set = s390_compat_last_break_set, }, [REGSET_GENERAL_EXTENDED] = { .core_note_type = NT_S390_HIGH_GPRS, diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 0260051c08f2..0c35dee10b00 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 943ea0e4b713..dff933065ab6 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -63,7 +63,7 @@ static DEFINE_PER_CPU(struct clock_event_device, comparators); */ unsigned long long notrace __kprobes sched_clock(void) { - return tod_to_ns(get_clock_monotonic()); + return (get_clock_monotonic() * 125) >> 9; } /* diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index a3db4c80e00e..35c21bf910c5 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -358,7 +358,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu) return 0; } - sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now); + sltime = ((vcpu->arch.sie_block->ckc - now)*125)>>9; hrtimer_start(&vcpu->arch.ckc_timer, ktime_set (0, sltime) , HRTIMER_MODE_REL); VCPU_EVENT(vcpu, 5, "enabled wait via clock comparator: %llx ns", sltime); diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 2ada634fc7c8..67345ae7ce8d 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -301,17 +301,11 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) { - struct kvm_vcpu *vcpu; - int rc = -EINVAL; - - if (id >= KVM_MAX_VCPUS) - goto out; - - rc = -ENOMEM; + struct kvm_vcpu *vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL); + int rc = -ENOMEM; - vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL); if (!vcpu) - goto out; + goto out_nomem; vcpu->arch.sie_block = (struct kvm_s390_sie_block *) get_zeroed_page(GFP_KERNEL); @@ -347,7 +341,7 @@ out_free_sie_block: free_page((unsigned long)(vcpu->arch.sie_block)); out_free_cpu: kfree(vcpu); -out: +out_nomem: return ERR_PTR(rc); } diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 6903d441068e..fe103e891e7a 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "../kernel/entry.h" #ifndef CONFIG_64BIT @@ -567,7 +568,6 @@ static void pfault_interrupt(unsigned int ext_int_code, tsk->thread.pfault_wait = 0; list_del(&tsk->thread.list); wake_up_process(tsk); - put_task_struct(tsk); } else { /* Completion interrupt was faster than initial * interrupt. Set pfault_wait to -1 so the initial @@ -577,22 +577,14 @@ static void pfault_interrupt(unsigned int ext_int_code, put_task_struct(tsk); } else { /* signal bit not set -> a real page is missing. */ - if (tsk->thread.pfault_wait == 1) { - /* Already on the list with a reference: put to sleep */ - set_task_state(tsk, TASK_UNINTERRUPTIBLE); - set_tsk_need_resched(tsk); - } else if (tsk->thread.pfault_wait == -1) { + if (tsk->thread.pfault_wait == -1) { /* Completion interrupt was faster than the initial * interrupt (pfault_wait == -1). Set pfault_wait * back to zero and exit. */ tsk->thread.pfault_wait = 0; } else { /* Initial interrupt arrived before completion - * interrupt. Let the task sleep. - * An extra task reference is needed since a different - * cpu may set the task state to TASK_RUNNING again - * before the scheduler is reached. */ - get_task_struct(tsk); + * interrupt. Let the task sleep. */ tsk->thread.pfault_wait = 1; list_add(&tsk->thread.list, &pfault_list); set_task_state(tsk, TASK_UNINTERRUPTIBLE); @@ -617,7 +609,6 @@ static int __cpuinit pfault_cpu_notify(struct notifier_block *self, list_del(&thread->list); tsk = container_of(thread, struct task_struct, thread); wake_up_process(tsk); - put_task_struct(tsk); } spin_unlock_irq(&pfault_lock); break; diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 4ccf9f54355e..45b405ca2567 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c @@ -52,7 +52,7 @@ static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, unsigned long end, int write, struct page **pages, int *nr) { unsigned long mask, result; - struct page *head, *page, *tail; + struct page *head, *page; int refs; result = write ? 0 : _SEGMENT_ENTRY_RO; @@ -64,7 +64,6 @@ static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, refs = 0; head = pmd_page(pmd); page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT); - tail = page; do { VM_BUG_ON(compound_head(page) != head); pages[*nr] = page; @@ -82,17 +81,6 @@ static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, *nr -= refs; while (refs--) put_page(head); - return 0; - } - - /* - * Any tail page need their mapcount reference taken before we - * return. - */ - while (refs--) { - if (PageTail(tail)) - get_huge_page_tail(tail); - tail++; } return 1; @@ -183,7 +171,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, addr = start; len = (unsigned long) nr_pages << PAGE_SHIFT; end = start + len; - if ((end < start) || (end > TASK_SIZE)) + if (end < start) goto slow_irqon; /* diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index c0cf9ceb3833..c9a9f7f18188 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c @@ -28,8 +28,8 @@ #include #include #include -#include #include +#include static unsigned long stack_maxrandom_size(void) { diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 51b80b9d1f6a..37a23c223705 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -243,6 +243,8 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) } } +#ifdef CONFIG_HAVE_RCU_TABLE_FREE + static void __page_table_free_rcu(void *table, unsigned bit) { struct page *page; @@ -289,9 +291,8 @@ void page_table_free_rcu(struct mmu_gather *tlb, unsigned long *table) void __tlb_remove_table(void *_table) { - const unsigned long mask = (FRAG_MASK << 4) | FRAG_MASK; - void *table = (void *)((unsigned long) _table & ~mask); - unsigned type = (unsigned long) _table & mask; + void *table = (void *)((unsigned long) _table & PAGE_MASK); + unsigned type = (unsigned long) _table & ~PAGE_MASK; if (type) __page_table_free_rcu(table, type); @@ -299,66 +300,7 @@ void __tlb_remove_table(void *_table) free_pages((unsigned long) table, ALLOC_ORDER); } -static void tlb_remove_table_smp_sync(void *arg) -{ - /* Simply deliver the interrupt */ -} - -static void tlb_remove_table_one(void *table) -{ - /* - * This isn't an RCU grace period and hence the page-tables cannot be - * assumed to be actually RCU-freed. - * - * It is however sufficient for software page-table walkers that rely - * on IRQ disabling. See the comment near struct mmu_table_batch. - */ - smp_call_function(tlb_remove_table_smp_sync, NULL, 1); - __tlb_remove_table(table); -} - -static void tlb_remove_table_rcu(struct rcu_head *head) -{ - struct mmu_table_batch *batch; - int i; - - batch = container_of(head, struct mmu_table_batch, rcu); - - for (i = 0; i < batch->nr; i++) - __tlb_remove_table(batch->tables[i]); - - free_page((unsigned long)batch); -} - -void tlb_table_flush(struct mmu_gather *tlb) -{ - struct mmu_table_batch **batch = &tlb->batch; - - if (*batch) { - __tlb_flush_mm(tlb->mm); - call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu); - *batch = NULL; - } -} - -void tlb_remove_table(struct mmu_gather *tlb, void *table) -{ - struct mmu_table_batch **batch = &tlb->batch; - - if (*batch == NULL) { - *batch = (struct mmu_table_batch *) - __get_free_page(GFP_NOWAIT | __GFP_NOWARN); - if (*batch == NULL) { - __tlb_flush_mm(tlb->mm); - tlb_remove_table_one(table); - return; - } - (*batch)->nr = 0; - } - (*batch)->tables[(*batch)->nr++] = table; - if ((*batch)->nr == MAX_TABLE_BATCH) - tlb_table_flush(tlb); -} +#endif /* * switch on pgstes for its userspace process (for kvm) diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c index 422110a4385b..0e358c2cffeb 100644 --- a/arch/s390/oprofile/init.c +++ b/arch/s390/oprofile/init.c @@ -90,7 +90,7 @@ static ssize_t hwsampler_write(struct file *file, char const __user *buf, return -EINVAL; retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval <= 0) + if (retval) return retval; if (oprofile_started) diff --git a/arch/score/kernel/entry.S b/arch/score/kernel/entry.S index 83bb96079c43..577abba3fac6 100644 --- a/arch/score/kernel/entry.S +++ b/arch/score/kernel/entry.S @@ -408,7 +408,7 @@ ENTRY(handle_sys) sw r9, [r0, PT_EPC] cmpi.c r27, __NR_syscalls # check syscall number - bgeu illegal_syscall + bgtu illegal_syscall slli r8, r27, 2 # get syscall routine la r11, sys_call_table diff --git a/arch/sh/include/asm/elf.h b/arch/sh/include/asm/elf.h index 978b7fd6d474..f38112be67d2 100644 --- a/arch/sh/include/asm/elf.h +++ b/arch/sh/include/asm/elf.h @@ -202,9 +202,9 @@ extern void __kernel_vsyscall; if (vdso_enabled) \ NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE); \ else \ - NEW_AUX_ENT(AT_IGNORE, 0) + NEW_AUX_ENT(AT_IGNORE, 0); #else -#define VSYSCALL_AUX_ENT NEW_AUX_ENT(AT_IGNORE, 0) +#define VSYSCALL_AUX_ENT #endif /* CONFIG_VSYSCALL */ #ifdef CONFIG_SH_FPU diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index abcc4dcc2d94..822d6084195b 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -141,13 +141,8 @@ typedef struct page *pgtable_t; #endif /* !__ASSEMBLY__ */ #ifdef CONFIG_UNCACHED_MAPPING -#if defined(CONFIG_29BIT) -#define UNCAC_ADDR(addr) P2SEGADDR(addr) -#define CAC_ADDR(addr) P1SEGADDR(addr) -#else #define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + uncached_start) #define CAC_ADDR(addr) ((addr) - uncached_start + PAGE_OFFSET) -#endif #else #define UNCAC_ADDR(addr) ((addr)) #define CAC_ADDR(addr) ((addr)) diff --git a/arch/sh/oprofile/common.c b/arch/sh/oprofile/common.c index e4dd5d5a1115..b4c2d2b946dd 100644 --- a/arch/sh/oprofile/common.c +++ b/arch/sh/oprofile/common.c @@ -49,7 +49,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) return oprofile_perf_init(ops); } -void oprofile_arch_exit(void) +void __exit oprofile_arch_exit(void) { oprofile_perf_exit(); kfree(sh_pmu_op_name); @@ -60,5 +60,5 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) ops->backtrace = sh_backtrace; return -ENODEV; } -void oprofile_arch_exit(void) {} +void __exit oprofile_arch_exit(void) {} #endif /* CONFIG_HW_PERF_EVENTS */ diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 9e702570001d..253986bd6bb6 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -53,7 +53,6 @@ config SPARC64 select HAVE_PERF_EVENTS select PERF_USE_VMALLOC select IRQ_PREFLOW_FASTEOI - select HAVE_C_RECORDMCOUNT config ARCH_DEFCONFIG string @@ -590,9 +589,6 @@ config SYSVIPC_COMPAT depends on COMPAT && SYSVIPC default y -config KEYS_COMPAT - def_bool y if COMPAT && KEYS - endmenu source "net/Kconfig" diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile index eddcfb36aafb..ad1fb5d969f3 100644 --- a/arch/sparc/Makefile +++ b/arch/sparc/Makefile @@ -31,7 +31,7 @@ UTS_MACHINE := sparc #KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7 KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7 -KBUILD_AFLAGS += -m32 -Wa,-Av8 +KBUILD_AFLAGS += -m32 #LDFLAGS_vmlinux = -N -Ttext 0xf0004000 # Since 2.5.40, the first stage is left not btfix-ed. diff --git a/arch/sparc/include/asm/bitops_64.h b/arch/sparc/include/asm/bitops_64.h index 3fc595ad6188..38e9aa1b2cea 100644 --- a/arch/sparc/include/asm/bitops_64.h +++ b/arch/sparc/include/asm/bitops_64.h @@ -26,28 +26,61 @@ extern void change_bit(unsigned long nr, volatile unsigned long *addr); #define smp_mb__before_clear_bit() barrier() #define smp_mb__after_clear_bit() barrier() +#include +#include #include #include #include #ifdef __KERNEL__ -extern int ffs(int x); -extern unsigned long __ffs(unsigned long); - -#include #include +#include /* * hweightN: returns the hamming weight (i.e. the number * of bits set) of a N-bit word */ -extern unsigned long __arch_hweight64(__u64 w); -extern unsigned int __arch_hweight32(unsigned int w); -extern unsigned int __arch_hweight16(unsigned int w); -extern unsigned int __arch_hweight8(unsigned int w); +#ifdef ULTRA_HAS_POPULATION_COUNT + +static inline unsigned int __arch_hweight64(unsigned long w) +{ + unsigned int res; + + __asm__ ("popc %1,%0" : "=r" (res) : "r" (w)); + return res; +} + +static inline unsigned int __arch_hweight32(unsigned int w) +{ + unsigned int res; + + __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffffffff)); + return res; +} +static inline unsigned int __arch_hweight16(unsigned int w) +{ + unsigned int res; + + __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffff)); + return res; +} + +static inline unsigned int __arch_hweight8(unsigned int w) +{ + unsigned int res; + + __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xff)); + return res; +} + +#else + +#include + +#endif #include #include #endif /* __KERNEL__ */ diff --git a/arch/sparc/include/asm/elf_64.h b/arch/sparc/include/asm/elf_64.h index 7df8b7f544d4..e67880381b84 100644 --- a/arch/sparc/include/asm/elf_64.h +++ b/arch/sparc/include/asm/elf_64.h @@ -59,33 +59,15 @@ #define R_SPARC_6 45 /* Bits present in AT_HWCAP, primarily for Sparc32. */ -#define HWCAP_SPARC_FLUSH 0x00000001 -#define HWCAP_SPARC_STBAR 0x00000002 -#define HWCAP_SPARC_SWAP 0x00000004 -#define HWCAP_SPARC_MULDIV 0x00000008 -#define HWCAP_SPARC_V9 0x00000010 -#define HWCAP_SPARC_ULTRA3 0x00000020 -#define HWCAP_SPARC_BLKINIT 0x00000040 -#define HWCAP_SPARC_N2 0x00000080 - -/* Solaris compatible AT_HWCAP bits. */ -#define AV_SPARC_MUL32 0x00000100 /* 32x32 multiply is efficient */ -#define AV_SPARC_DIV32 0x00000200 /* 32x32 divide is efficient */ -#define AV_SPARC_FSMULD 0x00000400 /* 'fsmuld' is efficient */ -#define AV_SPARC_V8PLUS 0x00000800 /* v9 insn available to 32bit */ -#define AV_SPARC_POPC 0x00001000 /* 'popc' is efficient */ -#define AV_SPARC_VIS 0x00002000 /* VIS insns available */ -#define AV_SPARC_VIS2 0x00004000 /* VIS2 insns available */ -#define AV_SPARC_ASI_BLK_INIT 0x00008000 /* block init ASIs available */ -#define AV_SPARC_FMAF 0x00010000 /* fused multiply-add */ -#define AV_SPARC_VIS3 0x00020000 /* VIS3 insns available */ -#define AV_SPARC_HPC 0x00040000 /* HPC insns available */ -#define AV_SPARC_RANDOM 0x00080000 /* 'random' insn available */ -#define AV_SPARC_TRANS 0x00100000 /* transaction insns available */ -#define AV_SPARC_FJFMAU 0x00200000 /* unfused multiply-add */ -#define AV_SPARC_IMA 0x00400000 /* integer multiply-add */ -#define AV_SPARC_ASI_CACHE_SPARING \ - 0x00800000 /* cache sparing ASIs available */ + +#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */ +#define HWCAP_SPARC_STBAR 2 +#define HWCAP_SPARC_SWAP 4 +#define HWCAP_SPARC_MULDIV 8 +#define HWCAP_SPARC_V9 16 +#define HWCAP_SPARC_ULTRA3 32 +#define HWCAP_SPARC_BLKINIT 64 +#define HWCAP_SPARC_N2 128 #define CORE_DUMP_USE_REGSET @@ -180,8 +162,31 @@ typedef struct { #define ELF_ET_DYN_BASE 0x0000010000000000UL #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL -extern unsigned long sparc64_elf_hwcap; -#define ELF_HWCAP sparc64_elf_hwcap + +/* This yields a mask that user programs can use to figure out what + instruction set this cpu supports. */ + +/* On Ultra, we support all of the v8 capabilities. */ +static inline unsigned int sparc64_elf_hwcap(void) +{ + unsigned int cap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | + HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV | + HWCAP_SPARC_V9); + + if (tlb_type == cheetah || tlb_type == cheetah_plus) + cap |= HWCAP_SPARC_ULTRA3; + else if (tlb_type == hypervisor) { + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || + sun4v_chip_type == SUN4V_CHIP_NIAGARA2) + cap |= HWCAP_SPARC_BLKINIT; + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2) + cap |= HWCAP_SPARC_N2; + } + + return cap; +} + +#define ELF_HWCAP sparc64_elf_hwcap(); /* This yields a string that ld.so will use to load implementation specific libraries for optimization. This is more specific in diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hugetlb.h index f368cef0379a..177061064ee6 100644 --- a/arch/sparc/include/asm/hugetlb.h +++ b/arch/sparc/include/asm/hugetlb.h @@ -58,20 +58,14 @@ static inline pte_t huge_pte_wrprotect(pte_t pte) static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - pte_t old_pte = *ptep; - set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); + ptep_set_wrprotect(mm, addr, ptep); } static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte, int dirty) { - int changed = !pte_same(*ptep, pte); - if (changed) { - set_huge_pte_at(vma->vm_mm, addr, ptep, pte); - flush_tlb_page(vma, addr); - } - return changed; + return ptep_set_access_flags(vma, addr, ptep, pte, dirty); } static inline pte_t huge_ptep_get(pte_t *ptep) diff --git a/arch/sparc/include/asm/hypervisor.h b/arch/sparc/include/asm/hypervisor.h index 015a761eaa32..75686409be24 100644 --- a/arch/sparc/include/asm/hypervisor.h +++ b/arch/sparc/include/asm/hypervisor.h @@ -2927,13 +2927,6 @@ extern unsigned long sun4v_ncs_request(unsigned long request, #define HV_FAST_FIRE_GET_PERFREG 0x120 #define HV_FAST_FIRE_SET_PERFREG 0x121 -#define HV_FAST_REBOOT_DATA_SET 0x172 - -#ifndef __ASSEMBLY__ -extern unsigned long sun4v_reboot_data_set(unsigned long ra, - unsigned long len); -#endif - /* Function numbers for HV_CORE_TRAP. */ #define HV_CORE_SET_VER 0x00 #define HV_CORE_PUTCHAR 0x01 @@ -2947,23 +2940,16 @@ extern unsigned long sun4v_reboot_data_set(unsigned long ra, #define HV_GRP_CORE 0x0001 #define HV_GRP_INTR 0x0002 #define HV_GRP_SOFT_STATE 0x0003 -#define HV_GRP_TM 0x0080 #define HV_GRP_PCI 0x0100 #define HV_GRP_LDOM 0x0101 #define HV_GRP_SVC_CHAN 0x0102 #define HV_GRP_NCS 0x0103 #define HV_GRP_RNG 0x0104 -#define HV_GRP_PBOOT 0x0105 -#define HV_GRP_TPM 0x0107 -#define HV_GRP_SDIO 0x0108 -#define HV_GRP_SDIO_ERR 0x0109 -#define HV_GRP_REBOOT_DATA 0x0110 #define HV_GRP_NIAG_PERF 0x0200 #define HV_GRP_FIRE_PERF 0x0201 #define HV_GRP_N2_CPU 0x0202 #define HV_GRP_NIU 0x0204 #define HV_GRP_VF_CPU 0x0205 -#define HV_GRP_KT_CPU 0x0209 #define HV_GRP_DIAG 0x0300 #ifndef __ASSEMBLY__ diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h index a790cc657476..5b31a8e89823 100644 --- a/arch/sparc/include/asm/pgtable_32.h +++ b/arch/sparc/include/asm/pgtable_32.h @@ -431,6 +431,10 @@ extern unsigned long *sparc_valid_addr_bitmap; #define kern_addr_valid(addr) \ (test_bit(__pa((unsigned long)(addr))>>20, sparc_valid_addr_bitmap)) +extern int io_remap_pfn_range(struct vm_area_struct *vma, + unsigned long from, unsigned long pfn, + unsigned long size, pgprot_t prot); + /* * For sparc32&64, the pfn in io_remap_pfn_range() carries in * its high 4 bits. These macros/functions put it there or get it from there. @@ -439,22 +443,6 @@ extern unsigned long *sparc_valid_addr_bitmap; #define GET_IOSPACE(pfn) (pfn >> (BITS_PER_LONG - 4)) #define GET_PFN(pfn) (pfn & 0x0fffffffUL) -extern int remap_pfn_range(struct vm_area_struct *, unsigned long, unsigned long, - unsigned long, pgprot_t); - -static inline int io_remap_pfn_range(struct vm_area_struct *vma, - unsigned long from, unsigned long pfn, - unsigned long size, pgprot_t prot) -{ - unsigned long long offset, space, phys_base; - - offset = ((unsigned long long) GET_PFN(pfn)) << PAGE_SHIFT; - space = GET_IOSPACE(pfn); - phys_base = offset | (space << 32ULL); - - return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot); -} - #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \ ({ \ diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 982262804237..1e03c5a6b4f7 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h @@ -750,6 +750,10 @@ static inline bool kern_addr_valid(unsigned long addr) extern int page_in_phys_avail(unsigned long paddr); +extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, + unsigned long pfn, + unsigned long size, pgprot_t prot); + /* * For sparc32&64, the pfn in io_remap_pfn_range() carries in * its high 4 bits. These macros/functions put it there or get it from there. @@ -758,22 +762,6 @@ extern int page_in_phys_avail(unsigned long paddr); #define GET_IOSPACE(pfn) (pfn >> (BITS_PER_LONG - 4)) #define GET_PFN(pfn) (pfn & 0x0fffffffffffffffUL) -extern int remap_pfn_range(struct vm_area_struct *, unsigned long, unsigned long, - unsigned long, pgprot_t); - -static inline int io_remap_pfn_range(struct vm_area_struct *vma, - unsigned long from, unsigned long pfn, - unsigned long size, pgprot_t prot) -{ - unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT; - int space = GET_IOSPACE(pfn); - unsigned long phys_base; - - phys_base = offset | (((unsigned long) space) << 32UL); - - return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot); -} - #include /* We provide our own get_unmapped_area to cope with VA holes and diff --git a/arch/sparc/include/asm/sigcontext.h b/arch/sparc/include/asm/sigcontext.h index 69914d748130..a1607d180354 100644 --- a/arch/sparc/include/asm/sigcontext.h +++ b/arch/sparc/include/asm/sigcontext.h @@ -45,19 +45,6 @@ typedef struct { int si_mask; } __siginfo32_t; -#define __SIGC_MAXWIN 7 - -typedef struct { - unsigned long locals[8]; - unsigned long ins[8]; -} __siginfo_reg_window; - -typedef struct { - int wsaved; - __siginfo_reg_window reg_window[__SIGC_MAXWIN]; - unsigned long rwbuf_stkptrs[__SIGC_MAXWIN]; -} __siginfo_rwin_t; - #ifdef CONFIG_SPARC64 typedef struct { unsigned int si_float_regs [64]; @@ -86,7 +73,6 @@ struct sigcontext { unsigned long ss_size; } sigc_stack; unsigned long sigc_mask; - __siginfo_rwin_t * sigc_rwin_save; }; #else diff --git a/arch/sparc/include/asm/spinlock_32.h b/arch/sparc/include/asm/spinlock_32.h index bcc98fc35281..5f5b8bf3f50d 100644 --- a/arch/sparc/include/asm/spinlock_32.h +++ b/arch/sparc/include/asm/spinlock_32.h @@ -131,15 +131,6 @@ static inline void arch_write_lock(arch_rwlock_t *rw) *(volatile __u32 *)&lp->lock = ~0U; } -static void inline arch_write_unlock(arch_rwlock_t *lock) -{ - __asm__ __volatile__( -" st %%g0, [%0]" - : /* no outputs */ - : "r" (lock) - : "memory"); -} - static inline int arch_write_trylock(arch_rwlock_t *rw) { unsigned int val; @@ -184,6 +175,8 @@ static inline int __arch_read_trylock(arch_rwlock_t *rw) res; \ }) +#define arch_write_unlock(rw) do { (rw)->lock = 0; } while(0) + #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) #define arch_read_lock_flags(rw, flags) arch_read_lock(rw) #define arch_write_lock_flags(rw, flags) arch_write_lock(rw) diff --git a/arch/sparc/include/asm/spinlock_64.h b/arch/sparc/include/asm/spinlock_64.h index 968917694978..073936a8b275 100644 --- a/arch/sparc/include/asm/spinlock_64.h +++ b/arch/sparc/include/asm/spinlock_64.h @@ -210,8 +210,14 @@ static int inline arch_write_trylock(arch_rwlock_t *lock) return result; } +#define arch_read_lock(p) arch_read_lock(p) #define arch_read_lock_flags(p, f) arch_read_lock(p) +#define arch_read_trylock(p) arch_read_trylock(p) +#define arch_read_unlock(p) arch_read_unlock(p) +#define arch_write_lock(p) arch_write_lock(p) #define arch_write_lock_flags(p, f) arch_write_lock(p) +#define arch_write_unlock(p) arch_write_unlock(p) +#define arch_write_trylock(p) arch_write_trylock(p) #define arch_read_can_lock(rw) (!((rw)->lock & 0x80000000UL)) #define arch_write_can_lock(rw) (!(rw)->lock) diff --git a/arch/sparc/include/asm/spitfire.h b/arch/sparc/include/asm/spitfire.h index 55a17c6efeb8..f0d0c40c44da 100644 --- a/arch/sparc/include/asm/spitfire.h +++ b/arch/sparc/include/asm/spitfire.h @@ -42,7 +42,6 @@ #define SUN4V_CHIP_INVALID 0x00 #define SUN4V_CHIP_NIAGARA1 0x01 #define SUN4V_CHIP_NIAGARA2 0x02 -#define SUN4V_CHIP_NIAGARA3 0x03 #define SUN4V_CHIP_UNKNOWN 0xff #ifndef __ASSEMBLY__ diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h index 1a8afd1ad04f..83c571d8c8a7 100644 --- a/arch/sparc/include/asm/tsb.h +++ b/arch/sparc/include/asm/tsb.h @@ -133,6 +133,29 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; sub TSB, 0x8, TSB; \ TSB_STORE(TSB, TAG); +#define KTSB_LOAD_QUAD(TSB, REG) \ + ldda [TSB] ASI_NUCLEUS_QUAD_LDD, REG; + +#define KTSB_STORE(ADDR, VAL) \ + stxa VAL, [ADDR] ASI_N; + +#define KTSB_LOCK_TAG(TSB, REG1, REG2) \ +99: lduwa [TSB] ASI_N, REG1; \ + sethi %hi(TSB_TAG_LOCK_HIGH), REG2;\ + andcc REG1, REG2, %g0; \ + bne,pn %icc, 99b; \ + nop; \ + casa [TSB] ASI_N, REG1, REG2;\ + cmp REG1, REG2; \ + bne,pn %icc, 99b; \ + nop; \ + +#define KTSB_WRITE(TSB, TTE, TAG) \ + add TSB, 0x8, TSB; \ + stxa TTE, [TSB] ASI_N; \ + sub TSB, 0x8, TSB; \ + stxa TAG, [TSB] ASI_N; + /* Do a kernel page table walk. Leaves physical PTE pointer in * REG1. Jumps to FAIL_LABEL on early page table walk termination. * VADDR will not be clobbered, but REG2 will. @@ -216,8 +239,6 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; (KERNEL_TSB_SIZE_BYTES / 16) #define KERNEL_TSB4M_NENTRIES 4096 -#define KTSB_PHYS_SHIFT 15 - /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL * on TSB hit. REG1, REG2, REG3, and REG4 are used as temporaries * and the found TTE will be left in REG1. REG3 and REG4 must @@ -226,22 +247,13 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; * VADDR and TAG will be preserved and not clobbered by this macro. */ #define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ -661: sethi %hi(swapper_tsb), REG1; \ + sethi %hi(swapper_tsb), REG1; \ or REG1, %lo(swapper_tsb), REG1; \ - .section .swapper_tsb_phys_patch, "ax"; \ - .word 661b; \ - .previous; \ -661: nop; \ - .section .tsb_ldquad_phys_patch, "ax"; \ - .word 661b; \ - sllx REG1, KTSB_PHYS_SHIFT, REG1; \ - sllx REG1, KTSB_PHYS_SHIFT, REG1; \ - .previous; \ srlx VADDR, PAGE_SHIFT, REG2; \ and REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \ sllx REG2, 4, REG2; \ add REG1, REG2, REG2; \ - TSB_LOAD_QUAD(REG2, REG3); \ + KTSB_LOAD_QUAD(REG2, REG3); \ cmp REG3, TAG; \ be,a,pt %xcc, OK_LABEL; \ mov REG4, REG1; @@ -251,21 +263,12 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; * we can make use of that for the index computation. */ #define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ -661: sethi %hi(swapper_4m_tsb), REG1; \ + sethi %hi(swapper_4m_tsb), REG1; \ or REG1, %lo(swapper_4m_tsb), REG1; \ - .section .swapper_4m_tsb_phys_patch, "ax"; \ - .word 661b; \ - .previous; \ -661: nop; \ - .section .tsb_ldquad_phys_patch, "ax"; \ - .word 661b; \ - sllx REG1, KTSB_PHYS_SHIFT, REG1; \ - sllx REG1, KTSB_PHYS_SHIFT, REG1; \ - .previous; \ and TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \ sllx REG2, 4, REG2; \ add REG1, REG2, REG2; \ - TSB_LOAD_QUAD(REG2, REG3); \ + KTSB_LOAD_QUAD(REG2, REG3); \ cmp REG3, TAG; \ be,a,pt %xcc, OK_LABEL; \ mov REG4, REG1; diff --git a/arch/sparc/include/asm/xor_64.h b/arch/sparc/include/asm/xor_64.h index 9ed6ff679ab7..bee4bf4be3af 100644 --- a/arch/sparc/include/asm/xor_64.h +++ b/arch/sparc/include/asm/xor_64.h @@ -65,7 +65,6 @@ static struct xor_block_template xor_block_niagara = { #define XOR_SELECT_TEMPLATE(FASTEST) \ ((tlb_type == hypervisor && \ (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || \ - sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || \ - sun4v_chip_type == SUN4V_CHIP_NIAGARA3)) ? \ + sun4v_chip_type == SUN4V_CHIP_NIAGARA2)) ? \ &xor_block_niagara : \ &xor_block_VIS) diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index cb85458f89d2..b90b4a1d070a 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -32,7 +32,6 @@ obj-$(CONFIG_SPARC32) += sun4m_irq.o sun4c_irq.o sun4d_irq.o obj-y += process_$(BITS).o obj-y += signal_$(BITS).o -obj-y += sigutil_$(BITS).o obj-$(CONFIG_SPARC32) += ioport.o obj-y += setup_$(BITS).o obj-y += idprom.o diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index f5ddc0bae38d..7eef3f741963 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -268,4 +268,4 @@ static int __init sunfire_init(void) return 0; } -fs_initcall(sunfire_init); +subsys_initcall(sunfire_init); diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c index 9810fd881058..138dbbc8dc84 100644 --- a/arch/sparc/kernel/cpu.c +++ b/arch/sparc/kernel/cpu.c @@ -396,7 +396,6 @@ static int show_cpuinfo(struct seq_file *m, void *__unused) , cpu_data(0).clock_tick #endif ); - cpucap_info(m); #ifdef CONFIG_SMP smp_bogo(m); #endif @@ -475,18 +474,11 @@ static void __init sun4v_cpu_probe(void) sparc_pmu_type = "niagara2"; break; - case SUN4V_CHIP_NIAGARA3: - sparc_cpu_type = "UltraSparc T3 (Niagara3)"; - sparc_fpu_type = "UltraSparc T3 integrated FPU"; - sparc_pmu_type = "niagara3"; - break; - default: printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n", prom_cpu_compatible); sparc_cpu_type = "Unknown SUN4V CPU"; sparc_fpu_type = "Unknown SUN4V FPU"; - sparc_pmu_type = "Unknown SUN4V PMU"; break; } } diff --git a/arch/sparc/kernel/cpumap.c b/arch/sparc/kernel/cpumap.c index 4197e8d62d4c..d91fd782743a 100644 --- a/arch/sparc/kernel/cpumap.c +++ b/arch/sparc/kernel/cpumap.c @@ -324,7 +324,6 @@ static int iterate_cpu(struct cpuinfo_tree *t, unsigned int root_index) switch (sun4v_chip_type) { case SUN4V_CHIP_NIAGARA1: case SUN4V_CHIP_NIAGARA2: - case SUN4V_CHIP_NIAGARA3: rover_inc_table = niagara_iterate_method; break; default: diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index dcae702fc1f3..dd1342c0a3be 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c @@ -15,15 +15,12 @@ #include #include -#include #include #include #include #include #include -#include "kernel.h" - #define DRV_MODULE_NAME "ds" #define PFX DRV_MODULE_NAME ": " #define DRV_MODULE_VERSION "1.0" @@ -831,32 +828,18 @@ void ldom_set_var(const char *var, const char *value) } } -static char full_boot_str[256] __attribute__((aligned(32))); -static int reboot_data_supported; - void ldom_reboot(const char *boot_command) { /* Don't bother with any of this if the boot_command * is empty. */ if (boot_command && strlen(boot_command)) { - unsigned long len; + char full_boot_str[256]; strcpy(full_boot_str, "boot "); strcpy(full_boot_str + strlen("boot "), boot_command); - len = strlen(full_boot_str); - if (reboot_data_supported) { - unsigned long ra = kimage_addr_to_ra(full_boot_str); - unsigned long hv_ret; - - hv_ret = sun4v_reboot_data_set(ra, len); - if (hv_ret != HV_EOK) - pr_err("SUN4V: Unable to set reboot data " - "hv_ret=%lu\n", hv_ret); - } else { - ldom_set_var("reboot-command", full_boot_str); - } + ldom_set_var("reboot-command", full_boot_str); } sun4v_mach_sir(); } @@ -1254,19 +1237,9 @@ static struct vio_driver ds_driver = { static int __init ds_init(void) { - unsigned long hv_ret, major, minor; - - if (tlb_type == hypervisor) { - hv_ret = sun4v_get_version(HV_GRP_REBOOT_DATA, &major, &minor); - if (hv_ret == HV_EOK) { - pr_info("SUN4V: Reboot data supported (maj=%lu,min=%lu).\n", - major, minor); - reboot_data_supported = 1; - } - } kthread_run(ds_thread, NULL, "kldomd"); return vio_register_driver(&ds_driver); } -fs_initcall(ds_init); +subsys_initcall(ds_init); diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h index 0c218e4c0881..d1f1361c4167 100644 --- a/arch/sparc/kernel/entry.h +++ b/arch/sparc/kernel/entry.h @@ -42,28 +42,7 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr, extern void fpload(unsigned long *fpregs, unsigned long *fsr); #else /* CONFIG_SPARC32 */ - -#include - -struct popc_3insn_patch_entry { - unsigned int addr; - unsigned int insns[3]; -}; -extern struct popc_3insn_patch_entry __popc_3insn_patch, - __popc_3insn_patch_end; - -struct popc_6insn_patch_entry { - unsigned int addr; - unsigned int insns[6]; -}; -extern struct popc_6insn_patch_entry __popc_6insn_patch, - __popc_6insn_patch_end; - extern void __init per_cpu_patch(void); -extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, - struct sun4v_1insn_patch_entry *); -extern void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *, - struct sun4v_2insn_patch_entry *); extern void __init sun4v_patch(void); extern void __init boot_cpu_id_too_large(int cpu); extern unsigned int dcache_parity_tl1_occurred; diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S index 0cbab31d3ec9..aa594c792d19 100644 --- a/arch/sparc/kernel/head_64.S +++ b/arch/sparc/kernel/head_64.S @@ -132,8 +132,6 @@ prom_sun4v_name: .asciz "sun4v" prom_niagara_prefix: .asciz "SUNW,UltraSPARC-T" -prom_sparc_prefix: - .asciz "SPARC-T" .align 4 prom_root_compatible: .skip 64 @@ -381,22 +379,6 @@ sun4v_chip_type: sethi %hi(prom_niagara_prefix), %g7 or %g7, %lo(prom_niagara_prefix), %g7 mov 17, %g3 -90: ldub [%g7], %g2 - ldub [%g1], %g4 - cmp %g2, %g4 - bne,pn %icc, 89f - add %g7, 1, %g7 - subcc %g3, 1, %g3 - bne,pt %xcc, 90b - add %g1, 1, %g1 - ba,pt %xcc, 91f - nop - -89: sethi %hi(prom_cpu_compatible), %g1 - or %g1, %lo(prom_cpu_compatible), %g1 - sethi %hi(prom_sparc_prefix), %g7 - or %g7, %lo(prom_sparc_prefix), %g7 - mov 7, %g3 90: ldub [%g7], %g2 ldub [%g1], %g4 cmp %g2, %g4 @@ -407,15 +389,6 @@ sun4v_chip_type: add %g1, 1, %g1 sethi %hi(prom_cpu_compatible), %g1 - or %g1, %lo(prom_cpu_compatible), %g1 - ldub [%g1 + 7], %g2 - cmp %g2, '3' - be,pt %xcc, 5f - mov SUN4V_CHIP_NIAGARA3, %g4 - ba,pt %xcc, 4f - nop - -91: sethi %hi(prom_cpu_compatible), %g1 or %g1, %lo(prom_cpu_compatible), %g1 ldub [%g1 + 17], %g2 cmp %g2, '1' @@ -424,7 +397,6 @@ sun4v_chip_type: cmp %g2, '2' be,pt %xcc, 5f mov SUN4V_CHIP_NIAGARA2, %g4 - 4: mov SUN4V_CHIP_UNKNOWN, %g4 5: sethi %hi(sun4v_chip_type), %g2 @@ -542,9 +514,6 @@ niagara_tlb_fixup: cmp %g1, SUN4V_CHIP_NIAGARA2 be,pt %xcc, niagara2_patch nop - cmp %g1, SUN4V_CHIP_NIAGARA3 - be,pt %xcc, niagara2_patch - nop call generic_patch_copyops nop @@ -559,7 +528,7 @@ niagara2_patch: nop call niagara_patch_bzero nop - call niagara_patch_pageops + call niagara2_patch_pageops nop ba,a,pt %xcc, 80f diff --git a/arch/sparc/kernel/hvapi.c b/arch/sparc/kernel/hvapi.c index c2d055d8ba9e..7c60afb835b0 100644 --- a/arch/sparc/kernel/hvapi.c +++ b/arch/sparc/kernel/hvapi.c @@ -28,23 +28,16 @@ static struct api_info api_table[] = { { .group = HV_GRP_CORE, .flags = FLAG_PRE_API }, { .group = HV_GRP_INTR, }, { .group = HV_GRP_SOFT_STATE, }, - { .group = HV_GRP_TM, }, { .group = HV_GRP_PCI, .flags = FLAG_PRE_API }, { .group = HV_GRP_LDOM, }, { .group = HV_GRP_SVC_CHAN, .flags = FLAG_PRE_API }, { .group = HV_GRP_NCS, .flags = FLAG_PRE_API }, { .group = HV_GRP_RNG, }, - { .group = HV_GRP_PBOOT, }, - { .group = HV_GRP_TPM, }, - { .group = HV_GRP_SDIO, }, - { .group = HV_GRP_SDIO_ERR, }, - { .group = HV_GRP_REBOOT_DATA, }, { .group = HV_GRP_NIAG_PERF, .flags = FLAG_PRE_API }, { .group = HV_GRP_FIRE_PERF, }, { .group = HV_GRP_N2_CPU, }, { .group = HV_GRP_NIU, }, { .group = HV_GRP_VF_CPU, }, - { .group = HV_GRP_KT_CPU, }, { .group = HV_GRP_DIAG, .flags = FLAG_PRE_API }, }; diff --git a/arch/sparc/kernel/hvcalls.S b/arch/sparc/kernel/hvcalls.S index 58d60de4d65b..8a5f35ffb15e 100644 --- a/arch/sparc/kernel/hvcalls.S +++ b/arch/sparc/kernel/hvcalls.S @@ -798,10 +798,3 @@ ENTRY(sun4v_niagara2_setperf) retl nop ENDPROC(sun4v_niagara2_setperf) - -ENTRY(sun4v_reboot_data_set) - mov HV_FAST_REBOOT_DATA_SET, %o5 - ta HV_FAST_TRAP - retl - nop -ENDPROC(sun4v_reboot_data_set) diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h index 42851122bbd9..100b9c204e78 100644 --- a/arch/sparc/kernel/irq.h +++ b/arch/sparc/kernel/irq.h @@ -88,7 +88,7 @@ BTFIXUPDEF_CALL(void, set_irq_udt, int) #define set_irq_udt(cpu) BTFIXUP_CALL(set_irq_udt)(cpu) /* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */ -#define SUN4D_IPI_IRQ 13 +#define SUN4D_IPI_IRQ 14 extern void sun4d_ipi_interrupt(void); diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index fd6c36b1df74..6f6544cfa0ef 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h @@ -4,27 +4,12 @@ #include #include -#include -#include /* cpu.c */ extern const char *sparc_pmu_type; extern unsigned int fsr_storage; extern int ncpus_probed; -#ifdef CONFIG_SPARC64 -/* setup_64.c */ -struct seq_file; -extern void cpucap_info(struct seq_file *); - -static inline unsigned long kimage_addr_to_ra(const char *p) -{ - unsigned long val = (unsigned long) p; - - return kern_base + (val - KERNBASE); -} -#endif - #ifdef CONFIG_SPARC32 /* cpu.c */ extern void cpu_probe(void); diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S index 79f310364849..1d361477d7d6 100644 --- a/arch/sparc/kernel/ktlb.S +++ b/arch/sparc/kernel/ktlb.S @@ -47,16 +47,16 @@ kvmap_itlb_tsb_miss: kvmap_itlb_vmalloc_addr: KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_itlb_longpath) - TSB_LOCK_TAG(%g1, %g2, %g7) + KTSB_LOCK_TAG(%g1, %g2, %g7) /* Load and check PTE. */ ldxa [%g5] ASI_PHYS_USE_EC, %g5 mov 1, %g7 sllx %g7, TSB_TAG_INVALID_BIT, %g7 brgez,a,pn %g5, kvmap_itlb_longpath - TSB_STORE(%g1, %g7) + KTSB_STORE(%g1, %g7) - TSB_WRITE(%g1, %g5, %g6) + KTSB_WRITE(%g1, %g5, %g6) /* fallthrough to TLB load */ @@ -102,9 +102,9 @@ kvmap_itlb_longpath: kvmap_itlb_obp: OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_itlb_longpath) - TSB_LOCK_TAG(%g1, %g2, %g7) + KTSB_LOCK_TAG(%g1, %g2, %g7) - TSB_WRITE(%g1, %g5, %g6) + KTSB_WRITE(%g1, %g5, %g6) ba,pt %xcc, kvmap_itlb_load nop @@ -112,17 +112,17 @@ kvmap_itlb_obp: kvmap_dtlb_obp: OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_dtlb_longpath) - TSB_LOCK_TAG(%g1, %g2, %g7) + KTSB_LOCK_TAG(%g1, %g2, %g7) - TSB_WRITE(%g1, %g5, %g6) + KTSB_WRITE(%g1, %g5, %g6) ba,pt %xcc, kvmap_dtlb_load nop .align 32 kvmap_dtlb_tsb4m_load: - TSB_LOCK_TAG(%g1, %g2, %g7) - TSB_WRITE(%g1, %g5, %g6) + KTSB_LOCK_TAG(%g1, %g2, %g7) + KTSB_WRITE(%g1, %g5, %g6) ba,pt %xcc, kvmap_dtlb_load nop @@ -222,16 +222,16 @@ kvmap_linear_patch: kvmap_dtlb_vmalloc_addr: KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_dtlb_longpath) - TSB_LOCK_TAG(%g1, %g2, %g7) + KTSB_LOCK_TAG(%g1, %g2, %g7) /* Load and check PTE. */ ldxa [%g5] ASI_PHYS_USE_EC, %g5 mov 1, %g7 sllx %g7, TSB_TAG_INVALID_BIT, %g7 brgez,a,pn %g5, kvmap_dtlb_longpath - TSB_STORE(%g1, %g7) + KTSB_STORE(%g1, %g7) - TSB_WRITE(%g1, %g5, %g6) + KTSB_WRITE(%g1, %g5, %g6) /* fallthrough to TLB load */ diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index acaebb63c4fd..42f28c7420e1 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c @@ -508,8 +508,6 @@ const char *mdesc_node_name(struct mdesc_handle *hp, u64 node) } EXPORT_SYMBOL(mdesc_node_name); -static u64 max_cpus = 64; - static void __init report_platform_properties(void) { struct mdesc_handle *hp = mdesc_grab(); @@ -545,10 +543,8 @@ static void __init report_platform_properties(void) if (v) printk("PLATFORM: watchdog-max-timeout [%llu ms]\n", *v); v = mdesc_get_property(hp, pn, "max-cpus", NULL); - if (v) { - max_cpus = *v; - printk("PLATFORM: max-cpus [%llu]\n", max_cpus); - } + if (v) + printk("PLATFORM: max-cpus [%llu]\n", *v); #ifdef CONFIG_SMP { @@ -719,7 +715,7 @@ static void __cpuinit set_proc_ids(struct mdesc_handle *hp) } static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask, - unsigned long def, unsigned long max) + unsigned char def) { u64 val; @@ -730,9 +726,6 @@ static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask, if (!val || val >= 64) goto use_default; - if (val > max) - val = max; - *mask = ((1U << val) * 64U) - 1U; return; @@ -743,28 +736,19 @@ use_default: static void __cpuinit get_mondo_data(struct mdesc_handle *hp, u64 mp, struct trap_per_cpu *tb) { - static int printed; const u64 *val; val = mdesc_get_property(hp, mp, "q-cpu-mondo-#bits", NULL); - get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7, ilog2(max_cpus * 2)); + get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7); val = mdesc_get_property(hp, mp, "q-dev-mondo-#bits", NULL); - get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7, 8); + get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7); val = mdesc_get_property(hp, mp, "q-resumable-#bits", NULL); - get_one_mondo_bits(val, &tb->resum_qmask, 6, 7); + get_one_mondo_bits(val, &tb->resum_qmask, 6); val = mdesc_get_property(hp, mp, "q-nonresumable-#bits", NULL); - get_one_mondo_bits(val, &tb->nonresum_qmask, 2, 2); - if (!printed++) { - pr_info("SUN4V: Mondo queue sizes " - "[cpu(%u) dev(%u) r(%u) nr(%u)]\n", - tb->cpu_mondo_qmask + 1, - tb->dev_mondo_qmask + 1, - tb->resum_qmask + 1, - tb->nonresum_qmask + 1); - } + get_one_mondo_bits(val, &tb->nonresum_qmask, 2); } static void * __cpuinit mdesc_iterate_over_cpus(void *(*func)(struct mdesc_handle *, u64, int, void *), void *arg, cpumask_t *mask) diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c index 8172c18d844f..99ba5baa9497 100644 --- a/arch/sparc/kernel/module.c +++ b/arch/sparc/kernel/module.c @@ -17,8 +17,6 @@ #include #include -#include "entry.h" - #ifdef CONFIG_SPARC64 #include @@ -222,29 +220,6 @@ int apply_relocate_add(Elf_Shdr *sechdrs, } #ifdef CONFIG_SPARC64 -static void do_patch_sections(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs) -{ - const Elf_Shdr *s, *sun4v_1insn = NULL, *sun4v_2insn = NULL; - char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; - - for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { - if (!strcmp(".sun4v_1insn_patch", secstrings + s->sh_name)) - sun4v_1insn = s; - if (!strcmp(".sun4v_2insn_patch", secstrings + s->sh_name)) - sun4v_2insn = s; - } - - if (sun4v_1insn && tlb_type == hypervisor) { - void *p = (void *) sun4v_1insn->sh_addr; - sun4v_patch_1insn_range(p, p + sun4v_1insn->sh_size); - } - if (sun4v_2insn && tlb_type == hypervisor) { - void *p = (void *) sun4v_2insn->sh_addr; - sun4v_patch_2insn_range(p, p + sun4v_2insn->sh_size); - } -} - int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) @@ -252,8 +227,6 @@ int module_finalize(const Elf_Ehdr *hdr, /* make jump label nops */ jump_label_apply_nops(me); - do_patch_sections(hdr, sechdrs); - /* Cheetah's I-cache is fully coherent. */ if (tlb_type == spitfire) { unsigned long va; diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 9e73c4a37ae9..b01a06e9ae4e 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -848,10 +848,10 @@ static int pci_sun4v_msiq_build_irq(struct pci_pbm_info *pbm, if (!irq) return -ENOMEM; - if (pci_sun4v_msiq_setvalid(pbm->devhandle, msiqid, HV_MSIQ_VALID)) - return -EINVAL; if (pci_sun4v_msiq_setstate(pbm->devhandle, msiqid, HV_MSIQSTATE_IDLE)) return -EINVAL; + if (pci_sun4v_msiq_setvalid(pbm->devhandle, msiqid, HV_MSIQ_VALID)) + return -EINVAL; return irq; } diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index 6418ba6e7dd4..948601a066ff 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -352,8 +352,8 @@ int __init pcic_probe(void) strcpy(pbm->prom_name, namebuf); { - extern volatile int t_nmi[4]; - extern int pcic_nmi_trap_patch[4]; + extern volatile int t_nmi[1]; + extern int pcic_nmi_trap_patch[1]; t_nmi[0] = pcic_nmi_trap_patch[0]; t_nmi[1] = pcic_nmi_trap_patch[1]; diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c index 343b0f9e2e7b..8ac23e660080 100644 --- a/arch/sparc/kernel/pcr.c +++ b/arch/sparc/kernel/pcr.c @@ -80,11 +80,8 @@ static void n2_pcr_write(u64 val) { unsigned long ret; - if (val & PCR_N2_HTRACE) { - ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val); - if (ret != HV_EOK) - write_pcr(val); - } else + ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val); + if (ret != HV_EOK) write_pcr(val); } @@ -109,10 +106,6 @@ static int __init register_perf_hsvc(void) perf_hsvc_group = HV_GRP_N2_CPU; break; - case SUN4V_CHIP_NIAGARA3: - perf_hsvc_group = HV_GRP_KT_CPU; - break; - default: return -ENODEV; } diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 904ed639bc11..2cb0e1c001e2 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -513,13 +513,11 @@ static u64 nop_for_index(int idx) static inline void sparc_pmu_enable_event(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc, int idx) { - u64 enc, val, mask = mask_for_index(idx); - - enc = perf_event_get_enc(cpuc->events[idx]); + u64 val, mask = mask_for_index(idx); val = cpuc->pcr; val &= ~mask; - val |= event_encoding(enc, idx); + val |= hwc->config; cpuc->pcr = val; pcr_ops->write(cpuc->pcr); @@ -1303,8 +1301,7 @@ static bool __init supported_pmu(void) sparc_pmu = &niagara1_pmu; return true; } - if (!strcmp(sparc_pmu_type, "niagara2") || - !strcmp(sparc_pmu_type, "niagara3")) { + if (!strcmp(sparc_pmu_type, "niagara2")) { sparc_pmu = &niagara2_pmu; return true; } @@ -1382,6 +1379,8 @@ static void perf_callchain_user_64(struct perf_callchain_entry *entry, { unsigned long ufp; + perf_callchain_store(entry, regs->tpc); + ufp = regs->u_regs[UREG_I6] + STACK_BIAS; do { struct sparc_stackf *usf, sf; @@ -1402,6 +1401,8 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, { unsigned long ufp; + perf_callchain_store(entry, regs->tpc); + ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; do { struct sparc_stackf32 *usf, sf; @@ -1420,11 +1421,6 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, void perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) { - perf_callchain_store(entry, regs->tpc); - - if (!current->mm) - return; - flushw_user(); if (test_thread_flag(TIF_32BIT)) perf_callchain_user_32(entry, regs); diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S index 9171fc238def..77f1b95e0806 100644 --- a/arch/sparc/kernel/rtrap_64.S +++ b/arch/sparc/kernel/rtrap_64.S @@ -20,6 +20,11 @@ .text .align 32 +__handle_softirq: + call do_softirq + nop + ba,a,pt %xcc, __handle_softirq_continue + nop __handle_preemption: call schedule wrpr %g0, RTRAP_PSTATE, %pstate @@ -84,7 +89,9 @@ rtrap: cmp %l1, 0 /* mm/ultra.S:xcall_report_regs KNOWS about this load. */ + bne,pn %icc, __handle_softirq ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 +__handle_softirq_continue: rtrap_xcall: sethi %hi(0xf << 20), %l4 and %l1, %l4, %l4 diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 4e7d3ff0ccb4..c4dd0999da86 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -47,8 +46,6 @@ #include #include #include -#include -#include #ifdef CONFIG_IP_PNP #include @@ -234,88 +231,44 @@ void __init per_cpu_patch(void) } } -void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *start, - struct sun4v_1insn_patch_entry *end) +void __init sun4v_patch(void) { - while (start < end) { - unsigned long addr = start->addr; + extern void sun4v_hvapi_init(void); + struct sun4v_1insn_patch_entry *p1; + struct sun4v_2insn_patch_entry *p2; + + if (tlb_type != hypervisor) + return; - *(unsigned int *) (addr + 0) = start->insn; + p1 = &__sun4v_1insn_patch; + while (p1 < &__sun4v_1insn_patch_end) { + unsigned long addr = p1->addr; + + *(unsigned int *) (addr + 0) = p1->insn; wmb(); __asm__ __volatile__("flush %0" : : "r" (addr + 0)); - start++; + p1++; } -} -void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *start, - struct sun4v_2insn_patch_entry *end) -{ - while (start < end) { - unsigned long addr = start->addr; + p2 = &__sun4v_2insn_patch; + while (p2 < &__sun4v_2insn_patch_end) { + unsigned long addr = p2->addr; - *(unsigned int *) (addr + 0) = start->insns[0]; + *(unsigned int *) (addr + 0) = p2->insns[0]; wmb(); __asm__ __volatile__("flush %0" : : "r" (addr + 0)); - *(unsigned int *) (addr + 4) = start->insns[1]; + *(unsigned int *) (addr + 4) = p2->insns[1]; wmb(); __asm__ __volatile__("flush %0" : : "r" (addr + 4)); - start++; + p2++; } -} - -void __init sun4v_patch(void) -{ - extern void sun4v_hvapi_init(void); - - if (tlb_type != hypervisor) - return; - - sun4v_patch_1insn_range(&__sun4v_1insn_patch, - &__sun4v_1insn_patch_end); - - sun4v_patch_2insn_range(&__sun4v_2insn_patch, - &__sun4v_2insn_patch_end); sun4v_hvapi_init(); } -static void __init popc_patch(void) -{ - struct popc_3insn_patch_entry *p3; - struct popc_6insn_patch_entry *p6; - - p3 = &__popc_3insn_patch; - while (p3 < &__popc_3insn_patch_end) { - unsigned long i, addr = p3->addr; - - for (i = 0; i < 3; i++) { - *(unsigned int *) (addr + (i * 4)) = p3->insns[i]; - wmb(); - __asm__ __volatile__("flush %0" - : : "r" (addr + (i * 4))); - } - - p3++; - } - - p6 = &__popc_6insn_patch; - while (p6 < &__popc_6insn_patch_end) { - unsigned long i, addr = p6->addr; - - for (i = 0; i < 6; i++) { - *(unsigned int *) (addr + (i * 4)) = p6->insns[i]; - wmb(); - __asm__ __volatile__("flush %0" - : : "r" (addr + (i * 4))); - } - - p6++; - } -} - #ifdef CONFIG_SMP void __init boot_cpu_id_too_large(int cpu) { @@ -325,160 +278,6 @@ void __init boot_cpu_id_too_large(int cpu) } #endif -/* On Ultra, we support all of the v8 capabilities. */ -unsigned long sparc64_elf_hwcap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | - HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV | - HWCAP_SPARC_V9); -EXPORT_SYMBOL(sparc64_elf_hwcap); - -static const char *hwcaps[] = { - "flush", "stbar", "swap", "muldiv", "v9", - "ultra3", "blkinit", "n2", - - /* These strings are as they appear in the machine description - * 'hwcap-list' property for cpu nodes. - */ - "mul32", "div32", "fsmuld", "v8plus", "popc", "vis", "vis2", - "ASIBlkInit", "fmaf", "vis3", "hpc", "random", "trans", "fjfmau", - "ima", "cspare", -}; - -void cpucap_info(struct seq_file *m) -{ - unsigned long caps = sparc64_elf_hwcap; - int i, printed = 0; - - seq_puts(m, "cpucaps\t\t: "); - for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { - unsigned long bit = 1UL << i; - if (caps & bit) { - seq_printf(m, "%s%s", - printed ? "," : "", hwcaps[i]); - printed++; - } - } - seq_putc(m, '\n'); -} - -static void __init report_hwcaps(unsigned long caps) -{ - int i, printed = 0; - - printk(KERN_INFO "CPU CAPS: ["); - for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { - unsigned long bit = 1UL << i; - if (caps & bit) { - printk(KERN_CONT "%s%s", - printed ? "," : "", hwcaps[i]); - if (++printed == 8) { - printk(KERN_CONT "]\n"); - printk(KERN_INFO "CPU CAPS: ["); - printed = 0; - } - } - } - printk(KERN_CONT "]\n"); -} - -static unsigned long __init mdesc_cpu_hwcap_list(void) -{ - struct mdesc_handle *hp; - unsigned long caps = 0; - const char *prop; - int len; - u64 pn; - - hp = mdesc_grab(); - if (!hp) - return 0; - - pn = mdesc_node_by_name(hp, MDESC_NODE_NULL, "cpu"); - if (pn == MDESC_NODE_NULL) - goto out; - - prop = mdesc_get_property(hp, pn, "hwcap-list", &len); - if (!prop) - goto out; - - while (len) { - int i, plen; - - for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { - unsigned long bit = 1UL << i; - - if (!strcmp(prop, hwcaps[i])) { - caps |= bit; - break; - } - } - - plen = strlen(prop) + 1; - prop += plen; - len -= plen; - } - -out: - mdesc_release(hp); - return caps; -} - -/* This yields a mask that user programs can use to figure out what - * instruction set this cpu supports. - */ -static void __init init_sparc64_elf_hwcap(void) -{ - unsigned long cap = sparc64_elf_hwcap; - unsigned long mdesc_caps; - - if (tlb_type == cheetah || tlb_type == cheetah_plus) - cap |= HWCAP_SPARC_ULTRA3; - else if (tlb_type == hypervisor) { - if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || - sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || - sun4v_chip_type == SUN4V_CHIP_NIAGARA3) - cap |= HWCAP_SPARC_BLKINIT; - if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || - sun4v_chip_type == SUN4V_CHIP_NIAGARA3) - cap |= HWCAP_SPARC_N2; - } - - cap |= (AV_SPARC_MUL32 | AV_SPARC_DIV32 | AV_SPARC_V8PLUS); - - mdesc_caps = mdesc_cpu_hwcap_list(); - if (!mdesc_caps) { - if (tlb_type == spitfire) - cap |= AV_SPARC_VIS; - if (tlb_type == cheetah || tlb_type == cheetah_plus) - cap |= AV_SPARC_VIS | AV_SPARC_VIS2; - if (tlb_type == cheetah_plus) { - unsigned long impl, ver; - - __asm__ __volatile__("rdpr %%ver, %0" : "=r" (ver)); - impl = ((ver >> 32) & 0xffff); - if (impl == PANTHER_IMPL) - cap |= AV_SPARC_POPC; - } - if (tlb_type == hypervisor) { - if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1) - cap |= AV_SPARC_ASI_BLK_INIT; - if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || - sun4v_chip_type == SUN4V_CHIP_NIAGARA3) - cap |= (AV_SPARC_VIS | AV_SPARC_VIS2 | - AV_SPARC_ASI_BLK_INIT | - AV_SPARC_POPC); - if (sun4v_chip_type == SUN4V_CHIP_NIAGARA3) - cap |= (AV_SPARC_VIS3 | AV_SPARC_HPC | - AV_SPARC_FMAF); - } - } - sparc64_elf_hwcap = cap | mdesc_caps; - - report_hwcaps(sparc64_elf_hwcap); - - if (sparc64_elf_hwcap & AV_SPARC_POPC) - popc_patch(); -} - void __init setup_arch(char **cmdline_p) { /* Initialize PROM console and command line. */ @@ -538,7 +337,6 @@ void __init setup_arch(char **cmdline_p) init_cur_cpu_trap(current_thread_info()); paging_init(); - init_sparc64_elf_hwcap(); } extern int stop_a_enabled; diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index 2e58328c30e0..75fad425e249 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -29,8 +29,6 @@ #include #include -#include "sigutil.h" - #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) /* This magic should be in g_upper[0] for all upper parts @@ -46,14 +44,14 @@ typedef struct { struct signal_frame32 { struct sparc_stackf32 ss; __siginfo32_t info; - /* __siginfo_fpu_t * */ u32 fpu_save; + /* __siginfo_fpu32_t * */ u32 fpu_save; unsigned int insns[2]; unsigned int extramask[_COMPAT_NSIG_WORDS - 1]; unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */ /* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */ siginfo_extra_v8plus_t v8plus; - /* __siginfo_rwin_t * */u32 rwin_save; -} __attribute__((aligned(8))); + __siginfo_fpu_t fpu_state; +}; typedef struct compat_siginfo{ int si_signo; @@ -112,14 +110,18 @@ struct rt_signal_frame32 { compat_siginfo_t info; struct pt_regs32 regs; compat_sigset_t mask; - /* __siginfo_fpu_t * */ u32 fpu_save; + /* __siginfo_fpu32_t * */ u32 fpu_save; unsigned int insns[2]; stack_t32 stack; unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */ /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */ siginfo_extra_v8plus_t v8plus; - /* __siginfo_rwin_t * */u32 rwin_save; -} __attribute__((aligned(8))); + __siginfo_fpu_t fpu_state; +}; + +/* Align macros */ +#define SF_ALIGNEDSZ (((sizeof(struct signal_frame32) + 15) & (~15))) +#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 15) & (~15))) int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) { @@ -190,13 +192,30 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) return 0; } +static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) +{ + unsigned long *fpregs = current_thread_info()->fpregs; + unsigned long fprs; + int err; + + err = __get_user(fprs, &fpu->si_fprs); + fprs_write(0); + regs->tstate &= ~TSTATE_PEF; + if (fprs & FPRS_DL) + err |= copy_from_user(fpregs, &fpu->si_float_regs[0], (sizeof(unsigned int) * 32)); + if (fprs & FPRS_DU) + err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], (sizeof(unsigned int) * 32)); + err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr); + err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr); + current_thread_info()->fpsaved[0] |= fprs; + return err; +} + void do_sigreturn32(struct pt_regs *regs) { struct signal_frame32 __user *sf; - compat_uptr_t fpu_save; - compat_uptr_t rwin_save; unsigned int psr; - unsigned pc, npc; + unsigned pc, npc, fpu_save; sigset_t set; unsigned seta[_COMPAT_NSIG_WORDS]; int err, i; @@ -254,13 +273,8 @@ void do_sigreturn32(struct pt_regs *regs) pt_regs_clear_syscall(regs); err |= __get_user(fpu_save, &sf->fpu_save); - if (!err && fpu_save) - err |= restore_fpu_state(regs, compat_ptr(fpu_save)); - err |= __get_user(rwin_save, &sf->rwin_save); - if (!err && rwin_save) { - if (restore_rwin_state(compat_ptr(rwin_save))) - goto segv; - } + if (fpu_save) + err |= restore_fpu_state32(regs, &sf->fpu_state); err |= __get_user(seta[0], &sf->info.si_mask); err |= copy_from_user(seta+1, &sf->extramask, (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int)); @@ -286,9 +300,7 @@ segv: asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) { struct rt_signal_frame32 __user *sf; - unsigned int psr, pc, npc, u_ss_sp; - compat_uptr_t fpu_save; - compat_uptr_t rwin_save; + unsigned int psr, pc, npc, fpu_save, u_ss_sp; mm_segment_t old_fs; sigset_t set; compat_sigset_t seta; @@ -347,8 +359,8 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) pt_regs_clear_syscall(regs); err |= __get_user(fpu_save, &sf->fpu_save); - if (!err && fpu_save) - err |= restore_fpu_state(regs, compat_ptr(fpu_save)); + if (fpu_save) + err |= restore_fpu_state32(regs, &sf->fpu_state); err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t)); err |= __get_user(u_ss_sp, &sf->stack.ss_sp); st.ss_sp = compat_ptr(u_ss_sp); @@ -364,12 +376,6 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf); set_fs(old_fs); - err |= __get_user(rwin_save, &sf->rwin_save); - if (!err && rwin_save) { - if (restore_rwin_state(compat_ptr(rwin_save))) - goto segv; - } - switch (_NSIG_WORDS) { case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32); case 3: set.sig[2] = seta.sig[4] + (((long)seta.sig[5]) << 32); @@ -427,6 +433,26 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns return (void __user *) sp; } +static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) +{ + unsigned long *fpregs = current_thread_info()->fpregs; + unsigned long fprs; + int err = 0; + + fprs = current_thread_info()->fpsaved[0]; + if (fprs & FPRS_DL) + err |= copy_to_user(&fpu->si_float_regs[0], fpregs, + (sizeof(unsigned int) * 32)); + if (fprs & FPRS_DU) + err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16, + (sizeof(unsigned int) * 32)); + err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr); + err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr); + err |= __put_user(fprs, &fpu->si_fprs); + + return err; +} + /* The I-cache flush instruction only works in the primary ASI, which * right now is the nucleus, aka. kernel space. * @@ -489,23 +515,18 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset) { struct signal_frame32 __user *sf; - int i, err, wsaved; - void __user *tail; int sigframe_size; u32 psr; + int i, err; unsigned int seta[_COMPAT_NSIG_WORDS]; /* 1. Make sure everything is clean */ synchronize_user_stack(); save_and_clear_fpu(); - wsaved = get_thread_wsaved(); - - sigframe_size = sizeof(*sf); - if (current_thread_info()->fpsaved[0] & FPRS_FEF) - sigframe_size += sizeof(__siginfo_fpu_t); - if (wsaved) - sigframe_size += sizeof(__siginfo_rwin_t); + sigframe_size = SF_ALIGNEDSZ; + if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) + sigframe_size -= sizeof(__siginfo_fpu_t); sf = (struct signal_frame32 __user *) get_sigframe(&ka->sa, regs, sigframe_size); @@ -513,7 +534,8 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (invalid_frame_pointer(sf, sigframe_size)) goto sigill; - tail = (sf + 1); + if (get_thread_wsaved() != 0) + goto sigill; /* 2. Save the current process state */ if (test_thread_flag(TIF_32BIT)) { @@ -538,22 +560,11 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, &sf->v8plus.asi); if (psr & PSR_EF) { - __siginfo_fpu_t __user *fp = tail; - tail += sizeof(*fp); - err |= save_fpu_state(regs, fp); - err |= __put_user((u64)fp, &sf->fpu_save); + err |= save_fpu_state32(regs, &sf->fpu_state); + err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save); } else { err |= __put_user(0, &sf->fpu_save); } - if (wsaved) { - __siginfo_rwin_t __user *rwp = tail; - tail += sizeof(*rwp); - err |= save_rwin_state(wsaved, rwp); - err |= __put_user((u64)rwp, &sf->rwin_save); - set_thread_wsaved(0); - } else { - err |= __put_user(0, &sf->rwin_save); - } switch (_NSIG_WORDS) { case 4: seta[7] = (oldset->sig[3] >> 32); @@ -569,21 +580,10 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, err |= __copy_to_user(sf->extramask, seta + 1, (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int)); - if (!wsaved) { - err |= copy_in_user((u32 __user *)sf, - (u32 __user *)(regs->u_regs[UREG_FP]), - sizeof(struct reg_window32)); - } else { - struct reg_window *rp; - - rp = ¤t_thread_info()->reg_window[wsaved - 1]; - for (i = 0; i < 8; i++) - err |= __put_user(rp->locals[i], &sf->ss.locals[i]); - for (i = 0; i < 6; i++) - err |= __put_user(rp->ins[i], &sf->ss.ins[i]); - err |= __put_user(rp->ins[6], &sf->ss.fp); - err |= __put_user(rp->ins[7], &sf->ss.callers_pc); - } + err |= copy_in_user((u32 __user *)sf, + (u32 __user *)(regs->u_regs[UREG_FP]), + sizeof(struct reg_window32)); + if (err) goto sigsegv; @@ -613,6 +613,7 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/ if (err) goto sigsegv; + flush_signal_insns(address); } return 0; @@ -631,23 +632,18 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, siginfo_t *info) { struct rt_signal_frame32 __user *sf; - int i, err, wsaved; - void __user *tail; int sigframe_size; u32 psr; + int i, err; compat_sigset_t seta; /* 1. Make sure everything is clean */ synchronize_user_stack(); save_and_clear_fpu(); - wsaved = get_thread_wsaved(); - - sigframe_size = sizeof(*sf); - if (current_thread_info()->fpsaved[0] & FPRS_FEF) - sigframe_size += sizeof(__siginfo_fpu_t); - if (wsaved) - sigframe_size += sizeof(__siginfo_rwin_t); + sigframe_size = RT_ALIGNEDSZ; + if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) + sigframe_size -= sizeof(__siginfo_fpu_t); sf = (struct rt_signal_frame32 __user *) get_sigframe(&ka->sa, regs, sigframe_size); @@ -655,7 +651,8 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (invalid_frame_pointer(sf, sigframe_size)) goto sigill; - tail = (sf + 1); + if (get_thread_wsaved() != 0) + goto sigill; /* 2. Save the current process state */ if (test_thread_flag(TIF_32BIT)) { @@ -680,22 +677,11 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, &sf->v8plus.asi); if (psr & PSR_EF) { - __siginfo_fpu_t __user *fp = tail; - tail += sizeof(*fp); - err |= save_fpu_state(regs, fp); - err |= __put_user((u64)fp, &sf->fpu_save); + err |= save_fpu_state32(regs, &sf->fpu_state); + err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save); } else { err |= __put_user(0, &sf->fpu_save); } - if (wsaved) { - __siginfo_rwin_t __user *rwp = tail; - tail += sizeof(*rwp); - err |= save_rwin_state(wsaved, rwp); - err |= __put_user((u64)rwp, &sf->rwin_save); - set_thread_wsaved(0); - } else { - err |= __put_user(0, &sf->rwin_save); - } /* Update the siginfo structure. */ err |= copy_siginfo_to_user32(&sf->info, info); @@ -717,21 +703,9 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, } err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t)); - if (!wsaved) { - err |= copy_in_user((u32 __user *)sf, - (u32 __user *)(regs->u_regs[UREG_FP]), - sizeof(struct reg_window32)); - } else { - struct reg_window *rp; - - rp = ¤t_thread_info()->reg_window[wsaved - 1]; - for (i = 0; i < 8; i++) - err |= __put_user(rp->locals[i], &sf->ss.locals[i]); - for (i = 0; i < 6; i++) - err |= __put_user(rp->ins[i], &sf->ss.ins[i]); - err |= __put_user(rp->ins[6], &sf->ss.fp); - err |= __put_user(rp->ins[7], &sf->ss.callers_pc); - } + err |= copy_in_user((u32 __user *)sf, + (u32 __user *)(regs->u_regs[UREG_FP]), + sizeof(struct reg_window32)); if (err) goto sigsegv; @@ -829,23 +803,21 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. */ -void do_signal32(sigset_t *oldset, struct pt_regs * regs) +void do_signal32(sigset_t *oldset, struct pt_regs * regs, + int restart_syscall, unsigned long orig_i0) { struct k_sigaction ka; - unsigned long orig_i0; - int restart_syscall; siginfo_t info; int signr; signr = get_signal_to_deliver(&info, &ka, regs, NULL); - restart_syscall = 0; - orig_i0 = 0; - if (pt_regs_is_syscall(regs) && - (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { - restart_syscall = 1; - orig_i0 = regs->u_regs[UREG_G6]; - } + /* If the debugger messes with the program counter, it clears + * the "in syscall" bit, directing us to not perform a syscall + * restart. + */ + if (restart_syscall && !pt_regs_is_syscall(regs)) + restart_syscall = 0; if (signr > 0) { if (restart_syscall) diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 2302567578ba..5e5c5fd03783 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c @@ -26,8 +26,6 @@ #include #include /* flush_sig_insns */ -#include "sigutil.h" - #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) extern void fpsave(unsigned long *fpregs, unsigned long *fsr, @@ -41,8 +39,8 @@ struct signal_frame { unsigned long insns[2] __attribute__ ((aligned (8))); unsigned int extramask[_NSIG_WORDS - 1]; unsigned int extra_size; /* Should be 0 */ - __siginfo_rwin_t __user *rwin_save; -} __attribute__((aligned(8))); + __siginfo_fpu_t fpu_state; +}; struct rt_signal_frame { struct sparc_stackf ss; @@ -53,8 +51,8 @@ struct rt_signal_frame { unsigned int insns[2]; stack_t stack; unsigned int extra_size; /* Should be 0 */ - __siginfo_rwin_t __user *rwin_save; -} __attribute__((aligned(8))); + __siginfo_fpu_t fpu_state; +}; /* Align macros */ #define SF_ALIGNEDSZ (((sizeof(struct signal_frame) + 7) & (~7))) @@ -81,13 +79,43 @@ asmlinkage int sys_sigsuspend(old_sigset_t set) return _sigpause_common(set); } +static inline int +restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) +{ + int err; +#ifdef CONFIG_SMP + if (test_tsk_thread_flag(current, TIF_USEDFPU)) + regs->psr &= ~PSR_EF; +#else + if (current == last_task_used_math) { + last_task_used_math = NULL; + regs->psr &= ~PSR_EF; + } +#endif + set_used_math(); + clear_tsk_thread_flag(current, TIF_USEDFPU); + + if (!access_ok(VERIFY_READ, fpu, sizeof(*fpu))) + return -EFAULT; + + err = __copy_from_user(¤t->thread.float_regs[0], &fpu->si_float_regs[0], + (sizeof(unsigned long) * 32)); + err |= __get_user(current->thread.fsr, &fpu->si_fsr); + err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth); + if (current->thread.fpqdepth != 0) + err |= __copy_from_user(¤t->thread.fpqueue[0], + &fpu->si_fpqueue[0], + ((sizeof(unsigned long) + + (sizeof(unsigned long *)))*16)); + return err; +} + asmlinkage void do_sigreturn(struct pt_regs *regs) { struct signal_frame __user *sf; unsigned long up_psr, pc, npc; sigset_t set; __siginfo_fpu_t __user *fpu_save; - __siginfo_rwin_t __user *rwin_save; int err; /* Always make any pending restarted system calls return -EINTR */ @@ -122,11 +150,9 @@ asmlinkage void do_sigreturn(struct pt_regs *regs) pt_regs_clear_syscall(regs); err |= __get_user(fpu_save, &sf->fpu_save); + if (fpu_save) err |= restore_fpu_state(regs, fpu_save); - err |= __get_user(rwin_save, &sf->rwin_save); - if (rwin_save) - err |= restore_rwin_state(rwin_save); /* This is pretty much atomic, no amount locking would prevent * the races which exist anyways. @@ -154,7 +180,6 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) struct rt_signal_frame __user *sf; unsigned int psr, pc, npc; __siginfo_fpu_t __user *fpu_save; - __siginfo_rwin_t __user *rwin_save; mm_segment_t old_fs; sigset_t set; stack_t st; @@ -182,7 +207,8 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) pt_regs_clear_syscall(regs); err |= __get_user(fpu_save, &sf->fpu_save); - if (!err && fpu_save) + + if (fpu_save) err |= restore_fpu_state(regs, fpu_save); err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); @@ -202,12 +228,6 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) do_sigaltstack((const stack_t __user *) &st, NULL, (unsigned long)sf); set_fs(old_fs); - err |= __get_user(rwin_save, &sf->rwin_save); - if (!err && rwin_save) { - if (restore_rwin_state(rwin_save)) - goto segv; - } - sigdelsetmask(&set, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); current->blocked = set; @@ -260,23 +280,53 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re return (void __user *) sp; } +static inline int +save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) +{ + int err = 0; +#ifdef CONFIG_SMP + if (test_tsk_thread_flag(current, TIF_USEDFPU)) { + put_psr(get_psr() | PSR_EF); + fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr, + ¤t->thread.fpqueue[0], ¤t->thread.fpqdepth); + regs->psr &= ~(PSR_EF); + clear_tsk_thread_flag(current, TIF_USEDFPU); + } +#else + if (current == last_task_used_math) { + put_psr(get_psr() | PSR_EF); + fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr, + ¤t->thread.fpqueue[0], ¤t->thread.fpqdepth); + last_task_used_math = NULL; + regs->psr &= ~(PSR_EF); + } +#endif + err |= __copy_to_user(&fpu->si_float_regs[0], + ¤t->thread.float_regs[0], + (sizeof(unsigned long) * 32)); + err |= __put_user(current->thread.fsr, &fpu->si_fsr); + err |= __put_user(current->thread.fpqdepth, &fpu->si_fpqdepth); + if (current->thread.fpqdepth != 0) + err |= __copy_to_user(&fpu->si_fpqueue[0], + ¤t->thread.fpqueue[0], + ((sizeof(unsigned long) + + (sizeof(unsigned long *)))*16)); + clear_used_math(); + return err; +} + static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset) { struct signal_frame __user *sf; - int sigframe_size, err, wsaved; - void __user *tail; + int sigframe_size, err; /* 1. Make sure everything is clean */ synchronize_user_stack(); - wsaved = current_thread_info()->w_saved; - - sigframe_size = sizeof(*sf); - if (used_math()) - sigframe_size += sizeof(__siginfo_fpu_t); - if (wsaved) - sigframe_size += sizeof(__siginfo_rwin_t); + sigframe_size = SF_ALIGNEDSZ; + if (!used_math()) + sigframe_size -= sizeof(__siginfo_fpu_t); sf = (struct signal_frame __user *) get_sigframe(&ka->sa, regs, sigframe_size); @@ -284,7 +334,8 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, if (invalid_frame_pointer(sf, sigframe_size)) goto sigill_and_return; - tail = sf + 1; + if (current_thread_info()->w_saved != 0) + goto sigill_and_return; /* 2. Save the current process state */ err = __copy_to_user(&sf->info.si_regs, regs, sizeof(struct pt_regs)); @@ -292,34 +343,17 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, err |= __put_user(0, &sf->extra_size); if (used_math()) { - __siginfo_fpu_t __user *fp = tail; - tail += sizeof(*fp); - err |= save_fpu_state(regs, fp); - err |= __put_user(fp, &sf->fpu_save); + err |= save_fpu_state(regs, &sf->fpu_state); + err |= __put_user(&sf->fpu_state, &sf->fpu_save); } else { err |= __put_user(0, &sf->fpu_save); } - if (wsaved) { - __siginfo_rwin_t __user *rwp = tail; - tail += sizeof(*rwp); - err |= save_rwin_state(wsaved, rwp); - err |= __put_user(rwp, &sf->rwin_save); - } else { - err |= __put_user(0, &sf->rwin_save); - } err |= __put_user(oldset->sig[0], &sf->info.si_mask); err |= __copy_to_user(sf->extramask, &oldset->sig[1], (_NSIG_WORDS - 1) * sizeof(unsigned int)); - if (!wsaved) { - err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], - sizeof(struct reg_window32)); - } else { - struct reg_window32 *rp; - - rp = ¤t_thread_info()->reg_window[wsaved - 1]; - err |= __copy_to_user(sf, rp, sizeof(struct reg_window32)); - } + err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], + sizeof(struct reg_window32)); if (err) goto sigsegv; @@ -365,24 +399,21 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset, siginfo_t *info) { struct rt_signal_frame __user *sf; - int sigframe_size, wsaved; - void __user *tail; + int sigframe_size; unsigned int psr; int err; synchronize_user_stack(); - wsaved = current_thread_info()->w_saved; - sigframe_size = sizeof(*sf); - if (used_math()) - sigframe_size += sizeof(__siginfo_fpu_t); - if (wsaved) - sigframe_size += sizeof(__siginfo_rwin_t); + sigframe_size = RT_ALIGNEDSZ; + if (!used_math()) + sigframe_size -= sizeof(__siginfo_fpu_t); sf = (struct rt_signal_frame __user *) get_sigframe(&ka->sa, regs, sigframe_size); if (invalid_frame_pointer(sf, sigframe_size)) goto sigill; + if (current_thread_info()->w_saved != 0) + goto sigill; - tail = sf + 1; err = __put_user(regs->pc, &sf->regs.pc); err |= __put_user(regs->npc, &sf->regs.npc); err |= __put_user(regs->y, &sf->regs.y); @@ -394,21 +425,11 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, err |= __put_user(0, &sf->extra_size); if (psr & PSR_EF) { - __siginfo_fpu_t *fp = tail; - tail += sizeof(*fp); - err |= save_fpu_state(regs, fp); - err |= __put_user(fp, &sf->fpu_save); + err |= save_fpu_state(regs, &sf->fpu_state); + err |= __put_user(&sf->fpu_state, &sf->fpu_save); } else { err |= __put_user(0, &sf->fpu_save); } - if (wsaved) { - __siginfo_rwin_t *rwp = tail; - tail += sizeof(*rwp); - err |= save_rwin_state(wsaved, rwp); - err |= __put_user(rwp, &sf->rwin_save); - } else { - err |= __put_user(0, &sf->rwin_save); - } err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t)); /* Setup sigaltstack */ @@ -416,15 +437,8 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags); err |= __put_user(current->sas_ss_size, &sf->stack.ss_size); - if (!wsaved) { - err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], - sizeof(struct reg_window32)); - } else { - struct reg_window32 *rp; - - rp = ¤t_thread_info()->reg_window[wsaved - 1]; - err |= __copy_to_user(sf, rp, sizeof(struct reg_window32)); - } + err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], + sizeof(struct reg_window32)); err |= copy_siginfo_to_user(&sf->info, info); @@ -525,26 +539,10 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) siginfo_t info; int signr; - /* It's a lot of work and synchronization to add a new ptrace - * register for GDB to save and restore in order to get - * orig_i0 correct for syscall restarts when debugging. - * - * Although it should be the case that most of the global - * registers are volatile across a system call, glibc already - * depends upon that fact that we preserve them. So we can't - * just use any global register to save away the orig_i0 value. - * - * In particular %g2, %g3, %g4, and %g5 are all assumed to be - * preserved across a system call trap by various pieces of - * code in glibc. - * - * %g7 is used as the "thread register". %g6 is not used in - * any fixed manner. %g6 is used as a scratch register and - * a compiler temporary, but it's value is never used across - * a system call. Therefore %g6 is usable for orig_i0 storage. - */ if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) - regs->u_regs[UREG_G6] = orig_i0; + restart_syscall = 1; + else + restart_syscall = 0; if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; @@ -557,12 +555,8 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) * the software "in syscall" bit, directing us to not perform * a syscall restart. */ - restart_syscall = 0; - if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) { - restart_syscall = 1; - orig_i0 = regs->u_regs[UREG_G6]; - } - + if (restart_syscall && !pt_regs_is_syscall(regs)) + restart_syscall = 0; if (signr > 0) { if (restart_syscall) diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 77d476175dc6..006fe4515886 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -34,7 +34,6 @@ #include "entry.h" #include "systbls.h" -#include "sigutil.h" #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) @@ -237,7 +236,7 @@ struct rt_signal_frame { __siginfo_fpu_t __user *fpu_save; stack_t stack; sigset_t mask; - __siginfo_rwin_t *rwin_save; + __siginfo_fpu_t fpu_state; }; static long _sigpause_common(old_sigset_t set) @@ -267,12 +266,33 @@ asmlinkage long sys_sigsuspend(old_sigset_t set) return _sigpause_common(set); } +static inline int +restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) +{ + unsigned long *fpregs = current_thread_info()->fpregs; + unsigned long fprs; + int err; + + err = __get_user(fprs, &fpu->si_fprs); + fprs_write(0); + regs->tstate &= ~TSTATE_PEF; + if (fprs & FPRS_DL) + err |= copy_from_user(fpregs, &fpu->si_float_regs[0], + (sizeof(unsigned int) * 32)); + if (fprs & FPRS_DU) + err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], + (sizeof(unsigned int) * 32)); + err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr); + err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr); + current_thread_info()->fpsaved[0] |= fprs; + return err; +} + void do_rt_sigreturn(struct pt_regs *regs) { struct rt_signal_frame __user *sf; unsigned long tpc, tnpc, tstate; __siginfo_fpu_t __user *fpu_save; - __siginfo_rwin_t __user *rwin_save; sigset_t set; int err; @@ -305,18 +325,14 @@ void do_rt_sigreturn(struct pt_regs *regs) regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC)); err |= __get_user(fpu_save, &sf->fpu_save); - if (!err && fpu_save) - err |= restore_fpu_state(regs, fpu_save); + if (fpu_save) + err |= restore_fpu_state(regs, &sf->fpu_state); err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); - if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT) - goto segv; + err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf); - err |= __get_user(rwin_save, &sf->rwin_save); - if (!err && rwin_save) { - if (restore_rwin_state(rwin_save)) - goto segv; - } + if (err) + goto segv; regs->tpc = tpc; regs->tnpc = tnpc; @@ -335,13 +351,34 @@ segv: } /* Checks if the fp is valid */ -static int invalid_frame_pointer(void __user *fp) +static int invalid_frame_pointer(void __user *fp, int fplen) { if (((unsigned long) fp) & 15) return 1; return 0; } +static inline int +save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) +{ + unsigned long *fpregs = current_thread_info()->fpregs; + unsigned long fprs; + int err = 0; + + fprs = current_thread_info()->fpsaved[0]; + if (fprs & FPRS_DL) + err |= copy_to_user(&fpu->si_float_regs[0], fpregs, + (sizeof(unsigned int) * 32)); + if (fprs & FPRS_DU) + err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16, + (sizeof(unsigned int) * 32)); + err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr); + err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr); + err |= __put_user(fprs, &fpu->si_fprs); + + return err; +} + static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize) { unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS; @@ -377,48 +414,34 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset, siginfo_t *info) { struct rt_signal_frame __user *sf; - int wsaved, err, sf_size; - void __user *tail; + int sigframe_size, err; /* 1. Make sure everything is clean */ synchronize_user_stack(); save_and_clear_fpu(); - wsaved = get_thread_wsaved(); + sigframe_size = sizeof(struct rt_signal_frame); + if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) + sigframe_size -= sizeof(__siginfo_fpu_t); - sf_size = sizeof(struct rt_signal_frame); - if (current_thread_info()->fpsaved[0] & FPRS_FEF) - sf_size += sizeof(__siginfo_fpu_t); - if (wsaved) - sf_size += sizeof(__siginfo_rwin_t); sf = (struct rt_signal_frame __user *) - get_sigframe(ka, regs, sf_size); - - if (invalid_frame_pointer (sf)) + get_sigframe(ka, regs, sigframe_size); + + if (invalid_frame_pointer (sf, sigframe_size)) goto sigill; - tail = (sf + 1); + if (get_thread_wsaved() != 0) + goto sigill; /* 2. Save the current process state */ err = copy_to_user(&sf->regs, regs, sizeof (*regs)); if (current_thread_info()->fpsaved[0] & FPRS_FEF) { - __siginfo_fpu_t __user *fpu_save = tail; - tail += sizeof(__siginfo_fpu_t); - err |= save_fpu_state(regs, fpu_save); - err |= __put_user((u64)fpu_save, &sf->fpu_save); + err |= save_fpu_state(regs, &sf->fpu_state); + err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save); } else { err |= __put_user(0, &sf->fpu_save); } - if (wsaved) { - __siginfo_rwin_t __user *rwin_save = tail; - tail += sizeof(__siginfo_rwin_t); - err |= save_rwin_state(wsaved, rwin_save); - err |= __put_user((u64)rwin_save, &sf->rwin_save); - set_thread_wsaved(0); - } else { - err |= __put_user(0, &sf->rwin_save); - } /* Setup sigaltstack */ err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); @@ -427,17 +450,10 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t)); - if (!wsaved) { - err |= copy_in_user((u64 __user *)sf, - (u64 __user *)(regs->u_regs[UREG_FP] + - STACK_BIAS), - sizeof(struct reg_window)); - } else { - struct reg_window *rp; + err |= copy_in_user((u64 __user *)sf, + (u64 __user *)(regs->u_regs[UREG_FP]+STACK_BIAS), + sizeof(struct reg_window)); - rp = ¤t_thread_info()->reg_window[wsaved - 1]; - err |= copy_to_user(sf, rp, sizeof(struct reg_window)); - } if (info) err |= copy_siginfo_to_user(&sf->info, info); else { @@ -533,27 +549,11 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) siginfo_t info; int signr; - /* It's a lot of work and synchronization to add a new ptrace - * register for GDB to save and restore in order to get - * orig_i0 correct for syscall restarts when debugging. - * - * Although it should be the case that most of the global - * registers are volatile across a system call, glibc already - * depends upon that fact that we preserve them. So we can't - * just use any global register to save away the orig_i0 value. - * - * In particular %g2, %g3, %g4, and %g5 are all assumed to be - * preserved across a system call trap by various pieces of - * code in glibc. - * - * %g7 is used as the "thread register". %g6 is not used in - * any fixed manner. %g6 is used as a scratch register and - * a compiler temporary, but it's value is never used across - * a system call. Therefore %g6 is usable for orig_i0 storage. - */ if (pt_regs_is_syscall(regs) && - (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) - regs->u_regs[UREG_G6] = orig_i0; + (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { + restart_syscall = 1; + } else + restart_syscall = 0; if (current_thread_info()->status & TS_RESTORE_SIGMASK) oldset = ¤t->saved_sigmask; @@ -562,20 +562,22 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_32BIT)) { - extern void do_signal32(sigset_t *, struct pt_regs *); - do_signal32(oldset, regs); + extern void do_signal32(sigset_t *, struct pt_regs *, + int restart_syscall, + unsigned long orig_i0); + do_signal32(oldset, regs, restart_syscall, orig_i0); return; } #endif signr = get_signal_to_deliver(&info, &ka, regs, NULL); - restart_syscall = 0; - if (pt_regs_is_syscall(regs) && - (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { - restart_syscall = 1; - orig_i0 = regs->u_regs[UREG_G6]; - } + /* If the debugger messes with the program counter, it clears + * the software "in syscall" bit, directing us to not perform + * a syscall restart. + */ + if (restart_syscall && !pt_regs_is_syscall(regs)) + restart_syscall = 0; if (signr > 0) { if (restart_syscall) diff --git a/arch/sparc/kernel/sigutil.h b/arch/sparc/kernel/sigutil.h deleted file mode 100644 index d223aa432bb6..000000000000 --- a/arch/sparc/kernel/sigutil.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _SIGUTIL_H -#define _SIGUTIL_H - -int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu); -int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu); -int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin); -int restore_rwin_state(__siginfo_rwin_t __user *rp); - -#endif /* _SIGUTIL_H */ diff --git a/arch/sparc/kernel/sigutil_32.c b/arch/sparc/kernel/sigutil_32.c deleted file mode 100644 index 35c7897b009a..000000000000 --- a/arch/sparc/kernel/sigutil_32.c +++ /dev/null @@ -1,120 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "sigutil.h" - -int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) -{ - int err = 0; -#ifdef CONFIG_SMP - if (test_tsk_thread_flag(current, TIF_USEDFPU)) { - put_psr(get_psr() | PSR_EF); - fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr, - ¤t->thread.fpqueue[0], ¤t->thread.fpqdepth); - regs->psr &= ~(PSR_EF); - clear_tsk_thread_flag(current, TIF_USEDFPU); - } -#else - if (current == last_task_used_math) { - put_psr(get_psr() | PSR_EF); - fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr, - ¤t->thread.fpqueue[0], ¤t->thread.fpqdepth); - last_task_used_math = NULL; - regs->psr &= ~(PSR_EF); - } -#endif - err |= __copy_to_user(&fpu->si_float_regs[0], - ¤t->thread.float_regs[0], - (sizeof(unsigned long) * 32)); - err |= __put_user(current->thread.fsr, &fpu->si_fsr); - err |= __put_user(current->thread.fpqdepth, &fpu->si_fpqdepth); - if (current->thread.fpqdepth != 0) - err |= __copy_to_user(&fpu->si_fpqueue[0], - ¤t->thread.fpqueue[0], - ((sizeof(unsigned long) + - (sizeof(unsigned long *)))*16)); - clear_used_math(); - return err; -} - -int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) -{ - int err; -#ifdef CONFIG_SMP - if (test_tsk_thread_flag(current, TIF_USEDFPU)) - regs->psr &= ~PSR_EF; -#else - if (current == last_task_used_math) { - last_task_used_math = NULL; - regs->psr &= ~PSR_EF; - } -#endif - set_used_math(); - clear_tsk_thread_flag(current, TIF_USEDFPU); - - if (!access_ok(VERIFY_READ, fpu, sizeof(*fpu))) - return -EFAULT; - - err = __copy_from_user(¤t->thread.float_regs[0], &fpu->si_float_regs[0], - (sizeof(unsigned long) * 32)); - err |= __get_user(current->thread.fsr, &fpu->si_fsr); - err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth); - if (current->thread.fpqdepth != 0) - err |= __copy_from_user(¤t->thread.fpqueue[0], - &fpu->si_fpqueue[0], - ((sizeof(unsigned long) + - (sizeof(unsigned long *)))*16)); - return err; -} - -int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin) -{ - int i, err = __put_user(wsaved, &rwin->wsaved); - - for (i = 0; i < wsaved; i++) { - struct reg_window32 *rp; - unsigned long fp; - - rp = ¤t_thread_info()->reg_window[i]; - fp = current_thread_info()->rwbuf_stkptrs[i]; - err |= copy_to_user(&rwin->reg_window[i], rp, - sizeof(struct reg_window32)); - err |= __put_user(fp, &rwin->rwbuf_stkptrs[i]); - } - return err; -} - -int restore_rwin_state(__siginfo_rwin_t __user *rp) -{ - struct thread_info *t = current_thread_info(); - int i, wsaved, err; - - __get_user(wsaved, &rp->wsaved); - if (wsaved > NSWINS) - return -EFAULT; - - err = 0; - for (i = 0; i < wsaved; i++) { - err |= copy_from_user(&t->reg_window[i], - &rp->reg_window[i], - sizeof(struct reg_window32)); - err |= __get_user(t->rwbuf_stkptrs[i], - &rp->rwbuf_stkptrs[i]); - } - if (err) - return err; - - t->w_saved = wsaved; - synchronize_user_stack(); - if (t->w_saved) - return -EFAULT; - return 0; - -} diff --git a/arch/sparc/kernel/sigutil_64.c b/arch/sparc/kernel/sigutil_64.c deleted file mode 100644 index 6edc4e5c48d1..000000000000 --- a/arch/sparc/kernel/sigutil_64.c +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include - -#include "sigutil.h" - -int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) -{ - unsigned long *fpregs = current_thread_info()->fpregs; - unsigned long fprs; - int err = 0; - - fprs = current_thread_info()->fpsaved[0]; - if (fprs & FPRS_DL) - err |= copy_to_user(&fpu->si_float_regs[0], fpregs, - (sizeof(unsigned int) * 32)); - if (fprs & FPRS_DU) - err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16, - (sizeof(unsigned int) * 32)); - err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr); - err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr); - err |= __put_user(fprs, &fpu->si_fprs); - - return err; -} - -int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) -{ - unsigned long *fpregs = current_thread_info()->fpregs; - unsigned long fprs; - int err; - - err = __get_user(fprs, &fpu->si_fprs); - fprs_write(0); - regs->tstate &= ~TSTATE_PEF; - if (fprs & FPRS_DL) - err |= copy_from_user(fpregs, &fpu->si_float_regs[0], - (sizeof(unsigned int) * 32)); - if (fprs & FPRS_DU) - err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], - (sizeof(unsigned int) * 32)); - err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr); - err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr); - current_thread_info()->fpsaved[0] |= fprs; - return err; -} - -int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin) -{ - int i, err = __put_user(wsaved, &rwin->wsaved); - - for (i = 0; i < wsaved; i++) { - struct reg_window *rp = ¤t_thread_info()->reg_window[i]; - unsigned long fp = current_thread_info()->rwbuf_stkptrs[i]; - - err |= copy_to_user(&rwin->reg_window[i], rp, - sizeof(struct reg_window)); - err |= __put_user(fp, &rwin->rwbuf_stkptrs[i]); - } - return err; -} - -int restore_rwin_state(__siginfo_rwin_t __user *rp) -{ - struct thread_info *t = current_thread_info(); - int i, wsaved, err; - - __get_user(wsaved, &rp->wsaved); - if (wsaved > NSWINS) - return -EFAULT; - - err = 0; - for (i = 0; i < wsaved; i++) { - err |= copy_from_user(&t->reg_window[i], - &rp->reg_window[i], - sizeof(struct reg_window)); - err |= __get_user(t->rwbuf_stkptrs[i], - &rp->rwbuf_stkptrs[i]); - } - if (err) - return err; - - set_thread_wsaved(wsaved); - synchronize_user_stack(); - if (get_thread_wsaved()) - return -EFAULT; - return 0; -} diff --git a/arch/sparc/kernel/sparc_ksyms_64.c b/arch/sparc/kernel/sparc_ksyms_64.c index 83b47ab02d96..372ad59c4cba 100644 --- a/arch/sparc/kernel/sparc_ksyms_64.c +++ b/arch/sparc/kernel/sparc_ksyms_64.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include @@ -39,15 +38,5 @@ EXPORT_SYMBOL(sun4v_niagara_setperf); EXPORT_SYMBOL(sun4v_niagara2_getperf); EXPORT_SYMBOL(sun4v_niagara2_setperf); -/* from hweight.S */ -EXPORT_SYMBOL(__arch_hweight8); -EXPORT_SYMBOL(__arch_hweight16); -EXPORT_SYMBOL(__arch_hweight32); -EXPORT_SYMBOL(__arch_hweight64); - -/* from ffs_ffz.S */ -EXPORT_SYMBOL(ffs); -EXPORT_SYMBOL(__ffs); - /* Exporting a symbol from /init/main.c */ EXPORT_SYMBOL(saved_command_line); diff --git a/arch/sparc/kernel/sstate.c b/arch/sparc/kernel/sstate.c index c59af546f522..8cdbe5946b43 100644 --- a/arch/sparc/kernel/sstate.c +++ b/arch/sparc/kernel/sstate.c @@ -14,10 +14,15 @@ #include #include -#include "kernel.h" - static int hv_supports_soft_state; +static unsigned long kimage_addr_to_ra(const char *p) +{ + unsigned long val = (unsigned long) p; + + return kern_base + (val - KERNBASE); +} + static void do_set_sstate(unsigned long state, const char *msg) { unsigned long err; diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 10c9b369169c..908b47a5ee24 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -519,12 +519,12 @@ SYSCALL_DEFINE1(sparc64_personality, unsigned long, personality) { int ret; - if (personality(current->personality) == PER_LINUX32 && - personality(personality) == PER_LINUX) - personality |= PER_LINUX32; + if (current->personality == PER_LINUX32 && + personality == PER_LINUX) + personality = PER_LINUX32; ret = sys_personality(personality); - if (personality(ret) == PER_LINUX32) - ret &= ~PER_LINUX32; + if (ret == PER_LINUX32) + ret = PER_LINUX; return ret; } diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index 7f5f65d0b3fd..1d7e274f3f2b 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S @@ -212,20 +212,24 @@ linux_sparc_syscall: 3: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] ret_sys_call: ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3 + ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc sra %o0, 0, %o0 mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2 sllx %g2, 32, %g2 + /* Check if force_successful_syscall_return() + * was invoked. + */ + ldub [%g6 + TI_SYS_NOERROR], %l2 + brnz,a,pn %l2, 80f + stb %g0, [%g6 + TI_SYS_NOERROR] + cmp %o0, -ERESTART_RESTARTBLOCK bgeu,pn %xcc, 1f - andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 - ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc - -2: - stb %g0, [%g6 + TI_SYS_NOERROR] + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6 +80: /* System call success, clear Carry condition code. */ andn %g3, %g2, %g3 -3: stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] bne,pn %icc, linux_syscall_trace2 add %l1, 0x4, %l2 ! npc = npc+4 @@ -234,20 +238,20 @@ ret_sys_call: stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] 1: - /* Check if force_successful_syscall_return() - * was invoked. - */ - ldub [%g6 + TI_SYS_NOERROR], %l2 - brnz,pn %l2, 2b - ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc /* System call failure, set Carry condition code. * Also, get abs(errno) to return to the process. */ + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6 sub %g0, %o0, %o0 + or %g3, %g2, %g3 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] - ba,pt %xcc, 3b - or %g3, %g2, %g3 + stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] + bne,pn %icc, linux_syscall_trace2 + add %l1, 0x4, %l2 ! npc = npc+4 + stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] + b,pt %xcc, rtrap + stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] linux_syscall_trace2: call syscall_trace_leave add %sp, PTREGS_OFF, %o0 diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 248fb6763362..f566518483b5 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -74,7 +74,7 @@ sys_call_table32: .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid -/*280*/ .word sys32_tee, sys_add_key, sys_request_key, compat_sys_keyctl, compat_sys_openat +/*280*/ .word sys32_tee, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64 /*290*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c index 9043106a2622..b2b019ea8caa 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c @@ -22,7 +22,6 @@ #include #include #include -#include #include enum direction { @@ -374,11 +373,16 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) } } +static char popc_helper[] = { +0, 1, 1, 2, 1, 2, 2, 3, +1, 2, 2, 3, 2, 3, 3, 4, +}; + int handle_popc(u32 insn, struct pt_regs *regs) { - int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; - int ret, rd = ((insn >> 25) & 0x1f); u64 value; + int ret, i, rd = ((insn >> 25) & 0x1f); + int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); if (insn & 0x2000) { @@ -388,7 +392,10 @@ int handle_popc(u32 insn, struct pt_regs *regs) maybe_flush_windows(0, insn & 0x1f, rd, from_kernel); value = fetch_reg(insn & 0x1f, regs); } - ret = hweight64(value); + for (ret = 0, i = 0; i < 16; i++) { + ret += popc_helper[value & 0xf]; + value >>= 4; + } if (rd < 16) { if (rd) regs->u_regs[rd] = ret; diff --git a/arch/sparc/kernel/visemul.c b/arch/sparc/kernel/visemul.c index 9384a0cbeba4..36357717d691 100644 --- a/arch/sparc/kernel/visemul.c +++ b/arch/sparc/kernel/visemul.c @@ -713,17 +713,17 @@ static void pcmp(struct pt_regs *regs, unsigned int insn, unsigned int opf) s16 b = (rs2 >> (i * 16)) & 0xffff; if (a > b) - rd_val |= 8 >> i; + rd_val |= 1 << i; } break; case FCMPGT32_OPF: for (i = 0; i < 2; i++) { - s32 a = (rs1 >> (i * 32)) & 0xffffffff; - s32 b = (rs2 >> (i * 32)) & 0xffffffff; + s32 a = (rs1 >> (i * 32)) & 0xffff; + s32 b = (rs2 >> (i * 32)) & 0xffff; if (a > b) - rd_val |= 2 >> i; + rd_val |= 1 << i; } break; @@ -733,17 +733,17 @@ static void pcmp(struct pt_regs *regs, unsigned int insn, unsigned int opf) s16 b = (rs2 >> (i * 16)) & 0xffff; if (a <= b) - rd_val |= 8 >> i; + rd_val |= 1 << i; } break; case FCMPLE32_OPF: for (i = 0; i < 2; i++) { - s32 a = (rs1 >> (i * 32)) & 0xffffffff; - s32 b = (rs2 >> (i * 32)) & 0xffffffff; + s32 a = (rs1 >> (i * 32)) & 0xffff; + s32 b = (rs2 >> (i * 32)) & 0xffff; if (a <= b) - rd_val |= 2 >> i; + rd_val |= 1 << i; } break; @@ -753,17 +753,17 @@ static void pcmp(struct pt_regs *regs, unsigned int insn, unsigned int opf) s16 b = (rs2 >> (i * 16)) & 0xffff; if (a != b) - rd_val |= 8 >> i; + rd_val |= 1 << i; } break; case FCMPNE32_OPF: for (i = 0; i < 2; i++) { - s32 a = (rs1 >> (i * 32)) & 0xffffffff; - s32 b = (rs2 >> (i * 32)) & 0xffffffff; + s32 a = (rs1 >> (i * 32)) & 0xffff; + s32 b = (rs2 >> (i * 32)) & 0xffff; if (a != b) - rd_val |= 2 >> i; + rd_val |= 1 << i; } break; @@ -773,17 +773,17 @@ static void pcmp(struct pt_regs *regs, unsigned int insn, unsigned int opf) s16 b = (rs2 >> (i * 16)) & 0xffff; if (a == b) - rd_val |= 8 >> i; + rd_val |= 1 << i; } break; case FCMPEQ32_OPF: for (i = 0; i < 2; i++) { - s32 a = (rs1 >> (i * 32)) & 0xffffffff; - s32 b = (rs2 >> (i * 32)) & 0xffffffff; + s32 a = (rs1 >> (i * 32)) & 0xffff; + s32 b = (rs2 >> (i * 32)) & 0xffff; if (a == b) - rd_val |= 2 >> i; + rd_val |= 1 << i; } break; } diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 0e1605697b49..c0220759003e 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -107,26 +107,7 @@ SECTIONS *(.sun4v_2insn_patch) __sun4v_2insn_patch_end = .; } - .swapper_tsb_phys_patch : { - __swapper_tsb_phys_patch = .; - *(.swapper_tsb_phys_patch) - __swapper_tsb_phys_patch_end = .; - } - .swapper_4m_tsb_phys_patch : { - __swapper_4m_tsb_phys_patch = .; - *(.swapper_4m_tsb_phys_patch) - __swapper_4m_tsb_phys_patch_end = .; - } - .popc_3insn_patch : { - __popc_3insn_patch = .; - *(.popc_3insn_patch) - __popc_3insn_patch_end = .; - } - .popc_6insn_patch : { - __popc_6insn_patch = .; - *(.popc_6insn_patch) - __popc_6insn_patch_end = .; - } + PERCPU_SECTION(SMP_CACHE_BYTES) . = ALIGN(PAGE_SIZE); diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index a3fc4375a150..7f01b8fce8bc 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile @@ -31,13 +31,13 @@ lib-$(CONFIG_SPARC64) += NGmemcpy.o NGcopy_from_user.o NGcopy_to_user.o lib-$(CONFIG_SPARC64) += NGpatch.o NGpage.o NGbzero.o lib-$(CONFIG_SPARC64) += NG2memcpy.o NG2copy_from_user.o NG2copy_to_user.o -lib-$(CONFIG_SPARC64) += NG2patch.o +lib-$(CONFIG_SPARC64) += NG2patch.o NG2page.o lib-$(CONFIG_SPARC64) += GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o lib-$(CONFIG_SPARC64) += copy_in_user.o user_fixup.o memmove.o -lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o +lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o obj-y += iomap.o obj-$(CONFIG_SPARC32) += atomic32.o diff --git a/arch/sparc/lib/NG2page.S b/arch/sparc/lib/NG2page.S new file mode 100644 index 000000000000..73b6b7c72cbf --- /dev/null +++ b/arch/sparc/lib/NG2page.S @@ -0,0 +1,61 @@ +/* NG2page.S: Niagara-2 optimized clear and copy page. + * + * Copyright (C) 2007 (davem@davemloft.net) + */ + +#include +#include +#include + + .text + .align 32 + + /* This is heavily simplified from the sun4u variants + * because Niagara-2 does not have any D-cache aliasing issues. + */ +NG2copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ + prefetch [%o1 + 0x00], #one_read + prefetch [%o1 + 0x40], #one_read + VISEntryHalf + set PAGE_SIZE, %g7 + sub %o0, %o1, %g3 +1: stxa %g0, [%o1 + %g3] ASI_BLK_INIT_QUAD_LDD_P + subcc %g7, 64, %g7 + ldda [%o1] ASI_BLK_P, %f0 + stda %f0, [%o1 + %g3] ASI_BLK_P + add %o1, 64, %o1 + bne,pt %xcc, 1b + prefetch [%o1 + 0x40], #one_read + membar #Sync + VISExitHalf + retl + nop + +#define BRANCH_ALWAYS 0x10680000 +#define NOP 0x01000000 +#define NG_DO_PATCH(OLD, NEW) \ + sethi %hi(NEW), %g1; \ + or %g1, %lo(NEW), %g1; \ + sethi %hi(OLD), %g2; \ + or %g2, %lo(OLD), %g2; \ + sub %g1, %g2, %g1; \ + sethi %hi(BRANCH_ALWAYS), %g3; \ + sll %g1, 11, %g1; \ + srl %g1, 11 + 2, %g1; \ + or %g3, %lo(BRANCH_ALWAYS), %g3; \ + or %g3, %g1, %g3; \ + stw %g3, [%g2]; \ + sethi %hi(NOP), %g3; \ + or %g3, %lo(NOP), %g3; \ + stw %g3, [%g2 + 0x4]; \ + flush %g2; + + .globl niagara2_patch_pageops + .type niagara2_patch_pageops,#function +niagara2_patch_pageops: + NG_DO_PATCH(copy_user_page, NG2copy_user_page) + NG_DO_PATCH(_clear_page, NGclear_page) + NG_DO_PATCH(clear_user_page, NGclear_user_page) + retl + nop + .size niagara2_patch_pageops,.-niagara2_patch_pageops diff --git a/arch/sparc/lib/NGpage.S b/arch/sparc/lib/NGpage.S index b9e790b9c6b8..428920de05ba 100644 --- a/arch/sparc/lib/NGpage.S +++ b/arch/sparc/lib/NGpage.S @@ -16,91 +16,55 @@ */ NGcopy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ - save %sp, -192, %sp - rd %asi, %g3 - wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi + prefetch [%o1 + 0x00], #one_read + mov 8, %g1 + mov 16, %g2 + mov 24, %g3 set PAGE_SIZE, %g7 - prefetch [%i1 + 0x00], #one_read - prefetch [%i1 + 0x40], #one_read -1: prefetch [%i1 + 0x80], #one_read - prefetch [%i1 + 0xc0], #one_read - ldda [%i1 + 0x00] %asi, %o2 - ldda [%i1 + 0x10] %asi, %o4 - ldda [%i1 + 0x20] %asi, %l2 - ldda [%i1 + 0x30] %asi, %l4 - stxa %o2, [%i0 + 0x00] %asi - stxa %o3, [%i0 + 0x08] %asi - stxa %o4, [%i0 + 0x10] %asi - stxa %o5, [%i0 + 0x18] %asi - stxa %l2, [%i0 + 0x20] %asi - stxa %l3, [%i0 + 0x28] %asi - stxa %l4, [%i0 + 0x30] %asi - stxa %l5, [%i0 + 0x38] %asi - ldda [%i1 + 0x40] %asi, %o2 - ldda [%i1 + 0x50] %asi, %o4 - ldda [%i1 + 0x60] %asi, %l2 - ldda [%i1 + 0x70] %asi, %l4 - stxa %o2, [%i0 + 0x40] %asi - stxa %o3, [%i0 + 0x48] %asi - stxa %o4, [%i0 + 0x50] %asi - stxa %o5, [%i0 + 0x58] %asi - stxa %l2, [%i0 + 0x60] %asi - stxa %l3, [%i0 + 0x68] %asi - stxa %l4, [%i0 + 0x70] %asi - stxa %l5, [%i0 + 0x78] %asi - add %i1, 128, %i1 - subcc %g7, 128, %g7 +1: ldda [%o1 + %g0] ASI_BLK_INIT_QUAD_LDD_P, %o2 + ldda [%o1 + %g2] ASI_BLK_INIT_QUAD_LDD_P, %o4 + prefetch [%o1 + 0x40], #one_read + add %o1, 32, %o1 + stxa %o2, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P + stxa %o3, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P + ldda [%o1 + %g0] ASI_BLK_INIT_QUAD_LDD_P, %o2 + stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P + stxa %o5, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P + ldda [%o1 + %g2] ASI_BLK_INIT_QUAD_LDD_P, %o4 + add %o1, 32, %o1 + add %o0, 32, %o0 + stxa %o2, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P + stxa %o3, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P + stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P + stxa %o5, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P + subcc %g7, 64, %g7 bne,pt %xcc, 1b - add %i0, 128, %i0 - wr %g3, 0x0, %asi + add %o0, 32, %o0 membar #Sync - ret - restore + retl + nop - .align 32 + .globl NGclear_page, NGclear_user_page NGclear_page: /* %o0=dest */ NGclear_user_page: /* %o0=dest, %o1=vaddr */ - rd %asi, %g3 - wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi + mov 8, %g1 + mov 16, %g2 + mov 24, %g3 set PAGE_SIZE, %g7 -1: stxa %g0, [%o0 + 0x00] %asi - stxa %g0, [%o0 + 0x08] %asi - stxa %g0, [%o0 + 0x10] %asi - stxa %g0, [%o0 + 0x18] %asi - stxa %g0, [%o0 + 0x20] %asi - stxa %g0, [%o0 + 0x28] %asi - stxa %g0, [%o0 + 0x30] %asi - stxa %g0, [%o0 + 0x38] %asi - stxa %g0, [%o0 + 0x40] %asi - stxa %g0, [%o0 + 0x48] %asi - stxa %g0, [%o0 + 0x50] %asi - stxa %g0, [%o0 + 0x58] %asi - stxa %g0, [%o0 + 0x60] %asi - stxa %g0, [%o0 + 0x68] %asi - stxa %g0, [%o0 + 0x70] %asi - stxa %g0, [%o0 + 0x78] %asi - stxa %g0, [%o0 + 0x80] %asi - stxa %g0, [%o0 + 0x88] %asi - stxa %g0, [%o0 + 0x90] %asi - stxa %g0, [%o0 + 0x98] %asi - stxa %g0, [%o0 + 0xa0] %asi - stxa %g0, [%o0 + 0xa8] %asi - stxa %g0, [%o0 + 0xb0] %asi - stxa %g0, [%o0 + 0xb8] %asi - stxa %g0, [%o0 + 0xc0] %asi - stxa %g0, [%o0 + 0xc8] %asi - stxa %g0, [%o0 + 0xd0] %asi - stxa %g0, [%o0 + 0xd8] %asi - stxa %g0, [%o0 + 0xe0] %asi - stxa %g0, [%o0 + 0xe8] %asi - stxa %g0, [%o0 + 0xf0] %asi - stxa %g0, [%o0 + 0xf8] %asi - subcc %g7, 256, %g7 +1: stxa %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P + stxa %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P + stxa %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P + stxa %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P + add %o0, 32, %o0 + stxa %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P + stxa %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P + stxa %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P + stxa %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P + subcc %g7, 64, %g7 bne,pt %xcc, 1b - add %o0, 256, %o0 - wr %g3, 0x0, %asi + add %o0, 32, %o0 membar #Sync retl nop diff --git a/arch/sparc/lib/ffs.S b/arch/sparc/lib/ffs.S deleted file mode 100644 index b39389f69899..000000000000 --- a/arch/sparc/lib/ffs.S +++ /dev/null @@ -1,84 +0,0 @@ -#include - - .register %g2,#scratch - - .text - .align 32 - -ENTRY(ffs) - brnz,pt %o0, 1f - mov 1, %o1 - retl - clr %o0 - nop - nop -ENTRY(__ffs) - sllx %o0, 32, %g1 /* 1 */ - srlx %o0, 32, %g2 - - clr %o1 /* 2 */ - movrz %g1, %g2, %o0 - - movrz %g1, 32, %o1 /* 3 */ -1: clr %o2 - - sllx %o0, (64 - 16), %g1 /* 4 */ - srlx %o0, 16, %g2 - - movrz %g1, %g2, %o0 /* 5 */ - clr %o3 - - movrz %g1, 16, %o2 /* 6 */ - clr %o4 - - and %o0, 0xff, %g1 /* 7 */ - srlx %o0, 8, %g2 - - movrz %g1, %g2, %o0 /* 8 */ - clr %o5 - - movrz %g1, 8, %o3 /* 9 */ - add %o2, %o1, %o2 - - and %o0, 0xf, %g1 /* 10 */ - srlx %o0, 4, %g2 - - movrz %g1, %g2, %o0 /* 11 */ - add %o2, %o3, %o2 - - movrz %g1, 4, %o4 /* 12 */ - - and %o0, 0x3, %g1 /* 13 */ - srlx %o0, 2, %g2 - - movrz %g1, %g2, %o0 /* 14 */ - add %o2, %o4, %o2 - - movrz %g1, 2, %o5 /* 15 */ - - and %o0, 0x1, %g1 /* 16 */ - - add %o2, %o5, %o2 /* 17 */ - xor %g1, 0x1, %g1 - - retl /* 18 */ - add %o2, %g1, %o0 -ENDPROC(ffs) -ENDPROC(__ffs) - - .section .popc_6insn_patch, "ax" - .word ffs - brz,pn %o0, 98f - neg %o0, %g1 - xnor %o0, %g1, %o1 - popc %o1, %o0 -98: retl - nop - .word __ffs - neg %o0, %g1 - xnor %o0, %g1, %o1 - popc %o1, %o0 - retl - sub %o0, 1, %o0 - nop - .previous diff --git a/arch/sparc/lib/hweight.S b/arch/sparc/lib/hweight.S deleted file mode 100644 index 95414e0a6808..000000000000 --- a/arch/sparc/lib/hweight.S +++ /dev/null @@ -1,51 +0,0 @@ -#include - - .text - .align 32 -ENTRY(__arch_hweight8) - ba,pt %xcc, __sw_hweight8 - nop - nop -ENDPROC(__arch_hweight8) - .section .popc_3insn_patch, "ax" - .word __arch_hweight8 - sllx %o0, 64-8, %g1 - retl - popc %g1, %o0 - .previous - -ENTRY(__arch_hweight16) - ba,pt %xcc, __sw_hweight16 - nop - nop -ENDPROC(__arch_hweight16) - .section .popc_3insn_patch, "ax" - .word __arch_hweight16 - sllx %o0, 64-16, %g1 - retl - popc %g1, %o0 - .previous - -ENTRY(__arch_hweight32) - ba,pt %xcc, __sw_hweight32 - nop - nop -ENDPROC(__arch_hweight32) - .section .popc_3insn_patch, "ax" - .word __arch_hweight32 - sllx %o0, 64-32, %g1 - retl - popc %g1, %o0 - .previous - -ENTRY(__arch_hweight64) - ba,pt %xcc, __sw_hweight64 - nop - nop -ENDPROC(__arch_hweight64) - .section .popc_3insn_patch, "ax" - .word __arch_hweight64 - retl - popc %o0, %o0 - nop - .previous diff --git a/arch/sparc/lib/memcpy.S b/arch/sparc/lib/memcpy.S index 4d8c497517bd..34fe65751737 100644 --- a/arch/sparc/lib/memcpy.S +++ b/arch/sparc/lib/memcpy.S @@ -7,12 +7,40 @@ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz) */ -#define FUNC(x) \ +#ifdef __KERNEL__ + +#define FUNC(x) \ .globl x; \ .type x,@function; \ - .align 4; \ + .align 4; \ x: +#undef FASTER_REVERSE +#undef FASTER_NONALIGNED +#define FASTER_ALIGNED + +/* In kernel these functions don't return a value. + * One should use macros in asm/string.h for that purpose. + * We return 0, so that bugs are more apparent. + */ +#define SETUP_RETL +#define RETL_INSN clr %o0 + +#else + +/* libc */ + +#include "DEFS.h" + +#define FASTER_REVERSE +#define FASTER_NONALIGNED +#define FASTER_ALIGNED + +#define SETUP_RETL mov %o0, %g6 +#define RETL_INSN mov %g6, %o0 + +#endif + /* Both these macros have to start with exactly the same insn */ #define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \ ldd [%src + (offset) + 0x00], %t0; \ @@ -136,6 +164,30 @@ x: .text .align 4 +#ifdef FASTER_REVERSE + +70: /* rdword_align */ + + andcc %o1, 1, %g0 + be 4f + andcc %o1, 2, %g0 + + ldub [%o1 - 1], %g2 + sub %o1, 1, %o1 + stb %g2, [%o0 - 1] + sub %o2, 1, %o2 + be 3f + sub %o0, 1, %o0 +4: + lduh [%o1 - 2], %g2 + sub %o1, 2, %o1 + sth %g2, [%o0 - 2] + sub %o2, 2, %o2 + b 3f + sub %o0, 2, %o0 + +#endif /* FASTER_REVERSE */ + 0: retl nop ! Only bcopy returns here and it retuns void... @@ -146,7 +198,7 @@ FUNC(__memmove) #endif FUNC(memmove) cmp %o0, %o1 - mov %o0, %g7 + SETUP_RETL bleu 9f sub %o0, %o1, %o4 @@ -155,6 +207,8 @@ FUNC(memmove) bleu 0f andcc %o4, 3, %o5 +#ifndef FASTER_REVERSE + add %o1, %o2, %o1 add %o0, %o2, %o0 sub %o1, 1, %o1 @@ -170,7 +224,295 @@ FUNC(memmove) sub %o0, 1, %o0 retl - mov %g7, %o0 + RETL_INSN + +#else /* FASTER_REVERSE */ + + add %o1, %o2, %o1 + add %o0, %o2, %o0 + bne 77f + cmp %o2, 15 + bleu 91f + andcc %o1, 3, %g0 + bne 70b +3: + andcc %o1, 4, %g0 + + be 2f + mov %o2, %g1 + + ld [%o1 - 4], %o4 + sub %g1, 4, %g1 + st %o4, [%o0 - 4] + sub %o1, 4, %o1 + sub %o0, 4, %o0 +2: + andcc %g1, 0xffffff80, %g7 + be 3f + andcc %o0, 4, %g0 + + be 74f + 4 +5: + RMOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5) + RMOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5) + RMOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5) + RMOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5) + subcc %g7, 128, %g7 + sub %o1, 128, %o1 + bne 5b + sub %o0, 128, %o0 +3: + andcc %g1, 0x70, %g7 + be 72f + andcc %g1, 8, %g0 + + sethi %hi(72f), %o5 + srl %g7, 1, %o4 + add %g7, %o4, %o4 + sub %o1, %g7, %o1 + sub %o5, %o4, %o5 + jmpl %o5 + %lo(72f), %g0 + sub %o0, %g7, %o0 + +71: /* rmemcpy_table */ + RMOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5) + RMOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5) + RMOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5) + RMOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5) + RMOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5) + RMOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5) + RMOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5) + +72: /* rmemcpy_table_end */ + + be 73f + andcc %g1, 4, %g0 + + ldd [%o1 - 0x08], %g2 + sub %o0, 8, %o0 + sub %o1, 8, %o1 + st %g2, [%o0] + st %g3, [%o0 + 0x04] + +73: /* rmemcpy_last7 */ + + be 1f + andcc %g1, 2, %g0 + + ld [%o1 - 4], %g2 + sub %o1, 4, %o1 + st %g2, [%o0 - 4] + sub %o0, 4, %o0 +1: + be 1f + andcc %g1, 1, %g0 + + lduh [%o1 - 2], %g2 + sub %o1, 2, %o1 + sth %g2, [%o0 - 2] + sub %o0, 2, %o0 +1: + be 1f + nop + + ldub [%o1 - 1], %g2 + stb %g2, [%o0 - 1] +1: + retl + RETL_INSN + +74: /* rldd_std */ + RMOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5) + RMOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5) + RMOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5) + RMOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5) + subcc %g7, 128, %g7 + sub %o1, 128, %o1 + bne 74b + sub %o0, 128, %o0 + + andcc %g1, 0x70, %g7 + be 72b + andcc %g1, 8, %g0 + + sethi %hi(72b), %o5 + srl %g7, 1, %o4 + add %g7, %o4, %o4 + sub %o1, %g7, %o1 + sub %o5, %o4, %o5 + jmpl %o5 + %lo(72b), %g0 + sub %o0, %g7, %o0 + +75: /* rshort_end */ + + and %o2, 0xe, %o3 +2: + sethi %hi(76f), %o5 + sll %o3, 3, %o4 + sub %o0, %o3, %o0 + sub %o5, %o4, %o5 + sub %o1, %o3, %o1 + jmpl %o5 + %lo(76f), %g0 + andcc %o2, 1, %g0 + + RMOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3) + RMOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3) + RMOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3) + RMOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3) + RMOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3) + RMOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3) + RMOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3) + +76: /* rshort_table_end */ + + be 1f + nop + ldub [%o1 - 1], %g2 + stb %g2, [%o0 - 1] +1: + retl + RETL_INSN + +91: /* rshort_aligned_end */ + + bne 75b + andcc %o2, 8, %g0 + + be 1f + andcc %o2, 4, %g0 + + ld [%o1 - 0x08], %g2 + ld [%o1 - 0x04], %g3 + sub %o1, 8, %o1 + st %g2, [%o0 - 0x08] + st %g3, [%o0 - 0x04] + sub %o0, 8, %o0 +1: + b 73b + mov %o2, %g1 + +77: /* rnon_aligned */ + cmp %o2, 15 + bleu 75b + andcc %o0, 3, %g0 + be 64f + andcc %o0, 1, %g0 + be 63f + andcc %o0, 2, %g0 + ldub [%o1 - 1], %g5 + sub %o1, 1, %o1 + stb %g5, [%o0 - 1] + sub %o0, 1, %o0 + be 64f + sub %o2, 1, %o2 +63: + ldub [%o1 - 1], %g5 + sub %o1, 2, %o1 + stb %g5, [%o0 - 1] + sub %o0, 2, %o0 + ldub [%o1], %g5 + sub %o2, 2, %o2 + stb %g5, [%o0] +64: + and %o1, 3, %g2 + and %o1, -4, %o1 + and %o2, 0xc, %g3 + add %o1, 4, %o1 + cmp %g3, 4 + sll %g2, 3, %g4 + mov 32, %g2 + be 4f + sub %g2, %g4, %g7 + + blu 3f + cmp %g3, 8 + + be 2f + srl %o2, 2, %g3 + + ld [%o1 - 4], %o3 + add %o0, -8, %o0 + ld [%o1 - 8], %o4 + add %o1, -16, %o1 + b 7f + add %g3, 1, %g3 +2: + ld [%o1 - 4], %o4 + add %o0, -4, %o0 + ld [%o1 - 8], %g1 + add %o1, -12, %o1 + b 8f + add %g3, 2, %g3 +3: + ld [%o1 - 4], %o5 + add %o0, -12, %o0 + ld [%o1 - 8], %o3 + add %o1, -20, %o1 + b 6f + srl %o2, 2, %g3 +4: + ld [%o1 - 4], %g1 + srl %o2, 2, %g3 + ld [%o1 - 8], %o5 + add %o1, -24, %o1 + add %o0, -16, %o0 + add %g3, -1, %g3 + + ld [%o1 + 12], %o3 +5: + sll %o5, %g4, %g2 + srl %g1, %g7, %g5 + or %g2, %g5, %g2 + st %g2, [%o0 + 12] +6: + ld [%o1 + 8], %o4 + sll %o3, %g4, %g2 + srl %o5, %g7, %g5 + or %g2, %g5, %g2 + st %g2, [%o0 + 8] +7: + ld [%o1 + 4], %g1 + sll %o4, %g4, %g2 + srl %o3, %g7, %g5 + or %g2, %g5, %g2 + st %g2, [%o0 + 4] +8: + ld [%o1], %o5 + sll %g1, %g4, %g2 + srl %o4, %g7, %g5 + addcc %g3, -4, %g3 + or %g2, %g5, %g2 + add %o1, -16, %o1 + st %g2, [%o0] + add %o0, -16, %o0 + bne,a 5b + ld [%o1 + 12], %o3 + sll %o5, %g4, %g2 + srl %g1, %g7, %g5 + srl %g4, 3, %g3 + or %g2, %g5, %g2 + add %o1, %g3, %o1 + andcc %o2, 2, %g0 + st %g2, [%o0 + 12] + be 1f + andcc %o2, 1, %g0 + + ldub [%o1 + 15], %g5 + add %o1, -2, %o1 + stb %g5, [%o0 + 11] + add %o0, -2, %o0 + ldub [%o1 + 16], %g5 + stb %g5, [%o0 + 12] +1: + be 1f + nop + ldub [%o1 + 15], %g5 + stb %g5, [%o0 + 11] +1: + retl + RETL_INSN + +#endif /* FASTER_REVERSE */ /* NOTE: This code is executed just for the cases, where %src (=%o1) & 3 is != 0. @@ -204,7 +546,7 @@ FUNC(memmove) FUNC(memcpy) /* %o0=dst %o1=src %o2=len */ sub %o0, %o1, %o4 - mov %o0, %g7 + SETUP_RETL 9: andcc %o4, 3, %o5 0: @@ -227,7 +569,7 @@ FUNC(memcpy) /* %o0=dst %o1=src %o2=len */ add %o1, 4, %o1 add %o0, 4, %o0 2: - andcc %g1, 0xffffff80, %g0 + andcc %g1, 0xffffff80, %g7 be 3f andcc %o0, 4, %g0 @@ -237,23 +579,22 @@ FUNC(memcpy) /* %o0=dst %o1=src %o2=len */ MOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5) MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5) MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5) - sub %g1, 128, %g1 + subcc %g7, 128, %g7 add %o1, 128, %o1 - cmp %g1, 128 - bge 5b + bne 5b add %o0, 128, %o0 3: - andcc %g1, 0x70, %g4 + andcc %g1, 0x70, %g7 be 80f andcc %g1, 8, %g0 sethi %hi(80f), %o5 - srl %g4, 1, %o4 - add %g4, %o4, %o4 - add %o1, %g4, %o1 + srl %g7, 1, %o4 + add %g7, %o4, %o4 + add %o1, %g7, %o1 sub %o5, %o4, %o5 jmpl %o5 + %lo(80f), %g0 - add %o0, %g4, %o0 + add %o0, %g7, %o0 79: /* memcpy_table */ @@ -300,28 +641,43 @@ FUNC(memcpy) /* %o0=dst %o1=src %o2=len */ stb %g2, [%o0] 1: retl - mov %g7, %o0 + RETL_INSN 82: /* ldd_std */ MOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5) MOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5) MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5) MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5) - subcc %g1, 128, %g1 + subcc %g7, 128, %g7 add %o1, 128, %o1 - cmp %g1, 128 - bge 82b + bne 82b add %o0, 128, %o0 - andcc %g1, 0x70, %g4 +#ifndef FASTER_ALIGNED + + andcc %g1, 0x70, %g7 + be 80b + andcc %g1, 8, %g0 + + sethi %hi(80b), %o5 + srl %g7, 1, %o4 + add %g7, %o4, %o4 + add %o1, %g7, %o1 + sub %o5, %o4, %o5 + jmpl %o5 + %lo(80b), %g0 + add %o0, %g7, %o0 + +#else /* FASTER_ALIGNED */ + + andcc %g1, 0x70, %g7 be 84f andcc %g1, 8, %g0 sethi %hi(84f), %o5 - add %o1, %g4, %o1 - sub %o5, %g4, %o5 + add %o1, %g7, %o1 + sub %o5, %g7, %o5 jmpl %o5 + %lo(84f), %g0 - add %o0, %g4, %o0 + add %o0, %g7, %o0 83: /* amemcpy_table */ @@ -365,132 +721,382 @@ FUNC(memcpy) /* %o0=dst %o1=src %o2=len */ stb %g2, [%o0] 1: retl - mov %g7, %o0 + RETL_INSN + +#endif /* FASTER_ALIGNED */ 86: /* non_aligned */ cmp %o2, 6 bleu 88f - nop - save %sp, -96, %sp - andcc %i0, 3, %g0 +#ifdef FASTER_NONALIGNED + + cmp %o2, 256 + bcc 87f + +#endif /* FASTER_NONALIGNED */ + + andcc %o0, 3, %g0 be 61f - andcc %i0, 1, %g0 + andcc %o0, 1, %g0 be 60f - andcc %i0, 2, %g0 + andcc %o0, 2, %g0 - ldub [%i1], %g5 - add %i1, 1, %i1 - stb %g5, [%i0] - sub %i2, 1, %i2 + ldub [%o1], %g5 + add %o1, 1, %o1 + stb %g5, [%o0] + sub %o2, 1, %o2 bne 61f - add %i0, 1, %i0 + add %o0, 1, %o0 60: - ldub [%i1], %g3 - add %i1, 2, %i1 - stb %g3, [%i0] - sub %i2, 2, %i2 - ldub [%i1 - 1], %g3 - add %i0, 2, %i0 - stb %g3, [%i0 - 1] + ldub [%o1], %g3 + add %o1, 2, %o1 + stb %g3, [%o0] + sub %o2, 2, %o2 + ldub [%o1 - 1], %g3 + add %o0, 2, %o0 + stb %g3, [%o0 - 1] 61: - and %i1, 3, %g2 - and %i2, 0xc, %g3 - and %i1, -4, %i1 + and %o1, 3, %g2 + and %o2, 0xc, %g3 + and %o1, -4, %o1 cmp %g3, 4 sll %g2, 3, %g4 mov 32, %g2 be 4f - sub %g2, %g4, %l0 + sub %g2, %g4, %g7 blu 3f cmp %g3, 0x8 be 2f - srl %i2, 2, %g3 + srl %o2, 2, %g3 - ld [%i1], %i3 - add %i0, -8, %i0 - ld [%i1 + 4], %i4 + ld [%o1], %o3 + add %o0, -8, %o0 + ld [%o1 + 4], %o4 b 8f add %g3, 1, %g3 2: - ld [%i1], %i4 - add %i0, -12, %i0 - ld [%i1 + 4], %i5 + ld [%o1], %o4 + add %o0, -12, %o0 + ld [%o1 + 4], %o5 add %g3, 2, %g3 b 9f - add %i1, -4, %i1 + add %o1, -4, %o1 3: - ld [%i1], %g1 - add %i0, -4, %i0 - ld [%i1 + 4], %i3 - srl %i2, 2, %g3 + ld [%o1], %g1 + add %o0, -4, %o0 + ld [%o1 + 4], %o3 + srl %o2, 2, %g3 b 7f - add %i1, 4, %i1 + add %o1, 4, %o1 4: - ld [%i1], %i5 - cmp %i2, 7 - ld [%i1 + 4], %g1 - srl %i2, 2, %g3 + ld [%o1], %o5 + cmp %o2, 7 + ld [%o1 + 4], %g1 + srl %o2, 2, %g3 bleu 10f - add %i1, 8, %i1 + add %o1, 8, %o1 - ld [%i1], %i3 + ld [%o1], %o3 add %g3, -1, %g3 5: - sll %i5, %g4, %g2 - srl %g1, %l0, %g5 + sll %o5, %g4, %g2 + srl %g1, %g7, %g5 or %g2, %g5, %g2 - st %g2, [%i0] + st %g2, [%o0] 7: - ld [%i1 + 4], %i4 + ld [%o1 + 4], %o4 sll %g1, %g4, %g2 - srl %i3, %l0, %g5 + srl %o3, %g7, %g5 or %g2, %g5, %g2 - st %g2, [%i0 + 4] + st %g2, [%o0 + 4] 8: - ld [%i1 + 8], %i5 - sll %i3, %g4, %g2 - srl %i4, %l0, %g5 + ld [%o1 + 8], %o5 + sll %o3, %g4, %g2 + srl %o4, %g7, %g5 or %g2, %g5, %g2 - st %g2, [%i0 + 8] + st %g2, [%o0 + 8] 9: - ld [%i1 + 12], %g1 - sll %i4, %g4, %g2 - srl %i5, %l0, %g5 + ld [%o1 + 12], %g1 + sll %o4, %g4, %g2 + srl %o5, %g7, %g5 addcc %g3, -4, %g3 or %g2, %g5, %g2 - add %i1, 16, %i1 - st %g2, [%i0 + 12] - add %i0, 16, %i0 + add %o1, 16, %o1 + st %g2, [%o0 + 12] + add %o0, 16, %o0 bne,a 5b - ld [%i1], %i3 + ld [%o1], %o3 10: - sll %i5, %g4, %g2 - srl %g1, %l0, %g5 - srl %l0, 3, %g3 + sll %o5, %g4, %g2 + srl %g1, %g7, %g5 + srl %g7, 3, %g3 or %g2, %g5, %g2 - sub %i1, %g3, %i1 - andcc %i2, 2, %g0 - st %g2, [%i0] + sub %o1, %g3, %o1 + andcc %o2, 2, %g0 + st %g2, [%o0] be 1f - andcc %i2, 1, %g0 - - ldub [%i1], %g2 - add %i1, 2, %i1 - stb %g2, [%i0 + 4] - add %i0, 2, %i0 - ldub [%i1 - 1], %g2 - stb %g2, [%i0 + 3] + andcc %o2, 1, %g0 + + ldub [%o1], %g2 + add %o1, 2, %o1 + stb %g2, [%o0 + 4] + add %o0, 2, %o0 + ldub [%o1 - 1], %g2 + stb %g2, [%o0 + 3] 1: be 1f nop - ldub [%i1], %g2 - stb %g2, [%i0 + 4] + ldub [%o1], %g2 + stb %g2, [%o0 + 4] +1: + retl + RETL_INSN + +#ifdef FASTER_NONALIGNED + +87: /* faster_nonaligned */ + + andcc %o1, 3, %g0 + be 3f + andcc %o1, 1, %g0 + + be 4f + andcc %o1, 2, %g0 + + ldub [%o1], %g2 + add %o1, 1, %o1 + stb %g2, [%o0] + sub %o2, 1, %o2 + bne 3f + add %o0, 1, %o0 +4: + lduh [%o1], %g2 + add %o1, 2, %o1 + srl %g2, 8, %g3 + sub %o2, 2, %o2 + stb %g3, [%o0] + add %o0, 2, %o0 + stb %g2, [%o0 - 1] +3: + andcc %o1, 4, %g0 + + bne 2f + cmp %o5, 1 + + ld [%o1], %o4 + srl %o4, 24, %g2 + stb %g2, [%o0] + srl %o4, 16, %g3 + stb %g3, [%o0 + 1] + srl %o4, 8, %g2 + stb %g2, [%o0 + 2] + sub %o2, 4, %o2 + stb %o4, [%o0 + 3] + add %o1, 4, %o1 + add %o0, 4, %o0 +2: + be 33f + cmp %o5, 2 + be 32f + sub %o2, 4, %o2 +31: + ld [%o1], %g2 + add %o1, 4, %o1 + srl %g2, 24, %g3 + and %o0, 7, %g5 + stb %g3, [%o0] + cmp %g5, 7 + sll %g2, 8, %g1 + add %o0, 4, %o0 + be 41f + and %o2, 0xffffffc0, %o3 + ld [%o0 - 7], %o4 +4: + SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) + SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) + SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) + SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) + subcc %o3, 64, %o3 + add %o1, 64, %o1 + bne 4b + add %o0, 64, %o0 + + andcc %o2, 0x30, %o3 + be,a 1f + srl %g1, 16, %g2 +4: + SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) + subcc %o3, 16, %o3 + add %o1, 16, %o1 + bne 4b + add %o0, 16, %o0 + + srl %g1, 16, %g2 +1: + st %o4, [%o0 - 7] + sth %g2, [%o0 - 3] + srl %g1, 8, %g4 + b 88f + stb %g4, [%o0 - 1] +32: + ld [%o1], %g2 + add %o1, 4, %o1 + srl %g2, 16, %g3 + and %o0, 7, %g5 + sth %g3, [%o0] + cmp %g5, 6 + sll %g2, 16, %g1 + add %o0, 4, %o0 + be 42f + and %o2, 0xffffffc0, %o3 + ld [%o0 - 6], %o4 +4: + SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) + SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) + SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) + SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) + subcc %o3, 64, %o3 + add %o1, 64, %o1 + bne 4b + add %o0, 64, %o0 + + andcc %o2, 0x30, %o3 + be,a 1f + srl %g1, 16, %g2 +4: + SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) + subcc %o3, 16, %o3 + add %o1, 16, %o1 + bne 4b + add %o0, 16, %o0 + + srl %g1, 16, %g2 +1: + st %o4, [%o0 - 6] + b 88f + sth %g2, [%o0 - 2] +33: + ld [%o1], %g2 + sub %o2, 4, %o2 + srl %g2, 24, %g3 + and %o0, 7, %g5 + stb %g3, [%o0] + cmp %g5, 5 + srl %g2, 8, %g4 + sll %g2, 24, %g1 + sth %g4, [%o0 + 1] + add %o1, 4, %o1 + be 43f + and %o2, 0xffffffc0, %o3 + + ld [%o0 - 1], %o4 + add %o0, 4, %o0 +4: + SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1) + SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1) + SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1) + SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1) + subcc %o3, 64, %o3 + add %o1, 64, %o1 + bne 4b + add %o0, 64, %o0 + + andcc %o2, 0x30, %o3 + be,a 1f + srl %g1, 24, %g2 +4: + SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1) + subcc %o3, 16, %o3 + add %o1, 16, %o1 + bne 4b + add %o0, 16, %o0 + + srl %g1, 24, %g2 +1: + st %o4, [%o0 - 5] + b 88f + stb %g2, [%o0 - 1] +41: + SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) + SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) + SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) + SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) + subcc %o3, 64, %o3 + add %o1, 64, %o1 + bne 41b + add %o0, 64, %o0 + + andcc %o2, 0x30, %o3 + be,a 1f + srl %g1, 16, %g2 +4: + SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) + subcc %o3, 16, %o3 + add %o1, 16, %o1 + bne 4b + add %o0, 16, %o0 + + srl %g1, 16, %g2 1: - ret - restore %g7, %g0, %o0 + sth %g2, [%o0 - 3] + srl %g1, 8, %g4 + b 88f + stb %g4, [%o0 - 1] +43: + SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3) + SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3) + SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3) + SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3) + subcc %o3, 64, %o3 + add %o1, 64, %o1 + bne 43b + add %o0, 64, %o0 + + andcc %o2, 0x30, %o3 + be,a 1f + srl %g1, 24, %g2 +4: + SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3) + subcc %o3, 16, %o3 + add %o1, 16, %o1 + bne 4b + add %o0, 16, %o0 + + srl %g1, 24, %g2 +1: + stb %g2, [%o0 + 3] + b 88f + add %o0, 4, %o0 +42: + SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) + SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) + SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) + SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) + subcc %o3, 64, %o3 + add %o1, 64, %o1 + bne 42b + add %o0, 64, %o0 + + andcc %o2, 0x30, %o3 + be,a 1f + srl %g1, 16, %g2 +4: + SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) + subcc %o3, 16, %o3 + add %o1, 16, %o1 + bne 4b + add %o0, 16, %o0 + + srl %g1, 16, %g2 +1: + sth %g2, [%o0 - 2] + + /* Fall through */ + +#endif /* FASTER_NONALIGNED */ 88: /* short_end */ @@ -521,7 +1127,7 @@ FUNC(memcpy) /* %o0=dst %o1=src %o2=len */ stb %g2, [%o0] 1: retl - mov %g7, %o0 + RETL_INSN 90: /* short_aligned_end */ bne 88b diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile index 3b6e248650d4..79836a7dd00c 100644 --- a/arch/sparc/mm/Makefile +++ b/arch/sparc/mm/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_SPARC64) += ultra.o tlb.o tsb.o obj-y += fault_$(BITS).o obj-y += init_$(BITS).o obj-$(CONFIG_SPARC32) += loadmmu.o +obj-y += generic_$(BITS).o obj-$(CONFIG_SPARC32) += extable.o btfixup.o srmmu.o iommu.o io-unit.o obj-$(CONFIG_SPARC32) += hypersparc.o viking.o tsunami.o swift.o obj-$(CONFIG_SPARC_LEON)+= leon_mm.o diff --git a/arch/sparc/mm/btfixup.c b/arch/sparc/mm/btfixup.c index 8a7f81743c12..5175ac2f4820 100644 --- a/arch/sparc/mm/btfixup.c +++ b/arch/sparc/mm/btfixup.c @@ -302,7 +302,8 @@ void __init btfixup(void) case 'i': /* INT */ if ((insn & 0xc1c00000) == 0x01000000) /* %HI */ set_addr(addr, q[1], fmangled, (insn & 0xffc00000) | (p[1] >> 10)); - else if ((insn & 0x80002000) == 0x80002000) /* %LO */ + else if ((insn & 0x80002000) == 0x80002000 && + (insn & 0x01800000) != 0x01800000) /* %LO */ set_addr(addr, q[1], fmangled, (insn & 0xffffe000) | (p[1] & 0x3ff)); else { prom_printf(insn_i, p, addr, insn); diff --git a/arch/sparc/mm/generic_32.c b/arch/sparc/mm/generic_32.c new file mode 100644 index 000000000000..e6067b75f11c --- /dev/null +++ b/arch/sparc/mm/generic_32.c @@ -0,0 +1,98 @@ +/* + * generic.c: Generic Sparc mm routines that are not dependent upon + * MMU type but are Sparc specific. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* Remap IO memory, the same way as remap_pfn_range(), but use + * the obio memory space. + * + * They use a pgprot that sets PAGE_IO and does not check the + * mem_map table as this is independent of normal memory. + */ +static inline void io_remap_pte_range(struct mm_struct *mm, pte_t * pte, unsigned long address, unsigned long size, + unsigned long offset, pgprot_t prot, int space) +{ + unsigned long end; + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + do { + set_pte_at(mm, address, pte, mk_pte_io(offset, prot, space)); + address += PAGE_SIZE; + offset += PAGE_SIZE; + pte++; + } while (address < end); +} + +static inline int io_remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size, + unsigned long offset, pgprot_t prot, int space) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + offset -= address; + do { + pte_t *pte = pte_alloc_map(mm, NULL, pmd, address); + if (!pte) + return -ENOMEM; + io_remap_pte_range(mm, pte, address, end - address, address + offset, prot, space); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address < end); + return 0; +} + +int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, + unsigned long pfn, unsigned long size, pgprot_t prot) +{ + int error = 0; + pgd_t * dir; + unsigned long beg = from; + unsigned long end = from + size; + struct mm_struct *mm = vma->vm_mm; + int space = GET_IOSPACE(pfn); + unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT; + + /* See comment in mm/memory.c remap_pfn_range */ + vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP; + vma->vm_pgoff = (offset >> PAGE_SHIFT) | + ((unsigned long)space << 28UL); + + offset -= from; + dir = pgd_offset(mm, from); + flush_cache_range(vma, beg, end); + + while (from < end) { + pmd_t *pmd = pmd_alloc(mm, dir, from); + error = -ENOMEM; + if (!pmd) + break; + error = io_remap_pmd_range(mm, pmd, from, end - from, offset + from, prot, space); + if (error) + break; + from = (from + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } + + flush_tlb_range(vma, beg, end); + return error; +} +EXPORT_SYMBOL(io_remap_pfn_range); diff --git a/arch/sparc/mm/generic_64.c b/arch/sparc/mm/generic_64.c new file mode 100644 index 000000000000..3cb00dfd4bd6 --- /dev/null +++ b/arch/sparc/mm/generic_64.c @@ -0,0 +1,164 @@ +/* + * generic.c: Generic Sparc mm routines that are not dependent upon + * MMU type but are Sparc specific. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Remap IO memory, the same way as remap_pfn_range(), but use + * the obio memory space. + * + * They use a pgprot that sets PAGE_IO and does not check the + * mem_map table as this is independent of normal memory. + */ +static inline void io_remap_pte_range(struct mm_struct *mm, pte_t * pte, + unsigned long address, + unsigned long size, + unsigned long offset, pgprot_t prot, + int space) +{ + unsigned long end; + + /* clear hack bit that was used as a write_combine side-effect flag */ + offset &= ~0x1UL; + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + do { + pte_t entry; + unsigned long curend = address + PAGE_SIZE; + + entry = mk_pte_io(offset, prot, space, PAGE_SIZE); + if (!(address & 0xffff)) { + if (PAGE_SIZE < (4 * 1024 * 1024) && + !(address & 0x3fffff) && + !(offset & 0x3ffffe) && + end >= address + 0x400000) { + entry = mk_pte_io(offset, prot, space, + 4 * 1024 * 1024); + curend = address + 0x400000; + offset += 0x400000; + } else if (PAGE_SIZE < (512 * 1024) && + !(address & 0x7ffff) && + !(offset & 0x7fffe) && + end >= address + 0x80000) { + entry = mk_pte_io(offset, prot, space, + 512 * 1024 * 1024); + curend = address + 0x80000; + offset += 0x80000; + } else if (PAGE_SIZE < (64 * 1024) && + !(offset & 0xfffe) && + end >= address + 0x10000) { + entry = mk_pte_io(offset, prot, space, + 64 * 1024); + curend = address + 0x10000; + offset += 0x10000; + } else + offset += PAGE_SIZE; + } else + offset += PAGE_SIZE; + + if (pte_write(entry)) + entry = pte_mkdirty(entry); + do { + BUG_ON(!pte_none(*pte)); + set_pte_at(mm, address, pte, entry); + address += PAGE_SIZE; + pte_val(entry) += PAGE_SIZE; + pte++; + } while (address < curend); + } while (address < end); +} + +static inline int io_remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size, + unsigned long offset, pgprot_t prot, int space) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + offset -= address; + do { + pte_t *pte = pte_alloc_map(mm, NULL, pmd, address); + if (!pte) + return -ENOMEM; + io_remap_pte_range(mm, pte, address, end - address, address + offset, prot, space); + pte_unmap(pte); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address < end); + return 0; +} + +static inline int io_remap_pud_range(struct mm_struct *mm, pud_t * pud, unsigned long address, unsigned long size, + unsigned long offset, pgprot_t prot, int space) +{ + unsigned long end; + + address &= ~PUD_MASK; + end = address + size; + if (end > PUD_SIZE) + end = PUD_SIZE; + offset -= address; + do { + pmd_t *pmd = pmd_alloc(mm, pud, address); + if (!pud) + return -ENOMEM; + io_remap_pmd_range(mm, pmd, address, end - address, address + offset, prot, space); + address = (address + PUD_SIZE) & PUD_MASK; + pud++; + } while (address < end); + return 0; +} + +int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, + unsigned long pfn, unsigned long size, pgprot_t prot) +{ + int error = 0; + pgd_t * dir; + unsigned long beg = from; + unsigned long end = from + size; + struct mm_struct *mm = vma->vm_mm; + int space = GET_IOSPACE(pfn); + unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT; + unsigned long phys_base; + + phys_base = offset | (((unsigned long) space) << 32UL); + + /* See comment in mm/memory.c remap_pfn_range */ + vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP; + vma->vm_pgoff = phys_base >> PAGE_SHIFT; + + offset -= from; + dir = pgd_offset(mm, from); + flush_cache_range(vma, beg, end); + + while (from < end) { + pud_t *pud = pud_alloc(mm, dir, from); + error = -ENOMEM; + if (!pud) + break; + error = io_remap_pud_range(mm, pud, from, end - from, offset + from, prot, space); + if (error) + break; + from = (from + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } + + flush_tlb_range(vma, beg, end); + return error; +} +EXPORT_SYMBOL(io_remap_pfn_range); diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 6ff4d78d8591..3fd8e18bed80 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -511,11 +511,6 @@ static void __init read_obp_translations(void) for (i = 0; i < prom_trans_ents; i++) prom_trans[i].data &= ~0x0003fe0000000000UL; } - - /* Force execute bit on. */ - for (i = 0; i < prom_trans_ents; i++) - prom_trans[i].data |= (tlb_type == hypervisor ? - _PAGE_EXEC_4V : _PAGE_EXEC_4U); } static void __init hypervisor_tlb_lock(unsigned long vaddr, @@ -1602,44 +1597,6 @@ static void __init tsb_phys_patch(void) static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR]; extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; -static void patch_one_ktsb_phys(unsigned int *start, unsigned int *end, unsigned long pa) -{ - pa >>= KTSB_PHYS_SHIFT; - - while (start < end) { - unsigned int *ia = (unsigned int *)(unsigned long)*start; - - ia[0] = (ia[0] & ~0x3fffff) | (pa >> 10); - __asm__ __volatile__("flush %0" : : "r" (ia)); - - ia[1] = (ia[1] & ~0x3ff) | (pa & 0x3ff); - __asm__ __volatile__("flush %0" : : "r" (ia + 1)); - - start++; - } -} - -static void ktsb_phys_patch(void) -{ - extern unsigned int __swapper_tsb_phys_patch; - extern unsigned int __swapper_tsb_phys_patch_end; - unsigned long ktsb_pa; - - ktsb_pa = kern_base + ((unsigned long)&swapper_tsb[0] - KERNBASE); - patch_one_ktsb_phys(&__swapper_tsb_phys_patch, - &__swapper_tsb_phys_patch_end, ktsb_pa); -#ifndef CONFIG_DEBUG_PAGEALLOC - { - extern unsigned int __swapper_4m_tsb_phys_patch; - extern unsigned int __swapper_4m_tsb_phys_patch_end; - ktsb_pa = (kern_base + - ((unsigned long)&swapper_4m_tsb[0] - KERNBASE)); - patch_one_ktsb_phys(&__swapper_4m_tsb_phys_patch, - &__swapper_4m_tsb_phys_patch_end, ktsb_pa); - } -#endif -} - static void __init sun4v_ktsb_init(void) { unsigned long ktsb_pa; @@ -1759,10 +1716,8 @@ void __init paging_init(void) sun4u_pgprot_init(); if (tlb_type == cheetah_plus || - tlb_type == hypervisor) { + tlb_type == hypervisor) tsb_phys_patch(); - ktsb_phys_patch(); - } if (tlb_type == hypervisor) { sun4v_patch_tlb_handlers(); @@ -2118,9 +2073,6 @@ EXPORT_SYMBOL(_PAGE_CACHE); #ifdef CONFIG_SPARSEMEM_VMEMMAP unsigned long vmemmap_table[VMEMMAP_SIZE]; -static long __meminitdata addr_start, addr_end; -static int __meminitdata node_start; - int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node) { unsigned long vstart = (unsigned long) start; @@ -2151,30 +2103,15 @@ int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node) *vmem_pp = pte_base | __pa(block); - /* check to see if we have contiguous blocks */ - if (addr_end != addr || node_start != node) { - if (addr_start) - printk(KERN_DEBUG " [%lx-%lx] on node %d\n", - addr_start, addr_end-1, node_start); - addr_start = addr; - node_start = node; - } - addr_end = addr + VMEMMAP_CHUNK; + printk(KERN_INFO "[%p-%p] page_structs=%lu " + "node=%d entry=%lu/%lu\n", start, block, nr, + node, + addr >> VMEMMAP_CHUNK_SHIFT, + VMEMMAP_SIZE); } } return 0; } - -void __meminit vmemmap_populate_print_last(void) -{ - if (addr_start) { - printk(KERN_DEBUG " [%lx-%lx] on node %d\n", - addr_start, addr_end-1, node_start); - addr_start = 0; - addr_end = 0; - node_start = 0; - } -} #endif /* CONFIG_SPARSEMEM_VMEMMAP */ static void prot_init_common(unsigned long page_none, diff --git a/arch/sparc/mm/ultra.S b/arch/sparc/mm/ultra.S index 874162a11ceb..b57a5942ba64 100644 --- a/arch/sparc/mm/ultra.S +++ b/arch/sparc/mm/ultra.S @@ -495,11 +495,11 @@ xcall_fetch_glob_regs: stx %o7, [%g1 + GR_SNAP_O7] stx %i7, [%g1 + GR_SNAP_I7] /* Don't try this at home kids... */ - rdpr %cwp, %g3 - sub %g3, 1, %g7 + rdpr %cwp, %g2 + sub %g2, 1, %g7 wrpr %g7, %cwp mov %i7, %g7 - wrpr %g3, %cwp + wrpr %g2, %cwp stx %g7, [%g1 + GR_SNAP_RPC] sethi %hi(trap_block), %g7 or %g7, %lo(trap_block), %g7 diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 532a2a42ab7e..0249b8b4db54 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -11,7 +11,6 @@ config TILE select GENERIC_IRQ_PROBE select GENERIC_PENDING_IRQ if SMP select GENERIC_IRQ_SHOW - select HAVE_SYSCALL_WRAPPERS if TILEGX select SYS_HYPERVISOR # FIXME: investigate whether we need/want these options. diff --git a/arch/tile/Makefile b/arch/tile/Makefile index 04c637c4eb43..17acce70569b 100644 --- a/arch/tile/Makefile +++ b/arch/tile/Makefile @@ -26,10 +26,6 @@ $(error Set TILERA_ROOT or CROSS_COMPILE when building $(ARCH) on $(HOST_ARCH)) endif endif -# The tile compiler may emit .eh_frame information for backtracing. -# In kernel modules, this causes load failures due to unsupported relocations. -KBUILD_CFLAGS += -fno-asynchronous-unwind-tables - ifneq ($(CONFIG_DEBUG_EXTRA_FLAGS),"") KBUILD_CFLAGS += $(CONFIG_DEBUG_EXTRA_FLAGS) endif diff --git a/arch/tile/include/asm/bitops.h b/arch/tile/include/asm/bitops.h index bd186c4eaa50..16f1fa51fea1 100644 --- a/arch/tile/include/asm/bitops.h +++ b/arch/tile/include/asm/bitops.h @@ -77,11 +77,6 @@ static inline int ffs(int x) return __builtin_ffs(x); } -static inline int fls64(__u64 w) -{ - return (sizeof(__u64) * 8) - __builtin_clzll(w); -} - /** * fls - find last set bit in word * @x: the word to search @@ -95,7 +90,12 @@ static inline int fls64(__u64 w) */ static inline int fls(int x) { - return fls64((unsigned int) x); + return (sizeof(int) * 8) - __builtin_clz(x); +} + +static inline int fls64(__u64 w) +{ + return (sizeof(__u64) * 8) - __builtin_clzll(w); } static inline unsigned int __arch_hweight32(unsigned int w) diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c index 41459d80b6bf..a7869ad62776 100644 --- a/arch/tile/kernel/compat_signal.c +++ b/arch/tile/kernel/compat_signal.c @@ -406,17 +406,19 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, * Set up registers for signal handler. * Registers that we don't modify keep the value they had from * user-space at the time we took the signal. - * We always pass siginfo and mcontext, regardless of SA_SIGINFO, - * since some things rely on this (e.g. glibc's debug/segfault.c). */ regs->pc = ptr_to_compat_reg(ka->sa.sa_handler); regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */ regs->sp = ptr_to_compat_reg(frame); regs->lr = restorer; regs->regs[0] = (unsigned long) usig; - regs->regs[1] = ptr_to_compat_reg(&frame->info); - regs->regs[2] = ptr_to_compat_reg(&frame->uc); - regs->flags |= PT_FLAGS_CALLER_SAVES; + + if (ka->sa.sa_flags & SA_SIGINFO) { + /* Need extra arguments, so mark to restore caller-saves. */ + regs->regs[1] = ptr_to_compat_reg(&frame->info); + regs->regs[2] = ptr_to_compat_reg(&frame->uc); + regs->flags |= PT_FLAGS_CALLER_SAVES; + } /* * Notify any tracer that was single-stepping it. diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 0491e40d6968..620f5b70957d 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -513,37 +513,8 @@ __uml_exitcall(kill_io_thread); static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) { char *file; - int fd; - int err; - - __u32 version; - __u32 align; - char *backing_file; - time_t mtime; - unsigned long long size; - int sector_size; - int bitmap_offset; - - if (ubd_dev->file && ubd_dev->cow.file) { - file = ubd_dev->cow.file; - - goto out; - } - fd = os_open_file(ubd_dev->file, global_openflags, 0); - if (fd < 0) - return fd; - - err = read_cow_header(file_reader, &fd, &version, &backing_file, \ - &mtime, &size, §or_size, &align, &bitmap_offset); - os_close_file(fd); - - if(err == -EINVAL) - file = ubd_dev->file; - else - file = backing_file; - -out: + file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file; return os_file_size(file, size_out); } diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h index aa365c55ecf9..41474fb5eee7 100644 --- a/arch/um/include/asm/pgtable.h +++ b/arch/um/include/asm/pgtable.h @@ -271,12 +271,6 @@ static inline void set_pte(pte_t *pteptr, pte_t pteval) } #define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) -#define __HAVE_ARCH_PTE_SAME -static inline int pte_same(pte_t pte_a, pte_t pte_b) -{ - return !((pte_val(pte_a) ^ pte_val(pte_b)) & ~_PAGE_NEWPAGE); -} - /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. @@ -352,11 +346,11 @@ extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr); #define update_mmu_cache(vma,address,ptep) do ; while (0) /* Encode and de-code a swap entry */ -#define __swp_type(x) (((x).val >> 5) & 0x1f) +#define __swp_type(x) (((x).val >> 4) & 0x3f) #define __swp_offset(x) ((x).val >> 11) #define __swp_entry(type, offset) \ - ((swp_entry_t) { ((type) << 5) | ((offset) << 11) }) + ((swp_entry_t) { ((type) << 4) | ((offset) << 11) }) #define __pte_to_swp_entry(pte) \ ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index a0e9bda72fda..37357a599dca 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1451,15 +1451,6 @@ config ARCH_USES_PG_UNCACHED def_bool y depends on X86_PAT -config ARCH_RANDOM - def_bool y - prompt "x86 architectural random number generator" if EXPERT - ---help--- - Enable the x86 architectural RDRAND instruction - (Intel Bull Mountain technology) to generate random numbers. - If supported, this is a high bandwidth, cryptographically - secure hardware random number generator. - config EFI bool "EFI runtime service support" depends on ACPI diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S index 3470624d7835..be6d9e365a80 100644 --- a/arch/x86/crypto/aesni-intel_asm.S +++ b/arch/x86/crypto/aesni-intel_asm.S @@ -2460,12 +2460,10 @@ ENTRY(aesni_cbc_dec) pxor IN3, STATE4 movaps IN4, IV #else + pxor (INP), STATE2 + pxor 0x10(INP), STATE3 pxor IN1, STATE4 movaps IN2, IV - movups (INP), IN1 - pxor IN1, STATE2 - movups 0x10(INP), IN2 - pxor IN2, STATE3 #endif movups STATE1, (OUTP) movups STATE2, 0x10(OUTP) diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 26af1e316290..c1870dddd322 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -208,7 +208,7 @@ sysexit_from_sys_call: testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),TI_flags(%r10) jnz ia32_ret_from_sys_call TRACE_IRQS_ON - ENABLE_INTERRUPTS(CLBR_NONE) + sti movl %eax,%esi /* second arg, syscall return value */ cmpl $0,%eax /* is it < 0? */ setl %al /* 1 if so, 0 if not */ @@ -218,7 +218,7 @@ sysexit_from_sys_call: GET_THREAD_INFO(%r10) movl RAX-ARGOFFSET(%rsp),%eax /* reload syscall return value */ movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),%edi - DISABLE_INTERRUPTS(CLBR_NONE) + cli TRACE_IRQS_OFF testl %edi,TI_flags(%r10) jz \exit diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h index 78a1eff74223..67f87f257611 100644 --- a/arch/x86/include/asm/amd_nb.h +++ b/arch/x86/include/asm/amd_nb.h @@ -1,7 +1,6 @@ #ifndef _ASM_X86_AMD_NB_H #define _ASM_X86_AMD_NB_H -#include #include struct amd_nb_bus_dev_range { @@ -14,7 +13,6 @@ extern const struct pci_device_id amd_nb_misc_ids[]; extern const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[]; extern bool early_is_amd_nb(u32 value); -extern struct resource *amd_get_mmconfig_range(struct resource *res); extern int amd_cache_northbridges(void); extern void amd_flush_garts(void); extern int amd_numa_init(void); diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 244ac77eee8d..4a0b7c7e2cce 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -495,7 +495,7 @@ static inline void default_wait_for_init_deassert(atomic_t *deassert) return; } -extern void generic_bigsmp_probe(void); +extern struct apic *generic_bigsmp_probe(void); #ifdef CONFIG_X86_LOCAL_APIC diff --git a/arch/x86/include/asm/archrandom.h b/arch/x86/include/asm/archrandom.h deleted file mode 100644 index 0d9ec770f2f8..000000000000 --- a/arch/x86/include/asm/archrandom.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is part of the Linux kernel. - * - * Copyright (c) 2011, Intel Corporation - * Authors: Fenghua Yu , - * H. Peter Anvin - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#ifndef ASM_X86_ARCHRANDOM_H -#define ASM_X86_ARCHRANDOM_H - -#include -#include -#include -#include - -#define RDRAND_RETRY_LOOPS 10 - -#define RDRAND_INT ".byte 0x0f,0xc7,0xf0" -#ifdef CONFIG_X86_64 -# define RDRAND_LONG ".byte 0x48,0x0f,0xc7,0xf0" -#else -# define RDRAND_LONG RDRAND_INT -#endif - -#ifdef CONFIG_ARCH_RANDOM - -#define GET_RANDOM(name, type, rdrand, nop) \ -static inline int name(type *v) \ -{ \ - int ok; \ - alternative_io("movl $0, %0\n\t" \ - nop, \ - "\n1: " rdrand "\n\t" \ - "jc 2f\n\t" \ - "decl %0\n\t" \ - "jnz 1b\n\t" \ - "2:", \ - X86_FEATURE_RDRAND, \ - ASM_OUTPUT2("=r" (ok), "=a" (*v)), \ - "0" (RDRAND_RETRY_LOOPS)); \ - return ok; \ -} - -#ifdef CONFIG_X86_64 - -GET_RANDOM(arch_get_random_long, unsigned long, RDRAND_LONG, ASM_NOP5); -GET_RANDOM(arch_get_random_int, unsigned int, RDRAND_INT, ASM_NOP4); - -#else - -GET_RANDOM(arch_get_random_long, unsigned long, RDRAND_LONG, ASM_NOP3); -GET_RANDOM(arch_get_random_int, unsigned int, RDRAND_INT, ASM_NOP3); - -#endif /* CONFIG_X86_64 */ - -#endif /* CONFIG_ARCH_RANDOM */ - -extern void x86_init_rdrand(struct cpuinfo_x86 *c); - -#endif /* ASM_X86_ARCHRANDOM_H */ diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index c5d941f08bac..71cc3800712c 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -173,7 +173,7 @@ #define X86_FEATURE_XSAVEOPT (7*32+ 4) /* Optimized Xsave */ #define X86_FEATURE_PLN (7*32+ 5) /* Intel Power Limit Notification */ #define X86_FEATURE_PTS (7*32+ 6) /* Intel Package Thermal Status */ -#define X86_FEATURE_DTHERM (7*32+ 7) /* Digital Thermal Sensor */ +#define X86_FEATURE_DTS (7*32+ 7) /* Digital Thermal Sensor */ /* Virtualization flags: Linux defined, word 8 */ #define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */ diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h index a850b4d8d14d..c9e09ea05644 100644 --- a/arch/x86/include/asm/i387.h +++ b/arch/x86/include/asm/i387.h @@ -29,8 +29,8 @@ extern unsigned int sig_xstate_size; extern void fpu_init(void); extern void mxcsr_feature_mask_init(void); extern int init_fpu(struct task_struct *child); -extern void __math_state_restore(struct task_struct *); -extern void math_state_restore(void); +extern asmlinkage void math_state_restore(void); +extern void __math_state_restore(void); extern int dump_fpu(struct pt_regs *, struct user_i387_struct *); extern user_regset_active_fn fpregs_active, xfpregs_active; @@ -212,11 +212,19 @@ static inline void fpu_fxsave(struct fpu *fpu) #endif /* CONFIG_X86_64 */ +/* We need a safe address that is cheap to find and that is already + in L1 during context switch. The best choices are unfortunately + different for UP and SMP */ +#ifdef CONFIG_SMP +#define safe_address (__per_cpu_offset[0]) +#else +#define safe_address (kstat_cpu(0).cpustat.user) +#endif + /* - * These must be called with preempt disabled. Returns - * 'true' if the FPU state is still intact. + * These must be called with preempt disabled */ -static inline int fpu_save_init(struct fpu *fpu) +static inline void fpu_save_init(struct fpu *fpu) { if (use_xsave()) { fpu_xsave(fpu); @@ -225,33 +233,33 @@ static inline int fpu_save_init(struct fpu *fpu) * xsave header may indicate the init state of the FP. */ if (!(fpu->state->xsave.xsave_hdr.xstate_bv & XSTATE_FP)) - return 1; + return; } else if (use_fxsr()) { fpu_fxsave(fpu); } else { asm volatile("fnsave %[fx]; fwait" : [fx] "=m" (fpu->state->fsave)); - return 0; + return; } - /* - * If exceptions are pending, we need to clear them so - * that we don't randomly get exceptions later. - * - * FIXME! Is this perhaps only true for the old-style - * irq13 case? Maybe we could leave the x87 state - * intact otherwise? - */ - if (unlikely(fpu->state->fxsave.swd & X87_FSW_ES)) { + if (unlikely(fpu->state->fxsave.swd & X87_FSW_ES)) asm volatile("fnclex"); - return 0; - } - return 1; + + /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception + is pending. Clear the x87 state here by setting it to fixed + values. safe_address is a random variable that should be in L1 */ + alternative_input( + ASM_NOP8 ASM_NOP2, + "emms\n\t" /* clear stack tags */ + "fildl %P[addr]", /* set F?P to defined value */ + X86_FEATURE_FXSAVE_LEAK, + [addr] "m" (safe_address)); } -static inline int __save_init_fpu(struct task_struct *tsk) +static inline void __save_init_fpu(struct task_struct *tsk) { - return fpu_save_init(&tsk->thread.fpu); + fpu_save_init(&tsk->thread.fpu); + task_thread_info(tsk)->status &= ~TS_USEDFPU; } static inline int fpu_fxrstor_checking(struct fpu *fpu) @@ -272,186 +280,40 @@ static inline int restore_fpu_checking(struct task_struct *tsk) return fpu_restore_checking(&tsk->thread.fpu); } -/* - * Software FPU state helpers. Careful: these need to - * be preemption protection *and* they need to be - * properly paired with the CR0.TS changes! - */ -static inline int __thread_has_fpu(struct task_struct *tsk) -{ - return tsk->thread.has_fpu; -} - -/* Must be paired with an 'stts' after! */ -static inline void __thread_clear_has_fpu(struct task_struct *tsk) -{ - tsk->thread.has_fpu = 0; -} - -/* Must be paired with a 'clts' before! */ -static inline void __thread_set_has_fpu(struct task_struct *tsk) -{ - tsk->thread.has_fpu = 1; -} - -/* - * Encapsulate the CR0.TS handling together with the - * software flag. - * - * These generally need preemption protection to work, - * do try to avoid using these on their own. - */ -static inline void __thread_fpu_end(struct task_struct *tsk) -{ - __thread_clear_has_fpu(tsk); - stts(); -} - -static inline void __thread_fpu_begin(struct task_struct *tsk) -{ - clts(); - __thread_set_has_fpu(tsk); -} - -/* - * FPU state switching for scheduling. - * - * This is a two-stage process: - * - * - switch_fpu_prepare() saves the old state and - * sets the new state of the CR0.TS bit. This is - * done within the context of the old process. - * - * - switch_fpu_finish() restores the new state as - * necessary. - */ -typedef struct { int preload; } fpu_switch_t; - -/* - * FIXME! We could do a totally lazy restore, but we need to - * add a per-cpu "this was the task that last touched the FPU - * on this CPU" variable, and the task needs to have a "I last - * touched the FPU on this CPU" and check them. - * - * We don't do that yet, so "fpu_lazy_restore()" always returns - * false, but some day.. - */ -#define fpu_lazy_restore(tsk) (0) -#define fpu_lazy_state_intact(tsk) do { } while (0) - -static inline fpu_switch_t switch_fpu_prepare(struct task_struct *old, struct task_struct *new) -{ - fpu_switch_t fpu; - - fpu.preload = tsk_used_math(new) && new->fpu_counter > 5; - if (__thread_has_fpu(old)) { - if (__save_init_fpu(old)) - fpu_lazy_state_intact(old); - __thread_clear_has_fpu(old); - old->fpu_counter++; - - /* Don't change CR0.TS if we just switch! */ - if (fpu.preload) { - __thread_set_has_fpu(new); - prefetch(new->thread.fpu.state); - } else - stts(); - } else { - old->fpu_counter = 0; - if (fpu.preload) { - if (fpu_lazy_restore(new)) - fpu.preload = 0; - else - prefetch(new->thread.fpu.state); - __thread_fpu_begin(new); - } - } - return fpu; -} - -/* - * By the time this gets called, we've already cleared CR0.TS and - * given the process the FPU if we are going to preload the FPU - * state - all we need to do is to conditionally restore the register - * state itself. - */ -static inline void switch_fpu_finish(struct task_struct *new, fpu_switch_t fpu) -{ - if (fpu.preload) - __math_state_restore(new); -} - /* * Signal frame handlers... */ extern int save_i387_xstate(void __user *buf); extern int restore_i387_xstate(void __user *buf); +static inline void __unlazy_fpu(struct task_struct *tsk) +{ + if (task_thread_info(tsk)->status & TS_USEDFPU) { + __save_init_fpu(tsk); + stts(); + } else + tsk->fpu_counter = 0; +} + static inline void __clear_fpu(struct task_struct *tsk) { - if (__thread_has_fpu(tsk)) { + if (task_thread_info(tsk)->status & TS_USEDFPU) { /* Ignore delayed exceptions from user space */ asm volatile("1: fwait\n" "2:\n" _ASM_EXTABLE(1b, 2b)); - __thread_fpu_end(tsk); + task_thread_info(tsk)->status &= ~TS_USEDFPU; + stts(); } } -/* - * Were we in an interrupt that interrupted kernel mode? - * - * We can do a kernel_fpu_begin/end() pair *ONLY* if that - * pair does nothing at all: the thread must not have fpu (so - * that we don't try to save the FPU state), and TS must - * be set (so that the clts/stts pair does nothing that is - * visible in the interrupted kernel thread). - */ -static inline bool interrupted_kernel_fpu_idle(void) -{ - return !__thread_has_fpu(current) && - (read_cr0() & X86_CR0_TS); -} - -/* - * Were we in user mode (or vm86 mode) when we were - * interrupted? - * - * Doing kernel_fpu_begin/end() is ok if we are running - * in an interrupt context from user mode - we'll just - * save the FPU state as required. - */ -static inline bool interrupted_user_mode(void) -{ - struct pt_regs *regs = get_irq_regs(); - return regs && user_mode_vm(regs); -} - -/* - * Can we use the FPU in kernel mode with the - * whole "kernel_fpu_begin/end()" sequence? - * - * It's always ok in process context (ie "not interrupt") - * but it is sometimes ok even from an irq. - */ -static inline bool irq_fpu_usable(void) -{ - return !in_interrupt() || - interrupted_user_mode() || - interrupted_kernel_fpu_idle(); -} - static inline void kernel_fpu_begin(void) { - struct task_struct *me = current; - - WARN_ON_ONCE(!irq_fpu_usable()); + struct thread_info *me = current_thread_info(); preempt_disable(); - if (__thread_has_fpu(me)) { - __save_init_fpu(me); - __thread_clear_has_fpu(me); - /* We do 'stts()' in kernel_fpu_end() */ - } else + if (me->status & TS_USEDFPU) + __save_init_fpu(me->task); + else clts(); } @@ -461,6 +323,14 @@ static inline void kernel_fpu_end(void) preempt_enable(); } +static inline bool irq_fpu_usable(void) +{ + struct pt_regs *regs; + + return !in_interrupt() || !(regs = get_irq_regs()) || \ + user_mode(regs) || (read_cr0() & X86_CR0_TS); +} + /* * Some instructions like VIA's padlock instructions generate a spurious * DNA fault but don't modify SSE registers. And these instructions @@ -492,65 +362,21 @@ static inline void irq_ts_restore(int TS_state) stts(); } -/* - * The question "does this thread have fpu access?" - * is slightly racy, since preemption could come in - * and revoke it immediately after the test. - * - * However, even in that very unlikely scenario, - * we can just assume we have FPU access - typically - * to save the FP state - we'll just take a #NM - * fault and get the FPU access back. - * - * The actual user_fpu_begin/end() functions - * need to be preemption-safe, though. - * - * NOTE! user_fpu_end() must be used only after you - * have saved the FP state, and user_fpu_begin() must - * be used only immediately before restoring it. - * These functions do not do any save/restore on - * their own. - */ -static inline int user_has_fpu(void) -{ - return __thread_has_fpu(current); -} - -static inline void user_fpu_end(void) -{ - preempt_disable(); - __thread_fpu_end(current); - preempt_enable(); -} - -static inline void user_fpu_begin(void) -{ - preempt_disable(); - if (!user_has_fpu()) - __thread_fpu_begin(current); - preempt_enable(); -} - /* * These disable preemption on their own and are safe */ static inline void save_init_fpu(struct task_struct *tsk) { - WARN_ON_ONCE(!__thread_has_fpu(tsk)); preempt_disable(); __save_init_fpu(tsk); - __thread_fpu_end(tsk); + stts(); preempt_enable(); } static inline void unlazy_fpu(struct task_struct *tsk) { preempt_disable(); - if (__thread_has_fpu(tsk)) { - __save_init_fpu(tsk); - __thread_fpu_end(tsk); - } else - tsk->fpu_counter = 0; + __unlazy_fpu(tsk); preempt_enable(); } diff --git a/arch/x86/include/asm/idle.h b/arch/x86/include/asm/idle.h index f1e4268ef3c6..f49253d75710 100644 --- a/arch/x86/include/asm/idle.h +++ b/arch/x86/include/asm/idle.h @@ -1,6 +1,13 @@ #ifndef _ASM_X86_IDLE_H #define _ASM_X86_IDLE_H +#define IDLE_START 1 +#define IDLE_END 2 + +struct notifier_block; +void idle_notifier_register(struct notifier_block *n); +void idle_notifier_unregister(struct notifier_block *n); + #ifdef CONFIG_X86_64 void enter_idle(void); void exit_idle(void); diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 0ab6a4dcb911..0049211959c0 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -189,9 +189,6 @@ struct x86_emulate_ops { int (*intercept)(struct x86_emulate_ctxt *ctxt, struct x86_instruction_info *info, enum x86_intercept_stage stage); - - bool (*get_cpuid)(struct x86_emulate_ctxt *ctxt, - u32 *eax, u32 *ebx, u32 *ecx, u32 *edx); }; typedef u32 __attribute__((vector_size(16))) sse128_t; @@ -301,19 +298,6 @@ struct x86_emulate_ctxt { #define X86EMUL_MODE_PROT (X86EMUL_MODE_PROT16|X86EMUL_MODE_PROT32| \ X86EMUL_MODE_PROT64) -/* CPUID vendors */ -#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx 0x68747541 -#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx 0x444d4163 -#define X86EMUL_CPUID_VENDOR_AuthenticAMD_edx 0x69746e65 - -#define X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx 0x69444d41 -#define X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx 0x21726574 -#define X86EMUL_CPUID_VENDOR_AMDisbetterI_edx 0x74656273 - -#define X86EMUL_CPUID_VENDOR_GenuineIntel_ebx 0x756e6547 -#define X86EMUL_CPUID_VENDOR_GenuineIntel_ecx 0x6c65746e -#define X86EMUL_CPUID_VENDOR_GenuineIntel_edx 0x49656e69 - enum x86_intercept_stage { X86_ICTP_NONE = 0, /* Allow zero-init to not match anything */ X86_ICPT_PRE_EXCEPT, diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 23a9d898baad..485b4f1f079b 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -259,9 +259,6 @@ #define MSR_IA32_TEMPERATURE_TARGET 0x000001a2 #define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0 -#define ENERGY_PERF_BIAS_PERFORMANCE 0 -#define ENERGY_PERF_BIAS_NORMAL 6 -#define ENERGY_PERF_BIAS_POWERSWAVE 15 #define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1 diff --git a/arch/x86/include/asm/pgtable-3level.h b/arch/x86/include/asm/pgtable-3level.h index 43876f16caf1..effff47a3c82 100644 --- a/arch/x86/include/asm/pgtable-3level.h +++ b/arch/x86/include/asm/pgtable-3level.h @@ -31,56 +31,6 @@ static inline void native_set_pte(pte_t *ptep, pte_t pte) ptep->pte_low = pte.pte_low; } -#define pmd_read_atomic pmd_read_atomic -/* - * pte_offset_map_lock on 32bit PAE kernels was reading the pmd_t with - * a "*pmdp" dereference done by gcc. Problem is, in certain places - * where pte_offset_map_lock is called, concurrent page faults are - * allowed, if the mmap_sem is hold for reading. An example is mincore - * vs page faults vs MADV_DONTNEED. On the page fault side - * pmd_populate rightfully does a set_64bit, but if we're reading the - * pmd_t with a "*pmdp" on the mincore side, a SMP race can happen - * because gcc will not read the 64bit of the pmd atomically. To fix - * this all places running pmd_offset_map_lock() while holding the - * mmap_sem in read mode, shall read the pmdp pointer using this - * function to know if the pmd is null nor not, and in turn to know if - * they can run pmd_offset_map_lock or pmd_trans_huge or other pmd - * operations. - * - * Without THP if the mmap_sem is hold for reading, the - * pmd can only transition from null to not null while pmd_read_atomic runs. - * So there's no need of literally reading it atomically. - * - * With THP if the mmap_sem is hold for reading, the pmd can become - * THP or null or point to a pte (and in turn become "stable") at any - * time under pmd_read_atomic, so it's mandatory to read it atomically - * with cmpxchg8b. - */ -#ifndef CONFIG_TRANSPARENT_HUGEPAGE -static inline pmd_t pmd_read_atomic(pmd_t *pmdp) -{ - pmdval_t ret; - u32 *tmp = (u32 *)pmdp; - - ret = (pmdval_t) (*tmp); - if (ret) { - /* - * If the low part is null, we must not read the high part - * or we can end up with a partial pmd. - */ - smp_rmb(); - ret |= ((pmdval_t)*(tmp + 1)) << 32; - } - - return (pmd_t) { ret }; -} -#else /* CONFIG_TRANSPARENT_HUGEPAGE */ -static inline pmd_t pmd_read_atomic(pmd_t *pmdp) -{ - return (pmd_t) { atomic64_read((atomic64_t *)pmdp) }; -} -#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ - static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte) { set_64bit((unsigned long long *)(ptep), native_pte_val(pte)); diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 6be990922d4b..18601c86fab1 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -142,16 +142,12 @@ static inline unsigned long pmd_pfn(pmd_t pmd) return (pmd_val(pmd) & PTE_PFN_MASK) >> PAGE_SHIFT; } -static inline unsigned long pud_pfn(pud_t pud) -{ - return (pud_val(pud) & PTE_PFN_MASK) >> PAGE_SHIFT; -} - #define pte_page(pte) pfn_to_page(pte_pfn(pte)) static inline int pmd_large(pmd_t pte) { - return pmd_flags(pte) & _PAGE_PSE; + return (pmd_flags(pte) & (_PAGE_PSE | _PAGE_PRESENT)) == + (_PAGE_PSE | _PAGE_PRESENT); } #ifdef CONFIG_TRANSPARENT_HUGEPAGE @@ -419,13 +415,7 @@ static inline int pte_hidden(pte_t pte) static inline int pmd_present(pmd_t pmd) { - /* - * Checking for _PAGE_PSE is needed too because - * split_huge_page will temporarily clear the present bit (but - * the _PAGE_PSE flag will remain set at all times while the - * _PAGE_PRESENT bit is clear). - */ - return pmd_flags(pmd) & (_PAGE_PRESENT | _PAGE_PROTNONE | _PAGE_PSE); + return pmd_flags(pmd) & _PAGE_PRESENT; } static inline int pmd_none(pmd_t pmd) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index e5f724834edb..219371546afd 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -99,6 +99,7 @@ struct cpuinfo_x86 { u16 apicid; u16 initial_apicid; u16 x86_clflush_size; +#ifdef CONFIG_SMP /* number of cores as seen by the OS: */ u16 booted_cores; /* Physical processor id: */ @@ -109,6 +110,7 @@ struct cpuinfo_x86 { u8 compute_unit_id; /* Index into per_cpu list: */ u16 cpu_index; +#endif } __attribute__((__aligned__(SMP_CACHE_BYTES))); #define X86_VENDOR_INTEL 0 @@ -452,7 +454,6 @@ struct thread_struct { unsigned long trap_no; unsigned long error_code; /* floating point and extended processor state */ - unsigned long has_fpu; struct fpu fpu; #ifdef CONFIG_X86_32 /* Virtual 86 mode info */ diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index f332d64cdd54..94e7618fcac8 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -187,14 +187,21 @@ static inline int v8086_mode(struct pt_regs *regs) #endif } -#ifdef CONFIG_X86_32 -extern unsigned long kernel_stack_pointer(struct pt_regs *regs); -#else +/* + * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode + * when it traps. The previous stack will be directly underneath the saved + * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'. + * + * This is valid only for kernel mode traps. + */ static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) { +#ifdef CONFIG_X86_32 + return (unsigned long)(®s->sp); +#else return regs->sp; -} #endif +} #define GET_IP(regs) ((regs)->ip) #define GET_FP(regs) ((regs)->bp) diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h index f0d89d9ba577..c2ff2a1d845e 100644 --- a/arch/x86/include/asm/system.h +++ b/arch/x86/include/asm/system.h @@ -93,6 +93,10 @@ do { \ "memory"); \ } while (0) +/* + * disable hlt during certain critical i/o operations + */ +#define HAVE_DISABLE_HLT #else /* frame pointer must be last for get_wchan */ @@ -388,6 +392,9 @@ static inline void clflush(volatile void *__p) #define nop() asm volatile ("nop") +void disable_hlt(void); +void enable_hlt(void); + void cpu_idle_wait(void); extern unsigned long arch_align_stack(unsigned long sp); diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index 278d3d5f9062..1f2e61e28981 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -242,6 +242,8 @@ static inline struct thread_info *current_thread_info(void) * ever touches our thread-synchronous status, so we don't * have to worry about atomic accesses. */ +#define TS_USEDFPU 0x0001 /* FPU was used by this task + this quantum (SMP) */ #define TS_COMPAT 0x0002 /* 32bit syscall active (64BIT)*/ #define TS_POLLING 0x0004 /* idle task polling need_resched, skip sending interrupt */ diff --git a/arch/x86/include/asm/timer.h b/arch/x86/include/asm/timer.h index 34baa0eb5d0c..fa7b9176b76c 100644 --- a/arch/x86/include/asm/timer.h +++ b/arch/x86/include/asm/timer.h @@ -32,22 +32,6 @@ extern int no_timer_check; * (mathieu.desnoyers@polymtl.ca) * * -johnstul@us.ibm.com "math is hard, lets go shopping!" - * - * In: - * - * ns = cycles * cyc2ns_scale / SC - * - * Although we may still have enough bits to store the value of ns, - * in some cases, we may not have enough bits to store cycles * cyc2ns_scale, - * leading to an incorrect result. - * - * To avoid this, we can decompose 'cycles' into quotient and remainder - * of division by SC. Then, - * - * ns = (quot * SC + rem) * cyc2ns_scale / SC - * = quot * cyc2ns_scale + (rem * cyc2ns_scale) / SC - * - * - sqazi@google.com */ DECLARE_PER_CPU(unsigned long, cyc2ns); @@ -59,8 +43,7 @@ static inline unsigned long long __cycles_2_ns(unsigned long long cyc) { int cpu = smp_processor_id(); unsigned long long ns = per_cpu(cyc2ns_offset, cpu); - ns += mult_frac(cyc, per_cpu(cyc2ns, cpu), - (1UL << CYC2NS_SCALE_FACTOR)); + ns += cyc * per_cpu(cyc2ns, cpu) >> CYC2NS_SCALE_FACTOR; return ns; } diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h index 1d4490379b55..0310da67307f 100644 --- a/arch/x86/include/asm/traps.h +++ b/arch/x86/include/asm/traps.h @@ -1,7 +1,6 @@ #ifndef _ASM_X86_TRAPS_H #define _ASM_X86_TRAPS_H -#include #include #include /* TRAP_TRACE, ... */ @@ -88,29 +87,4 @@ asmlinkage void smp_thermal_interrupt(void); asmlinkage void mce_threshold_interrupt(void); #endif -/* Interrupts/Exceptions */ -enum { - X86_TRAP_DE = 0, /* 0, Divide-by-zero */ - X86_TRAP_DB, /* 1, Debug */ - X86_TRAP_NMI, /* 2, Non-maskable Interrupt */ - X86_TRAP_BP, /* 3, Breakpoint */ - X86_TRAP_OF, /* 4, Overflow */ - X86_TRAP_BR, /* 5, Bound Range Exceeded */ - X86_TRAP_UD, /* 6, Invalid Opcode */ - X86_TRAP_NM, /* 7, Device Not Available */ - X86_TRAP_DF, /* 8, Double Fault */ - X86_TRAP_OLD_MF, /* 9, Coprocessor Segment Overrun */ - X86_TRAP_TS, /* 10, Invalid TSS */ - X86_TRAP_NP, /* 11, Segment Not Present */ - X86_TRAP_SS, /* 12, Stack Segment Fault */ - X86_TRAP_GP, /* 13, General Protection Fault */ - X86_TRAP_PF, /* 14, Page Fault */ - X86_TRAP_SPURIOUS, /* 15, Spurious Interrupt */ - X86_TRAP_MF, /* 16, x87 Floating-Point Exception */ - X86_TRAP_AC, /* 17, Alignment Check */ - X86_TRAP_MC, /* 18, Machine Check */ - X86_TRAP_XF, /* 19, SIMD Floating-Point Exception */ - X86_TRAP_IRET = 32, /* 32, IRET Exception */ -}; - #endif /* _ASM_X86_TRAPS_H */ diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index 5d62d651a628..a291c40efd43 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h @@ -55,7 +55,6 @@ #define UV_BAU_TUNABLES_DIR "sgi_uv" #define UV_BAU_TUNABLES_FILE "bau_tunables" #define WHITESPACE " \t\n" -#define uv_mmask ((1UL << uv_hub_info->m_val) - 1) #define uv_physnodeaddr(x) ((__pa((unsigned long)(x)) & uv_mmask)) #define cpubit_isset(cpu, bau_local_cpumask) \ test_bit((cpu), (bau_local_cpumask).bits) diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h index 21f7385badb8..f26544a15214 100644 --- a/arch/x86/include/asm/uv/uv_hub.h +++ b/arch/x86/include/asm/uv/uv_hub.h @@ -46,13 +46,6 @@ * PNODE - the low N bits of the GNODE. The PNODE is the most useful variant * of the nasid for socket usage. * - * GPA - (global physical address) a socket physical address converted - * so that it can be used by the GRU as a global address. Socket - * physical addresses 1) need additional NASID (node) bits added - * to the high end of the address, and 2) unaliased if the - * partition does not have a physical address 0. In addition, on - * UV2 rev 1, GPAs need the gnode left shifted to bits 39 or 40. - * * * NumaLink Global Physical Address Format: * +--------------------------------+---------------------+ @@ -148,8 +141,6 @@ struct uv_hub_info_s { unsigned int gnode_extra; unsigned char hub_revision; unsigned char apic_pnode_shift; - unsigned char m_shift; - unsigned char n_lshift; unsigned long gnode_upper; unsigned long lowmem_remap_top; unsigned long lowmem_remap_base; @@ -186,16 +177,6 @@ static inline int is_uv2_hub(void) return uv_hub_info->hub_revision >= UV2_HUB_REVISION_BASE; } -static inline int is_uv2_1_hub(void) -{ - return uv_hub_info->hub_revision == UV2_HUB_REVISION_BASE; -} - -static inline int is_uv2_2_hub(void) -{ - return uv_hub_info->hub_revision == UV2_HUB_REVISION_BASE + 1; -} - union uvh_apicid { unsigned long v; struct uvh_apicid_s { @@ -295,10 +276,7 @@ static inline unsigned long uv_soc_phys_ram_to_gpa(unsigned long paddr) { if (paddr < uv_hub_info->lowmem_remap_top) paddr |= uv_hub_info->lowmem_remap_base; - paddr |= uv_hub_info->gnode_upper; - paddr = ((paddr << uv_hub_info->m_shift) >> uv_hub_info->m_shift) | - ((paddr >> uv_hub_info->m_val) << uv_hub_info->n_lshift); - return paddr; + return paddr | uv_hub_info->gnode_upper; } @@ -318,23 +296,20 @@ uv_gpa_in_mmr_space(unsigned long gpa) /* UV global physical address --> socket phys RAM */ static inline unsigned long uv_gpa_to_soc_phys_ram(unsigned long gpa) { - unsigned long paddr; + unsigned long paddr = gpa & uv_hub_info->gpa_mask; unsigned long remap_base = uv_hub_info->lowmem_remap_base; unsigned long remap_top = uv_hub_info->lowmem_remap_top; - gpa = ((gpa << uv_hub_info->m_shift) >> uv_hub_info->m_shift) | - ((gpa >> uv_hub_info->n_lshift) << uv_hub_info->m_val); - paddr = gpa & uv_hub_info->gpa_mask; if (paddr >= remap_base && paddr < remap_base + remap_top) paddr -= remap_base; return paddr; } -/* gpa -> pnode */ +/* gnode -> pnode */ static inline unsigned long uv_gpa_to_gnode(unsigned long gpa) { - return gpa >> uv_hub_info->n_lshift; + return gpa >> uv_hub_info->m_val; } /* gpa -> pnode */ @@ -345,12 +320,6 @@ static inline int uv_gpa_to_pnode(unsigned long gpa) return uv_gpa_to_gnode(gpa) & n_mask; } -/* gpa -> node offset*/ -static inline unsigned long uv_gpa_to_offset(unsigned long gpa) -{ - return (gpa << uv_hub_info->m_shift) >> uv_hub_info->m_shift; -} - /* pnode, offset --> socket virtual */ static inline void *uv_pnode_offset_to_vaddr(int pnode, unsigned long offset) { diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h index 7ff4669580cf..64a619d47d34 100644 --- a/arch/x86/include/asm/xen/page.h +++ b/arch/x86/include/asm/xen/page.h @@ -39,7 +39,7 @@ typedef struct xpaddr { ((unsigned long)((u64)CONFIG_XEN_MAX_DOMAIN_MEMORY * 1024 * 1024 * 1024 / PAGE_SIZE)) extern unsigned long *machine_to_phys_mapping; -extern unsigned long machine_to_phys_nr; +extern unsigned int machine_to_phys_order; extern unsigned long get_phys_to_machine(unsigned long pfn); extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn); @@ -87,7 +87,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn) if (xen_feature(XENFEAT_auto_translated_physmap)) return mfn; - if (unlikely(mfn >= machine_to_phys_nr)) { + if (unlikely((mfn >> machine_to_phys_order) != 0)) { pfn = ~0; goto try_override; } diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 479d03c9c4c3..4558f0d0822d 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -416,14 +416,12 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header, return 0; } - if (intsrc->source_irq == 0) { + if (intsrc->source_irq == 0 && intsrc->global_irq == 2) { if (acpi_skip_timer_override) { - printk(PREFIX "BIOS IRQ0 override ignored.\n"); + printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n"); return 0; } - - if ((intsrc->global_irq == 2) && acpi_fix_pin2_polarity - && (intsrc->inti_flags & ACPI_MADT_POLARITY_MASK)) { + if (acpi_fix_pin2_polarity && (intsrc->inti_flags & ACPI_MADT_POLARITY_MASK)) { intsrc->inti_flags &= ~ACPI_MADT_POLARITY_MASK; printk(PREFIX "BIOS IRQ0 pin2 override: forcing polarity to high active.\n"); } @@ -1329,12 +1327,17 @@ static int __init dmi_disable_acpi(const struct dmi_system_id *d) } /* - * Force ignoring BIOS IRQ0 override + * Force ignoring BIOS IRQ0 pin2 override */ static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d) { + /* + * The ati_ixp4x0_rev() early PCI quirk should have set + * the acpi_skip_timer_override flag already: + */ if (!acpi_skip_timer_override) { - pr_notice("%s detected: Ignoring BIOS IRQ0 override\n", + WARN(1, KERN_ERR "ati_ixp4x0 quirk not complete.\n"); + pr_notice("%s detected: Ignoring BIOS IRQ0 pin2 override\n", d->ident); acpi_skip_timer_override = 1; } @@ -1428,7 +1431,7 @@ static struct dmi_system_id __initdata acpi_dmi_table_late[] = { * is enabled. This input is incorrectly designated the * ISA IRQ 0 via an interrupt source override even though * it is wired to the output of the master 8259A and INTIN0 - * is not connected at all. Force ignoring BIOS IRQ0 + * is not connected at all. Force ignoring BIOS IRQ0 pin2 * override in that cases. */ { @@ -1463,14 +1466,6 @@ static struct dmi_system_id __initdata acpi_dmi_table_late[] = { DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"), }, }, - { - .callback = dmi_ignore_irq0_timer_override, - .ident = "FUJITSU SIEMENS", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"), - }, - }, {} }; diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 4c734e6e5877..a81f2d52f869 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -161,7 +161,7 @@ static const unsigned char * const k7_nops[ASM_NOP_MAX+2] = #endif #ifdef P6_NOP1 -static const unsigned char p6nops[] = +static const unsigned char __initconst_or_module p6nops[] = { P6_NOP1, P6_NOP2, @@ -220,7 +220,7 @@ void __init arch_init_ideal_nops(void) ideal_nops = intel_nops; #endif } - break; + default: #ifdef CONFIG_X86_64 ideal_nops = k8_nops; diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index bfd75ff5d5bd..7c3a95e54ec5 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -531,9 +531,7 @@ static void build_inv_all(struct iommu_cmd *cmd) * Writes the command to the IOMMUs command buffer and informs the * hardware about the new command. */ -static int iommu_queue_command_sync(struct amd_iommu *iommu, - struct iommu_cmd *cmd, - bool sync) +static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd) { u32 left, tail, head, next_tail; unsigned long flags; @@ -567,18 +565,13 @@ again: copy_cmd_to_buffer(iommu, cmd, tail); /* We need to sync now to make sure all commands are processed */ - iommu->need_sync = sync; + iommu->need_sync = true; spin_unlock_irqrestore(&iommu->lock, flags); return 0; } -static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd) -{ - return iommu_queue_command_sync(iommu, cmd, true); -} - /* * This function queues a completion wait command into the command * buffer of an IOMMU @@ -594,7 +587,7 @@ static int iommu_completion_wait(struct amd_iommu *iommu) build_completion_wait(&cmd, (u64)&sem); - ret = iommu_queue_command_sync(iommu, &cmd, false); + ret = iommu_queue_command(iommu, &cmd); if (ret) return ret; @@ -780,9 +773,14 @@ static void domain_flush_complete(struct protection_domain *domain) static void domain_flush_devices(struct protection_domain *domain) { struct iommu_dev_data *dev_data; + unsigned long flags; + + spin_lock_irqsave(&domain->lock, flags); list_for_each_entry(dev_data, &domain->dev_list, list) device_flush_dte(dev_data->dev); + + spin_unlock_irqrestore(&domain->lock, flags); } /**************************************************************************** @@ -1203,7 +1201,7 @@ static int alloc_new_range(struct dma_ops_domain *dma_dom, if (!pte || !IOMMU_PTE_PRESENT(*pte)) continue; - dma_ops_reserve_addresses(dma_dom, i >> PAGE_SHIFT, 1); + dma_ops_reserve_addresses(dma_dom, i << PAGE_SHIFT, 1); } update_domain(&dma_dom->domain); diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 33df6e82f653..bfc8453bd98d 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c @@ -1031,9 +1031,8 @@ static int iommu_setup_msi(struct amd_iommu *iommu) { int r; - r = pci_enable_msi(iommu->dev); - if (r) - return r; + if (pci_enable_msi(iommu->dev)) + return 1; r = request_threaded_irq(iommu->dev->irq, amd_iommu_int_handler, @@ -1043,33 +1042,24 @@ static int iommu_setup_msi(struct amd_iommu *iommu) if (r) { pci_disable_msi(iommu->dev); - return r; + return 1; } iommu->int_enabled = true; + iommu_feature_enable(iommu, CONTROL_EVT_INT_EN); return 0; } static int iommu_init_msi(struct amd_iommu *iommu) { - int ret; - if (iommu->int_enabled) - goto enable_faults; + return 0; if (pci_find_capability(iommu->dev, PCI_CAP_ID_MSI)) - ret = iommu_setup_msi(iommu); - else - ret = -ENODEV; + return iommu_setup_msi(iommu); - if (ret) - return ret; - -enable_faults: - iommu_feature_enable(iommu, CONTROL_EVT_INT_EN); - - return 0; + return 1; } /**************************************************************************** diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index be16854591cc..4c39baa8facc 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -119,49 +119,20 @@ bool __init early_is_amd_nb(u32 device) return false; } -struct resource *amd_get_mmconfig_range(struct resource *res) -{ - u32 address; - u64 base, msr; - unsigned segn_busn_bits; - - if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) - return NULL; - - /* assume all cpus from fam10h have mmconfig */ - if (boot_cpu_data.x86 < 0x10) - return NULL; - - address = MSR_FAM10H_MMIO_CONF_BASE; - rdmsrl(address, msr); - - /* mmconfig is not enabled */ - if (!(msr & FAM10H_MMIO_CONF_ENABLE)) - return NULL; - - base = msr & (FAM10H_MMIO_CONF_BASE_MASK<> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) & - FAM10H_MMIO_CONF_BUSRANGE_MASK; - - res->flags = IORESOURCE_MEM; - res->start = base; - res->end = base + (1ULL<<(segn_busn_bits + 20)) - 1; - return res; -} - int amd_get_subcaches(int cpu) { struct pci_dev *link = node_to_amd_nb(amd_get_nb_id(cpu))->link; unsigned int mask; - int cuid; + int cuid = 0; if (!amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) return 0; pci_read_config_dword(link, 0x1d4, &mask); +#ifdef CONFIG_SMP cuid = cpu_data(cpu).compute_unit_id; +#endif return (mask >> (4 * cuid)) & 0xf; } @@ -170,7 +141,7 @@ int amd_set_subcaches(int cpu, int mask) static unsigned int reset, ban; struct amd_northbridge *nb = node_to_amd_nb(amd_get_nb_id(cpu)); unsigned int reg; - int cuid; + int cuid = 0; if (!amd_nb_has_feature(AMD_NB_L3_PARTITIONING) || mask > 0xf) return -EINVAL; @@ -188,7 +159,9 @@ int amd_set_subcaches(int cpu, int mask) pci_write_config_dword(nb->misc, 0x1b8, reg & ~0x180000); } +#ifdef CONFIG_SMP cuid = cpu_data(cpu).compute_unit_id; +#endif mask <<= 4 * cuid; mask |= (0xf ^ (1 << cuid)) << 26; diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 147169569274..b9338b8cf420 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -1558,11 +1558,9 @@ static int __init apic_verify(void) mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; /* The BIOS may have set up the APIC at some other address */ - if (boot_cpu_data.x86 >= 6) { - rdmsr(MSR_IA32_APICBASE, l, h); - if (l & MSR_IA32_APICBASE_ENABLE) - mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; - } + rdmsr(MSR_IA32_APICBASE, l, h); + if (l & MSR_IA32_APICBASE_ENABLE) + mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; pr_info("Found and enabled local APIC!\n"); return 0; @@ -1580,15 +1578,13 @@ int __init apic_force_enable(unsigned long addr) * MSR. This can only be done in software for Intel P6 or later * and AMD K7 (Model > 1) or later. */ - if (boot_cpu_data.x86 >= 6) { - rdmsr(MSR_IA32_APICBASE, l, h); - if (!(l & MSR_IA32_APICBASE_ENABLE)) { - pr_info("Local APIC disabled by BIOS -- reenabling.\n"); - l &= ~MSR_IA32_APICBASE_BASE; - l |= MSR_IA32_APICBASE_ENABLE | addr; - wrmsr(MSR_IA32_APICBASE, l, h); - enabled_via_apicbase = 1; - } + rdmsr(MSR_IA32_APICBASE, l, h); + if (!(l & MSR_IA32_APICBASE_ENABLE)) { + pr_info("Local APIC disabled by BIOS -- reenabling.\n"); + l &= ~MSR_IA32_APICBASE_BASE; + l |= MSR_IA32_APICBASE_ENABLE | addr; + wrmsr(MSR_IA32_APICBASE, l, h); + enabled_via_apicbase = 1; } return apic_verify(); } @@ -2116,12 +2112,10 @@ static void lapic_resume(void) * FIXME! This will be wrong if we ever support suspend on * SMP! We'll need to do this as part of the CPU restore! */ - if (boot_cpu_data.x86 >= 6) { - rdmsr(MSR_IA32_APICBASE, l, h); - l &= ~MSR_IA32_APICBASE_BASE; - l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; - wrmsr(MSR_IA32_APICBASE, l, h); - } + rdmsr(MSR_IA32_APICBASE, l, h); + l &= ~MSR_IA32_APICBASE_BASE; + l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; + wrmsr(MSR_IA32_APICBASE, l, h); } maxlvt = lapic_get_maxlvt(); diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c index 521bead01137..efd737e827f4 100644 --- a/arch/x86/kernel/apic/bigsmp_32.c +++ b/arch/x86/kernel/apic/bigsmp_32.c @@ -255,24 +255,12 @@ static struct apic apic_bigsmp = { .x86_32_early_logical_apicid = bigsmp_early_logical_apicid, }; -void __init generic_bigsmp_probe(void) +struct apic * __init generic_bigsmp_probe(void) { - unsigned int cpu; + if (probe_bigsmp()) + return &apic_bigsmp; - if (!probe_bigsmp()) - return; - - apic = &apic_bigsmp; - - for_each_possible_cpu(cpu) { - if (early_per_cpu(x86_cpu_to_logical_apicid, - cpu) == BAD_APICID) - continue; - early_per_cpu(x86_cpu_to_logical_apicid, cpu) = - bigsmp_early_logical_apicid(cpu); - } - - pr_info("Overriding APIC driver with %s\n", apic_bigsmp.name); + return NULL; } apic_driver(apic_bigsmp); diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index 0787bb3412f4..b5254ad044ab 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c @@ -200,8 +200,14 @@ void __init default_setup_apic_routing(void) * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support */ - if (!cmdline_apic && apic == &apic_default) - generic_bigsmp_probe(); + if (!cmdline_apic && apic == &apic_default) { + struct apic *bigsmp = generic_bigsmp_probe(); + if (bigsmp) { + apic = bigsmp; + printk(KERN_INFO "Overriding APIC driver with %s\n", + apic->name); + } + } #endif if (apic->setup_apic_routing) diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 874c20877140..adc66c3a1fef 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -207,6 +207,7 @@ static int __cpuinit uv_wakeup_secondary(int phys_apicid, unsigned long start_ri ((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | APIC_DM_INIT; uv_write_global_mmr64(pnode, UVH_IPI_INT, val); + mdelay(10); val = (1UL << UVH_IPI_INT_SEND_SHFT) | (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) | @@ -779,12 +780,7 @@ void __init uv_system_init(void) for(i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++) uv_possible_blades += hweight64(uv_read_local_mmr( UVH_NODE_PRESENT_TABLE + i * 8)); - - /* uv_num_possible_blades() is really the hub count */ - printk(KERN_INFO "UV: Found %d blades, %d hubs\n", - is_uv1_hub() ? uv_num_possible_blades() : - (uv_num_possible_blades() + 1) / 2, - uv_num_possible_blades()); + printk(KERN_DEBUG "UV: Found %d blades\n", uv_num_possible_blades()); bytes = sizeof(struct uv_blade_info) * uv_num_possible_blades(); uv_blade_info = kzalloc(bytes, GFP_KERNEL); @@ -837,10 +833,6 @@ void __init uv_system_init(void) uv_cpu_hub_info(cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift; uv_cpu_hub_info(cpu)->hub_revision = uv_hub_info->hub_revision; - uv_cpu_hub_info(cpu)->m_shift = 64 - m_val; - uv_cpu_hub_info(cpu)->n_lshift = is_uv2_1_hub() ? - (m_val == 40 ? 40 : 39) : m_val; - pnode = uv_apicid_to_pnode(apicid); blade = boot_pnode_to_blade(pnode); lcpu = uv_blade_info[blade].nr_possible_cpus; @@ -871,7 +863,8 @@ void __init uv_system_init(void) if (uv_node_to_blade[nid] >= 0) continue; paddr = node_start_pfn(nid) << PAGE_SHIFT; - pnode = uv_gpa_to_pnode(uv_soc_phys_ram_to_gpa(paddr)); + paddr = uv_soc_phys_ram_to_gpa(paddr); + pnode = (paddr >> m_val) & pnode_mask; blade = boot_pnode_to_blade(pnode); uv_node_to_blade[nid] = blade; } diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 0e3a82a41a66..6042981d0309 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -15,7 +15,6 @@ CFLAGS_common.o := $(nostackp) obj-y := intel_cacheinfo.o scattered.o topology.o obj-y += proc.o capflags.o powerflags.o common.o obj-y += vmware.o hypervisor.o sched.o mshyperv.o -obj-y += rdrand.o obj-$(CONFIG_X86_32) += bugs.o obj-$(CONFIG_X86_64) += bugs_64.o diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index a93741d8de78..b13ed393dfce 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -146,6 +146,7 @@ static void __cpuinit init_amd_k6(struct cpuinfo_x86 *c) static void __cpuinit amd_k7_smp_check(struct cpuinfo_x86 *c) { +#ifdef CONFIG_SMP /* calling is from identify_secondary_cpu() ? */ if (!c->cpu_index) return; @@ -189,6 +190,7 @@ static void __cpuinit amd_k7_smp_check(struct cpuinfo_x86 *c) valid_k7: ; +#endif } static void __cpuinit init_amd_k7(struct cpuinfo_x86 *c) @@ -554,34 +556,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) } } - /* - * The way access filter has a performance penalty on some workloads. - * Disable it on the affected CPUs. - */ - if ((c->x86 == 0x15) && - (c->x86_model >= 0x02) && (c->x86_model < 0x20)) { - u64 val; - - if (!rdmsrl_safe(0xc0011021, &val) && !(val & 0x1E)) { - val |= 0x1E; - checking_wrmsrl(0xc0011021, val); - } - } - - /* - * The way access filter has a performance penalty on some workloads. - * Disable it on the affected CPUs. - */ - if ((c->x86 == 0x15) && - (c->x86_model >= 0x02) && (c->x86_model < 0x20)) { - u64 val; - - if (!rdmsrl_safe(0xc0011021, &val) && !(val & 0x1E)) { - val |= 0x1E; - checking_wrmsrl(0xc0011021, val); - } - } - cpu_detect_cache_sizes(c); /* Multi core CPU? */ diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 1579ab92d80e..22a073d7fbff 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -676,7 +675,9 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) if (this_cpu->c_early_init) this_cpu->c_early_init(c); +#ifdef CONFIG_SMP c->cpu_index = 0; +#endif filter_cpuid_features(c, false); setup_smep(c); @@ -759,7 +760,10 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 *c) c->apicid = c->initial_apicid; # endif #endif + +#ifdef CONFIG_X86_HT c->phys_proc_id = c->initial_apicid; +#endif } setup_smep(c); @@ -853,7 +857,6 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) #endif init_hypervisor(c); - x86_init_rdrand(c); /* * Clear/Set all flags overriden by options, need do it diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index e0dc0005456d..1edf5ba4fb2b 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -179,6 +179,7 @@ static void __cpuinit trap_init_f00f_bug(void) static void __cpuinit intel_smp_check(struct cpuinfo_x86 *c) { +#ifdef CONFIG_SMP /* calling is from identify_secondary_cpu() ? */ if (!c->cpu_index) return; @@ -195,6 +196,7 @@ static void __cpuinit intel_smp_check(struct cpuinfo_x86 *c) WARN_ONCE(1, "WARNING: SMP operation may be unreliable" "with B stepping processors.\n"); } +#endif } static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c) @@ -454,24 +456,6 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) if (cpu_has(c, X86_FEATURE_VMX)) detect_vmx_virtcap(c); - - /* - * Initialize MSR_IA32_ENERGY_PERF_BIAS if BIOS did not. - * x86_energy_perf_policy(8) is available to change it at run-time - */ - if (cpu_has(c, X86_FEATURE_EPB)) { - u64 epb; - - rdmsrl(MSR_IA32_ENERGY_PERF_BIAS, epb); - if ((epb & 0xF) == ENERGY_PERF_BIAS_PERFORMANCE) { - printk_once(KERN_WARNING "ENERGY_PERF_BIAS:" - " Set to 'normal', was 'performance'\n" - "ENERGY_PERF_BIAS: View and update with" - " x86_energy_perf_policy(8)\n"); - epb = (epb & ~0xF) | ENERGY_PERF_BIAS_NORMAL; - wrmsrl(MSR_IA32_ENERGY_PERF_BIAS, epb); - } - } } #ifdef CONFIG_X86_32 diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index fde44284cf21..c105c533ed94 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -330,7 +330,8 @@ static void __cpuinit amd_calc_l3_indices(struct amd_l3_cache *l3) l3->indices = (max(max3(sc0, sc1, sc2), sc3) << 10) - 1; } -static void __cpuinit amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int index) +static void __cpuinit amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, + int index) { static struct amd_l3_cache *__cpuinitdata l3_caches; int node; @@ -747,16 +748,14 @@ static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info); #define CPUID4_INFO_IDX(x, y) (&((per_cpu(ici_cpuid4_info, x))[y])) #ifdef CONFIG_SMP - -static int __cpuinit cache_shared_amd_cpu_map_setup(unsigned int cpu, int index) +static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) { - struct _cpuid4_info *this_leaf; - int ret, i, sibling; + struct _cpuid4_info *this_leaf, *sibling_leaf; + unsigned long num_threads_sharing; + int index_msb, i, sibling; struct cpuinfo_x86 *c = &cpu_data(cpu); - ret = 0; - if (index == 3) { - ret = 1; + if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) { for_each_cpu(i, cpu_llc_shared_mask(cpu)) { if (!per_cpu(ici_cpuid4_info, i)) continue; @@ -767,35 +766,8 @@ static int __cpuinit cache_shared_amd_cpu_map_setup(unsigned int cpu, int index) set_bit(sibling, this_leaf->shared_cpu_map); } } - } else if ((c->x86 == 0x15) && ((index == 1) || (index == 2))) { - ret = 1; - for_each_cpu(i, cpu_sibling_mask(cpu)) { - if (!per_cpu(ici_cpuid4_info, i)) - continue; - this_leaf = CPUID4_INFO_IDX(i, index); - for_each_cpu(sibling, cpu_sibling_mask(cpu)) { - if (!cpu_online(sibling)) - continue; - set_bit(sibling, this_leaf->shared_cpu_map); - } - } - } - - return ret; -} - -static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) -{ - struct _cpuid4_info *this_leaf, *sibling_leaf; - unsigned long num_threads_sharing; - int index_msb, i; - struct cpuinfo_x86 *c = &cpu_data(cpu); - - if (c->x86_vendor == X86_VENDOR_AMD) { - if (cache_shared_amd_cpu_map_setup(cpu, index)) - return; + return; } - this_leaf = CPUID4_INFO_IDX(cpu, index); num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing; diff --git a/arch/x86/kernel/cpu/mcheck/mce-severity.c b/arch/x86/kernel/cpu/mcheck/mce-severity.c index 362190bd9e1e..1e8d66c1336a 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-severity.c +++ b/arch/x86/kernel/cpu/mcheck/mce-severity.c @@ -101,19 +101,15 @@ static struct severity { }; /* - * If mcgstatus indicated that ip/cs on the stack were - * no good, then "m->cs" will be zero and we will have - * to assume the worst case (IN_KERNEL) as we actually - * have no idea what we were executing when the machine - * check hit. - * If we do have a good "m->cs" (or a faked one in the - * case we were executing in VM86 mode) we can use it to - * distinguish an exception taken in user from from one - * taken in the kernel. + * If the EIPV bit is set, it means the saved IP is the + * instruction which caused the MCE. */ static int error_context(struct mce *m) { - return ((m->cs & 3) == 3) ? IN_USER : IN_KERNEL; + if (m->mcgstatus & MCG_STATUS_EIPV) + return (m->ip && (m->cs & 3) == 3) ? IN_USER : IN_KERNEL; + /* Unknown, assume kernel */ + return IN_KERNEL; } int mce_severity(struct mce *a, int tolerant, char **msg) diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 1396edf20b99..ff1ae9b6464d 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -122,7 +122,9 @@ void mce_setup(struct mce *m) m->time = get_seconds(); m->cpuvendor = boot_cpu_data.x86_vendor; m->cpuid = cpuid_eax(1); +#ifdef CONFIG_SMP m->socketid = cpu_data(m->extcpu).phys_proc_id; +#endif m->apicid = cpu_data(m->extcpu).initial_apicid; rdmsrl(MSR_IA32_MCG_CAP, m->mcgcap); } @@ -451,13 +453,6 @@ static inline void mce_get_rip(struct mce *m, struct pt_regs *regs) if (regs && (m->mcgstatus & (MCG_STATUS_RIPV|MCG_STATUS_EIPV))) { m->ip = regs->ip; m->cs = regs->cs; - /* - * When in VM86 mode make the cs look like ring 3 - * always. This is a lie, but it's better than passing - * the additional vm86 bit around everywhere. - */ - if (v8086_mode(regs)) - m->cs |= 3; } else { m->ip = 0; m->cs = 0; @@ -995,7 +990,6 @@ void do_machine_check(struct pt_regs *regs, long error_code) */ add_taint(TAINT_MACHINE_CHECK); - mce_get_rip(&m, regs); severity = mce_severity(&m, tolerant, NULL); /* @@ -1034,6 +1028,7 @@ void do_machine_check(struct pt_regs *regs, long error_code) if (severity == MCE_AO_SEVERITY && mce_usable_address(&m)) mce_ring_add(m.addr >> PAGE_SHIFT); + mce_get_rip(&m, regs); mce_log(&m); if (severity > worst) { diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index b97aa72702f1..bb0adad35143 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -52,7 +52,6 @@ struct threshold_block { unsigned int cpu; u32 address; u16 interrupt_enable; - bool interrupt_capable; u16 threshold_limit; struct kobject kobj; struct list_head miscj; @@ -65,9 +64,11 @@ struct threshold_bank { }; static DEFINE_PER_CPU(struct threshold_bank * [NR_BANKS], threshold_banks); +#ifdef CONFIG_SMP static unsigned char shared_bank[NR_BANKS] = { 0, 0, 0, 0, 1 }; +#endif static DEFINE_PER_CPU(unsigned char, bank_map); /* see which banks are on */ @@ -85,21 +86,6 @@ struct thresh_restart { u16 old_limit; }; -static bool lvt_interrupt_supported(unsigned int bank, u32 msr_high_bits) -{ - /* - * bank 4 supports APIC LVT interrupts implicitly since forever. - */ - if (bank == 4) - return true; - - /* - * IntP: interrupt present; if this bit is set, the thresholding - * bank can generate APIC LVT interrupts - */ - return msr_high_bits & BIT(28); -} - static int lvt_off_valid(struct threshold_block *b, int apic, u32 lo, u32 hi) { int msr = (hi & MASK_LVTOFF_HI) >> 20; @@ -121,10 +107,8 @@ static int lvt_off_valid(struct threshold_block *b, int apic, u32 lo, u32 hi) return 1; }; -/* - * Called via smp_call_function_single(), must be called with correct - * cpu affinity. - */ +/* must be called with correct cpu affinity */ +/* Called via smp_call_function_single() */ static void threshold_restart_bank(void *_tr) { struct thresh_restart *tr = _tr; @@ -147,12 +131,6 @@ static void threshold_restart_bank(void *_tr) (new_count & THRESHOLD_MAX); } - /* clear IntType */ - hi &= ~MASK_INT_TYPE_HI; - - if (!tr->b->interrupt_capable) - goto done; - if (tr->set_lvt_off) { if (lvt_off_valid(tr->b, tr->lvt_off, lo, hi)) { /* set new lvt offset */ @@ -161,10 +139,9 @@ static void threshold_restart_bank(void *_tr) } } - if (tr->b->interrupt_enable) - hi |= INT_TYPE_APIC; - - done: + tr->b->interrupt_enable ? + (hi = (hi & ~MASK_INT_TYPE_HI) | INT_TYPE_APIC) : + (hi &= ~MASK_INT_TYPE_HI); hi |= MASK_COUNT_EN_HI; wrmsr(tr->b->address, lo, hi); @@ -225,21 +202,18 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c) if (!block) per_cpu(bank_map, cpu) |= (1 << bank); - +#ifdef CONFIG_SMP if (shared_bank[bank] && c->cpu_core_id) break; +#endif + offset = setup_APIC_mce(offset, + (high & MASK_LVTOFF_HI) >> 20); memset(&b, 0, sizeof(b)); - b.cpu = cpu; - b.bank = bank; - b.block = block; - b.address = address; - b.interrupt_capable = lvt_interrupt_supported(bank, high); - - if (b.interrupt_capable) { - int new = (high & MASK_LVTOFF_HI) >> 20; - offset = setup_APIC_mce(offset, new); - } + b.cpu = cpu; + b.bank = bank; + b.block = block; + b.address = address; mce_threshold_block_init(&b, offset); mce_threshold_vector = amd_threshold_interrupt; @@ -339,9 +313,6 @@ store_interrupt_enable(struct threshold_block *b, const char *buf, size_t size) struct thresh_restart tr; unsigned long new; - if (!b->interrupt_capable) - return -EINVAL; - if (strict_strtoul(buf, 0, &new) < 0) return -EINVAL; @@ -500,7 +471,6 @@ static __cpuinit int allocate_threshold_blocks(unsigned int cpu, b->cpu = cpu; b->address = address; b->interrupt_enable = 0; - b->interrupt_capable = lvt_interrupt_supported(bank, high); b->threshold_limit = THRESHOLD_MAX; INIT_LIST_HEAD(&b->miscj); diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index 99cd9d2abb61..27c625178bf1 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c @@ -322,6 +322,17 @@ device_initcall(thermal_throttle_init_device); #endif /* CONFIG_SYSFS */ +/* + * Set up the most two significant bit to notify mce log that this thermal + * event type. + * This is a temp solution. May be changed in the future with mce log + * infrasture. + */ +#define CORE_THROTTLED (0) +#define CORE_POWER_LIMIT ((__u64)1 << 62) +#define PACKAGE_THROTTLED ((__u64)2 << 62) +#define PACKAGE_POWER_LIMIT ((__u64)3 << 62) + static void notify_thresholds(__u64 msr_val) { /* check whether the interrupt handler is defined; @@ -351,23 +362,27 @@ static void intel_thermal_interrupt(void) if (therm_throt_process(msr_val & THERM_STATUS_PROCHOT, THERMAL_THROTTLING_EVENT, CORE_LEVEL) != 0) - mce_log_therm_throt_event(msr_val); + mce_log_therm_throt_event(CORE_THROTTLED | msr_val); if (this_cpu_has(X86_FEATURE_PLN)) - therm_throt_process(msr_val & THERM_STATUS_POWER_LIMIT, + if (therm_throt_process(msr_val & THERM_STATUS_POWER_LIMIT, POWER_LIMIT_EVENT, - CORE_LEVEL); + CORE_LEVEL) != 0) + mce_log_therm_throt_event(CORE_POWER_LIMIT | msr_val); if (this_cpu_has(X86_FEATURE_PTS)) { rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val); - therm_throt_process(msr_val & PACKAGE_THERM_STATUS_PROCHOT, + if (therm_throt_process(msr_val & PACKAGE_THERM_STATUS_PROCHOT, THERMAL_THROTTLING_EVENT, - PACKAGE_LEVEL); + PACKAGE_LEVEL) != 0) + mce_log_therm_throt_event(PACKAGE_THROTTLED | msr_val); if (this_cpu_has(X86_FEATURE_PLN)) - therm_throt_process(msr_val & + if (therm_throt_process(msr_val & PACKAGE_THERM_STATUS_POWER_LIMIT, POWER_LIMIT_EVENT, - PACKAGE_LEVEL); + PACKAGE_LEVEL) != 0) + mce_log_therm_throt_event(PACKAGE_POWER_LIMIT + | msr_val); } } diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index 3d17bc7f06e6..929739a653d1 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c @@ -248,25 +248,6 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ unsigned long flags; int cpu; -#ifdef CONFIG_SMP - /* - * If this cpu is not yet active, we are in the cpu online path. There - * can be no stop_machine() in parallel, as stop machine ensures this - * by using get_online_cpus(). We can skip taking the stop_cpus_mutex, - * as we don't need it and also we can't afford to block while waiting - * for the mutex. - * - * If this cpu is active, we need to prevent stop_machine() happening - * in parallel by taking the stop cpus mutex. - * - * Also, this is called in the context of cpu online path or in the - * context where cpu hotplug is prevented. So checking the active status - * of the raw_smp_processor_id() is safe. - */ - if (cpu_active(raw_smp_processor_id())) - mutex_lock(&stop_cpus_mutex); -#endif - preempt_disable(); data.smp_reg = reg; @@ -349,10 +330,6 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ local_irq_restore(flags); preempt_enable(); -#ifdef CONFIG_SMP - if (cpu_active(raw_smp_processor_id())) - mutex_unlock(&stop_cpus_mutex); -#endif } /** diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index bf6d692c4d0f..3a0338b4b179 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1856,9 +1856,6 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) perf_callchain_store(entry, regs->ip); - if (!current->mm) - return; - if (perf_callchain_user32(regs, entry)) return; diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index 4b50c965f0e6..fe29c1d2219e 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c @@ -437,7 +437,6 @@ static __initconst const struct x86_pmu amd_pmu = { * 0x023 DE PERF_CTL[2:0] * 0x02D LS PERF_CTL[3] * 0x02E LS PERF_CTL[3,0] - * 0x031 LS PERF_CTL[2:0] (**) * 0x043 CU PERF_CTL[2:0] * 0x045 CU PERF_CTL[2:0] * 0x046 CU PERF_CTL[2:0] @@ -451,12 +450,10 @@ static __initconst const struct x86_pmu amd_pmu = { * 0x0DD LS PERF_CTL[5:0] * 0x0DE LS PERF_CTL[5:0] * 0x0DF LS PERF_CTL[5:0] - * 0x1C0 EX PERF_CTL[5:3] * 0x1D6 EX PERF_CTL[5:0] * 0x1D8 EX PERF_CTL[5:0] * - * (*) depending on the umask all FPU counters may be used - * (**) only one unitmask enabled at a time + * (*) depending on the umask all FPU counters may be used */ static struct event_constraint amd_f15_PMC0 = EVENT_CONSTRAINT(0, 0x01, 0); @@ -506,12 +503,6 @@ amd_get_event_constraints_f15h(struct cpu_hw_events *cpuc, struct perf_event *ev return &amd_f15_PMC3; case 0x02E: return &amd_f15_PMC30; - case 0x031: - if (hweight_long(hwc->config & ARCH_PERFMON_EVENTSEL_UMASK) <= 1) - return &amd_f15_PMC20; - return &emptyconstraint; - case 0x1C0: - return &amd_f15_PMC53; default: return &amd_f15_PMC50; } diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index dd208a829b2b..41178c826c48 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -1495,7 +1495,6 @@ static __init int intel_pmu_init(void) break; case 42: /* SandyBridge */ - case 45: /* SandyBridge, "Romely-EP" */ memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, sizeof(hw_cache_event_ids)); diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index d812fe2d02be..bab491b8ee25 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -508,7 +508,6 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) unsigned long from = cpuc->lbr_entries[0].from; unsigned long old_to, to = cpuc->lbr_entries[0].to; unsigned long ip = regs->ip; - int is_64bit = 0; /* * We don't need to fixup if the PEBS assist is fault like @@ -560,10 +559,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) } else kaddr = (void *)to; -#ifdef CONFIG_X86_64 - is_64bit = kernel_ip(to) || !test_thread_flag(TIF_IA32); -#endif - insn_init(&insn, kaddr, is_64bit); + kernel_insn_init(&insn, kaddr); insn_get_length(&insn); to += insn.length; } while (to < ip); diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c index 72c365a12406..62ac8cb6ba27 100644 --- a/arch/x86/kernel/cpu/proc.c +++ b/arch/x86/kernel/cpu/proc.c @@ -64,10 +64,12 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) static int show_cpuinfo(struct seq_file *m, void *v) { struct cpuinfo_x86 *c = v; - unsigned int cpu; + unsigned int cpu = 0; int i; +#ifdef CONFIG_SMP cpu = c->cpu_index; +#endif seq_printf(m, "processor\t: %u\n" "vendor_id\t: %s\n" "cpu family\t: %d\n" diff --git a/arch/x86/kernel/cpu/rdrand.c b/arch/x86/kernel/cpu/rdrand.c deleted file mode 100644 index feca286c2bb4..000000000000 --- a/arch/x86/kernel/cpu/rdrand.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is part of the Linux kernel. - * - * Copyright (c) 2011, Intel Corporation - * Authors: Fenghua Yu , - * H. Peter Anvin - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include -#include -#include - -static int __init x86_rdrand_setup(char *s) -{ - setup_clear_cpu_cap(X86_FEATURE_RDRAND); - return 1; -} -__setup("nordrand", x86_rdrand_setup); - -/* We can't use arch_get_random_long() here since alternatives haven't run */ -static inline int rdrand_long(unsigned long *v) -{ - int ok; - asm volatile("1: " RDRAND_LONG "\n\t" - "jc 2f\n\t" - "decl %0\n\t" - "jnz 1b\n\t" - "2:" - : "=r" (ok), "=a" (*v) - : "0" (RDRAND_RETRY_LOOPS)); - return ok; -} - -/* - * Force a reseed cycle; we are architecturally guaranteed a reseed - * after no more than 512 128-bit chunks of random data. This also - * acts as a test of the CPU capability. - */ -#define RESEED_LOOP ((512*128)/sizeof(unsigned long)) - -void __cpuinit x86_init_rdrand(struct cpuinfo_x86 *c) -{ -#ifdef CONFIG_ARCH_RANDOM - unsigned long tmp; - int i, count, ok; - - if (!cpu_has(c, X86_FEATURE_RDRAND)) - return; /* Nothing to do */ - - for (count = i = 0; i < RESEED_LOOP; i++) { - ok = rdrand_long(&tmp); - if (ok) - count++; - } - - if (count != RESEED_LOOP) - clear_cpu_cap(c, X86_FEATURE_RDRAND); -#endif -} diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index ea6106c5ef70..c7f64e6f537a 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c @@ -31,7 +31,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) const struct cpuid_bit *cb; static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { - { X86_FEATURE_DTHERM, CR_EAX, 0, 0x00000006, 0 }, + { X86_FEATURE_DTS, CR_EAX, 0, 0x00000006, 0 }, { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006, 0 }, { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 }, { X86_FEATURE_PLN, CR_EAX, 4, 0x00000006, 0 }, diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 2df12522aff5..5c1a91974918 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -98,6 +98,12 @@ #endif .endm +#ifdef CONFIG_VM86 +#define resume_userspace_sig check_userspace +#else +#define resume_userspace_sig resume_userspace +#endif + /* * User gs save/restore * @@ -321,19 +327,10 @@ ret_from_exception: preempt_stop(CLBR_ANY) ret_from_intr: GET_THREAD_INFO(%ebp) -resume_userspace_sig: -#ifdef CONFIG_VM86 +check_userspace: movl PT_EFLAGS(%esp), %eax # mix EFLAGS and CS movb PT_CS(%esp), %al andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax -#else - /* - * We can be coming here from a syscall done in the kernel space, - * e.g. a failed kernel_execve(). - */ - movl PT_CS(%esp), %eax - andl $SEGMENT_RPL_MASK, %eax -#endif cmpl $USER_RPL, %eax jb resume_kernel # not returning to v8086 or userspace @@ -1029,7 +1026,7 @@ ENTRY(xen_sysenter_target) ENTRY(xen_hypervisor_callback) CFI_STARTPROC - pushl_cfi $-1 /* orig_ax = -1 => not a system call */ + pushl_cfi $0 SAVE_ALL TRACE_IRQS_OFF @@ -1071,15 +1068,14 @@ ENTRY(xen_failsafe_callback) 2: mov 8(%esp),%es 3: mov 12(%esp),%fs 4: mov 16(%esp),%gs - /* EAX == 0 => Category 1 (Bad segment) - EAX != 0 => Category 2 (Bad IRET) */ testl %eax,%eax popl_cfi %eax lea 16(%esp),%esp CFI_ADJUST_CFA_OFFSET -16 jz 5f - jmp iret_exc -5: pushl_cfi $-1 /* orig_ax = -1 => not a system call */ + addl $16,%esp + jmp iret_exc # EAX != 0 => Category 2 (Bad IRET) +5: pushl_cfi $0 # EAX == 0 => Category 1 (Bad segment) SAVE_ALL jmp ret_from_exception CFI_ENDPROC diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index dd4dba4fadce..8a445a0c989e 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -1308,7 +1308,7 @@ ENTRY(xen_failsafe_callback) CFI_RESTORE r11 addq $0x30,%rsp CFI_ADJUST_CFA_OFFSET -0x30 - pushq_cfi $-1 /* orig_ax = -1 => not a system call */ + pushq_cfi $0 SAVE_ALL jmp error_exit CFI_ENDPROC diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 0aa649ee563b..6781765b3a0d 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -427,7 +427,7 @@ void hpet_msi_unmask(struct irq_data *data) /* unmask it */ cfg = hpet_readl(HPET_Tn_CFG(hdev->num)); - cfg |= HPET_TN_ENABLE | HPET_TN_FSB; + cfg |= HPET_TN_FSB; hpet_writel(cfg, HPET_Tn_CFG(hdev->num)); } @@ -438,7 +438,7 @@ void hpet_msi_mask(struct irq_data *data) /* mask it */ cfg = hpet_readl(HPET_Tn_CFG(hdev->num)); - cfg &= ~(HPET_TN_ENABLE | HPET_TN_FSB); + cfg &= ~HPET_TN_FSB; hpet_writel(cfg, HPET_Tn_CFG(hdev->num)); } @@ -1054,14 +1054,6 @@ int hpet_rtc_timer_init(void) } EXPORT_SYMBOL_GPL(hpet_rtc_timer_init); -static void hpet_disable_rtc_channel(void) -{ - unsigned long cfg; - cfg = hpet_readl(HPET_T1_CFG); - cfg &= ~HPET_TN_ENABLE; - hpet_writel(cfg, HPET_T1_CFG); -} - /* * The functions below are called from rtc driver. * Return 0 if HPET is not being used. @@ -1073,9 +1065,6 @@ int hpet_mask_rtc_irq_bit(unsigned long bit_mask) return 0; hpet_rtc_flags &= ~bit_mask; - if (unlikely(!hpet_rtc_flags)) - hpet_disable_rtc_channel(); - return 1; } EXPORT_SYMBOL_GPL(hpet_mask_rtc_irq_bit); @@ -1141,11 +1130,15 @@ EXPORT_SYMBOL_GPL(hpet_rtc_dropped_irq); static void hpet_rtc_timer_reinit(void) { - unsigned int delta; + unsigned int cfg, delta; int lost_ints = -1; - if (unlikely(!hpet_rtc_flags)) - hpet_disable_rtc_channel(); + if (unlikely(!hpet_rtc_flags)) { + cfg = hpet_readl(HPET_T1_CFG); + cfg &= ~HPET_TN_ENABLE; + hpet_writel(cfg, HPET_T1_CFG); + return; + } if (!(hpet_rtc_flags & RTC_PIE) || hpet_pie_limit) delta = hpet_default_delta; diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index fc1f48dc9989..5f9ecff328b5 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c @@ -43,8 +43,6 @@ #include #include #include -#include -#include #include #include @@ -712,64 +710,6 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip) regs->ip = ip; } -int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) -{ - int err; - char opc[BREAK_INSTR_SIZE]; - - bpt->type = BP_BREAKPOINT; - err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr, - BREAK_INSTR_SIZE); - if (err) - return err; - err = probe_kernel_write((char *)bpt->bpt_addr, - arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE); -#ifdef CONFIG_DEBUG_RODATA - if (!err) - return err; - /* - * It is safe to call text_poke() because normal kernel execution - * is stopped on all cores, so long as the text_mutex is not locked. - */ - if (mutex_is_locked(&text_mutex)) - return -EBUSY; - text_poke((void *)bpt->bpt_addr, arch_kgdb_ops.gdb_bpt_instr, - BREAK_INSTR_SIZE); - err = probe_kernel_read(opc, (char *)bpt->bpt_addr, BREAK_INSTR_SIZE); - if (err) - return err; - if (memcmp(opc, arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE)) - return -EINVAL; - bpt->type = BP_POKE_BREAKPOINT; -#endif /* CONFIG_DEBUG_RODATA */ - return err; -} - -int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) -{ -#ifdef CONFIG_DEBUG_RODATA - int err; - char opc[BREAK_INSTR_SIZE]; - - if (bpt->type != BP_POKE_BREAKPOINT) - goto knl_write; - /* - * It is safe to call text_poke() because normal kernel execution - * is stopped on all cores, so long as the text_mutex is not locked. - */ - if (mutex_is_locked(&text_mutex)) - goto knl_write; - text_poke((void *)bpt->bpt_addr, bpt->saved_instr, BREAK_INSTR_SIZE); - err = probe_kernel_read(opc, (char *)bpt->bpt_addr, BREAK_INSTR_SIZE); - if (err || memcmp(opc, bpt->saved_instr, BREAK_INSTR_SIZE)) - goto knl_write; - return err; -knl_write: -#endif /* CONFIG_DEBUG_RODATA */ - return probe_kernel_write((char *)bpt->bpt_addr, - (char *)bpt->saved_instr, BREAK_INSTR_SIZE); -} - struct kgdb_arch arch_kgdb_ops = { /* Breakpoint instruction: */ .gdb_bpt_instr = { 0xcc }, diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index 794bc95134cd..f1a6244d7d93 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c @@ -75,10 +75,8 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); /* * Undefined/reserved opcodes, conditional jump, Opcode Extension * Groups, and some special opcodes can not boost. - * This is non-const to keep gcc from statically optimizing it out, as - * variable_test_bit makes gcc think only *(unsigned long*) is used. */ -static u32 twobyte_is_boostable[256 / 32] = { +static const u32 twobyte_is_boostable[256 / 32] = { /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ /* ---------------------------------------------- */ W(0x00, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0) | /* 00 */ diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index 53ab9ff25a8e..c5610384ab16 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c @@ -162,7 +162,6 @@ static unsigned int verify_ucode_size(int cpu, const u8 *buf, unsigned int size) #define F1XH_MPB_MAX_SIZE 2048 #define F14H_MPB_MAX_SIZE 1824 #define F15H_MPB_MAX_SIZE 4096 -#define F16H_MPB_MAX_SIZE 3458 switch (c->x86) { case 0x14: @@ -171,9 +170,6 @@ static unsigned int verify_ucode_size(int cpu, const u8 *buf, unsigned int size) case 0x15: max_size = F15H_MPB_MAX_SIZE; break; - case 0x16: - max_size = F16H_MPB_MAX_SIZE; - break; default: max_size = F1XH_MPB_MAX_SIZE; break; @@ -302,33 +298,13 @@ free_table: return state; } -/* - * AMD microcode firmware naming convention, up to family 15h they are in - * the legacy file: - * - * amd-ucode/microcode_amd.bin - * - * This legacy file is always smaller than 2K in size. - * - * Starting at family 15h they are in family specific firmware files: - * - * amd-ucode/microcode_amd_fam15h.bin - * amd-ucode/microcode_amd_fam16h.bin - * ... - * - * These might be larger than 2K. - */ static enum ucode_state request_microcode_amd(int cpu, struct device *device) { - char fw_name[36] = "amd-ucode/microcode_amd.bin"; + const char *fw_name = "amd-ucode/microcode_amd.bin"; const struct firmware *fw; enum ucode_state ret = UCODE_NFOUND; - struct cpuinfo_x86 *c = &cpu_data(cpu); - - if (c->x86 >= 0x15) - snprintf(fw_name, sizeof(fw_name), "amd-ucode/microcode_amd_fam%.2xh.bin", c->x86); - if (request_firmware(&fw, (const char *)fw_name, device)) { + if (request_firmware(&fw, fw_name, device)) { pr_err("failed to load file %s\n", fw_name); goto out; } diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index c4e246541c54..f9242800bc84 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c @@ -297,31 +297,20 @@ static ssize_t reload_store(struct sys_device *dev, const char *buf, size_t size) { unsigned long val; - int cpu; - ssize_t ret = 0, tmp_ret; + int cpu = dev->id; + int ret = 0; + char *end; - /* allow reload only from the BSP */ - if (boot_cpu_data.cpu_index != dev->id) + val = simple_strtoul(buf, &end, 0); + if (end == buf) return -EINVAL; - ret = kstrtoul(buf, 0, &val); - if (ret) - return ret; - - if (val != 1) - return size; - - get_online_cpus(); - for_each_online_cpu(cpu) { - tmp_ret = reload_for_cpu(cpu); - if (tmp_ret != 0) - pr_warn("Error reloading microcode on CPU %d\n", cpu); - - /* save retval of the first encountered reload error */ - if (!ret) - ret = tmp_ret; + if (val == 1) { + get_online_cpus(); + if (cpu_online(cpu)) + ret = reload_for_cpu(cpu); + put_online_cpus(); } - put_online_cpus(); if (!ret) ret = size; diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 0741b062a304..9103b89c145a 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -95,8 +95,8 @@ static void __init MP_bus_info(struct mpc_bus *m) } #endif - set_bit(m->busid, mp_bus_not_pci); if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA) - 1) == 0) { + set_bit(m->busid, mp_bus_not_pci); #if defined(CONFIG_EISA) || defined(CONFIG_MCA) mp_bus_id_to_type[m->busid] = MP_BUS_ISA; #endif diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index f7d1a649a5b2..12fcbe2c143e 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c @@ -175,9 +175,6 @@ static int msr_open(struct inode *inode, struct file *file) unsigned int cpu; struct cpuinfo_x86 *c; - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - cpu = iminor(file->f_path.dentry->d_inode); if (cpu >= nr_cpu_ids || !cpu_online(cpu)) return -ENXIO; /* No such CPU */ diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 427250211f39..e1ba8cb24e4e 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -341,10 +341,34 @@ void (*pm_idle)(void); EXPORT_SYMBOL(pm_idle); #endif +#ifdef CONFIG_X86_32 +/* + * This halt magic was a workaround for ancient floppy DMA + * wreckage. It should be safe to remove. + */ +static int hlt_counter; +void disable_hlt(void) +{ + hlt_counter++; +} +EXPORT_SYMBOL(disable_hlt); + +void enable_hlt(void) +{ + hlt_counter--; +} +EXPORT_SYMBOL(enable_hlt); + +static inline int hlt_use_halt(void) +{ + return (!hlt_counter && boot_cpu_data.hlt_works_ok); +} +#else static inline int hlt_use_halt(void) { return 1; } +#endif /* * We use this if we don't have any better diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 12dae34bbe1d..a3d0dc59067b 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -98,7 +98,6 @@ void cpu_idle(void) /* endless idle loop with no priority at all */ while (1) { tick_nohz_stop_sched_tick(1); - idle_notifier_call_chain(IDLE_START); while (!need_resched()) { check_pgt_cache(); @@ -113,7 +112,6 @@ void cpu_idle(void) pm_idle(); start_critical_timings(); } - idle_notifier_call_chain(IDLE_END); tick_nohz_restart_sched_tick(); preempt_enable_no_resched(); schedule(); @@ -295,11 +293,22 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) *next = &next_p->thread; int cpu = smp_processor_id(); struct tss_struct *tss = &per_cpu(init_tss, cpu); - fpu_switch_t fpu; + bool preload_fpu; /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */ - fpu = switch_fpu_prepare(prev_p, next_p); + /* + * If the task has used fpu the last 5 timeslices, just do a full + * restore of the math state immediately to avoid the trap; the + * chances of needing FPU soon are obviously high now + */ + preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5; + + __unlazy_fpu(prev_p); + + /* we're going to use this soon, after a few expensive things */ + if (preload_fpu) + prefetch(next->fpu.state); /* * Reload esp0. @@ -339,6 +348,11 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT)) __switch_to_xtra(prev_p, next_p, tss); + /* If we're going to preload the fpu context, make sure clts + is run while we're batching the cpu state updates. */ + if (preload_fpu) + clts(); + /* * Leave lazy mode, flushing any hypercalls made here. * This must be done before restoring TLS segments so @@ -348,14 +362,15 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) */ arch_end_context_switch(next_p); + if (preload_fpu) + __math_state_restore(); + /* * Restore %gs if needed (which is common) */ if (prev->gs | next->gs) lazy_load_gs(next->gs); - switch_fpu_finish(next_p, fpu); - percpu_write(current_task, next_p); return prev_p; diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index eeb50045bfd3..ca6f7ab8df33 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -56,17 +56,31 @@ asmlinkage extern void ret_from_fork(void); DEFINE_PER_CPU(unsigned long, old_rsp); static DEFINE_PER_CPU(unsigned char, is_idle); +static ATOMIC_NOTIFIER_HEAD(idle_notifier); + +void idle_notifier_register(struct notifier_block *n) +{ + atomic_notifier_chain_register(&idle_notifier, n); +} +EXPORT_SYMBOL_GPL(idle_notifier_register); + +void idle_notifier_unregister(struct notifier_block *n) +{ + atomic_notifier_chain_unregister(&idle_notifier, n); +} +EXPORT_SYMBOL_GPL(idle_notifier_unregister); + void enter_idle(void) { percpu_write(is_idle, 1); - idle_notifier_call_chain(IDLE_START); + atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL); } static void __exit_idle(void) { if (x86_test_and_clear_bit_percpu(0, is_idle) == 0) return; - idle_notifier_call_chain(IDLE_END); + atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL); } /* Called from interrupts to signify idle end */ @@ -363,9 +377,18 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) int cpu = smp_processor_id(); struct tss_struct *tss = &per_cpu(init_tss, cpu); unsigned fsindex, gsindex; - fpu_switch_t fpu; + bool preload_fpu; + + /* + * If the task has used fpu the last 5 timeslices, just do a full + * restore of the math state immediately to avoid the trap; the + * chances of needing FPU soon are obviously high now + */ + preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5; - fpu = switch_fpu_prepare(prev_p, next_p); + /* we're going to use this soon, after a few expensive things */ + if (preload_fpu) + prefetch(next->fpu.state); /* * Reload esp0, LDT and the page table pointer: @@ -395,6 +418,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) load_TLS(next, cpu); + /* Must be after DS reload */ + __unlazy_fpu(prev_p); + + /* Make sure cpu is ready for new context */ + if (preload_fpu) + clts(); + /* * Leave lazy mode, flushing any hypercalls made here. * This must be done before restoring TLS segments so @@ -435,8 +465,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) wrmsrl(MSR_KERNEL_GS_BASE, next->gs); prev->gsindex = gsindex; - switch_fpu_finish(next_p, fpu); - /* * Switch the PDA and FPU contexts. */ @@ -455,6 +483,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV)) __switch_to_xtra(prev_p, next_p, tss); + /* + * Preload the FPU context, now that we've determined that the + * task is likely to be using it. + */ + if (preload_fpu) + __math_state_restore(); + return prev_p; } diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 911e16d8dfa4..807c2a2b80f1 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -165,35 +164,6 @@ static inline bool invalid_selector(u16 value) #define FLAG_MASK FLAG_MASK_32 -/* - * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode - * when it traps. The previous stack will be directly underneath the saved - * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'. - * - * Now, if the stack is empty, '®s->sp' is out of range. In this - * case we try to take the previous stack. To always return a non-null - * stack pointer we fall back to regs as stack if no previous stack - * exists. - * - * This is valid only for kernel mode traps. - */ -unsigned long kernel_stack_pointer(struct pt_regs *regs) -{ - unsigned long context = (unsigned long)regs & ~(THREAD_SIZE - 1); - unsigned long sp = (unsigned long)®s->sp; - struct thread_info *tinfo; - - if (context == (sp & ~(THREAD_SIZE - 1))) - return sp; - - tinfo = (struct thread_info *)context; - if (tinfo->previous_esp) - return tinfo->previous_esp; - - return (unsigned long)regs; -} -EXPORT_SYMBOL_GPL(kernel_stack_pointer); - static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno) { BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0); diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 89d68777f73a..9242436e9937 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -124,7 +124,7 @@ __setup("reboot=", reboot_setup); */ /* - * Some machines require the "reboot=b" or "reboot=k" commandline options, + * Some machines require the "reboot=b" commandline option, * this quirk makes that automatic. */ static int __init set_bios_reboot(const struct dmi_system_id *d) @@ -136,15 +136,6 @@ static int __init set_bios_reboot(const struct dmi_system_id *d) return 0; } -static int __init set_kbd_reboot(const struct dmi_system_id *d) -{ - if (reboot_type != BOOT_KBD) { - reboot_type = BOOT_KBD; - printk(KERN_INFO "%s series board detected. Selecting KBD-method for reboot.\n", d->ident); - } - return 0; -} - static struct dmi_system_id __initdata reboot_dmi_table[] = { { /* Handle problems with rebooting on Dell E520's */ .callback = set_bios_reboot, @@ -304,7 +295,7 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { }, }, { /* Handle reboot issue on Acer Aspire one */ - .callback = set_kbd_reboot, + .callback = set_bios_reboot, .ident = "Acer Aspire One A110", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), @@ -452,14 +443,6 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6420"), }, }, - { /* Handle problems with rebooting on the Precision M6600. */ - .callback = set_pci_reboot, - .ident = "Dell OptiPlex 990", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"), - }, - }, { } }; diff --git a/arch/x86/kernel/relocate_kernel_32.S b/arch/x86/kernel/relocate_kernel_32.S index 36818f8ec2be..41235531b11c 100644 --- a/arch/x86/kernel/relocate_kernel_32.S +++ b/arch/x86/kernel/relocate_kernel_32.S @@ -97,8 +97,6 @@ relocate_kernel: ret identity_mapped: - /* set return address to 0 if not preserving context */ - pushl $0 /* store the start address on the stack */ pushl %edx diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocate_kernel_64.S index 7a6f3b3be3cf..4de8f5b3d476 100644 --- a/arch/x86/kernel/relocate_kernel_64.S +++ b/arch/x86/kernel/relocate_kernel_64.S @@ -100,8 +100,6 @@ relocate_kernel: ret identity_mapped: - /* set return address to 0 if not preserving context */ - pushq $0 /* store the start address on the stack */ pushq %rdx diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 6c4e9ffc290c..afaf38447ef5 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -631,83 +631,6 @@ static __init void reserve_ibft_region(void) static unsigned reserve_low = CONFIG_X86_RESERVE_LOW << 10; -static bool __init snb_gfx_workaround_needed(void) -{ -#ifdef CONFIG_PCI - int i; - u16 vendor, devid; - static const u16 snb_ids[] = { - 0x0102, - 0x0112, - 0x0122, - 0x0106, - 0x0116, - 0x0126, - 0x010a, - }; - - /* Assume no if something weird is going on with PCI */ - if (!early_pci_allowed()) - return false; - - vendor = read_pci_config_16(0, 2, 0, PCI_VENDOR_ID); - if (vendor != 0x8086) - return false; - - devid = read_pci_config_16(0, 2, 0, PCI_DEVICE_ID); - for (i = 0; i < ARRAY_SIZE(snb_ids); i++) - if (devid == snb_ids[i]) - return true; -#endif - - return false; -} - -/* - * Sandy Bridge graphics has trouble with certain ranges, exclude - * them from allocation. - */ -static void __init trim_snb_memory(void) -{ - static const unsigned long bad_pages[] = { - 0x20050000, - 0x20110000, - 0x20130000, - 0x20138000, - 0x40004000, - }; - int i; - - if (!snb_gfx_workaround_needed()) - return; - - printk(KERN_DEBUG "reserving inaccessible SNB gfx pages\n"); - - /* - * Reserve all memory below the 1 MB mark that has not - * already been reserved. - */ - memblock_reserve(0, 1<<20); - - for (i = 0; i < ARRAY_SIZE(bad_pages); i++) { - if (memblock_reserve(bad_pages[i], PAGE_SIZE)) - printk(KERN_WARNING "failed to reserve 0x%08lx\n", - bad_pages[i]); - } -} - -/* - * Here we put platform-specific memory range workarounds, i.e. - * memory known to be corrupt or otherwise in need to be reserved on - * specific platforms. - * - * If this gets used more widely it could use a real dispatch mechanism. - */ -static void __init trim_platform_memory_ranges(void) -{ - trim_snb_memory(); -} - static void __init trim_bios_range(void) { /* @@ -728,7 +651,6 @@ static void __init trim_bios_range(void) * take them out. */ e820_remove_range(BIOS_BEGIN, BIOS_END - BIOS_BEGIN, E820_RAM, 1); - sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); } @@ -1007,8 +929,6 @@ void __init setup_arch(char **cmdline_p) setup_trampolines(); - trim_platform_memory_ranges(); - init_gbpages(); /* max_pfn_mapped is updated here */ @@ -1017,21 +937,8 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_X86_64 if (max_pfn > max_low_pfn) { - int i; - for (i = 0; i < e820.nr_map; i++) { - struct e820entry *ei = &e820.map[i]; - - if (ei->addr + ei->size <= 1UL << 32) - continue; - - if (ei->type == E820_RESERVED) - continue; - - max_pfn_mapped = init_memory_mapping( - ei->addr < 1UL << 32 ? 1UL << 32 : ei->addr, - ei->addr + ei->size); - } - + max_pfn_mapped = init_memory_mapping(1UL<<32, + max_pfn<= GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) || + if (pos > GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) || (pos % sizeof(struct user_desc)) != 0 || (count % sizeof(struct user_desc)) != 0) return -EINVAL; @@ -198,7 +198,7 @@ int regset_tls_set(struct task_struct *target, const struct user_regset *regset, struct user_desc infobuf[GDT_ENTRY_TLS_ENTRIES]; const struct user_desc *info; - if (pos >= GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) || + if (pos > GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) || (pos % sizeof(struct user_desc)) != 0 || (count % sizeof(struct user_desc)) != 0) return -EINVAL; diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 1b26e01047b5..b9b67166f9de 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -717,34 +717,25 @@ asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void) } /* - * This gets called with the process already owning the - * FPU state, and with CR0.TS cleared. It just needs to - * restore the FPU register state. + * __math_state_restore assumes that cr0.TS is already clear and the + * fpu state is all ready for use. Used during context switch. */ -void __math_state_restore(struct task_struct *tsk) +void __math_state_restore(void) { - /* We need a safe address that is cheap to find and that is already - in L1. We've just brought in "tsk->thread.has_fpu", so use that */ -#define safe_address (tsk->thread.has_fpu) - - /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception - is pending. Clear the x87 state here by setting it to fixed - values. safe_address is a random variable that should be in L1 */ - alternative_input( - ASM_NOP8 ASM_NOP2, - "emms\n\t" /* clear stack tags */ - "fildl %P[addr]", /* set F?P to defined value */ - X86_FEATURE_FXSAVE_LEAK, - [addr] "m" (safe_address)); + struct thread_info *thread = current_thread_info(); + struct task_struct *tsk = thread->task; /* * Paranoid restore. send a SIGSEGV if we fail to restore the state. */ if (unlikely(restore_fpu_checking(tsk))) { - __thread_fpu_end(tsk); + stts(); force_sig(SIGSEGV, tsk); return; } + + thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */ + tsk->fpu_counter++; } /* @@ -754,12 +745,13 @@ void __math_state_restore(struct task_struct *tsk) * Careful.. There are problems with IBM-designed IRQ13 behaviour. * Don't touch unless you *really* know how it works. * - * Must be called with kernel preemption disabled (eg with local - * local interrupts as in the case of do_device_not_available). + * Must be called with kernel preemption disabled (in this case, + * local interrupts are disabled at the call-site in entry.S). */ -void math_state_restore(void) +asmlinkage void math_state_restore(void) { - struct task_struct *tsk = current; + struct thread_info *thread = current_thread_info(); + struct task_struct *tsk = thread->task; if (!tsk_used_math(tsk)) { local_irq_enable(); @@ -776,10 +768,9 @@ void math_state_restore(void) local_irq_disable(); } - __thread_fpu_begin(tsk); - __math_state_restore(tsk); + clts(); /* Allow maths ops (or we recurse) */ - tsk->fpu_counter++; + __math_state_restore(); } EXPORT_SYMBOL_GPL(math_state_restore); diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 4406c038a0a8..6cc6922262af 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -623,8 +623,7 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) if (cpu_khz) { *scale = (NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR)/cpu_khz; - *offset = ns_now - mult_frac(tsc_now, *scale, - (1UL << CYC2NS_SCALE_FACTOR)); + *offset = ns_now - (tsc_now * *scale >> CYC2NS_SCALE_FACTOR); } sched_clock_idle_wakeup_event(0); @@ -957,16 +956,6 @@ static int __init init_tsc_clocksource(void) clocksource_tsc.rating = 0; clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS; } - - /* - * Trust the results of the earlier calibration on systems - * exporting a reliable TSC. - */ - if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) { - clocksource_register_khz(&clocksource_tsc, tsc_khz); - return 0; - } - schedule_delayed_work(&tsc_irqwork, 0); return 0; } diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c index 04b87269edfb..863f8753ab0a 100644 --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c @@ -172,7 +172,6 @@ static void mark_screen_rdonly(struct mm_struct *mm) spinlock_t *ptl; int i; - down_write(&mm->mmap_sem); pgd = pgd_offset(mm, 0xA0000); if (pgd_none_or_clear_bad(pgd)) goto out; @@ -191,7 +190,6 @@ static void mark_screen_rdonly(struct mm_struct *mm) } pte_unmap_unlock(pte, ptl); out: - up_write(&mm->mmap_sem); flush_tlb(); } diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c index 711091114119..a3911343976b 100644 --- a/arch/x86/kernel/xsave.c +++ b/arch/x86/kernel/xsave.c @@ -47,7 +47,7 @@ void __sanitize_i387_state(struct task_struct *tsk) if (!fx) return; - BUG_ON(__thread_has_fpu(tsk)); + BUG_ON(task_thread_info(tsk)->status & TS_USEDFPU); xstate_bv = tsk->thread.fpu.state->xsave.xsave_hdr.xstate_bv; @@ -168,7 +168,7 @@ int save_i387_xstate(void __user *buf) if (!used_math()) return 0; - if (user_has_fpu()) { + if (task_thread_info(tsk)->status & TS_USEDFPU) { if (use_xsave()) err = xsave_user(buf); else @@ -176,7 +176,8 @@ int save_i387_xstate(void __user *buf) if (err) return err; - user_fpu_end(); + task_thread_info(tsk)->status &= ~TS_USEDFPU; + stts(); } else { sanitize_i387_state(tsk); if (__copy_to_user(buf, &tsk->thread.fpu.state->fxsave, @@ -291,7 +292,10 @@ int restore_i387_xstate(void __user *buf) return err; } - user_fpu_begin(); + if (!(task_thread_info(current)->status & TS_USEDFPU)) { + clts(); + task_thread_info(current)->status |= TS_USEDFPU; + } if (use_xsave()) err = restore_user_xstate(buf); else diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 3e7d9138dd2e..adc98675cda0 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1901,51 +1901,6 @@ setup_syscalls_segments(struct x86_emulate_ctxt *ctxt, ss->p = 1; } -static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt) -{ - struct x86_emulate_ops *ops = ctxt->ops; - u32 eax, ebx, ecx, edx; - - /* - * syscall should always be enabled in longmode - so only become - * vendor specific (cpuid) if other modes are active... - */ - if (ctxt->mode == X86EMUL_MODE_PROT64) - return true; - - eax = 0x00000000; - ecx = 0x00000000; - if (ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx)) { - /* - * Intel ("GenuineIntel") - * remark: Intel CPUs only support "syscall" in 64bit - * longmode. Also an 64bit guest with a - * 32bit compat-app running will #UD !! While this - * behaviour can be fixed (by emulating) into AMD - * response - CPUs of AMD can't behave like Intel. - */ - if (ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx && - ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx && - edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx) - return false; - - /* AMD ("AuthenticAMD") */ - if (ebx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx && - ecx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx && - edx == X86EMUL_CPUID_VENDOR_AuthenticAMD_edx) - return true; - - /* AMD ("AMDisbetter!") */ - if (ebx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx && - ecx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx && - edx == X86EMUL_CPUID_VENDOR_AMDisbetterI_edx) - return true; - } - - /* default: (not Intel, not AMD), apply Intel's stricter rules... */ - return false; -} - static int emulate_syscall(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { @@ -1960,15 +1915,9 @@ emulate_syscall(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) ctxt->mode == X86EMUL_MODE_VM86) return emulate_ud(ctxt); - if (!(em_syscall_is_enabled(ctxt))) - return emulate_ud(ctxt); - ops->get_msr(ctxt, MSR_EFER, &efer); setup_syscalls_segments(ctxt, ops, &cs, &ss); - if (!(efer & EFER_SCE)) - return emulate_ud(ctxt); - ops->get_msr(ctxt, MSR_STAR, &msr_data); msr_data >>= 32; cs_sel = (u16)(msr_data & 0xfffc); diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 2ad060acc445..d48ec60ea421 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -948,7 +948,7 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx) #ifdef CONFIG_X86_64 wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base); #endif - if (__thread_has_fpu(current)) + if (current_thread_info()->status & TS_USEDFPU) clts(); load_gdt(&__get_cpu_var(host_gdt)); } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index fbb093601b5a..77c9d8673dc4 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4407,28 +4407,6 @@ static int emulator_intercept(struct x86_emulate_ctxt *ctxt, return kvm_x86_ops->check_intercept(emul_to_vcpu(ctxt), info, stage); } -static bool emulator_get_cpuid(struct x86_emulate_ctxt *ctxt, - u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) -{ - struct kvm_cpuid_entry2 *cpuid = NULL; - - if (eax && ecx) - cpuid = kvm_find_cpuid_entry(emul_to_vcpu(ctxt), - *eax, *ecx); - - if (cpuid) { - *eax = cpuid->eax; - *ecx = cpuid->ecx; - if (ebx) - *ebx = cpuid->ebx; - if (edx) - *edx = cpuid->edx; - return true; - } - - return false; -} - static struct x86_emulate_ops emulate_ops = { .read_std = kvm_read_guest_virt_system, .write_std = kvm_write_guest_virt_system, @@ -4459,7 +4437,6 @@ static struct x86_emulate_ops emulate_ops = { .get_fpu = emulator_get_fpu, .put_fpu = emulator_put_fpu, .intercept = emulator_intercept, - .get_cpuid = emulator_get_cpuid, }; static void cache_all_regs(struct kvm_vcpu *vcpu) diff --git a/arch/x86/lib/delay.c b/arch/x86/lib/delay.c index e395693abdb1..fc45ba887d05 100644 --- a/arch/x86/lib/delay.c +++ b/arch/x86/lib/delay.c @@ -48,9 +48,9 @@ static void delay_loop(unsigned long loops) } /* TSC based delay: */ -static void delay_tsc(unsigned long __loops) +static void delay_tsc(unsigned long loops) { - u32 bclock, now, loops = __loops; + unsigned long bclock, now; int cpu; preempt_disable(); diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c index dd74e46828c0..dbe34b931374 100644 --- a/arch/x86/mm/gup.c +++ b/arch/x86/mm/gup.c @@ -108,6 +108,16 @@ static inline void get_head_page_multiple(struct page *page, int nr) SetPageReferenced(page); } +static inline void get_huge_page_tail(struct page *page) +{ + /* + * __split_huge_page_refcount() cannot run + * from under us. + */ + VM_BUG_ON(atomic_read(&page->_count) < 0); + atomic_inc(&page->_count); +} + static noinline int gup_huge_pmd(pmd_t pmd, unsigned long addr, unsigned long end, int write, struct page **pages, int *nr) { @@ -201,8 +211,6 @@ static noinline int gup_huge_pud(pud_t pud, unsigned long addr, do { VM_BUG_ON(compound_head(page) != head); pages[*nr] = page; - if (PageTail(page)) - get_huge_page_tail(page); (*nr)++; page++; refs++; diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c index f4f29b19fac5..b49962662101 100644 --- a/arch/x86/mm/highmem_32.c +++ b/arch/x86/mm/highmem_32.c @@ -45,7 +45,6 @@ void *kmap_atomic_prot(struct page *page, pgprot_t prot) vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); BUG_ON(!pte_none(*(kmap_pte-idx))); set_pte(kmap_pte-idx, mk_pte(page, prot)); - arch_flush_lazy_mmu_mode(); return (void *)vaddr; } @@ -89,7 +88,6 @@ void __kunmap_atomic(void *kvaddr) */ kpte_clear_flush(kmap_pte-idx, vaddr); kmap_atomic_idx_pop(); - arch_flush_lazy_mmu_mode(); } #ifdef CONFIG_DEBUG_HIGHMEM else { diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c index df7d12c9af24..f581a18c0d4d 100644 --- a/arch/x86/mm/hugetlbpage.c +++ b/arch/x86/mm/hugetlbpage.c @@ -56,16 +56,9 @@ static int vma_shareable(struct vm_area_struct *vma, unsigned long addr) } /* - * Search for a shareable pmd page for hugetlb. In any case calls pmd_alloc() - * and returns the corresponding pte. While this is not necessary for the - * !shared pmd case because we can allocate the pmd later as well, it makes the - * code much cleaner. pmd allocation is essential for the shared case because - * pud has to be populated inside the same i_mmap_mutex section - otherwise - * racing tasks could either miss the sharing (see huge_pte_offset) or select a - * bad pmd for sharing. + * search for a shareable pmd page for hugetlb. */ -static pte_t * -huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) +static void huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) { struct vm_area_struct *vma = find_vma(mm, addr); struct address_space *mapping = vma->vm_file->f_mapping; @@ -75,10 +68,9 @@ huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) struct vm_area_struct *svma; unsigned long saddr; pte_t *spte = NULL; - pte_t *pte; if (!vma_shareable(vma, addr)) - return (pte_t *)pmd_alloc(mm, pud, addr); + return; mutex_lock(&mapping->i_mmap_mutex); vma_prio_tree_foreach(svma, &iter, &mapping->i_mmap, idx, idx) { @@ -105,9 +97,7 @@ huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) put_page(virt_to_page(spte)); spin_unlock(&mm->page_table_lock); out: - pte = (pte_t *)pmd_alloc(mm, pud, addr); mutex_unlock(&mapping->i_mmap_mutex); - return pte; } /* @@ -152,9 +142,8 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, } else { BUG_ON(sz != PMD_SIZE); if (pud_none(*pud)) - pte = huge_pmd_share(mm, addr, pud); - else - pte = (pte_t *)pmd_alloc(mm, pud, addr); + huge_pmd_share(mm, addr, pud); + pte = (pte_t *) pmd_alloc(mm, pud, addr); } } BUG_ON(pte && !pte_none(*pte) && !pte_huge(*pte)); diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index c22c4236d49d..30326443ab81 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -28,57 +28,44 @@ int direct_gbpages #endif ; -struct map_range { - unsigned long start; - unsigned long end; - unsigned page_size_mask; -}; - -/* - * First calculate space needed for kernel direct mapping page tables to cover - * mr[0].start to mr[nr_range - 1].end, while accounting for possible 2M and 1GB - * pages. Then find enough contiguous space for those page tables. - */ -static void __init find_early_table_space(struct map_range *mr, int nr_range) +static void __init find_early_table_space(unsigned long end, int use_pse, + int use_gbpages) { - int i; - unsigned long puds = 0, pmds = 0, ptes = 0, tables; - unsigned long start = 0, good_end; + unsigned long puds, pmds, ptes, tables, start = 0, good_end = end; phys_addr_t base; - for (i = 0; i < nr_range; i++) { - unsigned long range, extra; + puds = (end + PUD_SIZE - 1) >> PUD_SHIFT; + tables = roundup(puds * sizeof(pud_t), PAGE_SIZE); + + if (use_gbpages) { + unsigned long extra; + + extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT); + pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT; + } else + pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; - range = mr[i].end - mr[i].start; - puds += (range + PUD_SIZE - 1) >> PUD_SHIFT; + tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE); - if (mr[i].page_size_mask & (1 << PG_LEVEL_1G)) { - extra = range - ((range >> PUD_SHIFT) << PUD_SHIFT); - pmds += (extra + PMD_SIZE - 1) >> PMD_SHIFT; - } else { - pmds += (range + PMD_SIZE - 1) >> PMD_SHIFT; - } + if (use_pse) { + unsigned long extra; - if (mr[i].page_size_mask & (1 << PG_LEVEL_2M)) { - extra = range - ((range >> PMD_SHIFT) << PMD_SHIFT); + extra = end - ((end>>PMD_SHIFT) << PMD_SHIFT); #ifdef CONFIG_X86_32 - extra += PMD_SIZE; + extra += PMD_SIZE; #endif - ptes += (extra + PAGE_SIZE - 1) >> PAGE_SHIFT; - } else { - ptes += (range + PAGE_SIZE - 1) >> PAGE_SHIFT; - } - } + ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT; + } else + ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT; - tables = roundup(puds * sizeof(pud_t), PAGE_SIZE); - tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE); tables += roundup(ptes * sizeof(pte_t), PAGE_SIZE); #ifdef CONFIG_X86_32 /* for fixmap */ tables += roundup(__end_of_fixed_addresses * sizeof(pte_t), PAGE_SIZE); -#endif + good_end = max_pfn_mapped << PAGE_SHIFT; +#endif base = memblock_find_in_range(start, good_end, tables, PAGE_SIZE); if (base == MEMBLOCK_ERROR) @@ -88,9 +75,8 @@ static void __init find_early_table_space(struct map_range *mr, int nr_range) pgt_buf_end = pgt_buf_start; pgt_buf_top = pgt_buf_start + (tables >> PAGE_SHIFT); - printk(KERN_DEBUG "kernel direct mapping tables up to %#lx @ [mem %#010lx-%#010lx]\n", - mr[nr_range - 1].end - 1, pgt_buf_start << PAGE_SHIFT, - (pgt_buf_top << PAGE_SHIFT) - 1); + printk(KERN_DEBUG "kernel direct mapping tables up to %lx @ %lx-%lx\n", + end, pgt_buf_start << PAGE_SHIFT, pgt_buf_top << PAGE_SHIFT); } void __init native_pagetable_reserve(u64 start, u64 end) @@ -98,6 +84,12 @@ void __init native_pagetable_reserve(u64 start, u64 end) memblock_x86_reserve_range(start, end, "PGTABLE"); } +struct map_range { + unsigned long start; + unsigned long end; + unsigned page_size_mask; +}; + #ifdef CONFIG_X86_32 #define NR_RANGE_MR 3 #else /* CONFIG_X86_64 */ @@ -269,7 +261,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, * nodes are discovered. */ if (!after_bootmem) - find_early_table_space(mr, nr_range); + find_early_table_space(end, use_pse, use_gbpages); for (i = 0; i < nr_range; i++) ret = kernel_physical_mapping_init(mr[i].start, mr[i].end, diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 44b93da18401..bbaaa005bf0e 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -831,9 +831,6 @@ int kern_addr_valid(unsigned long addr) if (pud_none(*pud)) return 0; - if (pud_large(*pud)) - return pfn_valid(pud_pfn(*pud)); - pmd = pmd_offset(pud, addr); if (pmd_none(*pmd)) return 0; diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c index f927429d07ca..1dab5194fd9d 100644 --- a/arch/x86/mm/mmap.c +++ b/arch/x86/mm/mmap.c @@ -87,9 +87,9 @@ static unsigned long mmap_rnd(void) */ if (current->flags & PF_RANDOMIZE) { if (mmap_is_ia32()) - rnd = get_random_int() % (1<<8); + rnd = (long)get_random_int() % (1<<8); else - rnd = get_random_int() % (1<<28); + rnd = (long)(get_random_int() % (1<<28)); } return rnd << PAGE_SHIFT; } diff --git a/arch/x86/mm/srat.c b/arch/x86/mm/srat.c index 7efd0c615d58..81dbfdeb080d 100644 --- a/arch/x86/mm/srat.c +++ b/arch/x86/mm/srat.c @@ -104,8 +104,6 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0) return; pxm = pa->proximity_domain_lo; - if (acpi_srat_revision >= 2) - pxm |= *((unsigned int*)pa->proximity_domain_hi) << 8; node = setup_node(pxm); if (node < 0) { printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm); @@ -157,8 +155,6 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) start = ma->base_address; end = start + ma->length; pxm = ma->proximity_domain; - if (acpi_srat_revision <= 1) - pxm &= 0xff; node = setup_node(pxm); if (node < 0) { printk(KERN_ERR "SRAT: Too many proximity domains.\n"); diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index 5a5b6e4dd738..bfab3fa10edc 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -151,18 +151,17 @@ void bpf_jit_compile(struct sk_filter *fp) cleanup_addr = proglen; /* epilogue address */ for (pass = 0; pass < 10; pass++) { - u8 seen_or_pass0 = (pass == 0) ? (SEEN_XREG | SEEN_DATAREF | SEEN_MEM) : seen; /* no prologue/epilogue for trivial filters (RET something) */ proglen = 0; prog = temp; - if (seen_or_pass0) { + if (seen) { EMIT4(0x55, 0x48, 0x89, 0xe5); /* push %rbp; mov %rsp,%rbp */ EMIT4(0x48, 0x83, 0xec, 96); /* subq $96,%rsp */ /* note : must save %rbx in case bpf_error is hit */ - if (seen_or_pass0 & (SEEN_XREG | SEEN_DATAREF)) + if (seen & (SEEN_XREG | SEEN_DATAREF)) EMIT4(0x48, 0x89, 0x5d, 0xf8); /* mov %rbx, -8(%rbp) */ - if (seen_or_pass0 & SEEN_XREG) + if (seen & SEEN_XREG) CLEAR_X(); /* make sure we dont leek kernel memory */ /* @@ -171,7 +170,7 @@ void bpf_jit_compile(struct sk_filter *fp) * r9 = skb->len - skb->data_len * r8 = skb->data */ - if (seen_or_pass0 & SEEN_DATAREF) { + if (seen & SEEN_DATAREF) { if (offsetof(struct sk_buff, len) <= 127) /* mov off8(%rdi),%r9d */ EMIT4(0x44, 0x8b, 0x4f, offsetof(struct sk_buff, len)); @@ -261,14 +260,9 @@ void bpf_jit_compile(struct sk_filter *fp) case BPF_S_ALU_DIV_X: /* A /= X; */ seen |= SEEN_XREG; EMIT2(0x85, 0xdb); /* test %ebx,%ebx */ - if (pc_ret0 > 0) { - /* addrs[pc_ret0 - 1] is start address of target - * (addrs[i] - 4) is the address following this jmp - * ("xor %edx,%edx; div %ebx" being 4 bytes long) - */ - EMIT_COND_JMP(X86_JE, addrs[pc_ret0 - 1] - - (addrs[i] - 4)); - } else { + if (pc_ret0 != -1) + EMIT_COND_JMP(X86_JE, addrs[pc_ret0] - (addrs[i] - 4)); + else { EMIT_COND_JMP(X86_JNE, 2 + 5); CLEAR_A(); EMIT1_off32(0xe9, cleanup_addr - (addrs[i] - 4)); /* jmp .+off32 */ @@ -289,7 +283,7 @@ void bpf_jit_compile(struct sk_filter *fp) EMIT2(0x24, K & 0xFF); /* and imm8,%al */ } else if (K >= 0xFFFF0000) { EMIT2(0x66, 0x25); /* and imm16,%ax */ - EMIT(K, 2); + EMIT2(K, 2); } else { EMIT1_off32(0x25, K); /* and imm32,%eax */ } @@ -341,12 +335,12 @@ void bpf_jit_compile(struct sk_filter *fp) } /* fallinto */ case BPF_S_RET_A: - if (seen_or_pass0) { + if (seen) { if (i != flen - 1) { EMIT_JMP(cleanup_addr - addrs[i]); break; } - if (seen_or_pass0 & SEEN_XREG) + if (seen & SEEN_XREG) EMIT4(0x48, 0x8b, 0x5d, 0xf8); /* mov -8(%rbp),%rbx */ EMIT1(0xc9); /* leaveq */ } @@ -475,10 +469,8 @@ void bpf_jit_compile(struct sk_filter *fp) case BPF_S_LD_W_ABS: func = sk_load_word; common_load: seen |= SEEN_DATAREF; - if ((int)K < 0) { - /* Abort the JIT because __load_pointer() is needed. */ + if ((int)K < 0) goto out; - } t_offset = func - (image + addrs[i]); EMIT1_off32(0xbe, K); /* mov imm32,%esi */ EMIT1_off32(0xe8, t_offset); /* call */ @@ -491,8 +483,13 @@ common_load: seen |= SEEN_DATAREF; goto common_load; case BPF_S_LDX_B_MSH: if ((int)K < 0) { - /* Abort the JIT because __load_pointer() is needed. */ - goto out; + if (pc_ret0 != -1) { + EMIT_JMP(addrs[pc_ret0] - addrs[i]); + break; + } + CLEAR_A(); + EMIT_JMP(cleanup_addr - addrs[i]); + break; } seen |= SEEN_DATAREF | SEEN_XREG; t_offset = sk_load_byte_msh - (image + addrs[i]); @@ -571,8 +568,8 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i]; break; } if (filter[i].jt != 0) { - if (filter[i].jf && f_offset) - t_offset += is_near(f_offset) ? 2 : 5; + if (filter[i].jf) + t_offset += is_near(f_offset) ? 2 : 6; EMIT_COND_JMP(t_op, t_offset); if (filter[i].jf) EMIT_JMP(f_offset); @@ -602,14 +599,13 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i]; * use it to give the cleanup instruction(s) addr */ cleanup_addr = proglen - 1; /* ret */ - if (seen_or_pass0) + if (seen) cleanup_addr -= 1; /* leaveq */ - if (seen_or_pass0 & SEEN_XREG) + if (seen & SEEN_XREG) cleanup_addr -= 4; /* mov -8(%rbp),%rbx */ if (image) { - if (proglen != oldproglen) - pr_err("bpb_jit_compile proglen=%u != oldproglen=%u\n", proglen, oldproglen); + WARN_ON(proglen != oldproglen); break; } if (proglen == oldproglen) { diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c index 32f78eb46744..a5b64ab4cd6e 100644 --- a/arch/x86/oprofile/backtrace.c +++ b/arch/x86/oprofile/backtrace.c @@ -11,12 +11,10 @@ #include #include #include -#include -#include - #include #include #include +#include static int backtrace_stack(void *data, char *name) { @@ -38,53 +36,17 @@ static struct stacktrace_ops backtrace_ops = { .walk_stack = print_context_stack, }; -/* from arch/x86/kernel/cpu/perf_event.c: */ - -/* - * best effort, GUP based copy_from_user() that assumes IRQ or NMI context - */ -static unsigned long -copy_from_user_nmi(void *to, const void __user *from, unsigned long n) -{ - unsigned long offset, addr = (unsigned long)from; - unsigned long size, len = 0; - struct page *page; - void *map; - int ret; - - do { - ret = __get_user_pages_fast(addr, 1, 0, &page); - if (!ret) - break; - - offset = addr & (PAGE_SIZE - 1); - size = min(PAGE_SIZE - offset, n - len); - - map = kmap_atomic(page); - memcpy(to, map+offset, size); - kunmap_atomic(map); - put_page(page); - - len += size; - to += size; - addr += size; - - } while (len < n); - - return len; -} - #ifdef CONFIG_COMPAT static struct stack_frame_ia32 * dump_user_backtrace_32(struct stack_frame_ia32 *head) { - /* Also check accessibility of one struct frame_head beyond: */ struct stack_frame_ia32 bufhead[2]; struct stack_frame_ia32 *fp; - unsigned long bytes; - bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead)); - if (bytes != sizeof(bufhead)) + /* Also check accessibility of one struct frame_head beyond */ + if (!access_ok(VERIFY_READ, head, sizeof(bufhead))) + return NULL; + if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead))) return NULL; fp = (struct stack_frame_ia32 *) compat_ptr(bufhead[0].next_frame); @@ -125,12 +87,12 @@ x86_backtrace_32(struct pt_regs * const regs, unsigned int depth) static struct stack_frame *dump_user_backtrace(struct stack_frame *head) { - /* Also check accessibility of one struct frame_head beyond: */ struct stack_frame bufhead[2]; - unsigned long bytes; - bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead)); - if (bytes != sizeof(bufhead)) + /* Also check accessibility of one struct stack_frame beyond */ + if (!access_ok(VERIFY_READ, head, sizeof(bufhead))) + return NULL; + if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead))) return NULL; oprofile_add_trace(bufhead[0].return_address); diff --git a/arch/x86/oprofile/init.c b/arch/x86/oprofile/init.c index f148cf652678..cdfe4c54deca 100644 --- a/arch/x86/oprofile/init.c +++ b/arch/x86/oprofile/init.c @@ -21,7 +21,6 @@ extern int op_nmi_timer_init(struct oprofile_operations *ops); extern void op_nmi_exit(void); extern void x86_backtrace(struct pt_regs * const regs, unsigned int depth); -static int nmi_timer; int __init oprofile_arch_init(struct oprofile_operations *ops) { @@ -32,9 +31,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) #ifdef CONFIG_X86_LOCAL_APIC ret = op_nmi_init(ops); #endif - nmi_timer = (ret != 0); #ifdef CONFIG_X86_IO_APIC - if (nmi_timer) + if (ret < 0) ret = op_nmi_timer_init(ops); #endif ops->backtrace = x86_backtrace; @@ -46,7 +44,6 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) void oprofile_arch_exit(void) { #ifdef CONFIG_X86_LOCAL_APIC - if (!nmi_timer) - op_nmi_exit(); + op_nmi_exit(); #endif } diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index a00c588b69d4..68894fdc034b 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -55,7 +55,7 @@ u64 op_x86_get_ctrl(struct op_x86_model_spec const *model, val |= counter_config->extra; event &= model->event_mask ? model->event_mask : 0xFF; val |= event & 0xFF; - val |= (u64)(event & 0x0F00) << 24; + val |= (event & 0x0F00) << 24; return val; } diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index d24d3da72926..6b8759f7634e 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile @@ -18,9 +18,8 @@ obj-$(CONFIG_X86_NUMAQ) += numaq_32.o obj-$(CONFIG_X86_MRST) += mrst.o obj-y += common.o early.o -obj-y += bus_numa.o +obj-y += amd_bus.o bus_numa.o -obj-$(CONFIG_AMD_NB) += amd_bus.o obj-$(CONFIG_PCI_CNB20LE_QUIRK) += broadcom_bus.o ifeq ($(CONFIG_PCI_DEBUG),y) diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 0473a8f93501..68c3c1395202 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -43,27 +43,6 @@ static const struct dmi_system_id pci_use_crs_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "ALiveSATA2-GLAN"), }, }, - /* https://bugzilla.kernel.org/show_bug.cgi?id=30552 */ - /* 2006 AMD HT/VIA system with two host bridges */ - { - .callback = set_use_crs, - .ident = "ASUS M2V-MX SE", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), - DMI_MATCH(DMI_BOARD_NAME, "M2V-MX SE"), - DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), - }, - }, - /* https://bugzilla.kernel.org/show_bug.cgi?id=42619 */ - { - .callback = set_use_crs, - .ident = "MSI MS-7253", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), - DMI_MATCH(DMI_BOARD_NAME, "MS-7253"), - DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"), - }, - }, {} }; @@ -159,7 +138,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data) struct acpi_resource_address64 addr; acpi_status status; unsigned long flags; - u64 start, orig_end, end; + u64 start, end; status = resource_to_addr(acpi_res, &addr); if (!ACPI_SUCCESS(status)) @@ -175,21 +154,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data) return AE_OK; start = addr.minimum + addr.translation_offset; - orig_end = end = addr.maximum + addr.translation_offset; - - /* Exclude non-addressable range or non-addressable portion of range */ - end = min(end, (u64)iomem_resource.end); - if (end <= start) { - dev_info(&info->bridge->dev, - "host bridge window [%#llx-%#llx] " - "(ignored, not CPU addressable)\n", start, orig_end); - return AE_OK; - } else if (orig_end != end) { - dev_info(&info->bridge->dev, - "host bridge window [%#llx-%#llx] " - "([%#llx-%#llx] ignored, not CPU addressable)\n", - start, orig_end, end + 1, orig_end); - } + end = addr.maximum + addr.translation_offset; res = &info->res[info->res_num]; res->name = info->name; diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index 385a940b5422..026e4931d162 100644 --- a/arch/x86/pci/amd_bus.c +++ b/arch/x86/pci/amd_bus.c @@ -30,6 +30,34 @@ static struct pci_hostbridge_probe pci_probes[] __initdata = { { 0, 0x18, PCI_VENDOR_ID_AMD, 0x1300 }, }; +static u64 __initdata fam10h_mmconf_start; +static u64 __initdata fam10h_mmconf_end; +static void __init get_pci_mmcfg_amd_fam10h_range(void) +{ + u32 address; + u64 base, msr; + unsigned segn_busn_bits; + + /* assume all cpus from fam10h have mmconf */ + if (boot_cpu_data.x86 < 0x10) + return; + + address = MSR_FAM10H_MMIO_CONF_BASE; + rdmsrl(address, msr); + + /* mmconfig is not enable */ + if (!(msr & FAM10H_MMIO_CONF_ENABLE)) + return; + + base = msr & (FAM10H_MMIO_CONF_BASE_MASK<> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) & + FAM10H_MMIO_CONF_BUSRANGE_MASK; + + fam10h_mmconf_start = base; + fam10h_mmconf_end = base + (1ULL<<(segn_busn_bits + 20)) - 1; +} + #define RANGE_NUM 16 /** @@ -57,9 +85,6 @@ static int __init early_fill_mp_bus_info(void) u64 val; u32 address; bool found; - struct resource fam10h_mmconf_res, *fam10h_mmconf; - u64 fam10h_mmconf_start; - u64 fam10h_mmconf_end; if (!early_pci_allowed()) return -1; @@ -186,17 +211,12 @@ static int __init early_fill_mp_bus_info(void) subtract_range(range, RANGE_NUM, 0, end); /* get mmconfig */ - fam10h_mmconf = amd_get_mmconfig_range(&fam10h_mmconf_res); + get_pci_mmcfg_amd_fam10h_range(); /* need to take out mmconf range */ - if (fam10h_mmconf) { - printk(KERN_DEBUG "Fam 10h mmconf %pR\n", fam10h_mmconf); - fam10h_mmconf_start = fam10h_mmconf->start; - fam10h_mmconf_end = fam10h_mmconf->end; + if (fam10h_mmconf_end) { + printk(KERN_DEBUG "Fam 10h mmconf [%llx, %llx]\n", fam10h_mmconf_start, fam10h_mmconf_end); subtract_range(range, RANGE_NUM, fam10h_mmconf_start, fam10h_mmconf_end + 1); - } else { - fam10h_mmconf_start = 0; - fam10h_mmconf_end = 0; } /* mmio resource */ diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 0951b81ea90e..6dd89555fbfa 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c @@ -521,20 +521,3 @@ static void sb600_disable_hpet_bar(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x4385, sb600_disable_hpet_bar); - -/* - * Twinhead H12Y needs us to block out a region otherwise we map devices - * there and any access kills the box. - * - * See: https://bugzilla.kernel.org/show_bug.cgi?id=10231 - * - * Match off the LPC and svid/sdid (older kernels lose the bridge subvendor) - */ -static void __devinit twinhead_reserve_killing_zone(struct pci_dev *dev) -{ - if (dev->subsystem_vendor == 0x14FF && dev->subsystem_device == 0xA003) { - pr_info("Reserving memory on Twinhead H12Y\n"); - request_mem_region(0xFFB00000, 0x100000, "twinhead"); - } -} -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x27B9, twinhead_reserve_killing_zone); diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 6e96e65e7caa..f567965c0620 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -308,7 +308,7 @@ int __init pci_xen_init(void) int __init pci_xen_hvm_init(void) { - if (!xen_have_vector_callback || !xen_feature(XENFEAT_hvm_pirqs)) + if (!xen_feature(XENFEAT_hvm_pirqs)) return 0; #ifdef CONFIG_ACPI diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 0fba86da5895..ac3aa54e2654 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -38,7 +38,7 @@ #include #include -static pgd_t *save_pgd __initdata; +static pgd_t save_pgd __initdata; static unsigned long efi_flags __initdata; static void __init early_code_mapping_set_exec(int executable) @@ -61,20 +61,12 @@ static void __init early_code_mapping_set_exec(int executable) void __init efi_call_phys_prelog(void) { unsigned long vaddress; - int pgd; - int n_pgds; early_code_mapping_set_exec(1); local_irq_save(efi_flags); - - n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE); - save_pgd = kmalloc(n_pgds * sizeof(pgd_t), GFP_KERNEL); - - for (pgd = 0; pgd < n_pgds; pgd++) { - save_pgd[pgd] = *pgd_offset_k(pgd * PGDIR_SIZE); - vaddress = (unsigned long)__va(pgd * PGDIR_SIZE); - set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), *pgd_offset_k(vaddress)); - } + vaddress = (unsigned long)__va(0x0UL); + save_pgd = *pgd_offset_k(0x0UL); + set_pgd(pgd_offset_k(0x0UL), *pgd_offset_k(vaddress)); __flush_tlb_all(); } @@ -83,11 +75,7 @@ void __init efi_call_phys_epilog(void) /* * After the lock is released, the original page table is restored. */ - int pgd; - int n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE); - for (pgd = 0; pgd < n_pgds; pgd++) - set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), save_pgd[pgd]); - kfree(save_pgd); + set_pgd(pgd_offset_k(0x0UL), save_pgd); __flush_tlb_all(); local_irq_restore(efi_flags); early_code_mapping_set_exec(0); diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c index fe73276e026b..7000e74b3087 100644 --- a/arch/x86/platform/mrst/mrst.c +++ b/arch/x86/platform/mrst/mrst.c @@ -678,40 +678,36 @@ static int __init sfi_parse_devs(struct sfi_table_header *table) pentry = (struct sfi_device_table_entry *)sb->pentry; for (i = 0; i < num; i++, pentry++) { - int irq = pentry->irq; - - if (irq != (u8)0xff) { /* native RTE case */ + if (pentry->irq != (u8)0xff) { /* native RTE case */ /* these SPI2 devices are not exposed to system as PCI * devices, but they have separate RTE entry in IOAPIC * so we have to enable them one by one here */ - ioapic = mp_find_ioapic(irq); + ioapic = mp_find_ioapic(pentry->irq); irq_attr.ioapic = ioapic; - irq_attr.ioapic_pin = irq; + irq_attr.ioapic_pin = pentry->irq; irq_attr.trigger = 1; irq_attr.polarity = 1; - io_apic_set_pci_routing(NULL, irq, &irq_attr); - } else - irq = 0; /* No irq */ - + io_apic_set_pci_routing(NULL, pentry->irq, &irq_attr); + } switch (pentry->type) { case SFI_DEV_TYPE_IPC: /* ID as IRQ is a hack that will go away */ - pdev = platform_device_alloc(pentry->name, irq); + pdev = platform_device_alloc(pentry->name, pentry->irq); if (pdev == NULL) { pr_err("out of memory for SFI platform device '%s'.\n", pentry->name); continue; } - install_irq_resource(pdev, irq); + install_irq_resource(pdev, pentry->irq); pr_debug("info[%2d]: IPC bus, name = %16.16s, " - "irq = 0x%2x\n", i, pentry->name, irq); + "irq = 0x%2x\n", i, pentry->name, pentry->irq); sfi_handle_ipc_dev(pdev); break; case SFI_DEV_TYPE_SPI: memset(&spi_info, 0, sizeof(spi_info)); strncpy(spi_info.modalias, pentry->name, SFI_NAME_LEN); - spi_info.irq = irq; + spi_info.irq = pentry->irq; spi_info.bus_num = pentry->host_num; spi_info.chip_select = pentry->addr; spi_info.max_speed_hz = pentry->max_freq; @@ -728,7 +724,7 @@ static int __init sfi_parse_devs(struct sfi_table_header *table) memset(&i2c_info, 0, sizeof(i2c_info)); bus = pentry->host_num; strncpy(i2c_info.type, pentry->name, SFI_NAME_LEN); - i2c_info.irq = irq; + i2c_info.irq = pentry->irq; i2c_info.addr = pentry->addr; pr_debug("info[%2d]: I2C bus = %d, name = %16.16s, " "irq = 0x%2x, addr = 0x%x\n", i, bus, diff --git a/arch/x86/platform/olpc/olpc.c b/arch/x86/platform/olpc/olpc.c index 02e39345dc6d..0060fd59ea00 100644 --- a/arch/x86/platform/olpc/olpc.c +++ b/arch/x86/platform/olpc/olpc.c @@ -157,13 +157,13 @@ restart: if (inbuf && inlen) { /* write data to EC */ for (i = 0; i < inlen; i++) { - pr_devel("olpc-ec: sending cmd arg 0x%x\n", inbuf[i]); - outb(inbuf[i], 0x68); if (wait_on_ibf(0x6c, 0)) { printk(KERN_ERR "olpc-ec: timeout waiting for" " EC accept data!\n"); goto err; } + pr_devel("olpc-ec: sending cmd arg 0x%x\n", inbuf[i]); + outb(inbuf[i], 0x68); } } if (outbuf && outlen) { diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index edf435b74e85..68e467f69fec 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c @@ -115,6 +115,9 @@ early_param("nobau", setup_nobau); /* base pnode in this partition */ static int uv_base_pnode __read_mostly; +/* position of pnode (which is nasid>>1): */ +static int uv_nshift __read_mostly; +static unsigned long uv_mmask __read_mostly; static DEFINE_PER_CPU(struct ptc_stats, ptcstats); static DEFINE_PER_CPU(struct bau_control, bau_control); @@ -1423,7 +1426,7 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode) { int i; int cpu; - unsigned long gpa; + unsigned long pa; unsigned long m; unsigned long n; size_t dsize; @@ -1439,9 +1442,9 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode) bau_desc = kmalloc_node(dsize, GFP_KERNEL, node); BUG_ON(!bau_desc); - gpa = uv_gpa(bau_desc); - n = uv_gpa_to_gnode(gpa); - m = uv_gpa_to_offset(gpa); + pa = uv_gpa(bau_desc); /* need the real nasid*/ + n = pa >> uv_nshift; + m = pa & uv_mmask; /* the 14-bit pnode */ write_mmr_descriptor_base(pnode, (n << UV_DESC_PSHIFT | m)); @@ -1513,9 +1516,9 @@ static void pq_init(int node, int pnode) bcp->queue_last = pqp + (DEST_Q_SIZE - 1); } /* - * need the gnode of where the memory was really allocated + * need the pnode of where the memory was really allocated */ - pn = uv_gpa_to_gnode(uv_gpa(pqp)); + pn = uv_gpa(pqp) >> uv_nshift; first = uv_physnodeaddr(pqp); pn_first = ((unsigned long)pn << UV_PAYLOADQ_PNODE_SHIFT) | first; last = uv_physnodeaddr(pqp + (DEST_Q_SIZE - 1)); @@ -1575,14 +1578,14 @@ static int calculate_destination_timeout(void) ts_ns = base * mult1 * mult2; ret = ts_ns / 1000; } else { - /* 4 bits 0/1 for 10/80us base, 3 bits of multiplier */ - mmr_image = uv_read_local_mmr(UVH_LB_BAU_MISC_CONTROL); + /* 4 bits 0/1 for 10/80us, 3 bits of multiplier */ + mmr_image = uv_read_local_mmr(UVH_AGING_PRESCALE_SEL); mmr_image = (mmr_image & UV_SA_MASK) >> UV_SA_SHFT; if (mmr_image & (1L << UV2_ACK_UNITS_SHFT)) - base = 80; + mult1 = 80; else - base = 10; - mult1 = mmr_image & UV2_ACK_MASK; + mult1 = 10; + base = mmr_image & UV2_ACK_MASK; ret = mult1 * base; } return ret; @@ -1809,6 +1812,8 @@ static int __init uv_bau_init(void) zalloc_cpumask_var_node(mask, GFP_KERNEL, cpu_to_node(cur_cpu)); } + uv_nshift = uv_hub_info->m_val; + uv_mmask = (1UL << uv_hub_info->m_val) - 1; nuvhubs = uv_num_possible_blades(); spin_lock_init(&disable_lock); congested_cycles = usec_2_cycles(congested_respns_us); @@ -1820,8 +1825,6 @@ static int __init uv_bau_init(void) uv_base_pnode = uv_blade_to_pnode(uvhub); } - enable_timeouts(); - if (init_per_cpu(nuvhubs, uv_base_pnode)) { nobau = 1; return 0; @@ -1832,6 +1835,7 @@ static int __init uv_bau_init(void) if (uv_blade_nr_possible_cpus(uvhub)) init_uvhub(uvhub, vector, uv_base_pnode); + enable_timeouts(); alloc_intr_gate(vector, uv_bau_message_intr1); for_each_possible_blade(uvhub) { diff --git a/arch/x86/vdso/vdso32/sysenter.S b/arch/x86/vdso/vdso32/sysenter.S index e354bceee0e0..e2800affa754 100644 --- a/arch/x86/vdso/vdso32/sysenter.S +++ b/arch/x86/vdso/vdso32/sysenter.S @@ -43,7 +43,7 @@ __kernel_vsyscall: .space 7,0x90 /* 14: System call restart point is here! (SYSENTER_RETURN-2) */ - int $0x80 + jmp .Lenter_kernel /* 16: System call normal return point is here! */ VDSO32_SYSENTER_RETURN: /* Symbol used by sysenter.c via vdso32-syms.h */ pop %ebp diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile index a6575b949b11..17c565de3d64 100644 --- a/arch/x86/xen/Makefile +++ b/arch/x86/xen/Makefile @@ -18,5 +18,5 @@ obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \ obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o -obj-$(CONFIG_XEN_DOM0) += vga.o + obj-$(CONFIG_SWIOTLB_XEN) += pci-swiotlb-xen.o diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 9f808afe0d1b..5525163a0398 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -62,7 +62,6 @@ #include #include #include -#include #include "xen-ops.h" #include "mmu.h" @@ -78,8 +77,8 @@ EXPORT_SYMBOL_GPL(xen_domain_type); unsigned long *machine_to_phys_mapping = (void *)MACH2PHYS_VIRT_START; EXPORT_SYMBOL(machine_to_phys_mapping); -unsigned long machine_to_phys_nr; -EXPORT_SYMBOL(machine_to_phys_nr); +unsigned int machine_to_phys_order; +EXPORT_SYMBOL(machine_to_phys_order); struct start_info *xen_start_info; EXPORT_SYMBOL_GPL(xen_start_info); @@ -198,9 +197,6 @@ static void __init xen_banner(void) xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : ""); } -#define CPUID_THERM_POWER_LEAF 6 -#define APERFMPERF_PRESENT 0 - static __read_mostly unsigned int cpuid_leaf1_edx_mask = ~0; static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0; @@ -221,11 +217,6 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx, maskedx = cpuid_leaf1_edx_mask; break; - case CPUID_THERM_POWER_LEAF: - /* Disabling APERFMPERF for kernel usage */ - maskecx = ~(1 << APERFMPERF_PRESENT); - break; - case 0xb: /* Suppress extended topology stuff */ maskebx = 0; @@ -803,16 +794,7 @@ static void xen_write_cr4(unsigned long cr4) native_write_cr4(cr4); } -#ifdef CONFIG_X86_64 -static inline unsigned long xen_read_cr8(void) -{ - return 0; -} -static inline void xen_write_cr8(unsigned long val) -{ - BUG_ON(val); -} -#endif + static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) { int ret; @@ -977,11 +959,6 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = { .read_cr4_safe = native_read_cr4_safe, .write_cr4 = xen_write_cr4, -#ifdef CONFIG_X86_64 - .read_cr8 = xen_read_cr8, - .write_cr8 = xen_write_cr8, -#endif - .wbinvd = native_wbinvd, .read_msr = native_read_msr_safe, @@ -989,8 +966,6 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = { .read_tsc = native_read_tsc, .read_pmc = native_read_pmc, - .read_tscp = native_read_tscp, - .iret = xen_iret, .irq_enable_sysexit = xen_sysexit, #ifdef CONFIG_X86_64 @@ -1273,21 +1248,11 @@ asmlinkage void __init xen_start_kernel(void) if (pci_xen) x86_init.pci.arch_init = pci_xen_init; } else { - const struct dom0_vga_console_info *info = - (void *)((char *)xen_start_info + - xen_start_info->console.dom0.info_off); - - xen_init_vga(info, xen_start_info->console.dom0.info_size); - xen_start_info->console.domU.mfn = 0; - xen_start_info->console.domU.evtchn = 0; - /* Make sure ACS will be enabled */ pci_request_acs(); } -#ifdef CONFIG_PCI - /* PCI BIOS service won't work from a PV guest. */ - pci_probe &= ~PCI_PROBE_BIOS; -#endif + + xen_raw_console_write("about to get started...\n"); xen_setup_runstate_info(0); @@ -1364,7 +1329,7 @@ static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self, int cpu = (long)hcpu; switch (action) { case CPU_UP_PREPARE: - xen_vcpu_setup(cpu); + per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; if (xen_have_vector_callback) xen_init_lock_cpu(cpu); break; @@ -1394,6 +1359,7 @@ static void __init xen_hvm_guest_init(void) xen_hvm_smp_init(); register_cpu_notifier(&xen_hvm_cpu_notifier); xen_unplug_emulated_devices(); + have_vcpu_info_placement = 0; x86_init.irqs.intr_init = xen_init_IRQ; xen_hvm_init_time_ops(); xen_hvm_init_mmu_ops(); diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index d957dce61ede..0ccccb67a993 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -320,13 +320,8 @@ static pteval_t pte_mfn_to_pfn(pteval_t val) { if (val & _PAGE_PRESENT) { unsigned long mfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT; - unsigned long pfn = mfn_to_pfn(mfn); - pteval_t flags = val & PTE_FLAGS_MASK; - if (unlikely(pfn == ~0)) - val = flags & ~_PAGE_PRESENT; - else - val = ((pteval_t)pfn << PAGE_SHIFT) | flags; + val = ((pteval_t)mfn_to_pfn(mfn) << PAGE_SHIFT) | flags; } return val; @@ -1631,19 +1626,15 @@ static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn) void __init xen_setup_machphys_mapping(void) { struct xen_machphys_mapping mapping; + unsigned long machine_to_phys_nr_ents; if (HYPERVISOR_memory_op(XENMEM_machphys_mapping, &mapping) == 0) { machine_to_phys_mapping = (unsigned long *)mapping.v_start; - machine_to_phys_nr = mapping.max_mfn + 1; + machine_to_phys_nr_ents = mapping.max_mfn + 1; } else { - machine_to_phys_nr = MACH2PHYS_NR_ENTRIES; + machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES; } -#ifdef CONFIG_X86_32 - if ((machine_to_phys_mapping + machine_to_phys_nr) - < machine_to_phys_mapping) - machine_to_phys_nr = (unsigned long *)NULL - - machine_to_phys_mapping; -#endif + machine_to_phys_order = fls(machine_to_phys_nr_ents - 1); } #ifdef CONFIG_X86_64 diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index 2f7847d1055a..58efeb9d5440 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c @@ -683,7 +683,6 @@ int m2p_add_override(unsigned long mfn, struct page *page, bool clear_pte) unsigned long uninitialized_var(address); unsigned level; pte_t *ptep = NULL; - int ret = 0; pfn = page_to_pfn(page); if (!PageHighMem(page)) { @@ -707,24 +706,6 @@ int m2p_add_override(unsigned long mfn, struct page *page, bool clear_pte) list_add(&page->lru, &m2p_overrides[mfn_hash(mfn)]); spin_unlock_irqrestore(&m2p_override_lock, flags); - /* p2m(m2p(mfn)) == mfn: the mfn is already present somewhere in - * this domain. Set the FOREIGN_FRAME_BIT in the p2m for the other - * pfn so that the following mfn_to_pfn(mfn) calls will return the - * pfn from the m2p_override (the backend pfn) instead. - * We need to do this because the pages shared by the frontend - * (xen-blkfront) can be already locked (lock_page, called by - * do_read_cache_page); when the userspace backend tries to use them - * with direct_IO, mfn_to_pfn returns the pfn of the frontend, so - * do_blockdev_direct_IO is going to try to lock the same pages - * again resulting in a deadlock. - * As a side effect get_user_pages_fast might not be safe on the - * frontend pages while they are being shared with the backend, - * because mfn_to_pfn (that ends up being called by GUPF) will - * return the backend pfn rather than the frontend pfn. */ - ret = __get_user(pfn, &machine_to_phys_mapping[mfn]); - if (ret == 0 && get_phys_to_machine(pfn) == mfn) - set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)); - return 0; } EXPORT_SYMBOL_GPL(m2p_add_override); @@ -736,7 +717,6 @@ int m2p_remove_override(struct page *page, bool clear_pte) unsigned long uninitialized_var(address); unsigned level; pte_t *ptep = NULL; - int ret = 0; pfn = page_to_pfn(page); mfn = get_phys_to_machine(pfn); @@ -763,22 +743,6 @@ int m2p_remove_override(struct page *page, bool clear_pte) /* No tlb flush necessary because the caller already * left the pte unmapped. */ - /* p2m(m2p(mfn)) == FOREIGN_FRAME(mfn): the mfn is already present - * somewhere in this domain, even before being added to the - * m2p_override (see comment above in m2p_add_override). - * If there are no other entries in the m2p_override corresponding - * to this mfn, then remove the FOREIGN_FRAME_BIT from the p2m for - * the original pfn (the one shared by the frontend): the backend - * cannot do any IO on this page anymore because it has been - * unshared. Removing the FOREIGN_FRAME_BIT from the p2m entry of - * the original pfn causes mfn_to_pfn(mfn) to return the frontend - * pfn again. */ - mfn &= ~FOREIGN_FRAME_BIT; - ret = __get_user(pfn, &machine_to_phys_mapping[mfn]); - if (ret == 0 && get_phys_to_machine(pfn) == FOREIGN_FRAME(mfn) && - m2p_find_override(mfn) == NULL) - set_phys_to_machine(pfn, mfn); - return 0; } EXPORT_SYMBOL_GPL(m2p_remove_override); diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 5669564aadf1..60aeeb56948f 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -186,31 +185,6 @@ static unsigned long __init xen_set_identity(const struct e820entry *list, PFN_UP(start_pci), PFN_DOWN(last)); return identity; } - -static unsigned long __init xen_get_max_pages(void) -{ - unsigned long max_pages = MAX_DOMAIN_PAGES; - domid_t domid = DOMID_SELF; - int ret; - - /* - * For the initial domain we use the maximum reservation as - * the maximum page. - * - * For guest domains the current maximum reservation reflects - * the current maximum rather than the static maximum. In this - * case the e820 map provided to us will cover the static - * maximum region. - */ - if (xen_initial_domain()) { - ret = HYPERVISOR_memory_op(XENMEM_maximum_reservation, &domid); - if (ret > 0) - max_pages = ret; - } - - return min(max_pages, MAX_DOMAIN_PAGES); -} - /** * machine_specific_memory_setup - Hook for machine specific memory setup. **/ @@ -319,14 +293,6 @@ char * __init xen_memory_setup(void) sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); - extra_limit = xen_get_max_pages(); - if (max_pfn + extra_pages > extra_limit) { - if (extra_limit > max_pfn) - extra_pages = extra_limit - max_pfn; - else - extra_pages = 0; - } - extra_pages += xen_return_unused_memory(xen_start_info->nr_pages, &e820); /* @@ -464,7 +430,4 @@ void __init xen_arch_setup(void) boot_option_idle_override = IDLE_HALT; fiddle_vdso(); -#ifdef CONFIG_NUMA - numa_off = 1; -#endif } diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 2843b5e7cf07..b4533a86d7e4 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -32,7 +32,6 @@ #include #include -#include #include "xen-ops.h" #include "mmu.h" @@ -172,7 +171,6 @@ static void __init xen_fill_possible_map(void) static void __init xen_filter_cpu_maps(void) { int i, rc; - unsigned int subtract = 0; if (!xen_initial_domain()) return; @@ -187,22 +185,8 @@ static void __init xen_filter_cpu_maps(void) } else { set_cpu_possible(i, false); set_cpu_present(i, false); - subtract++; } } -#ifdef CONFIG_HOTPLUG_CPU - /* This is akin to using 'nr_cpus' on the Linux command line. - * Which is OK as when we use 'dom0_max_vcpus=X' we can only - * have up to X, while nr_cpu_ids is greater than X. This - * normally is not a problem, except when CPU hotplugging - * is involved and then there might be more than X CPUs - * in the guest - which will not work as there is no - * hypercall to expand the max number of VCPUs an already - * running guest has. So cap it up to X. */ - if (subtract) - nr_cpu_ids = nr_cpu_ids - subtract; -#endif - } static void __init xen_smp_prepare_boot_cpu(void) @@ -223,15 +207,6 @@ static void __init xen_smp_prepare_cpus(unsigned int max_cpus) unsigned cpu; unsigned int i; - if (skip_ioapic_setup) { - char *m = (max_cpus == 0) ? - "The nosmp parameter is incompatible with Xen; " \ - "use Xen dom0_max_vcpus=1 parameter" : - "The noapic parameter is incompatible with Xen"; - - xen_raw_printk(m); - panic(m); - } xen_init_lock_cpu(0); smp_store_cpu_info(0); @@ -546,6 +521,8 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus) native_smp_prepare_cpus(max_cpus); WARN_ON(xen_smp_intr_init(0)); + if (!xen_have_vector_callback) + return; xen_init_lock_cpu(0); xen_init_spinlocks(); } @@ -569,8 +546,6 @@ static void xen_hvm_cpu_die(unsigned int cpu) void __init xen_hvm_smp_init(void) { - if (!xen_have_vector_callback) - return; smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus; smp_ops.smp_send_reschedule = xen_smp_send_reschedule; smp_ops.cpu_up = xen_hvm_cpu_up; diff --git a/arch/x86/xen/vga.c b/arch/x86/xen/vga.c deleted file mode 100644 index 1cd7f4d11e29..000000000000 --- a/arch/x86/xen/vga.c +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include - -#include -#include - -#include - -#include "xen-ops.h" - -void __init xen_init_vga(const struct dom0_vga_console_info *info, size_t size) -{ - struct screen_info *screen_info = &boot_params.screen_info; - - /* This is drawn from a dump from vgacon:startup in - * standard Linux. */ - screen_info->orig_video_mode = 3; - screen_info->orig_video_isVGA = 1; - screen_info->orig_video_lines = 25; - screen_info->orig_video_cols = 80; - screen_info->orig_video_ega_bx = 3; - screen_info->orig_video_points = 16; - screen_info->orig_y = screen_info->orig_video_lines - 1; - - switch (info->video_type) { - case XEN_VGATYPE_TEXT_MODE_3: - if (size < offsetof(struct dom0_vga_console_info, u.text_mode_3) - + sizeof(info->u.text_mode_3)) - break; - screen_info->orig_video_lines = info->u.text_mode_3.rows; - screen_info->orig_video_cols = info->u.text_mode_3.columns; - screen_info->orig_x = info->u.text_mode_3.cursor_x; - screen_info->orig_y = info->u.text_mode_3.cursor_y; - screen_info->orig_video_points = - info->u.text_mode_3.font_height; - break; - - case XEN_VGATYPE_VESA_LFB: - if (size < offsetof(struct dom0_vga_console_info, - u.vesa_lfb.gbl_caps)) - break; - screen_info->orig_video_isVGA = VIDEO_TYPE_VLFB; - screen_info->lfb_width = info->u.vesa_lfb.width; - screen_info->lfb_height = info->u.vesa_lfb.height; - screen_info->lfb_depth = info->u.vesa_lfb.bits_per_pixel; - screen_info->lfb_base = info->u.vesa_lfb.lfb_base; - screen_info->lfb_size = info->u.vesa_lfb.lfb_size; - screen_info->lfb_linelength = info->u.vesa_lfb.bytes_per_line; - screen_info->red_size = info->u.vesa_lfb.red_size; - screen_info->red_pos = info->u.vesa_lfb.red_pos; - screen_info->green_size = info->u.vesa_lfb.green_size; - screen_info->green_pos = info->u.vesa_lfb.green_pos; - screen_info->blue_size = info->u.vesa_lfb.blue_size; - screen_info->blue_pos = info->u.vesa_lfb.blue_pos; - screen_info->rsvd_size = info->u.vesa_lfb.rsvd_size; - screen_info->rsvd_pos = info->u.vesa_lfb.rsvd_pos; - if (size >= offsetof(struct dom0_vga_console_info, - u.vesa_lfb.gbl_caps) - + sizeof(info->u.vesa_lfb.gbl_caps)) - screen_info->capabilities = info->u.vesa_lfb.gbl_caps; - if (size >= offsetof(struct dom0_vga_console_info, - u.vesa_lfb.mode_attrs) - + sizeof(info->u.vesa_lfb.mode_attrs)) - screen_info->vesa_attributes = info->u.vesa_lfb.mode_attrs; - break; - } -} diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S index 3e45aa000718..79d7362ad6d1 100644 --- a/arch/x86/xen/xen-asm.S +++ b/arch/x86/xen/xen-asm.S @@ -96,7 +96,7 @@ ENTRY(xen_restore_fl_direct) /* check for unmasked and pending */ cmpw $0x0001, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending - jnz 1f + jz 1f 2: call check_events 1: ENDPATCH(xen_restore_fl_direct) diff --git a/arch/x86/xen/xen-asm_32.S b/arch/x86/xen/xen-asm_32.S index 7328f71651e1..22a2093b5862 100644 --- a/arch/x86/xen/xen-asm_32.S +++ b/arch/x86/xen/xen-asm_32.S @@ -88,11 +88,11 @@ ENTRY(xen_iret) */ #ifdef CONFIG_SMP GET_THREAD_INFO(%eax) - movl %ss:TI_cpu(%eax), %eax - movl %ss:__per_cpu_offset(,%eax,4), %eax - mov %ss:xen_vcpu(%eax), %eax + movl TI_cpu(%eax), %eax + movl __per_cpu_offset(,%eax,4), %eax + mov xen_vcpu(%eax), %eax #else - movl %ss:xen_vcpu, %eax + movl xen_vcpu, %eax #endif /* check IF state we're restoring */ @@ -105,21 +105,19 @@ ENTRY(xen_iret) * resuming the code, so we don't have to be worried about * being preempted to another CPU. */ - setz %ss:XEN_vcpu_info_mask(%eax) + setz XEN_vcpu_info_mask(%eax) xen_iret_start_crit: /* check for unmasked and pending */ - cmpw $0x0001, %ss:XEN_vcpu_info_pending(%eax) + cmpw $0x0001, XEN_vcpu_info_pending(%eax) /* * If there's something pending, mask events again so we can - * jump back into xen_hypervisor_callback. Otherwise do not - * touch XEN_vcpu_info_mask. + * jump back into xen_hypervisor_callback */ - jne 1f - movb $1, %ss:XEN_vcpu_info_mask(%eax) + sete XEN_vcpu_info_mask(%eax) -1: popl %eax + popl %eax /* * From this point on the registers are restored and the stack diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index b095739ccd4c..97dfdc8757b3 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h @@ -88,17 +88,6 @@ static inline void xen_uninit_lock_cpu(int cpu) } #endif -struct dom0_vga_console_info; - -#ifdef CONFIG_XEN_DOM0 -void __init xen_init_vga(const struct dom0_vga_console_info *, size_t size); -#else -static inline void __init xen_init_vga(const struct dom0_vga_console_info *info, - size_t size) -{ -} -#endif - /* Declare an asm function, along with symbols needed to make it inlineable */ #define DECL_ASM(ret, name, ...) \ diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index a0d042aa2967..c72c9473ef99 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -147,9 +147,6 @@ int ptrace_setxregs(struct task_struct *child, void __user *uregs) elf_xtregs_t *xtregs = uregs; int ret = 0; - if (!access_ok(VERIFY_READ, uregs, sizeof(elf_xtregs_t))) - return -EFAULT; - #if XTENSA_HAVE_COPROCESSORS /* Flush all coprocessors before we overwrite them. */ coprocessor_flush_all(ti); diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index b596e54ddd71..bcaf16ee6ad1 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -785,10 +785,10 @@ static int blkio_policy_parse_and_set(char *buf, { char *s[4], *p, *major_s = NULL, *minor_s = NULL; int ret; - unsigned long major, minor; + unsigned long major, minor, temp; int i = 0; dev_t dev; - u64 temp; + u64 bps, iops; memset(s, 0, sizeof(s)); @@ -826,23 +826,20 @@ static int blkio_policy_parse_and_set(char *buf, dev = MKDEV(major, minor); - ret = strict_strtoull(s[1], 10, &temp); + ret = blkio_check_dev_num(dev); if (ret) - return -EINVAL; - - /* For rule removal, do not check for device presence. */ - if (temp) { - ret = blkio_check_dev_num(dev); - if (ret) - return ret; - } + return ret; newpn->dev = dev; + if (s[1] == NULL) + return -EINVAL; + switch (plid) { case BLKIO_POLICY_PROP: - if ((temp < BLKIO_WEIGHT_MIN && temp > 0) || - temp > BLKIO_WEIGHT_MAX) + ret = strict_strtoul(s[1], 10, &temp); + if (ret || (temp < BLKIO_WEIGHT_MIN && temp > 0) || + temp > BLKIO_WEIGHT_MAX) return -EINVAL; newpn->plid = plid; @@ -853,18 +850,26 @@ static int blkio_policy_parse_and_set(char *buf, switch(fileid) { case BLKIO_THROTL_read_bps_device: case BLKIO_THROTL_write_bps_device: + ret = strict_strtoull(s[1], 10, &bps); + if (ret) + return -EINVAL; + newpn->plid = plid; newpn->fileid = fileid; - newpn->val.bps = temp; + newpn->val.bps = bps; break; case BLKIO_THROTL_read_iops_device: case BLKIO_THROTL_write_iops_device: - if (temp > THROTL_IOPS_MAX) + ret = strict_strtoull(s[1], 10, &iops); + if (ret) + return -EINVAL; + + if (iops > THROTL_IOPS_MAX) return -EINVAL; newpn->plid = plid; newpn->fileid = fileid; - newpn->val.iops = (unsigned int)temp; + newpn->val.iops = (unsigned int)iops; break; } break; diff --git a/block/blk-core.c b/block/blk-core.c index 35ae52df6b6d..d2f8f4049abd 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -348,10 +348,9 @@ void blk_put_queue(struct request_queue *q) EXPORT_SYMBOL(blk_put_queue); /* - * Note: If a driver supplied the queue lock, it is disconnected - * by this function. The actual state of the lock doesn't matter - * here as the request_queue isn't accessible after this point - * (QUEUE_FLAG_DEAD is set) and no other requests will be queued. + * Note: If a driver supplied the queue lock, it should not zap that lock + * unexpectedly as some queue cleanup components like elevator_exit() and + * blk_throtl_exit() need queue lock. */ void blk_cleanup_queue(struct request_queue *q) { @@ -368,8 +367,10 @@ void blk_cleanup_queue(struct request_queue *q) queue_flag_set_unlocked(QUEUE_FLAG_DEAD, q); mutex_unlock(&q->sysfs_lock); - if (q->queue_lock != &q->__queue_lock) - q->queue_lock = &q->__queue_lock; + if (q->elevator) + elevator_exit(q->elevator); + + blk_throtl_exit(q); blk_put_queue(q); } @@ -418,7 +419,6 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) q->backing_dev_info.state = 0; q->backing_dev_info.capabilities = BDI_CAP_MAP_COPY; q->backing_dev_info.name = "block"; - q->node = node_id; err = bdi_init(&q->backing_dev_info); if (err) { @@ -503,7 +503,7 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id) if (!uninit_q) return NULL; - q = blk_init_allocated_queue(uninit_q, rfn, lock); + q = blk_init_allocated_queue_node(uninit_q, rfn, lock, node_id); if (!q) blk_cleanup_queue(uninit_q); @@ -514,10 +514,19 @@ EXPORT_SYMBOL(blk_init_queue_node); struct request_queue * blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn, spinlock_t *lock) +{ + return blk_init_allocated_queue_node(q, rfn, lock, -1); +} +EXPORT_SYMBOL(blk_init_allocated_queue); + +struct request_queue * +blk_init_allocated_queue_node(struct request_queue *q, request_fn_proc *rfn, + spinlock_t *lock, int node_id) { if (!q) return NULL; + q->node = node_id; if (blk_init_free_list(q)) return NULL; @@ -547,7 +556,7 @@ blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn, return NULL; } -EXPORT_SYMBOL(blk_init_allocated_queue); +EXPORT_SYMBOL(blk_init_allocated_queue_node); int blk_get_queue(struct request_queue *q) { @@ -830,9 +839,6 @@ struct request *blk_get_request(struct request_queue *q, int rw, gfp_t gfp_mask) { struct request *rq; - if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) - return NULL; - BUG_ON(rw != READ && rw != WRITE); spin_lock_irq(q->queue_lock); diff --git a/block/blk-exec.c b/block/blk-exec.c index a1ebceb332f9..8a0e7ec056e7 100644 --- a/block/blk-exec.c +++ b/block/blk-exec.c @@ -50,13 +50,6 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, { int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK; - if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) { - rq->errors = -ENXIO; - if (rq->end_io) - rq->end_io(rq, rq->errors); - return; - } - rq->rq_disk = bd_disk; rq->end_io = done; WARN_ON(irqs_disabled()); diff --git a/block/blk-map.c b/block/blk-map.c index 164cd0059706..e663ac2d8e68 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -204,11 +204,10 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, if (!iov[i].iov_len) return -EINVAL; - /* - * Keep going so we check length of all segments - */ - if (uaddr & queue_dma_alignment(q)) + if (uaddr & queue_dma_alignment(q)) { unaligned = 1; + break; + } } if (unaligned || (q->dma_pad_mask & len) || map_data) diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 45c56d86b826..d935bd859c87 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -472,11 +472,6 @@ static void blk_release_queue(struct kobject *kobj) blk_sync_queue(q); - if (q->elevator) - elevator_exit(q->elevator); - - blk_throtl_exit(q); - if (rl->rq_pool) mempool_destroy(rl->rq_pool); diff --git a/block/bsg.c b/block/bsg.c index 792ead666757..0c8b64a16484 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -985,8 +985,7 @@ void bsg_unregister_queue(struct request_queue *q) mutex_lock(&bsg_mutex); idr_remove(&bsg_minor_idr, bcd->minor); - if (q->kobj.sd) - sysfs_remove_link(&q->kobj, "bsg"); + sysfs_remove_link(&q->kobj, "bsg"); device_unregister(bcd->class_dev); bcd->class_dev = NULL; kref_put(&bcd->ref, bsg_kref_release_function); diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 23500ac7f0f3..ae21919f15e1 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -3169,7 +3169,7 @@ static int cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc, } } - if (ret && ret != -EEXIST) + if (ret) printk(KERN_ERR "cfq: cic link failed!\n"); return ret; @@ -3185,7 +3185,6 @@ cfq_get_io_context(struct cfq_data *cfqd, gfp_t gfp_mask) { struct io_context *ioc = NULL; struct cfq_io_context *cic; - int ret; might_sleep_if(gfp_mask & __GFP_WAIT); @@ -3193,7 +3192,6 @@ cfq_get_io_context(struct cfq_data *cfqd, gfp_t gfp_mask) if (!ioc) return NULL; -retry: cic = cfq_cic_lookup(cfqd, ioc); if (cic) goto out; @@ -3202,12 +3200,7 @@ retry: if (cic == NULL) goto err; - ret = cfq_cic_link(cfqd, ioc, cic, gfp_mask); - if (ret == -EEXIST) { - /* someone has linked cic to ioc already */ - cfq_cic_free(cic); - goto retry; - } else if (ret) + if (cfq_cic_link(cfqd, ioc, cic, gfp_mask)) goto err_free; out: @@ -4022,11 +4015,6 @@ static void *cfq_init_queue(struct request_queue *q) if (blkio_alloc_blkg_stats(&cfqg->blkg)) { kfree(cfqg); - - spin_lock(&cic_index_lock); - ida_remove(&cic_index_ida, cfqd->cic_index); - spin_unlock(&cic_index_lock); - kfree(cfqd); return NULL; } diff --git a/block/genhd.c b/block/genhd.c index a1b0b9012cd4..3608289c8ecd 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -36,7 +36,6 @@ static DEFINE_IDR(ext_devt_idr); static struct device_type disk_type; -static void disk_alloc_events(struct gendisk *disk); static void disk_add_events(struct gendisk *disk); static void disk_del_events(struct gendisk *disk); static void disk_release_events(struct gendisk *disk); @@ -603,8 +602,6 @@ void add_disk(struct gendisk *disk) disk->major = MAJOR(devt); disk->first_minor = MINOR(devt); - disk_alloc_events(disk); - /* Register BDI before referencing it from bdev */ bdi = &disk->queue->backing_dev_info; bdi_register_dev(bdi, disk_devt(disk)); @@ -614,12 +611,6 @@ void add_disk(struct gendisk *disk) register_disk(disk); blk_register_queue(disk); - /* - * Take an extra ref on queue which will be put on disk_release() - * so that it sticks around as long as @disk is there. - */ - WARN_ON_ONCE(blk_get_queue(disk->queue)); - retval = sysfs_create_link(&disk_to_dev(disk)->kobj, &bdi->dev->kobj, "bdi"); WARN_ON(retval); @@ -744,7 +735,7 @@ void __init printk_all_partitions(void) struct hd_struct *part; char name_buf[BDEVNAME_SIZE]; char devt_buf[BDEVT_SIZE]; - char uuid_buf[PARTITION_META_INFO_UUIDLTH * 2 + 5]; + u8 uuid[PARTITION_META_INFO_UUIDLTH * 2 + 1]; /* * Don't show empty devices or things that have been @@ -763,16 +754,14 @@ void __init printk_all_partitions(void) while ((part = disk_part_iter_next(&piter))) { bool is_part0 = part == &disk->part0; - uuid_buf[0] = '\0'; + uuid[0] = 0; if (part->info) - snprintf(uuid_buf, sizeof(uuid_buf), "%pU", - part->info->uuid); + part_unpack_uuid(part->info->uuid, uuid); printk("%s%s %10llu %s %s", is_part0 ? "" : " ", bdevt_str(part_devt(part), devt_buf), (unsigned long long)part->nr_sects >> 1, - disk_name(disk, part->partno, name_buf), - uuid_buf); + disk_name(disk, part->partno, name_buf), uuid); if (is_part0) { if (disk->driverfs_dev != NULL && disk->driverfs_dev->driver != NULL) @@ -1114,26 +1103,8 @@ static void disk_release(struct device *dev) disk_replace_part_tbl(disk, NULL); free_part_stats(&disk->part0); free_part_info(&disk->part0); - if (disk->queue) - blk_put_queue(disk->queue); kfree(disk); } - -static int disk_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - struct gendisk *disk = dev_to_disk(dev); - struct disk_part_iter piter; - struct hd_struct *part; - int cnt = 0; - - disk_part_iter_init(&piter, disk, 0); - while((part = disk_part_iter_next(&piter))) - cnt++; - disk_part_iter_exit(&piter); - add_uevent_var(env, "NPARTS=%u", cnt); - return 0; -} - struct class block_class = { .name = "block", }; @@ -1152,7 +1123,6 @@ static struct device_type disk_type = { .groups = disk_attr_groups, .release = disk_release, .devnode = block_devnode, - .uevent = disk_uevent, }; #ifdef CONFIG_PROC_FS @@ -1506,9 +1476,9 @@ static void __disk_unblock_events(struct gendisk *disk, bool check_now) intv = disk_events_poll_jiffies(disk); set_timer_slack(&ev->dwork.timer, intv / 4); if (check_now) - queue_delayed_work(system_nrt_freezable_wq, &ev->dwork, 0); + queue_delayed_work(system_nrt_wq, &ev->dwork, 0); else if (intv) - queue_delayed_work(system_nrt_freezable_wq, &ev->dwork, intv); + queue_delayed_work(system_nrt_wq, &ev->dwork, intv); out_unlock: spin_unlock_irqrestore(&ev->lock, flags); } @@ -1549,7 +1519,7 @@ void disk_check_events(struct gendisk *disk) spin_lock_irqsave(&ev->lock, flags); if (!ev->block) { cancel_delayed_work(&ev->dwork); - queue_delayed_work(system_nrt_freezable_wq, &ev->dwork, 0); + queue_delayed_work(system_nrt_wq, &ev->dwork, 0); } spin_unlock_irqrestore(&ev->lock, flags); } @@ -1587,7 +1557,7 @@ unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask) /* uncondtionally schedule event check and wait for it to finish */ disk_block_events(disk); - queue_delayed_work(system_nrt_freezable_wq, &ev->dwork, 0); + queue_delayed_work(system_nrt_wq, &ev->dwork, 0); flush_delayed_work(&ev->dwork); __disk_unblock_events(disk, false); @@ -1624,7 +1594,7 @@ static void disk_events_workfn(struct work_struct *work) intv = disk_events_poll_jiffies(disk); if (!ev->block && intv) - queue_delayed_work(system_nrt_freezable_wq, &ev->dwork, intv); + queue_delayed_work(system_nrt_wq, &ev->dwork, intv); spin_unlock_irq(&ev->lock); @@ -1762,9 +1732,9 @@ module_param_cb(events_dfl_poll_msecs, &disk_events_dfl_poll_msecs_param_ops, &disk_events_dfl_poll_msecs, 0644); /* - * disk_{alloc|add|del|release}_events - initialize and destroy disk_events. + * disk_{add|del|release}_events - initialize and destroy disk_events. */ -static void disk_alloc_events(struct gendisk *disk) +static void disk_add_events(struct gendisk *disk) { struct disk_events *ev; @@ -1777,6 +1747,16 @@ static void disk_alloc_events(struct gendisk *disk) return; } + if (sysfs_create_files(&disk_to_dev(disk)->kobj, + disk_events_attrs) < 0) { + pr_warn("%s: failed to create sysfs files for events\n", + disk->disk_name); + kfree(ev); + return; + } + + disk->ev = ev; + INIT_LIST_HEAD(&ev->node); ev->disk = disk; spin_lock_init(&ev->lock); @@ -1785,21 +1765,8 @@ static void disk_alloc_events(struct gendisk *disk) ev->poll_msecs = -1; INIT_DELAYED_WORK(&ev->dwork, disk_events_workfn); - disk->ev = ev; -} - -static void disk_add_events(struct gendisk *disk) -{ - if (!disk->ev) - return; - - /* FIXME: error handling */ - if (sysfs_create_files(&disk_to_dev(disk)->kobj, disk_events_attrs) < 0) - pr_warn("%s: failed to create sysfs files for events\n", - disk->disk_name); - mutex_lock(&disk_events_mutex); - list_add_tail(&disk->ev->node, &disk_events); + list_add_tail(&ev->node, &disk_events); mutex_unlock(&disk_events_mutex); /* diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index 055952e92fbd..4f4230b79bb6 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -692,60 +691,6 @@ int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mod } EXPORT_SYMBOL(scsi_cmd_ioctl); -int scsi_verify_blk_ioctl(struct block_device *bd, unsigned int cmd) -{ - if (bd && bd == bd->bd_contains) - return 0; - - /* Actually none of these is particularly useful on a partition, - * but they are safe. - */ - switch (cmd) { - case SCSI_IOCTL_GET_IDLUN: - case SCSI_IOCTL_GET_BUS_NUMBER: - case SCSI_IOCTL_GET_PCI: - case SCSI_IOCTL_PROBE_HOST: - case SG_GET_VERSION_NUM: - case SG_SET_TIMEOUT: - case SG_GET_TIMEOUT: - case SG_GET_RESERVED_SIZE: - case SG_SET_RESERVED_SIZE: - case SG_EMULATED_HOST: - return 0; - case CDROM_GET_CAPABILITY: - /* Keep this until we remove the printk below. udev sends it - * and we do not want to spam dmesg about it. CD-ROMs do - * not have partitions, so we get here only for disks. - */ - return -ENOTTY; - default: - break; - } - - if (capable(CAP_SYS_RAWIO)) - return 0; - - /* In particular, rule out all resets and host-specific ioctls. */ - printk_ratelimited(KERN_WARNING - "%s: sending ioctl %x to a partition!\n", current->comm, cmd); - - return -ENOTTY; -} -EXPORT_SYMBOL(scsi_verify_blk_ioctl); - -int scsi_cmd_blk_ioctl(struct block_device *bd, fmode_t mode, - unsigned int cmd, void __user *arg) -{ - int ret; - - ret = scsi_verify_blk_ioctl(bd, cmd); - if (ret < 0) - return ret; - - return scsi_cmd_ioctl(bd->bd_disk->queue, bd->bd_disk, mode, cmd, arg); -} -EXPORT_SYMBOL(scsi_cmd_blk_ioctl); - static int __init blk_scsi_ioctl_init(void) { blk_set_cmd_filter_defaults(&blk_default_cmd_filter); diff --git a/crypto/cryptd.c b/crypto/cryptd.c index 7bdd61b867c8..e46d21ae26bc 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c @@ -137,18 +137,13 @@ static void cryptd_queue_worker(struct work_struct *work) struct crypto_async_request *req, *backlog; cpu_queue = container_of(work, struct cryptd_cpu_queue, work); - /* - * Only handle one request at a time to avoid hogging crypto workqueue. - * preempt_disable/enable is used to prevent being preempted by - * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent - * cryptd_enqueue_request() being accessed from software interrupts. - */ - local_bh_disable(); + /* Only handle one request at a time to avoid hogging crypto + * workqueue. preempt_disable/enable is used to prevent + * being preempted by cryptd_enqueue_request() */ preempt_disable(); backlog = crypto_get_backlog(&cpu_queue->queue); req = crypto_dequeue_request(&cpu_queue->queue); preempt_enable(); - local_bh_enable(); if (!req) return; @@ -950,7 +945,7 @@ static void __exit cryptd_exit(void) crypto_unregister_template(&cryptd_tmpl); } -subsys_initcall(cryptd_init); +module_init(cryptd_init); module_exit(cryptd_exit); MODULE_LICENSE("GPL"); diff --git a/crypto/ghash-generic.c b/crypto/ghash-generic.c index 7835b8fc94db..be4425616931 100644 --- a/crypto/ghash-generic.c +++ b/crypto/ghash-generic.c @@ -67,9 +67,6 @@ static int ghash_update(struct shash_desc *desc, struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); u8 *dst = dctx->buffer; - if (!ctx->gf128) - return -ENOKEY; - if (dctx->bytes) { int n = min(srclen, dctx->bytes); u8 *pos = dst + (GHASH_BLOCK_SIZE - dctx->bytes); @@ -122,9 +119,6 @@ static int ghash_final(struct shash_desc *desc, u8 *dst) struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); u8 *buf = dctx->buffer; - if (!ctx->gf128) - return -ENOKEY; - ghash_flush(ctx, dctx); memcpy(dst, buf, GHASH_BLOCK_SIZE); diff --git a/crypto/md5.c b/crypto/md5.c index 7febeaab923b..30efc7dad891 100644 --- a/crypto/md5.c +++ b/crypto/md5.c @@ -21,9 +21,99 @@ #include #include #include -#include #include +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +#define MD5STEP(f, w, x, y, z, in, s) \ + (w += f(x, y, z) + in, w = (w<>(32-s)) + x) + +static void md5_transform(u32 *hash, u32 const *in) +{ + u32 a, b, c, d; + + a = hash[0]; + b = hash[1]; + c = hash[2]; + d = hash[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + hash[0] += a; + hash[1] += b; + hash[2] += c; + hash[3] += d; +} + /* XXX: this stuff can be optimized */ static inline void le32_to_cpu_array(u32 *buf, unsigned int words) { diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c index dd30f40af9f5..9ed9f60316e5 100644 --- a/crypto/sha512_generic.c +++ b/crypto/sha512_generic.c @@ -21,6 +21,8 @@ #include #include +static DEFINE_PER_CPU(u64[80], msg_schedule); + static inline u64 Ch(u64 x, u64 y, u64 z) { return z ^ (x & (y ^ z)); @@ -31,6 +33,11 @@ static inline u64 Maj(u64 x, u64 y, u64 z) return (x & y) | (z & (x | y)); } +static inline u64 RORu64(u64 x, u64 y) +{ + return (x >> y) | (x << (64 - y)); +} + static const u64 sha512_K[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, @@ -61,10 +68,10 @@ static const u64 sha512_K[80] = { 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL, }; -#define e0(x) (ror64(x,28) ^ ror64(x,34) ^ ror64(x,39)) -#define e1(x) (ror64(x,14) ^ ror64(x,18) ^ ror64(x,41)) -#define s0(x) (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7)) -#define s1(x) (ror64(x,19) ^ ror64(x,61) ^ (x >> 6)) +#define e0(x) (RORu64(x,28) ^ RORu64(x,34) ^ RORu64(x,39)) +#define e1(x) (RORu64(x,14) ^ RORu64(x,18) ^ RORu64(x,41)) +#define s0(x) (RORu64(x, 1) ^ RORu64(x, 8) ^ (x >> 7)) +#define s1(x) (RORu64(x,19) ^ RORu64(x,61) ^ (x >> 6)) static inline void LOAD_OP(int I, u64 *W, const u8 *input) { @@ -73,7 +80,7 @@ static inline void LOAD_OP(int I, u64 *W, const u8 *input) static inline void BLEND_OP(int I, u64 *W) { - W[I & 15] += s1(W[(I-2) & 15]) + W[(I-7) & 15] + s0(W[(I-15) & 15]); + W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16]; } static void @@ -82,7 +89,15 @@ sha512_transform(u64 *state, const u8 *input) u64 a, b, c, d, e, f, g, h, t1, t2; int i; - u64 W[16]; + u64 *W = get_cpu_var(msg_schedule); + + /* load the input */ + for (i = 0; i < 16; i++) + LOAD_OP(i, W, input); + + for (i = 16; i < 80; i++) { + BLEND_OP(i, W); + } /* load the state into our registers */ a=state[0]; b=state[1]; c=state[2]; d=state[3]; @@ -90,35 +105,21 @@ sha512_transform(u64 *state, const u8 *input) /* now iterate */ for (i=0; i<80; i+=8) { - if (!(i & 8)) { - int j; - - if (i < 16) { - /* load the input */ - for (j = 0; j < 16; j++) - LOAD_OP(i + j, W, input); - } else { - for (j = 0; j < 16; j++) { - BLEND_OP(i + j, W); - } - } - } - - t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i ] + W[(i & 15)]; + t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i ] + W[i ]; t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; - t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[(i & 15) + 1]; + t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[i+1]; t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; - t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[(i & 15) + 2]; + t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[i+2]; t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; - t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[(i & 15) + 3]; + t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[i+3]; t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; - t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[(i & 15) + 4]; + t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[i+4]; t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; - t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[(i & 15) + 5]; + t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[i+5]; t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; - t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[(i & 15) + 6]; + t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[i+6]; t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; - t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[(i & 15) + 7]; + t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[i+7]; t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; } @@ -127,6 +128,8 @@ sha512_transform(u64 *state, const u8 *input) /* erase our data */ a = b = c = d = e = f = g = h = t1 = t2 = 0; + memset(W, 0, sizeof(__get_cpu_var(msg_schedule))); + put_cpu_var(msg_schedule); } static int @@ -174,7 +177,7 @@ sha512_update(struct shash_desc *desc, const u8 *data, unsigned int len) index = sctx->count[0] & 0x7f; /* Update number of bytes */ - if ((sctx->count[0] += len) < len) + if (!(sctx->count[0] += len)) sctx->count[1]++; part_len = 128 - index; diff --git a/drivers/Kconfig b/drivers/Kconfig index d0258eb26d8b..3bb154d8c8cc 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -96,8 +96,6 @@ source "drivers/leds/Kconfig" source "drivers/nfc/Kconfig" -source "drivers/switch/Kconfig" - source "drivers/accessibility/Kconfig" source "drivers/infiniband/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 4ea4ac9e57af..09f3232bcdcd 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -98,7 +98,6 @@ obj-$(CONFIG_CPU_IDLE) += cpuidle/ obj-$(CONFIG_MMC) += mmc/ obj-$(CONFIG_MEMSTICK) += memstick/ obj-y += leds/ -obj-$(CONFIG_SWITCH) += switch/ obj-$(CONFIG_INFINIBAND) += infiniband/ obj-$(CONFIG_SGI_SN) += sn/ obj-y += firmware/ diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 958205046e06..58c3f74bd84c 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -292,9 +292,7 @@ static int acpi_ac_add(struct acpi_device *device) ac->charger.properties = ac_props; ac->charger.num_properties = ARRAY_SIZE(ac_props); ac->charger.get_property = get_ac_property; - result = power_supply_register(&ac->device->dev, &ac->charger); - if (result) - goto end; + power_supply_register(&ac->device->dev, &ac->charger); printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), acpi_device_bid(device), diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 1502c50273b5..a43fa1a57d57 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -36,7 +36,6 @@ #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" #define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80 static DEFINE_MUTEX(isolated_cpus_lock); -static DEFINE_MUTEX(round_robin_lock); static unsigned long power_saving_mwait_eax; @@ -108,7 +107,7 @@ static void round_robin_cpu(unsigned int tsk_index) if (!alloc_cpumask_var(&tmp, GFP_KERNEL)) return; - mutex_lock(&round_robin_lock); + mutex_lock(&isolated_cpus_lock); cpumask_clear(tmp); for_each_cpu(cpu, pad_busy_cpus) cpumask_or(tmp, tmp, topology_thread_cpumask(cpu)); @@ -117,7 +116,7 @@ static void round_robin_cpu(unsigned int tsk_index) if (cpumask_empty(tmp)) cpumask_andnot(tmp, cpu_online_mask, pad_busy_cpus); if (cpumask_empty(tmp)) { - mutex_unlock(&round_robin_lock); + mutex_unlock(&isolated_cpus_lock); return; } for_each_cpu(cpu, tmp) { @@ -132,7 +131,7 @@ static void round_robin_cpu(unsigned int tsk_index) tsk_in_cpu[tsk_index] = preferred_cpu; cpumask_set_cpu(preferred_cpu, pad_busy_cpus); cpu_weight[preferred_cpu]++; - mutex_unlock(&round_robin_lock); + mutex_unlock(&isolated_cpus_lock); set_cpus_allowed_ptr(current, cpumask_of(preferred_cpu)); } diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h index f895a244ca7e..bc533dde16c4 100644 --- a/drivers/acpi/acpica/acconfig.h +++ b/drivers/acpi/acpica/acconfig.h @@ -121,7 +121,7 @@ /* Maximum sleep allowed via Sleep() operator */ -#define ACPI_MAX_SLEEP 2000 /* Two seconds */ +#define ACPI_MAX_SLEEP 20000 /* Two seconds */ /****************************************************************************** * diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 5552125d8340..c7f743ca395b 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -357,7 +357,6 @@ struct acpi_predefined_data { char *pathname; const union acpi_predefined_info *predefined; union acpi_operand_object *parent_package; - struct acpi_namespace_node *node; u32 flags; u8 node_flags; }; diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index 6d276c20b57b..1055769f2f01 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h @@ -358,7 +358,6 @@ typedef enum { */ struct acpi_object_extra { ACPI_OBJECT_COMMON_HEADER struct acpi_namespace_node *method_REG; /* _REG method for this region (if any) */ - struct acpi_namespace_node *scope_node; void *region_context; /* Region-specific data */ u8 *aml_start; u32 aml_length; diff --git a/drivers/acpi/acpica/dsargs.c b/drivers/acpi/acpica/dsargs.c index d69e4a53175b..8c7b99728aa2 100644 --- a/drivers/acpi/acpica/dsargs.c +++ b/drivers/acpi/acpica/dsargs.c @@ -384,32 +384,8 @@ acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc) /* Execute the argument AML */ - status = acpi_ds_execute_arguments(node, extra_desc->extra.scope_node, + status = acpi_ds_execute_arguments(node, node->parent, extra_desc->extra.aml_length, extra_desc->extra.aml_start); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Validate the region address/length via the host OS */ - - status = acpi_os_validate_address(obj_desc->region.space_id, - obj_desc->region.address, - (acpi_size) obj_desc->region.length, - acpi_ut_get_node_name(node)); - - if (ACPI_FAILURE(status)) { - /* - * Invalid address/length. We will emit an error message and mark - * the region as invalid, so that it will cause an additional error if - * it is ever used. Then return AE_OK. - */ - ACPI_EXCEPTION((AE_INFO, status, - "During address validation of OpRegion [%4.4s]", - node->name.ascii)); - obj_desc->common.flags |= AOPOBJ_INVALID; - status = AE_OK; - } - return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index 8a06dc523af7..110711afada8 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c @@ -330,12 +330,6 @@ acpi_ex_create_region(u8 * aml_start, region_obj2 = obj_desc->common.next_object; region_obj2->extra.aml_start = aml_start; region_obj2->extra.aml_length = aml_length; - if (walk_state->scope_info) { - region_obj2->extra.scope_node = - walk_state->scope_info->scope.node; - } else { - region_obj2->extra.scope_node = node; - } /* Init the region from the operands */ diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index dc005827b9da..9fb03fa8ffde 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -212,7 +212,6 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, goto cleanup; } data->predefined = predefined; - data->node = node; data->node_flags = node->flags; data->pathname = pathname; diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index 024c4f263f87..973883babee1 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c @@ -503,21 +503,6 @@ acpi_ns_repair_TSS(struct acpi_predefined_data *data, { union acpi_operand_object *return_object = *return_object_ptr; acpi_status status; - struct acpi_namespace_node *node; - - /* - * We can only sort the _TSS return package if there is no _PSS in the - * same scope. This is because if _PSS is present, the ACPI specification - * dictates that the _TSS Power Dissipation field is to be ignored, and - * therefore some BIOSs leave garbage values in the _TSS Power field(s). - * In this case, it is best to just return the _TSS package as-is. - * (May, 2011) - */ - status = - acpi_ns_get_node(data->node, "^_PSS", ACPI_NS_NO_UPSEARCH, &node); - if (ACPI_SUCCESS(status)) { - return (AE_OK); - } status = acpi_ns_check_sorted_list(data, return_object, 5, 1, ACPI_SORT_DESCENDING, diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 4c531b4a9625..6f5588e62c0a 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -350,6 +350,10 @@ static void acpi_tb_convert_fadt(void) u32 address32; u32 i; + /* Update the local FADT table header length */ + + acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt); + /* * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary. * Later code will always use the X 64-bit field. Also, check for an @@ -391,10 +395,6 @@ static void acpi_tb_convert_fadt(void) acpi_gbl_FADT.boot_flags = 0; } - /* Update the local FADT table header length */ - - acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt); - /* * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" * generic address structures as necessary. Later code will always use diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index 55edd4ae0a01..4b7085dfc683 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c @@ -435,7 +435,6 @@ acpi_get_table_with_size(char *signature, return (AE_NOT_FOUND); } -ACPI_EXPORT_SYMBOL(acpi_get_table_with_size) acpi_status acpi_get_table(char *signature, diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c index f151afe61aab..7489b89c300f 100644 --- a/drivers/acpi/atomicio.c +++ b/drivers/acpi/atomicio.c @@ -76,7 +76,7 @@ static void __iomem *__acpi_ioremap_fast(phys_addr_t paddr, { struct acpi_iomap *map; - map = __acpi_find_iomap(paddr, size/8); + map = __acpi_find_iomap(paddr, size); if (map) return map->vaddr + (paddr - map->paddr); else diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 4a15d57b7bc2..fcc13ac0aa18 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -34,7 +34,6 @@ #include #include #include -#include #ifdef CONFIG_ACPI_PROCFS_POWER #include @@ -98,18 +97,6 @@ enum { */ ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, - /* On Lenovo Thinkpad models from 2010 and 2011, the power unit - switches between mWh and mAh depending on whether the system - is running on battery or not. When mAh is the unit, most - reported values are incorrect and need to be adjusted by - 10000/design_voltage. Verified on x201, t410, t410s, and x220. - Pre-2010 and 2012 models appear to always report in mWh and - are thus unaffected (tested with t42, t61, t500, x200, x300, - and x230). Also, in mid-2012 Lenovo issued a BIOS update for - the 2011 models that fixes the issue (tested on x220 with a - post-1.29 BIOS), but as of Nov. 2012, no such update is - available for the 2010 models. */ - ACPI_BATTERY_QUIRK_THINKPAD_MAH, }; struct acpi_battery { @@ -442,21 +429,6 @@ static int acpi_battery_get_info(struct acpi_battery *battery) kfree(buffer.pointer); if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) battery->full_charge_capacity = battery->design_capacity; - if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) && - battery->power_unit && battery->design_voltage) { - battery->design_capacity = battery->design_capacity * - 10000 / battery->design_voltage; - battery->full_charge_capacity = battery->full_charge_capacity * - 10000 / battery->design_voltage; - battery->design_capacity_warning = - battery->design_capacity_warning * - 10000 / battery->design_voltage; - /* Curiously, design_capacity_low, unlike the rest of them, - is correct. */ - /* capacity_granularity_* equal 1 on the systems tested, so - it's impossible to tell if they would need an adjustment - or not if their values were higher. */ - } return result; } @@ -497,11 +469,6 @@ static int acpi_battery_get_state(struct acpi_battery *battery) && battery->capacity_now >= 0 && battery->capacity_now <= 100) battery->capacity_now = (battery->capacity_now * battery->full_charge_capacity) / 100; - if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) && - battery->power_unit && battery->design_voltage) { - battery->capacity_now = battery->capacity_now * - 10000 / battery->design_voltage; - } return result; } @@ -613,24 +580,6 @@ static void acpi_battery_quirks(struct acpi_battery *battery) } } -static void find_battery(const struct dmi_header *dm, void *private) -{ - struct acpi_battery *battery = (struct acpi_battery *)private; - /* Note: the hardcoded offsets below have been extracted from - the source code of dmidecode. */ - if (dm->type == DMI_ENTRY_PORTABLE_BATTERY && dm->length >= 8) { - const u8 *dmi_data = (const u8 *)(dm + 1); - int dmi_capacity = get_unaligned((const u16 *)(dmi_data + 6)); - if (dm->length >= 18) - dmi_capacity *= dmi_data[17]; - if (battery->design_capacity * battery->design_voltage / 1000 - != dmi_capacity && - battery->design_capacity * 10 == dmi_capacity) - set_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, - &battery->flags); - } -} - /* * According to the ACPI spec, some kinds of primary batteries can * report percentage battery remaining capacity directly to OS. @@ -656,32 +605,6 @@ static void acpi_battery_quirks2(struct acpi_battery *battery) battery->capacity_now = (battery->capacity_now * battery->full_charge_capacity) / 100; } - - if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags)) - return ; - - if (battery->power_unit && dmi_name_in_vendors("LENOVO")) { - const char *s; - s = dmi_get_system_info(DMI_PRODUCT_VERSION); - if (s && !strnicmp(s, "ThinkPad", 8)) { - dmi_walk(find_battery, battery); - if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, - &battery->flags) && - battery->design_voltage) { - battery->design_capacity = - battery->design_capacity * - 10000 / battery->design_voltage; - battery->full_charge_capacity = - battery->full_charge_capacity * - 10000 / battery->design_voltage; - battery->design_capacity_warning = - battery->design_capacity_warning * - 10000 / battery->design_voltage; - battery->capacity_now = battery->capacity_now * - 10000 / battery->design_voltage; - } - } - } } static int acpi_battery_update(struct acpi_battery *battery) @@ -712,19 +635,11 @@ static int acpi_battery_update(struct acpi_battery *battery) static void acpi_battery_refresh(struct acpi_battery *battery) { - int power_unit; - if (!battery->bat.dev) return; - power_unit = battery->power_unit; - acpi_battery_get_info(battery); - - if (power_unit == battery->power_unit) - return; - - /* The battery has changed its reporting units. */ + /* The battery may have changed its reporting units. */ sysfs_remove_battery(battery); sysfs_add_battery(battery); } diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 1c57307c310f..d1e06c182cdb 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -944,18 +944,14 @@ static int __init acpi_bus_init(void) status = acpi_ec_ecdt_probe(); /* Ignore result. Not having an ECDT is not fatal. */ + acpi_bus_osc_support(); + status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION); if (ACPI_FAILURE(status)) { printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n"); goto error1; } - /* - * _OSC method may exist in module level code, - * so it must be run after ACPI_FULL_INITIALIZATION - */ - acpi_bus_osc_support(); - /* * _PDC control method may load dynamic SSDT tables, * and we need to install the table handler before that. diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index d2519b200e95..b19a18dd994f 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -71,6 +71,9 @@ enum ec_command { #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ +#define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts + per one transaction */ + enum { EC_FLAGS_QUERY_PENDING, /* Query is pending */ EC_FLAGS_GPE_STORM, /* GPE storm detected */ @@ -84,15 +87,6 @@ static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY; module_param(ec_delay, uint, 0644); MODULE_PARM_DESC(ec_delay, "Timeout(ms) waited until an EC command completes"); -/* - * If the number of false interrupts per one transaction exceeds - * this threshold, will think there is a GPE storm happened and - * will disable the GPE for normal transaction. - */ -static unsigned int ec_storm_threshold __read_mostly = 8; -module_param(ec_storm_threshold, uint, 0644); -MODULE_PARM_DESC(ec_storm_threshold, "Maxim false GPE numbers not considered as GPE storm"); - /* If we find an EC via the ECDT, we need to keep a ptr to its context */ /* External interfaces use first EC only, so remember */ typedef int (*acpi_ec_query_func) (void *data); @@ -325,7 +319,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) msleep(1); /* It is safe to enable the GPE outside of the transaction. */ acpi_enable_gpe(NULL, ec->gpe); - } else if (t->irq_count > ec_storm_threshold) { + } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) { pr_info(PREFIX "GPE storm detected, " "transactions will use polling mode\n"); set_bit(EC_FLAGS_GPE_STORM, &ec->flags); @@ -920,17 +914,6 @@ static int ec_flag_msi(const struct dmi_system_id *id) return 0; } -/* - * Clevo M720 notebook actually works ok with IRQ mode, if we lifted - * the GPE storm threshold back to 20 - */ -static int ec_enlarge_storm_threshold(const struct dmi_system_id *id) -{ - pr_debug("Setting the EC GPE storm threshold to 20\n"); - ec_storm_threshold = 20; - return 0; -} - static struct dmi_system_id __initdata ec_dmi_table[] = { { ec_skip_dsdt_scan, "Compal JFL92", { @@ -962,13 +945,10 @@ static struct dmi_system_id __initdata ec_dmi_table[] = { { ec_validate_ecdt, "ASUS hardware", { DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc.") }, NULL}, - { - ec_enlarge_storm_threshold, "CLEVO hardware", { - DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."), - DMI_MATCH(DMI_PRODUCT_NAME, "M720T/M730T"),}, NULL}, {}, }; + int __init acpi_ec_ecdt_probe(void) { acpi_status status; diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index e56f3be7b07d..3b5c3189fd99 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c @@ -45,8 +45,6 @@ static int pxm_to_node_map[MAX_PXM_DOMAINS] static int node_to_pxm_map[MAX_NUMNODES] = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL }; -unsigned char acpi_srat_revision __initdata; - int pxm_to_node(int pxm) { if (pxm < 0) @@ -257,13 +255,9 @@ acpi_parse_memory_affinity(struct acpi_subtable_header * header, static int __init acpi_parse_srat(struct acpi_table_header *table) { - struct acpi_table_srat *srat; if (!table) return -EINVAL; - srat = (struct acpi_table_srat *)table; - acpi_srat_revision = srat->header.revision; - /* Real work done in acpi_table_parse_srat below. */ return 0; diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index dfafecbddb53..d06078d660ad 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -595,13 +595,6 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) if (ACPI_SUCCESS(status)) { dev_info(root->bus->bridge, "ACPI _OSC control (0x%02x) granted\n", flags); - if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { - /* - * We have ASPM control, but the FADT indicates - * that it's unsupported. Clear it. - */ - pcie_clear_aspm(root->bus); - } } else { dev_info(root->bus->bridge, "ACPI _OSC request failed (%s), " diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 18935063138e..02d2a4c9084d 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -172,32 +172,8 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) apic_id = map_mat_entry(handle, type, acpi_id); if (apic_id == -1) apic_id = map_madt_entry(type, acpi_id); - if (apic_id == -1) { - /* - * On UP processor, there is no _MAT or MADT table. - * So above apic_id is always set to -1. - * - * BIOS may define multiple CPU handles even for UP processor. - * For example, - * - * Scope (_PR) - * { - * Processor (CPU0, 0x00, 0x00000410, 0x06) {} - * Processor (CPU1, 0x01, 0x00000410, 0x06) {} - * Processor (CPU2, 0x02, 0x00000410, 0x06) {} - * Processor (CPU3, 0x03, 0x00000410, 0x06) {} - * } - * - * Ignores apic_id and always returns 0 for the processor - * handle with acpi id 0 if nr_cpu_ids is 1. - * This should be the case if SMP tables are not found. - * Return -1 for other CPU's handle. - */ - if (nr_cpu_ids <= 1 && acpi_id == 0) - return acpi_id; - else - return apic_id; - } + if (apic_id == -1) + return apic_id; #ifdef CONFIG_SMP for_each_possible_cpu(i) { diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 6da4f0715593..a4e0f1ba6040 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -409,7 +409,6 @@ static void acpi_processor_notify(struct acpi_device *device, u32 event) acpi_bus_generate_proc_event(device, event, 0); acpi_bus_generate_netlink_event(device->pnp.device_class, dev_name(&device->dev), event, 0); - break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 65976cb77d93..431ab11c8c1b 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -991,9 +991,6 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) return -EINVAL; } - if (!dev) - return -EINVAL; - dev->cpu = pr->id; for (i = 0; i < CPUIDLE_STATE_MAX; i++) { dev->states[i].name[0] = '\0'; diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index 3854df25ac93..79cb65332894 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -58,27 +58,6 @@ ACPI_MODULE_NAME("processor_thermal"); static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg); static unsigned int acpi_thermal_cpufreq_is_init = 0; -#define reduction_pctg(cpu) \ - per_cpu(cpufreq_thermal_reduction_pctg, phys_package_first_cpu(cpu)) - -/* - * Emulate "per package data" using per cpu data (which should really be - * provided elsewhere) - * - * Note we can lose a CPU on cpu hotunplug, in this case we forget the state - * temporarily. Fortunately that's not a big issue here (I hope) - */ -static int phys_package_first_cpu(int cpu) -{ - int i; - int id = topology_physical_package_id(cpu); - - for_each_online_cpu(i) - if (topology_physical_package_id(i) == id) - return i; - return 0; -} - static int cpu_has_cpufreq(unsigned int cpu) { struct cpufreq_policy policy; @@ -98,7 +77,7 @@ static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb, max_freq = ( policy->cpuinfo.max_freq * - (100 - reduction_pctg(policy->cpu) * 20) + (100 - per_cpu(cpufreq_thermal_reduction_pctg, policy->cpu) * 20) ) / 100; cpufreq_verify_within_limits(policy, 0, max_freq); @@ -124,28 +103,16 @@ static int cpufreq_get_cur_state(unsigned int cpu) if (!cpu_has_cpufreq(cpu)) return 0; - return reduction_pctg(cpu); + return per_cpu(cpufreq_thermal_reduction_pctg, cpu); } static int cpufreq_set_cur_state(unsigned int cpu, int state) { - int i; - if (!cpu_has_cpufreq(cpu)) return 0; - reduction_pctg(cpu) = state; - - /* - * Update all the CPUs in the same package because they all - * contribute to the temperature and often share the same - * frequency. - */ - for_each_online_cpu(i) { - if (topology_physical_package_id(i) == - topology_physical_package_id(cpu)) - cpufreq_update_policy(i); - } + per_cpu(cpufreq_thermal_reduction_pctg, cpu) = state; + cpufreq_update_policy(cpu); return 0; } @@ -153,6 +120,10 @@ void acpi_thermal_cpufreq_init(void) { int i; + for (i = 0; i < nr_cpu_ids; i++) + if (cpu_present(i)) + per_cpu(cpufreq_thermal_reduction_pctg, i) = 0; + i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER); if (!i) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index ea1fe0a2d378..449c556274c0 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -789,8 +789,8 @@ acpi_bus_extract_wakeup_device_power_package(acpi_handle handle, static void acpi_bus_set_run_wake_flags(struct acpi_device *device) { struct acpi_device_id button_device_ids[] = { - {"PNP0C0C", 0}, {"PNP0C0D", 0}, + {"PNP0C0C", 0}, {"PNP0C0E", 0}, {"", 0}, }; @@ -802,11 +802,6 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) /* Power button, Lid switch always enable wakeup */ if (!acpi_match_device_ids(device, button_device_ids)) { device->wakeup.flags.run_wake = 1; - if (!acpi_match_device_ids(device, &button_device_ids[1])) { - /* Do not use Lid/sleep button for S5 wakeup */ - if (device->wakeup.sleep_state == ACPI_STATE_S5) - device->wakeup.sleep_state = ACPI_STATE_S4; - } device_set_wakeup_capable(&device->dev, true); return; } @@ -1158,7 +1153,7 @@ static void acpi_device_set_id(struct acpi_device *device) acpi_add_id(device, ACPI_DOCK_HID); else if (!acpi_ibm_smbus_match(device)) acpi_add_id(device, ACPI_SMBUS_IBM_HID); - else if (list_empty(&device->pnp.ids) && + else if (!acpi_device_hid(device) && ACPI_IS_ROOT_DEVICE(device->parent)) { acpi_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */ strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME); diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 79ddcdee83ad..6c949602cbd1 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -422,36 +422,12 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { }, { .callback = init_nvs_nosave, - .ident = "Sony Vaio VPCCW29FX", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "VPCCW29FX"), - }, - }, - { - .callback = init_nvs_nosave, .ident = "Averatec AV1020-ED2", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"), DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"), }, }, - { - .callback = init_nvs_nosave, - .ident = "Asus K54C", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "K54C"), - }, - }, - { - .callback = init_nvs_nosave, - .ident = "Asus K54HR", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "K54HR"), - }, - }, {}, }; #endif /* CONFIG_SUSPEND */ diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 0364b05fb7a2..77255f250dbb 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -173,7 +173,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) { int result = 0; - if (!strncmp(val, "enable", strlen("enable"))) { + if (!strncmp(val, "enable", strlen("enable") - 1)) { result = acpi_debug_trace(trace_method_name, trace_debug_level, trace_debug_layer, 0); if (result) @@ -181,7 +181,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) goto exit; } - if (!strncmp(val, "disable", strlen("disable"))) { + if (!strncmp(val, "disable", strlen("disable") - 1)) { int name = 0; result = acpi_debug_trace((char *)&name, trace_debug_level, trace_debug_layer, 0); diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 76f0b9432d83..db39e9e607d8 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -390,12 +390,6 @@ static int __init video_set_bqc_offset(const struct dmi_system_id *d) return 0; } -static int video_ignore_initial_backlight(const struct dmi_system_id *d) -{ - use_bios_initial_backlight = 0; - return 0; -} - static struct dmi_system_id video_dmi_table[] __initdata = { /* * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121 @@ -440,14 +434,6 @@ static struct dmi_system_id video_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"), }, }, - { - .callback = video_ignore_initial_backlight, - .ident = "HP Folio 13-2000", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13 - 2000 Notebook PC"), - }, - }, {} }; @@ -1746,7 +1732,6 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) static int __init intel_opregion_present(void) { - int i915 = 0; #if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE) struct pci_dev *dev = NULL; u32 address; @@ -1759,10 +1744,10 @@ static int __init intel_opregion_present(void) pci_read_config_dword(dev, 0xfc, &address); if (!address) continue; - i915 = 1; + return 1; } #endif - return i915; + return 0; } int acpi_video_register(void) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 75a8d0f2499e..71afe0371311 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -267,7 +267,6 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */ { PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */ { PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point RAID */ - { PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */ /* JMicron 360/1/3/5/6, match class to avoid IDE function */ { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, @@ -392,22 +391,12 @@ static const struct pci_device_id ahci_pci_tbl[] = { .driver_data = board_ahci_yes_fbs }, /* 88se9128 */ { PCI_DEVICE(0x1b4b, 0x9125), .driver_data = board_ahci_yes_fbs }, /* 88se9125 */ - { PCI_DEVICE(0x1b4b, 0x917a), - .driver_data = board_ahci_yes_fbs }, /* 88se9172 */ - { PCI_DEVICE(0x1b4b, 0x9192), - .driver_data = board_ahci_yes_fbs }, /* 88se9172 on some Gigabyte */ { PCI_DEVICE(0x1b4b, 0x91a3), .driver_data = board_ahci_yes_fbs }, /* Promise */ { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ - /* Asmedia */ - { PCI_VDEVICE(ASMEDIA, 0x0601), board_ahci }, /* ASM1060 */ - { PCI_VDEVICE(ASMEDIA, 0x0602), board_ahci }, /* ASM1060 */ - { PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci }, /* ASM1061 */ - { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ - /* Generic, PCI class code for AHCI */ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci }, @@ -822,18 +811,6 @@ static bool ahci_sb600_enable_64bit(struct pci_dev *pdev) DMI_MATCH(DMI_BOARD_NAME, "MS-7376"), }, }, - /* - * All BIOS versions for the Asus M3A support 64bit DMA. - * (all release versions from 0301 to 1206 were tested) - */ - { - .ident = "ASUS M3A", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, - "ASUSTeK Computer INC."), - DMI_MATCH(DMI_BOARD_NAME, "M3A"), - }, - }, { } }; const struct dmi_system_id *match; diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 6da6debee35b..6f6e7718b05c 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -113,8 +113,6 @@ enum { PIIX_PATA_FLAGS = ATA_FLAG_SLAVE_POSS, PIIX_SATA_FLAGS = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR, - PIIX_FLAG_PIO16 = (1 << 30), /*support 16bit PIO only*/ - PIIX_80C_PRI = (1 << 5) | (1 << 4), PIIX_80C_SEC = (1 << 7) | (1 << 6), @@ -149,7 +147,6 @@ enum piix_controller_ids { ich8m_apple_sata, /* locks up on second port enable */ tolapai_sata, piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */ - ich8_sata_snb, }; struct piix_map_db { @@ -180,7 +177,6 @@ static int piix_sidpr_scr_write(struct ata_link *link, static int piix_sidpr_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, unsigned hints); static bool piix_irq_check(struct ata_port *ap); -static int piix_port_start(struct ata_port *ap); #ifdef CONFIG_PM static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); static int piix_pci_device_resume(struct pci_dev *pdev); @@ -302,21 +298,21 @@ static const struct pci_device_id piix_pci_tbl[] = { /* SATA Controller IDE (PCH) */ { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, /* SATA Controller IDE (CPT) */ - { 0x8086, 0x1c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, + { 0x8086, 0x1c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, /* SATA Controller IDE (CPT) */ - { 0x8086, 0x1c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, + { 0x8086, 0x1c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, /* SATA Controller IDE (CPT) */ { 0x8086, 0x1c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, /* SATA Controller IDE (CPT) */ { 0x8086, 0x1c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, /* SATA Controller IDE (PBG) */ - { 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, + { 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, /* SATA Controller IDE (PBG) */ { 0x8086, 0x1d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, /* SATA Controller IDE (Panther Point) */ - { 0x8086, 0x1e00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, + { 0x8086, 0x1e00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, /* SATA Controller IDE (Panther Point) */ - { 0x8086, 0x1e01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, + { 0x8086, 0x1e01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, /* SATA Controller IDE (Panther Point) */ { 0x8086, 0x1e08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, /* SATA Controller IDE (Panther Point) */ @@ -342,7 +338,6 @@ static struct scsi_host_template piix_sht = { static struct ata_port_operations piix_sata_ops = { .inherits = &ata_bmdma32_port_ops, .sff_irq_check = piix_irq_check, - .port_start = piix_port_start, }; static struct ata_port_operations piix_pata_ops = { @@ -483,7 +478,6 @@ static const struct piix_map_db *piix_map_db_table[] = { [ich8_2port_sata] = &ich8_2port_map_db, [ich8m_apple_sata] = &ich8m_apple_map_db, [tolapai_sata] = &tolapai_map_db, - [ich8_sata_snb] = &ich8_map_db, }; static struct ata_port_info piix_port_info[] = { @@ -612,19 +606,6 @@ static struct ata_port_info piix_port_info[] = { .port_ops = &piix_vmw_ops, }, - /* - * some Sandybridge chipsets have broken 32 mode up to now, - * see https://bugzilla.kernel.org/show_bug.cgi?id=40592 - */ - [ich8_sata_snb] = - { - .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR | PIIX_FLAG_PIO16, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA6, - .port_ops = &piix_sata_ops, - }, - }; static struct pci_bits piix_enable_bits[] = { @@ -668,14 +649,6 @@ static const struct ich_laptop ich_laptop[] = { { 0, } }; -static int piix_port_start(struct ata_port *ap) -{ - if (!(ap->flags & PIIX_FLAG_PIO16)) - ap->pflags |= ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE; - - return ata_bmdma_port_start(ap); -} - /** * ich_pata_cable_detect - Probe host controller cable detect info * @ap: Port for which cable detect info is desired diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 5a72e36a3147..000d03ae6653 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2543,7 +2543,6 @@ int ata_bus_probe(struct ata_port *ap) * bus as we may be talking too fast. */ dev->pio_mode = XFER_PIO_0; - dev->dma_mode = 0xff; /* If the controller has a pio mode setup function * then use it to set the chipset to rights. Don't @@ -4139,7 +4138,6 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { /* Devices which aren't very happy with higher link speeds */ { "WD My Book", NULL, ATA_HORKAGE_1_5_GBPS, }, - { "Seagate FreeAgent GoFlex", NULL, ATA_HORKAGE_1_5_GBPS, }, /* * Devices which choke on SETXFER. Applies only if both the diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 1cbb0043638d..7f099d6e4e0b 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2602,7 +2602,6 @@ int ata_eh_reset(struct ata_link *link, int classify, * bus as we may be talking too fast. */ dev->pio_mode = XFER_PIO_0; - dev->dma_mode = 0xff; /* If the controller has a pio mode setup function * then use it to set the chipset to rights. Don't @@ -3488,8 +3487,7 @@ static int ata_count_probe_trials_cb(struct ata_ering_entry *ent, void *void_arg u64 now = get_jiffies_64(); int *trials = void_arg; - if ((ent->eflags & ATA_EFLAG_OLD_ER) || - (ent->timestamp < now - min(now, interval))) + if (ent->timestamp < now - min(now, interval)) return -1; (*trials)++; diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 3b42a5d6efdd..927f968e99d9 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -308,8 +308,7 @@ ata_scsi_activity_show(struct device *dev, struct device_attribute *attr, struct ata_port *ap = ata_shost_to_port(sdev->host); struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); - if (atadev && ap->ops->sw_activity_show && - (ap->flags & ATA_FLAG_SW_ACTIVITY)) + if (ap->ops->sw_activity_show && (ap->flags & ATA_FLAG_SW_ACTIVITY)) return ap->ops->sw_activity_show(atadev, buf); return -EINVAL; } @@ -324,8 +323,7 @@ ata_scsi_activity_store(struct device *dev, struct device_attribute *attr, enum sw_activity val; int rc; - if (atadev && ap->ops->sw_activity_store && - (ap->flags & ATA_FLAG_SW_ACTIVITY)) { + if (ap->ops->sw_activity_store && (ap->flags & ATA_FLAG_SW_ACTIVITY)) { val = simple_strtoul(buf, NULL, 0); switch (val) { case OFF: case BLINK_ON: case BLINK_OFF: diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index d750962916b1..6bd9425ba5ab 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -396,7 +396,8 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev) ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000); active = clamp_val(t.active, 2, 15); - recover = clamp_val(t.recover, 2, 16) & 0x0F; + recover = clamp_val(t.recover, 2, 16); + recover &= 0x15; inb(0x3E6); inb(0x3E6); diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index d6d4f57cdd3e..ac8d7d97e408 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -124,17 +124,6 @@ static const struct via_isa_bridge { { NULL } }; -static const struct dmi_system_id no_atapi_dma_dmi_table[] = { - { - .ident = "AVERATEC 3200", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "AVERATEC"), - DMI_MATCH(DMI_BOARD_NAME, "3200"), - }, - }, - { } -}; - struct via_port { u8 cached_device; }; @@ -366,13 +355,6 @@ static unsigned long via_mode_filter(struct ata_device *dev, unsigned long mask) mask &= ~ ATA_MASK_UDMA; } } - - if (dev->class == ATA_DEV_ATAPI && - dmi_check_system(no_atapi_dma_dmi_table)) { - ata_dev_printk(dev, KERN_WARNING, "controller locks up on ATAPI DMA, forcing PIO\n"); - mask &= ATA_MASK_PIO; - } - return mask; } diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index ca4646aa0d6b..a004b1e0ea6d 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -147,10 +147,6 @@ struct pdc_port_priv { dma_addr_t pkt_dma; }; -struct pdc_host_priv { - spinlock_t hard_reset_lock; -}; - static int pdc_sata_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); static int pdc_sata_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); static int pdc_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); @@ -805,10 +801,9 @@ static void pdc_hard_reset_port(struct ata_port *ap) void __iomem *host_mmio = ap->host->iomap[PDC_MMIO_BAR]; void __iomem *pcictl_b1_mmio = host_mmio + PDC_PCI_CTL + 1; unsigned int ata_no = pdc_ata_port_to_ata_no(ap); - struct pdc_host_priv *hpriv = ap->host->private_data; u8 tmp; - spin_lock(&hpriv->hard_reset_lock); + spin_lock(&ap->host->lock); tmp = readb(pcictl_b1_mmio); tmp &= ~(0x10 << ata_no); @@ -819,7 +814,7 @@ static void pdc_hard_reset_port(struct ata_port *ap) writeb(tmp, pcictl_b1_mmio); readb(pcictl_b1_mmio); /* flush */ - spin_unlock(&hpriv->hard_reset_lock); + spin_unlock(&ap->host->lock); } static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class, @@ -1188,7 +1183,6 @@ static int pdc_ata_init_one(struct pci_dev *pdev, const struct ata_port_info *pi = &pdc_port_info[ent->driver_data]; const struct ata_port_info *ppi[PDC_MAX_PORTS]; struct ata_host *host; - struct pdc_host_priv *hpriv; void __iomem *host_mmio; int n_ports, i, rc; int is_sataii_tx4; @@ -1226,11 +1220,6 @@ static int pdc_ata_init_one(struct pci_dev *pdev, dev_printk(KERN_ERR, &pdev->dev, "failed to allocate host\n"); return -ENOMEM; } - hpriv = devm_kzalloc(&pdev->dev, sizeof *hpriv, GFP_KERNEL); - if (!hpriv) - return -ENOMEM; - spin_lock_init(&hpriv->hard_reset_lock); - host->private_data = hpriv; host->iomap = pcim_iomap_table(pdev); is_sataii_tx4 = pdc_is_sataii_tx4(pi->flags); diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 84980acf324e..35eabcf34568 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -142,39 +142,6 @@ static int k2_sata_scr_write(struct ata_link *link, return 0; } -static int k2_sata_softreset(struct ata_link *link, - unsigned int *class, unsigned long deadline) -{ - u8 dmactl; - void __iomem *mmio = link->ap->ioaddr.bmdma_addr; - - dmactl = readb(mmio + ATA_DMA_CMD); - - /* Clear the start bit */ - if (dmactl & ATA_DMA_START) { - dmactl &= ~ATA_DMA_START; - writeb(dmactl, mmio + ATA_DMA_CMD); - } - - return ata_sff_softreset(link, class, deadline); -} - -static int k2_sata_hardreset(struct ata_link *link, - unsigned int *class, unsigned long deadline) -{ - u8 dmactl; - void __iomem *mmio = link->ap->ioaddr.bmdma_addr; - - dmactl = readb(mmio + ATA_DMA_CMD); - - /* Clear the start bit */ - if (dmactl & ATA_DMA_START) { - dmactl &= ~ATA_DMA_START; - writeb(dmactl, mmio + ATA_DMA_CMD); - } - - return sata_sff_hardreset(link, class, deadline); -} static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) { @@ -379,8 +346,6 @@ static struct scsi_host_template k2_sata_sht = { static struct ata_port_operations k2_sata_ops = { .inherits = &ata_bmdma_port_ops, - .softreset = k2_sata_softreset, - .hardreset = k2_sata_hardreset, .sff_tf_load = k2_sata_tf_load, .sff_tf_read = k2_sata_tf_read, .sff_check_status = k2_stat_check_status, diff --git a/drivers/atm/iphase.h b/drivers/atm/iphase.h index b2778e75e31f..077735e0e04b 100644 --- a/drivers/atm/iphase.h +++ b/drivers/atm/iphase.h @@ -636,82 +636,82 @@ struct rx_buf_desc { #define SEG_BASE IPHASE5575_FRAG_CONTROL_REG_BASE #define REASS_BASE IPHASE5575_REASS_CONTROL_REG_BASE -typedef volatile u_int ffreg_t; +typedef volatile u_int freg_t; typedef u_int rreg_t; typedef struct _ffredn_t { - ffreg_t idlehead_high; /* Idle cell header (high) */ - ffreg_t idlehead_low; /* Idle cell header (low) */ - ffreg_t maxrate; /* Maximum rate */ - ffreg_t stparms; /* Traffic Management Parameters */ - ffreg_t abrubr_abr; /* ABRUBR Priority Byte 1, TCR Byte 0 */ - ffreg_t rm_type; /* */ - u_int filler5[0x17 - 0x06]; - ffreg_t cmd_reg; /* Command register */ - u_int filler18[0x20 - 0x18]; - ffreg_t cbr_base; /* CBR Pointer Base */ - ffreg_t vbr_base; /* VBR Pointer Base */ - ffreg_t abr_base; /* ABR Pointer Base */ - ffreg_t ubr_base; /* UBR Pointer Base */ - u_int filler24; - ffreg_t vbrwq_base; /* VBR Wait Queue Base */ - ffreg_t abrwq_base; /* ABR Wait Queue Base */ - ffreg_t ubrwq_base; /* UBR Wait Queue Base */ - ffreg_t vct_base; /* Main VC Table Base */ - ffreg_t vcte_base; /* Extended Main VC Table Base */ - u_int filler2a[0x2C - 0x2A]; - ffreg_t cbr_tab_beg; /* CBR Table Begin */ - ffreg_t cbr_tab_end; /* CBR Table End */ - ffreg_t cbr_pointer; /* CBR Pointer */ - u_int filler2f[0x30 - 0x2F]; - ffreg_t prq_st_adr; /* Packet Ready Queue Start Address */ - ffreg_t prq_ed_adr; /* Packet Ready Queue End Address */ - ffreg_t prq_rd_ptr; /* Packet Ready Queue read pointer */ - ffreg_t prq_wr_ptr; /* Packet Ready Queue write pointer */ - ffreg_t tcq_st_adr; /* Transmit Complete Queue Start Address*/ - ffreg_t tcq_ed_adr; /* Transmit Complete Queue End Address */ - ffreg_t tcq_rd_ptr; /* Transmit Complete Queue read pointer */ - ffreg_t tcq_wr_ptr; /* Transmit Complete Queue write pointer*/ - u_int filler38[0x40 - 0x38]; - ffreg_t queue_base; /* Base address for PRQ and TCQ */ - ffreg_t desc_base; /* Base address of descriptor table */ - u_int filler42[0x45 - 0x42]; - ffreg_t mode_reg_0; /* Mode register 0 */ - ffreg_t mode_reg_1; /* Mode register 1 */ - ffreg_t intr_status_reg;/* Interrupt Status register */ - ffreg_t mask_reg; /* Mask Register */ - ffreg_t cell_ctr_high1; /* Total cell transfer count (high) */ - ffreg_t cell_ctr_lo1; /* Total cell transfer count (low) */ - ffreg_t state_reg; /* Status register */ - u_int filler4c[0x58 - 0x4c]; - ffreg_t curr_desc_num; /* Contains the current descriptor num */ - ffreg_t next_desc; /* Next descriptor */ - ffreg_t next_vc; /* Next VC */ - u_int filler5b[0x5d - 0x5b]; - ffreg_t present_slot_cnt;/* Present slot count */ - u_int filler5e[0x6a - 0x5e]; - ffreg_t new_desc_num; /* New descriptor number */ - ffreg_t new_vc; /* New VC */ - ffreg_t sched_tbl_ptr; /* Schedule table pointer */ - ffreg_t vbrwq_wptr; /* VBR wait queue write pointer */ - ffreg_t vbrwq_rptr; /* VBR wait queue read pointer */ - ffreg_t abrwq_wptr; /* ABR wait queue write pointer */ - ffreg_t abrwq_rptr; /* ABR wait queue read pointer */ - ffreg_t ubrwq_wptr; /* UBR wait queue write pointer */ - ffreg_t ubrwq_rptr; /* UBR wait queue read pointer */ - ffreg_t cbr_vc; /* CBR VC */ - ffreg_t vbr_sb_vc; /* VBR SB VC */ - ffreg_t abr_sb_vc; /* ABR SB VC */ - ffreg_t ubr_sb_vc; /* UBR SB VC */ - ffreg_t vbr_next_link; /* VBR next link */ - ffreg_t abr_next_link; /* ABR next link */ - ffreg_t ubr_next_link; /* UBR next link */ - u_int filler7a[0x7c-0x7a]; - ffreg_t out_rate_head; /* Out of rate head */ - u_int filler7d[0xca-0x7d]; /* pad out to full address space */ - ffreg_t cell_ctr_high1_nc;/* Total cell transfer count (high) */ - ffreg_t cell_ctr_lo1_nc;/* Total cell transfer count (low) */ - u_int fillercc[0x100-0xcc]; /* pad out to full address space */ + freg_t idlehead_high; /* Idle cell header (high) */ + freg_t idlehead_low; /* Idle cell header (low) */ + freg_t maxrate; /* Maximum rate */ + freg_t stparms; /* Traffic Management Parameters */ + freg_t abrubr_abr; /* ABRUBR Priority Byte 1, TCR Byte 0 */ + freg_t rm_type; /* */ + u_int filler5[0x17 - 0x06]; + freg_t cmd_reg; /* Command register */ + u_int filler18[0x20 - 0x18]; + freg_t cbr_base; /* CBR Pointer Base */ + freg_t vbr_base; /* VBR Pointer Base */ + freg_t abr_base; /* ABR Pointer Base */ + freg_t ubr_base; /* UBR Pointer Base */ + u_int filler24; + freg_t vbrwq_base; /* VBR Wait Queue Base */ + freg_t abrwq_base; /* ABR Wait Queue Base */ + freg_t ubrwq_base; /* UBR Wait Queue Base */ + freg_t vct_base; /* Main VC Table Base */ + freg_t vcte_base; /* Extended Main VC Table Base */ + u_int filler2a[0x2C - 0x2A]; + freg_t cbr_tab_beg; /* CBR Table Begin */ + freg_t cbr_tab_end; /* CBR Table End */ + freg_t cbr_pointer; /* CBR Pointer */ + u_int filler2f[0x30 - 0x2F]; + freg_t prq_st_adr; /* Packet Ready Queue Start Address */ + freg_t prq_ed_adr; /* Packet Ready Queue End Address */ + freg_t prq_rd_ptr; /* Packet Ready Queue read pointer */ + freg_t prq_wr_ptr; /* Packet Ready Queue write pointer */ + freg_t tcq_st_adr; /* Transmit Complete Queue Start Address*/ + freg_t tcq_ed_adr; /* Transmit Complete Queue End Address */ + freg_t tcq_rd_ptr; /* Transmit Complete Queue read pointer */ + freg_t tcq_wr_ptr; /* Transmit Complete Queue write pointer*/ + u_int filler38[0x40 - 0x38]; + freg_t queue_base; /* Base address for PRQ and TCQ */ + freg_t desc_base; /* Base address of descriptor table */ + u_int filler42[0x45 - 0x42]; + freg_t mode_reg_0; /* Mode register 0 */ + freg_t mode_reg_1; /* Mode register 1 */ + freg_t intr_status_reg;/* Interrupt Status register */ + freg_t mask_reg; /* Mask Register */ + freg_t cell_ctr_high1; /* Total cell transfer count (high) */ + freg_t cell_ctr_lo1; /* Total cell transfer count (low) */ + freg_t state_reg; /* Status register */ + u_int filler4c[0x58 - 0x4c]; + freg_t curr_desc_num; /* Contains the current descriptor num */ + freg_t next_desc; /* Next descriptor */ + freg_t next_vc; /* Next VC */ + u_int filler5b[0x5d - 0x5b]; + freg_t present_slot_cnt;/* Present slot count */ + u_int filler5e[0x6a - 0x5e]; + freg_t new_desc_num; /* New descriptor number */ + freg_t new_vc; /* New VC */ + freg_t sched_tbl_ptr; /* Schedule table pointer */ + freg_t vbrwq_wptr; /* VBR wait queue write pointer */ + freg_t vbrwq_rptr; /* VBR wait queue read pointer */ + freg_t abrwq_wptr; /* ABR wait queue write pointer */ + freg_t abrwq_rptr; /* ABR wait queue read pointer */ + freg_t ubrwq_wptr; /* UBR wait queue write pointer */ + freg_t ubrwq_rptr; /* UBR wait queue read pointer */ + freg_t cbr_vc; /* CBR VC */ + freg_t vbr_sb_vc; /* VBR SB VC */ + freg_t abr_sb_vc; /* ABR SB VC */ + freg_t ubr_sb_vc; /* UBR SB VC */ + freg_t vbr_next_link; /* VBR next link */ + freg_t abr_next_link; /* ABR next link */ + freg_t ubr_next_link; /* UBR next link */ + u_int filler7a[0x7c-0x7a]; + freg_t out_rate_head; /* Out of rate head */ + u_int filler7d[0xca-0x7d]; /* pad out to full address space */ + freg_t cell_ctr_high1_nc;/* Total cell transfer count (high) */ + freg_t cell_ctr_lo1_nc;/* Total cell transfer count (low) */ + u_int fillercc[0x100-0xcc]; /* pad out to full address space */ } ffredn_t; typedef struct _rfredn_t { diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index adfce9f1eb92..5d1d07645132 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -967,11 +967,10 @@ static uint32_t fpga_tx(struct solos_card *card) for (port = 0; tx_pending; tx_pending >>= 1, port++) { if (tx_pending & 1) { struct sk_buff *oldskb = card->tx_skb[port]; - if (oldskb) { + if (oldskb) pci_unmap_single(card->dev, SKB_CB(oldskb)->dma_addr, oldskb->len, PCI_DMA_TODEVICE); - card->tx_skb[port] = NULL; - } + spin_lock(&card->tx_queue_lock); skb = skb_dequeue(&card->tx_queue[port]); if (!skb) @@ -985,7 +984,6 @@ static uint32_t fpga_tx(struct solos_card *card) } else if (skb && card->using_dma) { SKB_CB(skb)->dma_addr = pci_map_single(card->dev, skb->data, skb->len, PCI_DMA_TODEVICE); - card->tx_skb[port] = skb; iowrite32(SKB_CB(skb)->dma_addr, card->config_regs + TX_DMA_ADDR(port)); } @@ -1154,8 +1152,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) db_fpga_upgrade = db_firmware_upgrade = 0; } - if (card->fpga_version >= DMA_SUPPORTED) { - pci_set_master(dev); + if (card->fpga_version >= DMA_SUPPORTED){ card->using_dma = 1; } else { card->using_dma = 0; diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 13305c8c3e21..d57e8d0fb823 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -168,30 +168,4 @@ config SYS_HYPERVISOR bool default n -config SYNC - bool "Synchronization framework" - default n - select ANON_INODES - help - This option enables the framework for synchronization between multiple - drivers. Sync implementations can take advantage of hardware - synchronization built into devices like GPUs. - -config SW_SYNC - bool "Software synchronization objects" - default n - depends on SYNC - help - A sync object driver that uses a 32bit counter to coordinate - syncrhronization. Useful when there is no hardware primitive backing - the synchronization. - -config SW_SYNC_USER - bool "Userspace API for SW_SYNC" - default n - depends on SW_SYNC - help - Provides a user space API to the sw sync object. - *WARNING* improper use of this can result in deadlocking kernel - drivers from userspace. endmenu diff --git a/drivers/base/Makefile b/drivers/base/Makefile index b61688245584..4c5701c15f53 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -19,8 +19,5 @@ obj-$(CONFIG_MODULES) += module.o endif obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o -obj-$(CONFIG_SYNC) += sync.o -obj-$(CONFIG_SW_SYNC) += sw_sync.o - ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG diff --git a/drivers/base/core.c b/drivers/base/core.c index d13851c5c684..bc8729d603a7 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -22,7 +22,6 @@ #include #include #include -#include #include "base.h" #include "power/power.h" @@ -1744,10 +1743,6 @@ void device_shutdown(void) list_del_init(&dev->kobj.entry); spin_unlock(&devices_kset->list_lock); - /* Don't allow any more runtime suspends */ - pm_runtime_get_noresume(dev); - pm_runtime_barrier(dev); - if (dev->bus && dev->bus->shutdown) { dev_dbg(dev, "shutdown\n"); dev->bus->shutdown(dev); diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 3719c94be19c..bbb03e6f7255 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -226,13 +226,13 @@ static ssize_t firmware_loading_store(struct device *dev, int loading = simple_strtol(buf, NULL, 10); int i; - mutex_lock(&fw_lock); - - if (!fw_priv->fw) - goto out; - switch (loading) { case 1: + mutex_lock(&fw_lock); + if (!fw_priv->fw) { + mutex_unlock(&fw_lock); + break; + } firmware_free_data(fw_priv->fw); memset(fw_priv->fw, 0, sizeof(struct firmware)); /* If the pages are not owned by 'struct firmware' */ @@ -243,6 +243,7 @@ static ssize_t firmware_loading_store(struct device *dev, fw_priv->page_array_size = 0; fw_priv->nr_pages = 0; set_bit(FW_STATUS_LOADING, &fw_priv->status); + mutex_unlock(&fw_lock); break; case 0: if (test_bit(FW_STATUS_LOADING, &fw_priv->status)) { @@ -273,8 +274,7 @@ static ssize_t firmware_loading_store(struct device *dev, fw_load_abort(fw_priv); break; } -out: - mutex_unlock(&fw_lock); + return count; } @@ -521,6 +521,11 @@ static int _request_firmware(const struct firmware **firmware_p, if (!firmware_p) return -EINVAL; + if (WARN_ON(usermodehelper_is_disabled())) { + dev_err(device, "firmware: %s will not be loaded\n", name); + return -EBUSY; + } + *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); if (!firmware) { dev_err(device, "%s: kmalloc(struct firmware) failed\n", @@ -534,12 +539,6 @@ static int _request_firmware(const struct firmware **firmware_p, return 0; } - if (WARN_ON(usermodehelper_is_disabled())) { - dev_err(device, "firmware: %s will not be loaded\n", name); - retval = -EBUSY; - goto out; - } - if (uevent) dev_dbg(device, "firmware: requesting %s\n", name); diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 5fb6aaed2adc..45d7c8fc73bd 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -223,42 +223,6 @@ int memory_isolate_notify(unsigned long val, void *v) return atomic_notifier_call_chain(&memory_isolate_chain, val, v); } -/* - * The probe routines leave the pages reserved, just as the bootmem code does. - * Make sure they're still that way. - */ -static bool pages_correctly_reserved(unsigned long start_pfn, - unsigned long nr_pages) -{ - int i, j; - struct page *page; - unsigned long pfn = start_pfn; - - /* - * memmap between sections is not contiguous except with - * SPARSEMEM_VMEMMAP. We lookup the page once per section - * and assume memmap is contiguous within each section - */ - for (i = 0; i < sections_per_block; i++, pfn += PAGES_PER_SECTION) { - if (WARN_ON_ONCE(!pfn_valid(pfn))) - return false; - page = pfn_to_page(pfn); - - for (j = 0; j < PAGES_PER_SECTION; j++) { - if (PageReserved(page + j)) - continue; - - printk(KERN_WARNING "section number %ld page number %d " - "not reserved, was it already online?\n", - pfn_to_section_nr(pfn), j); - - return false; - } - } - - return true; -} - /* * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is * OK to have direct references to sparsemem variables in here. @@ -266,6 +230,7 @@ static bool pages_correctly_reserved(unsigned long start_pfn, static int memory_block_action(unsigned long phys_index, unsigned long action) { + int i; unsigned long start_pfn, start_paddr; unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; struct page *first_page; @@ -273,13 +238,26 @@ memory_block_action(unsigned long phys_index, unsigned long action) first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT); + /* + * The probe routines leave the pages reserved, just + * as the bootmem code does. Make sure they're still + * that way. + */ + if (action == MEM_ONLINE) { + for (i = 0; i < nr_pages; i++) { + if (PageReserved(first_page+i)) + continue; + + printk(KERN_WARNING "section number %ld page number %d " + "not reserved, was it already online?\n", + phys_index, i); + return -EBUSY; + } + } + switch (action) { case MEM_ONLINE: start_pfn = page_to_pfn(first_page); - - if (!pages_correctly_reserved(start_pfn, nr_pages)) - return -EBUSY; - ret = online_pages(start_pfn, nr_pages); break; case MEM_OFFLINE: diff --git a/drivers/base/node.c b/drivers/base/node.c index 5693ecee9a40..793f796c4da3 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -127,13 +127,12 @@ static ssize_t node_read_meminfo(struct sys_device * dev, nid, K(node_page_state(nid, NR_WRITEBACK)), nid, K(node_page_state(nid, NR_FILE_PAGES)), nid, K(node_page_state(nid, NR_FILE_MAPPED)), -#ifdef CONFIG_TRANSPARENT_HUGEPAGE nid, K(node_page_state(nid, NR_ANON_PAGES) +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) * - HPAGE_PMD_NR), -#else - nid, K(node_page_state(nid, NR_ANON_PAGES)), + HPAGE_PMD_NR #endif + ), nid, K(node_page_state(nid, NR_SHMEM)), nid, node_page_state(nid, NR_KERNEL_STACK) * THREAD_SIZE / 1024, @@ -144,14 +143,13 @@ static ssize_t node_read_meminfo(struct sys_device * dev, nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE) + node_page_state(nid, NR_SLAB_UNRECLAIMABLE)), nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE)), -#ifdef CONFIG_TRANSPARENT_HUGEPAGE nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE)) +#ifdef CONFIG_TRANSPARENT_HUGEPAGE , nid, K(node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) * - HPAGE_PMD_NR)); -#else - nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE))); + HPAGE_PMD_NR) #endif + ); n += hugetlb_report_node_meminfo(nid, buf + n); return n; } diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 4282d442d352..06f09bf89cb2 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "../base.h" #include "power.h" @@ -50,12 +49,6 @@ LIST_HEAD(dpm_noirq_list); static DEFINE_MUTEX(dpm_list_mtx); static pm_message_t pm_transition; -static void dpm_drv_timeout(unsigned long data); -struct dpm_drv_wd_data { - struct device *dev; - struct task_struct *tsk; -}; - static int async_error; /** @@ -590,30 +583,6 @@ static bool is_async(struct device *dev) && !pm_trace_is_enabled(); } -/** - * dpm_drv_timeout - Driver suspend / resume watchdog handler - * @data: struct device which timed out - * - * Called when a driver has timed out suspending or resuming. - * There's not much we can do here to recover so - * BUG() out for a crash-dump - * - */ -static void dpm_drv_timeout(unsigned long data) -{ - struct dpm_drv_wd_data *wd_data = (void *)data; - struct device *dev = wd_data->dev; - struct task_struct *tsk = wd_data->tsk; - - printk(KERN_EMERG "**** DPM device timeout: %s (%s)\n", dev_name(dev), - (dev->driver ? dev->driver->name : "no driver")); - - printk(KERN_EMERG "dpm suspend stack:\n"); - show_stack(tsk, NULL); - - BUG(); -} - /** * dpm_resume - Execute "resume" callbacks for non-sysdev devices. * @state: PM transition of the system being carried out. @@ -872,19 +841,8 @@ static int legacy_suspend(struct device *dev, pm_message_t state, static int __device_suspend(struct device *dev, pm_message_t state, bool async) { int error = 0; - struct timer_list timer; - struct dpm_drv_wd_data data; dpm_wait_for_children(dev, async); - - data.dev = dev; - data.tsk = get_current(); - init_timer_on_stack(&timer); - timer.expires = jiffies + HZ * 12; - timer.function = dpm_drv_timeout; - timer.data = (unsigned long)&data; - add_timer(&timer); - device_lock(dev); if (async_error) @@ -934,10 +892,6 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) Unlock: device_unlock(dev); - - del_timer_sync(&timer); - destroy_timer_on_stack(&timer); - complete_all(&dev->power.completion); if (error) diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index da39fa50e563..0d4587b15c55 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -278,9 +278,6 @@ static int rpm_callback(int (*cb)(struct device *), struct device *dev) * If a deferred resume was requested while the callback was running then carry * it out; otherwise send an idle notification for the device (if the suspend * failed) or for its parent (if the suspend succeeded). - * If ->runtime_suspend failed with -EAGAIN or -EBUSY, and if the RPM_AUTO - * flag is set and the next autosuspend-delay expiration time is in the - * future, schedule another autosuspend attempt. * * This function must be called under dev->power.lock with interrupts disabled. */ @@ -360,6 +357,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) goto repeat; } + dev->power.deferred_resume = false; if (dev->power.no_callbacks) goto no_callback; /* Assume success. */ @@ -391,21 +389,10 @@ static int rpm_suspend(struct device *dev, int rpmflags) if (retval) { __update_runtime_status(dev, RPM_ACTIVE); dev->power.deferred_resume = 0; - if (retval == -EAGAIN || retval == -EBUSY) { + if (retval == -EAGAIN || retval == -EBUSY) dev->power.runtime_error = 0; - - /* - * If the callback routine failed an autosuspend, and - * if the last_busy time has been updated so that there - * is a new autosuspend expiration time, automatically - * reschedule another autosuspend. - */ - if ((rpmflags & RPM_AUTO) && - pm_runtime_autosuspend_expiration(dev) != 0) - goto repeat; - } else { + else pm_runtime_cancel_pending(dev); - } } else { no_callback: __update_runtime_status(dev, RPM_SUSPENDED); @@ -419,7 +406,6 @@ static int rpm_suspend(struct device *dev, int rpmflags) wake_up_all(&dev->power.wait_queue); if (dev->power.deferred_resume) { - dev->power.deferred_resume = false; rpm_resume(dev, 0); retval = -EAGAIN; goto out; @@ -533,7 +519,6 @@ static int rpm_resume(struct device *dev, int rpmflags) || dev->parent->power.runtime_status == RPM_ACTIVE) { atomic_inc(&dev->parent->power.child_count); spin_unlock(&dev->parent->power.lock); - retval = 1; goto no_callback; /* Assume success. */ } spin_unlock(&dev->parent->power.lock); @@ -611,7 +596,7 @@ static int rpm_resume(struct device *dev, int rpmflags) } wake_up_all(&dev->power.wait_queue); - if (retval >= 0) + if (!retval) rpm_idle(dev, RPM_ASYNC); out: @@ -747,8 +732,6 @@ int __pm_runtime_idle(struct device *dev, int rpmflags) unsigned long flags; int retval; - might_sleep_if(!(rpmflags & RPM_ASYNC)); - if (rpmflags & RPM_GET_PUT) { if (!atomic_dec_and_test(&dev->power.usage_count)) return 0; @@ -778,8 +761,6 @@ int __pm_runtime_suspend(struct device *dev, int rpmflags) unsigned long flags; int retval; - might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe); - if (rpmflags & RPM_GET_PUT) { if (!atomic_dec_and_test(&dev->power.usage_count)) return 0; @@ -808,8 +789,6 @@ int __pm_runtime_resume(struct device *dev, int rpmflags) unsigned long flags; int retval; - might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe); - if (rpmflags & RPM_GET_PUT) atomic_inc(&dev->power.usage_count); @@ -999,7 +978,6 @@ EXPORT_SYMBOL_GPL(pm_runtime_barrier); */ void __pm_runtime_disable(struct device *dev, bool check_resume) { - might_sleep(); spin_lock_irq(&dev->power.lock); if (dev->power.disable_depth > 0) { @@ -1206,8 +1184,6 @@ void __pm_runtime_use_autosuspend(struct device *dev, bool use) { int old_delay, old_use; - might_sleep(); - spin_lock_irq(&dev->power.lock); old_delay = dev->power.autosuspend_delay; old_use = dev->power.use_autosuspend; diff --git a/drivers/base/sw_sync.c b/drivers/base/sw_sync.c deleted file mode 100644 index 21ddf4ffd589..000000000000 --- a/drivers/base/sw_sync.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * drivers/base/sw_sync.c - * - * Copyright (C) 2012 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static int sw_sync_cmp(u32 a, u32 b) -{ - if (a == b) - return 0; - - return ((s32)a - (s32)b) < 0 ? -1 : 1; -} - -struct sync_pt *sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value) -{ - struct sw_sync_pt *pt; - - pt = (struct sw_sync_pt *) - sync_pt_create(&obj->obj, sizeof(struct sw_sync_pt)); - - pt->value = value; - - return (struct sync_pt *)pt; -} - -static struct sync_pt *sw_sync_pt_dup(struct sync_pt *sync_pt) -{ - struct sw_sync_pt *pt = (struct sw_sync_pt *) sync_pt; - struct sw_sync_timeline *obj = - (struct sw_sync_timeline *)sync_pt->parent; - - return (struct sync_pt *) sw_sync_pt_create(obj, pt->value); -} - -static int sw_sync_pt_has_signaled(struct sync_pt *sync_pt) -{ - struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt; - struct sw_sync_timeline *obj = - (struct sw_sync_timeline *)sync_pt->parent; - - return sw_sync_cmp(obj->value, pt->value) >= 0; -} - -static int sw_sync_pt_compare(struct sync_pt *a, struct sync_pt *b) -{ - struct sw_sync_pt *pt_a = (struct sw_sync_pt *)a; - struct sw_sync_pt *pt_b = (struct sw_sync_pt *)b; - - return sw_sync_cmp(pt_a->value, pt_b->value); -} - -static void sw_sync_print_obj(struct seq_file *s, - struct sync_timeline *sync_timeline) -{ - struct sw_sync_timeline *obj = (struct sw_sync_timeline *)sync_timeline; - - seq_printf(s, "%d", obj->value); -} - -static void sw_sync_print_pt(struct seq_file *s, struct sync_pt *sync_pt) -{ - struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt; - struct sw_sync_timeline *obj = - (struct sw_sync_timeline *)sync_pt->parent; - - seq_printf(s, "%d / %d", pt->value, obj->value); -} - -static int sw_sync_fill_driver_data(struct sync_pt *sync_pt, - void *data, int size) -{ - struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt; - - if (size < sizeof(pt->value)) - return -ENOMEM; - - memcpy(data, &pt->value, sizeof(pt->value)); - - return sizeof(pt->value); -} - -struct sync_timeline_ops sw_sync_timeline_ops = { - .driver_name = "sw_sync", - .dup = sw_sync_pt_dup, - .has_signaled = sw_sync_pt_has_signaled, - .compare = sw_sync_pt_compare, - .print_obj = sw_sync_print_obj, - .print_pt = sw_sync_print_pt, - .fill_driver_data = sw_sync_fill_driver_data, -}; - - -struct sw_sync_timeline *sw_sync_timeline_create(const char *name) -{ - struct sw_sync_timeline *obj = (struct sw_sync_timeline *) - sync_timeline_create(&sw_sync_timeline_ops, - sizeof(struct sw_sync_timeline), - name); - - return obj; -} - -void sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc) -{ - obj->value += inc; - - sync_timeline_signal(&obj->obj); -} - - -#ifdef CONFIG_SW_SYNC_USER -/* *WARNING* - * - * improper use of this can result in deadlocking kernel drivers from userspace. - */ - -/* opening sw_sync create a new sync obj */ -int sw_sync_open(struct inode *inode, struct file *file) -{ - struct sw_sync_timeline *obj; - char task_comm[TASK_COMM_LEN]; - - get_task_comm(task_comm, current); - - obj = sw_sync_timeline_create(task_comm); - if (obj == NULL) - return -ENOMEM; - - file->private_data = obj; - - return 0; -} - -int sw_sync_release(struct inode *inode, struct file *file) -{ - struct sw_sync_timeline *obj = file->private_data; - sync_timeline_destroy(&obj->obj); - return 0; -} - -long sw_sync_ioctl_create_fence(struct sw_sync_timeline *obj, unsigned long arg) -{ - int fd = get_unused_fd(); - int err; - struct sync_pt *pt; - struct sync_fence *fence; - struct sw_sync_create_fence_data data; - - if (copy_from_user(&data, (void __user *)arg, sizeof(data))) - return -EFAULT; - - pt = sw_sync_pt_create(obj, data.value); - if (pt == NULL) { - err = -ENOMEM; - goto err; - } - - data.name[sizeof(data.name) - 1] = '\0'; - fence = sync_fence_create(data.name, pt); - if (fence == NULL) { - sync_pt_free(pt); - err = -ENOMEM; - goto err; - } - - data.fence = fd; - if (copy_to_user((void __user *)arg, &data, sizeof(data))) { - sync_fence_put(fence); - err = -EFAULT; - goto err; - } - - sync_fence_install(fence, fd); - - return 0; - -err: - put_unused_fd(fd); - return err; -} - -long sw_sync_ioctl_inc(struct sw_sync_timeline *obj, unsigned long arg) -{ - u32 value; - - if (copy_from_user(&value, (void __user *)arg, sizeof(value))) - return -EFAULT; - - sw_sync_timeline_inc(obj, value); - - return 0; -} - -long sw_sync_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct sw_sync_timeline *obj = file->private_data; - - switch (cmd) { - case SW_SYNC_IOC_CREATE_FENCE: - return sw_sync_ioctl_create_fence(obj, arg); - - case SW_SYNC_IOC_INC: - return sw_sync_ioctl_inc(obj, arg); - - default: - return -ENOTTY; - } -} - -static const struct file_operations sw_sync_fops = { - .owner = THIS_MODULE, - .open = sw_sync_open, - .release = sw_sync_release, - .unlocked_ioctl = sw_sync_ioctl, -}; - -static struct miscdevice sw_sync_dev = { - .minor = MISC_DYNAMIC_MINOR, - .name = "sw_sync", - .fops = &sw_sync_fops, -}; - -int __init sw_sync_device_init(void) -{ - return misc_register(&sw_sync_dev); -} - -void __exit sw_sync_device_remove(void) -{ - misc_deregister(&sw_sync_dev); -} - -module_init(sw_sync_device_init); -module_exit(sw_sync_device_remove); - -#endif /* CONFIG_SW_SYNC_USER */ diff --git a/drivers/base/sync.c b/drivers/base/sync.c deleted file mode 100644 index d6913f8e194e..000000000000 --- a/drivers/base/sync.c +++ /dev/null @@ -1,801 +0,0 @@ -/* - * drivers/base/sync.c - * - * Copyright (C) 2012 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static void sync_fence_signal_pt(struct sync_pt *pt); -static int _sync_pt_has_signaled(struct sync_pt *pt); - -static LIST_HEAD(sync_timeline_list_head); -static DEFINE_SPINLOCK(sync_timeline_list_lock); - -static LIST_HEAD(sync_fence_list_head); -static DEFINE_SPINLOCK(sync_fence_list_lock); - -struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops, - int size, const char *name) -{ - struct sync_timeline *obj; - unsigned long flags; - - if (size < sizeof(struct sync_timeline)) - return NULL; - - obj = kzalloc(size, GFP_KERNEL); - if (obj == NULL) - return NULL; - - obj->ops = ops; - strlcpy(obj->name, name, sizeof(obj->name)); - - INIT_LIST_HEAD(&obj->child_list_head); - spin_lock_init(&obj->child_list_lock); - - INIT_LIST_HEAD(&obj->active_list_head); - spin_lock_init(&obj->active_list_lock); - - spin_lock_irqsave(&sync_timeline_list_lock, flags); - list_add_tail(&obj->sync_timeline_list, &sync_timeline_list_head); - spin_unlock_irqrestore(&sync_timeline_list_lock, flags); - - return obj; -} - -static void sync_timeline_free(struct sync_timeline *obj) -{ - unsigned long flags; - - if (obj->ops->release_obj) - obj->ops->release_obj(obj); - - spin_lock_irqsave(&sync_timeline_list_lock, flags); - list_del(&obj->sync_timeline_list); - spin_unlock_irqrestore(&sync_timeline_list_lock, flags); - - kfree(obj); -} - -void sync_timeline_destroy(struct sync_timeline *obj) -{ - unsigned long flags; - bool needs_freeing; - - spin_lock_irqsave(&obj->child_list_lock, flags); - obj->destroyed = true; - needs_freeing = list_empty(&obj->child_list_head); - spin_unlock_irqrestore(&obj->child_list_lock, flags); - - if (needs_freeing) - sync_timeline_free(obj); - else - sync_timeline_signal(obj); -} - -static void sync_timeline_add_pt(struct sync_timeline *obj, struct sync_pt *pt) -{ - unsigned long flags; - - pt->parent = obj; - - spin_lock_irqsave(&obj->child_list_lock, flags); - list_add_tail(&pt->child_list, &obj->child_list_head); - spin_unlock_irqrestore(&obj->child_list_lock, flags); -} - -static void sync_timeline_remove_pt(struct sync_pt *pt) -{ - struct sync_timeline *obj = pt->parent; - unsigned long flags; - bool needs_freeing; - - spin_lock_irqsave(&obj->active_list_lock, flags); - if (!list_empty(&pt->active_list)) - list_del_init(&pt->active_list); - spin_unlock_irqrestore(&obj->active_list_lock, flags); - - spin_lock_irqsave(&obj->child_list_lock, flags); - list_del(&pt->child_list); - needs_freeing = obj->destroyed && list_empty(&obj->child_list_head); - spin_unlock_irqrestore(&obj->child_list_lock, flags); - - if (needs_freeing) - sync_timeline_free(obj); -} - -void sync_timeline_signal(struct sync_timeline *obj) -{ - unsigned long flags; - LIST_HEAD(signaled_pts); - struct list_head *pos, *n; - - spin_lock_irqsave(&obj->active_list_lock, flags); - - list_for_each_safe(pos, n, &obj->active_list_head) { - struct sync_pt *pt = - container_of(pos, struct sync_pt, active_list); - - if (_sync_pt_has_signaled(pt)) - list_move(pos, &signaled_pts); - } - - spin_unlock_irqrestore(&obj->active_list_lock, flags); - - list_for_each_safe(pos, n, &signaled_pts) { - struct sync_pt *pt = - container_of(pos, struct sync_pt, active_list); - - list_del_init(pos); - sync_fence_signal_pt(pt); - } -} - -struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size) -{ - struct sync_pt *pt; - - if (size < sizeof(struct sync_pt)) - return NULL; - - pt = kzalloc(size, GFP_KERNEL); - if (pt == NULL) - return NULL; - - INIT_LIST_HEAD(&pt->active_list); - sync_timeline_add_pt(parent, pt); - - return pt; -} - -void sync_pt_free(struct sync_pt *pt) -{ - if (pt->parent->ops->free_pt) - pt->parent->ops->free_pt(pt); - - sync_timeline_remove_pt(pt); - - kfree(pt); -} - -/* call with pt->parent->active_list_lock held */ -static int _sync_pt_has_signaled(struct sync_pt *pt) -{ - int old_status = pt->status; - - if (!pt->status) - pt->status = pt->parent->ops->has_signaled(pt); - - if (!pt->status && pt->parent->destroyed) - pt->status = -ENOENT; - - if (pt->status != old_status) - pt->timestamp = ktime_get(); - - return pt->status; -} - -static struct sync_pt *sync_pt_dup(struct sync_pt *pt) -{ - return pt->parent->ops->dup(pt); -} - -/* Adds a sync pt to the active queue. Called when added to a fence */ -static void sync_pt_activate(struct sync_pt *pt) -{ - struct sync_timeline *obj = pt->parent; - unsigned long flags; - int err; - - spin_lock_irqsave(&obj->active_list_lock, flags); - - err = _sync_pt_has_signaled(pt); - if (err != 0) - goto out; - - list_add_tail(&pt->active_list, &obj->active_list_head); - -out: - spin_unlock_irqrestore(&obj->active_list_lock, flags); -} - -static int sync_fence_release(struct inode *inode, struct file *file); -static unsigned int sync_fence_poll(struct file *file, poll_table *wait); -static long sync_fence_ioctl(struct file *file, unsigned int cmd, - unsigned long arg); - - -static const struct file_operations sync_fence_fops = { - .release = sync_fence_release, - .poll = sync_fence_poll, - .unlocked_ioctl = sync_fence_ioctl, -}; - -static struct sync_fence *sync_fence_alloc(const char *name) -{ - struct sync_fence *fence; - unsigned long flags; - - fence = kzalloc(sizeof(struct sync_fence), GFP_KERNEL); - if (fence == NULL) - return NULL; - - fence->file = anon_inode_getfile("sync_fence", &sync_fence_fops, - fence, 0); - if (fence->file == NULL) - goto err; - - strlcpy(fence->name, name, sizeof(fence->name)); - - INIT_LIST_HEAD(&fence->pt_list_head); - INIT_LIST_HEAD(&fence->waiter_list_head); - spin_lock_init(&fence->waiter_list_lock); - - init_waitqueue_head(&fence->wq); - - spin_lock_irqsave(&sync_fence_list_lock, flags); - list_add_tail(&fence->sync_fence_list, &sync_fence_list_head); - spin_unlock_irqrestore(&sync_fence_list_lock, flags); - - return fence; - -err: - kfree(fence); - return NULL; -} - -/* TODO: implement a create which takes more that one sync_pt */ -struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt) -{ - struct sync_fence *fence; - - if (pt->fence) - return NULL; - - fence = sync_fence_alloc(name); - if (fence == NULL) - return NULL; - - pt->fence = fence; - list_add(&pt->pt_list, &fence->pt_list_head); - sync_pt_activate(pt); - - return fence; -} - -static int sync_fence_copy_pts(struct sync_fence *dst, struct sync_fence *src) -{ - struct list_head *pos; - - list_for_each(pos, &src->pt_list_head) { - struct sync_pt *orig_pt = - container_of(pos, struct sync_pt, pt_list); - struct sync_pt *new_pt = sync_pt_dup(orig_pt); - - if (new_pt == NULL) - return -ENOMEM; - - new_pt->fence = dst; - list_add(&new_pt->pt_list, &dst->pt_list_head); - sync_pt_activate(new_pt); - } - - return 0; -} - -static void sync_fence_free_pts(struct sync_fence *fence) -{ - struct list_head *pos, *n; - - list_for_each_safe(pos, n, &fence->pt_list_head) { - struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list); - sync_pt_free(pt); - } -} - -struct sync_fence *sync_fence_fdget(int fd) -{ - struct file *file = fget(fd); - - if (file == NULL) - return NULL; - - if (file->f_op != &sync_fence_fops) - goto err; - - return file->private_data; - -err: - fput(file); - return NULL; -} - -void sync_fence_put(struct sync_fence *fence) -{ - fput(fence->file); -} - -void sync_fence_install(struct sync_fence *fence, int fd) -{ - fd_install(fd, fence->file); -} - -static int sync_fence_get_status(struct sync_fence *fence) -{ - struct list_head *pos; - int status = 1; - - list_for_each(pos, &fence->pt_list_head) { - struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list); - int pt_status = pt->status; - - if (pt_status < 0) { - status = pt_status; - break; - } else if (status == 1) { - status = pt_status; - } - } - - return status; -} - -struct sync_fence *sync_fence_merge(const char *name, - struct sync_fence *a, struct sync_fence *b) -{ - struct sync_fence *fence; - int err; - - fence = sync_fence_alloc(name); - if (fence == NULL) - return NULL; - - err = sync_fence_copy_pts(fence, a); - if (err < 0) - goto err; - - err = sync_fence_copy_pts(fence, b); - if (err < 0) - goto err; - - fence->status = sync_fence_get_status(fence); - - return fence; -err: - sync_fence_free_pts(fence); - kfree(fence); - return NULL; -} - -static void sync_fence_signal_pt(struct sync_pt *pt) -{ - LIST_HEAD(signaled_waiters); - struct sync_fence *fence = pt->fence; - struct list_head *pos; - struct list_head *n; - unsigned long flags; - int status; - - status = sync_fence_get_status(fence); - - spin_lock_irqsave(&fence->waiter_list_lock, flags); - /* - * this should protect against two threads racing on the signaled - * false -> true transition - */ - if (status && !fence->status) { - list_for_each_safe(pos, n, &fence->waiter_list_head) - list_move(pos, &signaled_waiters); - - fence->status = status; - } else { - status = 0; - } - spin_unlock_irqrestore(&fence->waiter_list_lock, flags); - - if (status) { - list_for_each_safe(pos, n, &signaled_waiters) { - struct sync_fence_waiter *waiter = - container_of(pos, struct sync_fence_waiter, - waiter_list); - - waiter->callback(fence, waiter->callback_data); - list_del(pos); - kfree(waiter); - } - wake_up(&fence->wq); - } -} - -int sync_fence_wait_async(struct sync_fence *fence, - void (*callback)(struct sync_fence *, void *data), - void *callback_data) -{ - struct sync_fence_waiter *waiter; - unsigned long flags; - int err = 0; - - waiter = kzalloc(sizeof(struct sync_fence_waiter), GFP_KERNEL); - if (waiter == NULL) - return -ENOMEM; - - waiter->callback = callback; - waiter->callback_data = callback_data; - - spin_lock_irqsave(&fence->waiter_list_lock, flags); - - if (fence->status) { - kfree(waiter); - err = fence->status; - goto out; - } - - list_add_tail(&waiter->waiter_list, &fence->waiter_list_head); -out: - spin_unlock_irqrestore(&fence->waiter_list_lock, flags); - - return err; -} - -int sync_fence_wait(struct sync_fence *fence, long timeout) -{ - int err; - - if (timeout) { - timeout = msecs_to_jiffies(timeout); - err = wait_event_interruptible_timeout(fence->wq, - fence->status != 0, - timeout); - } else { - err = wait_event_interruptible(fence->wq, fence->status != 0); - } - - if (err < 0) - return err; - - if (fence->status < 0) - return fence->status; - - if (fence->status == 0) - return -ETIME; - - return 0; -} - -static int sync_fence_release(struct inode *inode, struct file *file) -{ - struct sync_fence *fence = file->private_data; - unsigned long flags; - - sync_fence_free_pts(fence); - - spin_lock_irqsave(&sync_fence_list_lock, flags); - list_del(&fence->sync_fence_list); - spin_unlock_irqrestore(&sync_fence_list_lock, flags); - - kfree(fence); - - return 0; -} - -static unsigned int sync_fence_poll(struct file *file, poll_table *wait) -{ - struct sync_fence *fence = file->private_data; - - poll_wait(file, &fence->wq, wait); - - if (fence->status == 1) - return POLLIN; - else if (fence->status < 0) - return POLLERR; - else - return 0; -} - -static long sync_fence_ioctl_wait(struct sync_fence *fence, unsigned long arg) -{ - __u32 value; - - if (copy_from_user(&value, (void __user *)arg, sizeof(value))) - return -EFAULT; - - return sync_fence_wait(fence, value); -} - -static long sync_fence_ioctl_merge(struct sync_fence *fence, unsigned long arg) -{ - int fd = get_unused_fd(); - int err; - struct sync_fence *fence2, *fence3; - struct sync_merge_data data; - - if (copy_from_user(&data, (void __user *)arg, sizeof(data))) - return -EFAULT; - - fence2 = sync_fence_fdget(data.fd2); - if (fence2 == NULL) { - err = -ENOENT; - goto err_put_fd; - } - - data.name[sizeof(data.name) - 1] = '\0'; - fence3 = sync_fence_merge(data.name, fence, fence2); - if (fence3 == NULL) { - err = -ENOMEM; - goto err_put_fence2; - } - - data.fence = fd; - if (copy_to_user((void __user *)arg, &data, sizeof(data))) { - err = -EFAULT; - goto err_put_fence3; - } - - sync_fence_install(fence3, fd); - sync_fence_put(fence2); - return 0; - -err_put_fence3: - sync_fence_put(fence3); - -err_put_fence2: - sync_fence_put(fence2); - -err_put_fd: - put_unused_fd(fd); - return err; -} - -int sync_fill_pt_info(struct sync_pt *pt, void *data, int size) -{ - struct sync_pt_info *info = data; - int ret; - - if (size < sizeof(struct sync_pt_info)) - return -ENOMEM; - - info->len = sizeof(struct sync_pt_info); - - if (pt->parent->ops->fill_driver_data) { - ret = pt->parent->ops->fill_driver_data(pt, info->driver_data, - size - sizeof(*info)); - if (ret < 0) - return ret; - - info->len += ret; - } - - strlcpy(info->obj_name, pt->parent->name, sizeof(info->obj_name)); - strlcpy(info->driver_name, pt->parent->ops->driver_name, - sizeof(info->driver_name)); - info->status = pt->status; - info->timestamp_ns = ktime_to_ns(pt->timestamp); - - return info->len; -} - - -static long sync_fence_ioctl_fence_info(struct sync_fence *fence, - unsigned long arg) -{ - struct sync_fence_info_data *data; - struct list_head *pos; - __u32 size; - __u32 len = 0; - int ret; - - if (copy_from_user(&size, (void __user *)arg, sizeof(size))) - return -EFAULT; - - if (size < sizeof(struct sync_fence_info_data)) - return -EINVAL; - - if (size > 4096) - size = 4096; - - data = kzalloc(size, GFP_KERNEL); - if (data == NULL) - return -ENOMEM; - - strlcpy(data->name, fence->name, sizeof(data->name)); - data->status = fence->status; - len = sizeof(struct sync_fence_info_data); - - list_for_each(pos, &fence->pt_list_head) { - struct sync_pt *pt = - container_of(pos, struct sync_pt, pt_list); - - ret = sync_fill_pt_info(pt, (u8 *)data + len, size - len); - - if (ret < 0) - goto out; - - len += ret; - } - - data->len = len; - - if (copy_to_user((void __user *)arg, data, len)) - ret = -EFAULT; - else - ret = 0; - -out: - kfree(data); - - return ret; -} - -static long sync_fence_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct sync_fence *fence = file->private_data; - switch (cmd) { - case SYNC_IOC_WAIT: - return sync_fence_ioctl_wait(fence, arg); - - case SYNC_IOC_MERGE: - return sync_fence_ioctl_merge(fence, arg); - - case SYNC_IOC_FENCE_INFO: - return sync_fence_ioctl_fence_info(fence, arg); - - default: - return -ENOTTY; - } -} - -#ifdef CONFIG_DEBUG_FS -static const char *sync_status_str(int status) -{ - if (status > 0) - return "signaled"; - else if (status == 0) - return "active"; - else - return "error"; -} - -static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence) -{ - int status = pt->status; - seq_printf(s, " %s%spt %s", - fence ? pt->parent->name : "", - fence ? "_" : "", - sync_status_str(status)); - if (pt->status) { - struct timeval tv = ktime_to_timeval(pt->timestamp); - seq_printf(s, "@%ld.%06ld", tv.tv_sec, tv.tv_usec); - } - - if (pt->parent->ops->print_pt) { - seq_printf(s, ": "); - pt->parent->ops->print_pt(s, pt); - } - - seq_printf(s, "\n"); -} - -static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj) -{ - struct list_head *pos; - unsigned long flags; - - seq_printf(s, "%s %s", obj->name, obj->ops->driver_name); - - if (obj->ops->print_obj) { - seq_printf(s, ": "); - obj->ops->print_obj(s, obj); - } - - seq_printf(s, "\n"); - - spin_lock_irqsave(&obj->child_list_lock, flags); - list_for_each(pos, &obj->child_list_head) { - struct sync_pt *pt = - container_of(pos, struct sync_pt, child_list); - sync_print_pt(s, pt, false); - } - spin_unlock_irqrestore(&obj->child_list_lock, flags); -} - -static void sync_print_fence(struct seq_file *s, struct sync_fence *fence) -{ - struct list_head *pos; - unsigned long flags; - - seq_printf(s, "%s: %s\n", fence->name, sync_status_str(fence->status)); - - list_for_each(pos, &fence->pt_list_head) { - struct sync_pt *pt = - container_of(pos, struct sync_pt, pt_list); - sync_print_pt(s, pt, true); - } - - spin_lock_irqsave(&fence->waiter_list_lock, flags); - list_for_each(pos, &fence->waiter_list_head) { - struct sync_fence_waiter *waiter = - container_of(pos, struct sync_fence_waiter, - waiter_list); - - seq_printf(s, "waiter %pF %p\n", waiter->callback, - waiter->callback_data); - } - spin_unlock_irqrestore(&fence->waiter_list_lock, flags); -} - -static int sync_debugfs_show(struct seq_file *s, void *unused) -{ - unsigned long flags; - struct list_head *pos; - - seq_printf(s, "objs:\n--------------\n"); - - spin_lock_irqsave(&sync_timeline_list_lock, flags); - list_for_each(pos, &sync_timeline_list_head) { - struct sync_timeline *obj = - container_of(pos, struct sync_timeline, - sync_timeline_list); - - sync_print_obj(s, obj); - seq_printf(s, "\n"); - } - spin_unlock_irqrestore(&sync_timeline_list_lock, flags); - - seq_printf(s, "fences:\n--------------\n"); - - spin_lock_irqsave(&sync_fence_list_lock, flags); - list_for_each(pos, &sync_fence_list_head) { - struct sync_fence *fence = - container_of(pos, struct sync_fence, sync_fence_list); - - sync_print_fence(s, fence); - seq_printf(s, "\n"); - } - spin_unlock_irqrestore(&sync_fence_list_lock, flags); - return 0; -} - -static int sync_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, sync_debugfs_show, inode->i_private); -} - -static const struct file_operations sync_debugfs_fops = { - .open = sync_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static __init int sync_debugfs_init(void) -{ - debugfs_create_file("sync", S_IRUGO, NULL, NULL, &sync_debugfs_fops); - return 0; -} - -late_initcall(sync_debugfs_init); - -#endif diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index a9cb23845cfc..be52344ed19d 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -110,10 +110,9 @@ static int bcma_register_cores(struct bcma_bus *bus) static void bcma_unregister_cores(struct bcma_bus *bus) { - struct bcma_device *core, *tmp; + struct bcma_device *core; - list_for_each_entry_safe(core, tmp, &bus->cores, list) { - list_del(&core->list); + list_for_each_entry(core, &bus->cores, list) { if (core->dev_registered) device_unregister(&core->dev); } diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 8db9089127c5..e086fbbbe853 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -1177,8 +1177,7 @@ static bool DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T int TimeoutCounter; int i; - memset(&CommandMailbox, 0, sizeof(DAC960_V1_CommandMailbox_T)); - + if (pci_set_dma_mask(Controller->PCIDevice, DMA_BIT_MASK(32))) return DAC960_Failure(Controller, "DMA mask out of range"); Controller->BounceBufferLimit = DMA_BIT_MASK(32); @@ -4628,8 +4627,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) DAC960_Controller_T *Controller = Command->Controller; DAC960_CommandType_T CommandType = Command->CommandType; DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; - DAC960_V2_IOCTL_Opcode_T IOCTLOpcode = CommandMailbox->Common.IOCTL_Opcode; - DAC960_V2_CommandOpcode_T CommandOpcode = CommandMailbox->SCSI_10.CommandOpcode; + DAC960_V2_IOCTL_Opcode_T CommandOpcode = CommandMailbox->Common.IOCTL_Opcode; DAC960_V2_CommandStatus_T CommandStatus = Command->V2.CommandStatus; if (CommandType == DAC960_ReadCommand || @@ -4701,7 +4699,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) { if (Controller->ShutdownMonitoringTimer) return; - if (IOCTLOpcode == DAC960_V2_GetControllerInfo) + if (CommandOpcode == DAC960_V2_GetControllerInfo) { DAC960_V2_ControllerInfo_T *NewControllerInfo = Controller->V2.NewControllerInformation; @@ -4721,14 +4719,14 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) memcpy(ControllerInfo, NewControllerInfo, sizeof(DAC960_V2_ControllerInfo_T)); } - else if (IOCTLOpcode == DAC960_V2_GetEvent) + else if (CommandOpcode == DAC960_V2_GetEvent) { if (CommandStatus == DAC960_V2_NormalCompletion) { DAC960_V2_ReportEvent(Controller, Controller->V2.Event); } Controller->V2.NextEventSequenceNumber++; } - else if (IOCTLOpcode == DAC960_V2_GetPhysicalDeviceInfoValid && + else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid && CommandStatus == DAC960_V2_NormalCompletion) { DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo = @@ -4917,7 +4915,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) NewPhysicalDeviceInfo->LogicalUnit++; Controller->V2.PhysicalDeviceIndex++; } - else if (IOCTLOpcode == DAC960_V2_GetPhysicalDeviceInfoValid) + else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid) { unsigned int DeviceIndex; for (DeviceIndex = Controller->V2.PhysicalDeviceIndex; @@ -4940,7 +4938,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) } Controller->V2.NeedPhysicalDeviceInformation = false; } - else if (IOCTLOpcode == DAC960_V2_GetLogicalDeviceInfoValid && + else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid && CommandStatus == DAC960_V2_NormalCompletion) { DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo = @@ -5067,7 +5065,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) [LogicalDeviceNumber] = true; NewLogicalDeviceInfo->LogicalDeviceNumber++; } - else if (IOCTLOpcode == DAC960_V2_GetLogicalDeviceInfoValid) + else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid) { int LogicalDriveNumber; for (LogicalDriveNumber = 0; diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h index e49ddd0aea12..db195abad698 100644 --- a/drivers/block/aoe/aoe.h +++ b/drivers/block/aoe/aoe.h @@ -1,5 +1,5 @@ /* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */ -#define VERSION "47q" +#define VERSION "47" #define AOE_MAJOR 152 #define DEVICE_NAME "aoe" diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index 2a0fdaeefcda..528f6318ded1 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c @@ -277,6 +277,8 @@ aoeblk_gdalloc(void *vp) goto err_mempool; blk_queue_make_request(d->blkq, aoeblk_make_request); d->blkq->backing_dev_info.name = "aoe"; + if (bdi_init(&d->blkq->backing_dev_info)) + goto err_blkq; spin_lock_irqsave(&d->lock, flags); gd->major = AOE_MAJOR; gd->first_minor = d->sysminor * AOE_PARTITIONS; @@ -297,6 +299,9 @@ aoeblk_gdalloc(void *vp) aoedisk_add_sysfs(d); return; +err_blkq: + blk_cleanup_queue(d->blkq); + d->blkq = NULL; err_mempool: mempool_destroy(d->bufpool); err_disk: diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 887f68f6d79a..de0435e63b02 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -35,7 +35,6 @@ new_skb(ulong len) skb_reset_mac_header(skb); skb_reset_network_header(skb); skb->protocol = __constant_htons(ETH_P_AOE); - skb_checksum_none_assert(skb); } return skb; } diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 1dab802d82b9..8f4ef656a1af 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1716,7 +1716,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, case CCISS_BIG_PASSTHRU: return cciss_bigpassthru(h, argp); - /* scsi_cmd_blk_ioctl handles these, below, though some are not */ + /* scsi_cmd_ioctl handles these, below, though some are not */ /* very meaningful for cciss. SG_IO is the main one people want. */ case SG_GET_VERSION_NUM: @@ -1727,9 +1727,9 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, case SG_EMULATED_HOST: case SG_IO: case SCSI_IOCTL_SEND_COMMAND: - return scsi_cmd_blk_ioctl(bdev, mode, cmd, argp); + return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp); - /* scsi_cmd_blk_ioctl would normally handle these, below, but */ + /* scsi_cmd_ioctl would normally handle these, below, but */ /* they aren't a good fit for cciss, as CD-ROMs are */ /* not supported, and we don't have any bus/target/lun */ /* which we present to the kernel. */ @@ -4533,13 +4533,6 @@ static int cciss_controller_hard_reset(struct pci_dev *pdev, pmcsr &= ~PCI_PM_CTRL_STATE_MASK; pmcsr |= PCI_D0; pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); - - /* - * The P600 requires a small delay when changing states. - * Otherwise we may think the board did not reset and we bail. - * This for kdump only and is particular to the P600. - */ - msleep(500); } return 0; } diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index c049548e68b7..16b4d58d84dd 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h @@ -223,7 +223,7 @@ static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c) h->ctlr, c->busaddr); #endif /* CCISS_DEBUG */ writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); - readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); + readl(h->vaddr + SA5_REQUEST_PORT_OFFSET); h->commands_outstanding++; if ( h->commands_outstanding > h->max_outstanding) h->max_outstanding = h->commands_outstanding; diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index f01b3507e5bc..696100241a6f 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -763,7 +763,16 @@ static void complete_scsi_command(CommandList_struct *c, int timeout, { case CMD_TARGET_STATUS: /* Pass it up to the upper layers... */ - if (!ei->ScsiStatus) { + if( ei->ScsiStatus) + { +#if 0 + printk(KERN_WARNING "cciss: cmd %p " + "has SCSI Status = %x\n", + c, ei->ScsiStatus); +#endif + cmd->result |= (ei->ScsiStatus << 1); + } + else { /* scsi status is zero??? How??? */ /* Ordinarily, this case should never happen, but there is a bug in some released firmware revisions that allows it to happen @@ -795,7 +804,6 @@ static void complete_scsi_command(CommandList_struct *c, int timeout, } break; case CMD_PROTOCOL_ERR: - cmd->result = DID_ERROR << 16; dev_warn(&h->pdev->dev, "%p has protocol error\n", c); break; @@ -858,7 +866,6 @@ cciss_scsi_detect(ctlr_info_t *h) sh->can_queue = cciss_tape_cmds; sh->sg_tablesize = h->maxsgentries; sh->max_cmd_len = MAX_COMMAND_SIZE; - sh->max_sectors = h->cciss_max_sectors; ((struct cciss_scsi_adapter_data_t *) h->scsi_ctlr)->scsi_host = sh; @@ -1403,7 +1410,7 @@ static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *c, /* track how many SG entries we are using */ if (request_nsgs > h->maxSG) h->maxSG = request_nsgs; - c->Header.SGTotal = (u16) request_nsgs + chained; + c->Header.SGTotal = (__u8) request_nsgs + chained; if (request_nsgs > h->max_cmd_sgentries) c->Header.SGList = h->max_cmd_sgentries; else diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index e59f53679d6f..3424d675b769 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -37,7 +37,6 @@ static void _drbd_start_io_acct(struct drbd_conf *mdev, struct drbd_request *req const int rw = bio_data_dir(bio); int cpu; cpu = part_stat_lock(); - part_round_stats(cpu, &mdev->vdisk->part0); part_stat_inc(cpu, &mdev->vdisk->part0, ios[rw]); part_stat_add(cpu, &mdev->vdisk->part0, sectors[rw], bio_sectors(bio)); part_inc_in_flight(&mdev->vdisk->part0, rw); diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 215ddc8261c9..98de8f418676 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -1032,6 +1032,37 @@ static int fd_wait_for_completion(unsigned long delay, timeout_fn function) return 0; } +static DEFINE_SPINLOCK(floppy_hlt_lock); +static int hlt_disabled; +static void floppy_disable_hlt(void) +{ + unsigned long flags; + + WARN_ONCE(1, "floppy_disable_hlt() scheduled for removal in 2012"); + spin_lock_irqsave(&floppy_hlt_lock, flags); + if (!hlt_disabled) { + hlt_disabled = 1; +#ifdef HAVE_DISABLE_HLT + disable_hlt(); +#endif + } + spin_unlock_irqrestore(&floppy_hlt_lock, flags); +} + +static void floppy_enable_hlt(void) +{ + unsigned long flags; + + spin_lock_irqsave(&floppy_hlt_lock, flags); + if (hlt_disabled) { + hlt_disabled = 0; +#ifdef HAVE_DISABLE_HLT + enable_hlt(); +#endif + } + spin_unlock_irqrestore(&floppy_hlt_lock, flags); +} + static void setup_DMA(void) { unsigned long f; @@ -1076,6 +1107,7 @@ static void setup_DMA(void) fd_enable_dma(); release_dma_lock(f); #endif + floppy_disable_hlt(); } static void show_floppy(void); @@ -1677,6 +1709,7 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id) fd_disable_dma(); release_dma_lock(f); + floppy_enable_hlt(); do_floppy = NULL; if (fdc >= N_FDC || FDCS->address == -1) { /* we don't even know which FDC is the culprit */ @@ -1825,6 +1858,8 @@ static void floppy_shutdown(unsigned long data) show_floppy(); cancel_activity(); + floppy_enable_hlt(); + flags = claim_dma_lock(); fd_disable_dma(); release_dma_lock(flags); @@ -4163,7 +4198,6 @@ static int __init floppy_init(void) disks[dr]->queue = blk_init_queue(do_fd_request, &floppy_lock); if (!disks[dr]->queue) { - put_disk(disks[dr]); err = -ENOMEM; goto out_put_disk; } @@ -4216,7 +4250,7 @@ static int __init floppy_init(void) use_virtual_dma = can_use_virtual_dma & 1; fdc_state[0].address = FDC1; if (fdc_state[0].address == -1) { - del_timer_sync(&fd_timeout); + del_timer(&fd_timeout); err = -ENODEV; goto out_unreg_region; } @@ -4227,7 +4261,7 @@ static int __init floppy_init(void) fdc = 0; /* reset fdc in case of unexpected interrupt */ err = floppy_grab_irq_and_dma(); if (err) { - del_timer_sync(&fd_timeout); + del_timer(&fd_timeout); err = -EBUSY; goto out_unreg_region; } @@ -4284,7 +4318,7 @@ static int __init floppy_init(void) user_reset_fdc(-1, FD_RESET_ALWAYS, false); } fdc = 0; - del_timer_sync(&fd_timeout); + del_timer(&fd_timeout); current_drive = 0; initialized = true; if (have_no_fdc) { @@ -4334,7 +4368,7 @@ out_unreg_blkdev: unregister_blkdev(FLOPPY_MAJOR, "fd"); out_put_disk: while (dr--) { - del_timer_sync(&motor_off_timer[dr]); + del_timer(&motor_off_timer[dr]); if (disks[dr]->queue) blk_cleanup_queue(disks[dr]->queue); put_disk(disks[dr]); @@ -4470,6 +4504,7 @@ static void floppy_release_irq_and_dma(void) #if N_FDC > 1 set_dor(1, ~8, 0); #endif + floppy_enable_hlt(); if (floppy_track_buffer && max_buffer_sectors) { tmpsize = max_buffer_sectors * 1024; diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 2ebacf0e1edb..76c8da78212b 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -750,10 +750,10 @@ static ssize_t loop_attr_backing_file_show(struct loop_device *lo, char *buf) ssize_t ret; char *p = NULL; - spin_lock_irq(&lo->lo_lock); + mutex_lock(&lo->lo_ctl_mutex); if (lo->lo_backing_file) p = d_path(&lo->lo_backing_file->f_path, buf, PAGE_SIZE - 1); - spin_unlock_irq(&lo->lo_lock); + mutex_unlock(&lo->lo_ctl_mutex); if (IS_ERR_OR_NULL(p)) ret = PTR_ERR(p); @@ -1007,9 +1007,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) kthread_stop(lo->lo_thread); - spin_lock_irq(&lo->lo_lock); lo->lo_backing_file = NULL; - spin_unlock_irq(&lo->lo_lock); loop_release_xfer(lo); lo->transfer = NULL; diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index eec7b7a43cba..b70f0fca9a42 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c @@ -1116,7 +1116,7 @@ static inline void carm_handle_resp(struct carm_host *host, break; case MISC_GET_FW_VER: { struct carm_fw_ver *ver = (struct carm_fw_ver *) - (mem + sizeof(struct carm_msg_get_fw_ver)); + mem + sizeof(struct carm_msg_get_fw_ver); if (!error) { host->fw_ver = le32_to_cpu(ver->version); host->flags |= (ver->features & FL_FW_VER_MASK); diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 7333b9e44411..0e376d46bdd1 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -1744,11 +1744,12 @@ static int ub_bd_release(struct gendisk *disk, fmode_t mode) static int ub_bd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { + struct gendisk *disk = bdev->bd_disk; void __user *usermem = (void __user *) arg; int ret; mutex_lock(&ub_mutex); - ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, usermem); + ret = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, usermem); mutex_unlock(&ub_mutex); return ret; diff --git a/drivers/block/umem.c b/drivers/block/umem.c index afa8463b2be7..031ca720d926 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c @@ -513,44 +513,6 @@ static void process_page(unsigned long data) } } -struct mm_plug_cb { - struct blk_plug_cb cb; - struct cardinfo *card; -}; - -static void mm_unplug(struct blk_plug_cb *cb) -{ - struct mm_plug_cb *mmcb = container_of(cb, struct mm_plug_cb, cb); - - spin_lock_irq(&mmcb->card->lock); - activate(mmcb->card); - spin_unlock_irq(&mmcb->card->lock); - kfree(mmcb); -} - -static int mm_check_plugged(struct cardinfo *card) -{ - struct blk_plug *plug = current->plug; - struct mm_plug_cb *mmcb; - - if (!plug) - return 0; - - list_for_each_entry(mmcb, &plug->cb_list, cb.list) { - if (mmcb->cb.callback == mm_unplug && mmcb->card == card) - return 1; - } - /* Not currently on the callback list */ - mmcb = kmalloc(sizeof(*mmcb), GFP_ATOMIC); - if (!mmcb) - return 0; - - mmcb->card = card; - mmcb->cb.callback = mm_unplug; - list_add(&mmcb->cb.list, &plug->cb_list); - return 1; -} - static int mm_make_request(struct request_queue *q, struct bio *bio) { struct cardinfo *card = q->queuedata; @@ -561,8 +523,6 @@ static int mm_make_request(struct request_queue *q, struct bio *bio) *card->biotail = bio; bio->bi_next = NULL; card->biotail = &bio->bi_next; - if (bio->bi_rw & REQ_SYNC || !mm_check_plugged(card)) - activate(card); spin_unlock_irq(&card->lock); return 0; diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 5d7a93403632..079c08808d8a 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -236,8 +236,8 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI)) return -ENOTTY; - return scsi_cmd_blk_ioctl(bdev, mode, cmd, - (void __user *)data); + return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, + (void __user *)data); } /* We provide getgeo only to please some old bootloader/partitioning tools */ diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 54139d0f5fec..5cf2993a8338 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -667,7 +667,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, if (operation == READ) blkif->st_rd_sect += preq.nr_sects; - else if (operation & WRITE) + else if (operation == WRITE || operation == WRITE_FLUSH) blkif->st_wr_sect += preq.nr_sects; return 0; diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 9ea8c2576c70..b536a9cef917 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -123,8 +123,8 @@ static DEFINE_SPINLOCK(minor_lock); #define BLKIF_MINOR_EXT(dev) ((dev)&(~EXTENDED)) #define EMULATED_HD_DISK_MINOR_OFFSET (0) #define EMULATED_HD_DISK_NAME_OFFSET (EMULATED_HD_DISK_MINOR_OFFSET / 256) -#define EMULATED_SD_DISK_MINOR_OFFSET (0) -#define EMULATED_SD_DISK_NAME_OFFSET (EMULATED_SD_DISK_MINOR_OFFSET / 256) +#define EMULATED_SD_DISK_MINOR_OFFSET (EMULATED_HD_DISK_MINOR_OFFSET + (4 * 16)) +#define EMULATED_SD_DISK_NAME_OFFSET (EMULATED_HD_DISK_NAME_OFFSET + 4) #define DEV_NAME "xvd" /* name in /dev */ @@ -529,7 +529,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, minor = BLKIF_MINOR_EXT(info->vdevice); nr_parts = PARTS_PER_EXT_DISK; offset = minor / nr_parts; - if (xen_hvm_domain() && offset < EMULATED_HD_DISK_NAME_OFFSET + 4) + if (xen_hvm_domain() && offset <= EMULATED_HD_DISK_NAME_OFFSET + 4) printk(KERN_WARNING "blkfront: vdevice 0x%x might conflict with " "emulated IDE disks,\n\t choose an xvd device name" "from xvde on\n", info->vdevice); diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 85e1ad66d037..6bacef368fab 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -63,25 +63,16 @@ static struct usb_device_id ath3k_table[] = { /* Atheros AR3011 with sflash firmware*/ { USB_DEVICE(0x0CF3, 0x3002) }, { USB_DEVICE(0x13d3, 0x3304) }, - { USB_DEVICE(0x0930, 0x0215) }, - { USB_DEVICE(0x0489, 0xE03D) }, - { USB_DEVICE(0x0489, 0xE027) }, /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03F0, 0x311D) }, /* Atheros AR3012 with sflash firmware*/ { USB_DEVICE(0x0CF3, 0x3004) }, - { USB_DEVICE(0x0CF3, 0x311D) }, - { USB_DEVICE(0x13d3, 0x3375) }, - { USB_DEVICE(0x04CA, 0x3005) }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xE02C) }, - /* Atheros AR5BBU22 with sflash firmware */ - { USB_DEVICE(0x0489, 0xE03C) }, - { } /* Terminating entry */ }; @@ -94,12 +85,6 @@ static struct usb_device_id ath3k_blist_tbl[] = { /* Atheros AR3012 with sflash firmware*/ { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, - - /* Atheros AR5BBU22 with sflash firmware */ - { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, { } /* Terminating entry */ }; @@ -390,11 +375,6 @@ static int ath3k_probe(struct usb_interface *intf, /* load patch and sysconfig files for AR3012 */ if (id->driver_info & BTUSB_ATH3012) { - - /* New firmware with patch and sysconfig files already loaded */ - if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x0001) - return -ENODEV; - ret = ath3k_load_patch(udev); if (ret < 0) { BT_ERR("Loading patch file failed"); diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 4b764f86daaf..c2de8951e3fb 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -54,18 +54,11 @@ static struct usb_driver btusb_driver; #define BTUSB_BCM92035 0x10 #define BTUSB_BROKEN_ISOC 0x20 #define BTUSB_WRONG_SCO_MTU 0x40 -#define BTUSB_ATH3012 0x80 static struct usb_device_id btusb_table[] = { /* Generic Bluetooth USB device */ { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, - /* Apple-specific (Broadcom) devices */ - { USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01) }, - - /* Broadcom SoftSailing reporting vendor specific */ - { USB_DEVICE(0x0a5c, 0x21e1) }, - /* Apple MacBookPro 7,1 */ { USB_DEVICE(0x05ac, 0x8213) }, @@ -78,15 +71,9 @@ static struct usb_device_id btusb_table[] = { /* Apple MacBookAir3,1, MacBookAir3,2 */ { USB_DEVICE(0x05ac, 0x821b) }, - /* Apple MacBookAir4,1 */ - { USB_DEVICE(0x05ac, 0x821f) }, - /* Apple MacBookPro8,2 */ { USB_DEVICE(0x05ac, 0x821a) }, - /* Apple MacMini5,1 */ - { USB_DEVICE(0x05ac, 0x8281) }, - /* AVM BlueFRITZ! USB v2.0 */ { USB_DEVICE(0x057c, 0x3800) }, @@ -103,16 +90,6 @@ static struct usb_device_id btusb_table[] = { /* Canyon CN-BTU1 with HID interfaces */ { USB_DEVICE(0x0c10, 0x0000) }, - /* Broadcom BCM20702A0 */ - { USB_DEVICE(0x0489, 0xe042) }, - { USB_DEVICE(0x413c, 0x8197) }, - - /* Foxconn - Hon Hai */ - { USB_DEVICE(0x0489, 0xe033) }, - - /*Broadcom devices with vendor specific id */ - { USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) }, - { } /* Terminating entry */ }; @@ -128,25 +105,16 @@ static struct usb_device_id blacklist_table[] = { /* Atheros 3011 with sflash firmware */ { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, - { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, - { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, - { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE }, /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, /* Atheros 3012 with sflash firmware */ - { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_IGNORE }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, - /* Atheros AR5BBU12 with sflash firmware */ - { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, - /* Broadcom BCM2035 */ { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, @@ -518,10 +486,15 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags) pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress); - usb_fill_int_urb(urb, data->udev, pipe, buf, size, btusb_isoc_complete, - hdev, data->isoc_rx_ep->bInterval); + urb->dev = data->udev; + urb->pipe = pipe; + urb->context = hdev; + urb->complete = btusb_isoc_complete; + urb->interval = data->isoc_rx_ep->bInterval; urb->transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP; + urb->transfer_buffer = buf; + urb->transfer_buffer_length = size; __fill_isoc_descriptor(urb, size, le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize)); @@ -941,15 +914,6 @@ static int btusb_probe(struct usb_interface *intf, if (ignore_sniffer && id->driver_info & BTUSB_SNIFFER) return -ENODEV; - if (id->driver_info & BTUSB_ATH3012) { - struct usb_device *udev = interface_to_usbdev(intf); - - /* Old firmware would otherwise let ath3k driver load - * patch and sysconfig files */ - if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001) - return -ENODEV; - } - data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 8f3d6dbeb122..48ad2a7ab080 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -237,6 +237,7 @@ static void hci_uart_destruct(struct hci_dev *hdev) return; BT_DBG("%s", hdev->name); + kfree(hdev->driver_data); } /* ------ LDISC part ------ */ @@ -309,13 +310,12 @@ static void hci_uart_tty_close(struct tty_struct *tty) hci_uart_close(hdev); if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) { + hu->proto->close(hu); if (hdev) { hci_unregister_dev(hdev); hci_free_dev(hdev); } - hu->proto->close(hu); } - kfree(hu); } } diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index cc6471aa9f46..75fb965b8f72 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -2114,6 +2114,11 @@ static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf, if (!nr) return -ENOMEM; + if (!access_ok(VERIFY_WRITE, ubuf, nframes * CD_FRAMESIZE_RAW)) { + ret = -EFAULT; + goto out; + } + cgc.data_direction = CGC_DATA_READ; while (nframes > 0) { if (nr > nframes) @@ -2122,7 +2127,7 @@ static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf, ret = cdrom_read_block(cdi, &cgc, lba, nr, 1, CD_FRAMESIZE_RAW); if (ret) break; - if (copy_to_user(ubuf, cgc.buffer, CD_FRAMESIZE_RAW * nr)) { + if (__copy_to_user(ubuf, cgc.buffer, CD_FRAMESIZE_RAW * nr)) { ret = -EFAULT; break; } @@ -2130,6 +2135,7 @@ static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf, nframes -= nr; lba += nr; } +out: kfree(cgc.buffer); return ret; } @@ -2735,11 +2741,12 @@ int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev, { void __user *argp = (void __user *)arg; int ret; + struct gendisk *disk = bdev->bd_disk; /* * Try the generic SCSI command ioctl's first. */ - ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp); + ret = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp); if (ret != -ENOTTY) return ret; diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 7d10ae3de25e..49502bc5360a 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -6,19 +6,6 @@ menu "Character devices" source "drivers/tty/Kconfig" -config DEVMEM - bool "Memory device driver" - default y - help - The memory driver provides two character devices, mem and kmem, which - provide access to the system's memory. The mem device is a view of - physical memory, and each byte in the device corresponds to the - matching physical address. The kmem device is the same as mem, but - the addresses correspond to the kernel's virtual address space rather - than physical memory. These devices are standard parts of a Linux - system and most users should say Y here. You might say N if very - security conscience or memory is tight. - config DEVKMEM bool "/dev/kmem virtual device support" default y @@ -611,10 +598,6 @@ config DEVPORT depends on ISA || PCI default y -config DCC_TTY - tristate "DCC tty driver" - depends on ARM - source "drivers/s390/char/Kconfig" config RAMOOPS diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 3f63254bbbda..7a00672bd85d 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -58,7 +58,6 @@ obj-$(CONFIG_IPMI_HANDLER) += ipmi/ obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o obj-$(CONFIG_TCG_TPM) += tpm/ -obj-$(CONFIG_DCC_TTY) += dcc_tty.o obj-$(CONFIG_PS3_FLASH) += ps3flash.o obj-$(CONFIG_RAMOOPS) += ramoops.o diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 58b49d1a283b..b427711be4be 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -897,7 +897,6 @@ static struct pci_device_id agp_intel_pci_table[] = { ID(PCI_DEVICE_ID_INTEL_B43_HB), ID(PCI_DEVICE_ID_INTEL_B43_1_HB), ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB), - ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D2_HB), ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB), ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB), ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB), diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index 6f246049d5b4..5da67f165afa 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h @@ -211,7 +211,6 @@ #define PCI_DEVICE_ID_INTEL_G41_HB 0x2E30 #define PCI_DEVICE_ID_INTEL_G41_IG 0x2E32 #define PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB 0x0040 -#define PCI_DEVICE_ID_INTEL_IRONLAKE_D2_HB 0x0069 #define PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG 0x0042 #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB 0x0044 #define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB 0x0062 diff --git a/drivers/char/dcc_tty.c b/drivers/char/dcc_tty.c deleted file mode 100644 index a787accdcb14..000000000000 --- a/drivers/char/dcc_tty.c +++ /dev/null @@ -1,326 +0,0 @@ -/* drivers/char/dcc_tty.c - * - * Copyright (C) 2007 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_DESCRIPTION("DCC TTY Driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION("1.0"); - -static spinlock_t g_dcc_tty_lock = SPIN_LOCK_UNLOCKED; -static struct hrtimer g_dcc_timer; -static char g_dcc_buffer[16]; -static int g_dcc_buffer_head; -static int g_dcc_buffer_count; -static unsigned g_dcc_write_delay_usecs = 1; -static struct tty_driver *g_dcc_tty_driver; -static struct tty_struct *g_dcc_tty; -static int g_dcc_tty_open_count; - -static void dcc_poll_locked(void) -{ - char ch; - int rch; - int written; - - while (g_dcc_buffer_count) { - ch = g_dcc_buffer[g_dcc_buffer_head]; - asm( - "mrc 14, 0, r15, c0, c1, 0\n" - "mcrcc 14, 0, %1, c0, c5, 0\n" - "movcc %0, #1\n" - "movcs %0, #0\n" - : "=r" (written) - : "r" (ch) - ); - if (written) { - if (ch == '\n') - g_dcc_buffer[g_dcc_buffer_head] = '\r'; - else { - g_dcc_buffer_head = (g_dcc_buffer_head + 1) % ARRAY_SIZE(g_dcc_buffer); - g_dcc_buffer_count--; - if (g_dcc_tty) - tty_wakeup(g_dcc_tty); - } - g_dcc_write_delay_usecs = 1; - } else { - if (g_dcc_write_delay_usecs > 0x100) - break; - g_dcc_write_delay_usecs <<= 1; - udelay(g_dcc_write_delay_usecs); - } - } - - if (g_dcc_tty && !test_bit(TTY_THROTTLED, &g_dcc_tty->flags)) { - asm( - "mrc 14, 0, %0, c0, c1, 0\n" - "tst %0, #(1 << 30)\n" - "moveq %0, #-1\n" - "mrcne 14, 0, %0, c0, c5, 0\n" - : "=r" (rch) - ); - if (rch >= 0) { - ch = rch; - tty_insert_flip_string(g_dcc_tty, &ch, 1); - tty_flip_buffer_push(g_dcc_tty); - } - } - - - if (g_dcc_buffer_count) - hrtimer_start(&g_dcc_timer, ktime_set(0, g_dcc_write_delay_usecs * NSEC_PER_USEC), HRTIMER_MODE_REL); - else - hrtimer_start(&g_dcc_timer, ktime_set(0, 20 * NSEC_PER_MSEC), HRTIMER_MODE_REL); -} - -static int dcc_tty_open(struct tty_struct * tty, struct file * filp) -{ - int ret; - unsigned long irq_flags; - - spin_lock_irqsave(&g_dcc_tty_lock, irq_flags); - if (g_dcc_tty == NULL || g_dcc_tty == tty) { - g_dcc_tty = tty; - g_dcc_tty_open_count++; - ret = 0; - } else - ret = -EBUSY; - spin_unlock_irqrestore(&g_dcc_tty_lock, irq_flags); - - printk("dcc_tty_open, tty %p, f_flags %x, returned %d\n", tty, filp->f_flags, ret); - - return ret; -} - -static void dcc_tty_close(struct tty_struct * tty, struct file * filp) -{ - printk("dcc_tty_close, tty %p, f_flags %x\n", tty, filp->f_flags); - if (g_dcc_tty == tty) { - if (--g_dcc_tty_open_count == 0) - g_dcc_tty = NULL; - } -} - -static int dcc_write(const unsigned char *buf_start, int count) -{ - const unsigned char *buf = buf_start; - unsigned long irq_flags; - int copy_len; - int space_left; - int tail; - - if (count < 1) - return 0; - - spin_lock_irqsave(&g_dcc_tty_lock, irq_flags); - do { - tail = (g_dcc_buffer_head + g_dcc_buffer_count) % ARRAY_SIZE(g_dcc_buffer); - copy_len = ARRAY_SIZE(g_dcc_buffer) - tail; - space_left = ARRAY_SIZE(g_dcc_buffer) - g_dcc_buffer_count; - if (copy_len > space_left) - copy_len = space_left; - if (copy_len > count) - copy_len = count; - memcpy(&g_dcc_buffer[tail], buf, copy_len); - g_dcc_buffer_count += copy_len; - buf += copy_len; - count -= copy_len; - if (copy_len < count && copy_len < space_left) { - space_left -= copy_len; - copy_len = count; - if (copy_len > space_left) { - copy_len = space_left; - } - memcpy(g_dcc_buffer, buf, copy_len); - buf += copy_len; - count -= copy_len; - g_dcc_buffer_count += copy_len; - } - dcc_poll_locked(); - space_left = ARRAY_SIZE(g_dcc_buffer) - g_dcc_buffer_count; - } while(count && space_left); - spin_unlock_irqrestore(&g_dcc_tty_lock, irq_flags); - return buf - buf_start; -} - -static int dcc_tty_write(struct tty_struct * tty, const unsigned char *buf, int count) -{ - int ret; - /* printk("dcc_tty_write %p, %d\n", buf, count); */ - ret = dcc_write(buf, count); - if (ret != count) - printk("dcc_tty_write %p, %d, returned %d\n", buf, count, ret); - return ret; -} - -static int dcc_tty_write_room(struct tty_struct *tty) -{ - int space_left; - unsigned long irq_flags; - - spin_lock_irqsave(&g_dcc_tty_lock, irq_flags); - space_left = ARRAY_SIZE(g_dcc_buffer) - g_dcc_buffer_count; - spin_unlock_irqrestore(&g_dcc_tty_lock, irq_flags); - return space_left; -} - -static int dcc_tty_chars_in_buffer(struct tty_struct *tty) -{ - int ret; - asm( - "mrc 14, 0, %0, c0, c1, 0\n" - "mov %0, %0, LSR #30\n" - "and %0, %0, #1\n" - : "=r" (ret) - ); - return ret; -} - -static void dcc_tty_unthrottle(struct tty_struct * tty) -{ - unsigned long irq_flags; - - spin_lock_irqsave(&g_dcc_tty_lock, irq_flags); - dcc_poll_locked(); - spin_unlock_irqrestore(&g_dcc_tty_lock, irq_flags); -} - -static enum hrtimer_restart dcc_tty_timer_func(struct hrtimer *timer) -{ - unsigned long irq_flags; - - spin_lock_irqsave(&g_dcc_tty_lock, irq_flags); - dcc_poll_locked(); - spin_unlock_irqrestore(&g_dcc_tty_lock, irq_flags); - return HRTIMER_NORESTART; -} - -void dcc_console_write(struct console *co, const char *b, unsigned count) -{ -#if 1 - dcc_write(b, count); -#else - /* blocking printk */ - while (count > 0) { - int written; - written = dcc_write(b, count); - if (written) { - b += written; - count -= written; - } - } -#endif -} - -static struct tty_driver *dcc_console_device(struct console *c, int *index) -{ - *index = 0; - return g_dcc_tty_driver; -} - -static int __init dcc_console_setup(struct console *co, char *options) -{ - if (co->index != 0) - return -ENODEV; - return 0; -} - - -static struct console dcc_console = -{ - .name = "ttyDCC", - .write = dcc_console_write, - .device = dcc_console_device, - .setup = dcc_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -static struct tty_operations dcc_tty_ops = { - .open = dcc_tty_open, - .close = dcc_tty_close, - .write = dcc_tty_write, - .write_room = dcc_tty_write_room, - .chars_in_buffer = dcc_tty_chars_in_buffer, - .unthrottle = dcc_tty_unthrottle, -}; - -static int __init dcc_tty_init(void) -{ - int ret; - - hrtimer_init(&g_dcc_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - g_dcc_timer.function = dcc_tty_timer_func; - - g_dcc_tty_driver = alloc_tty_driver(1); - if (!g_dcc_tty_driver) { - printk(KERN_ERR "dcc_tty_probe: alloc_tty_driver failed\n"); - ret = -ENOMEM; - goto err_alloc_tty_driver_failed; - } - g_dcc_tty_driver->owner = THIS_MODULE; - g_dcc_tty_driver->driver_name = "dcc"; - g_dcc_tty_driver->name = "ttyDCC"; - g_dcc_tty_driver->major = 0; // auto assign - g_dcc_tty_driver->minor_start = 0; - g_dcc_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - g_dcc_tty_driver->subtype = SERIAL_TYPE_NORMAL; - g_dcc_tty_driver->init_termios = tty_std_termios; - g_dcc_tty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; - tty_set_operations(g_dcc_tty_driver, &dcc_tty_ops); - ret = tty_register_driver(g_dcc_tty_driver); - if (ret) { - printk(KERN_ERR "dcc_tty_probe: tty_register_driver failed, %d\n", ret); - goto err_tty_register_driver_failed; - } - tty_register_device(g_dcc_tty_driver, 0, NULL); - - register_console(&dcc_console); - hrtimer_start(&g_dcc_timer, ktime_set(0, 0), HRTIMER_MODE_REL); - - return 0; - -err_tty_register_driver_failed: - put_tty_driver(g_dcc_tty_driver); - g_dcc_tty_driver = NULL; -err_alloc_tty_driver_failed: - return ret; -} - -static void __exit dcc_tty_exit(void) -{ - int ret; - - tty_unregister_device(g_dcc_tty_driver, 0); - ret = tty_unregister_driver(g_dcc_tty_driver); - if (ret < 0) { - printk(KERN_ERR "dcc_tty_remove: tty_unregister_driver failed, %d\n", ret); - } else { - put_tty_driver(g_dcc_tty_driver); - } - g_dcc_tty_driver = NULL; -} - -module_init(dcc_tty_init); -module_exit(dcc_tty_exit); - - diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 9b1eb188acdc..8fc04b4f311f 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -56,7 +56,6 @@ static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t size) } #endif -#if defined(CONFIG_DEVMEM) || defined(CONFIG_DEVKMEM) #ifdef CONFIG_STRICT_DEVMEM static inline int range_is_allowed(unsigned long pfn, unsigned long size) { @@ -82,9 +81,7 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size) return 1; } #endif -#endif -#ifdef CONFIG_DEVMEM void __weak unxlate_dev_mem_ptr(unsigned long phys, void *addr) { } @@ -211,9 +208,6 @@ static ssize_t write_mem(struct file *file, const char __user *buf, *ppos += written; return written; } -#endif /* CONFIG_DEVMEM */ - -#if defined(CONFIG_DEVMEM) || defined(CONFIG_DEVKMEM) int __weak phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, unsigned long size, pgprot_t *vma_prot) @@ -335,7 +329,6 @@ static int mmap_mem(struct file *file, struct vm_area_struct *vma) } return 0; } -#endif /* CONFIG_DEVMEM */ #ifdef CONFIG_DEVKMEM static int mmap_kmem(struct file *file, struct vm_area_struct *vma) @@ -700,8 +693,6 @@ static loff_t null_lseek(struct file *file, loff_t offset, int orig) return file->f_pos = 0; } -#if defined(CONFIG_DEVMEM) || defined(CONFIG_DEVKMEM) || defined(CONFIG_DEVPORT) - /* * The memory devices use the full 32/64 bits of the offset, and so we cannot * check against negative addresses: they are ok. The return value is weird, @@ -735,14 +726,10 @@ static loff_t memory_lseek(struct file *file, loff_t offset, int orig) return ret; } -#endif - -#if defined(CONFIG_DEVMEM) || defined(CONFIG_DEVKMEM) || defined(CONFIG_DEVPORT) static int open_port(struct inode * inode, struct file * filp) { return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; } -#endif #define zero_lseek null_lseek #define full_lseek null_lseek @@ -752,7 +739,6 @@ static int open_port(struct inode * inode, struct file * filp) #define open_kmem open_mem #define open_oldmem open_mem -#ifdef CONFIG_DEVMEM static const struct file_operations mem_fops = { .llseek = memory_lseek, .read = read_mem, @@ -761,7 +747,6 @@ static const struct file_operations mem_fops = { .open = open_mem, .get_unmapped_area = get_unmapped_area_mem, }; -#endif #ifdef CONFIG_DEVKMEM static const struct file_operations kmem_fops = { @@ -865,9 +850,7 @@ static const struct memdev { const struct file_operations *fops; struct backing_dev_info *dev_info; } devlist[] = { -#ifdef CONFIG_DEVMEM [1] = { "mem", 0, &mem_fops, &directly_mappable_cdev_bdi }, -#endif #ifdef CONFIG_DEVKMEM [2] = { "kmem", 0, &kmem_fops, &directly_mappable_cdev_bdi }, #endif diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c index 579051ce8545..25d139c9dbed 100644 --- a/drivers/char/mspec.c +++ b/drivers/char/mspec.c @@ -284,7 +284,7 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma, vdata->flags = flags; vdata->type = type; spin_lock_init(&vdata->lock); - atomic_set(&vdata->refcnt, 1); + vdata->refcnt = ATOMIC_INIT(1); vma->vm_private_data = vdata; vma->vm_flags |= (VM_IO | VM_RESERVED | VM_PFNMAP | VM_DONTEXPAND); diff --git a/drivers/char/random.c b/drivers/char/random.c index fceac955bfb8..d4ddeba56682 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -125,26 +125,21 @@ * The current exported interfaces for gathering environmental noise * from the devices are: * - * void add_device_randomness(const void *buf, unsigned int size); * void add_input_randomness(unsigned int type, unsigned int code, * unsigned int value); - * void add_interrupt_randomness(int irq, int irq_flags); + * void add_interrupt_randomness(int irq); * void add_disk_randomness(struct gendisk *disk); * - * add_device_randomness() is for adding data to the random pool that - * is likely to differ between two devices (or possibly even per boot). - * This would be things like MAC addresses or serial numbers, or the - * read-out of the RTC. This does *not* add any actual entropy to the - * pool, but it initializes the pool to different values for devices - * that might otherwise be identical and have very little entropy - * available to them (particularly common in the embedded world). - * * add_input_randomness() uses the input layer interrupt timing, as well as * the event type information from the hardware. * - * add_interrupt_randomness() uses the interrupt timing as random - * inputs to the entropy pool. Using the cycle counters and the irq source - * as inputs, it feeds the randomness roughly once a second. + * add_interrupt_randomness() uses the inter-interrupt timing as random + * inputs to the entropy pool. Note that not all interrupts are good + * sources of randomness! For example, the timer interrupts is not a + * good choice, because the periodicity of the interrupts is too + * regular, and hence predictable to an attacker. Network Interface + * Controller interrupts are a better measure, since the timing of the + * NIC interrupts are more unpredictable. * * add_disk_randomness() uses what amounts to the seek time of block * layer request events, on a per-disk_devt basis, as input to the @@ -253,8 +248,6 @@ #include #include #include -#include -#include #ifdef CONFIG_GENERIC_HARDIRQS # include @@ -263,12 +256,8 @@ #include #include #include -#include #include -#define CREATE_TRACE_POINTS -#include - /* * Configuration information */ @@ -277,8 +266,6 @@ #define SEC_XFER_SIZE 512 #define EXTRACT_SIZE 10 -#define LONGS(x) (((x) + sizeof(unsigned long) - 1)/sizeof(unsigned long)) - /* * The minimum number of bits of entropy before we wake up a read on * /dev/random. Should be enough to do a significant reseed. @@ -433,10 +420,8 @@ struct entropy_store { /* read-write data: */ spinlock_t lock; unsigned add_ptr; - unsigned input_rotate; int entropy_count; - int entropy_total; - unsigned int initialized:1; + int input_rotate; __u8 last_data[EXTRACT_SIZE]; }; @@ -469,10 +454,6 @@ static struct entropy_store nonblocking_pool = { .pool = nonblocking_pool_data }; -static __u32 const twist_table[8] = { - 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158, - 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 }; - /* * This function adds bytes into the entropy "pool". It does not * update the entropy estimate. The caller should call @@ -483,24 +464,29 @@ static __u32 const twist_table[8] = { * it's cheap to do so and helps slightly in the expected case where * the entropy is concentrated in the low-order bits. */ -static void _mix_pool_bytes(struct entropy_store *r, const void *in, - int nbytes, __u8 out[64]) +static void mix_pool_bytes_extract(struct entropy_store *r, const void *in, + int nbytes, __u8 out[64]) { + static __u32 const twist_table[8] = { + 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158, + 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 }; unsigned long i, j, tap1, tap2, tap3, tap4, tap5; int input_rotate; int wordmask = r->poolinfo->poolwords - 1; const char *bytes = in; __u32 w; + unsigned long flags; + /* Taps are constant, so we can load them without holding r->lock. */ tap1 = r->poolinfo->tap1; tap2 = r->poolinfo->tap2; tap3 = r->poolinfo->tap3; tap4 = r->poolinfo->tap4; tap5 = r->poolinfo->tap5; - smp_rmb(); - input_rotate = ACCESS_ONCE(r->input_rotate); - i = ACCESS_ONCE(r->add_ptr); + spin_lock_irqsave(&r->lock, flags); + input_rotate = r->input_rotate; + i = r->add_ptr; /* mix one byte at a time to simplify size handling and churn faster */ while (nbytes--) { @@ -527,61 +513,19 @@ static void _mix_pool_bytes(struct entropy_store *r, const void *in, input_rotate += i ? 7 : 14; } - ACCESS_ONCE(r->input_rotate) = input_rotate; - ACCESS_ONCE(r->add_ptr) = i; - smp_wmb(); + r->input_rotate = input_rotate; + r->add_ptr = i; if (out) for (j = 0; j < 16; j++) ((__u32 *)out)[j] = r->pool[(i - j) & wordmask]; -} -static void __mix_pool_bytes(struct entropy_store *r, const void *in, - int nbytes, __u8 out[64]) -{ - trace_mix_pool_bytes_nolock(r->name, nbytes, _RET_IP_); - _mix_pool_bytes(r, in, nbytes, out); -} - -static void mix_pool_bytes(struct entropy_store *r, const void *in, - int nbytes, __u8 out[64]) -{ - unsigned long flags; - - trace_mix_pool_bytes(r->name, nbytes, _RET_IP_); - spin_lock_irqsave(&r->lock, flags); - _mix_pool_bytes(r, in, nbytes, out); spin_unlock_irqrestore(&r->lock, flags); } -struct fast_pool { - __u32 pool[4]; - unsigned long last; - unsigned short count; - unsigned char rotate; - unsigned char last_timer_intr; -}; - -/* - * This is a fast mixing routine used by the interrupt randomness - * collector. It's hardcoded for an 128 bit pool and assumes that any - * locks that might be needed are taken by the caller. - */ -static void fast_mix(struct fast_pool *f, const void *in, int nbytes) +static void mix_pool_bytes(struct entropy_store *r, const void *in, int bytes) { - const char *bytes = in; - __u32 w; - unsigned i = f->count; - unsigned input_rotate = f->rotate; - - while (nbytes--) { - w = rol32(*bytes++, input_rotate & 31) ^ f->pool[i & 3] ^ - f->pool[(i + 1) & 3]; - f->pool[i & 3] = (w >> 3) ^ twist_table[w & 7]; - input_rotate += (i++ & 3) ? 7 : 14; - } - f->count = i; - f->rotate = input_rotate; + mix_pool_bytes_extract(r, in, bytes, NULL); } /* @@ -589,38 +533,30 @@ static void fast_mix(struct fast_pool *f, const void *in, int nbytes) */ static void credit_entropy_bits(struct entropy_store *r, int nbits) { - int entropy_count, orig; + unsigned long flags; + int entropy_count; if (!nbits) return; + spin_lock_irqsave(&r->lock, flags); + DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name); -retry: - entropy_count = orig = ACCESS_ONCE(r->entropy_count); + entropy_count = r->entropy_count; entropy_count += nbits; - if (entropy_count < 0) { DEBUG_ENT("negative entropy/overflow\n"); entropy_count = 0; } else if (entropy_count > r->poolinfo->POOLBITS) entropy_count = r->poolinfo->POOLBITS; - if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) - goto retry; - - if (!r->initialized && nbits > 0) { - r->entropy_total += nbits; - if (r->entropy_total > 128) - r->initialized = 1; - } - - trace_credit_entropy_bits(r->name, nbits, entropy_count, - r->entropy_total, _RET_IP_); + r->entropy_count = entropy_count; /* should we wake readers? */ if (r == &input_pool && entropy_count >= random_read_wakeup_thresh) { wake_up_interruptible(&random_read_wait); kill_fasync(&fasync, SIGIO, POLL_IN); } + spin_unlock_irqrestore(&r->lock, flags); } /********************************************************************* @@ -636,24 +572,42 @@ struct timer_rand_state { unsigned dont_count_entropy:1; }; -/* - * Add device- or boot-specific data to the input and nonblocking - * pools to help initialize them to unique values. - * - * None of this adds any entropy, it is meant to avoid the - * problem of the nonblocking pool having similar initial state - * across largely identical devices. - */ -void add_device_randomness(const void *buf, unsigned int size) +#ifndef CONFIG_GENERIC_HARDIRQS + +static struct timer_rand_state *irq_timer_state[NR_IRQS]; + +static struct timer_rand_state *get_timer_rand_state(unsigned int irq) +{ + return irq_timer_state[irq]; +} + +static void set_timer_rand_state(unsigned int irq, + struct timer_rand_state *state) { - unsigned long time = get_cycles() ^ jiffies; + irq_timer_state[irq] = state; +} + +#else + +static struct timer_rand_state *get_timer_rand_state(unsigned int irq) +{ + struct irq_desc *desc; + + desc = irq_to_desc(irq); - mix_pool_bytes(&input_pool, buf, size, NULL); - mix_pool_bytes(&input_pool, &time, sizeof(time), NULL); - mix_pool_bytes(&nonblocking_pool, buf, size, NULL); - mix_pool_bytes(&nonblocking_pool, &time, sizeof(time), NULL); + return desc->timer_rand_state; } -EXPORT_SYMBOL(add_device_randomness); + +static void set_timer_rand_state(unsigned int irq, + struct timer_rand_state *state) +{ + struct irq_desc *desc; + + desc = irq_to_desc(irq); + + desc->timer_rand_state = state; +} +#endif static struct timer_rand_state input_timer_state; @@ -670,8 +624,8 @@ static struct timer_rand_state input_timer_state; static void add_timer_randomness(struct timer_rand_state *state, unsigned num) { struct { + cycles_t cycles; long jiffies; - unsigned cycles; unsigned num; } sample; long delta, delta2, delta3; @@ -685,7 +639,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) sample.jiffies = jiffies; sample.cycles = get_cycles(); sample.num = num; - mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL); + mix_pool_bytes(&input_pool, &sample, sizeof(sample)); /* * Calculate number of bits of randomness we probably added. @@ -742,48 +696,17 @@ void add_input_randomness(unsigned int type, unsigned int code, } EXPORT_SYMBOL_GPL(add_input_randomness); -static DEFINE_PER_CPU(struct fast_pool, irq_randomness); - -void add_interrupt_randomness(int irq, int irq_flags) +void add_interrupt_randomness(int irq) { - struct entropy_store *r; - struct fast_pool *fast_pool = &__get_cpu_var(irq_randomness); - struct pt_regs *regs = get_irq_regs(); - unsigned long now = jiffies; - __u32 input[4], cycles = get_cycles(); - - input[0] = cycles ^ jiffies; - input[1] = irq; - if (regs) { - __u64 ip = instruction_pointer(regs); - input[2] = ip; - input[3] = ip >> 32; - } + struct timer_rand_state *state; - fast_mix(fast_pool, input, sizeof(input)); + state = get_timer_rand_state(irq); - if ((fast_pool->count & 1023) && - !time_after(now, fast_pool->last + HZ)) + if (state == NULL) return; - fast_pool->last = now; - - r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool; - __mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool), NULL); - /* - * If we don't have a valid cycle counter, and we see - * back-to-back timer interrupts, then skip giving credit for - * any entropy. - */ - if (cycles == 0) { - if (irq_flags & __IRQF_TIMER) { - if (fast_pool->last_timer_intr) - return; - fast_pool->last_timer_intr = 1; - } else - fast_pool->last_timer_intr = 0; - } - credit_entropy_bits(r, 1); + DEBUG_ENT("irq event %d\n", irq); + add_timer_randomness(state, 0x100 + irq); } #ifdef CONFIG_BLOCK @@ -815,7 +738,7 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, */ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) { - __u32 tmp[OUTPUT_POOL_WORDS]; + __u32 tmp[OUTPUT_POOL_WORDS]; if (r->pull && r->entropy_count < nbytes * 8 && r->entropy_count < r->poolinfo->POOLBITS) { @@ -834,7 +757,7 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) bytes = extract_entropy(r->pull, tmp, bytes, random_read_wakeup_thresh / 8, rsvd); - mix_pool_bytes(r, tmp, bytes, NULL); + mix_pool_bytes(r, tmp, bytes); credit_entropy_bits(r, bytes*8); } } @@ -893,19 +816,13 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, static void extract_buf(struct entropy_store *r, __u8 *out) { int i; - union { - __u32 w[5]; - unsigned long l[LONGS(EXTRACT_SIZE)]; - } hash; - __u32 workspace[SHA_WORKSPACE_WORDS]; + __u32 hash[5], workspace[SHA_WORKSPACE_WORDS]; __u8 extract[64]; - unsigned long flags; /* Generate a hash across the pool, 16 words (512 bits) at a time */ - sha_init(hash.w); - spin_lock_irqsave(&r->lock, flags); + sha_init(hash); for (i = 0; i < r->poolinfo->poolwords; i += 16) - sha_transform(hash.w, (__u8 *)(r->pool + i), workspace); + sha_transform(hash, (__u8 *)(r->pool + i), workspace); /* * We mix the hash back into the pool to prevent backtracking @@ -916,14 +833,13 @@ static void extract_buf(struct entropy_store *r, __u8 *out) * brute-forcing the feedback as hard as brute-forcing the * hash. */ - __mix_pool_bytes(r, hash.w, sizeof(hash.w), extract); - spin_unlock_irqrestore(&r->lock, flags); + mix_pool_bytes_extract(r, hash, sizeof(hash), extract); /* * To avoid duplicates, we atomically extract a portion of the * pool while mixing, and hash one final time. */ - sha_transform(hash.w, extract, workspace); + sha_transform(hash, extract, workspace); memset(extract, 0, sizeof(extract)); memset(workspace, 0, sizeof(workspace)); @@ -932,32 +848,20 @@ static void extract_buf(struct entropy_store *r, __u8 *out) * pattern, we fold it in half. Thus, we always feed back * twice as much data as we output. */ - hash.w[0] ^= hash.w[3]; - hash.w[1] ^= hash.w[4]; - hash.w[2] ^= rol32(hash.w[2], 16); - - /* - * If we have a architectural hardware random number - * generator, mix that in, too. - */ - for (i = 0; i < LONGS(EXTRACT_SIZE); i++) { - unsigned long v; - if (!arch_get_random_long(&v)) - break; - hash.l[i] ^= v; - } - - memcpy(out, &hash, EXTRACT_SIZE); - memset(&hash, 0, sizeof(hash)); + hash[0] ^= hash[3]; + hash[1] ^= hash[4]; + hash[2] ^= rol32(hash[2], 16); + memcpy(out, hash, EXTRACT_SIZE); + memset(hash, 0, sizeof(hash)); } static ssize_t extract_entropy(struct entropy_store *r, void *buf, - size_t nbytes, int min, int reserved) + size_t nbytes, int min, int reserved) { ssize_t ret = 0, i; __u8 tmp[EXTRACT_SIZE]; + unsigned long flags; - trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_); xfer_secondary_pool(r, nbytes); nbytes = account(r, nbytes, min, reserved); @@ -965,8 +869,6 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, extract_buf(r, tmp); if (fips_enabled) { - unsigned long flags; - spin_lock_irqsave(&r->lock, flags); if (!memcmp(tmp, r->last_data, EXTRACT_SIZE)) panic("Hardware RNG duplicated output!\n"); @@ -992,7 +894,6 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf, ssize_t ret = 0, i; __u8 tmp[EXTRACT_SIZE]; - trace_extract_entropy_user(r->name, nbytes, r->entropy_count, _RET_IP_); xfer_secondary_pool(r, nbytes); nbytes = account(r, nbytes, 0, 0); @@ -1026,9 +927,8 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf, /* * This function is the exported kernel interface. It returns some - * number of good random numbers, suitable for key generation, seeding - * TCP sequence numbers, etc. It does not use the hw random number - * generator, if available; use get_random_bytes_arch() for that. + * number of good random numbers, suitable for seeding TCP sequence + * numbers, etc. */ void get_random_bytes(void *buf, int nbytes) { @@ -1036,39 +936,6 @@ void get_random_bytes(void *buf, int nbytes) } EXPORT_SYMBOL(get_random_bytes); -/* - * This function will use the architecture-specific hardware random - * number generator if it is available. The arch-specific hw RNG will - * almost certainly be faster than what we can do in software, but it - * is impossible to verify that it is implemented securely (as - * opposed, to, say, the AES encryption of a sequence number using a - * key known by the NSA). So it's useful if we need the speed, but - * only if we're willing to trust the hardware manufacturer not to - * have put in a back door. - */ -void get_random_bytes_arch(void *buf, int nbytes) -{ - char *p = buf; - - trace_get_random_bytes(nbytes, _RET_IP_); - while (nbytes) { - unsigned long v; - int chunk = min(nbytes, (int)sizeof(unsigned long)); - - if (!arch_get_random_long(&v)) - break; - - memcpy(p, &v, chunk); - p += chunk; - nbytes -= chunk; - } - - if (nbytes) - extract_entropy(&nonblocking_pool, p, nbytes, 0, 0); -} -EXPORT_SYMBOL(get_random_bytes_arch); - - /* * init_std_data - initialize pool with system data * @@ -1080,31 +947,18 @@ EXPORT_SYMBOL(get_random_bytes_arch); */ static void init_std_data(struct entropy_store *r) { - int i; - ktime_t now = ktime_get_real(); - unsigned long rv; + ktime_t now; + unsigned long flags; + spin_lock_irqsave(&r->lock, flags); r->entropy_count = 0; - r->entropy_total = 0; - mix_pool_bytes(r, &now, sizeof(now), NULL); - for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(rv)) { - if (!arch_get_random_long(&rv)) - break; - mix_pool_bytes(r, &rv, sizeof(rv), NULL); - } - mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL); + spin_unlock_irqrestore(&r->lock, flags); + + now = ktime_get_real(); + mix_pool_bytes(r, &now, sizeof(now)); + mix_pool_bytes(r, utsname(), sizeof(*(utsname()))); } -/* - * Note that setup_arch() may call add_device_randomness() - * long before we get here. This allows seeding of the pools - * with some platform dependent data very early in the boot - * process. But it limits our options here. We must use - * statically allocated structures that already have all - * initializations complete at compile time. We should also - * take care not to overwrite the precious per platform data - * we were given. - */ static int rand_initialize(void) { init_std_data(&input_pool); @@ -1114,6 +968,24 @@ static int rand_initialize(void) } module_init(rand_initialize); +void rand_initialize_irq(int irq) +{ + struct timer_rand_state *state; + + state = get_timer_rand_state(irq); + + if (state) + return; + + /* + * If kzalloc returns null, we just won't use that entropy + * source. + */ + state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL); + if (state) + set_timer_rand_state(irq, state); +} + #ifdef CONFIG_BLOCK void rand_initialize_disk(struct gendisk *disk) { @@ -1221,7 +1093,7 @@ write_pool(struct entropy_store *r, const char __user *buffer, size_t count) count -= bytes; p += bytes; - mix_pool_bytes(r, buf, bytes, NULL); + mix_pool_bytes(r, buf, bytes); cond_resched(); } @@ -1364,15 +1236,10 @@ static int proc_do_uuid(ctl_table *table, int write, uuid = table->data; if (!uuid) { uuid = tmp_uuid; - generate_random_uuid(uuid); - } else { - static DEFINE_SPINLOCK(bootid_spinlock); - - spin_lock(&bootid_spinlock); - if (!uuid[8]) - generate_random_uuid(uuid); - spin_unlock(&bootid_spinlock); + uuid[8] = 0; } + if (uuid[8] == 0) + generate_random_uuid(uuid); sprintf(buf, "%pU", uuid); @@ -1433,14 +1300,330 @@ ctl_table random_table[] = { }; #endif /* CONFIG_SYSCTL */ -static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; +/******************************************************************** + * + * Random functions for networking + * + ********************************************************************/ + +/* + * TCP initial sequence number picking. This uses the random number + * generator to pick an initial secret value. This value is hashed + * along with the TCP endpoint information to provide a unique + * starting point for each pair of TCP endpoints. This defeats + * attacks which rely on guessing the initial TCP sequence number. + * This algorithm was suggested by Steve Bellovin. + * + * Using a very strong hash was taking an appreciable amount of the total + * TCP connection establishment time, so this is a weaker hash, + * compensated for by changing the secret periodically. + */ + +/* F, G and H are basic MD4 functions: selection, majority, parity */ +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) -static int __init random_int_secret_init(void) +/* + * The generic round function. The application is so specific that + * we don't bother protecting all the arguments with parens, as is generally + * good macro practice, in favor of extra legibility. + * Rotation is separate from addition to prevent recomputation + */ +#define ROUND(f, a, b, c, d, x, s) \ + (a += f(b, c, d) + x, a = (a << s) | (a >> (32 - s))) +#define K1 0 +#define K2 013240474631UL +#define K3 015666365641UL + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + +static __u32 twothirdsMD4Transform(__u32 const buf[4], __u32 const in[12]) { - get_random_bytes(random_int_secret, sizeof(random_int_secret)); + __u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + + /* Round 1 */ + ROUND(F, a, b, c, d, in[ 0] + K1, 3); + ROUND(F, d, a, b, c, in[ 1] + K1, 7); + ROUND(F, c, d, a, b, in[ 2] + K1, 11); + ROUND(F, b, c, d, a, in[ 3] + K1, 19); + ROUND(F, a, b, c, d, in[ 4] + K1, 3); + ROUND(F, d, a, b, c, in[ 5] + K1, 7); + ROUND(F, c, d, a, b, in[ 6] + K1, 11); + ROUND(F, b, c, d, a, in[ 7] + K1, 19); + ROUND(F, a, b, c, d, in[ 8] + K1, 3); + ROUND(F, d, a, b, c, in[ 9] + K1, 7); + ROUND(F, c, d, a, b, in[10] + K1, 11); + ROUND(F, b, c, d, a, in[11] + K1, 19); + + /* Round 2 */ + ROUND(G, a, b, c, d, in[ 1] + K2, 3); + ROUND(G, d, a, b, c, in[ 3] + K2, 5); + ROUND(G, c, d, a, b, in[ 5] + K2, 9); + ROUND(G, b, c, d, a, in[ 7] + K2, 13); + ROUND(G, a, b, c, d, in[ 9] + K2, 3); + ROUND(G, d, a, b, c, in[11] + K2, 5); + ROUND(G, c, d, a, b, in[ 0] + K2, 9); + ROUND(G, b, c, d, a, in[ 2] + K2, 13); + ROUND(G, a, b, c, d, in[ 4] + K2, 3); + ROUND(G, d, a, b, c, in[ 6] + K2, 5); + ROUND(G, c, d, a, b, in[ 8] + K2, 9); + ROUND(G, b, c, d, a, in[10] + K2, 13); + + /* Round 3 */ + ROUND(H, a, b, c, d, in[ 3] + K3, 3); + ROUND(H, d, a, b, c, in[ 7] + K3, 9); + ROUND(H, c, d, a, b, in[11] + K3, 11); + ROUND(H, b, c, d, a, in[ 2] + K3, 15); + ROUND(H, a, b, c, d, in[ 6] + K3, 3); + ROUND(H, d, a, b, c, in[10] + K3, 9); + ROUND(H, c, d, a, b, in[ 1] + K3, 11); + ROUND(H, b, c, d, a, in[ 5] + K3, 15); + ROUND(H, a, b, c, d, in[ 9] + K3, 3); + ROUND(H, d, a, b, c, in[ 0] + K3, 9); + ROUND(H, c, d, a, b, in[ 4] + K3, 11); + ROUND(H, b, c, d, a, in[ 8] + K3, 15); + + return buf[1] + b; /* "most hashed" word */ + /* Alternative: return sum of all words? */ +} +#endif + +#undef ROUND +#undef F +#undef G +#undef H +#undef K1 +#undef K2 +#undef K3 + +/* This should not be decreased so low that ISNs wrap too fast. */ +#define REKEY_INTERVAL (300 * HZ) +/* + * Bit layout of the tcp sequence numbers (before adding current time): + * bit 24-31: increased after every key exchange + * bit 0-23: hash(source,dest) + * + * The implementation is similar to the algorithm described + * in the Appendix of RFC 1185, except that + * - it uses a 1 MHz clock instead of a 250 kHz clock + * - it performs a rekey every 5 minutes, which is equivalent + * to a (source,dest) tulple dependent forward jump of the + * clock by 0..2^(HASH_BITS+1) + * + * Thus the average ISN wraparound time is 68 minutes instead of + * 4.55 hours. + * + * SMP cleanup and lock avoidance with poor man's RCU. + * Manfred Spraul + * + */ +#define COUNT_BITS 8 +#define COUNT_MASK ((1 << COUNT_BITS) - 1) +#define HASH_BITS 24 +#define HASH_MASK ((1 << HASH_BITS) - 1) + +static struct keydata { + __u32 count; /* already shifted to the final position */ + __u32 secret[12]; +} ____cacheline_aligned ip_keydata[2]; + +static unsigned int ip_cnt; + +static void rekey_seq_generator(struct work_struct *work); + +static DECLARE_DELAYED_WORK(rekey_work, rekey_seq_generator); + +/* + * Lock avoidance: + * The ISN generation runs lockless - it's just a hash over random data. + * State changes happen every 5 minutes when the random key is replaced. + * Synchronization is performed by having two copies of the hash function + * state and rekey_seq_generator always updates the inactive copy. + * The copy is then activated by updating ip_cnt. + * The implementation breaks down if someone blocks the thread + * that processes SYN requests for more than 5 minutes. Should never + * happen, and even if that happens only a not perfectly compliant + * ISN is generated, nothing fatal. + */ +static void rekey_seq_generator(struct work_struct *work) +{ + struct keydata *keyptr = &ip_keydata[1 ^ (ip_cnt & 1)]; + + get_random_bytes(keyptr->secret, sizeof(keyptr->secret)); + keyptr->count = (ip_cnt & COUNT_MASK) << HASH_BITS; + smp_wmb(); + ip_cnt++; + schedule_delayed_work(&rekey_work, + round_jiffies_relative(REKEY_INTERVAL)); +} + +static inline struct keydata *get_keyptr(void) +{ + struct keydata *keyptr = &ip_keydata[ip_cnt & 1]; + + smp_rmb(); + + return keyptr; +} + +static __init int seqgen_init(void) +{ + rekey_seq_generator(NULL); return 0; } -late_initcall(random_int_secret_init); +late_initcall(seqgen_init); + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +__u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, + __be16 sport, __be16 dport) +{ + __u32 seq; + __u32 hash[12]; + struct keydata *keyptr = get_keyptr(); + + /* The procedure is the same as for IPv4, but addresses are longer. + * Thus we must use twothirdsMD4Transform. + */ + + memcpy(hash, saddr, 16); + hash[4] = ((__force u16)sport << 16) + (__force u16)dport; + memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7); + + seq = twothirdsMD4Transform((const __u32 *)daddr, hash) & HASH_MASK; + seq += keyptr->count; + + seq += ktime_to_ns(ktime_get_real()); + + return seq; +} +EXPORT_SYMBOL(secure_tcpv6_sequence_number); +#endif + +/* The code below is shamelessly stolen from secure_tcp_sequence_number(). + * All blames to Andrey V. Savochkin . + */ +__u32 secure_ip_id(__be32 daddr) +{ + struct keydata *keyptr; + __u32 hash[4]; + + keyptr = get_keyptr(); + + /* + * Pick a unique starting offset for each IP destination. + * The dest ip address is placed in the starting vector, + * which is then hashed with random data. + */ + hash[0] = (__force __u32)daddr; + hash[1] = keyptr->secret[9]; + hash[2] = keyptr->secret[10]; + hash[3] = keyptr->secret[11]; + + return half_md4_transform(hash, keyptr->secret); +} + +#ifdef CONFIG_INET + +__u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, + __be16 sport, __be16 dport) +{ + __u32 seq; + __u32 hash[4]; + struct keydata *keyptr = get_keyptr(); + + /* + * Pick a unique starting offset for each TCP connection endpoints + * (saddr, daddr, sport, dport). + * Note that the words are placed into the starting vector, which is + * then mixed with a partial MD4 over random data. + */ + hash[0] = (__force u32)saddr; + hash[1] = (__force u32)daddr; + hash[2] = ((__force u16)sport << 16) + (__force u16)dport; + hash[3] = keyptr->secret[11]; + + seq = half_md4_transform(hash, keyptr->secret) & HASH_MASK; + seq += keyptr->count; + /* + * As close as possible to RFC 793, which + * suggests using a 250 kHz clock. + * Further reading shows this assumes 2 Mb/s networks. + * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate. + * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but + * we also need to limit the resolution so that the u32 seq + * overlaps less than one time per MSL (2 minutes). + * Choosing a clock of 64 ns period is OK. (period of 274 s) + */ + seq += ktime_to_ns(ktime_get_real()) >> 6; + + return seq; +} + +/* Generate secure starting point for ephemeral IPV4 transport port search */ +u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) +{ + struct keydata *keyptr = get_keyptr(); + u32 hash[4]; + + /* + * Pick a unique starting offset for each ephemeral port search + * (saddr, daddr, dport) and 48bits of random data. + */ + hash[0] = (__force u32)saddr; + hash[1] = (__force u32)daddr; + hash[2] = (__force u32)dport ^ keyptr->secret[10]; + hash[3] = keyptr->secret[11]; + + return half_md4_transform(hash, keyptr->secret); +} +EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral); + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, + __be16 dport) +{ + struct keydata *keyptr = get_keyptr(); + u32 hash[12]; + + memcpy(hash, saddr, 16); + hash[4] = (__force u32)dport; + memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7); + + return twothirdsMD4Transform((const __u32 *)daddr, hash); +} +#endif + +#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) +/* Similar to secure_tcp_sequence_number but generate a 48 bit value + * bit's 32-47 increase every key exchange + * 0-31 hash(source, dest) + */ +u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, + __be16 sport, __be16 dport) +{ + u64 seq; + __u32 hash[4]; + struct keydata *keyptr = get_keyptr(); + + hash[0] = (__force u32)saddr; + hash[1] = (__force u32)daddr; + hash[2] = ((__force u16)sport << 16) + (__force u16)dport; + hash[3] = keyptr->secret[11]; + + seq = half_md4_transform(hash, keyptr->secret); + seq |= ((u64)keyptr->count) << (32 - HASH_BITS); + + seq += ktime_to_ns(ktime_get_real()); + seq &= (1ull << 48) - 1; + + return seq; +} +EXPORT_SYMBOL(secure_dccp_sequence_number); +#endif + +#endif /* CONFIG_INET */ + /* * Get a random word for internal kernel use only. Similar to urandom but @@ -1448,20 +1631,17 @@ late_initcall(random_int_secret_init); * value is not cryptographically secure but for several uses the cost of * depleting entropy is too high */ -DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash); +DEFINE_PER_CPU(__u32 [4], get_random_int_hash); unsigned int get_random_int(void) { - __u32 *hash; - unsigned int ret; - - if (arch_get_random_int(&ret)) - return ret; - - hash = get_cpu_var(get_random_int_hash); + struct keydata *keyptr; + __u32 *hash = get_cpu_var(get_random_int_hash); + int ret; + keyptr = get_keyptr(); hash[0] += current->pid + jiffies + get_cycles(); - md5_transform(hash, random_int_secret); - ret = hash[0]; + + ret = half_md4_transform(hash, keyptr->secret); put_cpu_var(get_random_int_hash); return ret; diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 65b9d6f99437..7beb0e25f1e1 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -383,9 +383,6 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, u32 count, ordinal; unsigned long stop; - if (bufsiz > TPM_BUFSIZE) - bufsiz = TPM_BUFSIZE; - count = be32_to_cpu(*((__be32 *) (buf + 2))); ordinal = be32_to_cpu(*((__be32 *) (buf + 6))); if (count == 0) @@ -1019,21 +1016,18 @@ ssize_t tpm_write(struct file *file, const char __user *buf, size_t size, loff_t *off) { struct tpm_chip *chip = file->private_data; - size_t in_size = size; - ssize_t out_size; + size_t in_size = size, out_size; /* cannot perform a write until the read has cleared - either via tpm_read or a user_read_timer timeout. - This also prevents splitted buffered writes from blocking here. - */ - if (atomic_read(&chip->data_pending) != 0) - return -EBUSY; - - if (in_size > TPM_BUFSIZE) - return -E2BIG; + either via tpm_read or a user_read_timer timeout */ + while (atomic_read(&chip->data_pending) != 0) + msleep(TPM_TIMEOUT); mutex_lock(&chip->buffer_mutex); + if (in_size > TPM_BUFSIZE) + in_size = TPM_BUFSIZE; + if (copy_from_user (chip->data_buffer, (void __user *) buf, in_size)) { mutex_unlock(&chip->buffer_mutex); @@ -1042,10 +1036,6 @@ ssize_t tpm_write(struct file *file, const char __user *buf, /* atomic tpm command send and result receive */ out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE); - if (out_size < 0) { - mutex_unlock(&chip->buffer_mutex); - return out_size; - } atomic_set(&chip->data_pending, out_size); mutex_unlock(&chip->buffer_mutex); @@ -1062,7 +1052,6 @@ ssize_t tpm_read(struct file *file, char __user *buf, { struct tpm_chip *chip = file->private_data; ssize_t ret_size; - int rc; del_singleshot_timer_sync(&chip->user_read_timer); flush_work_sync(&chip->work); @@ -1073,11 +1062,8 @@ ssize_t tpm_read(struct file *file, char __user *buf, ret_size = size; mutex_lock(&chip->buffer_mutex); - rc = copy_to_user(buf, chip->data_buffer, ret_size); - memset(chip->data_buffer, 0, ret_size); - if (rc) + if (copy_to_user(buf, chip->data_buffer, ret_size)) ret_size = -EFAULT; - mutex_unlock(&chip->buffer_mutex); } diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index acce1a7aac75..a1f68af4ccf4 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c @@ -66,7 +66,7 @@ static int tpk_printk(const unsigned char *buf, int count) tmp[tpk_curr + 1] = '\0'; printk(KERN_INFO "%s%s", tpk_tag, tmp); tpk_curr = 0; - if ((i + 1) < count && buf[i + 1] == '\n') + if (buf[i + 1] == '\n') i++; break; case '\n': diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index a95256a3a493..fb68b1295373 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1750,8 +1750,7 @@ static void virtcons_remove(struct virtio_device *vdev) /* Disable interrupts for vqs */ vdev->config->reset(vdev); /* Finish up work that's lined up */ - if (use_multiport(portdev)) - cancel_work_sync(&portdev->control_work); + cancel_work_sync(&portdev->control_work); list_for_each_entry_safe(port, port2, &portdev->ports, list) unplug_port(port); diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 194708850ede..9fb84853d8e3 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -99,16 +99,6 @@ config CPU_FREQ_DEFAULT_GOV_CONSERVATIVE Be aware that not all cpufreq drivers support the conservative governor. If unsure have a look at the help section of the driver. Fallback governor will be the performance governor. - -config CPU_FREQ_DEFAULT_GOV_INTERACTIVE - bool "interactive" - select CPU_FREQ_GOV_INTERACTIVE - help - Use the CPUFreq governor 'interactive' as default. This allows - you to get a full dynamic cpu frequency capable system by simply - loading your cpufreq low-level hardware driver, using the - 'interactive' governor for latency-sensitive workloads. - endchoice config CPU_FREQ_GOV_PERFORMANCE @@ -166,23 +156,6 @@ config CPU_FREQ_GOV_ONDEMAND If in doubt, say N. -config CPU_FREQ_GOV_INTERACTIVE - tristate "'interactive' cpufreq policy governor" - help - 'interactive' - This driver adds a dynamic cpufreq policy governor - designed for latency-sensitive workloads. - - This governor attempts to reduce the latency of clock - increases so that the system is more responsive to - interactive workloads. - - To compile this driver as a module, choose M here: the - module will be called cpufreq_interactive. - - For details, take a look at linux/Documentation/cpu-freq. - - If in doubt, say N. - config CPU_FREQ_GOV_CONSERVATIVE tristate "'conservative' cpufreq governor" depends on CPU_FREQ diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index c044060a4b07..e2fc2d21fa61 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o -obj-$(CONFIG_CPU_FREQ_GOV_INTERACTIVE) += cpufreq_interactive.o # CPUfreq cross-arch helpers obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c deleted file mode 100644 index 7d1952c5cb16..000000000000 --- a/drivers/cpufreq/cpufreq_interactive.c +++ /dev/null @@ -1,1066 +0,0 @@ -/* - * drivers/cpufreq/cpufreq_interactive.c - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Author: Mike Chan (mike@android.com) - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define CREATE_TRACE_POINTS -#include - -static int active_count; - -struct cpufreq_interactive_cpuinfo { - struct timer_list cpu_timer; - struct timer_list cpu_slack_timer; - spinlock_t load_lock; /* protects the next 4 fields */ - u64 time_in_idle; - u64 time_in_idle_timestamp; - u64 cputime_speedadj; - u64 cputime_speedadj_timestamp; - struct cpufreq_policy *policy; - struct cpufreq_frequency_table *freq_table; - unsigned int target_freq; - unsigned int floor_freq; - u64 floor_validate_time; - u64 hispeed_validate_time; - struct rw_semaphore enable_sem; - int governor_enabled; -}; - -static DEFINE_PER_CPU(struct cpufreq_interactive_cpuinfo, cpuinfo); - -/* realtime thread handles frequency scaling */ -static struct task_struct *speedchange_task; -static cpumask_t speedchange_cpumask; -static spinlock_t speedchange_cpumask_lock; -static struct mutex gov_lock; - -/* Hi speed to bump to from lo speed when load burst (default max) */ -static unsigned int hispeed_freq; - -/* Go to hi speed when CPU load at or above this value. */ -#define DEFAULT_GO_HISPEED_LOAD 99 -static unsigned long go_hispeed_load = DEFAULT_GO_HISPEED_LOAD; - -/* Target load. Lower values result in higher CPU speeds. */ -#define DEFAULT_TARGET_LOAD 90 -static unsigned int default_target_loads[] = {DEFAULT_TARGET_LOAD}; -static spinlock_t target_loads_lock; -static unsigned int *target_loads = default_target_loads; -static int ntarget_loads = ARRAY_SIZE(default_target_loads); - -/* - * The minimum amount of time to spend at a frequency before we can ramp down. - */ -#define DEFAULT_MIN_SAMPLE_TIME (80 * USEC_PER_MSEC) -static unsigned long min_sample_time = DEFAULT_MIN_SAMPLE_TIME; - -/* - * The sample rate of the timer used to increase frequency - */ -#define DEFAULT_TIMER_RATE (20 * USEC_PER_MSEC) -static unsigned long timer_rate = DEFAULT_TIMER_RATE; - -/* - * Wait this long before raising speed above hispeed, by default a single - * timer interval. - */ -#define DEFAULT_ABOVE_HISPEED_DELAY DEFAULT_TIMER_RATE -static unsigned long above_hispeed_delay_val = DEFAULT_ABOVE_HISPEED_DELAY; - -/* Non-zero means indefinite speed boost active */ -static int boost_val; -/* Duration of a boot pulse in usecs */ -static int boostpulse_duration_val = DEFAULT_MIN_SAMPLE_TIME; -/* End time of boost pulse in ktime converted to usecs */ -static u64 boostpulse_endtime; - -/* - * Max additional time to wait in idle, beyond timer_rate, at speeds above - * minimum before wakeup to reduce speed, or -1 if unnecessary. - */ -#define DEFAULT_TIMER_SLACK (4 * DEFAULT_TIMER_RATE) -static int timer_slack_val = DEFAULT_TIMER_SLACK; - -static int cpufreq_governor_interactive(struct cpufreq_policy *policy, - unsigned int event); - -#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE -static -#endif -struct cpufreq_governor cpufreq_gov_interactive = { - .name = "interactive", - .governor = cpufreq_governor_interactive, - .max_transition_latency = 10000000, - .owner = THIS_MODULE, -}; - -static void cpufreq_interactive_timer_resched( - struct cpufreq_interactive_cpuinfo *pcpu) -{ - unsigned long expires = jiffies + usecs_to_jiffies(timer_rate); - unsigned long flags; - - mod_timer_pinned(&pcpu->cpu_timer, expires); - if (timer_slack_val >= 0 && pcpu->target_freq > pcpu->policy->min) { - expires += usecs_to_jiffies(timer_slack_val); - mod_timer_pinned(&pcpu->cpu_slack_timer, expires); - } - - spin_lock_irqsave(&pcpu->load_lock, flags); - pcpu->time_in_idle = - get_cpu_idle_time_us(smp_processor_id(), - &pcpu->time_in_idle_timestamp); - pcpu->cputime_speedadj = 0; - pcpu->cputime_speedadj_timestamp = pcpu->time_in_idle_timestamp; - spin_unlock_irqrestore(&pcpu->load_lock, flags); -} - -static unsigned int freq_to_targetload(unsigned int freq) -{ - int i; - unsigned int ret; - unsigned long flags; - - spin_lock_irqsave(&target_loads_lock, flags); - - for (i = 0; i < ntarget_loads - 1 && freq >= target_loads[i+1]; i += 2) - ; - - ret = target_loads[i]; - spin_unlock_irqrestore(&target_loads_lock, flags); - return ret; -} - -/* - * If increasing frequencies never map to a lower target load then - * choose_freq() will find the minimum frequency that does not exceed its - * target load given the current load. - */ - -static unsigned int choose_freq( - struct cpufreq_interactive_cpuinfo *pcpu, unsigned int loadadjfreq) -{ - unsigned int freq = pcpu->policy->cur; - unsigned int prevfreq, freqmin, freqmax; - unsigned int tl; - int index; - - freqmin = 0; - freqmax = UINT_MAX; - - do { - prevfreq = freq; - tl = freq_to_targetload(freq); - - /* - * Find the lowest frequency where the computed load is less - * than or equal to the target load. - */ - - cpufreq_frequency_table_target( - pcpu->policy, pcpu->freq_table, loadadjfreq / tl, - CPUFREQ_RELATION_L, &index); - freq = pcpu->freq_table[index].frequency; - - if (freq > prevfreq) { - /* The previous frequency is too low. */ - freqmin = prevfreq; - - if (freq >= freqmax) { - /* - * Find the highest frequency that is less - * than freqmax. - */ - cpufreq_frequency_table_target( - pcpu->policy, pcpu->freq_table, - freqmax - 1, CPUFREQ_RELATION_H, - &index); - freq = pcpu->freq_table[index].frequency; - - if (freq == freqmin) { - /* - * The first frequency below freqmax - * has already been found to be too - * low. freqmax is the lowest speed - * we found that is fast enough. - */ - freq = freqmax; - break; - } - } - } else if (freq < prevfreq) { - /* The previous frequency is high enough. */ - freqmax = prevfreq; - - if (freq <= freqmin) { - /* - * Find the lowest frequency that is higher - * than freqmin. - */ - cpufreq_frequency_table_target( - pcpu->policy, pcpu->freq_table, - freqmin + 1, CPUFREQ_RELATION_L, - &index); - freq = pcpu->freq_table[index].frequency; - - /* - * If freqmax is the first frequency above - * freqmin then we have already found that - * this speed is fast enough. - */ - if (freq == freqmax) - break; - } - } - - /* If same frequency chosen as previous then done. */ - } while (freq != prevfreq); - - return freq; -} - -static u64 update_load(int cpu) -{ - struct cpufreq_interactive_cpuinfo *pcpu = &per_cpu(cpuinfo, cpu); - u64 now; - u64 now_idle; - unsigned int delta_idle; - unsigned int delta_time; - u64 active_time; - - now_idle = get_cpu_idle_time_us(cpu, &now); - delta_idle = (unsigned int)(now_idle - pcpu->time_in_idle); - delta_time = (unsigned int)(now - pcpu->time_in_idle_timestamp); - active_time = delta_time - delta_idle; - pcpu->cputime_speedadj += active_time * pcpu->policy->cur; - - pcpu->time_in_idle = now_idle; - pcpu->time_in_idle_timestamp = now; - return now; -} - -static void cpufreq_interactive_timer(unsigned long data) -{ - u64 now; - unsigned int delta_time; - u64 cputime_speedadj; - int cpu_load; - struct cpufreq_interactive_cpuinfo *pcpu = - &per_cpu(cpuinfo, data); - unsigned int new_freq; - unsigned int loadadjfreq; - unsigned int index; - unsigned long flags; - bool boosted; - - if (!down_read_trylock(&pcpu->enable_sem)) - return; - if (!pcpu->governor_enabled) - goto exit; - - spin_lock_irqsave(&pcpu->load_lock, flags); - now = update_load(data); - delta_time = (unsigned int)(now - pcpu->cputime_speedadj_timestamp); - cputime_speedadj = pcpu->cputime_speedadj; - spin_unlock_irqrestore(&pcpu->load_lock, flags); - - if (WARN_ON_ONCE(!delta_time)) - goto rearm; - - do_div(cputime_speedadj, delta_time); - loadadjfreq = (unsigned int)cputime_speedadj * 100; - cpu_load = loadadjfreq / pcpu->target_freq; - boosted = boost_val || now < boostpulse_endtime; - - if (cpu_load >= go_hispeed_load || boosted) { - if (pcpu->target_freq < hispeed_freq) { - new_freq = hispeed_freq; - } else { - new_freq = choose_freq(pcpu, loadadjfreq); - - if (new_freq < hispeed_freq) - new_freq = hispeed_freq; - } - } else { - new_freq = choose_freq(pcpu, loadadjfreq); - } - - if (pcpu->target_freq >= hispeed_freq && - new_freq > pcpu->target_freq && - now - pcpu->hispeed_validate_time < above_hispeed_delay_val) { - trace_cpufreq_interactive_notyet( - data, cpu_load, pcpu->target_freq, - pcpu->policy->cur, new_freq); - goto rearm; - } - - pcpu->hispeed_validate_time = now; - - if (cpufreq_frequency_table_target(pcpu->policy, pcpu->freq_table, - new_freq, CPUFREQ_RELATION_L, - &index)) { - pr_warn_once("timer %d: cpufreq_frequency_table_target error\n", - (int) data); - goto rearm; - } - - new_freq = pcpu->freq_table[index].frequency; - - /* - * Do not scale below floor_freq unless we have been at or above the - * floor frequency for the minimum sample time since last validated. - */ - if (new_freq < pcpu->floor_freq) { - if (now - pcpu->floor_validate_time < min_sample_time) { - trace_cpufreq_interactive_notyet( - data, cpu_load, pcpu->target_freq, - pcpu->policy->cur, new_freq); - goto rearm; - } - } - - /* - * Update the timestamp for checking whether speed has been held at - * or above the selected frequency for a minimum of min_sample_time, - * if not boosted to hispeed_freq. If boosted to hispeed_freq then we - * allow the speed to drop as soon as the boostpulse duration expires - * (or the indefinite boost is turned off). - */ - - if (!boosted || new_freq > hispeed_freq) { - pcpu->floor_freq = new_freq; - pcpu->floor_validate_time = now; - } - - if (pcpu->target_freq == new_freq) { - trace_cpufreq_interactive_already( - data, cpu_load, pcpu->target_freq, - pcpu->policy->cur, new_freq); - goto rearm_if_notmax; - } - - trace_cpufreq_interactive_target(data, cpu_load, pcpu->target_freq, - pcpu->policy->cur, new_freq); - - pcpu->target_freq = new_freq; - spin_lock_irqsave(&speedchange_cpumask_lock, flags); - cpumask_set_cpu(data, &speedchange_cpumask); - spin_unlock_irqrestore(&speedchange_cpumask_lock, flags); - wake_up_process(speedchange_task); - -rearm_if_notmax: - /* - * Already set max speed and don't see a need to change that, - * wait until next idle to re-evaluate, don't need timer. - */ - if (pcpu->target_freq == pcpu->policy->max) - goto exit; - -rearm: - if (!timer_pending(&pcpu->cpu_timer)) - cpufreq_interactive_timer_resched(pcpu); - -exit: - up_read(&pcpu->enable_sem); - return; -} - -static void cpufreq_interactive_idle_start(void) -{ - struct cpufreq_interactive_cpuinfo *pcpu = - &per_cpu(cpuinfo, smp_processor_id()); - int pending; - - if (!down_read_trylock(&pcpu->enable_sem)) - return; - if (!pcpu->governor_enabled) { - up_read(&pcpu->enable_sem); - return; - } - - pending = timer_pending(&pcpu->cpu_timer); - - if (pcpu->target_freq != pcpu->policy->min) { - /* - * Entering idle while not at lowest speed. On some - * platforms this can hold the other CPU(s) at that speed - * even though the CPU is idle. Set a timer to re-evaluate - * speed so this idle CPU doesn't hold the other CPUs above - * min indefinitely. This should probably be a quirk of - * the CPUFreq driver. - */ - if (!pending) - cpufreq_interactive_timer_resched(pcpu); - } - - up_read(&pcpu->enable_sem); -} - -static void cpufreq_interactive_idle_end(void) -{ - struct cpufreq_interactive_cpuinfo *pcpu = - &per_cpu(cpuinfo, smp_processor_id()); - - if (!down_read_trylock(&pcpu->enable_sem)) - return; - if (!pcpu->governor_enabled) { - up_read(&pcpu->enable_sem); - return; - } - - /* Arm the timer for 1-2 ticks later if not already. */ - if (!timer_pending(&pcpu->cpu_timer)) { - cpufreq_interactive_timer_resched(pcpu); - } else if (time_after_eq(jiffies, pcpu->cpu_timer.expires)) { - del_timer(&pcpu->cpu_timer); - del_timer(&pcpu->cpu_slack_timer); - cpufreq_interactive_timer(smp_processor_id()); - } - - up_read(&pcpu->enable_sem); -} - -static int cpufreq_interactive_speedchange_task(void *data) -{ - unsigned int cpu; - cpumask_t tmp_mask; - unsigned long flags; - struct cpufreq_interactive_cpuinfo *pcpu; - - while (1) { - set_current_state(TASK_INTERRUPTIBLE); - spin_lock_irqsave(&speedchange_cpumask_lock, flags); - - if (cpumask_empty(&speedchange_cpumask)) { - spin_unlock_irqrestore(&speedchange_cpumask_lock, - flags); - schedule(); - - if (kthread_should_stop()) - break; - - spin_lock_irqsave(&speedchange_cpumask_lock, flags); - } - - set_current_state(TASK_RUNNING); - tmp_mask = speedchange_cpumask; - cpumask_clear(&speedchange_cpumask); - spin_unlock_irqrestore(&speedchange_cpumask_lock, flags); - - for_each_cpu(cpu, &tmp_mask) { - unsigned int j; - unsigned int max_freq = 0; - - pcpu = &per_cpu(cpuinfo, cpu); - if (!down_read_trylock(&pcpu->enable_sem)) - continue; - if (!pcpu->governor_enabled) { - up_read(&pcpu->enable_sem); - continue; - } - - for_each_cpu(j, pcpu->policy->cpus) { - struct cpufreq_interactive_cpuinfo *pjcpu = - &per_cpu(cpuinfo, j); - - if (pjcpu->target_freq > max_freq) - max_freq = pjcpu->target_freq; - } - - if (max_freq != pcpu->policy->cur) - __cpufreq_driver_target(pcpu->policy, - max_freq, - CPUFREQ_RELATION_H); - trace_cpufreq_interactive_setspeed(cpu, - pcpu->target_freq, - pcpu->policy->cur); - - up_read(&pcpu->enable_sem); - } - } - - return 0; -} - -static void cpufreq_interactive_boost(void) -{ - int i; - int anyboost = 0; - unsigned long flags; - struct cpufreq_interactive_cpuinfo *pcpu; - - spin_lock_irqsave(&speedchange_cpumask_lock, flags); - - for_each_online_cpu(i) { - pcpu = &per_cpu(cpuinfo, i); - - if (pcpu->target_freq < hispeed_freq) { - pcpu->target_freq = hispeed_freq; - cpumask_set_cpu(i, &speedchange_cpumask); - pcpu->hispeed_validate_time = - ktime_to_us(ktime_get()); - anyboost = 1; - } - - /* - * Set floor freq and (re)start timer for when last - * validated. - */ - - pcpu->floor_freq = hispeed_freq; - pcpu->floor_validate_time = ktime_to_us(ktime_get()); - } - - spin_unlock_irqrestore(&speedchange_cpumask_lock, flags); - - if (anyboost) - wake_up_process(speedchange_task); -} - -static int cpufreq_interactive_notifier( - struct notifier_block *nb, unsigned long val, void *data) -{ - struct cpufreq_freqs *freq = data; - struct cpufreq_interactive_cpuinfo *pcpu; - int cpu; - unsigned long flags; - - if (val == CPUFREQ_POSTCHANGE) { - pcpu = &per_cpu(cpuinfo, freq->cpu); - if (!down_read_trylock(&pcpu->enable_sem)) - return 0; - if (!pcpu->governor_enabled) { - up_read(&pcpu->enable_sem); - return 0; - } - - for_each_cpu(cpu, pcpu->policy->cpus) { - struct cpufreq_interactive_cpuinfo *pjcpu = - &per_cpu(cpuinfo, cpu); - spin_lock_irqsave(&pjcpu->load_lock, flags); - update_load(cpu); - spin_unlock_irqrestore(&pjcpu->load_lock, flags); - } - - up_read(&pcpu->enable_sem); - } - return 0; -} - -static struct notifier_block cpufreq_notifier_block = { - .notifier_call = cpufreq_interactive_notifier, -}; - -static ssize_t show_target_loads( - struct kobject *kobj, struct attribute *attr, char *buf) -{ - int i; - ssize_t ret = 0; - unsigned long flags; - - spin_lock_irqsave(&target_loads_lock, flags); - - for (i = 0; i < ntarget_loads; i++) - ret += sprintf(buf + ret, "%u%s", target_loads[i], - i & 0x1 ? ":" : " "); - - ret += sprintf(buf + ret, "\n"); - spin_unlock_irqrestore(&target_loads_lock, flags); - return ret; -} - -static ssize_t store_target_loads( - struct kobject *kobj, struct attribute *attr, const char *buf, - size_t count) -{ - int ret; - const char *cp; - unsigned int *new_target_loads = NULL; - int ntokens = 1; - int i; - unsigned long flags; - - cp = buf; - while ((cp = strpbrk(cp + 1, " :"))) - ntokens++; - - if (!(ntokens & 0x1)) - goto err_inval; - - new_target_loads = kmalloc(ntokens * sizeof(unsigned int), GFP_KERNEL); - if (!new_target_loads) { - ret = -ENOMEM; - goto err; - } - - cp = buf; - i = 0; - while (i < ntokens) { - if (sscanf(cp, "%u", &new_target_loads[i++]) != 1) - goto err_inval; - - cp = strpbrk(cp, " :"); - if (!cp) - break; - cp++; - } - - if (i != ntokens) - goto err_inval; - - spin_lock_irqsave(&target_loads_lock, flags); - if (target_loads != default_target_loads) - kfree(target_loads); - target_loads = new_target_loads; - ntarget_loads = ntokens; - spin_unlock_irqrestore(&target_loads_lock, flags); - return count; - -err_inval: - ret = -EINVAL; -err: - kfree(new_target_loads); - return ret; -} - -static struct global_attr target_loads_attr = - __ATTR(target_loads, S_IRUGO | S_IWUSR, - show_target_loads, store_target_loads); - -static ssize_t show_hispeed_freq(struct kobject *kobj, - struct attribute *attr, char *buf) -{ - return sprintf(buf, "%u\n", hispeed_freq); -} - -static ssize_t store_hispeed_freq(struct kobject *kobj, - struct attribute *attr, const char *buf, - size_t count) -{ - int ret; - long unsigned int val; - - ret = strict_strtoul(buf, 0, &val); - if (ret < 0) - return ret; - hispeed_freq = val; - return count; -} - -static struct global_attr hispeed_freq_attr = __ATTR(hispeed_freq, 0644, - show_hispeed_freq, store_hispeed_freq); - - -static ssize_t show_go_hispeed_load(struct kobject *kobj, - struct attribute *attr, char *buf) -{ - return sprintf(buf, "%lu\n", go_hispeed_load); -} - -static ssize_t store_go_hispeed_load(struct kobject *kobj, - struct attribute *attr, const char *buf, size_t count) -{ - int ret; - unsigned long val; - - ret = strict_strtoul(buf, 0, &val); - if (ret < 0) - return ret; - go_hispeed_load = val; - return count; -} - -static struct global_attr go_hispeed_load_attr = __ATTR(go_hispeed_load, 0644, - show_go_hispeed_load, store_go_hispeed_load); - -static ssize_t show_min_sample_time(struct kobject *kobj, - struct attribute *attr, char *buf) -{ - return sprintf(buf, "%lu\n", min_sample_time); -} - -static ssize_t store_min_sample_time(struct kobject *kobj, - struct attribute *attr, const char *buf, size_t count) -{ - int ret; - unsigned long val; - - ret = strict_strtoul(buf, 0, &val); - if (ret < 0) - return ret; - min_sample_time = val; - return count; -} - -static struct global_attr min_sample_time_attr = __ATTR(min_sample_time, 0644, - show_min_sample_time, store_min_sample_time); - -static ssize_t show_above_hispeed_delay(struct kobject *kobj, - struct attribute *attr, char *buf) -{ - return sprintf(buf, "%lu\n", above_hispeed_delay_val); -} - -static ssize_t store_above_hispeed_delay(struct kobject *kobj, - struct attribute *attr, - const char *buf, size_t count) -{ - int ret; - unsigned long val; - - ret = strict_strtoul(buf, 0, &val); - if (ret < 0) - return ret; - above_hispeed_delay_val = val; - return count; -} - -define_one_global_rw(above_hispeed_delay); - -static ssize_t show_timer_rate(struct kobject *kobj, - struct attribute *attr, char *buf) -{ - return sprintf(buf, "%lu\n", timer_rate); -} - -static ssize_t store_timer_rate(struct kobject *kobj, - struct attribute *attr, const char *buf, size_t count) -{ - int ret; - unsigned long val; - - ret = strict_strtoul(buf, 0, &val); - if (ret < 0) - return ret; - timer_rate = val; - return count; -} - -static struct global_attr timer_rate_attr = __ATTR(timer_rate, 0644, - show_timer_rate, store_timer_rate); - -static ssize_t show_timer_slack( - struct kobject *kobj, struct attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n", timer_slack_val); -} - -static ssize_t store_timer_slack( - struct kobject *kobj, struct attribute *attr, const char *buf, - size_t count) -{ - int ret; - unsigned long val; - - ret = kstrtol(buf, 10, &val); - if (ret < 0) - return ret; - - timer_slack_val = val; - return count; -} - -define_one_global_rw(timer_slack); - -static ssize_t show_boost(struct kobject *kobj, struct attribute *attr, - char *buf) -{ - return sprintf(buf, "%d\n", boost_val); -} - -static ssize_t store_boost(struct kobject *kobj, struct attribute *attr, - const char *buf, size_t count) -{ - int ret; - unsigned long val; - - ret = kstrtoul(buf, 0, &val); - if (ret < 0) - return ret; - - boost_val = val; - - if (boost_val) { - trace_cpufreq_interactive_boost("on"); - cpufreq_interactive_boost(); - } else { - trace_cpufreq_interactive_unboost("off"); - } - - return count; -} - -define_one_global_rw(boost); - -static ssize_t store_boostpulse(struct kobject *kobj, struct attribute *attr, - const char *buf, size_t count) -{ - int ret; - unsigned long val; - - ret = kstrtoul(buf, 0, &val); - if (ret < 0) - return ret; - - boostpulse_endtime = ktime_to_us(ktime_get()) + boostpulse_duration_val; - trace_cpufreq_interactive_boost("pulse"); - cpufreq_interactive_boost(); - return count; -} - -static struct global_attr boostpulse = - __ATTR(boostpulse, 0200, NULL, store_boostpulse); - -static ssize_t show_boostpulse_duration( - struct kobject *kobj, struct attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n", boostpulse_duration_val); -} - -static ssize_t store_boostpulse_duration( - struct kobject *kobj, struct attribute *attr, const char *buf, - size_t count) -{ - int ret; - unsigned long val; - - ret = kstrtoul(buf, 0, &val); - if (ret < 0) - return ret; - - boostpulse_duration_val = val; - return count; -} - -define_one_global_rw(boostpulse_duration); - -static struct attribute *interactive_attributes[] = { - &target_loads_attr.attr, - &hispeed_freq_attr.attr, - &go_hispeed_load_attr.attr, - &above_hispeed_delay.attr, - &min_sample_time_attr.attr, - &timer_rate_attr.attr, - &timer_slack.attr, - &boost.attr, - &boostpulse.attr, - &boostpulse_duration.attr, - NULL, -}; - -static struct attribute_group interactive_attr_group = { - .attrs = interactive_attributes, - .name = "interactive", -}; - -static int cpufreq_interactive_idle_notifier(struct notifier_block *nb, - unsigned long val, - void *data) -{ - switch (val) { - case IDLE_START: - cpufreq_interactive_idle_start(); - break; - case IDLE_END: - cpufreq_interactive_idle_end(); - break; - } - - return 0; -} - -static struct notifier_block cpufreq_interactive_idle_nb = { - .notifier_call = cpufreq_interactive_idle_notifier, -}; - -static int cpufreq_governor_interactive(struct cpufreq_policy *policy, - unsigned int event) -{ - int rc; - unsigned int j; - struct cpufreq_interactive_cpuinfo *pcpu; - struct cpufreq_frequency_table *freq_table; - - switch (event) { - case CPUFREQ_GOV_START: - if (!cpu_online(policy->cpu)) - return -EINVAL; - - mutex_lock(&gov_lock); - - freq_table = - cpufreq_frequency_get_table(policy->cpu); - if (!hispeed_freq) - hispeed_freq = policy->max; - - for_each_cpu(j, policy->cpus) { - unsigned long expires; - - pcpu = &per_cpu(cpuinfo, j); - pcpu->policy = policy; - pcpu->target_freq = policy->cur; - pcpu->freq_table = freq_table; - pcpu->floor_freq = pcpu->target_freq; - pcpu->floor_validate_time = - ktime_to_us(ktime_get()); - pcpu->hispeed_validate_time = - pcpu->floor_validate_time; - down_write(&pcpu->enable_sem); - expires = jiffies + usecs_to_jiffies(timer_rate); - pcpu->cpu_timer.expires = expires; - add_timer_on(&pcpu->cpu_timer, j); - if (timer_slack_val >= 0) { - expires += usecs_to_jiffies(timer_slack_val); - pcpu->cpu_slack_timer.expires = expires; - add_timer_on(&pcpu->cpu_slack_timer, j); - } - pcpu->governor_enabled = 1; - up_write(&pcpu->enable_sem); - } - - /* - * Do not register the idle hook and create sysfs - * entries if we have already done so. - */ - if (++active_count > 1) { - mutex_unlock(&gov_lock); - return 0; - } - - rc = sysfs_create_group(cpufreq_global_kobject, - &interactive_attr_group); - if (rc) { - mutex_unlock(&gov_lock); - return rc; - } - - idle_notifier_register(&cpufreq_interactive_idle_nb); - cpufreq_register_notifier( - &cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER); - mutex_unlock(&gov_lock); - break; - - case CPUFREQ_GOV_STOP: - mutex_lock(&gov_lock); - for_each_cpu(j, policy->cpus) { - pcpu = &per_cpu(cpuinfo, j); - down_write(&pcpu->enable_sem); - pcpu->governor_enabled = 0; - del_timer_sync(&pcpu->cpu_timer); - del_timer_sync(&pcpu->cpu_slack_timer); - up_write(&pcpu->enable_sem); - } - - if (--active_count > 0) { - mutex_unlock(&gov_lock); - return 0; - } - - cpufreq_unregister_notifier( - &cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER); - idle_notifier_unregister(&cpufreq_interactive_idle_nb); - sysfs_remove_group(cpufreq_global_kobject, - &interactive_attr_group); - mutex_unlock(&gov_lock); - - break; - - case CPUFREQ_GOV_LIMITS: - if (policy->max < policy->cur) - __cpufreq_driver_target(policy, - policy->max, CPUFREQ_RELATION_H); - else if (policy->min > policy->cur) - __cpufreq_driver_target(policy, - policy->min, CPUFREQ_RELATION_L); - break; - } - return 0; -} - -static void cpufreq_interactive_nop_timer(unsigned long data) -{ -} - -static int __init cpufreq_interactive_init(void) -{ - unsigned int i; - struct cpufreq_interactive_cpuinfo *pcpu; - struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; - - /* Initalize per-cpu timers */ - for_each_possible_cpu(i) { - pcpu = &per_cpu(cpuinfo, i); - init_timer_deferrable(&pcpu->cpu_timer); - pcpu->cpu_timer.function = cpufreq_interactive_timer; - pcpu->cpu_timer.data = i; - init_timer(&pcpu->cpu_slack_timer); - pcpu->cpu_slack_timer.function = cpufreq_interactive_nop_timer; - spin_lock_init(&pcpu->load_lock); - init_rwsem(&pcpu->enable_sem); - } - - spin_lock_init(&target_loads_lock); - spin_lock_init(&speedchange_cpumask_lock); - mutex_init(&gov_lock); - speedchange_task = - kthread_create(cpufreq_interactive_speedchange_task, NULL, - "cfinteractive"); - if (IS_ERR(speedchange_task)) - return PTR_ERR(speedchange_task); - - sched_setscheduler_nocheck(speedchange_task, SCHED_FIFO, ¶m); - get_task_struct(speedchange_task); - - /* NB: wake up so the thread does not look hung to the freezer */ - wake_up_process(speedchange_task); - - return cpufreq_register_governor(&cpufreq_gov_interactive); -} - -#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE -fs_initcall(cpufreq_interactive_init); -#else -module_init(cpufreq_interactive_init); -#endif - -static void __exit cpufreq_interactive_exit(void) -{ - cpufreq_unregister_governor(&cpufreq_gov_interactive); - kthread_stop(speedchange_task); - put_task_struct(speedchange_task); -} - -module_exit(cpufreq_interactive_exit); - -MODULE_AUTHOR("Mike Chan "); -MODULE_DESCRIPTION("'cpufreq_interactive' - A cpufreq governor for " - "Latency sensitive workloads"); -MODULE_LICENSE("GPL"); diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index c315ec9d5686..faf7c5217848 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -317,27 +317,6 @@ static int cpufreq_stat_notifier_trans(struct notifier_block *nb, return 0; } -static int cpufreq_stats_create_table_cpu(unsigned int cpu) -{ - struct cpufreq_policy *policy; - struct cpufreq_frequency_table *table; - int ret = -ENODEV; - - policy = cpufreq_cpu_get(cpu); - if (!policy) - return -ENODEV; - - table = cpufreq_frequency_get_table(cpu); - if (!table) - goto out; - - ret = cpufreq_stats_create_table(policy, table); - -out: - cpufreq_cpu_put(policy); - return ret; -} - static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) @@ -356,10 +335,6 @@ static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, case CPU_DEAD_FROZEN: cpufreq_stats_free_table(cpu); break; - case CPU_DOWN_FAILED: - case CPU_DOWN_FAILED_FROZEN: - cpufreq_stats_create_table_cpu(cpu); - break; } return NOTIFY_OK; } diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c index cdc02ac8f41a..7b0603eb0129 100644 --- a/drivers/cpufreq/pcc-cpufreq.c +++ b/drivers/cpufreq/pcc-cpufreq.c @@ -261,9 +261,6 @@ static int pcc_get_offset(int cpu) pr = per_cpu(processors, cpu); pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu); - if (!pr) - return -ENODEV; - status = acpi_evaluate_object(pr->handle, "PCCP", NULL, &buffer); if (ACPI_FAILURE(status)) return -ENODEV; diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index f6cd315ad945..bce576d7478e 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c @@ -32,6 +32,7 @@ #include #include #include +#include /* for current / set_cpus_allowed() */ #include #include @@ -53,9 +54,6 @@ static DEFINE_PER_CPU(struct powernow_k8_data *, powernow_data); static int cpu_family = CPU_OPTERON; -/* array to map SW pstate number to acpi state */ -static u32 ps_to_as[8]; - /* core performance boost */ static bool cpb_capable, cpb_enabled; static struct msr __percpu *msrs; @@ -82,9 +80,9 @@ static u32 find_khz_freq_from_fid(u32 fid) } static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data, - u32 pstate) + u32 pstate) { - return data[ps_to_as[pstate]].frequency; + return data[pstate].frequency; } /* Return the vco fid for an input fid @@ -928,27 +926,23 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data, invalidate_entry(powernow_table, i); continue; } + rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi); + if (!(hi & HW_PSTATE_VALID_MASK)) { + pr_debug("invalid pstate %d, ignoring\n", index); + invalidate_entry(powernow_table, i); + continue; + } - ps_to_as[index] = i; + powernow_table[i].index = index; /* Frequency may be rounded for these */ if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10) || boot_cpu_data.x86 == 0x11) { - - rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi); - if (!(hi & HW_PSTATE_VALID_MASK)) { - pr_debug("invalid pstate %d, ignoring\n", index); - invalidate_entry(powernow_table, i); - continue; - } - powernow_table[i].frequency = freq_from_fid_did(lo & 0x3f, (lo >> 6) & 7); } else powernow_table[i].frequency = data->acpi_data.states[i].core_frequency * 1000; - - powernow_table[i].index = index; } return 0; } @@ -1131,23 +1125,16 @@ static int transition_frequency_pstate(struct powernow_k8_data *data, return res; } -struct powernowk8_target_arg { - struct cpufreq_policy *pol; - unsigned targfreq; - unsigned relation; -}; - -static long powernowk8_target_fn(void *arg) +/* Driver entry point to switch to the target frequency */ +static int powernowk8_target(struct cpufreq_policy *pol, + unsigned targfreq, unsigned relation) { - struct powernowk8_target_arg *pta = arg; - struct cpufreq_policy *pol = pta->pol; - unsigned targfreq = pta->targfreq; - unsigned relation = pta->relation; + cpumask_var_t oldmask; struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); u32 checkfid; u32 checkvid; unsigned int newstate; - int ret; + int ret = -EIO; if (!data) return -EINVAL; @@ -1155,16 +1142,29 @@ static long powernowk8_target_fn(void *arg) checkfid = data->currfid; checkvid = data->currvid; + /* only run on specific CPU from here on. */ + /* This is poor form: use a workqueue or smp_call_function_single */ + if (!alloc_cpumask_var(&oldmask, GFP_KERNEL)) + return -ENOMEM; + + cpumask_copy(oldmask, tsk_cpus_allowed(current)); + set_cpus_allowed_ptr(current, cpumask_of(pol->cpu)); + + if (smp_processor_id() != pol->cpu) { + printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu); + goto err_out; + } + if (pending_bit_stuck()) { printk(KERN_ERR PFX "failing targ, change pending bit set\n"); - return -EIO; + goto err_out; } pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n", pol->cpu, targfreq, pol->min, pol->max, relation); if (query_current_values_with_pending_wait(data)) - return -EIO; + goto err_out; if (cpu_family != CPU_HW_PSTATE) { pr_debug("targ: curr fid 0x%x, vid 0x%x\n", @@ -1182,41 +1182,35 @@ static long powernowk8_target_fn(void *arg) if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate)) - return -EIO; + goto err_out; mutex_lock(&fidvid_mutex); powernow_k8_acpi_pst_values(data, newstate); if (cpu_family == CPU_HW_PSTATE) - ret = transition_frequency_pstate(data, - data->powernow_table[newstate].index); + ret = transition_frequency_pstate(data, newstate); else ret = transition_frequency_fidvid(data, newstate); if (ret) { printk(KERN_ERR PFX "transition frequency failed\n"); + ret = 1; mutex_unlock(&fidvid_mutex); - return 1; + goto err_out; } mutex_unlock(&fidvid_mutex); if (cpu_family == CPU_HW_PSTATE) pol->cur = find_khz_freq_from_pstate(data->powernow_table, - data->powernow_table[newstate].index); + newstate); else pol->cur = find_khz_freq_from_fid(data->currfid); + ret = 0; - return 0; -} - -/* Driver entry point to switch to the target frequency */ -static int powernowk8_target(struct cpufreq_policy *pol, - unsigned targfreq, unsigned relation) -{ - struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq, - .relation = relation }; - - return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); +err_out: + set_cpus_allowed_ptr(current, oldmask); + free_cpumask_var(oldmask); + return ret; } /* Driver entry point to verify the policy and range of frequencies */ diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index e2f7271915dc..c47f3d09c1ee 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -172,12 +172,7 @@ static inline int performance_multiplier(void) /* for higher loadavg, we are more reluctant */ - /* - * this doesn't work as intended - it is almost always 0, but can - * sometimes, depending on workload, spike very high into the hundreds - * even when the average cpu load is under 10%. - */ - /* mult += 2 * get_loadavg(); */ + mult += 2 * get_loadavg(); /* for IO wait tasks (per cpu!) we add 5x each */ mult += 10 * nr_iowait_cpu(smp_processor_id()); diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 98caccfdf217..e0b25de1e339 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -173,7 +173,6 @@ config CRYPTO_DEV_MV_CESA select CRYPTO_ALGAPI select CRYPTO_AES select CRYPTO_BLKCIPHER2 - select CRYPTO_HASH help This driver allows you to utilize the Cryptographic Engines and Security Accelerator (CESA) which can be found on the Marvell Orion diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index f53dd83438bc..3cf303ee3fe3 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -342,13 +342,11 @@ static void mv_process_hash_current(int first_block) else op.config |= CFG_MID_FRAG; - if (first_block) { - writel(req_ctx->state[0], cpg->reg + DIGEST_INITIAL_VAL_A); - writel(req_ctx->state[1], cpg->reg + DIGEST_INITIAL_VAL_B); - writel(req_ctx->state[2], cpg->reg + DIGEST_INITIAL_VAL_C); - writel(req_ctx->state[3], cpg->reg + DIGEST_INITIAL_VAL_D); - writel(req_ctx->state[4], cpg->reg + DIGEST_INITIAL_VAL_E); - } + writel(req_ctx->state[0], cpg->reg + DIGEST_INITIAL_VAL_A); + writel(req_ctx->state[1], cpg->reg + DIGEST_INITIAL_VAL_B); + writel(req_ctx->state[2], cpg->reg + DIGEST_INITIAL_VAL_C); + writel(req_ctx->state[3], cpg->reg + DIGEST_INITIAL_VAL_D); + writel(req_ctx->state[4], cpg->reg + DIGEST_INITIAL_VAL_E); } memcpy(cpg->sram + SRAM_CONFIG, &op, sizeof(struct sec_accel_config)); @@ -713,7 +711,6 @@ static int mv_hash_final(struct ahash_request *req) { struct mv_req_hash_ctx *ctx = ahash_request_ctx(req); - ahash_request_set_crypt(req, NULL, req->result, 0); mv_update_hash_req_ctx(ctx, 1, 0); return mv_handle_req(&req->base); } diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 6a718b77a2b1..25cf327cd1cb 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -200,17 +200,18 @@ config PL330_DMA platform_data for a dma-pl330 device. config PCH_DMA - tristate "Intel EG20T PCH / OKI Semi IOH(ML7213/ML7223/ML7831) DMA support" + tristate "Intel EG20T PCH / OKI Semi IOH(ML7213/ML7223) DMA support" depends on PCI && X86 select DMA_ENGINE help Enable support for Intel EG20T PCH DMA engine. + This driver also can be used for OKI SEMICONDUCTOR IOH(Input/ - Output Hub), ML7213, ML7223 and ML7831. - ML7213 IOH is for IVI(In-Vehicle Infotainment) use, ML7223 IOH is - for MP(Media Phone) use and ML7831 IOH is for general purpose use. - ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series. - ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH. + Output Hub), ML7213 and ML7223. + ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is + for MP(Media Phone) use. + ML7213/ML7223 is companion chip for Intel Atom E6xx series. + ML7213/ML7223 is completely compatible for Intel EG20T PCH. config IMX_SDMA tristate "i.MX SDMA support" diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 1357c3b1e3a2..36144f88d718 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -237,6 +237,10 @@ static void atc_dostart(struct at_dma_chan *atchan, struct at_desc *first) vdbg_dump_regs(atchan); + /* clear any pending interrupt */ + while (dma_readl(atdma, EBCISR)) + cpu_relax(); + channel_writel(atchan, SADDR, 0); channel_writel(atchan, DADDR, 0); channel_writel(atchan, CTRLA, 0); @@ -674,7 +678,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, flags); if (unlikely(!atslave || !sg_len)) { - dev_dbg(chan2dev(chan), "prep_slave_sg: sg length is zero!\n"); + dev_dbg(chan2dev(chan), "prep_dma_memcpy: length is zero!\n"); return NULL; } @@ -702,11 +706,6 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, mem = sg_dma_address(sg); len = sg_dma_len(sg); - if (unlikely(!len)) { - dev_dbg(chan2dev(chan), - "prep_slave_sg: sg(%d) data length is zero\n", i); - goto err; - } mem_width = 2; if (unlikely(mem & 3 || len & 3)) mem_width = 0; @@ -741,11 +740,6 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, mem = sg_dma_address(sg); len = sg_dma_len(sg); - if (unlikely(!len)) { - dev_dbg(chan2dev(chan), - "prep_slave_sg: sg(%d) data length is zero\n", i); - goto err; - } mem_width = 2; if (unlikely(mem & 3 || len & 3)) mem_width = 0; @@ -779,7 +773,6 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, err_desc_get: dev_err(chan2dev(chan), "not enough descriptors available\n"); -err: atc_desc_put(atchan, first); return NULL; } @@ -1286,7 +1279,7 @@ static int __init at_dma_probe(struct platform_device *pdev) tasklet_init(&atchan->tasklet, atc_tasklet, (unsigned long)atchan); - atc_enable_chan_irq(atdma, i); + atc_enable_irq(atchan); } /* set base routines */ @@ -1355,7 +1348,7 @@ static int __exit at_dma_remove(struct platform_device *pdev) struct at_dma_chan *atchan = to_at_dma_chan(chan); /* Disable interrupts */ - atc_disable_chan_irq(atdma, chan->chan_id); + atc_disable_irq(atchan); tasklet_disable(&atchan->tasklet); tasklet_kill(&atchan->tasklet); diff --git a/drivers/dma/at_hdmac_regs.h b/drivers/dma/at_hdmac_regs.h index 19ed47056da8..087dbf1dd39c 100644 --- a/drivers/dma/at_hdmac_regs.h +++ b/drivers/dma/at_hdmac_regs.h @@ -319,27 +319,28 @@ static void atc_dump_lli(struct at_dma_chan *atchan, struct at_lli *lli) } -static void atc_setup_irq(struct at_dma *atdma, int chan_id, int on) +static void atc_setup_irq(struct at_dma_chan *atchan, int on) { - u32 ebci; + struct at_dma *atdma = to_at_dma(atchan->chan_common.device); + u32 ebci; /* enable interrupts on buffer transfer completion & error */ - ebci = AT_DMA_BTC(chan_id) - | AT_DMA_ERR(chan_id); + ebci = AT_DMA_BTC(atchan->chan_common.chan_id) + | AT_DMA_ERR(atchan->chan_common.chan_id); if (on) dma_writel(atdma, EBCIER, ebci); else dma_writel(atdma, EBCIDR, ebci); } -static void atc_enable_chan_irq(struct at_dma *atdma, int chan_id) +static inline void atc_enable_irq(struct at_dma_chan *atchan) { - atc_setup_irq(atdma, chan_id, 1); + atc_setup_irq(atchan, 1); } -static void atc_disable_chan_irq(struct at_dma *atdma, int chan_id) +static inline void atc_disable_irq(struct at_dma_chan *atchan) { - atc_setup_irq(atdma, chan_id, 0); + atc_setup_irq(atchan, 0); } diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 6e3392691118..d845dc4b7103 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c @@ -949,7 +949,7 @@ static int __devinit ioat_xor_val_self_test(struct ioatdma_device *device) goto free_resources; } } - dma_sync_single_for_device(dev, dest_dma, PAGE_SIZE, DMA_FROM_DEVICE); + dma_sync_single_for_device(dev, dest_dma, PAGE_SIZE, DMA_TO_DEVICE); /* skip validate if the capability is not present */ if (!dma_has_cap(DMA_XOR_VAL, dma_chan->device->cap_mask)) diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c index 1ed89d0a1bda..ff5b38f9d45b 100644 --- a/drivers/dma/pch_dma.c +++ b/drivers/dma/pch_dma.c @@ -45,8 +45,7 @@ #define DMA_STATUS_MASK_BITS 0x3 #define DMA_STATUS_SHIFT_BITS 16 #define DMA_STATUS_IRQ(x) (0x1 << (x)) -#define DMA_STATUS0_ERR(x) (0x1 << ((x) + 8)) -#define DMA_STATUS2_ERR(x) (0x1 << (x)) +#define DMA_STATUS_ERR(x) (0x1 << ((x) + 8)) #define DMA_DESC_WIDTH_SHIFT_BITS 12 #define DMA_DESC_WIDTH_1_BYTE (0x3 << DMA_DESC_WIDTH_SHIFT_BITS) @@ -60,10 +59,7 @@ #define DMA_DESC_FOLLOW_WITHOUT_IRQ 0x2 #define DMA_DESC_FOLLOW_WITH_IRQ 0x3 -#define MAX_CHAN_NR 12 - -#define DMA_MASK_CTL0_MODE 0x33333333 -#define DMA_MASK_CTL2_MODE 0x00003333 +#define MAX_CHAN_NR 8 static unsigned int init_nr_desc_per_channel = 64; module_param(init_nr_desc_per_channel, uint, 0644); @@ -137,7 +133,6 @@ struct pch_dma { #define PCH_DMA_CTL3 0x0C #define PCH_DMA_STS0 0x10 #define PCH_DMA_STS1 0x14 -#define PCH_DMA_STS2 0x18 #define dma_readl(pd, name) \ readl((pd)->membase + PCH_DMA_##name) @@ -188,19 +183,13 @@ static void pdc_enable_irq(struct dma_chan *chan, int enable) { struct pch_dma *pd = to_pd(chan->device); u32 val; - int pos; - - if (chan->chan_id < 8) - pos = chan->chan_id; - else - pos = chan->chan_id + 8; val = dma_readl(pd, CTL2); if (enable) - val |= 0x1 << pos; + val |= 0x1 << chan->chan_id; else - val &= ~(0x1 << pos); + val &= ~(0x1 << chan->chan_id); dma_writel(pd, CTL2, val); @@ -213,17 +202,10 @@ static void pdc_set_dir(struct dma_chan *chan) struct pch_dma_chan *pd_chan = to_pd_chan(chan); struct pch_dma *pd = to_pd(chan->device); u32 val; - u32 mask_mode; - u32 mask_ctl; if (chan->chan_id < 8) { val = dma_readl(pd, CTL0); - mask_mode = DMA_CTL0_MODE_MASK_BITS << - (DMA_CTL0_BITS_PER_CH * chan->chan_id); - mask_ctl = DMA_MASK_CTL0_MODE & ~(DMA_CTL0_MODE_MASK_BITS << - (DMA_CTL0_BITS_PER_CH * chan->chan_id)); - val &= mask_mode; if (pd_chan->dir == DMA_TO_DEVICE) val |= 0x1 << (DMA_CTL0_BITS_PER_CH * chan->chan_id + DMA_CTL0_DIR_SHIFT_BITS); @@ -231,24 +213,18 @@ static void pdc_set_dir(struct dma_chan *chan) val &= ~(0x1 << (DMA_CTL0_BITS_PER_CH * chan->chan_id + DMA_CTL0_DIR_SHIFT_BITS)); - val |= mask_ctl; dma_writel(pd, CTL0, val); } else { int ch = chan->chan_id - 8; /* ch8-->0 ch9-->1 ... ch11->3 */ val = dma_readl(pd, CTL3); - mask_mode = DMA_CTL0_MODE_MASK_BITS << - (DMA_CTL0_BITS_PER_CH * ch); - mask_ctl = DMA_MASK_CTL2_MODE & ~(DMA_CTL0_MODE_MASK_BITS << - (DMA_CTL0_BITS_PER_CH * ch)); - val &= mask_mode; if (pd_chan->dir == DMA_TO_DEVICE) val |= 0x1 << (DMA_CTL0_BITS_PER_CH * ch + DMA_CTL0_DIR_SHIFT_BITS); else val &= ~(0x1 << (DMA_CTL0_BITS_PER_CH * ch + DMA_CTL0_DIR_SHIFT_BITS)); - val |= mask_ctl; + dma_writel(pd, CTL3, val); } @@ -260,37 +236,33 @@ static void pdc_set_mode(struct dma_chan *chan, u32 mode) { struct pch_dma *pd = to_pd(chan->device); u32 val; - u32 mask_ctl; - u32 mask_dir; if (chan->chan_id < 8) { - mask_ctl = DMA_MASK_CTL0_MODE & ~(DMA_CTL0_MODE_MASK_BITS << - (DMA_CTL0_BITS_PER_CH * chan->chan_id)); - mask_dir = 1 << (DMA_CTL0_BITS_PER_CH * chan->chan_id +\ - DMA_CTL0_DIR_SHIFT_BITS); val = dma_readl(pd, CTL0); - val &= mask_dir; + + val &= ~(DMA_CTL0_MODE_MASK_BITS << + (DMA_CTL0_BITS_PER_CH * chan->chan_id)); val |= mode << (DMA_CTL0_BITS_PER_CH * chan->chan_id); - val |= mask_ctl; + dma_writel(pd, CTL0, val); } else { int ch = chan->chan_id - 8; /* ch8-->0 ch9-->1 ... ch11->3 */ - mask_ctl = DMA_MASK_CTL2_MODE & ~(DMA_CTL0_MODE_MASK_BITS << - (DMA_CTL0_BITS_PER_CH * ch)); - mask_dir = 1 << (DMA_CTL0_BITS_PER_CH * ch +\ - DMA_CTL0_DIR_SHIFT_BITS); + val = dma_readl(pd, CTL3); - val &= mask_dir; + + val &= ~(DMA_CTL0_MODE_MASK_BITS << + (DMA_CTL0_BITS_PER_CH * ch)); val |= mode << (DMA_CTL0_BITS_PER_CH * ch); - val |= mask_ctl; + dma_writel(pd, CTL3, val); + } dev_dbg(chan2dev(chan), "pdc_set_mode: chan %d -> %x\n", chan->chan_id, val); } -static u32 pdc_get_status0(struct pch_dma_chan *pd_chan) +static u32 pdc_get_status(struct pch_dma_chan *pd_chan) { struct pch_dma *pd = to_pd(pd_chan->chan.device); u32 val; @@ -300,27 +272,9 @@ static u32 pdc_get_status0(struct pch_dma_chan *pd_chan) DMA_STATUS_BITS_PER_CH * pd_chan->chan.chan_id)); } -static u32 pdc_get_status2(struct pch_dma_chan *pd_chan) -{ - struct pch_dma *pd = to_pd(pd_chan->chan.device); - u32 val; - - val = dma_readl(pd, STS2); - return DMA_STATUS_MASK_BITS & (val >> (DMA_STATUS_SHIFT_BITS + - DMA_STATUS_BITS_PER_CH * (pd_chan->chan.chan_id - 8))); -} - static bool pdc_is_idle(struct pch_dma_chan *pd_chan) { - u32 sts; - - if (pd_chan->chan.chan_id < 8) - sts = pdc_get_status0(pd_chan); - else - sts = pdc_get_status2(pd_chan); - - - if (sts == DMA_STATUS_IDLE) + if (pdc_get_status(pd_chan) == DMA_STATUS_IDLE) return true; else return false; @@ -541,11 +495,11 @@ static int pd_alloc_chan_resources(struct dma_chan *chan) list_add_tail(&desc->desc_node, &tmp_list); } - spin_lock_irq(&pd_chan->lock); + spin_lock_bh(&pd_chan->lock); list_splice(&tmp_list, &pd_chan->free_list); pd_chan->descs_allocated = i; pd_chan->completed_cookie = chan->cookie = 1; - spin_unlock_irq(&pd_chan->lock); + spin_unlock_bh(&pd_chan->lock); pdc_enable_irq(chan, 1); @@ -563,10 +517,10 @@ static void pd_free_chan_resources(struct dma_chan *chan) BUG_ON(!list_empty(&pd_chan->active_list)); BUG_ON(!list_empty(&pd_chan->queue)); - spin_lock_irq(&pd_chan->lock); + spin_lock_bh(&pd_chan->lock); list_splice_init(&pd_chan->free_list, &tmp_list); pd_chan->descs_allocated = 0; - spin_unlock_irq(&pd_chan->lock); + spin_unlock_bh(&pd_chan->lock); list_for_each_entry_safe(desc, _d, &tmp_list, desc_node) pci_pool_free(pd->pool, desc, desc->txd.phys); @@ -582,10 +536,10 @@ static enum dma_status pd_tx_status(struct dma_chan *chan, dma_cookie_t cookie, dma_cookie_t last_completed; int ret; - spin_lock_irq(&pd_chan->lock); + spin_lock_bh(&pd_chan->lock); last_completed = pd_chan->completed_cookie; last_used = chan->cookie; - spin_unlock_irq(&pd_chan->lock); + spin_unlock_bh(&pd_chan->lock); ret = dma_async_is_complete(cookie, last_completed, last_used); @@ -700,7 +654,7 @@ static int pd_device_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, if (cmd != DMA_TERMINATE_ALL) return -ENXIO; - spin_lock_irq(&pd_chan->lock); + spin_lock_bh(&pd_chan->lock); pdc_set_mode(&pd_chan->chan, DMA_CTL0_DISABLE); @@ -710,7 +664,7 @@ static int pd_device_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, list_for_each_entry_safe(desc, _d, &list, desc_node) pdc_chain_complete(pd_chan, desc); - spin_unlock_irq(&pd_chan->lock); + spin_unlock_bh(&pd_chan->lock); return 0; } @@ -739,45 +693,30 @@ static irqreturn_t pd_irq(int irq, void *devid) struct pch_dma *pd = (struct pch_dma *)devid; struct pch_dma_chan *pd_chan; u32 sts0; - u32 sts2; int i; - int ret0 = IRQ_NONE; - int ret2 = IRQ_NONE; + int ret = IRQ_NONE; sts0 = dma_readl(pd, STS0); - sts2 = dma_readl(pd, STS2); dev_dbg(pd->dma.dev, "pd_irq sts0: %x\n", sts0); for (i = 0; i < pd->dma.chancnt; i++) { pd_chan = &pd->channels[i]; - if (i < 8) { - if (sts0 & DMA_STATUS_IRQ(i)) { - if (sts0 & DMA_STATUS0_ERR(i)) - set_bit(0, &pd_chan->err_status); - - tasklet_schedule(&pd_chan->tasklet); - ret0 = IRQ_HANDLED; - } - } else { - if (sts2 & DMA_STATUS_IRQ(i - 8)) { - if (sts2 & DMA_STATUS2_ERR(i)) - set_bit(0, &pd_chan->err_status); + if (sts0 & DMA_STATUS_IRQ(i)) { + if (sts0 & DMA_STATUS_ERR(i)) + set_bit(0, &pd_chan->err_status); - tasklet_schedule(&pd_chan->tasklet); - ret2 = IRQ_HANDLED; - } + tasklet_schedule(&pd_chan->tasklet); + ret = IRQ_HANDLED; } + } /* clear interrupt bits in status register */ - if (ret0) - dma_writel(pd, STS0, sts0); - if (ret2) - dma_writel(pd, STS2, sts2); + dma_writel(pd, STS0, sts0); - return ret0 | ret2; + return ret; } #ifdef CONFIG_PM @@ -1021,8 +960,6 @@ static void __devexit pch_dma_remove(struct pci_dev *pdev) #define PCI_DEVICE_ID_ML7223_DMA2_4CH 0x800E #define PCI_DEVICE_ID_ML7223_DMA3_4CH 0x8017 #define PCI_DEVICE_ID_ML7223_DMA4_4CH 0x803B -#define PCI_DEVICE_ID_ML7831_DMA1_8CH 0x8810 -#define PCI_DEVICE_ID_ML7831_DMA2_4CH 0x8815 DEFINE_PCI_DEVICE_TABLE(pch_dma_id_table) = { { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_EG20T_PCH_DMA_8CH), 8 }, @@ -1035,8 +972,6 @@ DEFINE_PCI_DEVICE_TABLE(pch_dma_id_table) = { { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_DMA2_4CH), 4}, /* Video SPI */ { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_DMA3_4CH), 4}, /* Security */ { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_DMA4_4CH), 4}, /* FPGA */ - { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7831_DMA1_8CH), 8}, /* UART */ - { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7831_DMA2_4CH), 4}, /* SPI */ { 0, }, }; @@ -1064,7 +999,7 @@ static void __exit pch_dma_exit(void) module_init(pch_dma_init); module_exit(pch_dma_exit); -MODULE_DESCRIPTION("Intel EG20T PCH / OKI SEMICON ML7213/ML7223/ML7831 IOH" - "DMA controller driver"); +MODULE_DESCRIPTION("Intel EG20T PCH / OKI SEMICONDUCTOR ML7213 IOH " + "DMA controller driver"); MODULE_AUTHOR("Yong Wang "); MODULE_LICENSE("GPL v2"); diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index feb2d10bba66..9a8bebcf6b17 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -161,11 +161,8 @@ static int __amd64_set_scrub_rate(struct pci_dev *ctl, u32 new_bw, u32 min_rate) * memory controller and apply to register. Search for the first * bandwidth entry that is greater or equal than the setting requested * and program that. If at last entry, turn off DRAM scrubbing. - * - * If no suitable bandwidth is found, turn off DRAM scrubbing entirely - * by falling back to the last element in scrubrates[]. */ - for (i = 0; i < ARRAY_SIZE(scrubrates) - 1; i++) { + for (i = 0; i < ARRAY_SIZE(scrubrates); i++) { /* * skip scrub rates which aren't recommended * (see F10 BKDG, F3x58) @@ -175,6 +172,12 @@ static int __amd64_set_scrub_rate(struct pci_dev *ctl, u32 new_bw, u32 min_rate) if (scrubrates[i].bandwidth <= new_bw) break; + + /* + * if no suitable bandwidth found, turn off DRAM scrubbing + * entirely by falling back to the last element in the + * scrubrates array. + */ } scrubval = scrubrates[i].scrubval; diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c index 8cc8676fa210..495198ad059c 100644 --- a/drivers/edac/edac_pci_sysfs.c +++ b/drivers/edac/edac_pci_sysfs.c @@ -257,7 +257,7 @@ static ssize_t edac_pci_dev_store(struct kobject *kobj, struct edac_pci_dev_attribute *edac_pci_dev; edac_pci_dev = (struct edac_pci_dev_attribute *)attr; - if (edac_pci_dev->store) + if (edac_pci_dev->show) return edac_pci_dev->store(edac_pci_dev->value, buffer, count); return -EIO; } diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 240966b4c7e7..04f1e7ce02b1 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1670,7 +1670,7 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, char *type, *optype, *err, *msg; unsigned long error = m->status & 0x1ff0000l; u32 optypenum = (m->status >> 4) & 0x07; - u32 core_err_cnt = (m->status >> 38) & 0x7fff; + u32 core_err_cnt = (m->status >> 38) && 0x7fff; u32 dimm = (m->misc >> 16) & 0x3; u32 channel = (m->misc >> 18) & 0x3; u32 syndrome = m->misc >> 32; @@ -1842,9 +1842,11 @@ static int i7core_mce_check_error(void *priv, struct mce *mce) if (mce->bank != 8) return 0; +#ifdef CONFIG_SMP /* Only handle if it is the right mc controller */ if (cpu_data(mce->cpu).phys_proc_id != pvt->i7core_dev->socket) return 0; +#endif smp_rmb(); if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) { diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index b97d4f00bb59..b1c11775839c 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -216,33 +216,15 @@ struct inbound_phy_packet_event { struct fw_cdev_event_phy_packet phy_packet; }; -#ifdef CONFIG_COMPAT -static void __user *u64_to_uptr(u64 value) -{ - if (is_compat_task()) - return compat_ptr(value); - else - return (void __user *)(unsigned long)value; -} - -static u64 uptr_to_u64(void __user *ptr) -{ - if (is_compat_task()) - return ptr_to_compat(ptr); - else - return (u64)(unsigned long)ptr; -} -#else -static inline void __user *u64_to_uptr(u64 value) +static inline void __user *u64_to_uptr(__u64 value) { return (void __user *)(unsigned long)value; } -static inline u64 uptr_to_u64(void __user *ptr) +static inline __u64 uptr_to_u64(void __user *ptr) { - return (u64)(unsigned long)ptr; + return (__u64)(unsigned long)ptr; } -#endif /* CONFIG_COMPAT */ static int fw_device_op_open(struct inode *inode, struct file *file) { @@ -271,11 +253,14 @@ static int fw_device_op_open(struct inode *inode, struct file *file) init_waitqueue_head(&client->wait); init_waitqueue_head(&client->tx_flush_wait); INIT_LIST_HEAD(&client->phy_receiver_link); - INIT_LIST_HEAD(&client->link); kref_init(&client->kref); file->private_data = client; + mutex_lock(&device->client_list_mutex); + list_add_tail(&client->link, &device->client_list); + mutex_unlock(&device->client_list_mutex); + return nonseekable_open(inode, file); } @@ -466,20 +451,15 @@ static int ioctl_get_info(struct client *client, union ioctl_arg *arg) if (ret != 0) return -EFAULT; - mutex_lock(&client->device->client_list_mutex); - client->bus_reset_closure = a->bus_reset_closure; if (a->bus_reset != 0) { fill_bus_reset_event(&bus_reset, client); - /* unaligned size of bus_reset is 36 bytes */ - ret = copy_to_user(u64_to_uptr(a->bus_reset), &bus_reset, 36); + if (copy_to_user(u64_to_uptr(a->bus_reset), + &bus_reset, sizeof(bus_reset))) + return -EFAULT; } - if (ret == 0 && list_empty(&client->link)) - list_add_tail(&client->link, &client->device->client_list); - mutex_unlock(&client->device->client_list_mutex); - - return ret ? -EFAULT : 0; + return 0; } static int add_client_resource(struct client *client, @@ -1603,7 +1583,7 @@ static int dispatch_ioctl(struct client *client, if (_IOC_TYPE(cmd) != '#' || _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers) || _IOC_SIZE(cmd) > sizeof(buffer)) - return -ENOTTY; + return -EINVAL; if (_IOC_DIR(cmd) == _IOC_READ) memset(&buffer, 0, _IOC_SIZE(cmd)); diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 9f661e069318..95a471401892 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -455,20 +455,15 @@ static struct device_attribute fw_device_attributes[] = { static int read_rom(struct fw_device *device, int generation, int index, u32 *data) { - u64 offset = (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4; - int i, rcode; + int rcode; /* device->node_id, accessed below, must not be older than generation */ smp_rmb(); - for (i = 10; i < 100; i += 10) { - rcode = fw_run_transaction(device->card, - TCODE_READ_QUADLET_REQUEST, device->node_id, - generation, device->max_speed, offset, data, 4); - if (rcode != RCODE_BUSY) - break; - msleep(i); - } + rcode = fw_run_transaction(device->card, TCODE_READ_QUADLET_REQUEST, + device->node_id, generation, device->max_speed, + (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4, + data, 4); be32_to_cpus(data); return rcode; diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index e74750bc0b76..b9762d07198d 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -863,8 +863,8 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context, if (specifier_id == IANA_SPECIFIER_ID && ver == RFC2734_SW_VERSION) { buf_ptr += 2; length -= IEEE1394_GASP_HDR_SIZE; - fwnet_incoming_packet(dev, buf_ptr, length, source_node_id, - context->card->generation, true); + fwnet_incoming_packet(dev, buf_ptr, length, + source_node_id, -1, true); } packet.payload_length = dev->rcv_buffer_size; @@ -959,12 +959,7 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) break; } - if (ptask->dest_node == IEEE1394_ALL_NODES) { - skb_pull(skb, - ptask->max_payload + IEEE1394_GASP_HDR_SIZE); - } else { - skb_pull(skb, ptask->max_payload); - } + skb_pull(skb, ptask->max_payload); if (ptask->outstanding_pkts > 1) { fwnet_make_sf_hdr(&ptask->hdr, RFC2374_HDR_INTFRAG, dg_size, fg_off, datagram_label); @@ -1067,7 +1062,7 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) smp_rmb(); node_id = dev->card->node_id; - p = skb_push(ptask->skb, IEEE1394_GASP_HDR_SIZE); + p = skb_push(ptask->skb, 8); put_unaligned_be32(node_id << 16 | IANA_SPECIFIER_ID >> 8, p); put_unaligned_be32((IANA_SPECIFIER_ID & 0xff) << 24 | RFC2734_SW_VERSION, &p[4]); diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 271fc518dec5..ebb897329c1e 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -262,7 +262,6 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card) static char ohci_driver_name[] = KBUILD_MODNAME; #define PCI_DEVICE_ID_AGERE_FW643 0x5901 -#define PCI_DEVICE_ID_CREATIVE_SB1394 0x4001 #define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 #define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 #define PCI_VENDOR_ID_PINNACLE_SYSTEMS 0x11bd @@ -286,20 +285,14 @@ static const struct { {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6, QUIRK_NO_MSI}, - {PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_SB1394, PCI_ANY_ID, - QUIRK_RESET_PACKET}, - {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, PCI_ANY_ID, QUIRK_NO_MSI}, {PCI_VENDOR_ID_NEC, PCI_ANY_ID, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, - {PCI_VENDOR_ID_O2, PCI_ANY_ID, PCI_ANY_ID, - QUIRK_NO_MSI}, - {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID, - QUIRK_CYCLE_TIMER | QUIRK_NO_MSI}, + QUIRK_CYCLE_TIMER}, {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, PCI_ANY_ID, QUIRK_CYCLE_TIMER | QUIRK_RESET_PACKET | QUIRK_NO_1394A}, @@ -2558,14 +2551,15 @@ static int handle_ir_buffer_fill(struct context *context, struct iso_context *ctx = container_of(context, struct iso_context, context); - if (last->res_count != 0) + if (!last->transfer_status) /* Descriptor(s) not done yet, stop iteration */ return 0; if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS) ctx->base.callback.mc(&ctx->base, le32_to_cpu(last->data_address) + - le16_to_cpu(last->req_count), + le16_to_cpu(last->req_count) - + le16_to_cpu(last->res_count), ctx->base.callback_data); return 1; diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 17cef864506a..41841a3e3f99 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -1198,10 +1198,6 @@ static int sbp2_remove(struct device *dev) { struct fw_unit *unit = fw_unit(dev); struct sbp2_target *tgt = dev_get_drvdata(&unit->device); - struct sbp2_logical_unit *lu; - - list_for_each_entry(lu, &tgt->lu_list, link) - cancel_delayed_work_sync(&lu->work); sbp2_target_put(tgt); return 0; diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 66b631568cf8..bcb1126e3d00 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -6,7 +6,6 @@ #include #include #include -#include #include /* @@ -16,7 +15,6 @@ */ static char dmi_empty_string[] = " "; -static u16 __initdata dmi_ver; /* * Catch too early calls to dmi_check_system(): */ @@ -113,18 +111,16 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *, dmi_table(buf, dmi_len, dmi_num, decode, NULL); - add_device_randomness(buf, dmi_len); - dmi_iounmap(buf, dmi_len); return 0; } -static int __init dmi_checksum(const u8 *buf, u8 len) +static int __init dmi_checksum(const u8 *buf) { u8 sum = 0; int a; - for (a = 0; a < len; a++) + for (a = 0; a < 15; a++) sum += buf[a]; return sum == 0; @@ -162,10 +158,8 @@ static void __init dmi_save_uuid(const struct dmi_header *dm, int slot, int inde return; for (i = 0; i < 16 && (is_ff || is_00); i++) { - if (d[i] != 0x00) - is_00 = 0; - if (d[i] != 0xFF) - is_ff = 0; + if(d[i] != 0x00) is_ff = 0; + if(d[i] != 0xFF) is_00 = 0; } if (is_ff || is_00) @@ -175,15 +169,7 @@ static void __init dmi_save_uuid(const struct dmi_header *dm, int slot, int inde if (!s) return; - /* - * As of version 2.6 of the SMBIOS specification, the first 3 fields of - * the UUID are supposed to be little-endian encoded. The specification - * says that this is the defacto standard. - */ - if (dmi_ver >= 0x0206) - sprintf(s, "%pUL", d); - else - sprintf(s, "%pUB", d); + sprintf(s, "%pUB", d); dmi_ident[slot] = s; } @@ -415,57 +401,29 @@ static int __init dmi_present(const char __iomem *p) u8 buf[15]; memcpy_fromio(buf, p, 15); - if (dmi_checksum(buf, 15)) { + if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) { dmi_num = (buf[13] << 8) | buf[12]; dmi_len = (buf[7] << 8) | buf[6]; dmi_base = (buf[11] << 24) | (buf[10] << 16) | (buf[9] << 8) | buf[8]; + /* + * DMI version 0.0 means that the real version is taken from + * the SMBIOS version, which we don't know at this point. + */ + if (buf[14] != 0) + printk(KERN_INFO "DMI %d.%d present.\n", + buf[14] >> 4, buf[14] & 0xF); + else + printk(KERN_INFO "DMI present.\n"); if (dmi_walk_early(dmi_decode) == 0) { - if (dmi_ver) - pr_info("SMBIOS %d.%d present.\n", - dmi_ver >> 8, dmi_ver & 0xFF); - else { - dmi_ver = (buf[14] & 0xF0) << 4 | - (buf[14] & 0x0F); - pr_info("Legacy DMI %d.%d present.\n", - dmi_ver >> 8, dmi_ver & 0xFF); - } dmi_dump_ids(); return 0; } } - dmi_ver = 0; return 1; } -static int __init smbios_present(const char __iomem *p) -{ - u8 buf[32]; - int offset = 0; - - memcpy_fromio(buf, p, 32); - if ((buf[5] < 32) && dmi_checksum(buf, buf[5])) { - dmi_ver = (buf[6] << 8) + buf[7]; - - /* Some BIOS report weird SMBIOS version, fix that up */ - switch (dmi_ver) { - case 0x021F: - case 0x0221: - pr_debug("SMBIOS version fixup(2.%d->2.%d)\n", - dmi_ver & 0xFF, 3); - dmi_ver = 0x0203; - break; - case 0x0233: - pr_debug("SMBIOS version fixup(2.%d->2.%d)\n", 51, 6); - dmi_ver = 0x0206; - break; - } - offset = 16; - } - return dmi_present(buf + offset); -} - void __init dmi_scan_machine(void) { char __iomem *p, *q; @@ -483,7 +441,7 @@ void __init dmi_scan_machine(void) if (p == NULL) goto error; - rc = smbios_present(p); + rc = dmi_present(p + 0x10); /* offset of _DMI_ string */ dmi_iounmap(p, 32); if (!rc) { dmi_available = 1; @@ -501,12 +459,7 @@ void __init dmi_scan_machine(void) goto error; for (q = p; q < p + 0x10000; q += 16) { - if (memcmp(q, "_SM_", 4) == 0 && q - p <= 0xFFE0) - rc = smbios_present(q); - else if (memcmp(q, "_DMI_", 5) == 0) - rc = dmi_present(q); - else - continue; + rc = dmi_present(q); if (!rc) { dmi_available = 1; dmi_iounmap(p, 0x10000); diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 6871ed3ea8d1..5f29aafd4462 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -141,213 +141,23 @@ efivar_create_sysfs_entry(struct efivars *efivars, /* Return the number of unicode characters in data */ static unsigned long -utf16_strnlen(efi_char16_t *s, size_t maxlength) +utf8_strlen(efi_char16_t *data, unsigned long maxlength) { unsigned long length = 0; - while (*s++ != 0 && length < maxlength) + while (*data++ != 0 && length < maxlength) length++; return length; } -static inline unsigned long -utf16_strlen(efi_char16_t *s) -{ - return utf16_strnlen(s, ~0UL); -} - /* * Return the number of bytes is the length of this string * Note: this is NOT the same as the number of unicode characters */ static inline unsigned long -utf16_strsize(efi_char16_t *data, unsigned long maxlength) -{ - return utf16_strnlen(data, maxlength/sizeof(efi_char16_t)) * sizeof(efi_char16_t); -} - -static bool -validate_device_path(struct efi_variable *var, int match, u8 *buffer, - unsigned long len) -{ - struct efi_generic_dev_path *node; - int offset = 0; - - node = (struct efi_generic_dev_path *)buffer; - - if (len < sizeof(*node)) - return false; - - while (offset <= len - sizeof(*node) && - node->length >= sizeof(*node) && - node->length <= len - offset) { - offset += node->length; - - if ((node->type == EFI_DEV_END_PATH || - node->type == EFI_DEV_END_PATH2) && - node->sub_type == EFI_DEV_END_ENTIRE) - return true; - - node = (struct efi_generic_dev_path *)(buffer + offset); - } - - /* - * If we're here then either node->length pointed past the end - * of the buffer or we reached the end of the buffer without - * finding a device path end node. - */ - return false; -} - -static bool -validate_boot_order(struct efi_variable *var, int match, u8 *buffer, - unsigned long len) -{ - /* An array of 16-bit integers */ - if ((len % 2) != 0) - return false; - - return true; -} - -static bool -validate_load_option(struct efi_variable *var, int match, u8 *buffer, - unsigned long len) -{ - u16 filepathlength; - int i, desclength = 0, namelen; - - namelen = utf16_strnlen(var->VariableName, sizeof(var->VariableName)); - - /* Either "Boot" or "Driver" followed by four digits of hex */ - for (i = match; i < match+4; i++) { - if (var->VariableName[i] > 127 || - hex_to_bin(var->VariableName[i] & 0xff) < 0) - return true; - } - - /* Reject it if there's 4 digits of hex and then further content */ - if (namelen > match + 4) - return false; - - /* A valid entry must be at least 8 bytes */ - if (len < 8) - return false; - - filepathlength = buffer[4] | buffer[5] << 8; - - /* - * There's no stored length for the description, so it has to be - * found by hand - */ - desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2; - - /* Each boot entry must have a descriptor */ - if (!desclength) - return false; - - /* - * If the sum of the length of the description, the claimed filepath - * length and the original header are greater than the length of the - * variable, it's malformed - */ - if ((desclength + filepathlength + 6) > len) - return false; - - /* - * And, finally, check the filepath - */ - return validate_device_path(var, match, buffer + desclength + 6, - filepathlength); -} - -static bool -validate_uint16(struct efi_variable *var, int match, u8 *buffer, - unsigned long len) +utf8_strsize(efi_char16_t *data, unsigned long maxlength) { - /* A single 16-bit integer */ - if (len != 2) - return false; - - return true; -} - -static bool -validate_ascii_string(struct efi_variable *var, int match, u8 *buffer, - unsigned long len) -{ - int i; - - for (i = 0; i < len; i++) { - if (buffer[i] > 127) - return false; - - if (buffer[i] == 0) - return true; - } - - return false; -} - -struct variable_validate { - char *name; - bool (*validate)(struct efi_variable *var, int match, u8 *data, - unsigned long len); -}; - -static const struct variable_validate variable_validate[] = { - { "BootNext", validate_uint16 }, - { "BootOrder", validate_boot_order }, - { "DriverOrder", validate_boot_order }, - { "Boot*", validate_load_option }, - { "Driver*", validate_load_option }, - { "ConIn", validate_device_path }, - { "ConInDev", validate_device_path }, - { "ConOut", validate_device_path }, - { "ConOutDev", validate_device_path }, - { "ErrOut", validate_device_path }, - { "ErrOutDev", validate_device_path }, - { "Timeout", validate_uint16 }, - { "Lang", validate_ascii_string }, - { "PlatformLang", validate_ascii_string }, - { "", NULL }, -}; - -static bool -validate_var(struct efi_variable *var, u8 *data, unsigned long len) -{ - int i; - u16 *unicode_name = var->VariableName; - - for (i = 0; variable_validate[i].validate != NULL; i++) { - const char *name = variable_validate[i].name; - int match; - - for (match = 0; ; match++) { - char c = name[match]; - u16 u = unicode_name[match]; - - /* All special variables are plain ascii */ - if (u > 127) - return true; - - /* Wildcard in the matching name means we've matched */ - if (c == '*') - return variable_validate[i].validate(var, - match, data, len); - - /* Case sensitive match */ - if (c != u) - break; - - /* Reached the end of the string while matching */ - if (!c) - return variable_validate[i].validate(var, - match, data, len); - } - } - - return true; + return utf8_strlen(data, maxlength/sizeof(efi_char16_t)) * sizeof(efi_char16_t); } static efi_status_t @@ -400,23 +210,12 @@ efivar_attr_read(struct efivar_entry *entry, char *buf) if (status != EFI_SUCCESS) return -EIO; - if (var->Attributes & EFI_VARIABLE_NON_VOLATILE) + if (var->Attributes & 0x1) str += sprintf(str, "EFI_VARIABLE_NON_VOLATILE\n"); - if (var->Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS) + if (var->Attributes & 0x2) str += sprintf(str, "EFI_VARIABLE_BOOTSERVICE_ACCESS\n"); - if (var->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) + if (var->Attributes & 0x4) str += sprintf(str, "EFI_VARIABLE_RUNTIME_ACCESS\n"); - if (var->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) - str += sprintf(str, "EFI_VARIABLE_HARDWARE_ERROR_RECORD\n"); - if (var->Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) - str += sprintf(str, - "EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS\n"); - if (var->Attributes & - EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) - str += sprintf(str, - "EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS\n"); - if (var->Attributes & EFI_VARIABLE_APPEND_WRITE) - str += sprintf(str, "EFI_VARIABLE_APPEND_WRITE\n"); return str - buf; } @@ -484,12 +283,6 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) return -EINVAL; } - if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 || - validate_var(new_var, new_var->Data, new_var->DataSize) == false) { - printk(KERN_ERR "efivars: Malformed variable content\n"); - return -EINVAL; - } - spin_lock(&efivars->lock); status = efivars->ops->set_variable(new_var->VariableName, &new_var->VendorGuid, @@ -615,20 +408,14 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 || - validate_var(new_var, new_var->Data, new_var->DataSize) == false) { - printk(KERN_ERR "efivars: Malformed variable content\n"); - return -EINVAL; - } - spin_lock(&efivars->lock); /* * Does this variable already exist? */ list_for_each_entry_safe(search_efivar, n, &efivars->list, list) { - strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024); - strsize2 = utf16_strsize(new_var->VariableName, 1024); + strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); + strsize2 = utf8_strsize(new_var->VariableName, 1024); if (strsize1 == strsize2 && !memcmp(&(search_efivar->var.VariableName), new_var->VariableName, strsize1) && @@ -660,8 +447,8 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, /* Create the entry in sysfs. Locking is not required here */ status = efivar_create_sysfs_entry(efivars, - utf16_strsize(new_var->VariableName, - 1024), + utf8_strsize(new_var->VariableName, + 1024), new_var->VariableName, &new_var->VendorGuid); if (status) { @@ -690,8 +477,8 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, * Does this variable already exist? */ list_for_each_entry_safe(search_efivar, n, &efivars->list, list) { - strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024); - strsize2 = utf16_strsize(del_var->VariableName, 1024); + strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); + strsize2 = utf8_strsize(del_var->VariableName, 1024); if (strsize1 == strsize2 && !memcmp(&(search_efivar->var.VariableName), del_var->VariableName, strsize1) && diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c index 2763643089c2..ce33f4626957 100644 --- a/drivers/firmware/iscsi_ibft.c +++ b/drivers/firmware/iscsi_ibft.c @@ -738,37 +738,6 @@ static void __exit ibft_exit(void) ibft_cleanup(); } -#ifdef CONFIG_ACPI -static const struct { - char *sign; -} ibft_signs[] = { - /* - * One spec says "IBFT", the other says "iBFT". We have to check - * for both. - */ - { ACPI_SIG_IBFT }, - { "iBFT" }, -}; - -static void __init acpi_find_ibft_region(void) -{ - int i; - struct acpi_table_header *table = NULL; - - if (acpi_disabled) - return; - - for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) { - acpi_get_table(ibft_signs[i].sign, 0, &table); - ibft_addr = (struct acpi_table_ibft *)table; - } -} -#else -static void __init acpi_find_ibft_region(void) -{ -} -#endif - /* * ibft_init() - creates sysfs tree entries for the iBFT data. */ @@ -776,16 +745,9 @@ static int __init ibft_init(void) { int rc = 0; - /* - As on UEFI systems the setup_arch()/find_ibft_region() - is called before ACPI tables are parsed and it only does - legacy finding. - */ - if (!ibft_addr) - acpi_find_ibft_region(); - if (ibft_addr) { - pr_info("iBFT detected.\n"); + printk(KERN_INFO "iBFT detected at 0x%llx.\n", + (u64)isa_virt_to_bus(ibft_addr)); rc = ibft_check_device(); if (rc) diff --git a/drivers/firmware/iscsi_ibft_find.c b/drivers/firmware/iscsi_ibft_find.c index 4da4eb9ae926..bfe723266fd8 100644 --- a/drivers/firmware/iscsi_ibft_find.c +++ b/drivers/firmware/iscsi_ibft_find.c @@ -45,6 +45,13 @@ EXPORT_SYMBOL_GPL(ibft_addr); static const struct { char *sign; } ibft_signs[] = { +#ifdef CONFIG_ACPI + /* + * One spec says "IBFT", the other says "iBFT". We have to check + * for both. + */ + { ACPI_SIG_IBFT }, +#endif { "iBFT" }, { "BIFT" }, /* Broadcom iSCSI Offload */ }; @@ -55,6 +62,14 @@ static const struct { #define VGA_MEM 0xA0000 /* VGA buffer */ #define VGA_SIZE 0x20000 /* 128kB */ +#ifdef CONFIG_ACPI +static int __init acpi_find_ibft(struct acpi_table_header *header) +{ + ibft_addr = (struct acpi_table_ibft *)header; + return 0; +} +#endif /* CONFIG_ACPI */ + static int __init find_ibft_in_mem(void) { unsigned long pos; @@ -79,7 +94,6 @@ static int __init find_ibft_in_mem(void) * the table cannot be valid. */ if (pos + len <= (IBFT_END-1)) { ibft_addr = (struct acpi_table_ibft *)virt; - pr_info("iBFT found at 0x%lx.\n", pos); goto done; } } @@ -94,12 +108,20 @@ done: */ unsigned long __init find_ibft_region(unsigned long *sizep) { +#ifdef CONFIG_ACPI + int i; +#endif ibft_addr = NULL; +#ifdef CONFIG_ACPI + for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) + acpi_table_parse(ibft_signs[i].sign, acpi_find_ibft); +#endif /* CONFIG_ACPI */ + /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will * only use ACPI for this */ - if (!efi_enabled) + if (!ibft_addr && !efi_enabled) find_ibft_in_mem(); if (ibft_addr) { diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c index a330492e06f9..51e0e2d8fac6 100644 --- a/drivers/firmware/pcdp.c +++ b/drivers/firmware/pcdp.c @@ -95,7 +95,7 @@ efi_setup_pcdp_console(char *cmdline) if (efi.hcdp == EFI_INVALID_TABLE_ADDR) return -ENODEV; - pcdp = early_ioremap(efi.hcdp, 4096); + pcdp = ioremap(efi.hcdp, 4096); printk(KERN_INFO "PCDP: v%d at 0x%lx\n", pcdp->rev, efi.hcdp); if (strstr(cmdline, "console=hcdp")) { @@ -131,6 +131,6 @@ efi_setup_pcdp_console(char *cmdline) } out: - early_iounmap(pcdp, 4096); + iounmap(pcdp); return rc; } diff --git a/drivers/firmware/sigma.c b/drivers/firmware/sigma.c index 1eedb6f7fdab..c19cd2c39fa6 100644 --- a/drivers/firmware/sigma.c +++ b/drivers/firmware/sigma.c @@ -11,37 +11,15 @@ #include #include #include -#include #include -static size_t sigma_action_size(struct sigma_action *sa) -{ - size_t payload = 0; - - switch (sa->instr) { - case SIGMA_ACTION_WRITEXBYTES: - case SIGMA_ACTION_WRITESINGLE: - case SIGMA_ACTION_WRITESAFELOAD: - payload = sigma_action_len(sa); - break; - default: - break; - } - - payload = ALIGN(payload, 2); - - return payload + sizeof(struct sigma_action); -} - -/* - * Returns a negative error value in case of an error, 0 if processing of - * the firmware should be stopped after this action, 1 otherwise. - */ +/* Return: 0==OK, <0==error, =1 ==no more actions */ static int -process_sigma_action(struct i2c_client *client, struct sigma_action *sa) +process_sigma_action(struct i2c_client *client, struct sigma_firmware *ssfw) { + struct sigma_action *sa = (void *)(ssfw->fw->data + ssfw->pos); size_t len = sigma_action_len(sa); - int ret; + int ret = 0; pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__, sa->instr, sa->addr, len); @@ -50,50 +28,44 @@ process_sigma_action(struct i2c_client *client, struct sigma_action *sa) case SIGMA_ACTION_WRITEXBYTES: case SIGMA_ACTION_WRITESINGLE: case SIGMA_ACTION_WRITESAFELOAD: + if (ssfw->fw->size < ssfw->pos + len) + return -EINVAL; ret = i2c_master_send(client, (void *)&sa->addr, len); if (ret < 0) return -EINVAL; break; + case SIGMA_ACTION_DELAY: + ret = 0; udelay(len); len = 0; break; + case SIGMA_ACTION_END: - return 0; + return 1; + default: return -EINVAL; } - return 1; + /* when arrive here ret=0 or sent data */ + ssfw->pos += sigma_action_size(sa, len); + return ssfw->pos == ssfw->fw->size; } static int process_sigma_actions(struct i2c_client *client, struct sigma_firmware *ssfw) { - struct sigma_action *sa; - size_t size; - int ret; - - while (ssfw->pos + sizeof(*sa) <= ssfw->fw->size) { - sa = (struct sigma_action *)(ssfw->fw->data + ssfw->pos); - - size = sigma_action_size(sa); - ssfw->pos += size; - if (ssfw->pos > ssfw->fw->size || size == 0) - break; - - ret = process_sigma_action(client, sa); + pr_debug("%s: processing %p\n", __func__, ssfw); + while (1) { + int ret = process_sigma_action(client, ssfw); pr_debug("%s: action returned %i\n", __func__, ret); - - if (ret <= 0) + if (ret == 1) + return 0; + else if (ret) return ret; } - - if (ssfw->pos != ssfw->fw->size) - return -EINVAL; - - return 0; } int process_sigma_firmware(struct i2c_client *client, const char *name) @@ -116,24 +88,16 @@ int process_sigma_firmware(struct i2c_client *client, const char *name) /* then verify the header */ ret = -EINVAL; - - /* - * Reject too small or unreasonable large files. The upper limit has been - * chosen a bit arbitrarily, but it should be enough for all practical - * purposes and having the limit makes it easier to avoid integer - * overflows later in the loading process. - */ - if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000) + if (fw->size < sizeof(*ssfw_head)) goto done; ssfw_head = (void *)fw->data; if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic))) goto done; - crc = crc32(0, fw->data + sizeof(*ssfw_head), - fw->size - sizeof(*ssfw_head)); + crc = crc32(0, fw->data, fw->size); pr_debug("%s: crc=%x\n", __func__, crc); - if (crc != le32_to_cpu(ssfw_head->crc)) + if (crc != ssfw_head->crc) goto done; ssfw.pos = sizeof(*ssfw_head); @@ -149,5 +113,3 @@ int process_sigma_firmware(struct i2c_client *client, const char *name) return ret; } EXPORT_SYMBOL(process_sigma_firmware); - -MODULE_LICENSE("GPL"); diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 80ccce9f6721..2967002a9f82 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -350,19 +350,18 @@ config GPIO_LANGWELL Say Y here to support Intel Langwell/Penwell GPIO. config GPIO_PCH - tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7223/ML7831) GPIO" + tristate "Intel EG20T PCH / OKI SEMICONDUCTOR ML7223 IOH GPIO" depends on PCI && X86 help This driver is for PCH(Platform controller Hub) GPIO of Intel Topcliff which is an IOH(Input/Output Hub) for x86 embedded processor. This driver can access PCH GPIO device. - This driver also can be used for LAPIS Semiconductor IOH(Input/ - Output Hub), ML7223 and ML7831. + This driver also can be used for OKI SEMICONDUCTOR IOH(Input/ + Output Hub), ML7223. ML7223 IOH is for MP(Media Phone) use. - ML7831 IOH is for general purpose use. - ML7223/ML7831 is companion chip for Intel Atom E6xx series. - ML7223/ML7831 is completely compatible for Intel EG20T PCH. + ML7223 is companion chip for Intel Atom E6xx series. + ML7223 is completely compatible for Intel EG20T PCH. config GPIO_ML_IOH tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support" diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index 532f69006264..0451d7ac94ac 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c @@ -437,7 +437,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) do { level = __ffs(pending); - handle_nested_irq(level + chip->irq_base); + generic_handle_irq(level + chip->irq_base); pending &= ~(1 << level); } while (pending); @@ -481,8 +481,8 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, int irq = lvl + chip->irq_base; irq_set_chip_data(irq, chip); - irq_set_chip(irq, &pca953x_irq_chip); - irq_set_nested_thread(irq, true); + irq_set_chip_and_handler(irq, &pca953x_irq_chip, + handle_simple_irq); #ifdef CONFIG_ARM set_irq_flags(irq, IRQF_VALID); #else diff --git a/drivers/gpio/pch_gpio.c b/drivers/gpio/pch_gpio.c index de26978b420b..36919e77c495 100644 --- a/drivers/gpio/pch_gpio.c +++ b/drivers/gpio/pch_gpio.c @@ -287,7 +287,6 @@ static int pch_gpio_resume(struct pci_dev *pdev) static DEFINE_PCI_DEVICE_TABLE(pch_gpio_pcidev_id) = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803) }, { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8014) }, - { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8803) }, { 0, } }; MODULE_DEVICE_TABLE(pci, pch_gpio_pcidev_id); diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile index ca2d3b34dbf5..cc9277885dd0 100644 --- a/drivers/gpu/Makefile +++ b/drivers/gpu/Makefile @@ -1 +1 @@ -obj-y += drm/ vga/ stub/ ion/ +obj-y += drm/ vga/ stub/ diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index ba23790450e9..3f46772f0cb2 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c @@ -101,7 +101,7 @@ static int drm_add_magic(struct drm_master *master, struct drm_file *priv, * Searches and unlinks the entry in drm_device::magiclist with the magic * number hash key, while holding the drm_device::struct_mutex lock. */ -int drm_remove_magic(struct drm_master *master, drm_magic_t magic) +static int drm_remove_magic(struct drm_master *master, drm_magic_t magic) { struct drm_magic_entry *pt; struct drm_hash_item *hash; @@ -136,8 +136,6 @@ int drm_remove_magic(struct drm_master *master, drm_magic_t magic) * If there is a magic number in drm_file::magic then use it, otherwise * searches an unique non-zero magic number and add it associating it with \p * file_priv. - * This ioctl needs protection by the drm_global_mutex, which protects - * struct drm_file::magic and struct drm_magic_entry::priv. */ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -175,8 +173,6 @@ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) * \return zero if authentication successed, or a negative number otherwise. * * Checks if \p file_priv is associated with the magic number passed in \arg. - * This ioctl needs protection by the drm_global_mutex, which protects - * struct drm_file::magic and struct drm_magic_entry::priv. */ int drm_authmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 1367ced8c26d..82db18506662 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1866,10 +1866,6 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev, } if (num_clips && clips_ptr) { - if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) { - ret = -EINVAL; - goto out_err1; - } clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); if (!clips) { ret = -ENOMEM; diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index a303b613a170..09292193dafe 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -127,23 +127,6 @@ static const u8 edid_header[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; - /* - * Sanity check the header of the base EDID block. Return 8 if the header - * is perfect, down to 0 if it's totally wrong. - */ -int drm_edid_header_is_valid(const u8 *raw_edid) -{ - int i, score = 0; - - for (i = 0; i < sizeof(edid_header); i++) - if (raw_edid[i] == edid_header[i]) - score++; - - return score; -} -EXPORT_SYMBOL(drm_edid_header_is_valid); - - /* * Sanity check the EDID block (base or extension). Return 0 if the block * doesn't check out, or 1 if it's valid. @@ -156,7 +139,12 @@ drm_edid_block_valid(u8 *raw_edid) struct edid *edid = (struct edid *)raw_edid; if (raw_edid[0] == 0x00) { - int score = drm_edid_header_is_valid(raw_edid); + int score = 0; + + for (i = 0; i < sizeof(edid_header); i++) + if (raw_edid[i] == edid_header[i]) + score++; + if (score == 8) ; else if (score >= 6) { DRM_DEBUG("Fixing EDID header, your hardware may be failing\n"); @@ -584,7 +572,7 @@ static bool drm_monitor_supports_rb(struct edid *edid) { if (edid->revision >= 4) { - bool ret = false; + bool ret; drm_for_each_detailed_block((u8 *)edid, is_rb, &ret); return ret; } diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index a9dcdc7d3728..802b61ac3139 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -610,13 +610,9 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, return -EINVAL; /* Need to resize the fb object !!! */ - if (var->bits_per_pixel > fb->bits_per_pixel || - var->xres > fb->width || var->yres > fb->height || - var->xres_virtual > fb->width || var->yres_virtual > fb->height) { + if (var->bits_per_pixel > fb->bits_per_pixel || var->xres > fb->width || var->yres > fb->height) { DRM_DEBUG("fb userspace requested width/height/bpp is greater than current fb " - "request %dx%d-%d (virtual %dx%d) > %dx%d-%d\n", - var->xres, var->yres, var->bits_per_pixel, - var->xres_virtual, var->yres_virtual, + "object %dx%d-%d > %dx%d-%d\n", var->xres, var->yres, var->bits_per_pixel, fb->width, fb->height, fb->bits_per_pixel); return -EINVAL; } diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 72fa601d4c47..2ec7d48fc4a8 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -135,11 +135,8 @@ int drm_open(struct inode *inode, struct file *filp) retcode = drm_open_helper(inode, filp, dev); if (!retcode) { atomic_inc(&dev->counts[_DRM_STAT_OPENS]); - if (!dev->open_count++) { + if (!dev->open_count++) retcode = drm_setup(dev); - if (retcode) - dev->open_count--; - } } if (!retcode) { mutex_lock(&dev->struct_mutex); @@ -489,11 +486,6 @@ int drm_release(struct inode *inode, struct file *filp) (long)old_encode_dev(file_priv->minor->device), dev->open_count); - /* Release any auth tokens that might point to this file_priv, - (do that under the drm_global_mutex) */ - if (file_priv->magic) - (void) drm_remove_magic(file_priv->master, file_priv->magic); - /* if the master has gone away we can't do anything with the lock */ if (file_priv->minor->master) drm_master_release(dev, filp); diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index e36efdc67e1f..0a893f7400fa 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -865,7 +865,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) MEMSTAT_VID_SHIFT); seq_printf(m, "Current P-state: %d\n", (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT); - } else if (IS_GEN6(dev) || IS_GEN7(dev)) { + } else if (IS_GEN6(dev)) { u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); u32 rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS); u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index ef164432ba6d..296fbd66f0e1 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -61,6 +61,7 @@ static void i915_write_hws_pga(struct drm_device *dev) static int i915_init_phys_hws(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; + struct intel_ring_buffer *ring = LP_RING(dev_priv); /* Program Hardware Status Page */ dev_priv->status_page_dmah = @@ -70,9 +71,10 @@ static int i915_init_phys_hws(struct drm_device *dev) DRM_ERROR("Can not allocate hardware status page\n"); return -ENOMEM; } + ring->status_page.page_addr = + (void __force __iomem *)dev_priv->status_page_dmah->vaddr; - memset_io((void __force __iomem *)dev_priv->status_page_dmah->vaddr, - 0, PAGE_SIZE); + memset_io(ring->status_page.page_addr, 0, PAGE_SIZE); i915_write_hws_pga(dev); @@ -1451,14 +1453,6 @@ unsigned long i915_chipset_val(struct drm_i915_private *dev_priv) diff1 = now - dev_priv->last_time1; - /* Prevent division-by-zero if we are asking too fast. - * Also, we don't get interesting results if we are polling - * faster than once in 10ms, so just return the saved value - * in such cases. - */ - if (diff1 <= 10) - return dev_priv->chipset_power; - count1 = I915_READ(DMIEC); count2 = I915_READ(DDREC); count3 = I915_READ(CSIEC); @@ -1489,8 +1483,6 @@ unsigned long i915_chipset_val(struct drm_i915_private *dev_priv) dev_priv->last_count1 = total_count; dev_priv->last_time1 = now; - dev_priv->chipset_power = ret; - return ret; } diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 111686ada271..eb91e2dd7914 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -379,10 +379,6 @@ static int i915_drm_freeze(struct drm_device *dev) /* Modeset on resume, not lid events */ dev_priv->modeset_on_lid = 0; - console_lock(); - intel_fbdev_set_suspend(dev, 1); - console_unlock(); - return 0; } @@ -442,9 +438,7 @@ static int i915_drm_thaw(struct drm_device *dev) drm_irq_install(dev); /* Resume the modeset for every activated CRTC */ - mutex_lock(&dev->mode_config.mutex); drm_helper_resume_force_mode(dev); - mutex_unlock(&dev->mode_config.mutex); if (IS_IRONLAKE_M(dev)) ironlake_enable_rc6(dev); @@ -454,9 +448,6 @@ static int i915_drm_thaw(struct drm_device *dev) dev_priv->modeset_on_lid = 0; - console_lock(); - intel_fbdev_set_suspend(dev, 0); - console_unlock(); return error; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b570415c3fd9..ce7914c4c044 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -325,8 +325,6 @@ typedef struct drm_i915_private { struct timer_list hangcheck_timer; int hangcheck_count; uint32_t last_acthd; - uint32_t last_acthd_bsd; - uint32_t last_acthd_blt; uint32_t last_instdone; uint32_t last_instdone1; @@ -543,7 +541,6 @@ typedef struct drm_i915_private { u32 savePIPEB_LINK_M1; u32 savePIPEB_LINK_N1; u32 saveMCHBAR_RENDER_STANDBY; - u32 savePCH_PORT_HOTPLUG; struct { /** Bridge to intel-gtt-ko */ @@ -704,7 +701,6 @@ typedef struct drm_i915_private { u64 last_count1; unsigned long last_time1; - unsigned long chipset_power; u64 last_count2; struct timespec last_time2; unsigned long gfx_power; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5548593040bf..a087e1bf0c2f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1475,7 +1475,7 @@ i915_gem_mmap_gtt(struct drm_file *file, if (obj->base.size > dev_priv->mm.gtt_mappable_end) { ret = -E2BIG; - goto out; + goto unlock; } if (obj->madv != I915_MADV_WILLNEED) { diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 490ab6b17cfb..4934cf84c320 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -655,8 +655,6 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, total = 0; for (i = 0; i < count; i++) { struct drm_i915_gem_relocation_entry __user *user_relocs; - u64 invalid_offset = (u64)-1; - int j; user_relocs = (void __user *)(uintptr_t)exec[i].relocs_ptr; @@ -667,25 +665,6 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, goto err; } - /* As we do not update the known relocation offsets after - * relocating (due to the complexities in lock handling), - * we need to mark them as invalid now so that we force the - * relocation processing next time. Just in case the target - * object is evicted and then rebound into its old - * presumed_offset before the next execbuffer - if that - * happened we would make the mistake of assuming that the - * relocations were valid. - */ - for (j = 0; j < exec[i].relocation_count; j++) { - if (copy_to_user(&user_relocs[j].presumed_offset, - &invalid_offset, - sizeof(invalid_offset))) { - ret = -EFAULT; - mutex_lock(&dev->struct_mutex); - goto err; - } - } - reloc_offset[i] = total; total += exec[i].relocation_count; } @@ -1067,11 +1046,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, return -EINVAL; } - if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) { - DRM_DEBUG("execbuf with %u cliprects\n", - args->num_cliprects); - return -EINVAL; - } cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects), GFP_KERNEL); if (cliprects == NULL) { @@ -1322,8 +1296,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, struct drm_i915_gem_exec_object2 *exec2_list = NULL; int ret; - if (args->buffer_count < 1 || - args->buffer_count > UINT_MAX / sizeof(*exec2_list)) { + if (args->buffer_count < 1) { DRM_ERROR("execbuf2 with %d buffers\n", args->buffer_count); return -EINVAL; } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index d05f03c62847..3b03f85ea627 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -306,15 +306,12 @@ static void i915_hotplug_work_func(struct work_struct *work) struct drm_mode_config *mode_config = &dev->mode_config; struct intel_encoder *encoder; - mutex_lock(&mode_config->mutex); DRM_DEBUG_KMS("running encoder hotplug functions\n"); list_for_each_entry(encoder, &mode_config->encoder_list, base.head) if (encoder->hot_plug) encoder->hot_plug(encoder); - mutex_unlock(&mode_config->mutex); - /* Just fire off a uevent and let userspace tell us what to do */ drm_helper_hpd_irq_event(dev); } @@ -422,11 +419,14 @@ static void gen6_pm_rps_work(struct work_struct *work) mutex_unlock(&dev_priv->dev->struct_mutex); } -static void pch_irq_handler(struct drm_device *dev, u32 pch_iir) +static void pch_irq_handler(struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + u32 pch_iir; int pipe; + pch_iir = I915_READ(SDEIIR); + if (pch_iir & SDE_AUDIO_POWER_MASK) DRM_DEBUG_DRIVER("PCH audio power change on port %d\n", (pch_iir & SDE_AUDIO_POWER_MASK) >> @@ -524,7 +524,7 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) if (de_iir & DE_PCH_EVENT_IVB) { if (pch_iir & SDE_HOTPLUG_MASK_CPT) queue_work(dev_priv->wq, &dev_priv->hotplug_work); - pch_irq_handler(dev, pch_iir); + pch_irq_handler(dev); } if (pm_iir & GEN6_PM_DEFERRED_EVENTS) { @@ -623,7 +623,7 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) if (de_iir & DE_PCH_EVENT) { if (pch_iir & hotplug_mask) queue_work(dev_priv->wq, &dev_priv->hotplug_work); - pch_irq_handler(dev, pch_iir); + pch_irq_handler(dev); } if (de_iir & DE_PCU_EVENT) { @@ -817,7 +817,6 @@ static void i915_gem_record_fences(struct drm_device *dev, /* Fences */ switch (INTEL_INFO(dev)->gen) { - case 7: case 6: for (i = 0; i < 16; i++) error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); @@ -1662,7 +1661,7 @@ void i915_hangcheck_elapsed(unsigned long data) { struct drm_device *dev = (struct drm_device *)data; drm_i915_private_t *dev_priv = dev->dev_private; - uint32_t acthd, instdone, instdone1, acthd_bsd, acthd_blt; + uint32_t acthd, instdone, instdone1; bool err = false; /* If all work is done then ACTHD clearly hasn't advanced. */ @@ -1676,21 +1675,16 @@ void i915_hangcheck_elapsed(unsigned long data) } if (INTEL_INFO(dev)->gen < 4) { + acthd = I915_READ(ACTHD); instdone = I915_READ(INSTDONE); instdone1 = 0; } else { + acthd = I915_READ(ACTHD_I965); instdone = I915_READ(INSTDONE_I965); instdone1 = I915_READ(INSTDONE1); } - acthd = intel_ring_get_active_head(&dev_priv->ring[RCS]); - acthd_bsd = HAS_BSD(dev) ? - intel_ring_get_active_head(&dev_priv->ring[VCS]) : 0; - acthd_blt = HAS_BLT(dev) ? - intel_ring_get_active_head(&dev_priv->ring[BCS]) : 0; if (dev_priv->last_acthd == acthd && - dev_priv->last_acthd_bsd == acthd_bsd && - dev_priv->last_acthd_blt == acthd_blt && dev_priv->last_instdone == instdone && dev_priv->last_instdone1 == instdone1) { if (dev_priv->hangcheck_count++ > 1) { @@ -1722,8 +1716,6 @@ void i915_hangcheck_elapsed(unsigned long data) dev_priv->hangcheck_count = 0; dev_priv->last_acthd = acthd; - dev_priv->last_acthd_bsd = acthd_bsd; - dev_priv->last_acthd_blt = acthd_blt; dev_priv->last_instdone = instdone; dev_priv->last_instdone1 = instdone1; } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5dc3b6d39321..5d5def756c9e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -27,8 +27,6 @@ #define _PIPE(pipe, a, b) ((a) + (pipe)*((b)-(a))) -#define _MASKED_BIT_ENABLE(a) (((a) << 16) | (a)) - /* * The Bridge device's PCI config space has information about the * fb aperture size and the amount of pre-reserved memory. @@ -356,7 +354,6 @@ * the enables for writing to the corresponding low bit. */ #define _3D_CHICKEN 0x02084 -#define _3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB (1 << 10) #define _3D_CHICKEN2 0x0208c /* Disables pipelining of read flushes past the SF-WIZ interface. * Required on all Ironlake steppings according to the B-Spec, but the @@ -540,21 +537,6 @@ #define GEN6_BSD_RNCID 0x12198 -#define GEN7_FF_THREAD_MODE 0x20a0 -#define GEN7_FF_SCHED_MASK 0x0077070 -#define GEN7_FF_TS_SCHED_HS1 (0x5<<16) -#define GEN7_FF_TS_SCHED_HS0 (0x3<<16) -#define GEN7_FF_TS_SCHED_LOAD_BALANCE (0x1<<16) -#define GEN7_FF_TS_SCHED_HW (0x0<<16) /* Default */ -#define GEN7_FF_VS_SCHED_HS1 (0x5<<12) -#define GEN7_FF_VS_SCHED_HS0 (0x3<<12) -#define GEN7_FF_VS_SCHED_LOAD_BALANCE (0x1<<12) /* Default */ -#define GEN7_FF_VS_SCHED_HW (0x0<<12) -#define GEN7_FF_DS_SCHED_HS1 (0x5<<4) -#define GEN7_FF_DS_SCHED_HS0 (0x3<<4) -#define GEN7_FF_DS_SCHED_LOAD_BALANCE (0x1<<4) /* Default */ -#define GEN7_FF_DS_SCHED_HW (0x0<<4) - /* * Framebuffer compression (915+ only) */ @@ -2292,7 +2274,6 @@ #define PIPECONF_DISABLE 0 #define PIPECONF_DOUBLE_WIDE (1<<30) #define I965_PIPECONF_ACTIVE (1<<30) -#define PIPECONF_FRAME_START_DELAY_MASK (3<<27) #define PIPECONF_SINGLE_WIDE 0 #define PIPECONF_PIPE_UNLOCKED 0 #define PIPECONF_PIPE_LOCKED (1<<25) @@ -2563,18 +2544,10 @@ #define _CURBBASE 0x700c4 #define _CURBPOS 0x700c8 -#define _CURBCNTR_IVB 0x71080 -#define _CURBBASE_IVB 0x71084 -#define _CURBPOS_IVB 0x71088 - #define CURCNTR(pipe) _PIPE(pipe, _CURACNTR, _CURBCNTR) #define CURBASE(pipe) _PIPE(pipe, _CURABASE, _CURBBASE) #define CURPOS(pipe) _PIPE(pipe, _CURAPOS, _CURBPOS) -#define CURCNTR_IVB(pipe) _PIPE(pipe, _CURACNTR, _CURBCNTR_IVB) -#define CURBASE_IVB(pipe) _PIPE(pipe, _CURABASE, _CURBBASE_IVB) -#define CURPOS_IVB(pipe) _PIPE(pipe, _CURAPOS, _CURBPOS_IVB) - /* Display A control */ #define _DSPACNTR 0x70180 #define DISPLAY_PLANE_ENABLE (1<<31) @@ -2757,8 +2730,6 @@ #define _PFA_CTL_1 0x68080 #define _PFB_CTL_1 0x68880 #define PF_ENABLE (1<<31) -#define PF_PIPE_SEL_MASK_IVB (3<<29) -#define PF_PIPE_SEL_IVB(pipe) ((pipe)<<29) #define PF_FILTER_MASK (3<<23) #define PF_FILTER_PROGRAMMED (0<<23) #define PF_FILTER_MED_3x3 (1<<23) @@ -2868,20 +2839,6 @@ #define DISP_TILE_SURFACE_SWIZZLING (1<<13) #define DISP_FBC_WM_DIS (1<<15) -/* GEN7 chicken */ -#define GEN7_COMMON_SLICE_CHICKEN1 0x7010 -# define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC ((1<<10) | (1<<26)) - -#define GEN7_L3CNTLREG1 0xB01C -#define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C4FFF8C - -#define GEN7_L3_CHICKEN_MODE_REGISTER 0xB030 -#define GEN7_WA_L3_CHICKEN_MODE 0x20000000 - -/* WaCatErrorRejectionIssue */ -#define GEN7_SQ_CHICKEN_MBCUNIT_CONFIG 0x9030 -#define GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB (1<<11) - /* PCH */ /* south display engine interrupt */ @@ -3118,11 +3075,6 @@ #define TRANS_6BPC (2<<5) #define TRANS_12BPC (3<<5) -#define _TRANSA_CHICKEN2 0xf0064 -#define _TRANSB_CHICKEN2 0xf1064 -#define TRANS_CHICKEN2(pipe) _PIPE(pipe, _TRANSA_CHICKEN2, _TRANSB_CHICKEN2) -#define TRANS_AUTOTRAIN_GEN_STALL_DIS (1<<31) - #define SOUTH_CHICKEN2 0xc2004 #define DPLS_EDP_PPS_FIX_DIS (1<<0) @@ -3181,7 +3133,6 @@ #define FDI_LINK_TRAIN_NONE_IVB (3<<8) /* both Tx and Rx */ -#define FDI_COMPOSITE_SYNC (1<<11) #define FDI_LINK_TRAIN_AUTO (1<<10) #define FDI_SCRAMBLING_ENABLE (0<<7) #define FDI_SCRAMBLING_DISABLE (1<<7) @@ -3410,11 +3361,6 @@ #define GT_FIFO_FREE_ENTRIES 0x120008 -#define GEN6_UCGCTL2 0x9404 -# define GEN6_RCZUNIT_CLOCK_GATE_DISABLE (1 << 13) -# define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) -# define GEN6_RCCUNIT_CLOCK_GATE_DISABLE (1 << 11) - #define GEN6_RPNSWREQ 0xA008 #define GEN6_TURBO_DISABLE (1<<31) #define GEN6_FREQUENCY(x) ((x)<<25) diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 5ad0b5124b75..5257cfc34c35 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -34,10 +34,6 @@ static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) struct drm_i915_private *dev_priv = dev->dev_private; u32 dpll_reg; - /* On IVB, 3rd pipe shares PLL with another one */ - if (pipe > 1) - return false; - if (HAS_PCH_SPLIT(dev)) dpll_reg = (pipe == PIPE_A) ? _PCH_DPLL_A : _PCH_DPLL_B; else @@ -374,7 +370,6 @@ static void i915_save_modeset_reg(struct drm_device *dev) /* Fences */ switch (INTEL_INFO(dev)->gen) { - case 7: case 6: for (i = 0; i < 16; i++) dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); @@ -409,7 +404,6 @@ static void i915_restore_modeset_reg(struct drm_device *dev) /* Fences */ switch (INTEL_INFO(dev)->gen) { - case 7: case 6: for (i = 0; i < 16; i++) I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]); @@ -739,11 +733,8 @@ static void i915_restore_display(struct drm_device *dev) if (HAS_PCH_SPLIT(dev)) { I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL); I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2); - /* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2; - * otherwise we get blank eDP screen after S3 on some machines - */ - I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->saveBLC_CPU_PWM_CTL2); I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); + I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->saveBLC_CPU_PWM_CTL2); I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); I915_WRITE(PCH_PP_DIVISOR, dev_priv->savePP_DIVISOR); @@ -823,7 +814,6 @@ int i915_save_state(struct drm_device *dev) dev_priv->saveFDI_RXB_IMR = I915_READ(_FDI_RXB_IMR); dev_priv->saveMCHBAR_RENDER_STANDBY = I915_READ(RSTDBYCTL); - dev_priv->savePCH_PORT_HOTPLUG = I915_READ(PCH_PORT_HOTPLUG); } else { dev_priv->saveIER = I915_READ(IER); dev_priv->saveIMR = I915_READ(IMR); @@ -875,7 +865,6 @@ int i915_restore_state(struct drm_device *dev) I915_WRITE(GTIMR, dev_priv->saveGTIMR); I915_WRITE(_FDI_RXA_IMR, dev_priv->saveFDI_RXA_IMR); I915_WRITE(_FDI_RXB_IMR, dev_priv->saveFDI_RXB_IMR); - I915_WRITE(PCH_PORT_HOTPLUG, dev_priv->savePCH_PORT_HOTPLUG); } else { I915_WRITE(IER, dev_priv->saveIER); I915_WRITE(IMR, dev_priv->saveIMR); diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index e5fa074b7830..927442a11925 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -24,7 +24,6 @@ * Eric Anholt * */ -#include #include #include "drmP.h" #include "drm.h" @@ -593,26 +592,6 @@ init_vbt_defaults(struct drm_i915_private *dev_priv) dev_priv->edp.bpp = 18; } -static int __init intel_no_opregion_vbt_callback(const struct dmi_system_id *id) -{ - DRM_DEBUG_KMS("Falling back to manually reading VBT from " - "VBIOS ROM for %s\n", - id->ident); - return 1; -} - -static const struct dmi_system_id intel_no_opregion_vbt[] = { - { - .callback = intel_no_opregion_vbt_callback, - .ident = "ThinkCentre A57", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "97027RG"), - }, - }, - { } -}; - /** * intel_parse_bios - find VBT and initialize settings from the BIOS * @dev: DRM device @@ -633,7 +612,7 @@ intel_parse_bios(struct drm_device *dev) init_vbt_defaults(dev_priv); /* XXX Should this validation be moved to intel_opregion.c? */ - if (!dmi_check_system(intel_no_opregion_vbt) && dev_priv->opregion.vbt) { + if (dev_priv->opregion.vbt) { struct vbt_header *vbt = dev_priv->opregion.vbt; if (memcmp(vbt->signature, "$VBT", 4) == 0) { DRM_DEBUG_DRIVER("Using VBT from OpRegion: %20s\n", diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b4f4d12e717c..0f1c799afea1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2340,7 +2340,6 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc) temp |= FDI_LINK_TRAIN_PATTERN_1_IVB; temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; - temp |= FDI_COMPOSITE_SYNC; I915_WRITE(reg, temp | FDI_TX_ENABLE); reg = FDI_RX_CTL(pipe); @@ -2348,7 +2347,6 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc) temp &= ~FDI_LINK_TRAIN_AUTO; temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; - temp |= FDI_COMPOSITE_SYNC; I915_WRITE(reg, temp | FDI_RX_ENABLE); POSTING_READ(reg); @@ -2696,27 +2694,19 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) * as some pre-programmed values are broken, * e.g. x201. */ - if (IS_IVYBRIDGE(dev)) - I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3 | - PF_PIPE_SEL_IVB(pipe)); - else - I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3); + I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3); I915_WRITE(PF_WIN_POS(pipe), dev_priv->pch_pf_pos); I915_WRITE(PF_WIN_SZ(pipe), dev_priv->pch_pf_size); } - /* - * On ILK+ LUT must be loaded before the pipe is running but with - * clocks enabled - */ - intel_crtc_load_lut(crtc); - intel_enable_pipe(dev_priv, pipe, is_pch_port); intel_enable_plane(dev_priv, plane, pipe); if (is_pch_port) ironlake_pch_enable(crtc); + intel_crtc_load_lut(crtc); + mutex_lock(&dev->struct_mutex); intel_update_fbc(dev); mutex_unlock(&dev->struct_mutex); @@ -4976,7 +4966,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, } else if (is_sdvo && is_tv) factor = 20; - if (clock.m < factor * clock.n) + if (clock.m1 < factor * clock.n) fp |= FP_CB_TUNE; dpll = 0; @@ -5269,7 +5259,7 @@ void intel_crtc_load_lut(struct drm_crtc *crtc) int i; /* The clocks have to be on to load the palette. */ - if (!crtc->enabled || !intel_crtc->active) + if (!crtc->enabled) return; /* use legacy palette for Ironlake */ @@ -5340,31 +5330,6 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) I915_WRITE(CURBASE(pipe), base); } -static void ivb_update_cursor(struct drm_crtc *crtc, u32 base) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - bool visible = base != 0; - - if (intel_crtc->cursor_visible != visible) { - uint32_t cntl = I915_READ(CURCNTR_IVB(pipe)); - if (base) { - cntl &= ~CURSOR_MODE; - cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; - } else { - cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); - cntl |= CURSOR_MODE_DISABLE; - } - I915_WRITE(CURCNTR_IVB(pipe), cntl); - - intel_crtc->cursor_visible = visible; - } - /* and commit changes on next vblank */ - I915_WRITE(CURBASE_IVB(pipe), base); -} - /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on) @@ -5412,16 +5377,11 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc, if (!visible && !intel_crtc->cursor_visible) return; - if (IS_IVYBRIDGE(dev)) { - I915_WRITE(CURPOS_IVB(pipe), pos); - ivb_update_cursor(crtc, base); - } else { - I915_WRITE(CURPOS(pipe), pos); - if (IS_845G(dev) || IS_I865G(dev)) - i845_update_cursor(crtc, base); - else - i9xx_update_cursor(crtc, base); - } + I915_WRITE(CURPOS(pipe), pos); + if (IS_845G(dev) || IS_I865G(dev)) + i845_update_cursor(crtc, base); + else + i9xx_update_cursor(crtc, base); if (visible) intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj); @@ -6583,13 +6543,6 @@ static void intel_sanitize_modesetting(struct drm_device *dev, { struct drm_i915_private *dev_priv = dev->dev_private; u32 reg, val; - int i; - - /* Clear any frame start delays used for debugging left by the BIOS */ - for_each_pipe(i) { - reg = PIPECONF(i); - I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); - } if (HAS_PCH_SPLIT(dev)) return; @@ -7412,28 +7365,10 @@ static void gen6_init_clock_gating(struct drm_device *dev) I915_READ(ILK_DISPLAY_CHICKEN2) | ILK_ELPIN_409_SELECT); - /* WaDisableHiZPlanesWhenMSAAEnabled */ - I915_WRITE(_3D_CHICKEN, - _MASKED_BIT_ENABLE(_3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB)); - I915_WRITE(WM3_LP_ILK, 0); I915_WRITE(WM2_LP_ILK, 0); I915_WRITE(WM1_LP_ILK, 0); - /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock - * gating disable must be set. Failure to set it results in - * flickering pixels due to Z write ordering failures after - * some amount of runtime in the Mesa "fire" demo, and Unigine - * Sanctuary and Tropics, and apparently anything else with - * alpha test or pixel discard. - * - * According to the spec, bit 11 (RCCUNIT) must also be set, - * but we didn't debug actual testcases to find it out. - */ - I915_WRITE(GEN6_UCGCTL2, - GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | - GEN6_RCCUNIT_CLOCK_GATE_DISABLE); - /* * According to the spec the following bits should be * set in order to enable memory self-refresh and fbc: @@ -7460,18 +7395,6 @@ static void gen6_init_clock_gating(struct drm_device *dev) DISPPLANE_TRICKLE_FEED_DISABLE); } -static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv) -{ - uint32_t reg = I915_READ(GEN7_FF_THREAD_MODE); - - reg &= ~GEN7_FF_SCHED_MASK; - reg |= GEN7_FF_TS_SCHED_HW; - reg |= GEN7_FF_VS_SCHED_HW; - reg |= GEN7_FF_DS_SCHED_HW; - - I915_WRITE(GEN7_FF_THREAD_MODE, reg); -} - static void ivybridge_init_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -7484,28 +7407,8 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) I915_WRITE(WM2_LP_ILK, 0); I915_WRITE(WM1_LP_ILK, 0); - /* According to the spec, bit 13 (RCZUNIT) must be set on IVB. - * This implements the WaDisableRCZUnitClockGating workaround. - */ - I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE); - I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); - /* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */ - I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1, - GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC); - - /* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */ - I915_WRITE(GEN7_L3CNTLREG1, - GEN7_WA_FOR_GEN7_L3_CONTROL); - I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, - GEN7_WA_L3_CHICKEN_MODE); - - /* This is required by WaCatErrorRejectionIssue */ - I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, - I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | - GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); - for_each_pipe(pipe) I915_WRITE(DSPCNTR(pipe), I915_READ(DSPCNTR(pipe)) | @@ -7592,7 +7495,6 @@ static void ibx_init_clock_gating(struct drm_device *dev) static void cpt_init_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - int pipe; /* * On Ibex Peak and Cougar Point, we need to disable clock @@ -7602,9 +7504,6 @@ static void cpt_init_clock_gating(struct drm_device *dev) I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) | DPLS_EDP_PPS_FIX_DIS); - /* Without this, mode sets may fail silently on FDI */ - for_each_pipe(pipe) - I915_WRITE(TRANS_CHICKEN2(pipe), TRANS_AUTOTRAIN_GEN_STALL_DIS); } static void ironlake_teardown_rc6(struct drm_device *dev) @@ -7622,8 +7521,6 @@ static void ironlake_teardown_rc6(struct drm_device *dev) drm_gem_object_unreference(&dev_priv->pwrctx->base); dev_priv->pwrctx = NULL; } - - gen7_setup_fixed_func_scheduler(dev_priv); } static void ironlake_disable_rc6(struct drm_device *dev) @@ -8042,7 +7939,7 @@ void intel_modeset_init(struct drm_device *dev) intel_init_emon(dev); } - if (IS_GEN6(dev) || IS_GEN7(dev)) + if (IS_GEN6(dev)) gen6_enable_rps(dev_priv); INIT_WORK(&dev_priv->idle_work, intel_idle_update); @@ -8084,7 +7981,7 @@ void intel_modeset_cleanup(struct drm_device *dev) if (IS_IRONLAKE_M(dev)) ironlake_disable_drps(dev); - if (IS_GEN6(dev) || IS_GEN7(dev)) + if (IS_GEN6(dev)) gen6_disable_rps(dev); if (IS_IRONLAKE_M(dev)) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index bf9fea941617..e2aced6eec4c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1554,7 +1554,6 @@ intel_dp_link_down(struct intel_dp *intel_dp) intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); } - DP &= ~DP_AUDIO_OUTPUT_ENABLE; I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); POSTING_READ(intel_dp->output_reg); } @@ -1659,31 +1658,6 @@ g4x_dp_detect(struct intel_dp *intel_dp) return status; } -static struct edid * -intel_dp_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) -{ - struct intel_dp *intel_dp = intel_attached_dp(connector); - struct edid *edid; - - ironlake_edp_panel_vdd_on(intel_dp); - edid = drm_get_edid(connector, adapter); - ironlake_edp_panel_vdd_off(intel_dp); - return edid; -} - -static int -intel_dp_get_edid_modes(struct drm_connector *connector, struct i2c_adapter *adapter) -{ - struct intel_dp *intel_dp = intel_attached_dp(connector); - int ret; - - ironlake_edp_panel_vdd_on(intel_dp); - ret = intel_ddc_get_modes(connector, adapter); - ironlake_edp_panel_vdd_off(intel_dp); - return ret; -} - - /** * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection. * @@ -1710,7 +1684,7 @@ intel_dp_detect(struct drm_connector *connector, bool force) if (intel_dp->force_audio) { intel_dp->has_audio = intel_dp->force_audio > 0; } else { - edid = intel_dp_get_edid(connector, &intel_dp->adapter); + edid = drm_get_edid(connector, &intel_dp->adapter); if (edid) { intel_dp->has_audio = drm_detect_monitor_audio(edid); connector->display_info.raw_edid = NULL; @@ -1731,7 +1705,7 @@ static int intel_dp_get_modes(struct drm_connector *connector) /* We should parse the EDID data and find out if it has an audio sink */ - ret = intel_dp_get_edid_modes(connector, &intel_dp->adapter); + ret = intel_ddc_get_modes(connector, &intel_dp->adapter); if (ret) { if (is_edp(intel_dp) && !dev_priv->panel_fixed_mode) { struct drm_display_mode *newmode; @@ -1767,7 +1741,7 @@ intel_dp_detect_audio(struct drm_connector *connector) struct edid *edid; bool has_audio = false; - edid = intel_dp_get_edid(connector, &intel_dp->adapter); + edid = drm_get_edid(connector, &intel_dp->adapter); if (edid) { has_audio = drm_detect_monitor_audio(edid); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 58b54ff36108..9ffa61eb4d7e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -204,7 +204,7 @@ struct dip_infoframe { uint16_t bottom_bar_start; uint16_t left_bar_end; uint16_t right_bar_start; - } __attribute__ ((packed)) avi; + } avi; uint8_t payload[27]; } __attribute__ ((packed)) body; } __attribute__((packed)); @@ -330,7 +330,7 @@ extern int intel_framebuffer_init(struct drm_device *dev, struct drm_i915_gem_object *obj); extern int intel_fbdev_init(struct drm_device *dev); extern void intel_fbdev_fini(struct drm_device *dev); -extern void intel_fbdev_set_suspend(struct drm_device *dev, int state); + extern void intel_prepare_page_flip(struct drm_device *dev, int plane); extern void intel_finish_page_flip(struct drm_device *dev, int pipe); extern void intel_finish_page_flip_plane(struct drm_device *dev, int plane); diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index d0ce34b78cc7..ec49bae73382 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -257,16 +257,6 @@ void intel_fbdev_fini(struct drm_device *dev) kfree(dev_priv->fbdev); dev_priv->fbdev = NULL; } - -void intel_fbdev_set_suspend(struct drm_device *dev, int state) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - if (!dev_priv->fbdev) - return; - - fb_set_suspend(dev_priv->fbdev->helper.fbdev, state); -} - MODULE_LICENSE("GPL and additional rights"); void intel_fb_output_poll_changed(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 918bac898ee9..aa0a8e83142e 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -158,10 +158,6 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); u32 temp; - u32 enable_bits = SDVO_ENABLE; - - if (intel_hdmi->has_audio || mode != DRM_MODE_DPMS_ON) - enable_bits |= SDVO_AUDIO_ENABLE; temp = I915_READ(intel_hdmi->sdvox_reg); @@ -174,9 +170,9 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) } if (mode != DRM_MODE_DPMS_ON) { - temp &= ~enable_bits; + temp &= ~SDVO_ENABLE; } else { - temp |= enable_bits; + temp |= SDVO_ENABLE; } I915_WRITE(intel_hdmi->sdvox_reg, temp); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index eebf0028619b..b28f7bd9f88a 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -712,14 +712,6 @@ static const struct dmi_system_id intel_no_lvds[] = { DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), }, }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "AOpen i45GMx-I", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), - DMI_MATCH(DMI_BOARD_NAME, "i45GMx-I"), - }, - }, { .callback = intel_no_lvds_dmi_callback, .ident = "Aopen i945GTt-VFA", @@ -743,30 +735,6 @@ static const struct dmi_system_id intel_no_lvds[] = { DMI_MATCH(DMI_PRODUCT_NAME, "EB1007"), }, }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "MSI Wind Box DC500", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), - DMI_MATCH(DMI_BOARD_NAME, "MS-7469"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "Gigabyte GA-D525TUD", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), - DMI_MATCH(DMI_BOARD_NAME, "D525TUD"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "Supermicro X7SPA-H", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"), - DMI_MATCH(DMI_PRODUCT_NAME, "X7SPA-H"), - }, - }, { } /* terminating entry */ }; diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 1fe7c073fa83..9e2959bc91cd 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -428,17 +428,9 @@ static int intel_overlay_off(struct intel_overlay *overlay) OUT_RING(flip_addr); OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); /* turn overlay off */ - if (IS_I830(dev)) { - /* Workaround: Don't disable the overlay fully, since otherwise - * it dies on the next OVERLAY_ON cmd. */ - OUT_RING(MI_NOOP); - OUT_RING(MI_NOOP); - OUT_RING(MI_NOOP); - } else { - OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF); - OUT_RING(flip_addr); - OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); - } + OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF); + OUT_RING(flip_addr); + OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); ADVANCE_LP_RING(); return intel_overlay_do_wait_request(overlay, request, diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index f8aa8211fed1..a06ff07a4d3b 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -83,15 +83,11 @@ intel_pch_panel_fitting(struct drm_device *dev, u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; if (scaled_width > scaled_height) { /* pillar */ width = scaled_height / mode->vdisplay; - if (width & 1) - width++; x = (adjusted_mode->hdisplay - width + 1) / 2; y = 0; height = adjusted_mode->vdisplay; } else if (scaled_width < scaled_height) { /* letter */ height = scaled_width / mode->hdisplay; - if (height & 1) - height++; y = (adjusted_mode->vdisplay - height + 1) / 2; x = 0; width = adjusted_mode->hdisplay; @@ -226,7 +222,7 @@ static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level) I915_WRITE(BLC_PWM_CPU_CTL, val | level); } -static void intel_panel_actually_set_backlight(struct drm_device *dev, u32 level) +void intel_panel_set_backlight(struct drm_device *dev, u32 level) { struct drm_i915_private *dev_priv = dev->dev_private; u32 tmp; @@ -254,21 +250,16 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev, u32 level I915_WRITE(BLC_PWM_CTL, tmp | level); } -void intel_panel_set_backlight(struct drm_device *dev, u32 level) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - dev_priv->backlight_level = level; - if (dev_priv->backlight_enabled) - intel_panel_actually_set_backlight(dev, level); -} - void intel_panel_disable_backlight(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - dev_priv->backlight_enabled = false; - intel_panel_actually_set_backlight(dev, 0); + if (dev_priv->backlight_enabled) { + dev_priv->backlight_level = intel_panel_get_backlight(dev); + dev_priv->backlight_enabled = false; + } + + intel_panel_set_backlight(dev, 0); } void intel_panel_enable_backlight(struct drm_device *dev) @@ -278,8 +269,8 @@ void intel_panel_enable_backlight(struct drm_device *dev) if (dev_priv->backlight_level == 0) dev_priv->backlight_level = intel_panel_get_max_backlight(dev); + intel_panel_set_backlight(dev, dev_priv->backlight_level); dev_priv->backlight_enabled = true; - intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); } void intel_panel_setup_backlight(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 3bd85f7e3904..95c4b1429935 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -150,6 +150,8 @@ static int init_ring_common(struct intel_ring_buffer *ring) I915_WRITE_HEAD(ring, 0); ring->write_tail(ring, 0); + /* Initialize the ring. */ + I915_WRITE_START(ring, obj->gtt_offset); head = I915_READ_HEAD(ring) & HEAD_ADDR; /* G45 ring initialization fails to reset head to zero */ @@ -175,11 +177,6 @@ static int init_ring_common(struct intel_ring_buffer *ring) } } - /* Initialize the ring. This must happen _after_ we've cleared the ring - * registers with the above sequence (the readback of the HEAD registers - * also enforces ordering), otherwise the hw might lose the new ring - * register values. */ - I915_WRITE_START(ring, obj->gtt_offset); I915_WRITE_CTL(ring, ((ring->size - PAGE_SIZE) & RING_NR_PAGES) | RING_REPORT_64K | RING_VALID); @@ -866,7 +863,7 @@ int intel_init_ring_buffer(struct drm_device *dev, * of the buffer. */ ring->effective_size = ring->size; - if (IS_I830(ring->dev) || IS_845G(ring->dev)) + if (IS_I830(ring->dev)) ring->effective_size -= 128; return 0; @@ -1322,9 +1319,6 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) ring->get_seqno = pc_render_get_seqno; } - if (!I915_NEED_GFX_HWS(dev)) - ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; - ring->dev = dev; INIT_LIST_HEAD(&ring->active_list); INIT_LIST_HEAD(&ring->request_list); diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d1141e83356d..30fe554d8936 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -724,7 +724,6 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, uint16_t width, height; uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; uint16_t h_sync_offset, v_sync_offset; - int mode_clock; width = mode->crtc_hdisplay; height = mode->crtc_vdisplay; @@ -739,11 +738,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start; v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; - mode_clock = mode->clock; - mode_clock /= intel_mode_get_pixel_multiplier(mode) ?: 1; - mode_clock /= 10; - dtd->part1.clock = mode_clock; - + dtd->part1.clock = mode->clock / 10; dtd->part1.h_active = width & 0xff; dtd->part1.h_blank = h_blank_len & 0xff; dtd->part1.h_high = (((width >> 8) & 0xf) << 4) | @@ -762,12 +757,10 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, ((v_sync_len & 0x30) >> 4); dtd->part2.dtd_flags = 0x18; - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - dtd->part2.dtd_flags |= DTD_FLAG_INTERLACE; if (mode->flags & DRM_MODE_FLAG_PHSYNC) - dtd->part2.dtd_flags |= DTD_FLAG_HSYNC_POSITIVE; + dtd->part2.dtd_flags |= 0x2; if (mode->flags & DRM_MODE_FLAG_PVSYNC) - dtd->part2.dtd_flags |= DTD_FLAG_VSYNC_POSITIVE; + dtd->part2.dtd_flags |= 0x4; dtd->part2.sdvo_flags = 0; dtd->part2.v_sync_off_high = v_sync_offset & 0xc0; @@ -801,11 +794,9 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, mode->clock = dtd->part1.clock * 10; mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); - if (dtd->part2.dtd_flags & DTD_FLAG_INTERLACE) - mode->flags |= DRM_MODE_FLAG_INTERLACE; - if (dtd->part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) + if (dtd->part2.dtd_flags & 0x2) mode->flags |= DRM_MODE_FLAG_PHSYNC; - if (dtd->part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) + if (dtd->part2.dtd_flags & 0x4) mode->flags |= DRM_MODE_FLAG_PVSYNC; } @@ -861,38 +852,31 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) } #endif -static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, - unsigned if_index, uint8_t tx_rate, - uint8_t *data, unsigned length) +static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) { - uint8_t set_buf_index[2] = { if_index, 0 }; - uint8_t hbuf_size, tmp[8]; - int i; + struct dip_infoframe avi_if = { + .type = DIP_TYPE_AVI, + .ver = DIP_VERSION_AVI, + .len = DIP_LEN_AVI, + }; + uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; + uint8_t set_buf_index[2] = { 1, 0 }; + uint64_t *data = (uint64_t *)&avi_if; + unsigned i; + + intel_dip_infoframe_csum(&avi_if); if (!intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2)) return false; - if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO, - &hbuf_size, 1)) - return false; - - /* Buffer size is 0 based, hooray! */ - hbuf_size++; - - DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n", - if_index, length, hbuf_size); - - for (i = 0; i < hbuf_size; i += 8) { - memset(tmp, 0, 8); - if (i < length) - memcpy(tmp, data + i, min_t(unsigned, 8, length - i)); - + for (i = 0; i < sizeof(avi_if); i += 8) { if (!intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_HBUF_DATA, - tmp, 8)) + data, 8)) return false; + data++; } return intel_sdvo_set_value(intel_sdvo, @@ -900,28 +884,6 @@ static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, &tx_rate, 1); } -static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) -{ - struct dip_infoframe avi_if = { - .type = DIP_TYPE_AVI, - .ver = DIP_VERSION_AVI, - .len = DIP_LEN_AVI, - }; - uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; - - intel_dip_infoframe_csum(&avi_if); - - /* sdvo spec says that the ecc is handled by the hw, and it looks like - * we must not send the ecc field, either. */ - memcpy(sdvo_data, &avi_if, 3); - sdvo_data[3] = avi_if.checksum; - memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); - - return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, - SDVO_HBUF_TX_VSYNC, - sdvo_data, sizeof(sdvo_data)); -} - static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) { struct intel_sdvo_tv_format format; @@ -1028,7 +990,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); u32 sdvox; struct intel_sdvo_in_out_map in_out; - struct intel_sdvo_dtd input_dtd, output_dtd; + struct intel_sdvo_dtd input_dtd; int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); int rate; @@ -1053,13 +1015,20 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, intel_sdvo->attached_output)) return; - /* lvds has a special fixed output timing. */ - if (intel_sdvo->is_lvds) - intel_sdvo_get_dtd_from_mode(&output_dtd, - intel_sdvo->sdvo_lvds_fixed_mode); - else - intel_sdvo_get_dtd_from_mode(&output_dtd, mode); - (void) intel_sdvo_set_output_timing(intel_sdvo, &output_dtd); + /* We have tried to get input timing in mode_fixup, and filled into + * adjusted_mode. + */ + if (intel_sdvo->is_tv || intel_sdvo->is_lvds) { + input_dtd = intel_sdvo->input_dtd; + } else { + /* Set the output timing to the screen */ + if (!intel_sdvo_set_target_output(intel_sdvo, + intel_sdvo->attached_output)) + return; + + intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); + (void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd); + } /* Set the input timing to the screen. Assume always input 0. */ if (!intel_sdvo_set_target_input(intel_sdvo)) @@ -1077,10 +1046,6 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, !intel_sdvo_set_tv_format(intel_sdvo)) return; - /* We have tried to get input timing in mode_fixup, and filled into - * adjusted_mode. - */ - intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); switch (pixel_multiplier) { @@ -1094,13 +1059,15 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, /* Set the SDVO control regs. */ if (INTEL_INFO(dev)->gen >= 4) { - /* The real mode polarity is set by the SDVO commands, using - * struct intel_sdvo_dtd. */ - sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH; + sdvox = 0; if (intel_sdvo->is_hdmi) sdvox |= intel_sdvo->color_range; if (INTEL_INFO(dev)->gen < 5) sdvox |= SDVO_BORDER_ENABLE; + if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) + sdvox |= SDVO_VSYNC_ACTIVE_HIGH; + if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) + sdvox |= SDVO_HSYNC_ACTIVE_HIGH; } else { sdvox = I915_READ(intel_sdvo->sdvo_reg); switch (intel_sdvo->sdvo_reg) { diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h index 50bebc36404e..4f4e23bc2d16 100644 --- a/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h @@ -61,11 +61,6 @@ struct intel_sdvo_caps { u16 output_flags; } __attribute__((packed)); -/* Note: SDVO detailed timing flags match EDID misc flags. */ -#define DTD_FLAG_HSYNC_POSITIVE (1 << 1) -#define DTD_FLAG_VSYNC_POSITIVE (1 << 2) -#define DTD_FLAG_INTERLACE (1 << 7) - /** This matches the EDID DTD structure, more or less */ struct intel_sdvo_dtd { struct { @@ -708,8 +703,6 @@ struct intel_sdvo_enhancements_arg { #define SDVO_CMD_SET_AUDIO_STAT 0x91 #define SDVO_CMD_GET_AUDIO_STAT 0x92 #define SDVO_CMD_SET_HBUF_INDEX 0x93 - #define SDVO_HBUF_INDEX_ELD 0 - #define SDVO_HBUF_INDEX_AVI_IF 1 #define SDVO_CMD_GET_HBUF_INDEX 0x94 #define SDVO_CMD_GET_HBUF_INFO 0x95 #define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 2136e6bc8937..113e4e7264cd 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -417,7 +417,7 @@ static const struct tv_mode tv_modes[] = { { .name = "NTSC-M", .clock = 108000, - .refresh = 59940, + .refresh = 29970, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ @@ -460,7 +460,7 @@ static const struct tv_mode tv_modes[] = { { .name = "NTSC-443", .clock = 108000, - .refresh = 59940, + .refresh = 29970, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */ @@ -502,7 +502,7 @@ static const struct tv_mode tv_modes[] = { { .name = "NTSC-J", .clock = 108000, - .refresh = 59940, + .refresh = 29970, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, @@ -545,7 +545,7 @@ static const struct tv_mode tv_modes[] = { { .name = "PAL-M", .clock = 108000, - .refresh = 59940, + .refresh = 29970, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, @@ -589,7 +589,7 @@ static const struct tv_mode tv_modes[] = { /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ .name = "PAL-N", .clock = 108000, - .refresh = 50000, + .refresh = 25000, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, @@ -634,7 +634,7 @@ static const struct tv_mode tv_modes[] = { /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ .name = "PAL", .clock = 108000, - .refresh = 50000, + .refresh = 25000, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, @@ -821,7 +821,7 @@ static const struct tv_mode tv_modes[] = { { .name = "1080i@50Hz", .clock = 148800, - .refresh = 50000, + .refresh = 25000, .oversample = TV_OVERSAMPLE_2X, .component_only = 1, @@ -847,7 +847,7 @@ static const struct tv_mode tv_modes[] = { { .name = "1080i@60Hz", .clock = 148800, - .refresh = 60000, + .refresh = 30000, .oversample = TV_OVERSAMPLE_2X, .component_only = 1, @@ -1301,11 +1301,6 @@ intel_tv_detect_type (struct intel_tv *intel_tv, I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN); I915_WRITE(TV_CTL, save_tv_ctl); - POSTING_READ(TV_CTL); - - /* For unknown reasons the hw barfs if we don't do this vblank wait. */ - intel_wait_for_vblank(intel_tv->base.base.dev, - to_intel_crtc(intel_tv->base.base.crtc)->pipe); /* Restore interrupt config */ if (connector->polled & DRM_CONNECTOR_POLL_HPD) { diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 5fb98de0c57d..2ad49cbf7c8b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1075,7 +1075,7 @@ nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo) nvbo->placement.fpfn = 0; nvbo->placement.lpfn = dev_priv->fb_mappable_pages; - nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_VRAM, 0); + nouveau_bo_placement_set(nvbo, TTM_PL_VRAM, 0); return nouveau_bo_validate(nvbo, false, true, false); } diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index d31d355f5ed0..a7583a8ddb01 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -159,7 +159,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, INIT_LIST_HEAD(&chan->nvsw.vbl_wait); INIT_LIST_HEAD(&chan->nvsw.flip); INIT_LIST_HEAD(&chan->fence.pending); - spin_lock_init(&chan->fence.lock); /* Allocate DMA push buffer */ chan->pushbuf_bo = nouveau_channel_user_pushbuf_alloc(dev); diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index ea71f78fb552..39aee6d4daf8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -487,7 +487,7 @@ int nouveau_fbcon_init(struct drm_device *dev) nfbdev->helper.funcs = &nouveau_fbcon_helper_funcs; ret = drm_fb_helper_init(dev, &nfbdev->helper, - dev->mode_config.num_crtc, 4); + nv_two_heads(dev) ? 2 : 1, 4); if (ret) { kfree(nfbdev); return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 56f06b0cfdb6..7347075ca5b8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -542,6 +542,8 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) return ret; } + INIT_LIST_HEAD(&chan->fence.pending); + spin_lock_init(&chan->fence.lock); atomic_set(&chan->fence.last_sequence_irq, 0); return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index cee78b26f60f..b52e46018245 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -314,25 +314,6 @@ retry: return 0; } -static int -validate_sync(struct nouveau_channel *chan, struct nouveau_bo *nvbo) -{ - struct nouveau_fence *fence = NULL; - int ret = 0; - - spin_lock(&nvbo->bo.bdev->fence_lock); - if (nvbo->bo.sync_obj) - fence = nouveau_fence_ref(nvbo->bo.sync_obj); - spin_unlock(&nvbo->bo.bdev->fence_lock); - - if (fence) { - ret = nouveau_fence_sync(fence, chan); - nouveau_fence_unref(&fence); - } - - return ret; -} - static int validate_list(struct nouveau_channel *chan, struct list_head *list, struct drm_nouveau_gem_pushbuf_bo *pbbo, uint64_t user_pbbo_ptr) @@ -346,7 +327,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, list_for_each_entry(nvbo, list, entry) { struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; - ret = validate_sync(chan, nvbo); + ret = nouveau_fence_sync(nvbo->bo.sync_obj, chan); if (unlikely(ret)) { NV_ERROR(dev, "fail pre-validate sync\n"); return ret; @@ -369,7 +350,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, return ret; } - ret = validate_sync(chan, nvbo); + ret = nouveau_fence_sync(nvbo->bo.sync_obj, chan); if (unlikely(ret)) { NV_ERROR(dev, "fail post-validate sync\n"); return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index ca6028f24b80..82fad914e648 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -37,11 +37,8 @@ nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages, return -ENOMEM; nvbe->ttm_alloced = kmalloc(sizeof(bool) * num_pages, GFP_KERNEL); - if (!nvbe->ttm_alloced) { - kfree(nvbe->pages); - nvbe->pages = NULL; + if (!nvbe->ttm_alloced) return -ENOMEM; - } nvbe->nr_pages = 0; while (num_pages--) { diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index 2d6bfd03dc1a..e000455e06d0 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c @@ -209,7 +209,7 @@ out: NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode); if (blue == 0x18) { - NV_DEBUG(dev, "Load detected on head A\n"); + NV_INFO(dev, "Load detected on head A\n"); return connector_status_connected; } @@ -323,7 +323,7 @@ nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) if (nv17_dac_sample_load(encoder) & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { - NV_DEBUG(dev, "Load detected on output %c\n", + NV_INFO(dev, "Load detected on output %c\n", '@' + ffs(dcb->or)); return connector_status_connected; } else { @@ -398,7 +398,7 @@ static void nv04_dac_commit(struct drm_encoder *encoder) helper->dpms(encoder, DRM_MODE_DPMS_ON); - NV_DEBUG(dev, "Output %s is running on CRTC %d using output %c\n", + NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); } @@ -447,7 +447,7 @@ static void nv04_dac_dpms(struct drm_encoder *encoder, int mode) return; nv_encoder->last_dpms = mode; - NV_DEBUG(dev, "Setting dpms mode %d on vga encoder (output %d)\n", + NV_INFO(dev, "Setting dpms mode %d on vga encoder (output %d)\n", mode, nv_encoder->dcb->index); nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index 752440c7a3d0..12098bf839c4 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c @@ -468,7 +468,7 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) helper->dpms(encoder, DRM_MODE_DPMS_ON); - NV_DEBUG(dev, "Output %s is running on CRTC %d using output %c\n", + NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); } @@ -511,7 +511,7 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) return; nv_encoder->last_dpms = mode; - NV_DEBUG(dev, "Setting dpms mode %d on lvds encoder (output %d)\n", + NV_INFO(dev, "Setting dpms mode %d on lvds encoder (output %d)\n", mode, nv_encoder->dcb->index); if (was_powersaving && is_powersaving_dpms(mode)) @@ -556,7 +556,7 @@ static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode) return; nv_encoder->last_dpms = mode; - NV_DEBUG(dev, "Setting dpms mode %d on tmds encoder (output %d)\n", + NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n", mode, nv_encoder->dcb->index); nv04_dfp_update_backlight(encoder, mode); diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c index 4de1fbeb8497..3eb605ddfd03 100644 --- a/drivers/gpu/drm/nouveau/nv04_tv.c +++ b/drivers/gpu/drm/nouveau/nv04_tv.c @@ -69,7 +69,7 @@ static void nv04_tv_dpms(struct drm_encoder *encoder, int mode) struct nv04_mode_state *state = &dev_priv->mode_reg; uint8_t crtc1A; - NV_DEBUG(dev, "Setting dpms mode %d on TV encoder (output %d)\n", + NV_INFO(dev, "Setting dpms mode %d on TV encoder (output %d)\n", mode, nv_encoder->dcb->index); state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK); @@ -162,7 +162,7 @@ static void nv04_tv_commit(struct drm_encoder *encoder) helper->dpms(encoder, DRM_MODE_DPMS_ON); - NV_DEBUG(dev, "Output %s is running on CRTC %d using output %c\n", + NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); } diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 88661eaa2c74..ebdb0fdb8348 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -277,12 +277,7 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr, case ATOM_ARG_FB: idx = U8(*ptr); (*ptr)++; - if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) { - DRM_ERROR("ATOM: fb read beyond scratch region: %d vs. %d\n", - gctx->fb_base + (idx * 4), gctx->scratch_size_bytes); - val = 0; - } else - val = gctx->scratch[(gctx->fb_base / 4) + idx]; + val = gctx->scratch[((gctx->fb_base + idx) / 4)]; if (print) DEBUG("FB[0x%02X]", idx); break; @@ -536,11 +531,7 @@ static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr, case ATOM_ARG_FB: idx = U8(*ptr); (*ptr)++; - if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) { - DRM_ERROR("ATOM: fb write beyond scratch region: %d vs. %d\n", - gctx->fb_base + (idx * 4), gctx->scratch_size_bytes); - } else - gctx->scratch[(gctx->fb_base / 4) + idx] = val; + gctx->scratch[((gctx->fb_base + idx) / 4)] = val; DEBUG("FB[0x%02X]", idx); break; case ATOM_ARG_PLL: @@ -1301,11 +1292,8 @@ struct atom_context *atom_parse(struct card_info *card, void *bios) int atom_asic_init(struct atom_context *ctx) { - struct radeon_device *rdev = ctx->card->dev->dev_private; int hwi = CU16(ctx->data_table + ATOM_DATA_FWI_PTR); uint32_t ps[16]; - int ret; - memset(ps, 0, 64); ps[0] = cpu_to_le32(CU32(hwi + ATOM_FWI_DEFSCLK_PTR)); @@ -1315,17 +1303,7 @@ int atom_asic_init(struct atom_context *ctx) if (!CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_INIT)) return 1; - ret = atom_execute_table(ctx, ATOM_CMD_INIT, ps); - if (ret) - return ret; - - memset(ps, 0, 64); - - if (rdev->family < CHIP_R600) { - if (CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_SPDFANCNTL)) - atom_execute_table(ctx, ATOM_CMD_SPDFANCNTL, ps); - } - return ret; + return atom_execute_table(ctx, ATOM_CMD_INIT, ps); } void atom_destroy(struct atom_context *ctx) @@ -1389,13 +1367,11 @@ int atom_allocate_fb_scratch(struct atom_context *ctx) usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024; } - ctx->scratch_size_bytes = 0; if (usage_bytes == 0) usage_bytes = 20 * 1024; /* allocate some scratch memory */ ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL); if (!ctx->scratch) return -ENOMEM; - ctx->scratch_size_bytes = usage_bytes; return 0; } diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h index 25fea631dad2..a589a55b223e 100644 --- a/drivers/gpu/drm/radeon/atom.h +++ b/drivers/gpu/drm/radeon/atom.h @@ -44,7 +44,6 @@ #define ATOM_CMD_SETSCLK 0x0A #define ATOM_CMD_SETMCLK 0x0B #define ATOM_CMD_SETPCLK 0x0C -#define ATOM_CMD_SPDFANCNTL 0x39 #define ATOM_DATA_FWI_PTR 0xC #define ATOM_DATA_IIO_PTR 0x32 @@ -138,7 +137,6 @@ struct atom_context { int cs_equal, cs_above; int io_mode; uint32_t *scratch; - int scratch_size_bytes; }; extern int atom_debug; diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 071ded119eb9..9541995e4b21 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1173,7 +1173,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1); WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, - target_fb->height); + crtc->mode.vdisplay); x &= ~3; y &= ~1; WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset, @@ -1342,7 +1342,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1); WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, - target_fb->height); + crtc->mode.vdisplay); x &= ~3; y &= ~1; WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset, diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index efc2b214b340..8c0f9e36ff8e 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -22,7 +22,6 @@ * * Authors: Dave Airlie * Alex Deucher - * Jerome Glisse */ #include "drmP.h" #include "radeon_drm.h" @@ -116,7 +115,6 @@ static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, u8 msg[20]; int msg_bytes = send_bytes + 4; u8 ack; - unsigned retry; if (send_bytes > 16) return -1; @@ -127,22 +125,20 @@ static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, msg[3] = (msg_bytes << 4) | (send_bytes - 1); memcpy(&msg[4], send, send_bytes); - for (retry = 0; retry < 4; retry++) { + while (1) { ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_bytes, NULL, 0, delay, &ack); - if (ret == -EBUSY) - continue; - else if (ret < 0) + if (ret < 0) return ret; if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) - return send_bytes; + break; else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) udelay(400); else return -EIO; } - return -EIO; + return send_bytes; } static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, @@ -153,31 +149,26 @@ static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, int msg_bytes = 4; u8 ack; int ret; - unsigned retry; msg[0] = address; msg[1] = address >> 8; msg[2] = AUX_NATIVE_READ << 4; msg[3] = (msg_bytes << 4) | (recv_bytes - 1); - for (retry = 0; retry < 4; retry++) { + while (1) { ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_bytes, recv, recv_bytes, delay, &ack); - if (ret == -EBUSY) - continue; - else if (ret < 0) + if (ret == 0) + return -EPROTO; + if (ret < 0) return ret; if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) return ret; else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) udelay(400); - else if (ret == 0) - return -EPROTO; else return -EIO; } - - return -EIO; } static void radeon_write_dpcd_reg(struct radeon_connector *radeon_connector, @@ -241,9 +232,7 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, for (retry = 0; retry < 4; retry++) { ret = radeon_process_aux_ch(auxch, msg, msg_bytes, reply, reply_bytes, 0, &ack); - if (ret == -EBUSY) - continue; - else if (ret < 0) { + if (ret < 0) { DRM_DEBUG_KMS("aux_ch failed %d\n", ret); return ret; } @@ -284,7 +273,7 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, } } - DRM_DEBUG_KMS("aux i2c too many retries, giving up\n"); + DRM_ERROR("aux i2c too many retries, giving up\n"); return -EREMOTEIO; } @@ -554,7 +543,6 @@ static void radeon_dp_set_panel_mode(struct drm_encoder *encoder, { struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; - struct radeon_connector *radeon_connector = to_radeon_connector(connector); int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; if (!ASIC_IS_DCE4(rdev)) @@ -562,20 +550,10 @@ static void radeon_dp_set_panel_mode(struct drm_encoder *encoder, if (radeon_connector_encoder_is_dp_bridge(connector)) panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; - else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { - u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); - if (tmp & 1) - panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; - } atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP_PANEL_MODE, panel_mode); - - if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) && - (panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) { - radeon_write_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_SET, 1); - } } void radeon_dp_set_link_config(struct drm_connector *connector, @@ -625,6 +603,7 @@ static bool radeon_dp_get_link_status(struct radeon_connector *radeon_connector, ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS, link_status, DP_LINK_STATUS_SIZE, 100); if (ret <= 0) { + DRM_ERROR("displayport link status failed\n"); return false; } @@ -634,18 +613,6 @@ static bool radeon_dp_get_link_status(struct radeon_connector *radeon_connector, return true; } -bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector) -{ - u8 link_status[DP_LINK_STATUS_SIZE]; - struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; - - if (!radeon_dp_get_link_status(radeon_connector, link_status)) - return false; - if (dp_channel_eq_ok(link_status, dig->dp_lane_count)) - return false; - return true; -} - struct radeon_dp_link_train_info { struct radeon_device *rdev; struct drm_encoder *encoder; @@ -660,7 +627,6 @@ struct radeon_dp_link_train_info { u8 train_set[4]; u8 link_status[DP_LINK_STATUS_SIZE]; u8 tries; - bool use_dpencoder; }; static void radeon_dp_update_vs_emph(struct radeon_dp_link_train_info *dp_info) @@ -680,7 +646,7 @@ static void radeon_dp_set_tp(struct radeon_dp_link_train_info *dp_info, int tp) int rtp = 0; /* set training pattern on the source */ - if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) { + if (ASIC_IS_DCE4(dp_info->rdev)) { switch (tp) { case DP_TRAINING_PATTERN_1: rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1; @@ -740,7 +706,7 @@ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LINK_BW_SET, tmp); /* start training on the source */ - if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) + if (ASIC_IS_DCE4(dp_info->rdev)) atombios_dig_encoder_setup(dp_info->encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_START, 0); else @@ -765,7 +731,7 @@ static int radeon_dp_link_train_finish(struct radeon_dp_link_train_info *dp_info DP_TRAINING_PATTERN_DISABLE); /* disable the training pattern on the source */ - if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) + if (ASIC_IS_DCE4(dp_info->rdev)) atombios_dig_encoder_setup(dp_info->encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE, 0); else @@ -797,10 +763,8 @@ static int radeon_dp_link_train_cr(struct radeon_dp_link_train_info *dp_info) else mdelay(dp_info->rd_interval * 4); - if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) { - DRM_ERROR("displayport link status failed\n"); + if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) break; - } if (dp_clock_recovery_ok(dp_info->link_status, dp_info->dp_lane_count)) { clock_recovery = true; @@ -862,10 +826,8 @@ static int radeon_dp_link_train_ce(struct radeon_dp_link_train_info *dp_info) else mdelay(dp_info->rd_interval * 4); - if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) { - DRM_ERROR("displayport link status failed\n"); + if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) break; - } if (dp_channel_eq_ok(dp_info->link_status, dp_info->dp_lane_count)) { channel_eq = true; @@ -907,8 +869,7 @@ void radeon_dp_link_train(struct drm_encoder *encoder, struct radeon_connector *radeon_connector; struct radeon_connector_atom_dig *dig_connector; struct radeon_dp_link_train_info dp_info; - int index; - u8 tmp, frev, crev; + u8 tmp; if (!radeon_encoder->enc_priv) return; @@ -923,18 +884,6 @@ void radeon_dp_link_train(struct drm_encoder *encoder, (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_eDP)) return; - /* DPEncoderService newer than 1.1 can't program properly the - * training pattern. When facing such version use the - * DIGXEncoderControl (X== 1 | 2) - */ - dp_info.use_dpencoder = true; - index = GetIndexIntoMasterTable(COMMAND, DPEncoderService); - if (atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) { - if (crev > 1) { - dp_info.use_dpencoder = false; - } - } - dp_info.enc_id = 0; if (dig->dig_encoder) dp_info.enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index a75d290b4f96..15bd0477a3e8 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -41,31 +41,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev); void evergreen_fini(struct radeon_device *rdev); static void evergreen_pcie_gen2_enable(struct radeon_device *rdev); -void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) -{ - u16 ctl, v; - int cap, err; - - cap = pci_pcie_cap(rdev->pdev); - if (!cap) - return; - - err = pci_read_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, &ctl); - if (err) - return; - - v = (ctl & PCI_EXP_DEVCTL_READRQ) >> 12; - - /* if bios or OS sets MAX_READ_REQUEST_SIZE to an invalid value, fix it - * to avoid hangs or perfomance issues - */ - if ((v == 0) || (v == 6) || (v == 7)) { - ctl &= ~PCI_EXP_DEVCTL_READRQ; - ctl |= (2 << 12); - pci_write_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, ctl); - } -} - void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc) { /* enable the pflip int */ @@ -82,7 +57,6 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) { struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset); - int i; /* Lock the graphics update lock */ tmp |= EVERGREEN_GRPH_UPDATE_LOCK; @@ -100,11 +74,7 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) (u32)crtc_base); /* Wait for update_pending to go high. */ - for (i = 0; i < rdev->usec_timeout; i++) { - if (RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING) - break; - udelay(1); - } + while (!(RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING)); DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); /* Unlock the lock, so double-buffering can take place inside vblank */ @@ -358,7 +328,6 @@ void evergreen_hpd_init(struct radeon_device *rdev) default: break; } - radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); } if (rdev->irq.installed) evergreen_irq_set(rdev); @@ -926,11 +895,6 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev) WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); - if ((rdev->family == CHIP_JUNIPER) || - (rdev->family == CHIP_CYPRESS) || - (rdev->family == CHIP_HEMLOCK) || - (rdev->family == CHIP_BARTS)) - WREG32(MC_VM_MD_L1_TLB3_CNTL, tmp); } WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); @@ -1019,8 +983,24 @@ void evergreen_agp_enable(struct radeon_device *rdev) void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) { + save->vga_control[0] = RREG32(D1VGA_CONTROL); + save->vga_control[1] = RREG32(D2VGA_CONTROL); save->vga_render_control = RREG32(VGA_RENDER_CONTROL); save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); + save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); + save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); + if (rdev->num_crtc >= 4) { + save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL); + save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL); + save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); + save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); + } + if (rdev->num_crtc >= 6) { + save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL); + save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL); + save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); + save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); + } /* Stop all video */ WREG32(VGA_RENDER_CONTROL, 0); @@ -1065,8 +1045,6 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav WREG32(EVERGREEN_D5VGA_CONTROL, 0); WREG32(EVERGREEN_D6VGA_CONTROL, 0); } - /* wait for the MC to settle */ - udelay(100); } void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) @@ -1133,6 +1111,47 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s /* Unlock host access */ WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); mdelay(1); + /* Restore video state */ + WREG32(D1VGA_CONTROL, save->vga_control[0]); + WREG32(D2VGA_CONTROL, save->vga_control[1]); + if (rdev->num_crtc >= 4) { + WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]); + WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]); + } + if (rdev->num_crtc >= 6) { + WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]); + WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); + } + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); + if (rdev->num_crtc >= 4) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); + } + if (rdev->num_crtc >= 6) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); + } + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]); + if (rdev->num_crtc >= 4) { + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); + } + if (rdev->num_crtc >= 6) { + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); + } + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); + if (rdev->num_crtc >= 4) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); + } + if (rdev->num_crtc >= 6) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + } WREG32(VGA_RENDER_CONTROL, save->vga_render_control); } @@ -1338,7 +1357,6 @@ int evergreen_cp_resume(struct radeon_device *rdev) SOFT_RESET_PA | SOFT_RESET_SH | SOFT_RESET_VGT | - SOFT_RESET_SPI | SOFT_RESET_SX)); RREG32(GRBM_SOFT_RESET); mdelay(15); @@ -1360,8 +1378,7 @@ int evergreen_cp_resume(struct radeon_device *rdev) /* Initialize the ring buffer's read and write pointers */ WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); WREG32(CP_RB_RPTR_WR, 0); - rdev->cp.wptr = 0; - WREG32(CP_RB_WPTR, rdev->cp.wptr); + WREG32(CP_RB_WPTR, 0); /* set the wb address wether it's enabled or not */ WREG32(CP_RB_RPTR_ADDR, @@ -1386,6 +1403,7 @@ int evergreen_cp_resume(struct radeon_device *rdev) WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); rdev->cp.rptr = RREG32(CP_RB_RPTR); + rdev->cp.wptr = RREG32(CP_RB_WPTR); evergreen_cp_start(rdev); rdev->cp.ready = true; @@ -1549,6 +1567,48 @@ static u32 evergreen_get_tile_pipe_to_backend_map(struct radeon_device *rdev, return backend_map; } +static void evergreen_program_channel_remap(struct radeon_device *rdev) +{ + u32 tcp_chan_steer_lo, tcp_chan_steer_hi, mc_shared_chremap, tmp; + + tmp = RREG32(MC_SHARED_CHMAP); + switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { + case 0: + case 1: + case 2: + case 3: + default: + /* default mapping */ + mc_shared_chremap = 0x00fac688; + break; + } + + switch (rdev->family) { + case CHIP_HEMLOCK: + case CHIP_CYPRESS: + case CHIP_BARTS: + tcp_chan_steer_lo = 0x54763210; + tcp_chan_steer_hi = 0x0000ba98; + break; + case CHIP_JUNIPER: + case CHIP_REDWOOD: + case CHIP_CEDAR: + case CHIP_PALM: + case CHIP_SUMO: + case CHIP_SUMO2: + case CHIP_TURKS: + case CHIP_CAICOS: + default: + tcp_chan_steer_lo = 0x76543210; + tcp_chan_steer_hi = 0x0000ba98; + break; + } + + WREG32(TCP_CHAN_STEER_LO, tcp_chan_steer_lo); + WREG32(TCP_CHAN_STEER_HI, tcp_chan_steer_hi); + WREG32(MC_SHARED_CHREMAP, mc_shared_chremap); +} + static void evergreen_gpu_init(struct radeon_device *rdev) { u32 cc_rb_backend_disable = 0; @@ -1805,8 +1865,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev) WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); - evergreen_fix_pci_max_read_req_size(rdev); - cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & ~2; cc_gc_shader_pipe_config |= @@ -1994,6 +2052,8 @@ static void evergreen_gpu_init(struct radeon_device *rdev) WREG32(DMIF_ADDR_CONFIG, gb_addr_config); WREG32(HDP_ADDR_CONFIG, gb_addr_config); + evergreen_program_channel_remap(rdev); + num_shader_engines = ((RREG32(GB_ADDR_CONFIG) & NUM_SHADER_ENGINES(3)) >> 12) + 1; grbm_gfx_index = INSTANCE_BROADCAST_WRITES; @@ -2014,9 +2074,9 @@ static void evergreen_gpu_init(struct radeon_device *rdev) WREG32(CC_SYS_RB_BACKEND_DISABLE, rb); WREG32(GC_USER_RB_BACKEND_DISABLE, rb); WREG32(CC_GC_SHADER_PIPE_CONFIG, sp); - } + } - grbm_gfx_index = INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES; + grbm_gfx_index |= SE_BROADCAST_WRITES; WREG32(GRBM_GFX_INDEX, grbm_gfx_index); WREG32(RLC_GFX_INDEX, grbm_gfx_index); @@ -3082,23 +3142,21 @@ int evergreen_suspend(struct radeon_device *rdev) } int evergreen_copy_blit(struct radeon_device *rdev, - uint64_t src_offset, - uint64_t dst_offset, - unsigned num_gpu_pages, - struct radeon_fence *fence) + uint64_t src_offset, uint64_t dst_offset, + unsigned num_pages, struct radeon_fence *fence) { int r; mutex_lock(&rdev->r600_blit.mutex); rdev->r600_blit.vb_ib = NULL; - r = evergreen_blit_prepare_copy(rdev, num_gpu_pages * RADEON_GPU_PAGE_SIZE); + r = evergreen_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE); if (r) { if (rdev->r600_blit.vb_ib) radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); mutex_unlock(&rdev->r600_blit.mutex); return r; } - evergreen_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages * RADEON_GPU_PAGE_SIZE); + evergreen_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE); evergreen_blit_done_copy(rdev, fence); mutex_unlock(&rdev->r600_blit.mutex); return 0; @@ -3207,18 +3265,6 @@ int evergreen_init(struct radeon_device *rdev) rdev->accel_working = false; } } - - /* Don't start up if the MC ucode is missing on BTC parts. - * The default clocks and voltages before the MC ucode - * is loaded are not suffient for advanced operations. - */ - if (ASIC_IS_DCE5(rdev)) { - if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) { - DRM_ERROR("radeon: MC ucode required for NI+.\n"); - return -EINVAL; - } - } - return 0; } diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 6078ae4cc16e..b7b2714f0b32 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -230,7 +230,6 @@ #define MC_VM_MD_L1_TLB0_CNTL 0x2654 #define MC_VM_MD_L1_TLB1_CNTL 0x2658 #define MC_VM_MD_L1_TLB2_CNTL 0x265C -#define MC_VM_MD_L1_TLB3_CNTL 0x2698 #define FUS_MC_VM_MD_L1_TLB0_CNTL 0x265C #define FUS_MC_VM_MD_L1_TLB1_CNTL 0x2660 diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 0c460c402174..559dbd412906 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -39,7 +39,6 @@ extern int evergreen_mc_wait_for_idle(struct radeon_device *rdev); extern void evergreen_mc_program(struct radeon_device *rdev); extern void evergreen_irq_suspend(struct radeon_device *rdev); extern int evergreen_mc_init(struct radeon_device *rdev); -extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev); #define EVERGREEN_PFP_UCODE_SIZE 1120 #define EVERGREEN_PM4_UCODE_SIZE 1376 @@ -569,6 +568,36 @@ static u32 cayman_get_tile_pipe_to_backend_map(struct radeon_device *rdev, return backend_map; } +static void cayman_program_channel_remap(struct radeon_device *rdev) +{ + u32 tcp_chan_steer_lo, tcp_chan_steer_hi, mc_shared_chremap, tmp; + + tmp = RREG32(MC_SHARED_CHMAP); + switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { + case 0: + case 1: + case 2: + case 3: + default: + /* default mapping */ + mc_shared_chremap = 0x00fac688; + break; + } + + switch (rdev->family) { + case CHIP_CAYMAN: + default: + //tcp_chan_steer_lo = 0x54763210 + tcp_chan_steer_lo = 0x76543210; + tcp_chan_steer_hi = 0x0000ba98; + break; + } + + WREG32(TCP_CHAN_STEER_LO, tcp_chan_steer_lo); + WREG32(TCP_CHAN_STEER_HI, tcp_chan_steer_hi); + WREG32(MC_SHARED_CHREMAP, mc_shared_chremap); +} + static u32 cayman_get_disable_mask_per_asic(struct radeon_device *rdev, u32 disable_mask_per_se, u32 max_disable_mask_per_se, @@ -640,8 +669,6 @@ static void cayman_gpu_init(struct radeon_device *rdev) WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); - evergreen_fix_pci_max_read_req_size(rdev); - mc_shared_chmap = RREG32(MC_SHARED_CHMAP); mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); @@ -811,6 +838,8 @@ static void cayman_gpu_init(struct radeon_device *rdev) WREG32(DMIF_ADDR_CONFIG, gb_addr_config); WREG32(HDP_ADDR_CONFIG, gb_addr_config); + cayman_program_channel_remap(rdev); + /* primary versions */ WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); @@ -1129,7 +1158,6 @@ int cayman_cp_resume(struct radeon_device *rdev) SOFT_RESET_PA | SOFT_RESET_SH | SOFT_RESET_VGT | - SOFT_RESET_SPI | SOFT_RESET_SX)); RREG32(GRBM_SOFT_RESET); mdelay(15); @@ -1154,8 +1182,7 @@ int cayman_cp_resume(struct radeon_device *rdev) /* Initialize the ring buffer's read and write pointers */ WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA); - rdev->cp.wptr = 0; - WREG32(CP_RB0_WPTR, rdev->cp.wptr); + WREG32(CP_RB0_WPTR, 0); /* set the wb address wether it's enabled or not */ WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); @@ -1175,6 +1202,7 @@ int cayman_cp_resume(struct radeon_device *rdev) WREG32(CP_RB0_BASE, rdev->cp.gpu_addr >> 8); rdev->cp.rptr = RREG32(CP_RB0_RPTR); + rdev->cp.wptr = RREG32(CP_RB0_WPTR); /* ring1 - compute only */ /* Set ring buffer size */ @@ -1187,8 +1215,7 @@ int cayman_cp_resume(struct radeon_device *rdev) /* Initialize the ring buffer's read and write pointers */ WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA); - rdev->cp1.wptr = 0; - WREG32(CP_RB1_WPTR, rdev->cp1.wptr); + WREG32(CP_RB1_WPTR, 0); /* set the wb address wether it's enabled or not */ WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC); @@ -1200,6 +1227,7 @@ int cayman_cp_resume(struct radeon_device *rdev) WREG32(CP_RB1_BASE, rdev->cp1.gpu_addr >> 8); rdev->cp1.rptr = RREG32(CP_RB1_RPTR); + rdev->cp1.wptr = RREG32(CP_RB1_WPTR); /* ring2 - compute only */ /* Set ring buffer size */ @@ -1212,8 +1240,7 @@ int cayman_cp_resume(struct radeon_device *rdev) /* Initialize the ring buffer's read and write pointers */ WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA); - rdev->cp2.wptr = 0; - WREG32(CP_RB2_WPTR, rdev->cp2.wptr); + WREG32(CP_RB2_WPTR, 0); /* set the wb address wether it's enabled or not */ WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC); @@ -1225,6 +1252,7 @@ int cayman_cp_resume(struct radeon_device *rdev) WREG32(CP_RB2_BASE, rdev->cp2.gpu_addr >> 8); rdev->cp2.rptr = RREG32(CP_RB2_RPTR); + rdev->cp2.wptr = RREG32(CP_RB2_WPTR); /* start the rings */ cayman_cp_start(rdev); diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index d94f440f1379..f2204cb1ccdf 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -84,18 +84,13 @@ u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) { struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK; - int i; /* Lock the graphics update lock */ /* update the scanout addresses */ WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp); /* Wait for update_pending to go high. */ - for (i = 0; i < rdev->usec_timeout; i++) { - if (RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET) - break; - udelay(1); - } + while (!(RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET)); DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); /* Unlock the lock, so double-buffering can take place inside vblank */ @@ -439,7 +434,6 @@ void r100_hpd_init(struct radeon_device *rdev) default: break; } - radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); } if (rdev->irq.installed) r100_irq_set(rdev); @@ -681,7 +675,9 @@ int r100_irq_process(struct radeon_device *rdev) WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM); break; default: - WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN); + msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN; + WREG32(RADEON_MSI_REARM_EN, msi_rearm); + WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN); break; } } @@ -725,11 +721,11 @@ void r100_fence_ring_emit(struct radeon_device *rdev, int r100_copy_blit(struct radeon_device *rdev, uint64_t src_offset, uint64_t dst_offset, - unsigned num_gpu_pages, + unsigned num_pages, struct radeon_fence *fence) { uint32_t cur_pages; - uint32_t stride_bytes = RADEON_GPU_PAGE_SIZE; + uint32_t stride_bytes = PAGE_SIZE; uint32_t pitch; uint32_t stride_pixels; unsigned ndw; @@ -741,7 +737,7 @@ int r100_copy_blit(struct radeon_device *rdev, /* radeon pitch is /64 */ pitch = stride_bytes / 64; stride_pixels = stride_bytes / 4; - num_loops = DIV_ROUND_UP(num_gpu_pages, 8191); + num_loops = DIV_ROUND_UP(num_pages, 8191); /* Ask for enough room for blit + flush + fence */ ndw = 64 + (10 * num_loops); @@ -750,12 +746,12 @@ int r100_copy_blit(struct radeon_device *rdev, DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw); return -EINVAL; } - while (num_gpu_pages > 0) { - cur_pages = num_gpu_pages; + while (num_pages > 0) { + cur_pages = num_pages; if (cur_pages > 8191) { cur_pages = 8191; } - num_gpu_pages -= cur_pages; + num_pages -= cur_pages; /* pages are in Y direction - height page width in X direction - width */ @@ -777,8 +773,8 @@ int r100_copy_blit(struct radeon_device *rdev, radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16)); radeon_ring_write(rdev, 0); radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16)); - radeon_ring_write(rdev, num_gpu_pages); - radeon_ring_write(rdev, num_gpu_pages); + radeon_ring_write(rdev, num_pages); + radeon_ring_write(rdev, num_pages); radeon_ring_write(rdev, cur_pages | (stride_pixels << 16)); } radeon_ring_write(rdev, PACKET0(RADEON_DSTCACHE_CTLSTAT, 0)); @@ -994,8 +990,7 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) /* Force read & write ptr to 0 */ WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA | RADEON_RB_NO_UPDATE); WREG32(RADEON_CP_RB_RPTR_WR, 0); - rdev->cp.wptr = 0; - WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr); + WREG32(RADEON_CP_RB_WPTR, 0); /* set the wb address whether it's enabled or not */ WREG32(R_00070C_CP_RB_RPTR_ADDR, @@ -1012,6 +1007,9 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) WREG32(RADEON_CP_RB_CNTL, tmp); udelay(10); rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); + rdev->cp.wptr = RREG32(RADEON_CP_RB_WPTR); + /* protect against crazy HW on resume */ + rdev->cp.wptr &= rdev->cp.ptr_mask; /* Set cp mode to bus mastering & enable cp*/ WREG32(RADEON_CP_CSQ_MODE, REG_SET(RADEON_INDIRECT2_START, indirect2_start) | @@ -2067,7 +2065,6 @@ bool r100_gpu_is_lockup(struct radeon_device *rdev) void r100_bm_disable(struct radeon_device *rdev) { u32 tmp; - u16 tmp16; /* disable bus mastering */ tmp = RREG32(R_000030_BUS_CNTL); @@ -2078,8 +2075,8 @@ void r100_bm_disable(struct radeon_device *rdev) WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000040); tmp = RREG32(RADEON_BUS_CNTL); mdelay(1); - pci_read_config_word(rdev->pdev, 0x4, &tmp16); - pci_write_config_word(rdev->pdev, 0x4, tmp16 & 0xFFFB); + pci_read_config_word(rdev->pdev, 0x4, (u16*)&tmp); + pci_write_config_word(rdev->pdev, 0x4, tmp & 0xFFFB); mdelay(1); } diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index a1f3ba063c2d..f24058300413 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c @@ -84,7 +84,7 @@ static int r200_get_vtx_size_0(uint32_t vtx_fmt_0) int r200_copy_dma(struct radeon_device *rdev, uint64_t src_offset, uint64_t dst_offset, - unsigned num_gpu_pages, + unsigned num_pages, struct radeon_fence *fence) { uint32_t size; @@ -93,7 +93,7 @@ int r200_copy_dma(struct radeon_device *rdev, int r = 0; /* radeon pitch is /64 */ - size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT; + size = num_pages << PAGE_SHIFT; num_loops = DIV_ROUND_UP(size, 0x1FFFFF); r = radeon_ring_lock(rdev, num_loops * 4 + 64); if (r) { diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 1a4ed433eba3..bc54b26cb32f 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -762,14 +762,13 @@ void r600_hpd_init(struct radeon_device *rdev) struct drm_device *dev = rdev->ddev; struct drm_connector *connector; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - - if (ASIC_IS_DCE3(rdev)) { - u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa); - if (ASIC_IS_DCE32(rdev)) - tmp |= DC_HPDx_EN; + if (ASIC_IS_DCE3(rdev)) { + u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa); + if (ASIC_IS_DCE32(rdev)) + tmp |= DC_HPDx_EN; + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct radeon_connector *radeon_connector = to_radeon_connector(connector); switch (radeon_connector->hpd.hpd) { case RADEON_HPD_1: WREG32(DC_HPD1_CONTROL, tmp); @@ -799,7 +798,10 @@ void r600_hpd_init(struct radeon_device *rdev) default: break; } - } else { + } + } else { + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct radeon_connector *radeon_connector = to_radeon_connector(connector); switch (radeon_connector->hpd.hpd) { case RADEON_HPD_1: WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN); @@ -817,7 +819,6 @@ void r600_hpd_init(struct radeon_device *rdev) break; } } - radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); } if (rdev->irq.installed) r600_irq_set(rdev); @@ -2207,8 +2208,7 @@ int r600_cp_resume(struct radeon_device *rdev) /* Initialize the ring buffer's read and write pointers */ WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); WREG32(CP_RB_RPTR_WR, 0); - rdev->cp.wptr = 0; - WREG32(CP_RB_WPTR, rdev->cp.wptr); + WREG32(CP_RB_WPTR, 0); /* set the wb address whether it's enabled or not */ WREG32(CP_RB_RPTR_ADDR, @@ -2233,6 +2233,7 @@ int r600_cp_resume(struct radeon_device *rdev) WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); rdev->cp.rptr = RREG32(CP_RB_RPTR); + rdev->cp.wptr = RREG32(CP_RB_WPTR); r600_cp_start(rdev); rdev->cp.ready = true; @@ -2354,23 +2355,21 @@ void r600_fence_ring_emit(struct radeon_device *rdev, } int r600_copy_blit(struct radeon_device *rdev, - uint64_t src_offset, - uint64_t dst_offset, - unsigned num_gpu_pages, - struct radeon_fence *fence) + uint64_t src_offset, uint64_t dst_offset, + unsigned num_pages, struct radeon_fence *fence) { int r; mutex_lock(&rdev->r600_blit.mutex); rdev->r600_blit.vb_ib = NULL; - r = r600_blit_prepare_copy(rdev, num_gpu_pages * RADEON_GPU_PAGE_SIZE); + r = r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE); if (r) { if (rdev->r600_blit.vb_ib) radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); mutex_unlock(&rdev->r600_blit.mutex); return r; } - r600_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages * RADEON_GPU_PAGE_SIZE); + r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE); r600_blit_done_copy(rdev, fence); mutex_unlock(&rdev->r600_blit.mutex); return 0; diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c index 73e2c7c6edbc..2d1f6c5ee2a7 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.c +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c @@ -313,10 +313,6 @@ const u32 r6xx_default_state[] = 0x00000000, /* VGT_REUSE_OFF */ 0x00000000, /* VGT_VTX_CNT_EN */ - 0xc0016900, - 0x000000d4, - 0x00000000, /* SX_MISC */ - 0xc0016900, 0x000002c8, 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ @@ -629,10 +625,6 @@ const u32 r7xx_default_state[] = 0x00000000, /* VGT_REUSE_OFF */ 0x00000000, /* VGT_VTX_CNT_EN */ - 0xc0016900, - 0x000000d4, - 0x00000000, /* SX_MISC */ - 0xc0016900, 0x000002c8, 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index c45d92191fd8..f5ac7e788d81 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -196,13 +196,6 @@ static void r600_hdmi_videoinfoframe( frame[0xD] = (right_bar >> 8); r600_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame); - /* Our header values (type, version, length) should be alright, Intel - * is using the same. Checksum function also seems to be OK, it works - * fine for audio infoframe. However calculated value is always lower - * by 2 in comparison to fglrx. It breaks displaying anything in case - * of TVs that strictly check the checksum. Hack it manually here to - * workaround this issue. */ - frame[0x0] += 2; WREG32(offset+R600_HDMI_VIDEOINFOFRAME_0, frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 59d72d0f5a88..ef0e0e016914 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -93,7 +93,6 @@ extern int radeon_audio; extern int radeon_disp_priority; extern int radeon_hw_i2c; extern int radeon_pcie_gen2; -extern int radeon_msi; /* * Copy from radeon_drv.h so we don't have to include both and have conflicting @@ -323,7 +322,6 @@ union radeon_gart_table { #define RADEON_GPU_PAGE_SIZE 4096 #define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1) -#define RADEON_GPU_PAGE_SHIFT 12 struct radeon_gart { dma_addr_t table_addr; @@ -916,17 +914,17 @@ struct radeon_asic { int (*copy_blit)(struct radeon_device *rdev, uint64_t src_offset, uint64_t dst_offset, - unsigned num_gpu_pages, + unsigned num_pages, struct radeon_fence *fence); int (*copy_dma)(struct radeon_device *rdev, uint64_t src_offset, uint64_t dst_offset, - unsigned num_gpu_pages, + unsigned num_pages, struct radeon_fence *fence); int (*copy)(struct radeon_device *rdev, uint64_t src_offset, uint64_t dst_offset, - unsigned num_gpu_pages, + unsigned num_pages, struct radeon_fence *fence); uint32_t (*get_engine_clock)(struct radeon_device *rdev); void (*set_engine_clock)(struct radeon_device *rdev, uint32_t eng_clock); diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index bc6b64fe0e09..bd2f33e5c91a 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c @@ -70,12 +70,9 @@ static struct radeon_agpmode_quirk radeon_agpmode_quirk_list[] = { /* Intel 82830 830 Chipset Host Bridge / Mobility M6 LY Needs AGPMode 2 (fdo #17360)*/ { PCI_VENDOR_ID_INTEL, 0x3575, PCI_VENDOR_ID_ATI, 0x4c59, PCI_VENDOR_ID_DELL, 0x00e3, 2}, - /* Intel 82852/82855 host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 (lp #296617) */ + /* Intel 82852/82855 host bridge / Mobility FireGL 9000 R250 Needs AGPMode 1 (lp #296617) */ { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4c66, PCI_VENDOR_ID_DELL, 0x0149, 1}, - /* Intel 82855PM host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 for suspend/resume */ - { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c66, - PCI_VENDOR_ID_IBM, 0x0531, 1}, /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (deb #467460) */ { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50, 0x1025, 0x0061, 1}, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 4d81e9612394..3d7a0d7c6a9a 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -75,7 +75,7 @@ uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg); int r100_copy_blit(struct radeon_device *rdev, uint64_t src_offset, uint64_t dst_offset, - unsigned num_gpu_pages, + unsigned num_pages, struct radeon_fence *fence); int r100_set_surface_reg(struct radeon_device *rdev, int reg, uint32_t tiling_flags, uint32_t pitch, @@ -143,7 +143,7 @@ extern void r100_post_page_flip(struct radeon_device *rdev, int crtc); extern int r200_copy_dma(struct radeon_device *rdev, uint64_t src_offset, uint64_t dst_offset, - unsigned num_gpu_pages, + unsigned num_pages, struct radeon_fence *fence); void r200_set_safe_registers(struct radeon_device *rdev); @@ -253,10 +253,13 @@ void rs690_line_buffer_adjust(struct radeon_device *rdev, * rv515 */ struct rv515_mc_save { + u32 d1vga_control; + u32 d2vga_control; u32 vga_render_control; u32 vga_hdp_control; + u32 d1crtc_control; + u32 d2crtc_control; }; - int rv515_init(struct radeon_device *rdev); void rv515_fini(struct radeon_device *rdev); uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); @@ -308,7 +311,7 @@ void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); int r600_ring_test(struct radeon_device *rdev); int r600_copy_blit(struct radeon_device *rdev, uint64_t src_offset, uint64_t dst_offset, - unsigned num_gpu_pages, struct radeon_fence *fence); + unsigned num_pages, struct radeon_fence *fence); void r600_hpd_init(struct radeon_device *rdev); void r600_hpd_fini(struct radeon_device *rdev); bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); @@ -384,10 +387,11 @@ void r700_cp_fini(struct radeon_device *rdev); * evergreen */ struct evergreen_mc_save { + u32 vga_control[6]; u32 vga_render_control; u32 vga_hdp_control; + u32 crtc_control[6]; }; - void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev); int evergreen_init(struct radeon_device *rdev); void evergreen_fini(struct radeon_device *rdev); @@ -399,7 +403,7 @@ void evergreen_bandwidth_update(struct radeon_device *rdev); void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); int evergreen_copy_blit(struct radeon_device *rdev, uint64_t src_offset, uint64_t dst_offset, - unsigned num_gpu_pages, struct radeon_fence *fence); + unsigned num_pages, struct radeon_fence *fence); void evergreen_hpd_init(struct radeon_device *rdev); void evergreen_hpd_fini(struct radeon_device *rdev); bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index cee31843629d..bf2b61584cdb 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -85,18 +85,6 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev for (i = 0; i < num_indices; i++) { gpio = &i2c_info->asGPIO_Info[i]; - /* r4xx mask is technically not used by the hw, so patch in the legacy mask bits */ - if ((rdev->family == CHIP_R420) || - (rdev->family == CHIP_R423) || - (rdev->family == CHIP_RV410)) { - if ((le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0018) || - (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0019) || - (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x001a)) { - gpio->ucClkMaskShift = 0x19; - gpio->ucDataMaskShift = 0x18; - } - } - /* some evergreen boards have bad data for this entry */ if (ASIC_IS_DCE4(rdev)) { if ((i == 7) && @@ -181,18 +169,6 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) gpio = &i2c_info->asGPIO_Info[i]; i2c.valid = false; - /* r4xx mask is technically not used by the hw, so patch in the legacy mask bits */ - if ((rdev->family == CHIP_R420) || - (rdev->family == CHIP_R423) || - (rdev->family == CHIP_RV410)) { - if ((le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0018) || - (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0019) || - (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x001a)) { - gpio->ucClkMaskShift = 0x19; - gpio->ucDataMaskShift = 0x18; - } - } - /* some evergreen boards have bad data for this entry */ if (ASIC_IS_DCE4(rdev)) { if ((i == 7) && @@ -480,26 +456,10 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, */ if ((dev->pdev->device == 0x9498) && (dev->pdev->subsystem_vendor == 0x1682) && - (dev->pdev->subsystem_device == 0x2452) && - (i2c_bus->valid == false) && - !(supported_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))) { + (dev->pdev->subsystem_device == 0x2452)) { struct radeon_device *rdev = dev->dev_private; *i2c_bus = radeon_lookup_i2c_gpio(rdev, 0x93); } - - /* Fujitsu D3003-S2 board lists DVI-I as DVI-D and VGA */ - if (((dev->pdev->device == 0x9802) || (dev->pdev->device == 0x9806)) && - (dev->pdev->subsystem_vendor == 0x1734) && - (dev->pdev->subsystem_device == 0x11bd)) { - if (*connector_type == DRM_MODE_CONNECTOR_VGA) { - *connector_type = DRM_MODE_CONNECTOR_DVII; - *line_mux = 0x3103; - } else if (*connector_type == DRM_MODE_CONNECTOR_DVID) { - *connector_type = DRM_MODE_CONNECTOR_DVII; - } - } - - return true; } @@ -2584,11 +2544,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; rdev->pm.current_clock_mode_index = 0; - if (rdev->pm.default_power_state_index >= 0) - rdev->pm.current_vddc = - rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage; - else - rdev->pm.current_vddc = 0; + rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage; } void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable) diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c index b956cf1f9f90..2d48e7a1474b 100644 --- a/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/drivers/gpu/drm/radeon/radeon_clocks.c @@ -219,9 +219,6 @@ void radeon_get_clock_info(struct drm_device *dev) } else { DRM_INFO("Using generic clock info\n"); - /* may need to be per card */ - rdev->clock.max_pixel_clock = 35000; - if (rdev->flags & RADEON_IS_IGP) { p1pll->reference_freq = 1432; p2pll->reference_freq = 1432; diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 2157e770d35a..e4594676a07c 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -620,8 +620,8 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde i2c.y_data_mask = 0x80; } else { /* default masks for ddc pads */ - i2c.mask_clk_mask = RADEON_GPIO_MASK_1; - i2c.mask_data_mask = RADEON_GPIO_MASK_0; + i2c.mask_clk_mask = RADEON_GPIO_EN_1; + i2c.mask_data_mask = RADEON_GPIO_EN_0; i2c.a_clk_mask = RADEON_GPIO_A_1; i2c.a_data_mask = RADEON_GPIO_A_0; i2c.en_clk_mask = RADEON_GPIO_EN_1; @@ -779,8 +779,7 @@ void radeon_combios_i2c_init(struct radeon_device *rdev) } } } - } else if ((rdev->family == CHIP_R200) || - (rdev->family >= CHIP_R300)) { + } else if (rdev->family >= CHIP_R200) { /* 0x68 */ i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); @@ -2338,14 +2337,6 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) 1), ATOM_DEVICE_CRT1_SUPPORT); } - /* RV100 board with external TDMS bit mis-set. - * Actually uses internal TMDS, clear the bit. - */ - if (dev->pdev->device == 0x5159 && - dev->pdev->subsystem_vendor == 0x1014 && - dev->pdev->subsystem_device == 0x029A) { - tmp &= ~(1 << 4); - } if ((tmp >> 4) & 0x1) { devices |= ATOM_DEVICE_DFP2_SUPPORT; radeon_add_legacy_encoder(dev, @@ -3287,14 +3278,6 @@ void radeon_combios_asic_init(struct drm_device *dev) rdev->pdev->subsystem_device == 0x30a4) return; - /* quirk for rs4xx Compaq Presario V5245EU laptop to make it resume - * - it hangs on resume inside the dynclk 1 table. - */ - if (rdev->family == CHIP_RS480 && - rdev->pdev->subsystem_vendor == 0x103c && - rdev->pdev->subsystem_device == 0x30ae) - return; - /* DYN CLK 1 */ table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE); if (table) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index f1a1e8aa4dad..9792d4ffdc86 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -60,39 +60,18 @@ void radeon_connector_hotplug(struct drm_connector *connector) radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); - /* if the connector is already off, don't turn it back on */ - if (connector->dpms != DRM_MODE_DPMS_ON) + /* powering up/down the eDP panel generates hpd events which + * can interfere with modesetting. + */ + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) return; - /* just deal with DP (not eDP) here. */ - if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { - struct radeon_connector_atom_dig *dig_connector = - radeon_connector->con_priv; - - /* if existing sink type was not DP no need to retrain */ - if (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_DISPLAYPORT) - return; - - /* first get sink type as it may be reset after (un)plug */ - dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); - /* don't do anything if sink is not display port, i.e., - * passive dp->(dvi|hdmi) adaptor - */ - if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { - int saved_dpms = connector->dpms; - /* Only turn off the display if it's physically disconnected */ - if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) { - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); - } else if (radeon_dp_needs_link_train(radeon_connector)) { - /* set it to OFF so that drm_helper_connector_dpms() - * won't return immediately since the current state - * is ON at this point. - */ - connector->dpms = DRM_MODE_DPMS_OFF; - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); - } - connector->dpms = saved_dpms; - } + /* pre-r600 did not always have the hpd pins mapped accurately to connectors */ + if (rdev->family >= CHIP_R600) { + if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) + drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); + else + drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); } } @@ -451,55 +430,6 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr return 0; } -/* - * Some integrated ATI Radeon chipset implementations (e. g. - * Asus M2A-VM HDMI) may indicate the availability of a DDC, - * even when there's no monitor connected. For these connectors - * following DDC probe extension will be applied: check also for the - * availability of EDID with at least a correct EDID header. Only then, - * DDC is assumed to be available. This prevents drm_get_edid() and - * drm_edid_block_valid() from periodically dumping data and kernel - * errors into the logs and onto the terminal. - */ -static bool radeon_connector_needs_extended_probe(struct radeon_device *dev, - uint32_t supported_device, - int connector_type) -{ - /* Asus M2A-VM HDMI board sends data to i2c bus even, - * if HDMI add-on card is not plugged in or HDMI is disabled in - * BIOS. Valid DDC can only be assumed, if also a valid EDID header - * can be retrieved via i2c bus during DDC probe */ - if ((dev->pdev->device == 0x791e) && - (dev->pdev->subsystem_vendor == 0x1043) && - (dev->pdev->subsystem_device == 0x826d)) { - if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) && - (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) - return true; - } - /* ECS A740GM-M with ATI RADEON 2100 sends data to i2c bus - * for a DVI connector that is not implemented */ - if ((dev->pdev->device == 0x796e) && - (dev->pdev->subsystem_vendor == 0x1019) && - (dev->pdev->subsystem_device == 0x2615)) { - if ((connector_type == DRM_MODE_CONNECTOR_DVID) && - (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) - return true; - } - /* TOSHIBA Satellite L300D with ATI Mobility Radeon x1100 - * (RS690M) sends data to i2c bus for a HDMI connector that - * is not implemented */ - if ((dev->pdev->device == 0x791f) && - (dev->pdev->subsystem_vendor == 0x1179) && - (dev->pdev->subsystem_device == 0xff68)) { - if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) && - (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) - return true; - } - - /* Default: no EDID header probe required for DDC probing */ - return false; -} - static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, struct drm_connector *connector) { @@ -731,10 +661,8 @@ radeon_vga_detect(struct drm_connector *connector, bool force) ret = connector_status_disconnected; if (radeon_connector->ddc_bus) - dret = radeon_ddc_probe(radeon_connector, - radeon_connector->requires_extended_probe); + dret = radeon_ddc_probe(radeon_connector); if (dret) { - radeon_connector->detected_by_load = false; if (radeon_connector->edid) { kfree(radeon_connector->edid); radeon_connector->edid = NULL; @@ -761,21 +689,12 @@ radeon_vga_detect(struct drm_connector *connector, bool force) } else { /* if we aren't forcing don't do destructive polling */ - if (!force) { - /* only return the previous status if we last - * detected a monitor via load. - */ - if (radeon_connector->detected_by_load) - return connector->status; - else - return ret; - } + if (!force) + return connector->status; if (radeon_connector->dac_load_detect && encoder) { encoder_funcs = encoder->helper_private; ret = encoder_funcs->detect(encoder, connector); - if (ret != connector_status_disconnected) - radeon_connector->detected_by_load = true; } } @@ -914,10 +833,8 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) bool dret = false; if (radeon_connector->ddc_bus) - dret = radeon_ddc_probe(radeon_connector, - radeon_connector->requires_extended_probe); + dret = radeon_ddc_probe(radeon_connector); if (dret) { - radeon_connector->detected_by_load = false; if (radeon_connector->edid) { kfree(radeon_connector->edid); radeon_connector->edid = NULL; @@ -980,18 +897,8 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) if ((ret == connector_status_connected) && (radeon_connector->use_digital == true)) goto out; - /* DVI-D and HDMI-A are digital only */ - if ((connector->connector_type == DRM_MODE_CONNECTOR_DVID) || - (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA)) - goto out; - - /* if we aren't forcing don't do destructive polling */ if (!force) { - /* only return the previous status if we last - * detected a monitor via load. - */ - if (radeon_connector->detected_by_load) - ret = connector->status; + ret = connector->status; goto out; } @@ -1009,10 +916,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) encoder = obj_to_encoder(obj); - if (encoder->encoder_type != DRM_MODE_ENCODER_DAC && - encoder->encoder_type != DRM_MODE_ENCODER_TVDAC) - continue; - encoder_funcs = encoder->helper_private; if (encoder_funcs->detect) { if (ret != connector_status_connected) { @@ -1020,8 +923,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) if (ret == connector_status_connected) { radeon_connector->use_digital = false; } - if (ret != connector_status_disconnected) - radeon_connector->detected_by_load = true; } break; } @@ -1039,7 +940,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) * cases the DVI port is actually a virtual KVM port connected to the service * processor. */ -out: if ((!rdev->is_atom_bios) && (ret == connector_status_disconnected) && rdev->mode_info.bios_hardcoded_edid_size) { @@ -1047,6 +947,7 @@ out: ret = connector_status_connected; } +out: /* updated in get modes as well since we need to know if it's analog or digital */ radeon_connector_update_scratch_regs(connector, ret); return ret; @@ -1350,8 +1251,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force) if (radeon_dp_getdpcd(radeon_connector)) ret = connector_status_connected; } else { - if (radeon_ddc_probe(radeon_connector, - radeon_connector->requires_extended_probe)) + if (radeon_ddc_probe(radeon_connector)) ret = connector_status_connected; } } @@ -1506,9 +1406,6 @@ radeon_add_atom_connector(struct drm_device *dev, radeon_connector->shared_ddc = shared_ddc; radeon_connector->connector_object_id = connector_object_id; radeon_connector->hpd = *hpd; - radeon_connector->requires_extended_probe = - radeon_connector_needs_extended_probe(rdev, supported_device, - connector_type); radeon_connector->router = *router; if (router->ddc_valid || router->cd_valid) { radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); @@ -1855,9 +1752,6 @@ radeon_add_legacy_connector(struct drm_device *dev, radeon_connector->devices = supported_device; radeon_connector->connector_object_id = connector_object_id; radeon_connector->hpd = *hpd; - radeon_connector->requires_extended_probe = - radeon_connector_needs_extended_probe(rdev, supported_device, - connector_type); switch (connector_type) { case DRM_MODE_CONNECTOR_VGA: drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index 72f749d56c12..3189a7efb2e9 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c @@ -151,9 +151,7 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, uint32_t height) { struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct radeon_device *rdev = crtc->dev->dev_private; struct drm_gem_object *obj; - struct radeon_bo *robj; uint64_t gpu_addr; int ret; @@ -175,15 +173,7 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, return -ENOENT; } - robj = gem_to_radeon_bo(obj); - ret = radeon_bo_reserve(robj, false); - if (unlikely(ret != 0)) - goto fail; - /* Only 27 bit offset for legacy cursor */ - ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM, - ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, - &gpu_addr); - radeon_bo_unreserve(robj); + ret = radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &gpu_addr); if (ret) goto fail; @@ -191,6 +181,7 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, radeon_crtc->cursor_height = height; radeon_lock_cursor(crtc, true); + /* XXX only 27 bit offset for legacy cursor */ radeon_set_cursor(crtc, obj, gpu_addr); radeon_show_cursor(crtc); radeon_lock_cursor(crtc, false); @@ -217,13 +208,6 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, int xorigin = 0, yorigin = 0; int w = radeon_crtc->cursor_width; - if (ASIC_IS_AVIVO(rdev)) { - /* avivo cursor are offset into the total surface */ - x += crtc->x; - y += crtc->y; - } - DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y); - if (x < 0) xorigin = -x + 1; if (y < 0) @@ -237,6 +221,11 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, int i = 0; struct drm_crtc *crtc_p; + /* avivo cursor are offset into the total surface */ + x += crtc->x; + y += crtc->y; + DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y); + /* avivo cursor image can't end on 128 pixel boundary or * go past the end of the frame if both crtcs are enabled */ @@ -257,14 +246,8 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, if (!(cursor_end & 0x7f)) w--; } - if (w <= 0) { + if (w <= 0) w = 1; - cursor_end = x - xorigin + w; - if (!(cursor_end & 0x7f)) { - x--; - WARN_ON_ONCE(x < 0); - } - } } } diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index e87893c2c88a..7cfaa7e2f3b5 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -223,11 +223,8 @@ int radeon_wb_init(struct radeon_device *rdev) if (radeon_no_wb == 1) rdev->wb.enabled = false; else { + /* often unreliable on AGP */ if (rdev->flags & RADEON_IS_AGP) { - /* often unreliable on AGP */ - rdev->wb.enabled = false; - } else if (rdev->family < CHIP_R300) { - /* often unreliable on pre-r300 */ rdev->wb.enabled = false; } else { rdev->wb.enabled = true; @@ -707,9 +704,8 @@ int radeon_device_init(struct radeon_device *rdev, rdev->gpu_lockup = false; rdev->accel_working = false; - DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n", - radeon_family_name[rdev->family], pdev->vendor, pdev->device, - pdev->subsystem_vendor, pdev->subsystem_device); + DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n", + radeon_family_name[rdev->family], pdev->vendor, pdev->device); /* mutex initialization are all done here so we * can recall function without having locking issues */ @@ -857,8 +853,6 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - drm_kms_helper_poll_disable(dev); - /* turn off display hw */ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); @@ -945,8 +939,6 @@ int radeon_resume_kms(struct drm_device *dev) list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); } - - drm_kms_helper_poll_enable(dev); return 0; } diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 0896faed9fd1..292f73f0ddbd 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -777,17 +777,8 @@ static int radeon_ddc_dump(struct drm_connector *connector) if (!radeon_connector->ddc_bus) return -1; edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter); - /* Log EDID retrieval status here. In particular with regard to - * connectors with requires_extended_probe flag set, that will prevent - * function radeon_dvi_detect() to fetch EDID on this connector, - * as long as there is no valid EDID header found */ if (edid) { - DRM_INFO("Radeon display connector %s: Found valid EDID", - drm_get_connector_name(connector)); kfree(edid); - } else { - DRM_INFO("Radeon display connector %s: No monitor connected or invalid EDID", - drm_get_connector_name(connector)); } return ret; } @@ -1158,10 +1149,8 @@ radeon_user_framebuffer_create(struct drm_device *dev, } radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL); - if (radeon_fb == NULL) { - drm_gem_object_unreference_unlocked(obj); + if (radeon_fb == NULL) return ERR_PTR(-ENOMEM); - } radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj); diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 60e160578f73..73dfbe8e5f9e 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -117,7 +117,6 @@ int radeon_audio = 0; int radeon_disp_priority = 0; int radeon_hw_i2c = 0; int radeon_pcie_gen2 = 0; -int radeon_msi = -1; MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); module_param_named(no_wb, radeon_no_wb, int, 0444); @@ -164,9 +163,6 @@ module_param_named(hw_i2c, radeon_hw_i2c, int, 0444); MODULE_PARM_DESC(pcie_gen2, "PCIE Gen2 mode (1 = enable)"); module_param_named(pcie_gen2, radeon_pcie_gen2, int, 0444); -MODULE_PARM_DESC(msi, "MSI support (1 = enable, 0 = disable, -1 = auto)"); -module_param_named(msi, radeon_msi, int, 0444); - static int radeon_suspend(struct drm_device *dev, pm_message_t state) { drm_radeon_private_t *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 8a171b21b453..b293487e5aa3 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -1507,14 +1507,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) switch (mode) { case DRM_MODE_DPMS_ON: args.ucAction = ATOM_ENABLE; - /* workaround for DVOOutputControl on some RS690 systems */ - if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DDI) { - u32 reg = RREG32(RADEON_BIOS_3_SCRATCH); - WREG32(RADEON_BIOS_3_SCRATCH, reg & ~ATOM_S3_DFP2I_ACTIVE); - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - WREG32(RADEON_BIOS_3_SCRATCH, reg); - } else - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { args.ucAction = ATOM_LCD_BLON; atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); @@ -1755,12 +1748,9 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) /* DCE4/5 */ if (ASIC_IS_DCE4(rdev)) { dig = radeon_encoder->enc_priv; - if (ASIC_IS_DCE41(rdev)) { - if (dig->linkb) - return 1; - else - return 0; - } else { + if (ASIC_IS_DCE41(rdev)) + return radeon_crtc->crtc_id; + else { switch (radeon_encoder->encoder_id) { case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: if (dig->linkb) @@ -2333,9 +2323,6 @@ radeon_add_atom_encoder(struct drm_device *dev, default: encoder->possible_crtcs = 0x3; break; - case 4: - encoder->possible_crtcs = 0xf; - break; case 6: encoder->possible_crtcs = 0x3f; break; diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index c90425c439d8..781196db792f 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -32,17 +32,17 @@ * radeon_ddc_probe * */ -bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_extended_probe) +bool radeon_ddc_probe(struct radeon_connector *radeon_connector) { - u8 out = 0x0; - u8 buf[8]; + u8 out_buf[] = { 0x0, 0x0}; + u8 buf[2]; int ret; struct i2c_msg msgs[] = { { .addr = 0x50, .flags = 0, .len = 1, - .buf = &out, + .buf = out_buf, }, { .addr = 0x50, @@ -52,31 +52,15 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_e } }; - /* Read 8 bytes from i2c for extended probe of EDID header */ - if (requires_extended_probe) - msgs[1].len = 8; - /* on hw with routers, select right port */ if (radeon_connector->router.ddc_valid) radeon_router_select_ddc_port(radeon_connector); ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); - if (ret != 2) - /* Couldn't find an accessible DDC on this connector */ - return false; - if (requires_extended_probe) { - /* Probe also for valid EDID header - * EDID header starts with: - * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00. - * Only the first 6 bytes must be valid as - * drm_edid_block_valid() can fix the last 2 bytes */ - if (drm_edid_header_is_valid(buf) < 6) { - /* Couldn't find an accessible EDID on this - * connector */ - return false; - } - } - return true; + if (ret == 2) + return true; + + return false; } /* bit banging i2c */ @@ -898,10 +882,6 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, struct radeon_i2c_chan *i2c; int ret; - /* don't add the mm_i2c bus unless hw_i2c is enabled */ - if (rec->mm_i2c && (radeon_hw_i2c == 0)) - return NULL; - i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); if (i2c == NULL) return NULL; diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 1cfe7539fd9f..9ec830c77af0 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -108,68 +108,6 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev) radeon_irq_set(rdev); } -static bool radeon_msi_ok(struct radeon_device *rdev) -{ - /* RV370/RV380 was first asic with MSI support */ - if (rdev->family < CHIP_RV380) - return false; - - /* MSIs don't work on AGP */ - if (rdev->flags & RADEON_IS_AGP) - return false; - - /* force MSI on */ - if (radeon_msi == 1) - return true; - else if (radeon_msi == 0) - return false; - - /* Quirks */ - /* HP RS690 only seems to work with MSIs. */ - if ((rdev->pdev->device == 0x791f) && - (rdev->pdev->subsystem_vendor == 0x103c) && - (rdev->pdev->subsystem_device == 0x30c2)) - return true; - - /* Dell RS690 only seems to work with MSIs. */ - if ((rdev->pdev->device == 0x791f) && - (rdev->pdev->subsystem_vendor == 0x1028) && - (rdev->pdev->subsystem_device == 0x01fc)) - return true; - - /* Dell RS690 only seems to work with MSIs. */ - if ((rdev->pdev->device == 0x791f) && - (rdev->pdev->subsystem_vendor == 0x1028) && - (rdev->pdev->subsystem_device == 0x01fd)) - return true; - - /* Gateway RS690 only seems to work with MSIs. */ - if ((rdev->pdev->device == 0x791f) && - (rdev->pdev->subsystem_vendor == 0x107b) && - (rdev->pdev->subsystem_device == 0x0185)) - return true; - - /* try and enable MSIs by default on all RS690s */ - if (rdev->family == CHIP_RS690) - return true; - - /* RV515 seems to have MSI issues where it loses - * MSI rearms occasionally. This leads to lockups and freezes. - * disable it by default. - */ - if (rdev->family == CHIP_RV515) - return false; - if (rdev->flags & RADEON_IS_IGP) { - /* APUs work fine with MSIs */ - if (rdev->family >= CHIP_PALM) - return true; - /* lots of IGPs have problems with MSIs */ - return false; - } - - return true; -} - int radeon_irq_kms_init(struct radeon_device *rdev) { int i; @@ -186,8 +124,12 @@ int radeon_irq_kms_init(struct radeon_device *rdev) } /* enable msi */ rdev->msi_enabled = 0; - - if (radeon_msi_ok(rdev)) { + /* MSIs don't seem to work reliably on all IGP + * chips. Disable MSI on them for now. + */ + if ((rdev->family >= CHIP_RV380) && + ((!(rdev->flags & RADEON_IS_IGP)) || (rdev->family >= CHIP_PALM)) && + (!(rdev->flags & RADEON_IS_AGP))) { int ret = pci_enable_msi(rdev->pdev); if (!ret) { rdev->msi_enabled = 1; diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index a9068031ef5b..2f46e0c8df53 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -617,14 +617,6 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc enum drm_connector_status found = connector_status_disconnected; bool color = true; - /* just don't bother on RN50 those chip are often connected to remoting - * console hw and often we get failure to load detect those. So to make - * everyone happy report the encoder as always connected. - */ - if (ASIC_IS_RN50(rdev)) { - return connector_status_connected; - } - /* save the regs we need */ vclk_ecp_cntl = RREG32_PLL(RADEON_VCLK_ECP_CNTL); crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); @@ -658,7 +650,6 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN; WREG32(RADEON_DAC_CNTL, tmp); - tmp = dac_macro_cntl; tmp &= ~(RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G | RADEON_DAC_PDWN_B); @@ -982,7 +973,11 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, static void radeon_ext_tmds_enc_destroy(struct drm_encoder *encoder) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - /* don't destroy the i2c bus record here, this will be done in radeon_i2c_fini */ + struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv; + if (tmds) { + if (tmds->i2c_bus) + radeon_i2c_destroy(tmds->i2c_bus); + } kfree(radeon_encoder->enc_priv); drm_encoder_cleanup(encoder); kfree(radeon_encoder); diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index ed0178f03235..6df4e3cec0c2 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -438,16 +438,12 @@ struct radeon_connector { struct radeon_i2c_chan *ddc_bus; /* some systems have an hdmi and vga port with a shared ddc line */ bool shared_ddc; - /* for some Radeon chip families we apply an additional EDID header - check as part of the DDC probe */ - bool requires_extended_probe; bool use_digital; /* we need to mind the EDID between detect and get modes due to analog/digital/tvencoder */ struct edid *edid; void *con_priv; bool dac_load_detect; - bool detected_by_load; /* if the connection status was determined by load */ uint16_t connector_object_id; struct radeon_hpd hpd; struct radeon_router router; @@ -480,7 +476,6 @@ extern void radeon_dp_set_link_config(struct drm_connector *connector, struct drm_display_mode *mode); extern void radeon_dp_link_train(struct drm_encoder *encoder, struct drm_connector *connector); -extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode); @@ -519,8 +514,7 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c, u8 val); extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector); extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); -extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector, - bool requires_extended_probe); +extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector); diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 35da1b474197..976c3b1b1b6e 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -204,8 +204,7 @@ void radeon_bo_unref(struct radeon_bo **bo) *bo = NULL; } -int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset, - u64 *gpu_addr) +int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr) { int r, i; @@ -213,7 +212,6 @@ int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset, bo->pin_count++; if (gpu_addr) *gpu_addr = radeon_bo_gpu_offset(bo); - WARN_ON_ONCE(max_offset != 0); return 0; } radeon_ttm_placement_from_domain(bo, domain); @@ -221,15 +219,6 @@ int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset, /* force to pin into visible video ram */ bo->placement.lpfn = bo->rdev->mc.visible_vram_size >> PAGE_SHIFT; } - if (max_offset) { - u64 lpfn = max_offset >> PAGE_SHIFT; - - if (!bo->placement.lpfn) - bo->placement.lpfn = bo->rdev->mc.gtt_size >> PAGE_SHIFT; - - if (lpfn < bo->placement.lpfn) - bo->placement.lpfn = lpfn; - } for (i = 0; i < bo->placement.num_placement; i++) bo->placements[i] |= TTM_PL_FLAG_NO_EVICT; r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false, false); @@ -243,11 +232,6 @@ int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset, return r; } -int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr) -{ - return radeon_bo_pin_restricted(bo, domain, 0, gpu_addr); -} - int radeon_bo_unpin(struct radeon_bo *bo) { int r, i; diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index 7199c6ab027e..ede6c13628f2 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -144,8 +144,6 @@ extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr); extern void radeon_bo_kunmap(struct radeon_bo *bo); extern void radeon_bo_unref(struct radeon_bo **bo); extern int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr); -extern int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, - u64 max_offset, u64 *gpu_addr); extern int radeon_bo_unpin(struct radeon_bo *bo); extern int radeon_bo_evict_vram(struct radeon_device *rdev); extern void radeon_bo_force_delete(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 4f88863bcc4c..aaa19dc418a0 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -535,9 +535,7 @@ void radeon_pm_suspend(struct radeon_device *rdev) void radeon_pm_resume(struct radeon_device *rdev) { /* set up the default clocks if the MC ucode is loaded */ - if ((rdev->family >= CHIP_BARTS) && - (rdev->family <= CHIP_CAYMAN) && - rdev->mc_fw) { + if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) { if (rdev->pm.default_vddc) radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, SET_VOLTAGE_TYPE_ASIC_VDDC); @@ -592,15 +590,10 @@ int radeon_pm_init(struct radeon_device *rdev) radeon_pm_print_states(rdev); radeon_pm_init_profile(rdev); /* set up the default clocks if the MC ucode is loaded */ - if ((rdev->family >= CHIP_BARTS) && - (rdev->family <= CHIP_CAYMAN) && - rdev->mc_fw) { + if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) { if (rdev->pm.default_vddc) radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, SET_VOLTAGE_TYPE_ASIC_VDDC); - if (rdev->pm.default_vddci) - radeon_atom_set_voltage(rdev, rdev->pm.default_vddci, - SET_VOLTAGE_TYPE_ASIC_VDDCI); if (rdev->pm.default_sclk) radeon_set_engine_clock(rdev, rdev->pm.default_sclk); if (rdev->pm.default_mclk) diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 3e9b41b38c3f..60125ddba1e9 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -277,12 +277,7 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, DRM_ERROR("Trying to move memory with CP turned off.\n"); return -EINVAL; } - - BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0); - - r = radeon_copy(rdev, old_start, new_start, - new_mem->num_pages * (PAGE_SIZE / RADEON_GPU_PAGE_SIZE), /* GPU pages */ - fence); + r = radeon_copy(rdev, old_start, new_start, new_mem->num_pages, fence); /* FIXME: handle copy error */ r = ttm_bo_move_accel_cleanup(bo, (void *)fence, NULL, evict, no_wait_reserve, no_wait_gpu, new_mem); diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 2026c2d52c57..1f5850e473cc 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -62,7 +62,6 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) { struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); - int i; /* Lock the graphics update lock */ tmp |= AVIVO_D1GRPH_UPDATE_LOCK; @@ -75,11 +74,7 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) (u32)crtc_base); /* Wait for update_pending to go high. */ - for (i = 0; i < rdev->usec_timeout; i++) { - if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING) - break; - udelay(1); - } + while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)); DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); /* Unlock the lock, so double-buffering can take place inside vblank */ @@ -292,7 +287,6 @@ void rs600_hpd_init(struct radeon_device *rdev) default: break; } - radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); } if (rdev->irq.installed) rs600_irq_set(rdev); @@ -324,10 +318,10 @@ void rs600_hpd_fini(struct radeon_device *rdev) void rs600_bm_disable(struct radeon_device *rdev) { - u16 tmp; + u32 tmp; /* disable bus mastering */ - pci_read_config_word(rdev->pdev, 0x4, &tmp); + pci_read_config_word(rdev->pdev, 0x4, (u16*)&tmp); pci_write_config_word(rdev->pdev, 0x4, tmp & 0xFFFB); mdelay(1); } @@ -698,7 +692,9 @@ int rs600_irq_process(struct radeon_device *rdev) WREG32(RADEON_BUS_CNTL, msi_rearm | RS600_MSI_REARM); break; default: - WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN); + msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN; + WREG32(RADEON_MSI_REARM_EN, msi_rearm); + WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN); break; } } diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index d5f45b4c1bec..6613ee9ecca3 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -281,8 +281,12 @@ int rv515_debugfs_ga_info_init(struct radeon_device *rdev) void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) { + save->d1vga_control = RREG32(R_000330_D1VGA_CONTROL); + save->d2vga_control = RREG32(R_000338_D2VGA_CONTROL); save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); + save->d1crtc_control = RREG32(R_006080_D1CRTC_CONTROL); + save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL); /* Stop all video */ WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); @@ -307,6 +311,15 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) /* Unlock host access */ WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); mdelay(1); + /* Restore video state */ + WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control); + WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control); + WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); + WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); + WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control); + WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control); + WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); + WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); } diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 51d20aa63d03..4de51891aa6d 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -47,7 +47,6 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) { struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); - int i; /* Lock the graphics update lock */ tmp |= AVIVO_D1GRPH_UPDATE_LOCK; @@ -67,11 +66,7 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) (u32)crtc_base); /* Wait for update_pending to go high. */ - for (i = 0; i < rdev->usec_timeout; i++) { - if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING) - break; - udelay(1); - } + while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)); DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); /* Unlock the lock, so double-buffering can take place inside vblank */ @@ -151,8 +146,6 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev) WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); - if (rdev->family == CHIP_RV740) - WREG32(MC_VM_MD_L1_TLB3_CNTL, tmp); WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); @@ -543,6 +536,55 @@ static u32 r700_get_tile_pipe_to_backend_map(struct radeon_device *rdev, return backend_map; } +static void rv770_program_channel_remap(struct radeon_device *rdev) +{ + u32 tcp_chan_steer, mc_shared_chremap, tmp; + bool force_no_swizzle; + + switch (rdev->family) { + case CHIP_RV770: + case CHIP_RV730: + force_no_swizzle = false; + break; + case CHIP_RV710: + case CHIP_RV740: + default: + force_no_swizzle = true; + break; + } + + tmp = RREG32(MC_SHARED_CHMAP); + switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { + case 0: + case 1: + default: + /* default mapping */ + mc_shared_chremap = 0x00fac688; + break; + case 2: + case 3: + if (force_no_swizzle) + mc_shared_chremap = 0x00fac688; + else + mc_shared_chremap = 0x00bbc298; + break; + } + + if (rdev->family == CHIP_RV740) + tcp_chan_steer = 0x00ef2a60; + else + tcp_chan_steer = 0x00fac688; + + /* RV770 CE has special chremap setup */ + if (rdev->pdev->device == 0x944e) { + tcp_chan_steer = 0x00b08b08; + mc_shared_chremap = 0x00b08b08; + } + + WREG32(TCP_CHAN_STEER, tcp_chan_steer); + WREG32(MC_SHARED_CHREMAP, mc_shared_chremap); +} + static void rv770_gpu_init(struct radeon_device *rdev) { int i, j, num_qd_pipes; @@ -742,6 +784,8 @@ static void rv770_gpu_init(struct radeon_device *rdev) WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); + rv770_program_channel_remap(rdev); + WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index 75380927e9c6..79fa588e9ed5 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h @@ -174,7 +174,6 @@ #define MC_VM_MD_L1_TLB0_CNTL 0x2654 #define MC_VM_MD_L1_TLB1_CNTL 0x2658 #define MC_VM_MD_L1_TLB2_CNTL 0x265C -#define MC_VM_MD_L1_TLB3_CNTL 0x2698 #define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C #define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 #define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 7632edb2f46e..2e618b5ac465 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -353,10 +353,8 @@ static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc) ret = ttm_tt_set_user(bo->ttm, current, bo->buffer_start, bo->num_pages); - if (unlikely(ret != 0)) { + if (unlikely(ret != 0)) ttm_tt_destroy(bo->ttm); - bo->ttm = NULL; - } break; default: printk(KERN_ERR TTM_PFX "Illegal buffer object type\n"); @@ -392,13 +390,10 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, * Create and bind a ttm if required. */ - if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) { - if (bo->ttm == NULL) { - bool zero = !(old_man->flags & TTM_MEMTYPE_FLAG_FIXED); - ret = ttm_bo_add_ttm(bo, zero); - if (ret) - goto out_err; - } + if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED) && (bo->ttm == NULL)) { + ret = ttm_bo_add_ttm(bo, false); + if (ret) + goto out_err; ret = ttm_tt_set_placement_caching(bo->ttm, mem->placement); if (ret) @@ -1809,7 +1804,6 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink) spin_unlock(&glob->lru_lock); (void) ttm_bo_cleanup_refs(bo, false, false, false); kref_put(&bo->list_kref, ttm_bo_release_list); - spin_lock(&glob->lru_lock); continue; } diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index ae3c6f5dd2b7..77dbf408c0d0 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -635,13 +635,13 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, if (ret) return ret; + ttm_bo_free_old_node(bo); if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && (bo->ttm != NULL)) { ttm_tt_unbind(bo->ttm); ttm_tt_destroy(bo->ttm); bo->ttm = NULL; } - ttm_bo_free_old_node(bo); } else { /** * This should help pipeline ordinary buffer moves. diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 55d4b29330fa..96949b93d920 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -147,7 +147,6 @@ static struct pci_device_id vmw_pci_id_list[] = { {0x15ad, 0x0405, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VMWGFX_CHIP_SVGAII}, {0, 0, 0} }; -MODULE_DEVICE_TABLE(pci, vmw_pci_id_list); static int enable_fbdev; @@ -858,11 +857,6 @@ static void vmw_pm_complete(struct device *kdev) struct drm_device *dev = pci_get_drvdata(pdev); struct vmw_private *dev_priv = vmw_priv(dev); - mutex_lock(&dev_priv->hw_mutex); - vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); - (void) vmw_read(dev_priv, SVGA_REG_ID); - mutex_unlock(&dev_priv->hw_mutex); - /** * Reclaim 3d reference held by fbdev and potentially * start fifo. diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 8a38c91f4c9c..dfe32e62bd90 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -313,7 +313,7 @@ int vmw_framebuffer_create_handle(struct drm_framebuffer *fb, unsigned int *handle) { if (handle) - *handle = 0; + handle = 0; return 0; } diff --git a/drivers/gpu/ion/Kconfig b/drivers/gpu/ion/Kconfig deleted file mode 100644 index 5b48b4e85e73..000000000000 --- a/drivers/gpu/ion/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -menuconfig ION - tristate "Ion Memory Manager" - select GENERIC_ALLOCATOR - help - Chose this option to enable the ION Memory Manager. - -config ION_TEGRA - tristate "Ion for Tegra" - depends on ARCH_TEGRA && ION - help - Choose this option if you wish to use ion on an nVidia Tegra. - diff --git a/drivers/gpu/ion/Makefile b/drivers/gpu/ion/Makefile deleted file mode 100644 index 73fe3fa10706..000000000000 --- a/drivers/gpu/ion/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -obj-$(CONFIG_ION) += ion.o ion_heap.o ion_system_heap.o ion_carveout_heap.o -obj-$(CONFIG_ION_TEGRA) += tegra/ diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c deleted file mode 100644 index 37b23af0550b..000000000000 --- a/drivers/gpu/ion/ion.c +++ /dev/null @@ -1,1186 +0,0 @@ -/* - * drivers/gpu/ion/ion.c - * - * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ion_priv.h" -#define DEBUG - -/** - * struct ion_device - the metadata of the ion device node - * @dev: the actual misc device - * @buffers: an rb tree of all the existing buffers - * @lock: lock protecting the buffers & heaps trees - * @heaps: list of all the heaps in the system - * @user_clients: list of all the clients created from userspace - */ -struct ion_device { - struct miscdevice dev; - struct rb_root buffers; - struct mutex lock; - struct rb_root heaps; - long (*custom_ioctl) (struct ion_client *client, unsigned int cmd, - unsigned long arg); - struct rb_root user_clients; - struct rb_root kernel_clients; - struct dentry *debug_root; -}; - -/** - * struct ion_client - a process/hw block local address space - * @ref: for reference counting the client - * @node: node in the tree of all clients - * @dev: backpointer to ion device - * @handles: an rb tree of all the handles in this client - * @lock: lock protecting the tree of handles - * @heap_mask: mask of all supported heaps - * @name: used for debugging - * @task: used for debugging - * - * A client represents a list of buffers this client may access. - * The mutex stored here is used to protect both handles tree - * as well as the handles themselves, and should be held while modifying either. - */ -struct ion_client { - struct kref ref; - struct rb_node node; - struct ion_device *dev; - struct rb_root handles; - struct mutex lock; - unsigned int heap_mask; - const char *name; - struct task_struct *task; - pid_t pid; - struct dentry *debug_root; -}; - -/** - * ion_handle - a client local reference to a buffer - * @ref: reference count - * @client: back pointer to the client the buffer resides in - * @buffer: pointer to the buffer - * @node: node in the client's handle rbtree - * @kmap_cnt: count of times this client has mapped to kernel - * @dmap_cnt: count of times this client has mapped for dma - * @usermap_cnt: count of times this client has mapped for userspace - * - * Modifications to node, map_cnt or mapping should be protected by the - * lock in the client. Other fields are never changed after initialization. - */ -struct ion_handle { - struct kref ref; - struct ion_client *client; - struct ion_buffer *buffer; - struct rb_node node; - unsigned int kmap_cnt; - unsigned int dmap_cnt; - unsigned int usermap_cnt; -}; - -/* this function should only be called while dev->lock is held */ -static void ion_buffer_add(struct ion_device *dev, - struct ion_buffer *buffer) -{ - struct rb_node **p = &dev->buffers.rb_node; - struct rb_node *parent = NULL; - struct ion_buffer *entry; - - while (*p) { - parent = *p; - entry = rb_entry(parent, struct ion_buffer, node); - - if (buffer < entry) { - p = &(*p)->rb_left; - } else if (buffer > entry) { - p = &(*p)->rb_right; - } else { - pr_err("%s: buffer already found.", __func__); - BUG(); - } - } - - rb_link_node(&buffer->node, parent, p); - rb_insert_color(&buffer->node, &dev->buffers); -} - -/* this function should only be called while dev->lock is held */ -static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, - struct ion_device *dev, - unsigned long len, - unsigned long align, - unsigned long flags) -{ - struct ion_buffer *buffer; - int ret; - - buffer = kzalloc(sizeof(struct ion_buffer), GFP_KERNEL); - if (!buffer) - return ERR_PTR(-ENOMEM); - - buffer->heap = heap; - kref_init(&buffer->ref); - - ret = heap->ops->allocate(heap, buffer, len, align, flags); - if (ret) { - kfree(buffer); - return ERR_PTR(ret); - } - buffer->dev = dev; - buffer->size = len; - mutex_init(&buffer->lock); - ion_buffer_add(dev, buffer); - return buffer; -} - -static void ion_buffer_destroy(struct kref *kref) -{ - struct ion_buffer *buffer = container_of(kref, struct ion_buffer, ref); - struct ion_device *dev = buffer->dev; - - buffer->heap->ops->free(buffer); - mutex_lock(&dev->lock); - rb_erase(&buffer->node, &dev->buffers); - mutex_unlock(&dev->lock); - kfree(buffer); -} - -static void ion_buffer_get(struct ion_buffer *buffer) -{ - kref_get(&buffer->ref); -} - -static int ion_buffer_put(struct ion_buffer *buffer) -{ - return kref_put(&buffer->ref, ion_buffer_destroy); -} - -static struct ion_handle *ion_handle_create(struct ion_client *client, - struct ion_buffer *buffer) -{ - struct ion_handle *handle; - - handle = kzalloc(sizeof(struct ion_handle), GFP_KERNEL); - if (!handle) - return ERR_PTR(-ENOMEM); - kref_init(&handle->ref); - rb_init_node(&handle->node); - handle->client = client; - ion_buffer_get(buffer); - handle->buffer = buffer; - - return handle; -} - -static void ion_handle_destroy(struct kref *kref) -{ - struct ion_handle *handle = container_of(kref, struct ion_handle, ref); - /* XXX Can a handle be destroyed while it's map count is non-zero?: - if (handle->map_cnt) unmap - */ - ion_buffer_put(handle->buffer); - mutex_lock(&handle->client->lock); - if (!RB_EMPTY_NODE(&handle->node)) - rb_erase(&handle->node, &handle->client->handles); - mutex_unlock(&handle->client->lock); - kfree(handle); -} - -struct ion_buffer *ion_handle_buffer(struct ion_handle *handle) -{ - return handle->buffer; -} - -static void ion_handle_get(struct ion_handle *handle) -{ - kref_get(&handle->ref); -} - -static int ion_handle_put(struct ion_handle *handle) -{ - return kref_put(&handle->ref, ion_handle_destroy); -} - -static struct ion_handle *ion_handle_lookup(struct ion_client *client, - struct ion_buffer *buffer) -{ - struct rb_node *n; - - for (n = rb_first(&client->handles); n; n = rb_next(n)) { - struct ion_handle *handle = rb_entry(n, struct ion_handle, - node); - if (handle->buffer == buffer) - return handle; - } - return NULL; -} - -static bool ion_handle_validate(struct ion_client *client, struct ion_handle *handle) -{ - struct rb_node *n = client->handles.rb_node; - - while (n) { - struct ion_handle *handle_node = rb_entry(n, struct ion_handle, - node); - if (handle < handle_node) - n = n->rb_left; - else if (handle > handle_node) - n = n->rb_right; - else - return true; - } - return false; -} - -static void ion_handle_add(struct ion_client *client, struct ion_handle *handle) -{ - struct rb_node **p = &client->handles.rb_node; - struct rb_node *parent = NULL; - struct ion_handle *entry; - - while (*p) { - parent = *p; - entry = rb_entry(parent, struct ion_handle, node); - - if (handle < entry) - p = &(*p)->rb_left; - else if (handle > entry) - p = &(*p)->rb_right; - else - WARN(1, "%s: buffer already found.", __func__); - } - - rb_link_node(&handle->node, parent, p); - rb_insert_color(&handle->node, &client->handles); -} - -struct ion_handle *ion_alloc(struct ion_client *client, size_t len, - size_t align, unsigned int flags) -{ - struct rb_node *n; - struct ion_handle *handle; - struct ion_device *dev = client->dev; - struct ion_buffer *buffer = NULL; - - /* - * traverse the list of heaps available in this system in priority - * order. If the heap type is supported by the client, and matches the - * request of the caller allocate from it. Repeat until allocate has - * succeeded or all heaps have been tried - */ - mutex_lock(&dev->lock); - for (n = rb_first(&dev->heaps); n != NULL; n = rb_next(n)) { - struct ion_heap *heap = rb_entry(n, struct ion_heap, node); - /* if the client doesn't support this heap type */ - if (!((1 << heap->type) & client->heap_mask)) - continue; - /* if the caller didn't specify this heap type */ - if (!((1 << heap->id) & flags)) - continue; - buffer = ion_buffer_create(heap, dev, len, align, flags); - if (!IS_ERR_OR_NULL(buffer)) - break; - } - mutex_unlock(&dev->lock); - - if (IS_ERR_OR_NULL(buffer)) - return ERR_PTR(PTR_ERR(buffer)); - - handle = ion_handle_create(client, buffer); - - if (IS_ERR_OR_NULL(handle)) - goto end; - - /* - * ion_buffer_create will create a buffer with a ref_cnt of 1, - * and ion_handle_create will take a second reference, drop one here - */ - ion_buffer_put(buffer); - - mutex_lock(&client->lock); - ion_handle_add(client, handle); - mutex_unlock(&client->lock); - return handle; - -end: - ion_buffer_put(buffer); - return handle; -} - -void ion_free(struct ion_client *client, struct ion_handle *handle) -{ - bool valid_handle; - - BUG_ON(client != handle->client); - - mutex_lock(&client->lock); - valid_handle = ion_handle_validate(client, handle); - mutex_unlock(&client->lock); - - if (!valid_handle) { - WARN("%s: invalid handle passed to free.\n", __func__); - return; - } - ion_handle_put(handle); -} - -static void ion_client_get(struct ion_client *client); -static int ion_client_put(struct ion_client *client); - -static bool _ion_map(int *buffer_cnt, int *handle_cnt) -{ - bool map; - - BUG_ON(*handle_cnt != 0 && *buffer_cnt == 0); - - if (*buffer_cnt) - map = false; - else - map = true; - if (*handle_cnt == 0) - (*buffer_cnt)++; - (*handle_cnt)++; - return map; -} - -static bool _ion_unmap(int *buffer_cnt, int *handle_cnt) -{ - BUG_ON(*handle_cnt == 0); - (*handle_cnt)--; - if (*handle_cnt != 0) - return false; - BUG_ON(*buffer_cnt == 0); - (*buffer_cnt)--; - if (*buffer_cnt == 0) - return true; - return false; -} - -int ion_phys(struct ion_client *client, struct ion_handle *handle, - ion_phys_addr_t *addr, size_t *len) -{ - struct ion_buffer *buffer; - int ret; - - mutex_lock(&client->lock); - if (!ion_handle_validate(client, handle)) { - mutex_unlock(&client->lock); - return -EINVAL; - } - - buffer = handle->buffer; - - if (!buffer->heap->ops->phys) { - pr_err("%s: ion_phys is not implemented by this heap.\n", - __func__); - mutex_unlock(&client->lock); - return -ENODEV; - } - mutex_unlock(&client->lock); - ret = buffer->heap->ops->phys(buffer->heap, buffer, addr, len); - return ret; -} - -void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle) -{ - struct ion_buffer *buffer; - void *vaddr; - - mutex_lock(&client->lock); - if (!ion_handle_validate(client, handle)) { - pr_err("%s: invalid handle passed to map_kernel.\n", - __func__); - mutex_unlock(&client->lock); - return ERR_PTR(-EINVAL); - } - - buffer = handle->buffer; - mutex_lock(&buffer->lock); - - if (!handle->buffer->heap->ops->map_kernel) { - pr_err("%s: map_kernel is not implemented by this heap.\n", - __func__); - mutex_unlock(&buffer->lock); - mutex_unlock(&client->lock); - return ERR_PTR(-ENODEV); - } - - if (_ion_map(&buffer->kmap_cnt, &handle->kmap_cnt)) { - vaddr = buffer->heap->ops->map_kernel(buffer->heap, buffer); - if (IS_ERR_OR_NULL(vaddr)) - _ion_unmap(&buffer->kmap_cnt, &handle->kmap_cnt); - buffer->vaddr = vaddr; - } else { - vaddr = buffer->vaddr; - } - mutex_unlock(&buffer->lock); - mutex_unlock(&client->lock); - return vaddr; -} - -struct scatterlist *ion_map_dma(struct ion_client *client, - struct ion_handle *handle) -{ - struct ion_buffer *buffer; - struct scatterlist *sglist; - - mutex_lock(&client->lock); - if (!ion_handle_validate(client, handle)) { - pr_err("%s: invalid handle passed to map_dma.\n", - __func__); - mutex_unlock(&client->lock); - return ERR_PTR(-EINVAL); - } - buffer = handle->buffer; - mutex_lock(&buffer->lock); - - if (!handle->buffer->heap->ops->map_dma) { - pr_err("%s: map_kernel is not implemented by this heap.\n", - __func__); - mutex_unlock(&buffer->lock); - mutex_unlock(&client->lock); - return ERR_PTR(-ENODEV); - } - if (_ion_map(&buffer->dmap_cnt, &handle->dmap_cnt)) { - sglist = buffer->heap->ops->map_dma(buffer->heap, buffer); - if (IS_ERR_OR_NULL(sglist)) - _ion_unmap(&buffer->dmap_cnt, &handle->dmap_cnt); - buffer->sglist = sglist; - } else { - sglist = buffer->sglist; - } - mutex_unlock(&buffer->lock); - mutex_unlock(&client->lock); - return sglist; -} - -void ion_unmap_kernel(struct ion_client *client, struct ion_handle *handle) -{ - struct ion_buffer *buffer; - - mutex_lock(&client->lock); - buffer = handle->buffer; - mutex_lock(&buffer->lock); - if (_ion_unmap(&buffer->kmap_cnt, &handle->kmap_cnt)) { - buffer->heap->ops->unmap_kernel(buffer->heap, buffer); - buffer->vaddr = NULL; - } - mutex_unlock(&buffer->lock); - mutex_unlock(&client->lock); -} - -void ion_unmap_dma(struct ion_client *client, struct ion_handle *handle) -{ - struct ion_buffer *buffer; - - mutex_lock(&client->lock); - buffer = handle->buffer; - mutex_lock(&buffer->lock); - if (_ion_unmap(&buffer->dmap_cnt, &handle->dmap_cnt)) { - buffer->heap->ops->unmap_dma(buffer->heap, buffer); - buffer->sglist = NULL; - } - mutex_unlock(&buffer->lock); - mutex_unlock(&client->lock); -} - - -struct ion_buffer *ion_share(struct ion_client *client, - struct ion_handle *handle) -{ - bool valid_handle; - - mutex_lock(&client->lock); - valid_handle = ion_handle_validate(client, handle); - mutex_unlock(&client->lock); - if (!valid_handle) { - WARN("%s: invalid handle passed to share.\n", __func__); - return ERR_PTR(-EINVAL); - } - - /* do not take an extra reference here, the burden is on the caller - * to make sure the buffer doesn't go away while it's passing it - * to another client -- ion_free should not be called on this handle - * until the buffer has been imported into the other client - */ - return handle->buffer; -} - -struct ion_handle *ion_import(struct ion_client *client, - struct ion_buffer *buffer) -{ - struct ion_handle *handle = NULL; - - mutex_lock(&client->lock); - /* if a handle exists for this buffer just take a reference to it */ - handle = ion_handle_lookup(client, buffer); - if (!IS_ERR_OR_NULL(handle)) { - ion_handle_get(handle); - goto end; - } - handle = ion_handle_create(client, buffer); - if (IS_ERR_OR_NULL(handle)) - goto end; - ion_handle_add(client, handle); -end: - mutex_unlock(&client->lock); - return handle; -} - -static const struct file_operations ion_share_fops; - -struct ion_handle *ion_import_fd(struct ion_client *client, int fd) -{ - struct file *file = fget(fd); - struct ion_handle *handle; - - if (!file) { - pr_err("%s: imported fd not found in file table.\n", __func__); - return ERR_PTR(-EINVAL); - } - if (file->f_op != &ion_share_fops) { - pr_err("%s: imported file is not a shared ion file.\n", - __func__); - handle = ERR_PTR(-EINVAL); - goto end; - } - handle = ion_import(client, file->private_data); -end: - fput(file); - return handle; -} - -static int ion_debug_client_show(struct seq_file *s, void *unused) -{ - struct ion_client *client = s->private; - struct rb_node *n; - size_t sizes[ION_NUM_HEAPS] = {0}; - const char *names[ION_NUM_HEAPS] = {0}; - int i; - - mutex_lock(&client->lock); - for (n = rb_first(&client->handles); n; n = rb_next(n)) { - struct ion_handle *handle = rb_entry(n, struct ion_handle, - node); - enum ion_heap_type type = handle->buffer->heap->type; - - if (!names[type]) - names[type] = handle->buffer->heap->name; - sizes[type] += handle->buffer->size; - } - mutex_unlock(&client->lock); - - seq_printf(s, "%16.16s: %16.16s\n", "heap_name", "size_in_bytes"); - for (i = 0; i < ION_NUM_HEAPS; i++) { - if (!names[i]) - continue; - seq_printf(s, "%16.16s: %16u %d\n", names[i], sizes[i], - atomic_read(&client->ref.refcount)); - } - return 0; -} - -static int ion_debug_client_open(struct inode *inode, struct file *file) -{ - return single_open(file, ion_debug_client_show, inode->i_private); -} - -static const struct file_operations debug_client_fops = { - .open = ion_debug_client_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static struct ion_client *ion_client_lookup(struct ion_device *dev, - struct task_struct *task) -{ - struct rb_node *n = dev->user_clients.rb_node; - struct ion_client *client; - - mutex_lock(&dev->lock); - while (n) { - client = rb_entry(n, struct ion_client, node); - if (task == client->task) { - ion_client_get(client); - mutex_unlock(&dev->lock); - return client; - } else if (task < client->task) { - n = n->rb_left; - } else if (task > client->task) { - n = n->rb_right; - } - } - mutex_unlock(&dev->lock); - return NULL; -} - -struct ion_client *ion_client_create(struct ion_device *dev, - unsigned int heap_mask, - const char *name) -{ - struct ion_client *client; - struct task_struct *task; - struct rb_node **p; - struct rb_node *parent = NULL; - struct ion_client *entry; - char debug_name[64]; - pid_t pid; - - get_task_struct(current->group_leader); - task_lock(current->group_leader); - pid = task_pid_nr(current->group_leader); - /* don't bother to store task struct for kernel threads, - they can't be killed anyway */ - if (current->group_leader->flags & PF_KTHREAD) { - put_task_struct(current->group_leader); - task = NULL; - } else { - task = current->group_leader; - } - task_unlock(current->group_leader); - - /* if this isn't a kernel thread, see if a client already - exists */ - if (task) { - client = ion_client_lookup(dev, task); - if (!IS_ERR_OR_NULL(client)) { - put_task_struct(current->group_leader); - return client; - } - } - - client = kzalloc(sizeof(struct ion_client), GFP_KERNEL); - if (!client) { - put_task_struct(current->group_leader); - return ERR_PTR(-ENOMEM); - } - - client->dev = dev; - client->handles = RB_ROOT; - mutex_init(&client->lock); - client->name = name; - client->heap_mask = heap_mask; - client->task = task; - client->pid = pid; - kref_init(&client->ref); - - mutex_lock(&dev->lock); - if (task) { - p = &dev->user_clients.rb_node; - while (*p) { - parent = *p; - entry = rb_entry(parent, struct ion_client, node); - - if (task < entry->task) - p = &(*p)->rb_left; - else if (task > entry->task) - p = &(*p)->rb_right; - } - rb_link_node(&client->node, parent, p); - rb_insert_color(&client->node, &dev->user_clients); - } else { - p = &dev->kernel_clients.rb_node; - while (*p) { - parent = *p; - entry = rb_entry(parent, struct ion_client, node); - - if (client < entry) - p = &(*p)->rb_left; - else if (client > entry) - p = &(*p)->rb_right; - } - rb_link_node(&client->node, parent, p); - rb_insert_color(&client->node, &dev->kernel_clients); - } - - snprintf(debug_name, 64, "%u", client->pid); - client->debug_root = debugfs_create_file(debug_name, 0664, - dev->debug_root, client, - &debug_client_fops); - mutex_unlock(&dev->lock); - - return client; -} - -static void _ion_client_destroy(struct kref *kref) -{ - struct ion_client *client = container_of(kref, struct ion_client, ref); - struct ion_device *dev = client->dev; - struct rb_node *n; - - pr_debug("%s: %d\n", __func__, __LINE__); - while ((n = rb_first(&client->handles))) { - struct ion_handle *handle = rb_entry(n, struct ion_handle, - node); - ion_handle_destroy(&handle->ref); - } - mutex_lock(&dev->lock); - if (client->task) { - rb_erase(&client->node, &dev->user_clients); - put_task_struct(client->task); - } else { - rb_erase(&client->node, &dev->kernel_clients); - } - debugfs_remove_recursive(client->debug_root); - mutex_unlock(&dev->lock); - - kfree(client); -} - -static void ion_client_get(struct ion_client *client) -{ - kref_get(&client->ref); -} - -static int ion_client_put(struct ion_client *client) -{ - return kref_put(&client->ref, _ion_client_destroy); -} - -void ion_client_destroy(struct ion_client *client) -{ - ion_client_put(client); -} - -static int ion_share_release(struct inode *inode, struct file* file) -{ - struct ion_buffer *buffer = file->private_data; - - pr_debug("%s: %d\n", __func__, __LINE__); - /* drop the reference to the buffer -- this prevents the - buffer from going away because the client holding it exited - while it was being passed */ - ion_buffer_put(buffer); - return 0; -} - -static void ion_vma_open(struct vm_area_struct *vma) -{ - - struct ion_buffer *buffer = vma->vm_file->private_data; - struct ion_handle *handle = vma->vm_private_data; - struct ion_client *client; - - pr_debug("%s: %d\n", __func__, __LINE__); - /* check that the client still exists and take a reference so - it can't go away until this vma is closed */ - client = ion_client_lookup(buffer->dev, current->group_leader); - if (IS_ERR_OR_NULL(client)) { - vma->vm_private_data = NULL; - return; - } - pr_debug("%s: %d client_cnt %d handle_cnt %d alloc_cnt %d\n", - __func__, __LINE__, - atomic_read(&client->ref.refcount), - atomic_read(&handle->ref.refcount), - atomic_read(&buffer->ref.refcount)); -} - -static void ion_vma_close(struct vm_area_struct *vma) -{ - struct ion_handle *handle = vma->vm_private_data; - struct ion_buffer *buffer = vma->vm_file->private_data; - struct ion_client *client; - - pr_debug("%s: %d\n", __func__, __LINE__); - /* this indicates the client is gone, nothing to do here */ - if (!handle) - return; - client = handle->client; - pr_debug("%s: %d client_cnt %d handle_cnt %d alloc_cnt %d\n", - __func__, __LINE__, - atomic_read(&client->ref.refcount), - atomic_read(&handle->ref.refcount), - atomic_read(&buffer->ref.refcount)); - ion_handle_put(handle); - ion_client_put(client); - pr_debug("%s: %d client_cnt %d handle_cnt %d alloc_cnt %d\n", - __func__, __LINE__, - atomic_read(&client->ref.refcount), - atomic_read(&handle->ref.refcount), - atomic_read(&buffer->ref.refcount)); -} - -static struct vm_operations_struct ion_vm_ops = { - .open = ion_vma_open, - .close = ion_vma_close, -}; - -static int ion_share_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct ion_buffer *buffer = file->private_data; - unsigned long size = vma->vm_end - vma->vm_start; - struct ion_client *client; - struct ion_handle *handle; - int ret; - - pr_debug("%s: %d\n", __func__, __LINE__); - /* make sure the client still exists, it's possible for the client to - have gone away but the map/share fd still to be around, take - a reference to it so it can't go away while this mapping exists */ - client = ion_client_lookup(buffer->dev, current->group_leader); - if (IS_ERR_OR_NULL(client)) { - pr_err("%s: trying to mmap an ion handle in a process with no " - "ion client\n", __func__); - return -EINVAL; - } - - if ((size > buffer->size) || (size + (vma->vm_pgoff << PAGE_SHIFT) > - buffer->size)) { - pr_err("%s: trying to map larger area than handle has available" - "\n", __func__); - ret = -EINVAL; - goto err; - } - - /* find the handle and take a reference to it */ - handle = ion_import(client, buffer); - if (IS_ERR_OR_NULL(handle)) { - ret = -EINVAL; - goto err; - } - - if (!handle->buffer->heap->ops->map_user) { - pr_err("%s: this heap does not define a method for mapping " - "to userspace\n", __func__); - ret = -EINVAL; - goto err1; - } - - mutex_lock(&buffer->lock); - /* now map it to userspace */ - ret = buffer->heap->ops->map_user(buffer->heap, buffer, vma); - mutex_unlock(&buffer->lock); - if (ret) { - pr_err("%s: failure mapping buffer to userspace\n", - __func__); - goto err1; - } - - vma->vm_ops = &ion_vm_ops; - /* move the handle into the vm_private_data so we can access it from - vma_open/close */ - vma->vm_private_data = handle; - pr_debug("%s: %d client_cnt %d handle_cnt %d alloc_cnt %d\n", - __func__, __LINE__, - atomic_read(&client->ref.refcount), - atomic_read(&handle->ref.refcount), - atomic_read(&buffer->ref.refcount)); - return 0; - -err1: - /* drop the reference to the handle */ - ion_handle_put(handle); -err: - /* drop the reference to the client */ - ion_client_put(client); - return ret; -} - -static const struct file_operations ion_share_fops = { - .owner = THIS_MODULE, - .release = ion_share_release, - .mmap = ion_share_mmap, -}; - -static int ion_ioctl_share(struct file *parent, struct ion_client *client, - struct ion_handle *handle) -{ - int fd = get_unused_fd(); - struct file *file; - - if (fd < 0) - return -ENFILE; - - file = anon_inode_getfile("ion_share_fd", &ion_share_fops, - handle->buffer, O_RDWR); - if (IS_ERR_OR_NULL(file)) - goto err; - ion_buffer_get(handle->buffer); - fd_install(fd, file); - - return fd; - -err: - put_unused_fd(fd); - return -ENFILE; -} - -static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - struct ion_client *client = filp->private_data; - - switch (cmd) { - case ION_IOC_ALLOC: - { - struct ion_allocation_data data; - - if (copy_from_user(&data, (void __user *)arg, sizeof(data))) - return -EFAULT; - data.handle = ion_alloc(client, data.len, data.align, - data.flags); - if (copy_to_user((void __user *)arg, &data, sizeof(data))) - return -EFAULT; - break; - } - case ION_IOC_FREE: - { - struct ion_handle_data data; - bool valid; - - if (copy_from_user(&data, (void __user *)arg, - sizeof(struct ion_handle_data))) - return -EFAULT; - mutex_lock(&client->lock); - valid = ion_handle_validate(client, data.handle); - mutex_unlock(&client->lock); - if (!valid) - return -EINVAL; - ion_free(client, data.handle); - break; - } - case ION_IOC_MAP: - case ION_IOC_SHARE: - { - struct ion_fd_data data; - - if (copy_from_user(&data, (void __user *)arg, sizeof(data))) - return -EFAULT; - mutex_lock(&client->lock); - if (!ion_handle_validate(client, data.handle)) { - pr_err("%s: invalid handle passed to share ioctl.\n", - __func__); - mutex_unlock(&client->lock); - return -EINVAL; - } - data.fd = ion_ioctl_share(filp, client, data.handle); - mutex_unlock(&client->lock); - if (copy_to_user((void __user *)arg, &data, sizeof(data))) - return -EFAULT; - break; - } - case ION_IOC_IMPORT: - { - struct ion_fd_data data; - if (copy_from_user(&data, (void __user *)arg, - sizeof(struct ion_fd_data))) - return -EFAULT; - - data.handle = ion_import_fd(client, data.fd); - if (IS_ERR(data.handle)) - data.handle = NULL; - if (copy_to_user((void __user *)arg, &data, - sizeof(struct ion_fd_data))) - return -EFAULT; - break; - } - case ION_IOC_CUSTOM: - { - struct ion_device *dev = client->dev; - struct ion_custom_data data; - - if (!dev->custom_ioctl) - return -ENOTTY; - if (copy_from_user(&data, (void __user *)arg, - sizeof(struct ion_custom_data))) - return -EFAULT; - return dev->custom_ioctl(client, data.cmd, data.arg); - } - default: - return -ENOTTY; - } - return 0; -} - -static int ion_release(struct inode *inode, struct file *file) -{ - struct ion_client *client = file->private_data; - - pr_debug("%s: %d\n", __func__, __LINE__); - ion_client_put(client); - return 0; -} - -static int ion_open(struct inode *inode, struct file *file) -{ - struct miscdevice *miscdev = file->private_data; - struct ion_device *dev = container_of(miscdev, struct ion_device, dev); - struct ion_client *client; - - pr_debug("%s: %d\n", __func__, __LINE__); - client = ion_client_create(dev, -1, "user"); - if (IS_ERR_OR_NULL(client)) - return PTR_ERR(client); - file->private_data = client; - - return 0; -} - -static const struct file_operations ion_fops = { - .owner = THIS_MODULE, - .open = ion_open, - .release = ion_release, - .unlocked_ioctl = ion_ioctl, -}; - -static size_t ion_debug_heap_total(struct ion_client *client, - enum ion_heap_type type) -{ - size_t size = 0; - struct rb_node *n; - - mutex_lock(&client->lock); - for (n = rb_first(&client->handles); n; n = rb_next(n)) { - struct ion_handle *handle = rb_entry(n, - struct ion_handle, - node); - if (handle->buffer->heap->type == type) - size += handle->buffer->size; - } - mutex_unlock(&client->lock); - return size; -} - -static int ion_debug_heap_show(struct seq_file *s, void *unused) -{ - struct ion_heap *heap = s->private; - struct ion_device *dev = heap->dev; - struct rb_node *n; - - seq_printf(s, "%16.s %16.s %16.s\n", "client", "pid", "size"); - for (n = rb_first(&dev->user_clients); n; n = rb_next(n)) { - struct ion_client *client = rb_entry(n, struct ion_client, - node); - char task_comm[TASK_COMM_LEN]; - size_t size = ion_debug_heap_total(client, heap->type); - if (!size) - continue; - - get_task_comm(task_comm, client->task); - seq_printf(s, "%16.s %16u %16u\n", task_comm, client->pid, - size); - } - - for (n = rb_first(&dev->kernel_clients); n; n = rb_next(n)) { - struct ion_client *client = rb_entry(n, struct ion_client, - node); - size_t size = ion_debug_heap_total(client, heap->type); - if (!size) - continue; - seq_printf(s, "%16.s %16u %16u\n", client->name, client->pid, - size); - } - return 0; -} - -static int ion_debug_heap_open(struct inode *inode, struct file *file) -{ - return single_open(file, ion_debug_heap_show, inode->i_private); -} - -static const struct file_operations debug_heap_fops = { - .open = ion_debug_heap_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap) -{ - struct rb_node **p = &dev->heaps.rb_node; - struct rb_node *parent = NULL; - struct ion_heap *entry; - - heap->dev = dev; - mutex_lock(&dev->lock); - while (*p) { - parent = *p; - entry = rb_entry(parent, struct ion_heap, node); - - if (heap->id < entry->id) { - p = &(*p)->rb_left; - } else if (heap->id > entry->id ) { - p = &(*p)->rb_right; - } else { - pr_err("%s: can not insert multiple heaps with " - "id %d\n", __func__, heap->id); - goto end; - } - } - - rb_link_node(&heap->node, parent, p); - rb_insert_color(&heap->node, &dev->heaps); - debugfs_create_file(heap->name, 0664, dev->debug_root, heap, - &debug_heap_fops); -end: - mutex_unlock(&dev->lock); -} - -struct ion_device *ion_device_create(long (*custom_ioctl) - (struct ion_client *client, - unsigned int cmd, - unsigned long arg)) -{ - struct ion_device *idev; - int ret; - - idev = kzalloc(sizeof(struct ion_device), GFP_KERNEL); - if (!idev) - return ERR_PTR(-ENOMEM); - - idev->dev.minor = MISC_DYNAMIC_MINOR; - idev->dev.name = "ion"; - idev->dev.fops = &ion_fops; - idev->dev.parent = NULL; - ret = misc_register(&idev->dev); - if (ret) { - pr_err("ion: failed to register misc device.\n"); - return ERR_PTR(ret); - } - - idev->debug_root = debugfs_create_dir("ion", NULL); - if (IS_ERR_OR_NULL(idev->debug_root)) - pr_err("ion: failed to create debug files.\n"); - - idev->custom_ioctl = custom_ioctl; - idev->buffers = RB_ROOT; - mutex_init(&idev->lock); - idev->heaps = RB_ROOT; - idev->user_clients = RB_ROOT; - idev->kernel_clients = RB_ROOT; - return idev; -} - -void ion_device_destroy(struct ion_device *dev) -{ - misc_deregister(&dev->dev); - /* XXX need to free the heaps and clients ? */ - kfree(dev); -} diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c deleted file mode 100644 index 606adae13f48..000000000000 --- a/drivers/gpu/ion/ion_carveout_heap.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * drivers/gpu/ion/ion_carveout_heap.c - * - * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include "ion_priv.h" - -#include - -struct ion_carveout_heap { - struct ion_heap heap; - struct gen_pool *pool; - ion_phys_addr_t base; -}; - -ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap, - unsigned long size, - unsigned long align) -{ - struct ion_carveout_heap *carveout_heap = - container_of(heap, struct ion_carveout_heap, heap); - unsigned long offset = gen_pool_alloc(carveout_heap->pool, size); - - if (!offset) - return ION_CARVEOUT_ALLOCATE_FAIL; - - return offset; -} - -void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr, - unsigned long size) -{ - struct ion_carveout_heap *carveout_heap = - container_of(heap, struct ion_carveout_heap, heap); - - if (addr == ION_CARVEOUT_ALLOCATE_FAIL) - return; - gen_pool_free(carveout_heap->pool, addr, size); -} - -static int ion_carveout_heap_phys(struct ion_heap *heap, - struct ion_buffer *buffer, - ion_phys_addr_t *addr, size_t *len) -{ - *addr = buffer->priv_phys; - *len = buffer->size; - return 0; -} - -static int ion_carveout_heap_allocate(struct ion_heap *heap, - struct ion_buffer *buffer, - unsigned long size, unsigned long align, - unsigned long flags) -{ - buffer->priv_phys = ion_carveout_allocate(heap, size, align); - return buffer->priv_phys == ION_CARVEOUT_ALLOCATE_FAIL ? -ENOMEM : 0; -} - -static void ion_carveout_heap_free(struct ion_buffer *buffer) -{ - struct ion_heap *heap = buffer->heap; - - ion_carveout_free(heap, buffer->priv_phys, buffer->size); - buffer->priv_phys = ION_CARVEOUT_ALLOCATE_FAIL; -} - -struct scatterlist *ion_carveout_heap_map_dma(struct ion_heap *heap, - struct ion_buffer *buffer) -{ - return ERR_PTR(-EINVAL); -} - -void ion_carveout_heap_unmap_dma(struct ion_heap *heap, - struct ion_buffer *buffer) -{ - return; -} - -void *ion_carveout_heap_map_kernel(struct ion_heap *heap, - struct ion_buffer *buffer) -{ - return __arch_ioremap(buffer->priv_phys, buffer->size, - MT_MEMORY_NONCACHED); -} - -void ion_carveout_heap_unmap_kernel(struct ion_heap *heap, - struct ion_buffer *buffer) -{ - __arch_iounmap(buffer->vaddr); - buffer->vaddr = NULL; - return; -} - -int ion_carveout_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, - struct vm_area_struct *vma) -{ - return remap_pfn_range(vma, vma->vm_start, - __phys_to_pfn(buffer->priv_phys) + vma->vm_pgoff, - buffer->size, - pgprot_noncached(vma->vm_page_prot)); -} - -static struct ion_heap_ops carveout_heap_ops = { - .allocate = ion_carveout_heap_allocate, - .free = ion_carveout_heap_free, - .phys = ion_carveout_heap_phys, - .map_user = ion_carveout_heap_map_user, - .map_kernel = ion_carveout_heap_map_kernel, - .unmap_kernel = ion_carveout_heap_unmap_kernel, -}; - -struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data) -{ - struct ion_carveout_heap *carveout_heap; - - carveout_heap = kzalloc(sizeof(struct ion_carveout_heap), GFP_KERNEL); - if (!carveout_heap) - return ERR_PTR(-ENOMEM); - - carveout_heap->pool = gen_pool_create(12, -1); - if (!carveout_heap->pool) { - kfree(carveout_heap); - return ERR_PTR(-ENOMEM); - } - carveout_heap->base = heap_data->base; - gen_pool_add(carveout_heap->pool, carveout_heap->base, heap_data->size, - -1); - carveout_heap->heap.ops = &carveout_heap_ops; - carveout_heap->heap.type = ION_HEAP_TYPE_CARVEOUT; - - return &carveout_heap->heap; -} - -void ion_carveout_heap_destroy(struct ion_heap *heap) -{ - struct ion_carveout_heap *carveout_heap = - container_of(heap, struct ion_carveout_heap, heap); - - gen_pool_destroy(carveout_heap->pool); - kfree(carveout_heap); - carveout_heap = NULL; -} diff --git a/drivers/gpu/ion/ion_heap.c b/drivers/gpu/ion/ion_heap.c deleted file mode 100644 index 8ce3c1907bad..000000000000 --- a/drivers/gpu/ion/ion_heap.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * drivers/gpu/ion/ion_heap.c - * - * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include "ion_priv.h" - -struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data) -{ - struct ion_heap *heap = NULL; - - switch (heap_data->type) { - case ION_HEAP_TYPE_SYSTEM_CONTIG: - heap = ion_system_contig_heap_create(heap_data); - break; - case ION_HEAP_TYPE_SYSTEM: - heap = ion_system_heap_create(heap_data); - break; - case ION_HEAP_TYPE_CARVEOUT: - heap = ion_carveout_heap_create(heap_data); - break; - default: - pr_err("%s: Invalid heap type %d\n", __func__, - heap_data->type); - return ERR_PTR(-EINVAL); - } - - if (IS_ERR_OR_NULL(heap)) { - pr_err("%s: error creating heap %s type %d base %lu size %u\n", - __func__, heap_data->name, heap_data->type, - heap_data->base, heap_data->size); - return ERR_PTR(-EINVAL); - } - - heap->name = heap_data->name; - heap->id = heap_data->id; - return heap; -} - -void ion_heap_destroy(struct ion_heap *heap) -{ - if (!heap) - return; - - switch (heap->type) { - case ION_HEAP_TYPE_SYSTEM_CONTIG: - ion_system_contig_heap_destroy(heap); - break; - case ION_HEAP_TYPE_SYSTEM: - ion_system_heap_destroy(heap); - break; - case ION_HEAP_TYPE_CARVEOUT: - ion_carveout_heap_destroy(heap); - break; - default: - pr_err("%s: Invalid heap type %d\n", __func__, - heap->type); - } -} diff --git a/drivers/gpu/ion/ion_priv.h b/drivers/gpu/ion/ion_priv.h deleted file mode 100644 index 3323954c03a0..000000000000 --- a/drivers/gpu/ion/ion_priv.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - * drivers/gpu/ion/ion_priv.h - * - * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _ION_PRIV_H -#define _ION_PRIV_H - -#include -#include -#include -#include -#include - -struct ion_mapping; - -struct ion_dma_mapping { - struct kref ref; - struct scatterlist *sglist; -}; - -struct ion_kernel_mapping { - struct kref ref; - void *vaddr; -}; - -struct ion_buffer *ion_handle_buffer(struct ion_handle *handle); - -/** - * struct ion_buffer - metadata for a particular buffer - * @ref: refernce count - * @node: node in the ion_device buffers tree - * @dev: back pointer to the ion_device - * @heap: back pointer to the heap the buffer came from - * @flags: buffer specific flags - * @size: size of the buffer - * @priv_virt: private data to the buffer representable as - * a void * - * @priv_phys: private data to the buffer representable as - * an ion_phys_addr_t (and someday a phys_addr_t) - * @lock: protects the buffers cnt fields - * @kmap_cnt: number of times the buffer is mapped to the kernel - * @vaddr: the kenrel mapping if kmap_cnt is not zero - * @dmap_cnt: number of times the buffer is mapped for dma - * @sglist: the scatterlist for the buffer is dmap_cnt is not zero -*/ -struct ion_buffer { - struct kref ref; - struct rb_node node; - struct ion_device *dev; - struct ion_heap *heap; - unsigned long flags; - size_t size; - union { - void *priv_virt; - ion_phys_addr_t priv_phys; - }; - struct mutex lock; - int kmap_cnt; - void *vaddr; - int dmap_cnt; - struct scatterlist *sglist; -}; - -/** - * struct ion_heap_ops - ops to operate on a given heap - * @allocate: allocate memory - * @free: free memory - * @phys get physical address of a buffer (only define on - * physically contiguous heaps) - * @map_dma map the memory for dma to a scatterlist - * @unmap_dma unmap the memory for dma - * @map_kernel map memory to the kernel - * @unmap_kernel unmap memory to the kernel - * @map_user map memory to userspace - */ -struct ion_heap_ops { - int (*allocate) (struct ion_heap *heap, - struct ion_buffer *buffer, unsigned long len, - unsigned long align, unsigned long flags); - void (*free) (struct ion_buffer *buffer); - int (*phys) (struct ion_heap *heap, struct ion_buffer *buffer, - ion_phys_addr_t *addr, size_t *len); - struct scatterlist *(*map_dma) (struct ion_heap *heap, - struct ion_buffer *buffer); - void (*unmap_dma) (struct ion_heap *heap, struct ion_buffer *buffer); - void * (*map_kernel) (struct ion_heap *heap, struct ion_buffer *buffer); - void (*unmap_kernel) (struct ion_heap *heap, struct ion_buffer *buffer); - int (*map_user) (struct ion_heap *mapper, struct ion_buffer *buffer, - struct vm_area_struct *vma); -}; - -/** - * struct ion_heap - represents a heap in the system - * @node: rb node to put the heap on the device's tree of heaps - * @dev: back pointer to the ion_device - * @type: type of heap - * @ops: ops struct as above - * @id: id of heap, also indicates priority of this heap when - * allocating. These are specified by platform data and - * MUST be unique - * @name: used for debugging - * - * Represents a pool of memory from which buffers can be made. In some - * systems the only heap is regular system memory allocated via vmalloc. - * On others, some blocks might require large physically contiguous buffers - * that are allocated from a specially reserved heap. - */ -struct ion_heap { - struct rb_node node; - struct ion_device *dev; - enum ion_heap_type type; - struct ion_heap_ops *ops; - int id; - const char *name; -}; - -/** - * ion_device_create - allocates and returns an ion device - * @custom_ioctl: arch specific ioctl function if applicable - * - * returns a valid device or -PTR_ERR - */ -struct ion_device *ion_device_create(long (*custom_ioctl) - (struct ion_client *client, - unsigned int cmd, - unsigned long arg)); - -/** - * ion_device_destroy - free and device and it's resource - * @dev: the device - */ -void ion_device_destroy(struct ion_device *dev); - -/** - * ion_device_add_heap - adds a heap to the ion device - * @dev: the device - * @heap: the heap to add - */ -void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap); - -/** - * functions for creating and destroying the built in ion heaps. - * architectures can add their own custom architecture specific - * heaps as appropriate. - */ - -struct ion_heap *ion_heap_create(struct ion_platform_heap *); -void ion_heap_destroy(struct ion_heap *); - -struct ion_heap *ion_system_heap_create(struct ion_platform_heap *); -void ion_system_heap_destroy(struct ion_heap *); - -struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *); -void ion_system_contig_heap_destroy(struct ion_heap *); - -struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *); -void ion_carveout_heap_destroy(struct ion_heap *); -/** - * kernel api to allocate/free from carveout -- used when carveout is - * used to back an architecture specific custom heap - */ -ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap, unsigned long size, - unsigned long align); -void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr, - unsigned long size); -/** - * The carveout heap returns physical addresses, since 0 may be a valid - * physical address, this is used to indicate allocation failed - */ -#define ION_CARVEOUT_ALLOCATE_FAIL -1 - -#endif /* _ION_PRIV_H */ diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c deleted file mode 100644 index c046cf1a3219..000000000000 --- a/drivers/gpu/ion/ion_system_heap.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * drivers/gpu/ion/ion_system_heap.c - * - * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include "ion_priv.h" - -static int ion_system_heap_allocate(struct ion_heap *heap, - struct ion_buffer *buffer, - unsigned long size, unsigned long align, - unsigned long flags) -{ - buffer->priv_virt = vmalloc_user(size); - if (!buffer->priv_virt) - return -ENOMEM; - return 0; -} - -void ion_system_heap_free(struct ion_buffer *buffer) -{ - vfree(buffer->priv_virt); -} - -struct scatterlist *ion_system_heap_map_dma(struct ion_heap *heap, - struct ion_buffer *buffer) -{ - struct scatterlist *sglist; - struct page *page; - int i; - int npages = PAGE_ALIGN(buffer->size) / PAGE_SIZE; - void *vaddr = buffer->priv_virt; - - sglist = vmalloc(npages * sizeof(struct scatterlist)); - if (!sglist) - return ERR_PTR(-ENOMEM); - memset(sglist, 0, npages * sizeof(struct scatterlist)); - sg_init_table(sglist, npages); - for (i = 0; i < npages; i++) { - page = vmalloc_to_page(vaddr); - if (!page) - goto end; - sg_set_page(&sglist[i], page, PAGE_SIZE, 0); - vaddr += PAGE_SIZE; - } - /* XXX do cache maintenance for dma? */ - return sglist; -end: - vfree(sglist); - return NULL; -} - -void ion_system_heap_unmap_dma(struct ion_heap *heap, - struct ion_buffer *buffer) -{ - /* XXX undo cache maintenance for dma? */ - if (buffer->sglist) - vfree(buffer->sglist); -} - -void *ion_system_heap_map_kernel(struct ion_heap *heap, - struct ion_buffer *buffer) -{ - return buffer->priv_virt; -} - -void ion_system_heap_unmap_kernel(struct ion_heap *heap, - struct ion_buffer *buffer) -{ -} - -int ion_system_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, - struct vm_area_struct *vma) -{ - return remap_vmalloc_range(vma, buffer->priv_virt, vma->vm_pgoff); -} - -static struct ion_heap_ops vmalloc_ops = { - .allocate = ion_system_heap_allocate, - .free = ion_system_heap_free, - .map_dma = ion_system_heap_map_dma, - .unmap_dma = ion_system_heap_unmap_dma, - .map_kernel = ion_system_heap_map_kernel, - .unmap_kernel = ion_system_heap_unmap_kernel, - .map_user = ion_system_heap_map_user, -}; - -struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused) -{ - struct ion_heap *heap; - - heap = kzalloc(sizeof(struct ion_heap), GFP_KERNEL); - if (!heap) - return ERR_PTR(-ENOMEM); - heap->ops = &vmalloc_ops; - heap->type = ION_HEAP_TYPE_SYSTEM; - return heap; -} - -void ion_system_heap_destroy(struct ion_heap *heap) -{ - kfree(heap); -} - -static int ion_system_contig_heap_allocate(struct ion_heap *heap, - struct ion_buffer *buffer, - unsigned long len, - unsigned long align, - unsigned long flags) -{ - buffer->priv_virt = kzalloc(len, GFP_KERNEL); - if (!buffer->priv_virt) - return -ENOMEM; - return 0; -} - -void ion_system_contig_heap_free(struct ion_buffer *buffer) -{ - kfree(buffer->priv_virt); -} - -static int ion_system_contig_heap_phys(struct ion_heap *heap, - struct ion_buffer *buffer, - ion_phys_addr_t *addr, size_t *len) -{ - *addr = virt_to_phys(buffer->priv_virt); - *len = buffer->size; - return 0; -} - -struct scatterlist *ion_system_contig_heap_map_dma(struct ion_heap *heap, - struct ion_buffer *buffer) -{ - struct scatterlist *sglist; - - sglist = vmalloc(sizeof(struct scatterlist)); - if (!sglist) - return ERR_PTR(-ENOMEM); - sg_init_table(sglist, 1); - sg_set_page(sglist, virt_to_page(buffer->priv_virt), buffer->size, 0); - return sglist; -} - -int ion_system_contig_heap_map_user(struct ion_heap *heap, - struct ion_buffer *buffer, - struct vm_area_struct *vma) -{ - unsigned long pfn = __phys_to_pfn(virt_to_phys(buffer->priv_virt)); - return remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff, - vma->vm_end - vma->vm_start, - vma->vm_page_prot); - -} - -static struct ion_heap_ops kmalloc_ops = { - .allocate = ion_system_contig_heap_allocate, - .free = ion_system_contig_heap_free, - .phys = ion_system_contig_heap_phys, - .map_dma = ion_system_contig_heap_map_dma, - .unmap_dma = ion_system_heap_unmap_dma, - .map_kernel = ion_system_heap_map_kernel, - .unmap_kernel = ion_system_heap_unmap_kernel, - .map_user = ion_system_contig_heap_map_user, -}; - -struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *unused) -{ - struct ion_heap *heap; - - heap = kzalloc(sizeof(struct ion_heap), GFP_KERNEL); - if (!heap) - return ERR_PTR(-ENOMEM); - heap->ops = &kmalloc_ops; - heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG; - return heap; -} - -void ion_system_contig_heap_destroy(struct ion_heap *heap) -{ - kfree(heap); -} - diff --git a/drivers/gpu/ion/ion_system_mapper.c b/drivers/gpu/ion/ion_system_mapper.c deleted file mode 100644 index 692458e07b5e..000000000000 --- a/drivers/gpu/ion/ion_system_mapper.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * drivers/gpu/ion/ion_system_mapper.c - * - * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include "ion_priv.h" -/* - * This mapper is valid for any heap that allocates memory that already has - * a kernel mapping, this includes vmalloc'd memory, kmalloc'd memory, - * pages obtained via io_remap, etc. - */ -static void *ion_kernel_mapper_map(struct ion_mapper *mapper, - struct ion_buffer *buffer, - struct ion_mapping **mapping) -{ - if (!((1 << buffer->heap->type) & mapper->heap_mask)) { - pr_err("%s: attempting to map an unsupported heap\n", __func__); - return ERR_PTR(-EINVAL); - } - /* XXX REVISIT ME!!! */ - *((unsigned long *)mapping) = (unsigned long)buffer->priv; - return buffer->priv; -} - -static void ion_kernel_mapper_unmap(struct ion_mapper *mapper, - struct ion_buffer *buffer, - struct ion_mapping *mapping) -{ - if (!((1 << buffer->heap->type) & mapper->heap_mask)) - pr_err("%s: attempting to unmap an unsupported heap\n", - __func__); -} - -static void *ion_kernel_mapper_map_kernel(struct ion_mapper *mapper, - struct ion_buffer *buffer, - struct ion_mapping *mapping) -{ - if (!((1 << buffer->heap->type) & mapper->heap_mask)) { - pr_err("%s: attempting to unmap an unsupported heap\n", - __func__); - return ERR_PTR(-EINVAL); - } - return buffer->priv; -} - -static int ion_kernel_mapper_map_user(struct ion_mapper *mapper, - struct ion_buffer *buffer, - struct vm_area_struct *vma, - struct ion_mapping *mapping) -{ - int ret; - - switch (buffer->heap->type) { - case ION_HEAP_KMALLOC: - { - unsigned long pfn = __phys_to_pfn(virt_to_phys(buffer->priv)); - ret = remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff, - vma->vm_end - vma->vm_start, - vma->vm_page_prot); - break; - } - case ION_HEAP_VMALLOC: - ret = remap_vmalloc_range(vma, buffer->priv, vma->vm_pgoff); - break; - default: - pr_err("%s: attempting to map unsupported heap to userspace\n", - __func__); - return -EINVAL; - } - - return ret; -} - -static struct ion_mapper_ops ops = { - .map = ion_kernel_mapper_map, - .map_kernel = ion_kernel_mapper_map_kernel, - .map_user = ion_kernel_mapper_map_user, - .unmap = ion_kernel_mapper_unmap, -}; - -struct ion_mapper *ion_system_mapper_create(void) -{ - struct ion_mapper *mapper; - mapper = kzalloc(sizeof(struct ion_mapper), GFP_KERNEL); - if (!mapper) - return ERR_PTR(-ENOMEM); - mapper->type = ION_SYSTEM_MAPPER; - mapper->ops = &ops; - mapper->heap_mask = (1 << ION_HEAP_VMALLOC) | (1 << ION_HEAP_KMALLOC); - return mapper; -} - -void ion_system_mapper_destroy(struct ion_mapper *mapper) -{ - kfree(mapper); -} - diff --git a/drivers/gpu/ion/tegra/Makefile b/drivers/gpu/ion/tegra/Makefile deleted file mode 100644 index 11cd003fb08f..000000000000 --- a/drivers/gpu/ion/tegra/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-y += tegra_ion.o diff --git a/drivers/gpu/ion/tegra/tegra_ion.c b/drivers/gpu/ion/tegra/tegra_ion.c deleted file mode 100644 index 7af6e168ff4c..000000000000 --- a/drivers/gpu/ion/tegra/tegra_ion.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * drivers/gpu/tegra/tegra_ion.c - * - * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include "../ion_priv.h" - -struct ion_device *idev; -struct ion_mapper *tegra_user_mapper; -int num_heaps; -struct ion_heap **heaps; - -int tegra_ion_probe(struct platform_device *pdev) -{ - struct ion_platform_data *pdata = pdev->dev.platform_data; - int err; - int i; - - num_heaps = pdata->nr; - - heaps = kzalloc(sizeof(struct ion_heap *) * pdata->nr, GFP_KERNEL); - - idev = ion_device_create(NULL); - if (IS_ERR_OR_NULL(idev)) { - kfree(heaps); - return PTR_ERR(idev); - } - - /* create the heaps as specified in the board file */ - for (i = 0; i < num_heaps; i++) { - struct ion_platform_heap *heap_data = &pdata->heaps[i]; - - heaps[i] = ion_heap_create(heap_data); - if (IS_ERR_OR_NULL(heaps[i])) { - err = PTR_ERR(heaps[i]); - goto err; - } - ion_device_add_heap(idev, heaps[i]); - } - platform_set_drvdata(pdev, idev); - return 0; -err: - for (i = 0; i < num_heaps; i++) { - if (heaps[i]) - ion_heap_destroy(heaps[i]); - } - kfree(heaps); - return err; -} - -int tegra_ion_remove(struct platform_device *pdev) -{ - struct ion_device *idev = platform_get_drvdata(pdev); - int i; - - ion_device_destroy(idev); - for (i = 0; i < num_heaps; i++) - ion_heap_destroy(heaps[i]); - kfree(heaps); - return 0; -} - -static struct platform_driver ion_driver = { - .probe = tegra_ion_probe, - .remove = tegra_ion_remove, - .driver = { .name = "ion-tegra" } -}; - -static int __init ion_init(void) -{ - return platform_driver_register(&ion_driver); -} - -static void __exit ion_exit(void) -{ - platform_driver_unregister(&ion_driver); -} - -module_init(ion_init); -module_exit(ion_exit); - diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index c5fd7f7dd310..36ca465c00ce 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -50,27 +50,6 @@ config HIDRAW If unsure, say Y. -config UHID - tristate "User-space I/O driver support for HID subsystem" - depends on HID - default n - ---help--- - Say Y here if you want to provide HID I/O Drivers from user-space. - This allows to write I/O drivers in user-space and feed the data from - the device into the kernel. The kernel parses the HID reports, loads the - corresponding HID Device Driver or provides input devices on top of your - user-space device. - - This driver cannot be used to parse HID-reports in user-space and write - special HID-drivers. You should use hidraw for that. - Instead, this driver allows to write the transport-layer driver in - user-space like USB-HID and Bluetooth-HID do in kernel-space. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called uhid. - source "drivers/hid/usbhid/Kconfig" menu "Special HID drivers" @@ -90,7 +69,7 @@ config HID_ACRUX Say Y here if you want to enable support for ACRUX game controllers. config HID_ACRUX_FF - bool "ACRUX force feedback support" + tristate "ACRUX force feedback support" depends on HID_ACRUX select INPUT_FF_MEMLESS ---help--- @@ -335,7 +314,6 @@ config HID_MULTITOUCH - Hanvon dual touch panels - Ilitek dual touch panels - IrTouch Infrared USB panels - - LG Display panels (Dell ST2220Tc) - Lumio CrystalTouch panels - MosArt dual-touch panels - PenMount dual touch panels diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 5a255e029872..f8cc4ea7335a 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -8,7 +8,6 @@ ifdef CONFIG_DEBUG_FS endif obj-$(CONFIG_HID) += hid.o -obj-$(CONFIG_UHID) += uhid.o hid-$(CONFIG_HIDRAW) += hidraw.o diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 299d23871122..b85744fe8464 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -444,20 +444,11 @@ static const struct hid_device_id apple_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | APPLE_RDESC_JIS }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI), - .driver_data = APPLE_HAS_FN }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO), - .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS), - .driver_data = APPLE_HAS_FN }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | - APPLE_ISO_KEYBOARD }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), @@ -496,24 +487,6 @@ static const struct hid_device_id apple_devices[] = { .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS), .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI), - .driver_data = APPLE_HAS_FN }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO), - .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS), - .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI), - .driver_data = APPLE_HAS_FN }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO), - .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS), - .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI), - .driver_data = APPLE_HAS_FN }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO), - .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS), - .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c index b99af346fdff..8965ad93d510 100644 --- a/drivers/hid/hid-chicony.c +++ b/drivers/hid/hid-chicony.c @@ -45,12 +45,6 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, case 0xff09: ch_map_key_clear(BTN_9); break; case 0xff0a: ch_map_key_clear(BTN_A); break; case 0xff0b: ch_map_key_clear(BTN_B); break; - case 0x00f1: ch_map_key_clear(KEY_WLAN); break; - case 0x00f2: ch_map_key_clear(KEY_BRIGHTNESSDOWN); break; - case 0x00f3: ch_map_key_clear(KEY_BRIGHTNESSUP); break; - case 0x00f4: ch_map_key_clear(KEY_DISPLAY_OFF); break; - case 0x00f7: ch_map_key_clear(KEY_CAMERA); break; - case 0x00f8: ch_map_key_clear(KEY_PROG1); break; default: return 0; } @@ -59,7 +53,6 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, static const struct hid_device_id ch_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, { } }; MODULE_DEVICE_TABLE(hid, ch_devices); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 53576e7c8bcf..6f3289a57888 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -361,7 +361,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: parser->global.report_size = item_udata(item); - if (parser->global.report_size > 96) { + if (parser->global.report_size > 32) { dbg_hid("invalid report_size %d\n", parser->global.report_size); return -1; @@ -1340,22 +1340,9 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, @@ -1372,7 +1359,6 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, { HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, USB_DEVICE_ID_CVTOUCH_SCREEN) }, @@ -1383,13 +1369,11 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) }, - { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) }, - { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) }, - { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) }, - { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) }, - { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) }, - { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) }, - { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2515) }, { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) }, @@ -1411,7 +1395,6 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LG, USB_DEVICE_ID_LG_MULTITOUCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, @@ -1724,8 +1707,8 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) }, { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) }, { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) }, + { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) }, { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0004) }, { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30) }, { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30) }, @@ -1900,9 +1883,6 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, { } diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index 9a243ca96e6d..bae48745bb42 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -450,11 +450,6 @@ void hid_dump_field(struct hid_field *field, int n, struct seq_file *f) { seq_printf(f, "Logical("); hid_resolv_usage(field->logical, f); seq_printf(f, ")\n"); } - if (field->application) { - tab(n, f); - seq_printf(f, "Application("); - hid_resolv_usage(field->application, f); seq_printf(f, ")\n"); - } tab(n, f); seq_printf(f, "Usage(%d)\n", field->maxusage); for (j = 0; j < field->maxusage; j++) { tab(n+2, f); hid_resolv_usage(field->usage[j].hid, f); seq_printf(f, "\n"); diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 08cc68ba9ebe..a756ee6c7df5 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -21,7 +21,6 @@ #define USB_VENDOR_ID_3M 0x0596 #define USB_DEVICE_ID_3M1968 0x0500 #define USB_DEVICE_ID_3M2256 0x0502 -#define USB_DEVICE_ID_3M3266 0x0506 #define USB_VENDOR_ID_A4TECH 0x09da #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 @@ -59,9 +58,6 @@ #define USB_VENDOR_ID_AIRCABLE 0x16CA #define USB_DEVICE_ID_AIRCABLE1 0x1502 -#define USB_VENDOR_ID_AIREN 0x1a2c -#define USB_DEVICE_ID_AIREN_SLIMPLUS 0x0002 - #define USB_VENDOR_ID_ALCOR 0x058f #define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 @@ -113,22 +109,9 @@ #define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI 0x0245 #define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO 0x0246 #define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS 0x0247 -#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI 0x0249 -#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO 0x024a -#define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS 0x024b -#define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI 0x024c -#define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO 0x024d -#define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS 0x024e -#define USB_DEVICE_ID_APPLE_ALU_REVB_ANSI 0x024f -#define USB_DEVICE_ID_APPLE_ALU_REVB_ISO 0x0250 -#define USB_DEVICE_ID_APPLE_ALU_REVB_JIS 0x0251 -#define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI 0x0252 -#define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO 0x0253 -#define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS 0x0254 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b -#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO 0x0256 #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b #define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241 @@ -189,7 +172,6 @@ #define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 #define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d #define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618 -#define USB_DEVICE_ID_CHICONY_WIRELESS2 0x1123 #define USB_VENDOR_ID_CHUNGHWAT 0x2247 #define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001 @@ -235,14 +217,11 @@ #define USB_VENDOR_ID_DWAV 0x0eef #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 -#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D 0x480d -#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E 0x480e -#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C 0x720c -#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B 0x726b -#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1 0x72a1 -#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA 0x72fa -#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302 0x7302 -#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001 +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1 0x720c +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2 0x72a1 +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3 0x480e +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4 0x726b #define USB_VENDOR_ID_ELECOM 0x056e #define USB_DEVICE_ID_ELECOM_BM084 0x0061 @@ -274,7 +253,7 @@ #define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002 #define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc -#define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0003 +#define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0001 #define USB_VENDOR_ID_GLAB 0x06c2 #define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 @@ -295,7 +274,6 @@ #define USB_DEVICE_ID_PENPOWER 0x00f4 #define USB_VENDOR_ID_GREENASIA 0x0e8f -#define USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD 0x3013 #define USB_VENDOR_ID_GRETAGMACBETH 0x0971 #define USB_DEVICE_ID_GRETAGMACBETH_HUEY 0x2005 @@ -438,9 +416,6 @@ #define USB_DEVICE_ID_LD_HYBRID 0x2090 #define USB_DEVICE_ID_LD_HEATCONTROL 0x20A0 -#define USB_VENDOR_ID_LG 0x1fd2 -#define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 - #define USB_VENDOR_ID_LOGITECH 0x046d #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 @@ -593,9 +568,6 @@ #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 #define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600 -#define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f -#define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002 - #define USB_VENDOR_ID_SKYCABLE 0x1223 #define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07 diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 1483c8296d57..6559e2e3364e 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -971,9 +971,6 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) * UGCI) cram a lot of unrelated inputs into the * same interface. */ hidinput->report = report; - if (hid->driver->input_register && - hid->driver->input_register(hid, hidinput)) - goto out_cleanup; if (input_register_device(hidinput->input)) goto out_cleanup; hidinput = NULL; @@ -981,10 +978,6 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) } } - if (hidinput && hid->driver->input_register && - hid->driver->input_register(hid, hidinput)) - goto out_cleanup; - if (hidinput && input_register_device(hidinput->input)) goto out_cleanup; diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index c696f7f20e47..0ec91c18a421 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -365,10 +365,8 @@ static int magicmouse_raw_event(struct hid_device *hdev, return 1; } -static int magicmouse_setup_input(struct hid_device *hdev, struct hid_input *hi) +static void magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev) { - struct input_dev *input = hi->input; - __set_bit(EV_KEY, input->evbit); if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { @@ -428,8 +426,6 @@ static int magicmouse_setup_input(struct hid_device *hdev, struct hid_input *hi) __set_bit(EV_MSC, input->evbit); __set_bit(MSC_RAW, input->mscbit); } - - return 0; } static int magicmouse_input_mapping(struct hid_device *hdev, @@ -482,6 +478,12 @@ static int magicmouse_probe(struct hid_device *hdev, goto err_free; } + /* We do this after hid-input is done parsing reports so that + * hid-input uses the most natural button and axis IDs. + */ + if (msc->input) + magicmouse_setup_input(msc->input, hdev); + if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) report = hid_register_report(hdev, HID_INPUT_REPORT, MOUSE_REPORT_ID); @@ -499,17 +501,9 @@ static int magicmouse_probe(struct hid_device *hdev, } report->size = 6; - /* - * Some devices repond with 'invalid report id' when feature - * report switching it into multitouch mode is sent to it. - * - * This results in -EIO from the _raw low-level transport callback, - * but there seems to be no other way of switching the mode. - * Thus the super-ugly hacky success check below. - */ ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature), HID_FEATURE_REPORT); - if (ret != -EIO && ret != sizeof(feature)) { + if (ret != sizeof(feature)) { hid_err(hdev, "unable to request touch data (%d)\n", ret); goto err_stop_hw; } @@ -546,7 +540,6 @@ static struct hid_driver magicmouse_driver = { .remove = magicmouse_remove, .raw_event = magicmouse_raw_event, .input_mapping = magicmouse_input_mapping, - .input_register = magicmouse_setup_input, }; static int __init magicmouse_init(void) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 91319f90a168..62cac4dc3b62 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -213,16 +213,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, struct mt_class *cls = td->mtclass; __s32 quirks = cls->quirks; - /* Only map fields from TouchScreen or TouchPad collections. - * We need to ignore fields that belong to other collections - * such as Mouse that might have the same GenericDesktop usages. */ - if (field->application == HID_DG_TOUCHSCREEN) - set_bit(INPUT_PROP_DIRECT, hi->input->propbit); - else if (field->application == HID_DG_TOUCHPAD) - set_bit(INPUT_PROP_POINTER, hi->input->propbit); - else - return 0; - switch (usage->hid & HID_USAGE_PAGE) { case HID_UP_GENDESK: @@ -603,9 +593,6 @@ static const struct hid_device_id mt_devices[] = { { .driver_data = MT_CLS_3M, HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) }, - { .driver_data = MT_CLS_3M, - HID_USB_DEVICE(USB_VENDOR_ID_3M, - USB_DEVICE_ID_3M3266) }, /* ActionStar panels */ { .driver_data = MT_CLS_DEFAULT, @@ -642,32 +629,23 @@ static const struct hid_device_id mt_devices[] = { USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, /* eGalax devices (resistive) */ - { .driver_data = MT_CLS_EGALAX, + { .driver_data = MT_CLS_EGALAX, HID_USB_DEVICE(USB_VENDOR_ID_DWAV, - USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) }, - { .driver_data = MT_CLS_EGALAX, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, + { .driver_data = MT_CLS_EGALAX, HID_USB_DEVICE(USB_VENDOR_ID_DWAV, - USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) }, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) }, /* eGalax devices (capacitive) */ - { .driver_data = MT_CLS_EGALAX, + { .driver_data = MT_CLS_EGALAX, HID_USB_DEVICE(USB_VENDOR_ID_DWAV, - USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) }, - { .driver_data = MT_CLS_EGALAX, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, + { .driver_data = MT_CLS_EGALAX, HID_USB_DEVICE(USB_VENDOR_ID_DWAV, - USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) }, - { .driver_data = MT_CLS_EGALAX, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) }, + { .driver_data = MT_CLS_EGALAX, HID_USB_DEVICE(USB_VENDOR_ID_DWAV, - USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) }, - { .driver_data = MT_CLS_EGALAX, - HID_USB_DEVICE(USB_VENDOR_ID_DWAV, - USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA) }, - { .driver_data = MT_CLS_EGALAX, - HID_USB_DEVICE(USB_VENDOR_ID_DWAV, - USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) }, - { .driver_data = MT_CLS_EGALAX, - HID_USB_DEVICE(USB_VENDOR_ID_DWAV, - USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, /* Elo TouchSystems IntelliTouch Plus panel */ { .driver_data = MT_CLS_DUAL_NSMU_CONTACTID, @@ -694,11 +672,6 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, - /* LG Display panels */ - { .driver_data = MT_CLS_DEFAULT, - HID_USB_DEVICE(USB_VENDOR_ID_LG, - USB_DEVICE_ID_LG_MULTITOUCH) }, - /* Lumio panels */ { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c deleted file mode 100644 index 714cd8cc9579..000000000000 --- a/drivers/hid/uhid.c +++ /dev/null @@ -1,572 +0,0 @@ -/* - * User-space I/O driver support for HID subsystem - * Copyright (c) 2012 David Herrmann - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define UHID_NAME "uhid" -#define UHID_BUFSIZE 32 - -struct uhid_device { - struct mutex devlock; - bool running; - - __u8 *rd_data; - uint rd_size; - - struct hid_device *hid; - struct uhid_event input_buf; - - wait_queue_head_t waitq; - spinlock_t qlock; - __u8 head; - __u8 tail; - struct uhid_event *outq[UHID_BUFSIZE]; - - struct mutex report_lock; - wait_queue_head_t report_wait; - atomic_t report_done; - atomic_t report_id; - struct uhid_event report_buf; -}; - -static struct miscdevice uhid_misc; - -static void uhid_queue(struct uhid_device *uhid, struct uhid_event *ev) -{ - __u8 newhead; - - newhead = (uhid->head + 1) % UHID_BUFSIZE; - - if (newhead != uhid->tail) { - uhid->outq[uhid->head] = ev; - uhid->head = newhead; - wake_up_interruptible(&uhid->waitq); - } else { - hid_warn(uhid->hid, "Output queue is full\n"); - kfree(ev); - } -} - -static int uhid_queue_event(struct uhid_device *uhid, __u32 event) -{ - unsigned long flags; - struct uhid_event *ev; - - ev = kzalloc(sizeof(*ev), GFP_KERNEL); - if (!ev) - return -ENOMEM; - - ev->type = event; - - spin_lock_irqsave(&uhid->qlock, flags); - uhid_queue(uhid, ev); - spin_unlock_irqrestore(&uhid->qlock, flags); - - return 0; -} - -static int uhid_hid_start(struct hid_device *hid) -{ - struct uhid_device *uhid = hid->driver_data; - - return uhid_queue_event(uhid, UHID_START); -} - -static void uhid_hid_stop(struct hid_device *hid) -{ - struct uhid_device *uhid = hid->driver_data; - - hid->claimed = 0; - uhid_queue_event(uhid, UHID_STOP); -} - -static int uhid_hid_open(struct hid_device *hid) -{ - struct uhid_device *uhid = hid->driver_data; - - return uhid_queue_event(uhid, UHID_OPEN); -} - -static void uhid_hid_close(struct hid_device *hid) -{ - struct uhid_device *uhid = hid->driver_data; - - uhid_queue_event(uhid, UHID_CLOSE); -} - -static int uhid_hid_input(struct input_dev *input, unsigned int type, - unsigned int code, int value) -{ - struct hid_device *hid = input_get_drvdata(input); - struct uhid_device *uhid = hid->driver_data; - unsigned long flags; - struct uhid_event *ev; - - ev = kzalloc(sizeof(*ev), GFP_ATOMIC); - if (!ev) - return -ENOMEM; - - ev->type = UHID_OUTPUT_EV; - ev->u.output_ev.type = type; - ev->u.output_ev.code = code; - ev->u.output_ev.value = value; - - spin_lock_irqsave(&uhid->qlock, flags); - uhid_queue(uhid, ev); - spin_unlock_irqrestore(&uhid->qlock, flags); - - return 0; -} - -static int uhid_hid_parse(struct hid_device *hid) -{ - struct uhid_device *uhid = hid->driver_data; - - return hid_parse_report(hid, uhid->rd_data, uhid->rd_size); -} - -static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum, - __u8 *buf, size_t count, unsigned char rtype) -{ - struct uhid_device *uhid = hid->driver_data; - __u8 report_type; - struct uhid_event *ev; - unsigned long flags; - int ret; - size_t uninitialized_var(len); - struct uhid_feature_answer_req *req; - - if (!uhid->running) - return -EIO; - - switch (rtype) { - case HID_FEATURE_REPORT: - report_type = UHID_FEATURE_REPORT; - break; - case HID_OUTPUT_REPORT: - report_type = UHID_OUTPUT_REPORT; - break; - case HID_INPUT_REPORT: - report_type = UHID_INPUT_REPORT; - break; - default: - return -EINVAL; - } - - ret = mutex_lock_interruptible(&uhid->report_lock); - if (ret) - return ret; - - ev = kzalloc(sizeof(*ev), GFP_KERNEL); - if (!ev) { - ret = -ENOMEM; - goto unlock; - } - - spin_lock_irqsave(&uhid->qlock, flags); - ev->type = UHID_FEATURE; - ev->u.feature.id = atomic_inc_return(&uhid->report_id); - ev->u.feature.rnum = rnum; - ev->u.feature.rtype = report_type; - - atomic_set(&uhid->report_done, 0); - uhid_queue(uhid, ev); - spin_unlock_irqrestore(&uhid->qlock, flags); - - ret = wait_event_interruptible_timeout(uhid->report_wait, - atomic_read(&uhid->report_done), 5 * HZ); - - /* - * Make sure "uhid->running" is cleared on shutdown before - * "uhid->report_done" is set. - */ - smp_rmb(); - if (!ret || !uhid->running) { - ret = -EIO; - } else if (ret < 0) { - ret = -ERESTARTSYS; - } else { - spin_lock_irqsave(&uhid->qlock, flags); - req = &uhid->report_buf.u.feature_answer; - - if (req->err) { - ret = -EIO; - } else { - ret = 0; - len = min(count, - min_t(size_t, req->size, UHID_DATA_MAX)); - memcpy(buf, req->data, len); - } - - spin_unlock_irqrestore(&uhid->qlock, flags); - } - - atomic_set(&uhid->report_done, 1); - -unlock: - mutex_unlock(&uhid->report_lock); - return ret ? ret : len; -} - -static int uhid_hid_output_raw(struct hid_device *hid, __u8 *buf, size_t count, - unsigned char report_type) -{ - struct uhid_device *uhid = hid->driver_data; - __u8 rtype; - unsigned long flags; - struct uhid_event *ev; - - switch (report_type) { - case HID_FEATURE_REPORT: - rtype = UHID_FEATURE_REPORT; - break; - case HID_OUTPUT_REPORT: - rtype = UHID_OUTPUT_REPORT; - break; - default: - return -EINVAL; - } - - if (count < 1 || count > UHID_DATA_MAX) - return -EINVAL; - - ev = kzalloc(sizeof(*ev), GFP_KERNEL); - if (!ev) - return -ENOMEM; - - ev->type = UHID_OUTPUT; - ev->u.output.size = count; - ev->u.output.rtype = rtype; - memcpy(ev->u.output.data, buf, count); - - spin_lock_irqsave(&uhid->qlock, flags); - uhid_queue(uhid, ev); - spin_unlock_irqrestore(&uhid->qlock, flags); - - return count; -} - -static struct hid_ll_driver uhid_hid_driver = { - .start = uhid_hid_start, - .stop = uhid_hid_stop, - .open = uhid_hid_open, - .close = uhid_hid_close, - .hidinput_input_event = uhid_hid_input, - .parse = uhid_hid_parse, -}; - -static int uhid_dev_create(struct uhid_device *uhid, - const struct uhid_event *ev) -{ - struct hid_device *hid; - int ret; - - if (uhid->running) - return -EALREADY; - - uhid->rd_size = ev->u.create.rd_size; - if (uhid->rd_size <= 0 || uhid->rd_size > HID_MAX_DESCRIPTOR_SIZE) - return -EINVAL; - - uhid->rd_data = kmalloc(uhid->rd_size, GFP_KERNEL); - if (!uhid->rd_data) - return -ENOMEM; - - if (copy_from_user(uhid->rd_data, ev->u.create.rd_data, - uhid->rd_size)) { - ret = -EFAULT; - goto err_free; - } - - hid = hid_allocate_device(); - if (IS_ERR(hid)) { - ret = PTR_ERR(hid); - goto err_free; - } - - strncpy(hid->name, ev->u.create.name, 127); - hid->name[127] = 0; - strncpy(hid->phys, ev->u.create.phys, 63); - hid->phys[63] = 0; - strncpy(hid->uniq, ev->u.create.uniq, 63); - hid->uniq[63] = 0; - - hid->ll_driver = &uhid_hid_driver; - hid->hid_get_raw_report = uhid_hid_get_raw; - hid->hid_output_raw_report = uhid_hid_output_raw; - hid->bus = ev->u.create.bus; - hid->vendor = ev->u.create.vendor; - hid->product = ev->u.create.product; - hid->version = ev->u.create.version; - hid->country = ev->u.create.country; - hid->driver_data = uhid; - hid->dev.parent = uhid_misc.this_device; - - uhid->hid = hid; - uhid->running = true; - - ret = hid_add_device(hid); - if (ret) { - hid_err(hid, "Cannot register HID device\n"); - goto err_hid; - } - - return 0; - -err_hid: - hid_destroy_device(hid); - uhid->hid = NULL; - uhid->running = false; -err_free: - kfree(uhid->rd_data); - return ret; -} - -static int uhid_dev_destroy(struct uhid_device *uhid) -{ - if (!uhid->running) - return -EINVAL; - - /* clear "running" before setting "report_done" */ - uhid->running = false; - smp_wmb(); - atomic_set(&uhid->report_done, 1); - wake_up_interruptible(&uhid->report_wait); - - hid_destroy_device(uhid->hid); - kfree(uhid->rd_data); - - return 0; -} - -static int uhid_dev_input(struct uhid_device *uhid, struct uhid_event *ev) -{ - if (!uhid->running) - return -EINVAL; - - hid_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input.data, - min_t(size_t, ev->u.input.size, UHID_DATA_MAX), 0); - - return 0; -} - -static int uhid_dev_feature_answer(struct uhid_device *uhid, - struct uhid_event *ev) -{ - unsigned long flags; - - if (!uhid->running) - return -EINVAL; - - spin_lock_irqsave(&uhid->qlock, flags); - - /* id for old report; drop it silently */ - if (atomic_read(&uhid->report_id) != ev->u.feature_answer.id) - goto unlock; - if (atomic_read(&uhid->report_done)) - goto unlock; - - memcpy(&uhid->report_buf, ev, sizeof(*ev)); - atomic_set(&uhid->report_done, 1); - wake_up_interruptible(&uhid->report_wait); - -unlock: - spin_unlock_irqrestore(&uhid->qlock, flags); - return 0; -} - -static int uhid_char_open(struct inode *inode, struct file *file) -{ - struct uhid_device *uhid; - - uhid = kzalloc(sizeof(*uhid), GFP_KERNEL); - if (!uhid) - return -ENOMEM; - - mutex_init(&uhid->devlock); - mutex_init(&uhid->report_lock); - spin_lock_init(&uhid->qlock); - init_waitqueue_head(&uhid->waitq); - init_waitqueue_head(&uhid->report_wait); - uhid->running = false; - atomic_set(&uhid->report_done, 1); - - file->private_data = uhid; - nonseekable_open(inode, file); - - return 0; -} - -static int uhid_char_release(struct inode *inode, struct file *file) -{ - struct uhid_device *uhid = file->private_data; - unsigned int i; - - uhid_dev_destroy(uhid); - - for (i = 0; i < UHID_BUFSIZE; ++i) - kfree(uhid->outq[i]); - - kfree(uhid); - - return 0; -} - -static ssize_t uhid_char_read(struct file *file, char __user *buffer, - size_t count, loff_t *ppos) -{ - struct uhid_device *uhid = file->private_data; - int ret; - unsigned long flags; - size_t len; - - /* they need at least the "type" member of uhid_event */ - if (count < sizeof(__u32)) - return -EINVAL; - -try_again: - if (file->f_flags & O_NONBLOCK) { - if (uhid->head == uhid->tail) - return -EAGAIN; - } else { - ret = wait_event_interruptible(uhid->waitq, - uhid->head != uhid->tail); - if (ret) - return ret; - } - - ret = mutex_lock_interruptible(&uhid->devlock); - if (ret) - return ret; - - if (uhid->head == uhid->tail) { - mutex_unlock(&uhid->devlock); - goto try_again; - } else { - len = min(count, sizeof(**uhid->outq)); - if (copy_to_user(buffer, uhid->outq[uhid->tail], len)) { - ret = -EFAULT; - } else { - kfree(uhid->outq[uhid->tail]); - uhid->outq[uhid->tail] = NULL; - - spin_lock_irqsave(&uhid->qlock, flags); - uhid->tail = (uhid->tail + 1) % UHID_BUFSIZE; - spin_unlock_irqrestore(&uhid->qlock, flags); - } - } - - mutex_unlock(&uhid->devlock); - return ret ? ret : len; -} - -static ssize_t uhid_char_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) -{ - struct uhid_device *uhid = file->private_data; - int ret; - size_t len; - - /* we need at least the "type" member of uhid_event */ - if (count < sizeof(__u32)) - return -EINVAL; - - ret = mutex_lock_interruptible(&uhid->devlock); - if (ret) - return ret; - - memset(&uhid->input_buf, 0, sizeof(uhid->input_buf)); - len = min(count, sizeof(uhid->input_buf)); - if (copy_from_user(&uhid->input_buf, buffer, len)) { - ret = -EFAULT; - goto unlock; - } - - switch (uhid->input_buf.type) { - case UHID_CREATE: - ret = uhid_dev_create(uhid, &uhid->input_buf); - break; - case UHID_DESTROY: - ret = uhid_dev_destroy(uhid); - break; - case UHID_INPUT: - ret = uhid_dev_input(uhid, &uhid->input_buf); - break; - case UHID_FEATURE_ANSWER: - ret = uhid_dev_feature_answer(uhid, &uhid->input_buf); - break; - default: - ret = -EOPNOTSUPP; - } - -unlock: - mutex_unlock(&uhid->devlock); - - /* return "count" not "len" to not confuse the caller */ - return ret ? ret : count; -} - -static unsigned int uhid_char_poll(struct file *file, poll_table *wait) -{ - struct uhid_device *uhid = file->private_data; - - poll_wait(file, &uhid->waitq, wait); - - if (uhid->head != uhid->tail) - return POLLIN | POLLRDNORM; - - return 0; -} - -static const struct file_operations uhid_fops = { - .owner = THIS_MODULE, - .open = uhid_char_open, - .release = uhid_char_release, - .read = uhid_char_read, - .write = uhid_char_write, - .poll = uhid_char_poll, - .llseek = no_llseek, -}; - -static struct miscdevice uhid_misc = { - .fops = &uhid_fops, - .minor = MISC_DYNAMIC_MINOR, - .name = UHID_NAME, -}; - -static int __init uhid_init(void) -{ - return misc_register(&uhid_misc); -} - -static void __exit uhid_exit(void) -{ - misc_deregister(&uhid_misc); -} - -module_init(uhid_init); -module_exit(uhid_exit); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("David Herrmann "); -MODULE_DESCRIPTION("User-space I/O driver support for HID subsystem"); diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 85c845f7f61e..621959d5cc42 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -47,12 +47,10 @@ static const struct hid_blacklist { { USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL }, { USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH, HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, @@ -91,7 +89,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS }, { 0, 0 } }; diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 6030f2085499..5f888f7e7dcb 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -474,9 +474,8 @@ config SENSORS_JC42 If you say yes here, you get support for JEDEC JC42.4 compliant temperature sensors, which are used on many DDR3 memory modules for mobile devices and servers. Support will include, but not be limited - to, ADT7408, AT30TS00, CAT34TS02, CAT6095, MAX6604, MCP9804, MCP9805, - MCP98242, MCP98243, MCP9843, SE97, SE98, STTS424(E), STTS2002, - STTS3000, TSE2002B3, TSE2002GB2, TS3000B3, and TS3000GB2. + to, ADT7408, CAT34TS02, CAT6095, MAX6604, MCP9805, MCP98242, MCP98243, + MCP9843, SE97, SE98, STTS424(E), TSE2002B3, and TS3000B3. This driver can also be built as a module. If so, the module will be called jc42. diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c index 9a5af38bffd3..e9beeda4cbe5 100644 --- a/drivers/hwmon/ads1015.c +++ b/drivers/hwmon/ads1015.c @@ -284,7 +284,7 @@ static int ads1015_probe(struct i2c_client *client, continue; err = device_create_file(&client->dev, &ads1015_in[k].dev_attr); if (err) - goto exit_remove; + goto exit_free; } data->hwmon_dev = hwmon_device_register(&client->dev); @@ -298,6 +298,7 @@ static int ads1015_probe(struct i2c_client *client, exit_remove: for (k = 0; k < ADS1015_CHANNELS; ++k) device_remove_file(&client->dev, &ads1015_in[k].dev_attr); +exit_free: kfree(data); exit: return err; diff --git a/drivers/hwmon/ads7871.c b/drivers/hwmon/ads7871.c index a5737a54461b..52319340e182 100644 --- a/drivers/hwmon/ads7871.c +++ b/drivers/hwmon/ads7871.c @@ -133,12 +133,6 @@ static ssize_t show_voltage(struct device *dev, } } -static ssize_t ads7871_show_name(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - return sprintf(buf, "%s\n", to_spi_device(dev)->modalias); -} - static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_voltage, NULL, 0); static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 1); static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 2); @@ -148,8 +142,6 @@ static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_voltage, NULL, 5); static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 6); static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 7); -static DEVICE_ATTR(name, S_IRUGO, ads7871_show_name, NULL); - static struct attribute *ads7871_attributes[] = { &sensor_dev_attr_in0_input.dev_attr.attr, &sensor_dev_attr_in1_input.dev_attr.attr, @@ -159,7 +151,6 @@ static struct attribute *ads7871_attributes[] = { &sensor_dev_attr_in5_input.dev_attr.attr, &sensor_dev_attr_in6_input.dev_attr.attr, &sensor_dev_attr_in7_input.dev_attr.attr, - &dev_attr_name.attr, NULL }; diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index d99aa8484777..4c0743660e9c 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -215,7 +215,7 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) int i; if (send_command(cmd) || send_argument(key)) { - pr_warn("%.4s: read arg fail\n", key); + pr_warn("%s: read arg fail\n", key); return -EIO; } @@ -223,7 +223,7 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) for (i = 0; i < len; i++) { if (__wait_status(0x05)) { - pr_warn("%.4s: read data fail\n", key); + pr_warn("%s: read data fail\n", key); return -EIO; } buffer[i] = inb(APPLESMC_DATA_PORT); diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 83d2fbd670d6..00e98517f94c 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c @@ -34,12 +34,6 @@ static const struct dmi_system_id __initconst atk_force_new_if[] = { .matches = { DMI_MATCH(DMI_BOARD_NAME, "SABERTOOTH X58") } - }, { - /* Old interface reads the same sensor for fan0 and fan1 */ - .ident = "Asus M5A78L", - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "M5A78L") - } }, { } }; diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 87fd034dabd9..0070d5476dd0 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -42,18 +42,20 @@ #define DRVNAME "coretemp" #define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */ -#define NUM_REAL_CORES 32 /* Number of Real cores per cpu */ +#define NUM_REAL_CORES 16 /* Number of Real cores per cpu */ #define CORETEMP_NAME_LENGTH 17 /* String Length of attrs */ #define MAX_ATTRS 5 /* Maximum no of per-core attrs */ #define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO) +#ifdef CONFIG_SMP #define TO_PHYS_ID(cpu) cpu_data(cpu).phys_proc_id #define TO_CORE_ID(cpu) cpu_data(cpu).cpu_core_id #define TO_ATTR_NO(cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO) - -#ifdef CONFIG_SMP #define for_each_sibling(i, cpu) for_each_cpu(i, cpu_sibling_mask(cpu)) #else +#define TO_PHYS_ID(cpu) (cpu) +#define TO_CORE_ID(cpu) (cpu) +#define TO_ATTR_NO(cpu) (cpu) #define for_each_sibling(i, cpu) for (i = 0; false; ) #endif @@ -538,8 +540,6 @@ static void coretemp_add_core(unsigned int cpu, int pkg_flag) return; pdata = platform_get_drvdata(pdev); - if (!pdata) - return; err = create_core_data(pdata, pdev, cpu, pkg_flag); if (err) @@ -708,7 +708,7 @@ static void __cpuinit get_core_online(unsigned int cpu) * sensors. We check this bit only, all the early CPUs * without thermal sensors will be filtered out. */ - if (!cpu_has(c, X86_FEATURE_DTHERM)) + if (!cpu_has(c, X86_FEATURE_DTS)) return; if (!pdev) { @@ -746,15 +746,9 @@ static void __cpuinit put_core_offline(unsigned int cpu) return; pdata = platform_get_drvdata(pdev); - if (!pdata) - return; indx = TO_ATTR_NO(cpu); - /* The core id is too big, just return */ - if (indx > MAX_CORE_DATA - 1) - return; - if (pdata->core_data[indx] && pdata->core_data[indx]->cpu == cpu) coretemp_remove_core(pdata, &pdev->dev, indx); diff --git a/drivers/hwmon/ds620.c b/drivers/hwmon/ds620.c index 4f7c3fc40a89..257957c69d92 100644 --- a/drivers/hwmon/ds620.c +++ b/drivers/hwmon/ds620.c @@ -72,7 +72,7 @@ struct ds620_data { char valid; /* !=0 if following fields are valid */ unsigned long last_updated; /* In jiffies */ - s16 temp[3]; /* Register values, word */ + u16 temp[3]; /* Register values, word */ }; /* diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c index 6dbfd3e516e4..92f949767ece 100644 --- a/drivers/hwmon/f71805f.c +++ b/drivers/hwmon/f71805f.c @@ -283,11 +283,11 @@ static inline long temp_from_reg(u8 reg) static inline u8 temp_to_reg(long val) { - if (val <= 0) - return 0; - if (val >= 1000 * 0xff) - return 0xff; - return (val + 500) / 1000; + if (val < 0) + val = 0; + else if (val > 1000 * 0xff) + val = 0xff; + return ((val + 500) / 1000); } /* diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index 040a820acd15..95cbfb3a7077 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -159,7 +159,7 @@ static inline void f75375_write8(struct i2c_client *client, u8 reg, static inline void f75375_write16(struct i2c_client *client, u8 reg, u16 value) { - int err = i2c_smbus_write_byte_data(client, reg, (value >> 8)); + int err = i2c_smbus_write_byte_data(client, reg, (value << 8)); if (err) return; i2c_smbus_write_byte_data(client, reg + 1, (value & 0xFF)); @@ -304,21 +304,20 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val) case 0: /* Full speed */ fanmode |= (3 << FAN_CTRL_MODE(nr)); data->pwm[nr] = 255; + f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), + data->pwm[nr]); break; case 1: /* PWM */ fanmode |= (3 << FAN_CTRL_MODE(nr)); break; case 2: /* AUTOMATIC*/ - fanmode |= (1 << FAN_CTRL_MODE(nr)); + fanmode |= (2 << FAN_CTRL_MODE(nr)); break; case 3: /* fan speed */ break; } f75375_write8(client, F75375_REG_FAN_TIMER, fanmode); data->pwm_enable[nr] = val; - if (val == 0) - f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), - data->pwm[nr]); return 0; } diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c index 770e95951a56..523f8fb9e7d9 100644 --- a/drivers/hwmon/fam15h_power.c +++ b/drivers/hwmon/fam15h_power.c @@ -31,9 +31,6 @@ MODULE_DESCRIPTION("AMD Family 15h CPU processor power monitor"); MODULE_AUTHOR("Andreas Herrmann "); MODULE_LICENSE("GPL"); -/* Family 16h Northbridge's function 4 PCI ID */ -#define PCI_DEVICE_ID_AMD_16H_NB_F4 0x1534 - /* D18F3 */ #define REG_NORTHBRIDGE_CAP 0xe8 @@ -63,15 +60,15 @@ static ssize_t show_power(struct device *dev, pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5), REG_TDP_RUNNING_AVERAGE, &val); running_avg_capture = (val >> 4) & 0x3fffff; - running_avg_capture = sign_extend32(running_avg_capture, 21); - running_avg_range = (val & 0xf) + 1; + running_avg_capture = sign_extend32(running_avg_capture, 22); + running_avg_range = val & 0xf; pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5), REG_TDP_LIMIT3, &val); tdp_limit = val >> 16; - curr_pwr_watts = (tdp_limit + data->base_tdp) << running_avg_range; - curr_pwr_watts -= running_avg_capture; + curr_pwr_watts = tdp_limit + data->base_tdp - + (s32)(running_avg_capture >> (running_avg_range + 1)); curr_pwr_watts *= data->tdp_to_watts; /* @@ -81,7 +78,7 @@ static ssize_t show_power(struct device *dev, * scaling factor 1/(2^16). For conversion we use * (10^6)/(2^16) = 15625/(2^10) */ - curr_pwr_watts = (curr_pwr_watts * 15625) >> (10 + running_avg_range); + curr_pwr_watts = (curr_pwr_watts * 15625) >> 10; return sprintf(buf, "%u\n", (unsigned int) curr_pwr_watts); } static DEVICE_ATTR(power1_input, S_IRUGO, show_power, NULL); @@ -125,51 +122,6 @@ static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4) return true; } -/* - * Newer BKDG versions have an updated recommendation on how to properly - * initialize the running average range (was: 0xE, now: 0x9). This avoids - * counter saturations resulting in bogus power readings. - * We correct this value ourselves to cope with older BIOSes. - */ -static const struct pci_device_id affected_device[] = { - { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }, - { 0 } -}; - -static void tweak_runavg_range(struct pci_dev *pdev) -{ - u32 val; - - /* - * let this quirk apply only to the current version of the - * northbridge, since future versions may change the behavior - */ - if (!pci_match_id(affected_device, pdev)) - return; - - pci_bus_read_config_dword(pdev->bus, - PCI_DEVFN(PCI_SLOT(pdev->devfn), 5), - REG_TDP_RUNNING_AVERAGE, &val); - if ((val & 0xf) != 0xe) - return; - - val &= ~0xf; - val |= 0x9; - pci_bus_write_config_dword(pdev->bus, - PCI_DEVFN(PCI_SLOT(pdev->devfn), 5), - REG_TDP_RUNNING_AVERAGE, val); -} - -#ifdef CONFIG_PM -static int fam15h_power_resume(struct pci_dev *pdev) -{ - tweak_runavg_range(pdev); - return 0; -} -#else -#define fam15h_power_resume NULL -#endif - static void __devinit fam15h_power_init_data(struct pci_dev *f4, struct fam15h_power_data *data) { @@ -203,13 +155,6 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev, struct device *dev; int err; - /* - * though we ignore every other northbridge, we still have to - * do the tweaking on _each_ node in MCM processors as the counters - * are working hand-in-hand - */ - tweak_runavg_range(pdev); - if (!fam15h_power_is_internal_node0(pdev)) { err = -ENODEV; goto exit; @@ -259,7 +204,6 @@ static void __devexit fam15h_power_remove(struct pci_dev *pdev) static DEFINE_PCI_DEVICE_TABLE(fam15h_power_id_table) = { { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }, - { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) }, {} }; MODULE_DEVICE_TABLE(pci, fam15h_power_id_table); @@ -269,7 +213,6 @@ static struct pci_driver fam15h_power_driver = { .id_table = fam15h_power_id_table, .probe = fam15h_power_probe, .remove = __devexit_p(fam15h_power_remove), - .resume = fam15h_power_resume, }; static int __init fam15h_power_init(void) diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c index c316294c48b4..1a409c5bc9bc 100644 --- a/drivers/hwmon/ibmaem.c +++ b/drivers/hwmon/ibmaem.c @@ -432,15 +432,13 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, aem_send_message(ipmi); res = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); - if (!res) { - res = -ETIMEDOUT; - goto out; - } + if (!res) + return -ETIMEDOUT; if (ipmi->rx_result || ipmi->rx_msg_len != rs_size || memcmp(&rs_resp->id, &system_x_id, sizeof(system_x_id))) { - res = -ENOENT; - goto out; + kfree(rs_resp); + return -ENOENT; } switch (size) { @@ -465,11 +463,8 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, break; } } - res = 0; -out: - kfree(rs_resp); - return res; + return 0; } /* Update AEM energy registers */ diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index b358c87c3bca..5f5247750430 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -2057,7 +2057,7 @@ static void __devinit it87_init_device(struct platform_device *pdev) /* Start monitoring */ it87_write_value(data, IT87_REG_CONFIG, - (it87_read_value(data, IT87_REG_CONFIG) & 0x3e) + (it87_read_value(data, IT87_REG_CONFIG) & 0x36) | (update_vbat ? 0x41 : 0x01)); } diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index ed4392406e93..02cebb74e206 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -64,7 +64,6 @@ static const unsigned short normal_i2c[] = { /* Manufacturer IDs */ #define ADT_MANID 0x11d4 /* Analog Devices */ -#define ATMEL_MANID 0x001f /* Atmel */ #define MAX_MANID 0x004d /* Maxim */ #define IDT_MANID 0x00b3 /* IDT */ #define MCP_MANID 0x0054 /* Microchip */ @@ -78,25 +77,15 @@ static const unsigned short normal_i2c[] = { #define ADT7408_DEVID 0x0801 #define ADT7408_DEVID_MASK 0xffff -/* Atmel */ -#define AT30TS00_DEVID 0x8201 -#define AT30TS00_DEVID_MASK 0xffff - /* IDT */ #define TS3000B3_DEVID 0x2903 /* Also matches TSE2002B3 */ #define TS3000B3_DEVID_MASK 0xffff -#define TS3000GB2_DEVID 0x2912 /* Also matches TSE2002GB2 */ -#define TS3000GB2_DEVID_MASK 0xffff - /* Maxim */ #define MAX6604_DEVID 0x3e00 #define MAX6604_DEVID_MASK 0xffff /* Microchip */ -#define MCP9804_DEVID 0x0200 -#define MCP9804_DEVID_MASK 0xfffc - #define MCP98242_DEVID 0x2000 #define MCP98242_DEVID_MASK 0xfffc @@ -124,12 +113,6 @@ static const unsigned short normal_i2c[] = { #define STTS424E_DEVID 0x0000 #define STTS424E_DEVID_MASK 0xfffe -#define STTS2002_DEVID 0x0300 -#define STTS2002_DEVID_MASK 0xffff - -#define STTS3000_DEVID 0x0200 -#define STTS3000_DEVID_MASK 0xffff - static u16 jc42_hysteresis[] = { 0, 1500, 3000, 6000 }; struct jc42_chips { @@ -140,11 +123,8 @@ struct jc42_chips { static struct jc42_chips jc42_chips[] = { { ADT_MANID, ADT7408_DEVID, ADT7408_DEVID_MASK }, - { ATMEL_MANID, AT30TS00_DEVID, AT30TS00_DEVID_MASK }, { IDT_MANID, TS3000B3_DEVID, TS3000B3_DEVID_MASK }, - { IDT_MANID, TS3000GB2_DEVID, TS3000GB2_DEVID_MASK }, { MAX_MANID, MAX6604_DEVID, MAX6604_DEVID_MASK }, - { MCP_MANID, MCP9804_DEVID, MCP9804_DEVID_MASK }, { MCP_MANID, MCP98242_DEVID, MCP98242_DEVID_MASK }, { MCP_MANID, MCP98243_DEVID, MCP98243_DEVID_MASK }, { MCP_MANID, MCP9843_DEVID, MCP9843_DEVID_MASK }, @@ -153,8 +133,6 @@ static struct jc42_chips jc42_chips[] = { { NXP_MANID, SE98_DEVID, SE98_DEVID_MASK }, { STM_MANID, STTS424_DEVID, STTS424_DEVID_MASK }, { STM_MANID, STTS424E_DEVID, STTS424E_DEVID_MASK }, - { STM_MANID, STTS2002_DEVID, STTS2002_DEVID_MASK }, - { STM_MANID, STTS3000_DEVID, STTS3000_DEVID_MASK }, }; /* Each client has this additional data */ @@ -183,12 +161,10 @@ static struct jc42_data *jc42_update_device(struct device *dev); static const struct i2c_device_id jc42_id[] = { { "adt7408", 0 }, - { "at30ts00", 0 }, { "cat94ts02", 0 }, { "cat6095", 0 }, { "jc42", 0 }, { "max6604", 0 }, - { "mcp9804", 0 }, { "mcp9805", 0 }, { "mcp98242", 0 }, { "mcp98243", 0 }, @@ -197,10 +173,8 @@ static const struct i2c_device_id jc42_id[] = { { "se97b", 0 }, { "se98", 0 }, { "stts424", 0 }, - { "stts2002", 0 }, - { "stts3000", 0 }, - { "tse2002", 0 }, - { "ts3000", 0 }, + { "tse2002b3", 0 }, + { "ts3000b3", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, jc42_id); diff --git a/drivers/hwmon/jz4740-hwmon.c b/drivers/hwmon/jz4740-hwmon.c index b65a4dae3f5e..fea292d43407 100644 --- a/drivers/hwmon/jz4740-hwmon.c +++ b/drivers/hwmon/jz4740-hwmon.c @@ -59,7 +59,7 @@ static ssize_t jz4740_hwmon_read_adcin(struct device *dev, { struct jz4740_hwmon *hwmon = dev_get_drvdata(dev); struct completion *completion = &hwmon->read_completion; - long t; + unsigned long t; unsigned long val; int ret; diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c index dd2d7b9620c2..d94a24fdf4ba 100644 --- a/drivers/hwmon/max16065.c +++ b/drivers/hwmon/max16065.c @@ -124,7 +124,7 @@ static inline int MV_TO_LIMIT(int mv, int range) static inline int ADC_TO_CURR(int adc, int gain) { - return adc * 1400000 / (gain * 255); + return adc * 1400000 / gain * 255; } /* diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c index 8c3df047e568..f20d9978ee78 100644 --- a/drivers/hwmon/max6639.c +++ b/drivers/hwmon/max6639.c @@ -72,8 +72,8 @@ static unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END }; static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 }; -#define FAN_FROM_REG(val, rpm_range) ((val) == 0 || (val) == 255 ? \ - 0 : (rpm_ranges[rpm_range] * 30) / (val)) +#define FAN_FROM_REG(val, div, rpm_range) ((val) == 0 ? -1 : \ + (val) == 255 ? 0 : (rpm_ranges[rpm_range] * 30) / ((div + 1) * (val))) #define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT((val) / 1000, 0, 255) /* @@ -333,7 +333,7 @@ static ssize_t show_fan_input(struct device *dev, return PTR_ERR(data); return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index], - data->rpm_range)); + data->ppr, data->rpm_range)); } static ssize_t show_alarm(struct device *dev, @@ -429,9 +429,9 @@ static int max6639_init_client(struct i2c_client *client) struct max6639_data *data = i2c_get_clientdata(client); struct max6639_platform_data *max6639_info = client->dev.platform_data; - int i; + int i = 0; int rpm_range = 1; /* default: 4000 RPM */ - int err; + int err = 0; /* Reset chip to default values, see below for GCONFIG setup */ err = i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG, @@ -446,6 +446,11 @@ static int max6639_init_client(struct i2c_client *client) else data->ppr = 2; data->ppr -= 1; + err = i2c_smbus_write_byte_data(client, + MAX6639_REG_FAN_PPR(i), + data->ppr << 5); + if (err) + goto exit; if (max6639_info) rpm_range = rpm_range_to_reg(max6639_info->rpm_range); @@ -453,13 +458,6 @@ static int max6639_init_client(struct i2c_client *client) for (i = 0; i < 2; i++) { - /* Set Fan pulse per revolution */ - err = i2c_smbus_write_byte_data(client, - MAX6639_REG_FAN_PPR(i), - data->ppr << 6); - if (err) - goto exit; - /* Fans config PWM, RPM */ err = i2c_smbus_write_byte_data(client, MAX6639_REG_FAN_CONFIG1(i), diff --git a/drivers/hwmon/pmbus_core.c b/drivers/hwmon/pmbus_core.c index ffa54dd7dbda..8e31a8e2c746 100644 --- a/drivers/hwmon/pmbus_core.c +++ b/drivers/hwmon/pmbus_core.c @@ -50,8 +50,7 @@ lcrit_alarm, crit_alarm */ #define PMBUS_IOUT_BOOLEANS_PER_PAGE 3 /* alarm, lcrit_alarm, crit_alarm */ -#define PMBUS_POUT_BOOLEANS_PER_PAGE 3 /* cap_alarm, alarm, crit_alarm - */ +#define PMBUS_POUT_BOOLEANS_PER_PAGE 2 /* alarm, crit_alarm */ #define PMBUS_MAX_BOOLEANS_PER_FAN 2 /* alarm, fault */ #define PMBUS_MAX_BOOLEANS_PER_TEMP 4 /* min_alarm, max_alarm, lcrit_alarm, crit_alarm */ diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 9594cdb1cd0f..cf4330b352ef 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -883,7 +883,7 @@ static int sht15_invalidate_voltage(struct notifier_block *nb, static int __devinit sht15_probe(struct platform_device *pdev) { - int ret; + int ret = 0; struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL); u8 status = 0; @@ -901,7 +901,6 @@ static int __devinit sht15_probe(struct platform_device *pdev) init_waitqueue_head(&data->wait_queue); if (pdev->dev.platform_data == NULL) { - ret = -EINVAL; dev_err(&pdev->dev, "no platform data supplied\n"); goto err_free_data; } diff --git a/drivers/hwmon/twl4030-madc-hwmon.c b/drivers/hwmon/twl4030-madc-hwmon.c index b6adfac6ca9c..57240740b161 100644 --- a/drivers/hwmon/twl4030-madc-hwmon.c +++ b/drivers/hwmon/twl4030-madc-hwmon.c @@ -44,13 +44,12 @@ static ssize_t madc_read(struct device *dev, struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct twl4030_madc_request req = { - .channels = 1 << attr->index, - .method = TWL4030_MADC_SW2, - .type = TWL4030_MADC_WAIT, - }; + struct twl4030_madc_request req; long val; + req.channels = (1 << attr->index); + req.method = TWL4030_MADC_SW2; + req.func_cb = NULL; val = twl4030_madc_conversion(&req); if (val < 0) return val; diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 1198a6e5e8ce..f2b377c56a3a 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -390,7 +390,7 @@ temp_from_reg(u16 reg, s16 regval) { if (is_word_sized(reg)) return LM75_TEMP_FROM_REG(regval); - return ((s8)regval) * 1000; + return regval * 1000; } static inline u16 @@ -398,8 +398,7 @@ temp_to_reg(u16 reg, long temp) { if (is_word_sized(reg)) return LM75_TEMP_TO_REG(temp); - return (s8)DIV_ROUND_CLOSEST(SENSORS_LIMIT(temp, -127000, 128000), - 1000); + return DIV_ROUND_CLOSEST(SENSORS_LIMIT(temp, -127000, 128000), 1000); } /* Some of analog inputs have internal scaling (2x), 8mV is ADC LSB */ @@ -1295,7 +1294,6 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, { struct w83627ehf_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - struct w83627ehf_sio_data *sio_data = dev->platform_data; int nr = sensor_attr->index; unsigned long val; int err; @@ -1307,11 +1305,6 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, if (val > 1) return -EINVAL; - - /* On NCT67766F, DC mode is only supported for pwm1 */ - if (sio_data->kind == nct6776 && nr && val != 1) - return -EINVAL; - mutex_lock(&data->update_lock); reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]); data->pwm_mode[nr] = val; @@ -1583,7 +1576,7 @@ store_##reg(struct device *dev, struct device_attribute *attr, \ val = step_time_to_reg(val, data->pwm_mode[nr]); \ mutex_lock(&data->update_lock); \ data->reg[nr] = val; \ - w83627ehf_write_value(data, data->REG_##REG[nr], val); \ + w83627ehf_write_value(data, W83627EHF_REG_##REG[nr], val); \ mutex_unlock(&data->update_lock); \ return count; \ } \ @@ -1722,8 +1715,7 @@ static void w83627ehf_device_remove_files(struct device *dev) } /* Get the monitoring functions started */ -static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data, - enum kinds kind) +static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data) { int i; u8 tmp, diode; @@ -1754,26 +1746,10 @@ static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data, w83627ehf_write_value(data, W83627EHF_REG_VBAT, tmp | 0x01); /* Get thermal sensor types */ - switch (kind) { - case w83627ehf: - diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE); - break; - default: - diode = 0x70; - } + diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE); for (i = 0; i < 3; i++) { - const char *label = NULL; - - if (data->temp_label) - label = data->temp_label[data->temp_src[i]]; - - /* Digital source overrides analog type */ - if (label && strncmp(label, "PECI", 4) == 0) - data->temp_type[i] = 6; - else if (label && strncmp(label, "AMD", 3) == 0) - data->temp_type[i] = 5; - else if ((tmp & (0x02 << i))) - data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 3; + if ((tmp & (0x02 << i))) + data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 2; else data->temp_type[i] = 4; /* thermistor */ } @@ -1823,8 +1799,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) goto exit; } - data = devm_kzalloc(&pdev->dev, sizeof(struct w83627ehf_data), - GFP_KERNEL); + data = kzalloc(sizeof(struct w83627ehf_data), GFP_KERNEL); if (!data) { err = -ENOMEM; goto exit_release; @@ -1834,7 +1809,6 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) mutex_init(&data->lock); mutex_init(&data->update_lock); data->name = w83627ehf_device_names[sio_data->kind]; - data->bank = 0xff; /* Force initial bank selection */ platform_set_drvdata(pdev, data); /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */ @@ -2042,7 +2016,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) } /* Initialize the chip */ - w83627ehf_init_device(data, sio_data->kind); + w83627ehf_init_device(data); data->vrm = vid_which_vrm(); superio_enter(sio_data->sioreg); @@ -2106,29 +2080,9 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) fan4min = 0; fan5pin = 0; } else if (sio_data->kind == nct6776) { - bool gpok = superio_inb(sio_data->sioreg, 0x27) & 0x80; - u8 regval; - - superio_select(sio_data->sioreg, W83627EHF_LD_HWM); - regval = superio_inb(sio_data->sioreg, SIO_REG_ENABLE); - - if (regval & 0x80) - fan3pin = gpok; - else - fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40); - - if (regval & 0x40) - fan4pin = gpok; - else - fan4pin = !!(superio_inb(sio_data->sioreg, 0x1C) - & 0x01); - - if (regval & 0x20) - fan5pin = gpok; - else - fan5pin = !!(superio_inb(sio_data->sioreg, 0x1C) - & 0x02); - + fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40); + fan4pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x01); + fan5pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x02); fan4min = fan4pin; } else if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b) { fan3pin = 1; @@ -2321,8 +2275,9 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) exit_remove: w83627ehf_device_remove_files(dev); -exit_release: + kfree(data); platform_set_drvdata(pdev, NULL); +exit_release: release_region(res->start, IOREGION_LENGTH); exit: return err; @@ -2336,6 +2291,7 @@ static int __devexit w83627ehf_remove(struct platform_device *pdev) w83627ehf_device_remove_files(&pdev->dev); release_region(data->addr, IOREGION_LENGTH); platform_set_drvdata(pdev, NULL); + kfree(data); return 0; } diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c index 12f7c8300c75..43a62714b4fb 100644 --- a/drivers/hwspinlock/hwspinlock_core.c +++ b/drivers/hwspinlock/hwspinlock_core.c @@ -26,7 +26,6 @@ #include #include #include -#include #include "hwspinlock_internal.h" @@ -53,12 +52,10 @@ static RADIX_TREE(hwspinlock_tree, GFP_KERNEL); /* - * Synchronization of access to the tree is achieved using this mutex, + * Synchronization of access to the tree is achieved using this spinlock, * as the radix-tree API requires that users provide all synchronisation. - * A mutex is needed because we're using non-atomic radix tree allocations. */ -static DEFINE_MUTEX(hwspinlock_tree_lock); - +static DEFINE_SPINLOCK(hwspinlock_tree_lock); /** * __hwspin_trylock() - attempt to lock a specific hwspinlock @@ -264,7 +261,8 @@ EXPORT_SYMBOL_GPL(__hwspin_unlock); * This function should be called from the underlying platform-specific * implementation, to register a new hwspinlock instance. * - * Should be called from a process context (might sleep) + * Can be called from an atomic context (will not sleep) but not from + * within interrupt context. * * Returns 0 on success, or an appropriate error code on failure */ @@ -281,7 +279,7 @@ int hwspin_lock_register(struct hwspinlock *hwlock) spin_lock_init(&hwlock->lock); - mutex_lock(&hwspinlock_tree_lock); + spin_lock(&hwspinlock_tree_lock); ret = radix_tree_insert(&hwspinlock_tree, hwlock->id, hwlock); if (ret) @@ -295,7 +293,7 @@ int hwspin_lock_register(struct hwspinlock *hwlock) WARN_ON(tmp != hwlock); out: - mutex_unlock(&hwspinlock_tree_lock); + spin_unlock(&hwspinlock_tree_lock); return ret; } EXPORT_SYMBOL_GPL(hwspin_lock_register); @@ -307,7 +305,8 @@ EXPORT_SYMBOL_GPL(hwspin_lock_register); * This function should be called from the underlying platform-specific * implementation, to unregister an existing (and unused) hwspinlock. * - * Should be called from a process context (might sleep) + * Can be called from an atomic context (will not sleep) but not from + * within interrupt context. * * Returns the address of hwspinlock @id on success, or NULL on failure */ @@ -316,7 +315,7 @@ struct hwspinlock *hwspin_lock_unregister(unsigned int id) struct hwspinlock *hwlock = NULL; int ret; - mutex_lock(&hwspinlock_tree_lock); + spin_lock(&hwspinlock_tree_lock); /* make sure the hwspinlock is not in use (tag is set) */ ret = radix_tree_tag_get(&hwspinlock_tree, id, HWSPINLOCK_UNUSED); @@ -332,7 +331,7 @@ struct hwspinlock *hwspin_lock_unregister(unsigned int id) } out: - mutex_unlock(&hwspinlock_tree_lock); + spin_unlock(&hwspinlock_tree_lock); return hwlock; } EXPORT_SYMBOL_GPL(hwspin_lock_unregister); @@ -401,7 +400,9 @@ EXPORT_SYMBOL_GPL(hwspin_lock_get_id); * to the remote core before it can be used for synchronization (to get the * id of a given hwlock, use hwspin_lock_get_id()). * - * Should be called from a process context (might sleep) + * Can be called from an atomic context (will not sleep) but not from + * within interrupt context (simply because there is no use case for + * that yet). * * Returns the address of the assigned hwspinlock, or NULL on error */ @@ -410,7 +411,7 @@ struct hwspinlock *hwspin_lock_request(void) struct hwspinlock *hwlock; int ret; - mutex_lock(&hwspinlock_tree_lock); + spin_lock(&hwspinlock_tree_lock); /* look for an unused lock */ ret = radix_tree_gang_lookup_tag(&hwspinlock_tree, (void **)&hwlock, @@ -430,7 +431,7 @@ struct hwspinlock *hwspin_lock_request(void) hwlock = NULL; out: - mutex_unlock(&hwspinlock_tree_lock); + spin_unlock(&hwspinlock_tree_lock); return hwlock; } EXPORT_SYMBOL_GPL(hwspin_lock_request); @@ -444,7 +445,9 @@ EXPORT_SYMBOL_GPL(hwspin_lock_request); * Usually early board code will be calling this function in order to * reserve specific hwspinlock ids for predefined purposes. * - * Should be called from a process context (might sleep) + * Can be called from an atomic context (will not sleep) but not from + * within interrupt context (simply because there is no use case for + * that yet). * * Returns the address of the assigned hwspinlock, or NULL on error */ @@ -453,7 +456,7 @@ struct hwspinlock *hwspin_lock_request_specific(unsigned int id) struct hwspinlock *hwlock; int ret; - mutex_lock(&hwspinlock_tree_lock); + spin_lock(&hwspinlock_tree_lock); /* make sure this hwspinlock exists */ hwlock = radix_tree_lookup(&hwspinlock_tree, id); @@ -479,7 +482,7 @@ struct hwspinlock *hwspin_lock_request_specific(unsigned int id) hwlock = NULL; out: - mutex_unlock(&hwspinlock_tree_lock); + spin_unlock(&hwspinlock_tree_lock); return hwlock; } EXPORT_SYMBOL_GPL(hwspin_lock_request_specific); @@ -492,7 +495,9 @@ EXPORT_SYMBOL_GPL(hwspin_lock_request_specific); * Should only be called with an @hwlock that was retrieved from * an earlier call to omap_hwspin_lock_request{_specific}. * - * Should be called from a process context (might sleep) + * Can be called from an atomic context (will not sleep) but not from + * within interrupt context (simply because there is no use case for + * that yet). * * Returns 0 on success, or an appropriate error code on failure */ @@ -506,7 +511,7 @@ int hwspin_lock_free(struct hwspinlock *hwlock) return -EINVAL; } - mutex_lock(&hwspinlock_tree_lock); + spin_lock(&hwspinlock_tree_lock); /* make sure the hwspinlock is used */ ret = radix_tree_tag_get(&hwspinlock_tree, hwlock->id, @@ -533,7 +538,7 @@ int hwspin_lock_free(struct hwspinlock *hwlock) module_put(hwlock->owner); out: - mutex_unlock(&hwspinlock_tree_lock); + spin_unlock(&hwspinlock_tree_lock); return ret; } EXPORT_SYMBOL_GPL(hwspin_lock_free); diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index f2ce8c36816f..d6d58684712b 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -103,14 +103,8 @@ static int sclhi(struct i2c_algo_bit_data *adap) * chips may hold it low ("clock stretching") while they * are processing data internally. */ - if (time_after(jiffies, start + adap->timeout)) { - /* Test one last time, as we may have been preempted - * between last check and timeout test. - */ - if (getscl(adap)) - break; + if (time_after(jiffies, start + adap->timeout)) return -ETIMEDOUT; - } cond_resched(); } #ifdef DEBUG @@ -492,7 +486,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) if (flags & I2C_M_TEN) { /* a ten bit address */ - addr = 0xf0 | ((msg->addr >> 7) & 0x06); + addr = 0xf0 | ((msg->addr >> 7) & 0x03); bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr); /* try extended address code...*/ ret = try_address(i2c_adap, addr, retries); @@ -502,7 +496,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) return -EREMOTEIO; } /* the remaining 8 bit address */ - ret = i2c_outb(i2c_adap, msg->addr & 0xff); + ret = i2c_outb(i2c_adap, msg->addr & 0x7f); if ((ret != 1) && !nak_ok) { /* the chip did not ack / xmission error occurred */ dev_err(&i2c_adap->dev, "died at 2nd address code\n"); diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index cd7ac5c6783e..dd364171f9c5 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c @@ -140,7 +140,7 @@ static unsigned short ali1535_smba; defined to make the transition easier. */ static int __devinit ali1535_setup(struct pci_dev *dev) { - int retval; + int retval = -ENODEV; unsigned char temp; /* Check the following things: @@ -155,7 +155,6 @@ static int __devinit ali1535_setup(struct pci_dev *dev) if (ali1535_smba == 0) { dev_warn(&dev->dev, "ALI1535_smb region uninitialized - upgrade BIOS?\n"); - retval = -ENODEV; goto exit; } @@ -168,7 +167,6 @@ static int __devinit ali1535_setup(struct pci_dev *dev) ali1535_driver.name)) { dev_err(&dev->dev, "ALI1535_smb region 0x%x already in use!\n", ali1535_smba); - retval = -EBUSY; goto exit; } @@ -176,7 +174,6 @@ static int __devinit ali1535_setup(struct pci_dev *dev) pci_read_config_byte(dev, SMBCFG, &temp); if ((temp & ALI1535_SMBIO_EN) == 0) { dev_err(&dev->dev, "SMB device not enabled - upgrade BIOS?\n"); - retval = -ENODEV; goto exit_free; } @@ -184,7 +181,6 @@ static int __devinit ali1535_setup(struct pci_dev *dev) pci_read_config_byte(dev, SMBHSTCFG, &temp); if ((temp & 1) == 0) { dev_err(&dev->dev, "SMBus controller not enabled - upgrade BIOS?\n"); - retval = -ENODEV; goto exit_free; } @@ -202,11 +198,12 @@ static int __devinit ali1535_setup(struct pci_dev *dev) dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp); dev_dbg(&dev->dev, "ALI1535_smba = 0x%X\n", ali1535_smba); - return 0; + retval = 0; +exit: + return retval; exit_free: release_region(ali1535_smba, ALI1535_SMB_IOSIZE); -exit: return retval; } diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 79b4bcb3b85c..a76d85fa3ad7 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -755,7 +755,7 @@ static int davinci_i2c_remove(struct platform_device *pdev) dev->clk = NULL; davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, 0); - free_irq(dev->irq, dev); + free_irq(IRQ_I2C, dev); iounmap(dev->base); kfree(dev); diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c index 656b028d9816..8abfa4a03ce1 100644 --- a/drivers/i2c/busses/i2c-eg20t.c +++ b/drivers/i2c/busses/i2c-eg20t.c @@ -242,7 +242,7 @@ static void pch_i2c_init(struct i2c_algo_pch_data *adap) if (pch_clk > PCH_MAX_CLK) pch_clk = 62500; - pch_i2cbc = (pch_clk + (pch_i2c_speed * 4)) / (pch_i2c_speed * 8); + pch_i2cbc = (pch_clk + (pch_i2c_speed * 4)) / pch_i2c_speed * 8; /* Set transfer speed in I2CBC */ iowrite32(pch_i2cbc, p + PCH_I2CBC); diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 3d471d56bf15..7e78f7c87857 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -72,7 +72,6 @@ #define MXS_I2C_QUEUESTAT (0x70) #define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY 0x00002000 -#define MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK 0x0000001F #define MXS_I2C_QUEUECMD (0x80) @@ -220,14 +219,14 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int ret; int flags; + init_completion(&i2c->cmd_complete); + dev_dbg(i2c->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n", msg->addr, msg->len, msg->flags, stop); if (msg->len == 0) return -EINVAL; - init_completion(&i2c->cmd_complete); - flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0; if (msg->flags & I2C_M_RD) @@ -287,7 +286,6 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) { struct mxs_i2c_dev *i2c = dev_id; u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK; - bool is_last_cmd; if (!stat) return IRQ_NONE; @@ -302,14 +300,9 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) else i2c->cmd_err = 0; - is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) & - MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0; - - if (is_last_cmd || i2c->cmd_err) - complete(&i2c->cmd_complete); + complete(&i2c->cmd_complete); writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR); - return IRQ_HANDLED; } diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 4853b52a40a8..ff1e127dfea8 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -356,7 +356,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar, error = acpi_check_region(smbus->base, smbus->size, nforce2_driver.name); if (error) - return error; + return -1; if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) { dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n", diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 137e1a3bfad1..58a58c7eaa17 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -235,7 +235,7 @@ const static u8 omap4_reg_map[] = { [OMAP_I2C_BUF_REG] = 0x94, [OMAP_I2C_CNT_REG] = 0x98, [OMAP_I2C_DATA_REG] = 0x9c, - [OMAP_I2C_SYSC_REG] = 0x10, + [OMAP_I2C_SYSC_REG] = 0x20, [OMAP_I2C_CON_REG] = 0xa4, [OMAP_I2C_OA_REG] = 0xa8, [OMAP_I2C_SA_REG] = 0xac, diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index eb8ad538c79f..04be9f82e14b 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -546,7 +546,8 @@ static int i2c_pnx_controller_suspend(struct platform_device *pdev, { struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); - clk_disable(alg_data->clk); + /* FIXME: shouldn't this be clk_disable? */ + clk_enable(alg_data->clk); return 0; } diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c index 6d60284cc04b..437586611d4a 100644 --- a/drivers/i2c/busses/i2c-sis5595.c +++ b/drivers/i2c/busses/i2c-sis5595.c @@ -147,7 +147,7 @@ static int __devinit sis5595_setup(struct pci_dev *SIS5595_dev) u16 a; u8 val; int *i; - int retval; + int retval = -ENODEV; /* Look for imposters */ for (i = blacklist; *i != 0; i++) { @@ -223,7 +223,7 @@ static int __devinit sis5595_setup(struct pci_dev *SIS5595_dev) error: release_region(sis5595_base + SMB_INDEX, 2); - return -ENODEV; + return retval; } static int sis5595_transaction(struct i2c_adapter *adap) diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index b617fd068ac7..e6f539e26f65 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -393,7 +393,7 @@ static int __devinit sis630_setup(struct pci_dev *sis630_dev) { unsigned char b; struct pci_dev *dummy = NULL; - int retval, i; + int retval = -ENODEV, i; /* check for supported SiS devices */ for (i=0; supported[i] > 0 ; i++) { @@ -418,21 +418,18 @@ static int __devinit sis630_setup(struct pci_dev *sis630_dev) */ if (pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) { dev_err(&sis630_dev->dev, "Error: Can't read bios ctl reg\n"); - retval = -ENODEV; goto exit; } /* if ACPI already enabled , do nothing */ if (!(b & 0x80) && pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) { dev_err(&sis630_dev->dev, "Error: Can't enable ACPI\n"); - retval = -ENODEV; goto exit; } /* Determine the ACPI base address */ if (pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) { dev_err(&sis630_dev->dev, "Error: Can't determine ACPI base address\n"); - retval = -ENODEV; goto exit; } @@ -448,7 +445,6 @@ static int __devinit sis630_setup(struct pci_dev *sis630_dev) sis630_driver.name)) { dev_err(&sis630_dev->dev, "SMBus registers 0x%04x-0x%04x already " "in use!\n", acpi_base + SMB_STS, acpi_base + SMB_SAA); - retval = -EBUSY; goto exit; } diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index 58261d4725b6..0b012f1f8ac5 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -324,7 +324,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev, const struct pci_device_id *id) { unsigned char temp; - int error; + int error = -ENODEV; /* Determine the address of the SMBus areas */ if (force_addr) { @@ -390,7 +390,6 @@ found: dev_err(&pdev->dev, "SMBUS: Error: Host SMBus " "controller not enabled! - upgrade BIOS or " "use force=1\n"); - error = -ENODEV; goto release_region; } } @@ -423,11 +422,9 @@ found: "SMBus Via Pro adapter at %04x", vt596_smba); vt596_pdev = pci_dev_get(pdev); - error = i2c_add_adapter(&vt596_adapter); - if (error) { + if (i2c_add_adapter(&vt596_adapter)) { pci_dev_put(vt596_pdev); vt596_pdev = NULL; - goto release_region; } /* Always return failure here. This is to allow other drivers to bind diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 16f69be820c7..274798068a54 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -435,12 +435,7 @@ static int idedisk_prep_fn(struct request_queue *q, struct request *rq) if (!(rq->cmd_flags & REQ_FLUSH)) return BLKPREP_OK; - if (rq->special) { - cmd = rq->special; - memset(cmd, 0, sizeof(*cmd)); - } else { - cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); - } + cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); /* FIXME: map struct ide_taskfile on rq->cmd[] */ BUG_ON(cmd == NULL); diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c index a22ca8467010..d267b7affad6 100644 --- a/drivers/ide/ide-floppy_ioctl.c +++ b/drivers/ide/ide-floppy_ioctl.c @@ -292,7 +292,8 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev, * and CDROM_SEND_PACKET (legacy) ioctls */ if (cmd != CDROM_SEND_PACKET && cmd != SCSI_IOCTL_SEND_COMMAND) - err = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp); + err = scsi_cmd_ioctl(bdev->bd_disk->queue, bdev->bd_disk, + mode, cmd, argp); if (err == -ENOTTY) err = generic_ide_ioctl(drive, bdev, cmd, arg); diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 026f9aa789e3..a46dddf61078 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -321,8 +321,7 @@ static int intel_idle_probe(void) cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates); if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) || - !(ecx & CPUID5_ECX_INTERRUPT_BREAK) || - !mwait_substates) + !(ecx & CPUID5_ECX_INTERRUPT_BREAK)) return -ENODEV; pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates); @@ -368,7 +367,7 @@ static int intel_idle_probe(void) if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */ lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE; else { - on_each_cpu(__setup_broadcast_timer, (void *)true, 1); + smp_call_function(__setup_broadcast_timer, (void *)true, 1); register_cpu_notifier(&setup_broadcast_notifier); } @@ -460,7 +459,7 @@ static int intel_idle_cpuidle_devices_init(void) } } if (auto_demotion_disable_flags) - on_each_cpu(auto_demotion_disable, NULL, 1); + smp_call_function(auto_demotion_disable, NULL, 1); return 0; } @@ -500,7 +499,7 @@ static void __exit intel_idle_exit(void) cpuidle_unregister_driver(&intel_idle_driver); if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE) { - on_each_cpu(__setup_broadcast_timer, (void *)false, 1); + smp_call_function(__setup_broadcast_timer, (void *)false, 1); unregister_cpu_notifier(&setup_broadcast_notifier); } diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index f2a84c6f8543..8e21d457b899 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -215,9 +215,7 @@ static int addr4_resolve(struct sockaddr_in *src_in, neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->dst.dev); if (!neigh || !(neigh->nud_state & NUD_VALID)) { - rcu_read_lock(); - neigh_event_send(dst_get_neighbour(&rt->dst), NULL); - rcu_read_unlock(); + neigh_event_send(rt->dst.neighbour, NULL); ret = -ENODATA; if (neigh) goto release; @@ -275,16 +273,14 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, goto put; } - rcu_read_lock(); - neigh = dst_get_neighbour(dst); + neigh = dst->neighbour; if (!neigh || !(neigh->nud_state & NUD_VALID)) { - if (neigh) - neigh_event_send(neigh, NULL); + neigh_event_send(dst->neighbour, NULL); ret = -ENODATA; - } else { - ret = rdma_copy_addr(addr, dst->dev, neigh->ha); + goto put; } - rcu_read_unlock(); + + ret = rdma_copy_addr(addr, dst->dev, neigh->ha); put: dst_release(dst); return ret; diff --git a/drivers/infiniband/core/netlink.c b/drivers/infiniband/core/netlink.c index 9227f4acd79c..4a5abaf0a25c 100644 --- a/drivers/infiniband/core/netlink.c +++ b/drivers/infiniband/core/netlink.c @@ -148,7 +148,7 @@ static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) return -EINVAL; return netlink_dump_start(nls, skb, nlh, client->cb_table[op].dump, - NULL, 0); + NULL); } } diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index e55ce7a428be..0a5008fbebac 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c @@ -287,7 +287,7 @@ void __free_ep(struct kref *kref) if (test_bit(RELEASE_RESOURCES, &ep->com.flags)) { cxgb3_remove_tid(ep->com.tdev, (void *)ep, ep->hwtid); dst_release(ep->dst); - l2t_release(ep->com.tdev, ep->l2t); + l2t_release(L2DATA(ep->com.tdev), ep->l2t); } kfree(ep); } @@ -1178,7 +1178,7 @@ static int act_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) release_tid(ep->com.tdev, GET_TID(rpl), NULL); cxgb3_free_atid(ep->com.tdev, ep->atid); dst_release(ep->dst); - l2t_release(ep->com.tdev, ep->l2t); + l2t_release(L2DATA(ep->com.tdev), ep->l2t); put_ep(&ep->com); return CPL_RET_BUF_DONE; } @@ -1328,7 +1328,6 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) struct iwch_ep *child_ep, *parent_ep = ctx; struct cpl_pass_accept_req *req = cplhdr(skb); unsigned int hwtid = GET_TID(req); - struct neighbour *neigh; struct dst_entry *dst; struct l2t_entry *l2t; struct rtable *rt; @@ -1365,10 +1364,7 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) goto reject; } dst = &rt->dst; - rcu_read_lock(); - neigh = dst_get_neighbour(dst); - l2t = t3_l2t_get(tdev, neigh, neigh->dev); - rcu_read_unlock(); + l2t = t3_l2t_get(tdev, dst->neighbour, dst->neighbour->dev); if (!l2t) { printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n", __func__); @@ -1379,7 +1375,7 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) if (!child_ep) { printk(KERN_ERR MOD "%s - failed to allocate ep entry!\n", __func__); - l2t_release(tdev, l2t); + l2t_release(L2DATA(tdev), l2t); dst_release(dst); goto reject; } @@ -1878,11 +1874,10 @@ static int is_loopback_dst(struct iw_cm_id *cm_id) int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) { + int err = 0; struct iwch_dev *h = to_iwch_dev(cm_id->device); - struct neighbour *neigh; struct iwch_ep *ep; struct rtable *rt; - int err = 0; if (is_loopback_dst(cm_id)) { err = -ENOSYS; @@ -1938,12 +1933,9 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) } ep->dst = &rt->dst; - rcu_read_lock(); - neigh = dst_get_neighbour(ep->dst); - /* get a l2t entry */ - ep->l2t = t3_l2t_get(ep->com.tdev, neigh, neigh->dev); - rcu_read_unlock(); + ep->l2t = t3_l2t_get(ep->com.tdev, ep->dst->neighbour, + ep->dst->neighbour->dev); if (!ep->l2t) { printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__); err = -ENOMEM; @@ -1960,7 +1952,7 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) if (!err) goto out; - l2t_release(h->rdev.t3cdev_p, ep->l2t); + l2t_release(L2DATA(h->rdev.t3cdev_p), ep->l2t); fail4: dst_release(ep->dst); fail3: @@ -2131,7 +2123,7 @@ int iwch_ep_redirect(void *ctx, struct dst_entry *old, struct dst_entry *new, PDBG("%s ep %p redirect to dst %p l2t %p\n", __func__, ep, new, l2t); dst_hold(new); - l2t_release(ep->com.tdev, ep->l2t); + l2t_release(L2DATA(ep->com.tdev), ep->l2t); ep->l2t = l2t; dst_release(old); ep->dst = new; diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 267005d0e66f..31fb44085c9b 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -1325,7 +1325,6 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) unsigned int stid = GET_POPEN_TID(ntohl(req->tos_stid)); struct tid_info *t = dev->rdev.lldi.tids; unsigned int hwtid = GET_TID(req); - struct neighbour *neigh; struct dst_entry *dst; struct l2t_entry *l2t; struct rtable *rt; @@ -1358,12 +1357,11 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) goto reject; } dst = &rt->dst; - rcu_read_lock(); - neigh = dst_get_neighbour(dst); - if (neigh->dev->flags & IFF_LOOPBACK) { + if (dst->neighbour->dev->flags & IFF_LOOPBACK) { pdev = ip_dev_find(&init_net, peer_ip); BUG_ON(!pdev); - l2t = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh, pdev, 0); + l2t = cxgb4_l2t_get(dev->rdev.lldi.l2t, dst->neighbour, + pdev, 0); mtu = pdev->mtu; tx_chan = cxgb4_port_chan(pdev); smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1; @@ -1374,18 +1372,18 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) rss_qid = dev->rdev.lldi.rxq_ids[cxgb4_port_idx(pdev) * step]; dev_put(pdev); } else { - l2t = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh, neigh->dev, 0); + l2t = cxgb4_l2t_get(dev->rdev.lldi.l2t, dst->neighbour, + dst->neighbour->dev, 0); mtu = dst_mtu(dst); - tx_chan = cxgb4_port_chan(neigh->dev); - smac_idx = (cxgb4_port_viid(neigh->dev) & 0x7F) << 1; + tx_chan = cxgb4_port_chan(dst->neighbour->dev); + smac_idx = (cxgb4_port_viid(dst->neighbour->dev) & 0x7F) << 1; step = dev->rdev.lldi.ntxq / dev->rdev.lldi.nchan; - txq_idx = cxgb4_port_idx(neigh->dev) * step; - ctrlq_idx = cxgb4_port_idx(neigh->dev); + txq_idx = cxgb4_port_idx(dst->neighbour->dev) * step; + ctrlq_idx = cxgb4_port_idx(dst->neighbour->dev); step = dev->rdev.lldi.nrxq / dev->rdev.lldi.nchan; rss_qid = dev->rdev.lldi.rxq_ids[ - cxgb4_port_idx(neigh->dev) * step]; + cxgb4_port_idx(dst->neighbour->dev) * step]; } - rcu_read_unlock(); if (!l2t) { printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n", __func__); @@ -1849,7 +1847,6 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) struct c4iw_ep *ep; struct rtable *rt; struct net_device *pdev; - struct neighbour *neigh; int step; if ((conn_param->ord > c4iw_max_read_depth) || @@ -1911,16 +1908,14 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) } ep->dst = &rt->dst; - rcu_read_lock(); - neigh = dst_get_neighbour(ep->dst); - /* get a l2t entry */ - if (neigh->dev->flags & IFF_LOOPBACK) { + if (ep->dst->neighbour->dev->flags & IFF_LOOPBACK) { PDBG("%s LOOPBACK\n", __func__); pdev = ip_dev_find(&init_net, cm_id->remote_addr.sin_addr.s_addr); ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t, - neigh, pdev, 0); + ep->dst->neighbour, + pdev, 0); ep->mtu = pdev->mtu; ep->tx_chan = cxgb4_port_chan(pdev); ep->smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1; @@ -1935,20 +1930,21 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) dev_put(pdev); } else { ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t, - neigh, neigh->dev, 0); + ep->dst->neighbour, + ep->dst->neighbour->dev, 0); ep->mtu = dst_mtu(ep->dst); - ep->tx_chan = cxgb4_port_chan(neigh->dev); - ep->smac_idx = (cxgb4_port_viid(neigh->dev) & 0x7F) << 1; + ep->tx_chan = cxgb4_port_chan(ep->dst->neighbour->dev); + ep->smac_idx = (cxgb4_port_viid(ep->dst->neighbour->dev) & + 0x7F) << 1; step = ep->com.dev->rdev.lldi.ntxq / ep->com.dev->rdev.lldi.nchan; - ep->txq_idx = cxgb4_port_idx(neigh->dev) * step; - ep->ctrlq_idx = cxgb4_port_idx(neigh->dev); + ep->txq_idx = cxgb4_port_idx(ep->dst->neighbour->dev) * step; + ep->ctrlq_idx = cxgb4_port_idx(ep->dst->neighbour->dev); step = ep->com.dev->rdev.lldi.nrxq / ep->com.dev->rdev.lldi.nchan; ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[ - cxgb4_port_idx(neigh->dev) * step]; + cxgb4_port_idx(ep->dst->neighbour->dev) * step]; } - rcu_read_unlock(); if (!ep->l2t) { printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__); err = -ENOMEM; @@ -2316,12 +2312,6 @@ static int peer_abort_intr(struct c4iw_dev *dev, struct sk_buff *skb) unsigned int tid = GET_TID(req); ep = lookup_tid(t, tid); - if (!ep) { - printk(KERN_WARNING MOD - "Abort on non-existent endpoint, tid %d\n", tid); - kfree_skb(skb); - return 0; - } if (is_neg_adv_abort(req->status)) { PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep, ep->hwtid); diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 44fc3104e918..57ffa50f509e 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c @@ -255,9 +255,12 @@ int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, return IB_MAD_RESULT_SUCCESS; /* - * Don't process SMInfo queries -- the SMA can't handle them. + * Don't process SMInfo queries or vendor-specific + * MADs -- the SMA can't handle them. */ - if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO) + if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO || + ((in_mad->mad_hdr.attr_id & IB_SMP_ATTR_VENDOR_MASK) == + IB_SMP_ATTR_VENDOR_MASK)) return IB_MAD_RESULT_SUCCESS; } else if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT || in_mad->mad_hdr.mgmt_class == MLX4_IB_VENDOR_CLASS1 || diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 23c04ff6519b..2001f20a4361 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -1301,7 +1301,7 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr, int is_eth; int is_vlan = 0; int is_grh; - u16 vlan = 0; + u16 vlan; send_size = 0; for (i = 0; i < wr->num_sge; ++i) diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h index 6e3027387e2a..6fe79876009e 100644 --- a/drivers/infiniband/hw/nes/nes.h +++ b/drivers/infiniband/hw/nes/nes.h @@ -511,7 +511,6 @@ void nes_iwarp_ce_handler(struct nes_device *, struct nes_hw_cq *); int nes_destroy_cqp(struct nes_device *); int nes_nic_cm_xmit(struct sk_buff *, struct net_device *); void nes_recheck_link_status(struct work_struct *work); -void nes_terminate_timeout(unsigned long context); /* nes_nic.c */ struct net_device *nes_netdev_init(struct nes_device *, void __iomem *); diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index a1f74f6381ba..e74cdf9ef471 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -1150,11 +1150,9 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi neigh_release(neigh); } - if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID))) { - rcu_read_lock(); - neigh_event_send(dst_get_neighbour(&rt->dst), NULL); - rcu_read_unlock(); - } + if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID))) + neigh_event_send(rt->dst.neighbour, NULL); + ip_rt_put(rt); return rc; } diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index ba4814a21ab2..96fa9a4cafdf 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -75,6 +75,7 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, static void process_critical_error(struct nes_device *nesdev); static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number); static unsigned int nes_reset_adapter_ne020(struct nes_device *nesdev, u8 *OneG_Mode); +static void nes_terminate_timeout(unsigned long context); static void nes_terminate_start_timer(struct nes_qp *nesqp); #ifdef CONFIG_INFINIBAND_NES_DEBUG @@ -3495,7 +3496,7 @@ static void nes_terminate_received(struct nes_device *nesdev, } /* Timeout routine in case terminate fails to complete */ -void nes_terminate_timeout(unsigned long context) +static void nes_terminate_timeout(unsigned long context) { struct nes_qp *nesqp = (struct nes_qp *)(unsigned long)context; @@ -3505,7 +3506,11 @@ void nes_terminate_timeout(unsigned long context) /* Set a timer in case hw cannot complete the terminate sequence */ static void nes_terminate_start_timer(struct nes_qp *nesqp) { - mod_timer(&nesqp->terminate_timer, (jiffies + HZ)); + init_timer(&nesqp->terminate_timer); + nesqp->terminate_timer.function = nes_terminate_timeout; + nesqp->terminate_timer.expires = jiffies + HZ; + nesqp->terminate_timer.data = (unsigned long)nesqp; + add_timer(&nesqp->terminate_timer); } /** diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 59db49fbec87..95ca93ceedac 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -1414,9 +1414,6 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, } nesqp->sig_all = (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR); - init_timer(&nesqp->terminate_timer); - nesqp->terminate_timer.function = nes_terminate_timeout; - nesqp->terminate_timer.data = (unsigned long)nesqp; /* update the QP table */ nesdev->nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = nesqp; @@ -1426,6 +1423,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, return &nesqp->ibqp; } + /** * nes_clean_cq */ @@ -2570,11 +2568,6 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, return ibmr; case IWNES_MEMREG_TYPE_QP: case IWNES_MEMREG_TYPE_CQ: - if (!region->length) { - nes_debug(NES_DBG_MR, "Unable to register zero length region for CQ\n"); - ib_umem_release(region); - return ERR_PTR(-EINVAL); - } nespbl = kzalloc(sizeof(*nespbl), GFP_KERNEL); if (!nespbl) { nes_debug(NES_DBG_MR, "Unable to allocate PBL\n"); diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c index 65df26ce538a..d8ca0a0b970d 100644 --- a/drivers/infiniband/hw/qib/qib_iba6120.c +++ b/drivers/infiniband/hw/qib/qib_iba6120.c @@ -2076,11 +2076,9 @@ static void qib_6120_config_ctxts(struct qib_devdata *dd) static void qib_update_6120_usrhead(struct qib_ctxtdata *rcd, u64 hd, u32 updegr, u32 egrhd, u32 npkts) { + qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); if (updegr) qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); - mmiowb(); - qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); - mmiowb(); } static u32 qib_6120_hdrqempty(struct qib_ctxtdata *rcd) diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c index 759bb63bb3b8..c765a2eb04cf 100644 --- a/drivers/infiniband/hw/qib/qib_iba7220.c +++ b/drivers/infiniband/hw/qib/qib_iba7220.c @@ -2704,11 +2704,9 @@ static int qib_7220_set_loopback(struct qib_pportdata *ppd, const char *what) static void qib_update_7220_usrhead(struct qib_ctxtdata *rcd, u64 hd, u32 updegr, u32 egrhd, u32 npkts) { + qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); if (updegr) qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); - mmiowb(); - qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); - mmiowb(); } static u32 qib_7220_hdrqempty(struct qib_ctxtdata *rcd) diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 49e4a589479d..8ec5237031a0 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c @@ -4060,12 +4060,10 @@ static void qib_update_7322_usrhead(struct qib_ctxtdata *rcd, u64 hd, */ if (hd >> IBA7322_HDRHEAD_PKTINT_SHIFT) adjust_rcv_timeout(rcd, npkts); - if (updegr) - qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); - mmiowb(); qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); - mmiowb(); + if (updegr) + qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); } static u32 qib_7322_hdrqempty(struct qib_ctxtdata *rcd) diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 936804efb776..7b6985a2e652 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -44,7 +44,6 @@ #include #include -#include #include @@ -118,9 +117,8 @@ struct ipoib_header { u16 reserved; }; -struct ipoib_cb { - struct qdisc_skb_cb qdisc_cb; - u8 hwaddr[INFINIBAND_ALEN]; +struct ipoib_pseudoheader { + u8 hwaddr[INFINIBAND_ALEN]; }; /* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */ diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 6ea960015e0a..86addca9ddf6 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -148,7 +148,7 @@ static int ipoib_stop(struct net_device *dev) netif_stop_queue(dev); - ipoib_ib_dev_down(dev, 1); + ipoib_ib_dev_down(dev, 0); ipoib_ib_dev_stop(dev, 0); if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { @@ -555,17 +555,14 @@ static int path_rec_start(struct net_device *dev, return 0; } -/* called with rcu_read_lock */ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_path *path; struct ipoib_neigh *neigh; - struct neighbour *n; unsigned long flags; - n = dst_get_neighbour(skb_dst(skb)); - neigh = ipoib_neigh_alloc(n, skb->dev); + neigh = ipoib_neigh_alloc(skb_dst(skb)->neighbour, skb->dev); if (!neigh) { ++dev->stats.tx_dropped; dev_kfree_skb_any(skb); @@ -574,9 +571,9 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) spin_lock_irqsave(&priv->lock, flags); - path = __path_find(dev, n->ha + 4); + path = __path_find(dev, skb_dst(skb)->neighbour->ha + 4); if (!path) { - path = path_rec_create(dev, n->ha + 4); + path = path_rec_create(dev, skb_dst(skb)->neighbour->ha + 4); if (!path) goto err_path; @@ -610,7 +607,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) } } else { spin_unlock_irqrestore(&priv->lock, flags); - ipoib_send(dev, skb, path->ah, IPOIB_QPN(n->ha)); + ipoib_send(dev, skb, path->ah, IPOIB_QPN(skb_dst(skb)->neighbour->ha)); return; } } else { @@ -637,28 +634,24 @@ err_drop: spin_unlock_irqrestore(&priv->lock, flags); } -/* called with rcu_read_lock */ static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(skb->dev); - struct dst_entry *dst = skb_dst(skb); - struct neighbour *n; /* Look up path record for unicasts */ - n = dst_get_neighbour(dst); - if (n->ha[4] != 0xff) { + if (skb_dst(skb)->neighbour->ha[4] != 0xff) { neigh_add_path(skb, dev); return; } /* Add in the P_Key for multicasts */ - n->ha[8] = (priv->pkey >> 8) & 0xff; - n->ha[9] = priv->pkey & 0xff; - ipoib_mcast_send(dev, n->ha + 4, skb); + skb_dst(skb)->neighbour->ha[8] = (priv->pkey >> 8) & 0xff; + skb_dst(skb)->neighbour->ha[9] = priv->pkey & 0xff; + ipoib_mcast_send(dev, skb_dst(skb)->neighbour->ha + 4, skb); } static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, - struct ipoib_cb *cb) + struct ipoib_pseudoheader *phdr) { struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_path *path; @@ -666,15 +659,17 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, spin_lock_irqsave(&priv->lock, flags); - path = __path_find(dev, cb->hwaddr + 4); + path = __path_find(dev, phdr->hwaddr + 4); if (!path || !path->valid) { int new_path = 0; if (!path) { - path = path_rec_create(dev, cb->hwaddr + 4); + path = path_rec_create(dev, phdr->hwaddr + 4); new_path = 1; } if (path) { + /* put pseudoheader back on for next time */ + skb_push(skb, sizeof *phdr); __skb_queue_tail(&path->queue, skb); if (!path->query && path_rec_start(dev, path)) { @@ -698,10 +693,12 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, be16_to_cpu(path->pathrec.dlid)); spin_unlock_irqrestore(&priv->lock, flags); - ipoib_send(dev, skb, path->ah, IPOIB_QPN(cb->hwaddr)); + ipoib_send(dev, skb, path->ah, IPOIB_QPN(phdr->hwaddr)); return; } else if ((path->query || !path_rec_start(dev, path)) && skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) { + /* put pseudoheader back on for next time */ + skb_push(skb, sizeof *phdr); __skb_queue_tail(&path->queue, skb); } else { ++dev->stats.tx_dropped; @@ -715,23 +712,18 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_neigh *neigh; - struct neighbour *n = NULL; unsigned long flags; - rcu_read_lock(); - if (likely(skb_dst(skb))) - n = dst_get_neighbour(skb_dst(skb)); - - if (likely(n)) { - if (unlikely(!*to_ipoib_neigh(n))) { + if (likely(skb_dst(skb) && skb_dst(skb)->neighbour)) { + if (unlikely(!*to_ipoib_neigh(skb_dst(skb)->neighbour))) { ipoib_path_lookup(skb, dev); - goto unlock; + return NETDEV_TX_OK; } - neigh = *to_ipoib_neigh(n); + neigh = *to_ipoib_neigh(skb_dst(skb)->neighbour); if (unlikely((memcmp(&neigh->dgid.raw, - n->ha + 4, + skb_dst(skb)->neighbour->ha + 4, sizeof(union ib_gid))) || (neigh->dev != dev))) { spin_lock_irqsave(&priv->lock, flags); @@ -748,17 +740,17 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) ipoib_neigh_free(dev, neigh); spin_unlock_irqrestore(&priv->lock, flags); ipoib_path_lookup(skb, dev); - goto unlock; + return NETDEV_TX_OK; } if (ipoib_cm_get(neigh)) { if (ipoib_cm_up(neigh)) { ipoib_cm_send(dev, skb, ipoib_cm_get(neigh)); - goto unlock; + return NETDEV_TX_OK; } } else if (neigh->ah) { - ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(n->ha)); - goto unlock; + ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb_dst(skb)->neighbour->ha)); + return NETDEV_TX_OK; } if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) { @@ -770,14 +762,16 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) dev_kfree_skb_any(skb); } } else { - struct ipoib_cb *cb = (struct ipoib_cb *) skb->cb; + struct ipoib_pseudoheader *phdr = + (struct ipoib_pseudoheader *) skb->data; + skb_pull(skb, sizeof *phdr); - if (cb->hwaddr[4] == 0xff) { + if (phdr->hwaddr[4] == 0xff) { /* Add in the P_Key for multicast*/ - cb->hwaddr[8] = (priv->pkey >> 8) & 0xff; - cb->hwaddr[9] = priv->pkey & 0xff; + phdr->hwaddr[8] = (priv->pkey >> 8) & 0xff; + phdr->hwaddr[9] = priv->pkey & 0xff; - ipoib_mcast_send(dev, cb->hwaddr + 4, skb); + ipoib_mcast_send(dev, phdr->hwaddr + 4, skb); } else { /* unicast GID -- should be ARP or RARP reply */ @@ -786,18 +780,17 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x %pI6\n", skb_dst(skb) ? "neigh" : "dst", be16_to_cpup((__be16 *) skb->data), - IPOIB_QPN(cb->hwaddr), - cb->hwaddr + 4); + IPOIB_QPN(phdr->hwaddr), + phdr->hwaddr + 4); dev_kfree_skb_any(skb); ++dev->stats.tx_dropped; - goto unlock; + return NETDEV_TX_OK; } - unicast_arp_send(skb, dev, cb); + unicast_arp_send(skb, dev, phdr); } } -unlock: - rcu_read_unlock(); + return NETDEV_TX_OK; } @@ -826,13 +819,14 @@ static int ipoib_hard_header(struct sk_buff *skb, header->reserved = 0; /* - * If we don't have a dst_entry structure, stuff the - * destination address into skb->cb so we can figure out where - * to send the packet later. + * If we don't have a neighbour structure, stuff the + * destination address onto the front of the skb so we can + * figure out where to send the packet later. */ - if (!skb_dst(skb)) { - struct ipoib_cb *cb = (struct ipoib_cb *) skb->cb; - memcpy(cb->hwaddr, daddr, INFINIBAND_ALEN); + if ((!skb_dst(skb) || !skb_dst(skb)->neighbour) && daddr) { + struct ipoib_pseudoheader *phdr = + (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr); + memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN); } return 0; @@ -1008,7 +1002,11 @@ static void ipoib_setup(struct net_device *dev) dev->flags |= IFF_BROADCAST | IFF_MULTICAST; - dev->hard_header_len = IPOIB_ENCAP_LEN; + /* + * We add in INFINIBAND_ALEN to allow for the destination + * address "pseudoheader" for skbs without neighbour struct. + */ + dev->hard_header_len = IPOIB_ENCAP_LEN + INFINIBAND_ALEN; dev->addr_len = INFINIBAND_ALEN; dev->type = ARPHRD_INFINIBAND; dev->tx_queue_len = ipoib_sendq_size * 2; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index fc045946298e..3871ac663554 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -189,9 +189,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, mcast->mcmember = *mcmember; - /* Set the multicast MTU and cached Q_Key before we attach if it's - * the broadcast group. - */ + /* Set the cached Q_Key before we attach if it's the broadcast group */ if (!memcmp(mcast->mcmember.mgid.raw, priv->dev->broadcast + 4, sizeof (union ib_gid))) { spin_lock_irq(&priv->lock); @@ -199,17 +197,10 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, spin_unlock_irq(&priv->lock); return -EAGAIN; } - priv->mcast_mtu = IPOIB_UD_MTU(ib_mtu_enum_to_int(priv->broadcast->mcmember.mtu)); priv->qkey = be32_to_cpu(priv->broadcast->mcmember.qkey); spin_unlock_irq(&priv->lock); priv->tx_wr.wr.ud.remote_qkey = priv->qkey; set_qkey = 1; - - if (!ipoib_cm_admin_enabled(dev)) { - rtnl_lock(); - dev_set_mtu(dev, min(priv->mcast_mtu, priv->admin_mtu)); - rtnl_unlock(); - } } if (!test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) { @@ -267,14 +258,17 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, netif_tx_lock_bh(dev); while (!skb_queue_empty(&mcast->pkt_queue)) { struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue); - netif_tx_unlock_bh(dev); skb->dev = dev; + if (!skb_dst(skb) || !skb_dst(skb)->neighbour) { + /* put pseudoheader back on for next time */ + skb_push(skb, sizeof (struct ipoib_pseudoheader)); + } + if (dev_queue_xmit(skb)) ipoib_warn(priv, "dev_queue_xmit failed to requeue packet\n"); - netif_tx_lock_bh(dev); } netif_tx_unlock_bh(dev); @@ -595,6 +589,14 @@ void ipoib_mcast_join_task(struct work_struct *work) return; } + priv->mcast_mtu = IPOIB_UD_MTU(ib_mtu_enum_to_int(priv->broadcast->mcmember.mtu)); + + if (!ipoib_cm_admin_enabled(dev)) { + rtnl_lock(); + dev_set_mtu(dev, min(priv->mcast_mtu, priv->admin_mtu)); + rtnl_unlock(); + } + ipoib_dbg_mcast(priv, "successfully joined all multicast groups\n"); clear_bit(IPOIB_MCAST_RUN, &priv->flags); @@ -713,15 +715,11 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb) out: if (mcast && mcast->ah) { - struct dst_entry *dst = skb_dst(skb); - struct neighbour *n = NULL; - - rcu_read_lock(); - if (dst) - n = dst_get_neighbour(dst); - if (n && !*to_ipoib_neigh(n)) { - struct ipoib_neigh *neigh = ipoib_neigh_alloc(n, - skb->dev); + if (skb_dst(skb) && + skb_dst(skb)->neighbour && + !*to_ipoib_neigh(skb_dst(skb)->neighbour)) { + struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb_dst(skb)->neighbour, + skb->dev); if (neigh) { kref_get(&mcast->ah->ref); @@ -729,7 +727,7 @@ out: list_add_tail(&neigh->list, &mcast->neigh_list); } } - rcu_read_unlock(); + spin_unlock_irqrestore(&priv->lock, flags); ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN); return; diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index f8f57583f5d0..8db008de5392 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -354,9 +354,6 @@ iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session, } ib_conn = ep->dd_data; - if (iser_alloc_rx_descriptors(ib_conn)) - return -ENOMEM; - /* binds the iSER connection retrieved from the previously * connected ep_handle to the iSCSI layer connection. exchanges * connection pointers */ @@ -391,6 +388,19 @@ iscsi_iser_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) iser_conn->ib_conn = NULL; } +static int +iscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn) +{ + struct iscsi_conn *conn = cls_conn->dd_data; + int err; + + err = iser_conn_set_full_featured_mode(conn); + if (err) + return err; + + return iscsi_conn_start(cls_conn); +} + static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session) { struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); @@ -676,7 +686,7 @@ static struct iscsi_transport iscsi_iser_transport = { .get_conn_param = iscsi_conn_get_param, .get_ep_param = iscsi_iser_get_ep_param, .get_session_param = iscsi_session_get_param, - .start_conn = iscsi_conn_start, + .start_conn = iscsi_iser_conn_start, .stop_conn = iscsi_iser_conn_stop, /* iscsi host params */ .get_host_param = iscsi_host_get_param, diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index 634aef039fe2..2f02ab0ccc1e 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h @@ -365,5 +365,4 @@ int iser_dma_map_task_data(struct iscsi_iser_task *iser_task, void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task); int iser_initialize_task_headers(struct iscsi_task *task, struct iser_tx_desc *tx_desc); -int iser_alloc_rx_descriptors(struct iser_conn *ib_conn); #endif diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c index eb1ee6f8d894..95a08a8ca8aa 100644 --- a/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/drivers/infiniband/ulp/iser/iser_initiator.c @@ -170,7 +170,7 @@ static void iser_create_send_desc(struct iser_conn *ib_conn, } -int iser_alloc_rx_descriptors(struct iser_conn *ib_conn) +static int iser_alloc_rx_descriptors(struct iser_conn *ib_conn) { int i, j; u64 dma_addr; @@ -236,24 +236,23 @@ void iser_free_rx_descriptors(struct iser_conn *ib_conn) kfree(ib_conn->rx_descs); } -static int iser_post_rx_bufs(struct iscsi_conn *conn, struct iscsi_hdr *req) +/** + * iser_conn_set_full_featured_mode - (iSER API) + */ +int iser_conn_set_full_featured_mode(struct iscsi_conn *conn) { struct iscsi_iser_conn *iser_conn = conn->dd_data; - iser_dbg("req op %x flags %x\n", req->opcode, req->flags); - /* check if this is the last login - going to full feature phase */ - if ((req->flags & ISCSI_FULL_FEATURE_PHASE) != ISCSI_FULL_FEATURE_PHASE) - return 0; + iser_dbg("Initially post: %d\n", ISER_MIN_POSTED_RX); - /* - * Check that there is one posted recv buffer (for the last login - * response) and no posted send buffers left - they must have been - * consumed during previous login phases. - */ - WARN_ON(iser_conn->ib_conn->post_recv_buf_count != 1); - WARN_ON(atomic_read(&iser_conn->ib_conn->post_send_buf_count) != 0); + /* Check that there is no posted recv or send buffers left - */ + /* they must be consumed during the login phase */ + BUG_ON(iser_conn->ib_conn->post_recv_buf_count != 0); + BUG_ON(atomic_read(&iser_conn->ib_conn->post_send_buf_count) != 0); + + if (iser_alloc_rx_descriptors(iser_conn->ib_conn)) + return -ENOMEM; - iser_dbg("Initially post: %d\n", ISER_MIN_POSTED_RX); /* Initial post receive buffers */ if (iser_post_recvm(iser_conn->ib_conn, ISER_MIN_POSTED_RX)) return -ENOMEM; @@ -422,9 +421,6 @@ int iser_send_control(struct iscsi_conn *conn, err = iser_post_recvl(iser_conn->ib_conn); if (err) goto send_control_error; - err = iser_post_rx_bufs(conn, task->hdr); - if (err) - goto send_control_error; } err = iser_post_send(iser_conn->ib_conn, mdesc); diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index aa5eafa194ab..ee165fdcb596 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -568,62 +568,24 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd, scmnd->sc_data_direction); } -/** - * srp_claim_req - Take ownership of the scmnd associated with a request. - * @target: SRP target port. - * @req: SRP request. - * @scmnd: If NULL, take ownership of @req->scmnd. If not NULL, only take - * ownership of @req->scmnd if it equals @scmnd. - * - * Return value: - * Either NULL or a pointer to the SCSI command the caller became owner of. - */ -static struct scsi_cmnd *srp_claim_req(struct srp_target_port *target, - struct srp_request *req, - struct scsi_cmnd *scmnd) +static void srp_remove_req(struct srp_target_port *target, + struct srp_request *req, s32 req_lim_delta) { unsigned long flags; - spin_lock_irqsave(&target->lock, flags); - if (!scmnd) { - scmnd = req->scmnd; - req->scmnd = NULL; - } else if (req->scmnd == scmnd) { - req->scmnd = NULL; - } else { - scmnd = NULL; - } - spin_unlock_irqrestore(&target->lock, flags); - - return scmnd; -} - -/** - * srp_free_req() - Unmap data and add request to the free request list. - */ -static void srp_free_req(struct srp_target_port *target, - struct srp_request *req, struct scsi_cmnd *scmnd, - s32 req_lim_delta) -{ - unsigned long flags; - - srp_unmap_data(scmnd, target, req); - + srp_unmap_data(req->scmnd, target, req); spin_lock_irqsave(&target->lock, flags); target->req_lim += req_lim_delta; + req->scmnd = NULL; list_add_tail(&req->list, &target->free_reqs); spin_unlock_irqrestore(&target->lock, flags); } static void srp_reset_req(struct srp_target_port *target, struct srp_request *req) { - struct scsi_cmnd *scmnd = srp_claim_req(target, req, NULL); - - if (scmnd) { - srp_free_req(target, req, scmnd, 0); - scmnd->result = DID_RESET << 16; - scmnd->scsi_done(scmnd); - } + req->scmnd->result = DID_RESET << 16; + req->scmnd->scsi_done(req->scmnd); + srp_remove_req(target, req, 0); } static int srp_reconnect_target(struct srp_target_port *target) @@ -1093,18 +1055,11 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) complete(&target->tsk_mgmt_done); } else { req = &target->req_ring[rsp->tag]; - scmnd = srp_claim_req(target, req, NULL); - if (!scmnd) { + scmnd = req->scmnd; + if (!scmnd) shost_printk(KERN_ERR, target->scsi_host, "Null scmnd for RSP w/tag %016llx\n", (unsigned long long) rsp->tag); - - spin_lock_irqsave(&target->lock, flags); - target->req_lim += be32_to_cpu(rsp->req_lim_delta); - spin_unlock_irqrestore(&target->lock, flags); - - return; - } scmnd->result = rsp->status; if (rsp->flags & SRP_RSP_FLAG_SNSVALID) { @@ -1119,9 +1074,7 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER)) scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt)); - srp_free_req(target, req, scmnd, - be32_to_cpu(rsp->req_lim_delta)); - + srp_remove_req(target, req, be32_to_cpu(rsp->req_lim_delta)); scmnd->host_scribble = NULL; scmnd->scsi_done(scmnd); } @@ -1660,18 +1613,25 @@ static int srp_abort(struct scsi_cmnd *scmnd) { struct srp_target_port *target = host_to_target(scmnd->device->host); struct srp_request *req = (struct srp_request *) scmnd->host_scribble; + int ret = SUCCESS; shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); - if (!req || target->qp_in_error || !srp_claim_req(target, req, scmnd)) + if (!req || target->qp_in_error) + return FAILED; + if (srp_send_tsk_mgmt(target, req->index, scmnd->device->lun, + SRP_TSK_ABORT_TASK)) return FAILED; - srp_send_tsk_mgmt(target, req->index, scmnd->device->lun, - SRP_TSK_ABORT_TASK); - srp_free_req(target, req, scmnd, 0); - scmnd->result = DID_ABORT << 16; - scmnd->scsi_done(scmnd); - return SUCCESS; + if (req->scmnd) { + if (!target->tsk_mgmt_status) { + srp_remove_req(target, req, 0); + scmnd->result = DID_ABORT << 16; + } else + ret = FAILED; + } + + return ret; } static int srp_reset_device(struct scsi_cmnd *scmnd) @@ -2167,8 +2127,6 @@ static ssize_t srp_create_target(struct device *dev, return -ENOMEM; target_host->transportt = ib_srp_transport_template; - target_host->max_channel = 0; - target_host->max_id = 1; target_host->max_lun = SRP_MAX_LUN; target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb; diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index c0e639c1b179..23e82e46656d 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -161,15 +161,6 @@ config INPUT_APMPOWER To compile this driver as a module, choose M here: the module will be called apm-power. -config INPUT_KEYRESET - tristate "Reset key" - depends on INPUT - ---help--- - Say Y here if you want to reboot when some keys are pressed; - - To compile this driver as a module, choose M here: the - module will be called keyreset. - comment "Input Device Drivers" source "drivers/input/keyboard/Kconfig" diff --git a/drivers/input/Makefile b/drivers/input/Makefile index 5d4593d3101d..0c789490e0b3 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -24,4 +24,3 @@ obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/ obj-$(CONFIG_INPUT_MISC) += misc/ obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o -obj-$(CONFIG_INPUT_KEYRESET) += keyreset.o diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 6288d7d84fa7..4cf25347b015 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -23,7 +23,6 @@ #include #include #include -#include #include "input-compat.h" struct evdev { @@ -44,9 +43,6 @@ struct evdev_client { unsigned int tail; unsigned int packet_head; /* [future] position of the first element of next packet */ spinlock_t buffer_lock; /* protects access to buffer, head and tail */ - struct wake_lock wake_lock; - bool use_wake_lock; - char name[28]; struct fasync_struct *fasync; struct evdev *evdev; struct list_head node; @@ -79,14 +75,10 @@ static void evdev_pass_event(struct evdev_client *client, client->buffer[client->tail].value = 0; client->packet_head = client->tail; - if (client->use_wake_lock) - wake_unlock(&client->wake_lock); } if (event->type == EV_SYN && event->code == SYN_REPORT) { client->packet_head = client->head; - if (client->use_wake_lock) - wake_lock(&client->wake_lock); kill_fasync(&client->fasync, SIGIO, POLL_IN); } @@ -102,11 +94,8 @@ static void evdev_event(struct input_handle *handle, struct evdev *evdev = handle->private; struct evdev_client *client; struct input_event event; - struct timespec ts; - ktime_get_ts(&ts); - event.time.tv_sec = ts.tv_sec; - event.time.tv_usec = ts.tv_nsec / NSEC_PER_USEC; + do_gettimeofday(&event.time); event.type = type; event.code = code; event.value = value; @@ -266,8 +255,6 @@ static int evdev_release(struct inode *inode, struct file *file) mutex_unlock(&evdev->mutex); evdev_detach_client(evdev, client); - if (client->use_wake_lock) - wake_lock_destroy(&client->wake_lock); kfree(client); evdev_close_device(evdev); @@ -319,8 +306,6 @@ static int evdev_open(struct inode *inode, struct file *file) client->bufsize = bufsize; spin_lock_init(&client->buffer_lock); - snprintf(client->name, sizeof(client->name), "%s-%d", - dev_name(&evdev->dev), task_tgid_vnr(current)); client->evdev = evdev; evdev_attach_client(evdev, client); @@ -384,13 +369,10 @@ static int evdev_fetch_next_event(struct evdev_client *client, spin_lock_irq(&client->buffer_lock); - have_event = client->packet_head != client->tail; + have_event = client->head != client->tail; if (have_event) { *event = client->buffer[client->tail++]; client->tail &= client->bufsize - 1; - if (client->use_wake_lock && - client->packet_head == client->tail) - wake_unlock(&client->wake_lock); } spin_unlock_irq(&client->buffer_lock); @@ -404,17 +386,19 @@ static ssize_t evdev_read(struct file *file, char __user *buffer, struct evdev_client *client = file->private_data; struct evdev *evdev = client->evdev; struct input_event event; - int retval = 0; + int retval; if (count < input_event_size()) return -EINVAL; - if (!(file->f_flags & O_NONBLOCK)) { - retval = wait_event_interruptible(evdev->wait, - client->packet_head != client->tail || !evdev->exist); - if (retval) - return retval; - } + if (client->packet_head == client->tail && evdev->exist && + (file->f_flags & O_NONBLOCK)) + return -EAGAIN; + + retval = wait_event_interruptible(evdev->wait, + client->packet_head != client->tail || !evdev->exist); + if (retval) + return retval; if (!evdev->exist) return -ENODEV; @@ -428,8 +412,6 @@ static ssize_t evdev_read(struct file *file, char __user *buffer, retval += input_event_size(); } - if (retval == 0 && file->f_flags & O_NONBLOCK) - retval = -EAGAIN; return retval; } @@ -639,35 +621,6 @@ static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p) return input_set_keycode(dev, &ke); } -static int evdev_enable_suspend_block(struct evdev *evdev, - struct evdev_client *client) -{ - if (client->use_wake_lock) - return 0; - - spin_lock_irq(&client->buffer_lock); - wake_lock_init(&client->wake_lock, WAKE_LOCK_SUSPEND, client->name); - client->use_wake_lock = true; - if (client->packet_head != client->tail) - wake_lock(&client->wake_lock); - spin_unlock_irq(&client->buffer_lock); - return 0; -} - -static int evdev_disable_suspend_block(struct evdev *evdev, - struct evdev_client *client) -{ - if (!client->use_wake_lock) - return 0; - - spin_lock_irq(&client->buffer_lock); - client->use_wake_lock = false; - wake_lock_destroy(&client->wake_lock); - spin_unlock_irq(&client->buffer_lock); - - return 0; -} - static long evdev_do_ioctl(struct file *file, unsigned int cmd, void __user *p, int compat_mode) { @@ -741,15 +694,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, case EVIOCSKEYCODE_V2: return evdev_handle_set_keycode_v2(dev, p); - - case EVIOCGSUSPENDBLOCK: - return put_user(client->use_wake_lock, ip); - - case EVIOCSSUSPENDBLOCK: - if (p) - return evdev_enable_suspend_block(evdev, client); - else - return evdev_disable_suspend_block(evdev, client); } size = _IOC_SIZE(cmd); diff --git a/drivers/input/joystick/walkera0701.c b/drivers/input/joystick/walkera0701.c index f8f892b076e8..4dfa1eed4b7c 100644 --- a/drivers/input/joystick/walkera0701.c +++ b/drivers/input/joystick/walkera0701.c @@ -196,7 +196,6 @@ static void walkera0701_close(struct input_dev *dev) struct walkera_dev *w = input_get_drvdata(dev); parport_disable_irq(w->parport); - hrtimer_cancel(&w->timer); } static int walkera0701_connect(struct walkera_dev *w, int parport) @@ -225,9 +224,6 @@ static int walkera0701_connect(struct walkera_dev *w, int parport) if (parport_claim(w->pardevice)) goto init_err1; - hrtimer_init(&w->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - w->timer.function = timer_handler; - w->input_dev = input_allocate_device(); if (!w->input_dev) goto init_err2; @@ -258,6 +254,8 @@ static int walkera0701_connect(struct walkera_dev *w, int parport) if (err) goto init_err3; + hrtimer_init(&w->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + w->timer.function = timer_handler; return 0; init_err3: @@ -273,6 +271,7 @@ static int walkera0701_connect(struct walkera_dev *w, int parport) static void walkera0701_disconnect(struct walkera_dev *w) { + hrtimer_cancel(&w->timer); input_unregister_device(w->input_dev); parport_release(w->pardevice); parport_unregister_device(w->pardevice); diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 92c7be14bd4a..56abf3d0e911 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -142,7 +142,6 @@ static const struct xpad_device { { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", 0, XTYPE_XBOX }, { 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX }, - { 0x0d2f, 0x0002, "Andamiro Pump It Up pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX }, { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX }, { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", 0, XTYPE_XBOX }, diff --git a/drivers/input/keyreset.c b/drivers/input/keyreset.c deleted file mode 100644 index 36208fe0baae..000000000000 --- a/drivers/input/keyreset.c +++ /dev/null @@ -1,239 +0,0 @@ -/* drivers/input/keyreset.c - * - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -struct keyreset_state { - struct input_handler input_handler; - unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; - unsigned long upbit[BITS_TO_LONGS(KEY_CNT)]; - unsigned long key[BITS_TO_LONGS(KEY_CNT)]; - spinlock_t lock; - int key_down_target; - int key_down; - int key_up; - int restart_disabled; - int (*reset_fn)(void); -}; - -int restart_requested; -static void deferred_restart(struct work_struct *dummy) -{ - restart_requested = 2; - sys_sync(); - restart_requested = 3; - kernel_restart(NULL); -} -static DECLARE_WORK(restart_work, deferred_restart); - -static void keyreset_event(struct input_handle *handle, unsigned int type, - unsigned int code, int value) -{ - unsigned long flags; - struct keyreset_state *state = handle->private; - - if (type != EV_KEY) - return; - - if (code >= KEY_MAX) - return; - - if (!test_bit(code, state->keybit)) - return; - - spin_lock_irqsave(&state->lock, flags); - if (!test_bit(code, state->key) == !value) - goto done; - __change_bit(code, state->key); - if (test_bit(code, state->upbit)) { - if (value) { - state->restart_disabled = 1; - state->key_up++; - } else - state->key_up--; - } else { - if (value) - state->key_down++; - else - state->key_down--; - } - if (state->key_down == 0 && state->key_up == 0) - state->restart_disabled = 0; - - pr_debug("reset key changed %d %d new state %d-%d-%d\n", code, value, - state->key_down, state->key_up, state->restart_disabled); - - if (value && !state->restart_disabled && - state->key_down == state->key_down_target) { - state->restart_disabled = 1; - if (restart_requested) - panic("keyboard reset failed, %d", restart_requested); - if (state->reset_fn) { - restart_requested = state->reset_fn(); - } else { - pr_info("keyboard reset\n"); - schedule_work(&restart_work); - restart_requested = 1; - } - } -done: - spin_unlock_irqrestore(&state->lock, flags); -} - -static int keyreset_connect(struct input_handler *handler, - struct input_dev *dev, - const struct input_device_id *id) -{ - int i; - int ret; - struct input_handle *handle; - struct keyreset_state *state = - container_of(handler, struct keyreset_state, input_handler); - - for (i = 0; i < KEY_MAX; i++) { - if (test_bit(i, state->keybit) && test_bit(i, dev->keybit)) - break; - } - if (i == KEY_MAX) - return -ENODEV; - - handle = kzalloc(sizeof(*handle), GFP_KERNEL); - if (!handle) - return -ENOMEM; - - handle->dev = dev; - handle->handler = handler; - handle->name = "keyreset"; - handle->private = state; - - ret = input_register_handle(handle); - if (ret) - goto err_input_register_handle; - - ret = input_open_device(handle); - if (ret) - goto err_input_open_device; - - pr_info("using input dev %s for key reset\n", dev->name); - - return 0; - -err_input_open_device: - input_unregister_handle(handle); -err_input_register_handle: - kfree(handle); - return ret; -} - -static void keyreset_disconnect(struct input_handle *handle) -{ - input_close_device(handle); - input_unregister_handle(handle); - kfree(handle); -} - -static const struct input_device_id keyreset_ids[] = { - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT, - .evbit = { BIT_MASK(EV_KEY) }, - }, - { }, -}; -MODULE_DEVICE_TABLE(input, keyreset_ids); - -static int keyreset_probe(struct platform_device *pdev) -{ - int ret; - int key, *keyp; - struct keyreset_state *state; - struct keyreset_platform_data *pdata = pdev->dev.platform_data; - - if (!pdata) - return -EINVAL; - - state = kzalloc(sizeof(*state), GFP_KERNEL); - if (!state) - return -ENOMEM; - - spin_lock_init(&state->lock); - keyp = pdata->keys_down; - while ((key = *keyp++)) { - if (key >= KEY_MAX) - continue; - state->key_down_target++; - __set_bit(key, state->keybit); - } - if (pdata->keys_up) { - keyp = pdata->keys_up; - while ((key = *keyp++)) { - if (key >= KEY_MAX) - continue; - __set_bit(key, state->keybit); - __set_bit(key, state->upbit); - } - } - - if (pdata->reset_fn) - state->reset_fn = pdata->reset_fn; - - state->input_handler.event = keyreset_event; - state->input_handler.connect = keyreset_connect; - state->input_handler.disconnect = keyreset_disconnect; - state->input_handler.name = KEYRESET_NAME; - state->input_handler.id_table = keyreset_ids; - ret = input_register_handler(&state->input_handler); - if (ret) { - kfree(state); - return ret; - } - platform_set_drvdata(pdev, state); - return 0; -} - -int keyreset_remove(struct platform_device *pdev) -{ - struct keyreset_state *state = platform_get_drvdata(pdev); - input_unregister_handler(&state->input_handler); - kfree(state); - return 0; -} - - -struct platform_driver keyreset_driver = { - .driver.name = KEYRESET_NAME, - .probe = keyreset_probe, - .remove = keyreset_remove, -}; - -static int __init keyreset_init(void) -{ - return platform_driver_register(&keyreset_driver); -} - -static void __exit keyreset_exit(void) -{ - return platform_driver_unregister(&keyreset_driver); -} - -module_init(keyreset_init); -module_exit(keyreset_exit); diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 6f4ad1a7c3ee..45dc6aa62ba4 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -193,17 +193,6 @@ config INPUT_ATI_REMOTE2 To compile this driver as a module, choose M here: the module will be called ati_remote2. -config INPUT_KEYCHORD - tristate "Key chord input driver support" - help - Say Y here if you want to enable the key chord driver - accessible at /dev/keychord. This driver can be used - for receiving notifications when client specified key - combinations are pressed. - - To compile this driver as a module, choose M here: the - module will be called keychord. - config INPUT_KEYSPAN_REMOTE tristate "Keyspan DMR USB remote control (EXPERIMENTAL)" depends on EXPERIMENTAL @@ -305,11 +294,6 @@ config INPUT_SGI_BTNS To compile this driver as a module, choose M here: the module will be called sgi_btns. -config INPUT_GPIO - tristate "GPIO driver support" - help - Say Y here if you want to support gpio based keys, wheels etc... - config HP_SDC_RTC tristate "HP SDC Real Time Clock" depends on (GSC || HP300) && SERIO diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index eb73834150b7..38efb2cb182b 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -22,10 +22,8 @@ obj-$(CONFIG_INPUT_CMA3000) += cma3000_d0x.o obj-$(CONFIG_INPUT_CMA3000_I2C) += cma3000_d0x_i2c.o obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o -obj-$(CONFIG_INPUT_GPIO) += gpio_event.o gpio_matrix.o gpio_input.o gpio_output.o gpio_axis.o obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o -obj-$(CONFIG_INPUT_KEYCHORD) += keychord.o obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o diff --git a/drivers/input/misc/gpio_axis.c b/drivers/input/misc/gpio_axis.c deleted file mode 100644 index 0acf4a576f53..000000000000 --- a/drivers/input/misc/gpio_axis.c +++ /dev/null @@ -1,192 +0,0 @@ -/* drivers/input/misc/gpio_axis.c - * - * Copyright (C) 2007 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include - -struct gpio_axis_state { - struct gpio_event_input_devs *input_devs; - struct gpio_event_axis_info *info; - uint32_t pos; -}; - -uint16_t gpio_axis_4bit_gray_map_table[] = { - [0x0] = 0x0, [0x1] = 0x1, /* 0000 0001 */ - [0x3] = 0x2, [0x2] = 0x3, /* 0011 0010 */ - [0x6] = 0x4, [0x7] = 0x5, /* 0110 0111 */ - [0x5] = 0x6, [0x4] = 0x7, /* 0101 0100 */ - [0xc] = 0x8, [0xd] = 0x9, /* 1100 1101 */ - [0xf] = 0xa, [0xe] = 0xb, /* 1111 1110 */ - [0xa] = 0xc, [0xb] = 0xd, /* 1010 1011 */ - [0x9] = 0xe, [0x8] = 0xf, /* 1001 1000 */ -}; -uint16_t gpio_axis_4bit_gray_map(struct gpio_event_axis_info *info, uint16_t in) -{ - return gpio_axis_4bit_gray_map_table[in]; -} - -uint16_t gpio_axis_5bit_singletrack_map_table[] = { - [0x10] = 0x00, [0x14] = 0x01, [0x1c] = 0x02, /* 10000 10100 11100 */ - [0x1e] = 0x03, [0x1a] = 0x04, [0x18] = 0x05, /* 11110 11010 11000 */ - [0x08] = 0x06, [0x0a] = 0x07, [0x0e] = 0x08, /* 01000 01010 01110 */ - [0x0f] = 0x09, [0x0d] = 0x0a, [0x0c] = 0x0b, /* 01111 01101 01100 */ - [0x04] = 0x0c, [0x05] = 0x0d, [0x07] = 0x0e, /* 00100 00101 00111 */ - [0x17] = 0x0f, [0x16] = 0x10, [0x06] = 0x11, /* 10111 10110 00110 */ - [0x02] = 0x12, [0x12] = 0x13, [0x13] = 0x14, /* 00010 10010 10011 */ - [0x1b] = 0x15, [0x0b] = 0x16, [0x03] = 0x17, /* 11011 01011 00011 */ - [0x01] = 0x18, [0x09] = 0x19, [0x19] = 0x1a, /* 00001 01001 11001 */ - [0x1d] = 0x1b, [0x15] = 0x1c, [0x11] = 0x1d, /* 11101 10101 10001 */ -}; -uint16_t gpio_axis_5bit_singletrack_map( - struct gpio_event_axis_info *info, uint16_t in) -{ - return gpio_axis_5bit_singletrack_map_table[in]; -} - -static void gpio_event_update_axis(struct gpio_axis_state *as, int report) -{ - struct gpio_event_axis_info *ai = as->info; - int i; - int change; - uint16_t state = 0; - uint16_t pos; - uint16_t old_pos = as->pos; - for (i = ai->count - 1; i >= 0; i--) - state = (state << 1) | gpio_get_value(ai->gpio[i]); - pos = ai->map(ai, state); - if (ai->flags & GPIOEAF_PRINT_RAW) - pr_info("axis %d-%d raw %x, pos %d -> %d\n", - ai->type, ai->code, state, old_pos, pos); - if (report && pos != old_pos) { - if (ai->type == EV_REL) { - change = (ai->decoded_size + pos - old_pos) % - ai->decoded_size; - if (change > ai->decoded_size / 2) - change -= ai->decoded_size; - if (change == ai->decoded_size / 2) { - if (ai->flags & GPIOEAF_PRINT_EVENT) - pr_info("axis %d-%d unknown direction, " - "pos %d -> %d\n", ai->type, - ai->code, old_pos, pos); - change = 0; /* no closest direction */ - } - if (ai->flags & GPIOEAF_PRINT_EVENT) - pr_info("axis %d-%d change %d\n", - ai->type, ai->code, change); - input_report_rel(as->input_devs->dev[ai->dev], - ai->code, change); - } else { - if (ai->flags & GPIOEAF_PRINT_EVENT) - pr_info("axis %d-%d now %d\n", - ai->type, ai->code, pos); - input_event(as->input_devs->dev[ai->dev], - ai->type, ai->code, pos); - } - input_sync(as->input_devs->dev[ai->dev]); - } - as->pos = pos; -} - -static irqreturn_t gpio_axis_irq_handler(int irq, void *dev_id) -{ - struct gpio_axis_state *as = dev_id; - gpio_event_update_axis(as, 1); - return IRQ_HANDLED; -} - -int gpio_event_axis_func(struct gpio_event_input_devs *input_devs, - struct gpio_event_info *info, void **data, int func) -{ - int ret; - int i; - int irq; - struct gpio_event_axis_info *ai; - struct gpio_axis_state *as; - - ai = container_of(info, struct gpio_event_axis_info, info); - if (func == GPIO_EVENT_FUNC_SUSPEND) { - for (i = 0; i < ai->count; i++) - disable_irq(gpio_to_irq(ai->gpio[i])); - return 0; - } - if (func == GPIO_EVENT_FUNC_RESUME) { - for (i = 0; i < ai->count; i++) - enable_irq(gpio_to_irq(ai->gpio[i])); - return 0; - } - - if (func == GPIO_EVENT_FUNC_INIT) { - *data = as = kmalloc(sizeof(*as), GFP_KERNEL); - if (as == NULL) { - ret = -ENOMEM; - goto err_alloc_axis_state_failed; - } - as->input_devs = input_devs; - as->info = ai; - if (ai->dev >= input_devs->count) { - pr_err("gpio_event_axis: bad device index %d >= %d " - "for %d:%d\n", ai->dev, input_devs->count, - ai->type, ai->code); - ret = -EINVAL; - goto err_bad_device_index; - } - - input_set_capability(input_devs->dev[ai->dev], - ai->type, ai->code); - if (ai->type == EV_ABS) { - input_set_abs_params(input_devs->dev[ai->dev], ai->code, - 0, ai->decoded_size - 1, 0, 0); - } - for (i = 0; i < ai->count; i++) { - ret = gpio_request(ai->gpio[i], "gpio_event_axis"); - if (ret < 0) - goto err_request_gpio_failed; - ret = gpio_direction_input(ai->gpio[i]); - if (ret < 0) - goto err_gpio_direction_input_failed; - ret = irq = gpio_to_irq(ai->gpio[i]); - if (ret < 0) - goto err_get_irq_num_failed; - ret = request_irq(irq, gpio_axis_irq_handler, - IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING, - "gpio_event_axis", as); - if (ret < 0) - goto err_request_irq_failed; - } - gpio_event_update_axis(as, 0); - return 0; - } - - ret = 0; - as = *data; - for (i = ai->count - 1; i >= 0; i--) { - free_irq(gpio_to_irq(ai->gpio[i]), as); -err_request_irq_failed: -err_get_irq_num_failed: -err_gpio_direction_input_failed: - gpio_free(ai->gpio[i]); -err_request_gpio_failed: - ; - } -err_bad_device_index: - kfree(as); - *data = NULL; -err_alloc_axis_state_failed: - return ret; -} diff --git a/drivers/input/misc/gpio_event.c b/drivers/input/misc/gpio_event.c deleted file mode 100644 index a98be67d1ab0..000000000000 --- a/drivers/input/misc/gpio_event.c +++ /dev/null @@ -1,260 +0,0 @@ -/* drivers/input/misc/gpio_event.c - * - * Copyright (C) 2007 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -struct gpio_event { - struct gpio_event_input_devs *input_devs; - const struct gpio_event_platform_data *info; - struct early_suspend early_suspend; - void *state[0]; -}; - -static int gpio_input_event( - struct input_dev *dev, unsigned int type, unsigned int code, int value) -{ - int i; - int devnr; - int ret = 0; - int tmp_ret; - struct gpio_event_info **ii; - struct gpio_event *ip = input_get_drvdata(dev); - - for (devnr = 0; devnr < ip->input_devs->count; devnr++) - if (ip->input_devs->dev[devnr] == dev) - break; - if (devnr == ip->input_devs->count) { - pr_err("gpio_input_event: unknown device %p\n", dev); - return -EIO; - } - - for (i = 0, ii = ip->info->info; i < ip->info->info_count; i++, ii++) { - if ((*ii)->event) { - tmp_ret = (*ii)->event(ip->input_devs, *ii, - &ip->state[i], - devnr, type, code, value); - if (tmp_ret) - ret = tmp_ret; - } - } - return ret; -} - -static int gpio_event_call_all_func(struct gpio_event *ip, int func) -{ - int i; - int ret; - struct gpio_event_info **ii; - - if (func == GPIO_EVENT_FUNC_INIT || func == GPIO_EVENT_FUNC_RESUME) { - ii = ip->info->info; - for (i = 0; i < ip->info->info_count; i++, ii++) { - if ((*ii)->func == NULL) { - ret = -ENODEV; - pr_err("gpio_event_probe: Incomplete pdata, " - "no function\n"); - goto err_no_func; - } - if (func == GPIO_EVENT_FUNC_RESUME && (*ii)->no_suspend) - continue; - ret = (*ii)->func(ip->input_devs, *ii, &ip->state[i], - func); - if (ret) { - pr_err("gpio_event_probe: function failed\n"); - goto err_func_failed; - } - } - return 0; - } - - ret = 0; - i = ip->info->info_count; - ii = ip->info->info + i; - while (i > 0) { - i--; - ii--; - if ((func & ~1) == GPIO_EVENT_FUNC_SUSPEND && (*ii)->no_suspend) - continue; - (*ii)->func(ip->input_devs, *ii, &ip->state[i], func & ~1); -err_func_failed: -err_no_func: - ; - } - return ret; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -void gpio_event_suspend(struct early_suspend *h) -{ - struct gpio_event *ip; - ip = container_of(h, struct gpio_event, early_suspend); - gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_SUSPEND); - ip->info->power(ip->info, 0); -} - -void gpio_event_resume(struct early_suspend *h) -{ - struct gpio_event *ip; - ip = container_of(h, struct gpio_event, early_suspend); - ip->info->power(ip->info, 1); - gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_RESUME); -} -#endif - -static int gpio_event_probe(struct platform_device *pdev) -{ - int err; - struct gpio_event *ip; - struct gpio_event_platform_data *event_info; - int dev_count = 1; - int i; - int registered = 0; - - event_info = pdev->dev.platform_data; - if (event_info == NULL) { - pr_err("gpio_event_probe: No pdata\n"); - return -ENODEV; - } - if ((!event_info->name && !event_info->names[0]) || - !event_info->info || !event_info->info_count) { - pr_err("gpio_event_probe: Incomplete pdata\n"); - return -ENODEV; - } - if (!event_info->name) - while (event_info->names[dev_count]) - dev_count++; - ip = kzalloc(sizeof(*ip) + - sizeof(ip->state[0]) * event_info->info_count + - sizeof(*ip->input_devs) + - sizeof(ip->input_devs->dev[0]) * dev_count, GFP_KERNEL); - if (ip == NULL) { - err = -ENOMEM; - pr_err("gpio_event_probe: Failed to allocate private data\n"); - goto err_kp_alloc_failed; - } - ip->input_devs = (void*)&ip->state[event_info->info_count]; - platform_set_drvdata(pdev, ip); - - for (i = 0; i < dev_count; i++) { - struct input_dev *input_dev = input_allocate_device(); - if (input_dev == NULL) { - err = -ENOMEM; - pr_err("gpio_event_probe: " - "Failed to allocate input device\n"); - goto err_input_dev_alloc_failed; - } - input_set_drvdata(input_dev, ip); - input_dev->name = event_info->name ? - event_info->name : event_info->names[i]; - input_dev->event = gpio_input_event; - ip->input_devs->dev[i] = input_dev; - } - ip->input_devs->count = dev_count; - ip->info = event_info; - if (event_info->power) { -#ifdef CONFIG_HAS_EARLYSUSPEND - ip->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; - ip->early_suspend.suspend = gpio_event_suspend; - ip->early_suspend.resume = gpio_event_resume; - register_early_suspend(&ip->early_suspend); -#endif - ip->info->power(ip->info, 1); - } - - err = gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_INIT); - if (err) - goto err_call_all_func_failed; - - for (i = 0; i < dev_count; i++) { - err = input_register_device(ip->input_devs->dev[i]); - if (err) { - pr_err("gpio_event_probe: Unable to register %s " - "input device\n", ip->input_devs->dev[i]->name); - goto err_input_register_device_failed; - } - registered++; - } - - return 0; - -err_input_register_device_failed: - gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT); -err_call_all_func_failed: - if (event_info->power) { -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&ip->early_suspend); -#endif - ip->info->power(ip->info, 0); - } - for (i = 0; i < registered; i++) - input_unregister_device(ip->input_devs->dev[i]); - for (i = dev_count - 1; i >= registered; i--) { - input_free_device(ip->input_devs->dev[i]); -err_input_dev_alloc_failed: - ; - } - kfree(ip); -err_kp_alloc_failed: - return err; -} - -static int gpio_event_remove(struct platform_device *pdev) -{ - struct gpio_event *ip = platform_get_drvdata(pdev); - int i; - - gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT); - if (ip->info->power) { -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&ip->early_suspend); -#endif - ip->info->power(ip->info, 0); - } - for (i = 0; i < ip->input_devs->count; i++) - input_unregister_device(ip->input_devs->dev[i]); - kfree(ip); - return 0; -} - -static struct platform_driver gpio_event_driver = { - .probe = gpio_event_probe, - .remove = gpio_event_remove, - .driver = { - .name = GPIO_EVENT_DEV_NAME, - }, -}; - -static int __devinit gpio_event_init(void) -{ - return platform_driver_register(&gpio_event_driver); -} - -static void __exit gpio_event_exit(void) -{ - platform_driver_unregister(&gpio_event_driver); -} - -module_init(gpio_event_init); -module_exit(gpio_event_exit); - -MODULE_DESCRIPTION("GPIO Event Driver"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/input/misc/gpio_input.c b/drivers/input/misc/gpio_input.c deleted file mode 100644 index 6a0c31510968..000000000000 --- a/drivers/input/misc/gpio_input.c +++ /dev/null @@ -1,376 +0,0 @@ -/* drivers/input/misc/gpio_input.c - * - * Copyright (C) 2007 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -enum { - DEBOUNCE_UNSTABLE = BIT(0), /* Got irq, while debouncing */ - DEBOUNCE_PRESSED = BIT(1), - DEBOUNCE_NOTPRESSED = BIT(2), - DEBOUNCE_WAIT_IRQ = BIT(3), /* Stable irq state */ - DEBOUNCE_POLL = BIT(4), /* Stable polling state */ - - DEBOUNCE_UNKNOWN = - DEBOUNCE_PRESSED | DEBOUNCE_NOTPRESSED, -}; - -struct gpio_key_state { - struct gpio_input_state *ds; - uint8_t debounce; -}; - -struct gpio_input_state { - struct gpio_event_input_devs *input_devs; - const struct gpio_event_input_info *info; - struct hrtimer timer; - int use_irq; - int debounce_count; - spinlock_t irq_lock; - struct wake_lock wake_lock; - struct gpio_key_state key_state[0]; -}; - -static enum hrtimer_restart gpio_event_input_timer_func(struct hrtimer *timer) -{ - int i; - int pressed; - struct gpio_input_state *ds = - container_of(timer, struct gpio_input_state, timer); - unsigned gpio_flags = ds->info->flags; - unsigned npolarity; - int nkeys = ds->info->keymap_size; - const struct gpio_event_direct_entry *key_entry; - struct gpio_key_state *key_state; - unsigned long irqflags; - uint8_t debounce; - bool sync_needed; - -#if 0 - key_entry = kp->keys_info->keymap; - key_state = kp->key_state; - for (i = 0; i < nkeys; i++, key_entry++, key_state++) - pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio, - gpio_read_detect_status(key_entry->gpio)); -#endif - key_entry = ds->info->keymap; - key_state = ds->key_state; - sync_needed = false; - spin_lock_irqsave(&ds->irq_lock, irqflags); - for (i = 0; i < nkeys; i++, key_entry++, key_state++) { - debounce = key_state->debounce; - if (debounce & DEBOUNCE_WAIT_IRQ) - continue; - if (key_state->debounce & DEBOUNCE_UNSTABLE) { - debounce = key_state->debounce = DEBOUNCE_UNKNOWN; - enable_irq(gpio_to_irq(key_entry->gpio)); - if (gpio_flags & GPIOEDF_PRINT_KEY_UNSTABLE) - pr_info("gpio_keys_scan_keys: key %x-%x, %d " - "(%d) continue debounce\n", - ds->info->type, key_entry->code, - i, key_entry->gpio); - } - npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH); - pressed = gpio_get_value(key_entry->gpio) ^ npolarity; - if (debounce & DEBOUNCE_POLL) { - if (pressed == !(debounce & DEBOUNCE_PRESSED)) { - ds->debounce_count++; - key_state->debounce = DEBOUNCE_UNKNOWN; - if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE) - pr_info("gpio_keys_scan_keys: key %x-" - "%x, %d (%d) start debounce\n", - ds->info->type, key_entry->code, - i, key_entry->gpio); - } - continue; - } - if (pressed && (debounce & DEBOUNCE_NOTPRESSED)) { - if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE) - pr_info("gpio_keys_scan_keys: key %x-%x, %d " - "(%d) debounce pressed 1\n", - ds->info->type, key_entry->code, - i, key_entry->gpio); - key_state->debounce = DEBOUNCE_PRESSED; - continue; - } - if (!pressed && (debounce & DEBOUNCE_PRESSED)) { - if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE) - pr_info("gpio_keys_scan_keys: key %x-%x, %d " - "(%d) debounce pressed 0\n", - ds->info->type, key_entry->code, - i, key_entry->gpio); - key_state->debounce = DEBOUNCE_NOTPRESSED; - continue; - } - /* key is stable */ - ds->debounce_count--; - if (ds->use_irq) - key_state->debounce |= DEBOUNCE_WAIT_IRQ; - else - key_state->debounce |= DEBOUNCE_POLL; - if (gpio_flags & GPIOEDF_PRINT_KEYS) - pr_info("gpio_keys_scan_keys: key %x-%x, %d (%d) " - "changed to %d\n", ds->info->type, - key_entry->code, i, key_entry->gpio, pressed); - input_event(ds->input_devs->dev[key_entry->dev], ds->info->type, - key_entry->code, pressed); - sync_needed = true; - } - if (sync_needed) { - for (i = 0; i < ds->input_devs->count; i++) - input_sync(ds->input_devs->dev[i]); - } - -#if 0 - key_entry = kp->keys_info->keymap; - key_state = kp->key_state; - for (i = 0; i < nkeys; i++, key_entry++, key_state++) { - pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio, - gpio_read_detect_status(key_entry->gpio)); - } -#endif - - if (ds->debounce_count) - hrtimer_start(timer, ds->info->debounce_time, HRTIMER_MODE_REL); - else if (!ds->use_irq) - hrtimer_start(timer, ds->info->poll_time, HRTIMER_MODE_REL); - else - wake_unlock(&ds->wake_lock); - - spin_unlock_irqrestore(&ds->irq_lock, irqflags); - - return HRTIMER_NORESTART; -} - -static irqreturn_t gpio_event_input_irq_handler(int irq, void *dev_id) -{ - struct gpio_key_state *ks = dev_id; - struct gpio_input_state *ds = ks->ds; - int keymap_index = ks - ds->key_state; - const struct gpio_event_direct_entry *key_entry; - unsigned long irqflags; - int pressed; - - if (!ds->use_irq) - return IRQ_HANDLED; - - key_entry = &ds->info->keymap[keymap_index]; - - if (ds->info->debounce_time.tv64) { - spin_lock_irqsave(&ds->irq_lock, irqflags); - if (ks->debounce & DEBOUNCE_WAIT_IRQ) { - ks->debounce = DEBOUNCE_UNKNOWN; - if (ds->debounce_count++ == 0) { - wake_lock(&ds->wake_lock); - hrtimer_start( - &ds->timer, ds->info->debounce_time, - HRTIMER_MODE_REL); - } - if (ds->info->flags & GPIOEDF_PRINT_KEY_DEBOUNCE) - pr_info("gpio_event_input_irq_handler: " - "key %x-%x, %d (%d) start debounce\n", - ds->info->type, key_entry->code, - keymap_index, key_entry->gpio); - } else { - disable_irq_nosync(irq); - ks->debounce = DEBOUNCE_UNSTABLE; - } - spin_unlock_irqrestore(&ds->irq_lock, irqflags); - } else { - pressed = gpio_get_value(key_entry->gpio) ^ - !(ds->info->flags & GPIOEDF_ACTIVE_HIGH); - if (ds->info->flags & GPIOEDF_PRINT_KEYS) - pr_info("gpio_event_input_irq_handler: key %x-%x, %d " - "(%d) changed to %d\n", - ds->info->type, key_entry->code, keymap_index, - key_entry->gpio, pressed); - input_event(ds->input_devs->dev[key_entry->dev], ds->info->type, - key_entry->code, pressed); - input_sync(ds->input_devs->dev[key_entry->dev]); - } - return IRQ_HANDLED; -} - -static int gpio_event_input_request_irqs(struct gpio_input_state *ds) -{ - int i; - int err; - unsigned int irq; - unsigned long req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; - - for (i = 0; i < ds->info->keymap_size; i++) { - err = irq = gpio_to_irq(ds->info->keymap[i].gpio); - if (err < 0) - goto err_gpio_get_irq_num_failed; - err = request_irq(irq, gpio_event_input_irq_handler, - req_flags, "gpio_keys", &ds->key_state[i]); - if (err) { - pr_err("gpio_event_input_request_irqs: request_irq " - "failed for input %d, irq %d\n", - ds->info->keymap[i].gpio, irq); - goto err_request_irq_failed; - } - if (ds->info->info.no_suspend) { - err = enable_irq_wake(irq); - if (err) { - pr_err("gpio_event_input_request_irqs: " - "enable_irq_wake failed for input %d, " - "irq %d\n", - ds->info->keymap[i].gpio, irq); - goto err_enable_irq_wake_failed; - } - } - } - return 0; - - for (i = ds->info->keymap_size - 1; i >= 0; i--) { - irq = gpio_to_irq(ds->info->keymap[i].gpio); - if (ds->info->info.no_suspend) - disable_irq_wake(irq); -err_enable_irq_wake_failed: - free_irq(irq, &ds->key_state[i]); -err_request_irq_failed: -err_gpio_get_irq_num_failed: - ; - } - return err; -} - -int gpio_event_input_func(struct gpio_event_input_devs *input_devs, - struct gpio_event_info *info, void **data, int func) -{ - int ret; - int i; - unsigned long irqflags; - struct gpio_event_input_info *di; - struct gpio_input_state *ds = *data; - - di = container_of(info, struct gpio_event_input_info, info); - - if (func == GPIO_EVENT_FUNC_SUSPEND) { - if (ds->use_irq) - for (i = 0; i < di->keymap_size; i++) - disable_irq(gpio_to_irq(di->keymap[i].gpio)); - hrtimer_cancel(&ds->timer); - return 0; - } - if (func == GPIO_EVENT_FUNC_RESUME) { - spin_lock_irqsave(&ds->irq_lock, irqflags); - if (ds->use_irq) - for (i = 0; i < di->keymap_size; i++) - enable_irq(gpio_to_irq(di->keymap[i].gpio)); - hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL); - spin_unlock_irqrestore(&ds->irq_lock, irqflags); - return 0; - } - - if (func == GPIO_EVENT_FUNC_INIT) { - if (ktime_to_ns(di->poll_time) <= 0) - di->poll_time = ktime_set(0, 20 * NSEC_PER_MSEC); - - *data = ds = kzalloc(sizeof(*ds) + sizeof(ds->key_state[0]) * - di->keymap_size, GFP_KERNEL); - if (ds == NULL) { - ret = -ENOMEM; - pr_err("gpio_event_input_func: " - "Failed to allocate private data\n"); - goto err_ds_alloc_failed; - } - ds->debounce_count = di->keymap_size; - ds->input_devs = input_devs; - ds->info = di; - wake_lock_init(&ds->wake_lock, WAKE_LOCK_SUSPEND, "gpio_input"); - spin_lock_init(&ds->irq_lock); - - for (i = 0; i < di->keymap_size; i++) { - int dev = di->keymap[i].dev; - if (dev >= input_devs->count) { - pr_err("gpio_event_input_func: bad device " - "index %d >= %d for key code %d\n", - dev, input_devs->count, - di->keymap[i].code); - ret = -EINVAL; - goto err_bad_keymap; - } - input_set_capability(input_devs->dev[dev], di->type, - di->keymap[i].code); - ds->key_state[i].ds = ds; - ds->key_state[i].debounce = DEBOUNCE_UNKNOWN; - } - - for (i = 0; i < di->keymap_size; i++) { - ret = gpio_request(di->keymap[i].gpio, "gpio_kp_in"); - if (ret) { - pr_err("gpio_event_input_func: gpio_request " - "failed for %d\n", di->keymap[i].gpio); - goto err_gpio_request_failed; - } - ret = gpio_direction_input(di->keymap[i].gpio); - if (ret) { - pr_err("gpio_event_input_func: " - "gpio_direction_input failed for %d\n", - di->keymap[i].gpio); - goto err_gpio_configure_failed; - } - } - - ret = gpio_event_input_request_irqs(ds); - - spin_lock_irqsave(&ds->irq_lock, irqflags); - ds->use_irq = ret == 0; - - pr_info("GPIO Input Driver: Start gpio inputs for %s%s in %s " - "mode\n", input_devs->dev[0]->name, - (input_devs->count > 1) ? "..." : "", - ret == 0 ? "interrupt" : "polling"); - - hrtimer_init(&ds->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - ds->timer.function = gpio_event_input_timer_func; - hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL); - spin_unlock_irqrestore(&ds->irq_lock, irqflags); - return 0; - } - - ret = 0; - spin_lock_irqsave(&ds->irq_lock, irqflags); - hrtimer_cancel(&ds->timer); - if (ds->use_irq) { - for (i = di->keymap_size - 1; i >= 0; i--) { - int irq = gpio_to_irq(di->keymap[i].gpio); - if (ds->info->info.no_suspend) - disable_irq_wake(irq); - free_irq(irq, &ds->key_state[i]); - } - } - spin_unlock_irqrestore(&ds->irq_lock, irqflags); - - for (i = di->keymap_size - 1; i >= 0; i--) { -err_gpio_configure_failed: - gpio_free(di->keymap[i].gpio); -err_gpio_request_failed: - ; - } -err_bad_keymap: - wake_lock_destroy(&ds->wake_lock); - kfree(ds); -err_ds_alloc_failed: - return ret; -} diff --git a/drivers/input/misc/gpio_matrix.c b/drivers/input/misc/gpio_matrix.c deleted file mode 100644 index eaa9e89d473a..000000000000 --- a/drivers/input/misc/gpio_matrix.c +++ /dev/null @@ -1,441 +0,0 @@ -/* drivers/input/misc/gpio_matrix.c - * - * Copyright (C) 2007 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -struct gpio_kp { - struct gpio_event_input_devs *input_devs; - struct gpio_event_matrix_info *keypad_info; - struct hrtimer timer; - struct wake_lock wake_lock; - int current_output; - unsigned int use_irq:1; - unsigned int key_state_changed:1; - unsigned int last_key_state_changed:1; - unsigned int some_keys_pressed:2; - unsigned int disabled_irq:1; - unsigned long keys_pressed[0]; -}; - -static void clear_phantom_key(struct gpio_kp *kp, int out, int in) -{ - struct gpio_event_matrix_info *mi = kp->keypad_info; - int key_index = out * mi->ninputs + in; - unsigned short keyentry = mi->keymap[key_index]; - unsigned short keycode = keyentry & MATRIX_KEY_MASK; - unsigned short dev = keyentry >> MATRIX_CODE_BITS; - - if (!test_bit(keycode, kp->input_devs->dev[dev]->key)) { - if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS) - pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) " - "cleared\n", keycode, out, in, - mi->output_gpios[out], mi->input_gpios[in]); - __clear_bit(key_index, kp->keys_pressed); - } else { - if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS) - pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) " - "not cleared\n", keycode, out, in, - mi->output_gpios[out], mi->input_gpios[in]); - } -} - -static int restore_keys_for_input(struct gpio_kp *kp, int out, int in) -{ - int rv = 0; - int key_index; - - key_index = out * kp->keypad_info->ninputs + in; - while (out < kp->keypad_info->noutputs) { - if (test_bit(key_index, kp->keys_pressed)) { - rv = 1; - clear_phantom_key(kp, out, in); - } - key_index += kp->keypad_info->ninputs; - out++; - } - return rv; -} - -static void remove_phantom_keys(struct gpio_kp *kp) -{ - int out, in, inp; - int key_index; - - if (kp->some_keys_pressed < 3) - return; - - for (out = 0; out < kp->keypad_info->noutputs; out++) { - inp = -1; - key_index = out * kp->keypad_info->ninputs; - for (in = 0; in < kp->keypad_info->ninputs; in++, key_index++) { - if (test_bit(key_index, kp->keys_pressed)) { - if (inp == -1) { - inp = in; - continue; - } - if (inp >= 0) { - if (!restore_keys_for_input(kp, out + 1, - inp)) - break; - clear_phantom_key(kp, out, inp); - inp = -2; - } - restore_keys_for_input(kp, out, in); - } - } - } -} - -static void report_key(struct gpio_kp *kp, int key_index, int out, int in) -{ - struct gpio_event_matrix_info *mi = kp->keypad_info; - int pressed = test_bit(key_index, kp->keys_pressed); - unsigned short keyentry = mi->keymap[key_index]; - unsigned short keycode = keyentry & MATRIX_KEY_MASK; - unsigned short dev = keyentry >> MATRIX_CODE_BITS; - - if (pressed != test_bit(keycode, kp->input_devs->dev[dev]->key)) { - if (keycode == KEY_RESERVED) { - if (mi->flags & GPIOKPF_PRINT_UNMAPPED_KEYS) - pr_info("gpiomatrix: unmapped key, %d-%d " - "(%d-%d) changed to %d\n", - out, in, mi->output_gpios[out], - mi->input_gpios[in], pressed); - } else { - if (mi->flags & GPIOKPF_PRINT_MAPPED_KEYS) - pr_info("gpiomatrix: key %x, %d-%d (%d-%d) " - "changed to %d\n", keycode, - out, in, mi->output_gpios[out], - mi->input_gpios[in], pressed); - input_report_key(kp->input_devs->dev[dev], keycode, pressed); - } - } -} - -static void report_sync(struct gpio_kp *kp) -{ - int i; - - for (i = 0; i < kp->input_devs->count; i++) - input_sync(kp->input_devs->dev[i]); -} - -static enum hrtimer_restart gpio_keypad_timer_func(struct hrtimer *timer) -{ - int out, in; - int key_index; - int gpio; - struct gpio_kp *kp = container_of(timer, struct gpio_kp, timer); - struct gpio_event_matrix_info *mi = kp->keypad_info; - unsigned gpio_keypad_flags = mi->flags; - unsigned polarity = !!(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH); - - out = kp->current_output; - if (out == mi->noutputs) { - out = 0; - kp->last_key_state_changed = kp->key_state_changed; - kp->key_state_changed = 0; - kp->some_keys_pressed = 0; - } else { - key_index = out * mi->ninputs; - for (in = 0; in < mi->ninputs; in++, key_index++) { - gpio = mi->input_gpios[in]; - if (gpio_get_value(gpio) ^ !polarity) { - if (kp->some_keys_pressed < 3) - kp->some_keys_pressed++; - kp->key_state_changed |= !__test_and_set_bit( - key_index, kp->keys_pressed); - } else - kp->key_state_changed |= __test_and_clear_bit( - key_index, kp->keys_pressed); - } - gpio = mi->output_gpios[out]; - if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE) - gpio_set_value(gpio, !polarity); - else - gpio_direction_input(gpio); - out++; - } - kp->current_output = out; - if (out < mi->noutputs) { - gpio = mi->output_gpios[out]; - if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE) - gpio_set_value(gpio, polarity); - else - gpio_direction_output(gpio, polarity); - hrtimer_start(timer, mi->settle_time, HRTIMER_MODE_REL); - return HRTIMER_NORESTART; - } - if (gpio_keypad_flags & GPIOKPF_DEBOUNCE) { - if (kp->key_state_changed) { - hrtimer_start(&kp->timer, mi->debounce_delay, - HRTIMER_MODE_REL); - return HRTIMER_NORESTART; - } - kp->key_state_changed = kp->last_key_state_changed; - } - if (kp->key_state_changed) { - if (gpio_keypad_flags & GPIOKPF_REMOVE_SOME_PHANTOM_KEYS) - remove_phantom_keys(kp); - key_index = 0; - for (out = 0; out < mi->noutputs; out++) - for (in = 0; in < mi->ninputs; in++, key_index++) - report_key(kp, key_index, out, in); - report_sync(kp); - } - if (!kp->use_irq || kp->some_keys_pressed) { - hrtimer_start(timer, mi->poll_time, HRTIMER_MODE_REL); - return HRTIMER_NORESTART; - } - - /* No keys are pressed, reenable interrupt */ - for (out = 0; out < mi->noutputs; out++) { - if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE) - gpio_set_value(mi->output_gpios[out], polarity); - else - gpio_direction_output(mi->output_gpios[out], polarity); - } - for (in = 0; in < mi->ninputs; in++) - enable_irq(gpio_to_irq(mi->input_gpios[in])); - wake_unlock(&kp->wake_lock); - return HRTIMER_NORESTART; -} - -static irqreturn_t gpio_keypad_irq_handler(int irq_in, void *dev_id) -{ - int i; - struct gpio_kp *kp = dev_id; - struct gpio_event_matrix_info *mi = kp->keypad_info; - unsigned gpio_keypad_flags = mi->flags; - - if (!kp->use_irq) { - /* ignore interrupt while registering the handler */ - kp->disabled_irq = 1; - disable_irq_nosync(irq_in); - return IRQ_HANDLED; - } - - for (i = 0; i < mi->ninputs; i++) - disable_irq_nosync(gpio_to_irq(mi->input_gpios[i])); - for (i = 0; i < mi->noutputs; i++) { - if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE) - gpio_set_value(mi->output_gpios[i], - !(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH)); - else - gpio_direction_input(mi->output_gpios[i]); - } - wake_lock(&kp->wake_lock); - hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL); - return IRQ_HANDLED; -} - -static int gpio_keypad_request_irqs(struct gpio_kp *kp) -{ - int i; - int err; - unsigned int irq; - unsigned long request_flags; - struct gpio_event_matrix_info *mi = kp->keypad_info; - - switch (mi->flags & (GPIOKPF_ACTIVE_HIGH|GPIOKPF_LEVEL_TRIGGERED_IRQ)) { - default: - request_flags = IRQF_TRIGGER_FALLING; - break; - case GPIOKPF_ACTIVE_HIGH: - request_flags = IRQF_TRIGGER_RISING; - break; - case GPIOKPF_LEVEL_TRIGGERED_IRQ: - request_flags = IRQF_TRIGGER_LOW; - break; - case GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_ACTIVE_HIGH: - request_flags = IRQF_TRIGGER_HIGH; - break; - } - - for (i = 0; i < mi->ninputs; i++) { - err = irq = gpio_to_irq(mi->input_gpios[i]); - if (err < 0) - goto err_gpio_get_irq_num_failed; - err = request_irq(irq, gpio_keypad_irq_handler, request_flags, - "gpio_kp", kp); - if (err) { - pr_err("gpiomatrix: request_irq failed for input %d, " - "irq %d\n", mi->input_gpios[i], irq); - goto err_request_irq_failed; - } - err = enable_irq_wake(irq); - if (err) { - pr_err("gpiomatrix: set_irq_wake failed for input %d, " - "irq %d\n", mi->input_gpios[i], irq); - } - disable_irq(irq); - if (kp->disabled_irq) { - kp->disabled_irq = 0; - enable_irq(irq); - } - } - return 0; - - for (i = mi->noutputs - 1; i >= 0; i--) { - free_irq(gpio_to_irq(mi->input_gpios[i]), kp); -err_request_irq_failed: -err_gpio_get_irq_num_failed: - ; - } - return err; -} - -int gpio_event_matrix_func(struct gpio_event_input_devs *input_devs, - struct gpio_event_info *info, void **data, int func) -{ - int i; - int err; - int key_count; - struct gpio_kp *kp; - struct gpio_event_matrix_info *mi; - - mi = container_of(info, struct gpio_event_matrix_info, info); - if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) { - /* TODO: disable scanning */ - return 0; - } - - if (func == GPIO_EVENT_FUNC_INIT) { - if (mi->keymap == NULL || - mi->input_gpios == NULL || - mi->output_gpios == NULL) { - err = -ENODEV; - pr_err("gpiomatrix: Incomplete pdata\n"); - goto err_invalid_platform_data; - } - key_count = mi->ninputs * mi->noutputs; - - *data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) * - BITS_TO_LONGS(key_count), GFP_KERNEL); - if (kp == NULL) { - err = -ENOMEM; - pr_err("gpiomatrix: Failed to allocate private data\n"); - goto err_kp_alloc_failed; - } - kp->input_devs = input_devs; - kp->keypad_info = mi; - for (i = 0; i < key_count; i++) { - unsigned short keyentry = mi->keymap[i]; - unsigned short keycode = keyentry & MATRIX_KEY_MASK; - unsigned short dev = keyentry >> MATRIX_CODE_BITS; - if (dev >= input_devs->count) { - pr_err("gpiomatrix: bad device index %d >= " - "%d for key code %d\n", - dev, input_devs->count, keycode); - err = -EINVAL; - goto err_bad_keymap; - } - if (keycode && keycode <= KEY_MAX) - input_set_capability(input_devs->dev[dev], - EV_KEY, keycode); - } - - for (i = 0; i < mi->noutputs; i++) { - err = gpio_request(mi->output_gpios[i], "gpio_kp_out"); - if (err) { - pr_err("gpiomatrix: gpio_request failed for " - "output %d\n", mi->output_gpios[i]); - goto err_request_output_gpio_failed; - } - if (gpio_cansleep(mi->output_gpios[i])) { - pr_err("gpiomatrix: unsupported output gpio %d," - " can sleep\n", mi->output_gpios[i]); - err = -EINVAL; - goto err_output_gpio_configure_failed; - } - if (mi->flags & GPIOKPF_DRIVE_INACTIVE) - err = gpio_direction_output(mi->output_gpios[i], - !(mi->flags & GPIOKPF_ACTIVE_HIGH)); - else - err = gpio_direction_input(mi->output_gpios[i]); - if (err) { - pr_err("gpiomatrix: gpio_configure failed for " - "output %d\n", mi->output_gpios[i]); - goto err_output_gpio_configure_failed; - } - } - for (i = 0; i < mi->ninputs; i++) { - err = gpio_request(mi->input_gpios[i], "gpio_kp_in"); - if (err) { - pr_err("gpiomatrix: gpio_request failed for " - "input %d\n", mi->input_gpios[i]); - goto err_request_input_gpio_failed; - } - err = gpio_direction_input(mi->input_gpios[i]); - if (err) { - pr_err("gpiomatrix: gpio_direction_input failed" - " for input %d\n", mi->input_gpios[i]); - goto err_gpio_direction_input_failed; - } - } - kp->current_output = mi->noutputs; - kp->key_state_changed = 1; - - hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - kp->timer.function = gpio_keypad_timer_func; - wake_lock_init(&kp->wake_lock, WAKE_LOCK_SUSPEND, "gpio_kp"); - err = gpio_keypad_request_irqs(kp); - kp->use_irq = err == 0; - - pr_info("GPIO Matrix Keypad Driver: Start keypad matrix for " - "%s%s in %s mode\n", input_devs->dev[0]->name, - (input_devs->count > 1) ? "..." : "", - kp->use_irq ? "interrupt" : "polling"); - - if (kp->use_irq) - wake_lock(&kp->wake_lock); - hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL); - - return 0; - } - - err = 0; - kp = *data; - - if (kp->use_irq) - for (i = mi->noutputs - 1; i >= 0; i--) - free_irq(gpio_to_irq(mi->input_gpios[i]), kp); - - hrtimer_cancel(&kp->timer); - wake_lock_destroy(&kp->wake_lock); - for (i = mi->noutputs - 1; i >= 0; i--) { -err_gpio_direction_input_failed: - gpio_free(mi->input_gpios[i]); -err_request_input_gpio_failed: - ; - } - for (i = mi->noutputs - 1; i >= 0; i--) { -err_output_gpio_configure_failed: - gpio_free(mi->output_gpios[i]); -err_request_output_gpio_failed: - ; - } -err_bad_keymap: - kfree(kp); -err_kp_alloc_failed: -err_invalid_platform_data: - return err; -} diff --git a/drivers/input/misc/gpio_output.c b/drivers/input/misc/gpio_output.c deleted file mode 100644 index 2aac2fad0a17..000000000000 --- a/drivers/input/misc/gpio_output.c +++ /dev/null @@ -1,97 +0,0 @@ -/* drivers/input/misc/gpio_output.c - * - * Copyright (C) 2007 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include - -int gpio_event_output_event( - struct gpio_event_input_devs *input_devs, struct gpio_event_info *info, - void **data, unsigned int dev, unsigned int type, - unsigned int code, int value) -{ - int i; - struct gpio_event_output_info *oi; - oi = container_of(info, struct gpio_event_output_info, info); - if (type != oi->type) - return 0; - if (!(oi->flags & GPIOEDF_ACTIVE_HIGH)) - value = !value; - for (i = 0; i < oi->keymap_size; i++) - if (dev == oi->keymap[i].dev && code == oi->keymap[i].code) - gpio_set_value(oi->keymap[i].gpio, value); - return 0; -} - -int gpio_event_output_func( - struct gpio_event_input_devs *input_devs, struct gpio_event_info *info, - void **data, int func) -{ - int ret; - int i; - struct gpio_event_output_info *oi; - oi = container_of(info, struct gpio_event_output_info, info); - - if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) - return 0; - - if (func == GPIO_EVENT_FUNC_INIT) { - int output_level = !(oi->flags & GPIOEDF_ACTIVE_HIGH); - - for (i = 0; i < oi->keymap_size; i++) { - int dev = oi->keymap[i].dev; - if (dev >= input_devs->count) { - pr_err("gpio_event_output_func: bad device " - "index %d >= %d for key code %d\n", - dev, input_devs->count, - oi->keymap[i].code); - ret = -EINVAL; - goto err_bad_keymap; - } - input_set_capability(input_devs->dev[dev], oi->type, - oi->keymap[i].code); - } - - for (i = 0; i < oi->keymap_size; i++) { - ret = gpio_request(oi->keymap[i].gpio, - "gpio_event_output"); - if (ret) { - pr_err("gpio_event_output_func: gpio_request " - "failed for %d\n", oi->keymap[i].gpio); - goto err_gpio_request_failed; - } - ret = gpio_direction_output(oi->keymap[i].gpio, - output_level); - if (ret) { - pr_err("gpio_event_output_func: " - "gpio_direction_output failed for %d\n", - oi->keymap[i].gpio); - goto err_gpio_direction_output_failed; - } - } - return 0; - } - - ret = 0; - for (i = oi->keymap_size - 1; i >= 0; i--) { -err_gpio_direction_output_failed: - gpio_free(oi->keymap[i].gpio); -err_gpio_request_failed: - ; - } -err_bad_keymap: - return ret; -} - diff --git a/drivers/input/misc/keychord.c b/drivers/input/misc/keychord.c deleted file mode 100644 index 3ffab6da411b..000000000000 --- a/drivers/input/misc/keychord.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * drivers/input/misc/keychord.c - * - * Copyright (C) 2008 Google, Inc. - * Author: Mike Lockwood - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define KEYCHORD_NAME "keychord" -#define BUFFER_SIZE 16 - -MODULE_AUTHOR("Mike Lockwood "); -MODULE_DESCRIPTION("Key chord input driver"); -MODULE_SUPPORTED_DEVICE("keychord"); -MODULE_LICENSE("GPL"); - -#define NEXT_KEYCHORD(kc) ((struct input_keychord *) \ - ((char *)kc + sizeof(struct input_keychord) + \ - kc->count * sizeof(kc->keycodes[0]))) - -struct keychord_device { - struct input_handler input_handler; - int registered; - - /* list of keychords to monitor */ - struct input_keychord *keychords; - int keychord_count; - - /* bitmask of keys contained in our keychords */ - unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; - /* current state of the keys */ - unsigned long keystate[BITS_TO_LONGS(KEY_CNT)]; - /* number of keys that are currently pressed */ - int key_down; - - /* second input_device_id is needed for null termination */ - struct input_device_id device_ids[2]; - - spinlock_t lock; - wait_queue_head_t waitq; - unsigned char head; - unsigned char tail; - __u16 buff[BUFFER_SIZE]; -}; - -static int check_keychord(struct keychord_device *kdev, - struct input_keychord *keychord) -{ - int i; - - if (keychord->count != kdev->key_down) - return 0; - - for (i = 0; i < keychord->count; i++) { - if (!test_bit(keychord->keycodes[i], kdev->keystate)) - return 0; - } - - /* we have a match */ - return 1; -} - -static void keychord_event(struct input_handle *handle, unsigned int type, - unsigned int code, int value) -{ - struct keychord_device *kdev = handle->private; - struct input_keychord *keychord; - unsigned long flags; - int i, got_chord = 0; - - if (type != EV_KEY || code >= KEY_MAX) - return; - - spin_lock_irqsave(&kdev->lock, flags); - /* do nothing if key state did not change */ - if (!test_bit(code, kdev->keystate) == !value) - goto done; - __change_bit(code, kdev->keystate); - if (value) - kdev->key_down++; - else - kdev->key_down--; - - /* don't notify on key up */ - if (!value) - goto done; - /* ignore this event if it is not one of the keys we are monitoring */ - if (!test_bit(code, kdev->keybit)) - goto done; - - keychord = kdev->keychords; - if (!keychord) - goto done; - - /* check to see if the keyboard state matches any keychords */ - for (i = 0; i < kdev->keychord_count; i++) { - if (check_keychord(kdev, keychord)) { - kdev->buff[kdev->head] = keychord->id; - kdev->head = (kdev->head + 1) % BUFFER_SIZE; - got_chord = 1; - break; - } - /* skip to next keychord */ - keychord = NEXT_KEYCHORD(keychord); - } - -done: - spin_unlock_irqrestore(&kdev->lock, flags); - - if (got_chord) - wake_up_interruptible(&kdev->waitq); -} - -static int keychord_connect(struct input_handler *handler, - struct input_dev *dev, - const struct input_device_id *id) -{ - int i, ret; - struct input_handle *handle; - struct keychord_device *kdev = - container_of(handler, struct keychord_device, input_handler); - - /* - * ignore this input device if it does not contain any keycodes - * that we are monitoring - */ - for (i = 0; i < KEY_MAX; i++) { - if (test_bit(i, kdev->keybit) && test_bit(i, dev->keybit)) - break; - } - if (i == KEY_MAX) - return -ENODEV; - - handle = kzalloc(sizeof(*handle), GFP_KERNEL); - if (!handle) - return -ENOMEM; - - handle->dev = dev; - handle->handler = handler; - handle->name = KEYCHORD_NAME; - handle->private = kdev; - - ret = input_register_handle(handle); - if (ret) - goto err_input_register_handle; - - ret = input_open_device(handle); - if (ret) - goto err_input_open_device; - - pr_info("keychord: using input dev %s for fevent\n", dev->name); - - return 0; - -err_input_open_device: - input_unregister_handle(handle); -err_input_register_handle: - kfree(handle); - return ret; -} - -static void keychord_disconnect(struct input_handle *handle) -{ - input_close_device(handle); - input_unregister_handle(handle); - kfree(handle); -} - -/* - * keychord_read is used to read keychord events from the driver - */ -static ssize_t keychord_read(struct file *file, char __user *buffer, - size_t count, loff_t *ppos) -{ - struct keychord_device *kdev = file->private_data; - __u16 id; - int retval; - unsigned long flags; - - if (count < sizeof(id)) - return -EINVAL; - count = sizeof(id); - - if (kdev->head == kdev->tail && (file->f_flags & O_NONBLOCK)) - return -EAGAIN; - - retval = wait_event_interruptible(kdev->waitq, - kdev->head != kdev->tail); - if (retval) - return retval; - - spin_lock_irqsave(&kdev->lock, flags); - /* pop a keychord ID off the queue */ - id = kdev->buff[kdev->tail]; - kdev->tail = (kdev->tail + 1) % BUFFER_SIZE; - spin_unlock_irqrestore(&kdev->lock, flags); - - if (copy_to_user(buffer, &id, count)) - return -EFAULT; - - return count; -} - -/* - * keychord_write is used to configure the driver - */ -static ssize_t keychord_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) -{ - struct keychord_device *kdev = file->private_data; - struct input_keychord *keychords = 0; - struct input_keychord *keychord, *next, *end; - int ret, i, key; - unsigned long flags; - - if (count < sizeof(struct input_keychord)) - return -EINVAL; - keychords = kzalloc(count, GFP_KERNEL); - if (!keychords) - return -ENOMEM; - - /* read list of keychords from userspace */ - if (copy_from_user(keychords, buffer, count)) { - kfree(keychords); - return -EFAULT; - } - - /* unregister handler before changing configuration */ - if (kdev->registered) { - input_unregister_handler(&kdev->input_handler); - kdev->registered = 0; - } - - spin_lock_irqsave(&kdev->lock, flags); - /* clear any existing configuration */ - kfree(kdev->keychords); - kdev->keychords = 0; - kdev->keychord_count = 0; - kdev->key_down = 0; - memset(kdev->keybit, 0, sizeof(kdev->keybit)); - memset(kdev->keystate, 0, sizeof(kdev->keystate)); - kdev->head = kdev->tail = 0; - - keychord = keychords; - end = (struct input_keychord *)((char *)keychord + count); - - while (keychord < end) { - next = NEXT_KEYCHORD(keychord); - if (keychord->count <= 0 || next > end) { - pr_err("keychord: invalid keycode count %d\n", - keychord->count); - goto err_unlock_return; - } - if (keychord->version != KEYCHORD_VERSION) { - pr_err("keychord: unsupported version %d\n", - keychord->version); - goto err_unlock_return; - } - - /* keep track of the keys we are monitoring in keybit */ - for (i = 0; i < keychord->count; i++) { - key = keychord->keycodes[i]; - if (key < 0 || key >= KEY_CNT) { - pr_err("keychord: keycode %d out of range\n", - key); - goto err_unlock_return; - } - __set_bit(key, kdev->keybit); - } - - kdev->keychord_count++; - keychord = next; - } - - kdev->keychords = keychords; - spin_unlock_irqrestore(&kdev->lock, flags); - - ret = input_register_handler(&kdev->input_handler); - if (ret) { - kfree(keychords); - kdev->keychords = 0; - return ret; - } - kdev->registered = 1; - - return count; - -err_unlock_return: - spin_unlock_irqrestore(&kdev->lock, flags); - kfree(keychords); - return -EINVAL; -} - -static unsigned int keychord_poll(struct file *file, poll_table *wait) -{ - struct keychord_device *kdev = file->private_data; - - poll_wait(file, &kdev->waitq, wait); - - if (kdev->head != kdev->tail) - return POLLIN | POLLRDNORM; - - return 0; -} - -static int keychord_open(struct inode *inode, struct file *file) -{ - struct keychord_device *kdev; - - kdev = kzalloc(sizeof(struct keychord_device), GFP_KERNEL); - if (!kdev) - return -ENOMEM; - - spin_lock_init(&kdev->lock); - init_waitqueue_head(&kdev->waitq); - - kdev->input_handler.event = keychord_event; - kdev->input_handler.connect = keychord_connect; - kdev->input_handler.disconnect = keychord_disconnect; - kdev->input_handler.name = KEYCHORD_NAME; - kdev->input_handler.id_table = kdev->device_ids; - - kdev->device_ids[0].flags = INPUT_DEVICE_ID_MATCH_EVBIT; - __set_bit(EV_KEY, kdev->device_ids[0].evbit); - - file->private_data = kdev; - - return 0; -} - -static int keychord_release(struct inode *inode, struct file *file) -{ - struct keychord_device *kdev = file->private_data; - - if (kdev->registered) - input_unregister_handler(&kdev->input_handler); - kfree(kdev); - - return 0; -} - -static const struct file_operations keychord_fops = { - .owner = THIS_MODULE, - .open = keychord_open, - .release = keychord_release, - .read = keychord_read, - .write = keychord_write, - .poll = keychord_poll, -}; - -static struct miscdevice keychord_misc = { - .fops = &keychord_fops, - .name = KEYCHORD_NAME, - .minor = MISC_DYNAMIC_MINOR, -}; - -static int __init keychord_init(void) -{ - return misc_register(&keychord_misc); -} - -static void __exit keychord_exit(void) -{ - misc_deregister(&keychord_misc); -} - -module_init(keychord_init); -module_exit(keychord_exit); diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 0b9944346ec3..99d58764ef03 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -426,9 +426,7 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int /* * First try "E6 report". - * ALPS should return 0,0,10 or 0,0,100 if no buttons are pressed. - * The bits 0-2 of the first byte will be 1s if some buttons are - * pressed. + * ALPS should return 0,0,10 or 0,0,100 */ param[0] = 0; if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) || @@ -443,8 +441,7 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int dbg("E6 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]); - if ((param[0] & 0xf8) != 0 || param[1] != 0 || - (param[2] != 10 && param[2] != 100)) + if (param[0] != 0 || param[1] != 0 || (param[2] != 10 && param[2] != 100)) return NULL; /* diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 13e38ffec35b..3126983c004a 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c @@ -373,9 +373,6 @@ static void setup_events_to_report(struct input_dev *input_dev, __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); __set_bit(BTN_LEFT, input_dev->keybit); - if (cfg->caps & HAS_INTEGRATED_BUTTON) - __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); - input_set_events_per_packet(input_dev, 60); } diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 6ad728f0e287..e06e045bf907 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -24,7 +24,6 @@ */ #include -#include #include #include #include @@ -761,16 +760,6 @@ static int synaptics_reconnect(struct psmouse *psmouse) do { psmouse_reset(psmouse); - if (retry) { - /* - * On some boxes, right after resuming, the touchpad - * needs some time to finish initializing (I assume - * it needs time to calibrate) and start responding - * to Synaptics-specific queries, so let's wait a - * bit. - */ - ssleep(1); - } error = synaptics_detect(psmouse, 0); } while (error && ++retry < 3); diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 20153fe81512..bb9f5d31f0d0 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -176,20 +176,6 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Spring Peak"), }, }, - { - /* Gigabyte T1005 - defines wrong chassis type ("Other") */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), - DMI_MATCH(DMI_PRODUCT_NAME, "T1005"), - }, - }, - { - /* Gigabyte T1005M/P - defines wrong chassis type ("Other") */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), - DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P"), - }, - }, { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), @@ -333,12 +319,6 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"), }, }, - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"), - }, - }, { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), @@ -900,7 +880,6 @@ static int __init i8042_platform_init(void) int retval; #ifdef CONFIG_X86 - u8 a20_on = 0xdf; /* Just return if pre-detection shows no i8042 controller exist */ if (!x86_platform.i8042_detect()) return -ENODEV; @@ -940,14 +919,6 @@ static int __init i8042_platform_init(void) if (dmi_check_system(i8042_dmi_dritek_table)) i8042_dritek = true; - - /* - * A20 was already enabled during early kernel init. But some buggy - * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to - * resume from S3. So we do it here and hope that nothing breaks. - */ - i8042_command(&a20_on, 0x10d1); - i8042_command(NULL, 0x00ff); /* Null command for SMM firmware */ #endif /* CONFIG_X86 */ return retval; diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index a28ebf08560c..08ba5ad9c9be 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -242,7 +242,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom) input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); if (wacom->tool[0] != BTN_TOOL_MOUSE) { - input_report_abs(input, ABS_PRESSURE, data[6] | ((data[7] & 0x03) << 8)); + input_report_abs(input, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8)); input_report_key(input, BTN_TOUCH, data[1] & 0x01); input_report_key(input, BTN_STYLUS, data[1] & 0x02); input_report_key(input, BTN_STYLUS2, data[1] & 0x04); diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 410410396700..cabd9e54863f 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -383,12 +383,6 @@ config TOUCHSCREEN_TNETV107X To compile this driver as a module, choose M here: the module will be called tnetv107x-ts. -config TOUCHSCREEN_SYNAPTICS_I2C_RMI - tristate "Synaptics i2c touchscreen" - depends on I2C - help - This enables support for Synaptics RMI over I2C based touchscreens. - config TOUCHSCREEN_TOUCHRIGHT tristate "Touchright serial touchscreen" select SERIO diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 0738f19633b1..282d6f76ae26 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -43,7 +43,6 @@ obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o obj-$(CONFIG_TOUCHSCREEN_ST1232) += st1232.o obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o obj-$(CONFIG_TOUCHSCREEN_TNETV107X) += tnetv107x-ts.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI) += synaptics_i2c_rmi.o obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi.c b/drivers/input/touchscreen/synaptics_i2c_rmi.c deleted file mode 100644 index 5729602cbb63..000000000000 --- a/drivers/input/touchscreen/synaptics_i2c_rmi.c +++ /dev/null @@ -1,675 +0,0 @@ -/* drivers/input/keyboard/synaptics_i2c_rmi.c - * - * Copyright (C) 2007 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct workqueue_struct *synaptics_wq; - -struct synaptics_ts_data { - uint16_t addr; - struct i2c_client *client; - struct input_dev *input_dev; - int use_irq; - bool has_relative_report; - struct hrtimer timer; - struct work_struct work; - uint16_t max[2]; - int snap_state[2][2]; - int snap_down_on[2]; - int snap_down_off[2]; - int snap_up_on[2]; - int snap_up_off[2]; - int snap_down[2]; - int snap_up[2]; - uint32_t flags; - int reported_finger_count; - int8_t sensitivity_adjust; - int (*power)(int on); - struct early_suspend early_suspend; -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void synaptics_ts_early_suspend(struct early_suspend *h); -static void synaptics_ts_late_resume(struct early_suspend *h); -#endif - -static int synaptics_init_panel(struct synaptics_ts_data *ts) -{ - int ret; - - ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x10); /* page select = 0x10 */ - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_write_byte_data failed for page select\n"); - goto err_page_select_failed; - } - ret = i2c_smbus_write_byte_data(ts->client, 0x41, 0x04); /* Set "No Clip Z" */ - if (ret < 0) - printk(KERN_ERR "i2c_smbus_write_byte_data failed for No Clip Z\n"); - - ret = i2c_smbus_write_byte_data(ts->client, 0x44, - ts->sensitivity_adjust); - if (ret < 0) - pr_err("synaptics_ts: failed to set Sensitivity Adjust\n"); - -err_page_select_failed: - ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x04); /* page select = 0x04 */ - if (ret < 0) - printk(KERN_ERR "i2c_smbus_write_byte_data failed for page select\n"); - ret = i2c_smbus_write_byte_data(ts->client, 0xf0, 0x81); /* normal operation, 80 reports per second */ - if (ret < 0) - printk(KERN_ERR "synaptics_ts_resume: i2c_smbus_write_byte_data failed\n"); - return ret; -} - -static void synaptics_ts_work_func(struct work_struct *work) -{ - int i; - int ret; - int bad_data = 0; - struct i2c_msg msg[2]; - uint8_t start_reg; - uint8_t buf[15]; - struct synaptics_ts_data *ts = container_of(work, struct synaptics_ts_data, work); - int buf_len = ts->has_relative_report ? 15 : 13; - - msg[0].addr = ts->client->addr; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = &start_reg; - start_reg = 0x00; - msg[1].addr = ts->client->addr; - msg[1].flags = I2C_M_RD; - msg[1].len = buf_len; - msg[1].buf = buf; - - /* printk("synaptics_ts_work_func\n"); */ - for (i = 0; i < ((ts->use_irq && !bad_data) ? 1 : 10); i++) { - ret = i2c_transfer(ts->client->adapter, msg, 2); - if (ret < 0) { - printk(KERN_ERR "synaptics_ts_work_func: i2c_transfer failed\n"); - bad_data = 1; - } else { - /* printk("synaptics_ts_work_func: %x %x %x %x %x %x" */ - /* " %x %x %x %x %x %x %x %x %x, ret %d\n", */ - /* buf[0], buf[1], buf[2], buf[3], */ - /* buf[4], buf[5], buf[6], buf[7], */ - /* buf[8], buf[9], buf[10], buf[11], */ - /* buf[12], buf[13], buf[14], ret); */ - if ((buf[buf_len - 1] & 0xc0) != 0x40) { - printk(KERN_WARNING "synaptics_ts_work_func:" - " bad read %x %x %x %x %x %x %x %x %x" - " %x %x %x %x %x %x, ret %d\n", - buf[0], buf[1], buf[2], buf[3], - buf[4], buf[5], buf[6], buf[7], - buf[8], buf[9], buf[10], buf[11], - buf[12], buf[13], buf[14], ret); - if (bad_data) - synaptics_init_panel(ts); - bad_data = 1; - continue; - } - bad_data = 0; - if ((buf[buf_len - 1] & 1) == 0) { - /* printk("read %d coordinates\n", i); */ - break; - } else { - int pos[2][2]; - int f, a; - int base; - /* int x = buf[3] | (uint16_t)(buf[2] & 0x1f) << 8; */ - /* int y = buf[5] | (uint16_t)(buf[4] & 0x1f) << 8; */ - int z = buf[1]; - int w = buf[0] >> 4; - int finger = buf[0] & 7; - - /* int x2 = buf[3+6] | (uint16_t)(buf[2+6] & 0x1f) << 8; */ - /* int y2 = buf[5+6] | (uint16_t)(buf[4+6] & 0x1f) << 8; */ - /* int z2 = buf[1+6]; */ - /* int w2 = buf[0+6] >> 4; */ - /* int finger2 = buf[0+6] & 7; */ - - /* int dx = (int8_t)buf[12]; */ - /* int dy = (int8_t)buf[13]; */ - int finger2_pressed; - - /* printk("x %4d, y %4d, z %3d, w %2d, F %d, 2nd: x %4d, y %4d, z %3d, w %2d, F %d, dx %4d, dy %4d\n", */ - /* x, y, z, w, finger, */ - /* x2, y2, z2, w2, finger2, */ - /* dx, dy); */ - - base = 2; - for (f = 0; f < 2; f++) { - uint32_t flip_flag = SYNAPTICS_FLIP_X; - for (a = 0; a < 2; a++) { - int p = buf[base + 1]; - p |= (uint16_t)(buf[base] & 0x1f) << 8; - if (ts->flags & flip_flag) - p = ts->max[a] - p; - if (ts->flags & SYNAPTICS_SNAP_TO_INACTIVE_EDGE) { - if (ts->snap_state[f][a]) { - if (p <= ts->snap_down_off[a]) - p = ts->snap_down[a]; - else if (p >= ts->snap_up_off[a]) - p = ts->snap_up[a]; - else - ts->snap_state[f][a] = 0; - } else { - if (p <= ts->snap_down_on[a]) { - p = ts->snap_down[a]; - ts->snap_state[f][a] = 1; - } else if (p >= ts->snap_up_on[a]) { - p = ts->snap_up[a]; - ts->snap_state[f][a] = 1; - } - } - } - pos[f][a] = p; - base += 2; - flip_flag <<= 1; - } - base += 2; - if (ts->flags & SYNAPTICS_SWAP_XY) - swap(pos[f][0], pos[f][1]); - } - if (z) { - input_report_abs(ts->input_dev, ABS_X, pos[0][0]); - input_report_abs(ts->input_dev, ABS_Y, pos[0][1]); - } - input_report_abs(ts->input_dev, ABS_PRESSURE, z); - input_report_abs(ts->input_dev, ABS_TOOL_WIDTH, w); - input_report_key(ts->input_dev, BTN_TOUCH, finger); - finger2_pressed = finger > 1 && finger != 7; - input_report_key(ts->input_dev, BTN_2, finger2_pressed); - if (finger2_pressed) { - input_report_abs(ts->input_dev, ABS_HAT0X, pos[1][0]); - input_report_abs(ts->input_dev, ABS_HAT0Y, pos[1][1]); - } - - if (!finger) - z = 0; - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, z); - input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w); - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, pos[0][0]); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, pos[0][1]); - input_mt_sync(ts->input_dev); - if (finger2_pressed) { - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, z); - input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w); - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, pos[1][0]); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, pos[1][1]); - input_mt_sync(ts->input_dev); - } else if (ts->reported_finger_count > 1) { - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); - input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0); - input_mt_sync(ts->input_dev); - } - ts->reported_finger_count = finger; - input_sync(ts->input_dev); - } - } - } - if (ts->use_irq) - enable_irq(ts->client->irq); -} - -static enum hrtimer_restart synaptics_ts_timer_func(struct hrtimer *timer) -{ - struct synaptics_ts_data *ts = container_of(timer, struct synaptics_ts_data, timer); - /* printk("synaptics_ts_timer_func\n"); */ - - queue_work(synaptics_wq, &ts->work); - - hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL); - return HRTIMER_NORESTART; -} - -static irqreturn_t synaptics_ts_irq_handler(int irq, void *dev_id) -{ - struct synaptics_ts_data *ts = dev_id; - - /* printk("synaptics_ts_irq_handler\n"); */ - disable_irq_nosync(ts->client->irq); - queue_work(synaptics_wq, &ts->work); - return IRQ_HANDLED; -} - -static int synaptics_ts_probe( - struct i2c_client *client, const struct i2c_device_id *id) -{ - struct synaptics_ts_data *ts; - uint8_t buf0[4]; - uint8_t buf1[8]; - struct i2c_msg msg[2]; - int ret = 0; - uint16_t max_x, max_y; - int fuzz_x, fuzz_y, fuzz_p, fuzz_w; - struct synaptics_i2c_rmi_platform_data *pdata; - unsigned long irqflags; - int inactive_area_left; - int inactive_area_right; - int inactive_area_top; - int inactive_area_bottom; - int snap_left_on; - int snap_left_off; - int snap_right_on; - int snap_right_off; - int snap_top_on; - int snap_top_off; - int snap_bottom_on; - int snap_bottom_off; - uint32_t panel_version; - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - printk(KERN_ERR "synaptics_ts_probe: need I2C_FUNC_I2C\n"); - ret = -ENODEV; - goto err_check_functionality_failed; - } - - ts = kzalloc(sizeof(*ts), GFP_KERNEL); - if (ts == NULL) { - ret = -ENOMEM; - goto err_alloc_data_failed; - } - INIT_WORK(&ts->work, synaptics_ts_work_func); - ts->client = client; - i2c_set_clientdata(client, ts); - pdata = client->dev.platform_data; - if (pdata) - ts->power = pdata->power; - if (ts->power) { - ret = ts->power(1); - if (ret < 0) { - printk(KERN_ERR "synaptics_ts_probe power on failed\n"); - goto err_power_failed; - } - } - - ret = i2c_smbus_write_byte_data(ts->client, 0xf4, 0x01); /* device command = reset */ - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_write_byte_data failed\n"); - /* fail? */ - } - { - int retry = 10; - while (retry-- > 0) { - ret = i2c_smbus_read_byte_data(ts->client, 0xe4); - if (ret >= 0) - break; - msleep(100); - } - } - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_read_byte_data failed\n"); - goto err_detect_failed; - } - printk(KERN_INFO "synaptics_ts_probe: Product Major Version %x\n", ret); - panel_version = ret << 8; - ret = i2c_smbus_read_byte_data(ts->client, 0xe5); - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_read_byte_data failed\n"); - goto err_detect_failed; - } - printk(KERN_INFO "synaptics_ts_probe: Product Minor Version %x\n", ret); - panel_version |= ret; - - ret = i2c_smbus_read_byte_data(ts->client, 0xe3); - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_read_byte_data failed\n"); - goto err_detect_failed; - } - printk(KERN_INFO "synaptics_ts_probe: product property %x\n", ret); - - if (pdata) { - while (pdata->version > panel_version) - pdata++; - ts->flags = pdata->flags; - ts->sensitivity_adjust = pdata->sensitivity_adjust; - irqflags = pdata->irqflags; - inactive_area_left = pdata->inactive_left; - inactive_area_right = pdata->inactive_right; - inactive_area_top = pdata->inactive_top; - inactive_area_bottom = pdata->inactive_bottom; - snap_left_on = pdata->snap_left_on; - snap_left_off = pdata->snap_left_off; - snap_right_on = pdata->snap_right_on; - snap_right_off = pdata->snap_right_off; - snap_top_on = pdata->snap_top_on; - snap_top_off = pdata->snap_top_off; - snap_bottom_on = pdata->snap_bottom_on; - snap_bottom_off = pdata->snap_bottom_off; - fuzz_x = pdata->fuzz_x; - fuzz_y = pdata->fuzz_y; - fuzz_p = pdata->fuzz_p; - fuzz_w = pdata->fuzz_w; - } else { - irqflags = 0; - inactive_area_left = 0; - inactive_area_right = 0; - inactive_area_top = 0; - inactive_area_bottom = 0; - snap_left_on = 0; - snap_left_off = 0; - snap_right_on = 0; - snap_right_off = 0; - snap_top_on = 0; - snap_top_off = 0; - snap_bottom_on = 0; - snap_bottom_off = 0; - fuzz_x = 0; - fuzz_y = 0; - fuzz_p = 0; - fuzz_w = 0; - } - - ret = i2c_smbus_read_byte_data(ts->client, 0xf0); - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_read_byte_data failed\n"); - goto err_detect_failed; - } - printk(KERN_INFO "synaptics_ts_probe: device control %x\n", ret); - - ret = i2c_smbus_read_byte_data(ts->client, 0xf1); - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_read_byte_data failed\n"); - goto err_detect_failed; - } - printk(KERN_INFO "synaptics_ts_probe: interrupt enable %x\n", ret); - - ret = i2c_smbus_write_byte_data(ts->client, 0xf1, 0); /* disable interrupt */ - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_write_byte_data failed\n"); - goto err_detect_failed; - } - - msg[0].addr = ts->client->addr; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = buf0; - buf0[0] = 0xe0; - msg[1].addr = ts->client->addr; - msg[1].flags = I2C_M_RD; - msg[1].len = 8; - msg[1].buf = buf1; - ret = i2c_transfer(ts->client->adapter, msg, 2); - if (ret < 0) { - printk(KERN_ERR "i2c_transfer failed\n"); - goto err_detect_failed; - } - printk(KERN_INFO "synaptics_ts_probe: 0xe0: %x %x %x %x %x %x %x %x\n", - buf1[0], buf1[1], buf1[2], buf1[3], - buf1[4], buf1[5], buf1[6], buf1[7]); - - ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x10); /* page select = 0x10 */ - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_write_byte_data failed for page select\n"); - goto err_detect_failed; - } - ret = i2c_smbus_read_word_data(ts->client, 0x02); - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_read_word_data failed\n"); - goto err_detect_failed; - } - ts->has_relative_report = !(ret & 0x100); - printk(KERN_INFO "synaptics_ts_probe: Sensor properties %x\n", ret); - ret = i2c_smbus_read_word_data(ts->client, 0x04); - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_read_word_data failed\n"); - goto err_detect_failed; - } - ts->max[0] = max_x = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8); - ret = i2c_smbus_read_word_data(ts->client, 0x06); - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_read_word_data failed\n"); - goto err_detect_failed; - } - ts->max[1] = max_y = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8); - if (ts->flags & SYNAPTICS_SWAP_XY) - swap(max_x, max_y); - - ret = synaptics_init_panel(ts); /* will also switch back to page 0x04 */ - if (ret < 0) { - printk(KERN_ERR "synaptics_init_panel failed\n"); - goto err_detect_failed; - } - - ts->input_dev = input_allocate_device(); - if (ts->input_dev == NULL) { - ret = -ENOMEM; - printk(KERN_ERR "synaptics_ts_probe: Failed to allocate input device\n"); - goto err_input_dev_alloc_failed; - } - ts->input_dev->name = "synaptics-rmi-touchscreen"; - set_bit(EV_SYN, ts->input_dev->evbit); - set_bit(EV_KEY, ts->input_dev->evbit); - set_bit(BTN_TOUCH, ts->input_dev->keybit); - set_bit(BTN_2, ts->input_dev->keybit); - set_bit(EV_ABS, ts->input_dev->evbit); - inactive_area_left = inactive_area_left * max_x / 0x10000; - inactive_area_right = inactive_area_right * max_x / 0x10000; - inactive_area_top = inactive_area_top * max_y / 0x10000; - inactive_area_bottom = inactive_area_bottom * max_y / 0x10000; - snap_left_on = snap_left_on * max_x / 0x10000; - snap_left_off = snap_left_off * max_x / 0x10000; - snap_right_on = snap_right_on * max_x / 0x10000; - snap_right_off = snap_right_off * max_x / 0x10000; - snap_top_on = snap_top_on * max_y / 0x10000; - snap_top_off = snap_top_off * max_y / 0x10000; - snap_bottom_on = snap_bottom_on * max_y / 0x10000; - snap_bottom_off = snap_bottom_off * max_y / 0x10000; - fuzz_x = fuzz_x * max_x / 0x10000; - fuzz_y = fuzz_y * max_y / 0x10000; - ts->snap_down[!!(ts->flags & SYNAPTICS_SWAP_XY)] = -inactive_area_left; - ts->snap_up[!!(ts->flags & SYNAPTICS_SWAP_XY)] = max_x + inactive_area_right; - ts->snap_down[!(ts->flags & SYNAPTICS_SWAP_XY)] = -inactive_area_top; - ts->snap_up[!(ts->flags & SYNAPTICS_SWAP_XY)] = max_y + inactive_area_bottom; - ts->snap_down_on[!!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_left_on; - ts->snap_down_off[!!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_left_off; - ts->snap_up_on[!!(ts->flags & SYNAPTICS_SWAP_XY)] = max_x - snap_right_on; - ts->snap_up_off[!!(ts->flags & SYNAPTICS_SWAP_XY)] = max_x - snap_right_off; - ts->snap_down_on[!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_top_on; - ts->snap_down_off[!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_top_off; - ts->snap_up_on[!(ts->flags & SYNAPTICS_SWAP_XY)] = max_y - snap_bottom_on; - ts->snap_up_off[!(ts->flags & SYNAPTICS_SWAP_XY)] = max_y - snap_bottom_off; - printk(KERN_INFO "synaptics_ts_probe: max_x %d, max_y %d\n", max_x, max_y); - printk(KERN_INFO "synaptics_ts_probe: inactive_x %d %d, inactive_y %d %d\n", - inactive_area_left, inactive_area_right, - inactive_area_top, inactive_area_bottom); - printk(KERN_INFO "synaptics_ts_probe: snap_x %d-%d %d-%d, snap_y %d-%d %d-%d\n", - snap_left_on, snap_left_off, snap_right_on, snap_right_off, - snap_top_on, snap_top_off, snap_bottom_on, snap_bottom_off); - input_set_abs_params(ts->input_dev, ABS_X, -inactive_area_left, max_x + inactive_area_right, fuzz_x, 0); - input_set_abs_params(ts->input_dev, ABS_Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0); - input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, fuzz_p, 0); - input_set_abs_params(ts->input_dev, ABS_TOOL_WIDTH, 0, 15, fuzz_w, 0); - input_set_abs_params(ts->input_dev, ABS_HAT0X, -inactive_area_left, max_x + inactive_area_right, fuzz_x, 0); - input_set_abs_params(ts->input_dev, ABS_HAT0Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0); - input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, -inactive_area_left, max_x + inactive_area_right, fuzz_x, 0); - input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0); - input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, fuzz_p, 0); - input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 15, fuzz_w, 0); - /* ts->input_dev->name = ts->keypad_info->name; */ - ret = input_register_device(ts->input_dev); - if (ret) { - printk(KERN_ERR "synaptics_ts_probe: Unable to register %s input device\n", ts->input_dev->name); - goto err_input_register_device_failed; - } - if (client->irq) { - ret = request_irq(client->irq, synaptics_ts_irq_handler, irqflags, client->name, ts); - if (ret == 0) { - ret = i2c_smbus_write_byte_data(ts->client, 0xf1, 0x01); /* enable abs int */ - if (ret) - free_irq(client->irq, ts); - } - if (ret == 0) - ts->use_irq = 1; - else - dev_err(&client->dev, "request_irq failed\n"); - } - if (!ts->use_irq) { - hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - ts->timer.function = synaptics_ts_timer_func; - hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); - } -#ifdef CONFIG_HAS_EARLYSUSPEND - ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; - ts->early_suspend.suspend = synaptics_ts_early_suspend; - ts->early_suspend.resume = synaptics_ts_late_resume; - register_early_suspend(&ts->early_suspend); -#endif - - printk(KERN_INFO "synaptics_ts_probe: Start touchscreen %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "interrupt" : "polling"); - - return 0; - -err_input_register_device_failed: - input_free_device(ts->input_dev); - -err_input_dev_alloc_failed: -err_detect_failed: -err_power_failed: - kfree(ts); -err_alloc_data_failed: -err_check_functionality_failed: - return ret; -} - -static int synaptics_ts_remove(struct i2c_client *client) -{ - struct synaptics_ts_data *ts = i2c_get_clientdata(client); - unregister_early_suspend(&ts->early_suspend); - if (ts->use_irq) - free_irq(client->irq, ts); - else - hrtimer_cancel(&ts->timer); - input_unregister_device(ts->input_dev); - kfree(ts); - return 0; -} - -static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg) -{ - int ret; - struct synaptics_ts_data *ts = i2c_get_clientdata(client); - - if (ts->use_irq) - disable_irq(client->irq); - else - hrtimer_cancel(&ts->timer); - ret = cancel_work_sync(&ts->work); - if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */ - enable_irq(client->irq); - ret = i2c_smbus_write_byte_data(ts->client, 0xf1, 0); /* disable interrupt */ - if (ret < 0) - printk(KERN_ERR "synaptics_ts_suspend: i2c_smbus_write_byte_data failed\n"); - - ret = i2c_smbus_write_byte_data(client, 0xf0, 0x86); /* deep sleep */ - if (ret < 0) - printk(KERN_ERR "synaptics_ts_suspend: i2c_smbus_write_byte_data failed\n"); - if (ts->power) { - ret = ts->power(0); - if (ret < 0) - printk(KERN_ERR "synaptics_ts_resume power off failed\n"); - } - return 0; -} - -static int synaptics_ts_resume(struct i2c_client *client) -{ - int ret; - struct synaptics_ts_data *ts = i2c_get_clientdata(client); - - if (ts->power) { - ret = ts->power(1); - if (ret < 0) - printk(KERN_ERR "synaptics_ts_resume power on failed\n"); - } - - synaptics_init_panel(ts); - - if (ts->use_irq) - enable_irq(client->irq); - - if (!ts->use_irq) - hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); - else - i2c_smbus_write_byte_data(ts->client, 0xf1, 0x01); /* enable abs int */ - - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void synaptics_ts_early_suspend(struct early_suspend *h) -{ - struct synaptics_ts_data *ts; - ts = container_of(h, struct synaptics_ts_data, early_suspend); - synaptics_ts_suspend(ts->client, PMSG_SUSPEND); -} - -static void synaptics_ts_late_resume(struct early_suspend *h) -{ - struct synaptics_ts_data *ts; - ts = container_of(h, struct synaptics_ts_data, early_suspend); - synaptics_ts_resume(ts->client); -} -#endif - -static const struct i2c_device_id synaptics_ts_id[] = { - { SYNAPTICS_I2C_RMI_NAME, 0 }, - { } -}; - -static struct i2c_driver synaptics_ts_driver = { - .probe = synaptics_ts_probe, - .remove = synaptics_ts_remove, -#ifndef CONFIG_HAS_EARLYSUSPEND - .suspend = synaptics_ts_suspend, - .resume = synaptics_ts_resume, -#endif - .id_table = synaptics_ts_id, - .driver = { - .name = SYNAPTICS_I2C_RMI_NAME, - }, -}; - -static int __devinit synaptics_ts_init(void) -{ - synaptics_wq = create_singlethread_workqueue("synaptics_wq"); - if (!synaptics_wq) - return -ENOMEM; - return i2c_add_driver(&synaptics_ts_driver); -} - -static void __exit synaptics_ts_exit(void) -{ - i2c_del_driver(&synaptics_ts_driver); - if (synaptics_wq) - destroy_workqueue(synaptics_wq); -} - -module_init(synaptics_ts_init); -module_exit(synaptics_ts_exit); - -MODULE_DESCRIPTION("Synaptics Touchscreen Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 492aa520b9df..3913f47ef86d 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c @@ -616,13 +616,7 @@ static void int_in_work(struct work_struct *work) if (rc == 0) /* success, resubmit interrupt read URB */ rc = usb_submit_urb(urb, GFP_ATOMIC); - - switch (rc) { - case 0: /* success */ - case -ENODEV: /* device gone */ - case -EINVAL: /* URB already resubmitted, or terminal badness */ - break; - default: /* failure: try to recover by resetting the device */ + if (rc != 0 && rc != -ENODEV) { dev_err(cs->dev, "clear halt failed: %s\n", get_usb_rcmsg(rc)); rc = usb_lock_device_for_reset(ucs->udev, ucs->interface); if (rc == 0) { @@ -2443,9 +2437,7 @@ static void gigaset_disconnect(struct usb_interface *interface) } /* gigaset_suspend - * This function is called before the USB connection is suspended - * or before the USB device is reset. - * In the latter case, message == PMSG_ON. + * This function is called before the USB connection is suspended. */ static int gigaset_suspend(struct usb_interface *intf, pm_message_t message) { @@ -2501,12 +2493,7 @@ static int gigaset_suspend(struct usb_interface *intf, pm_message_t message) del_timer_sync(&ucs->timer_atrdy); del_timer_sync(&ucs->timer_cmd_in); del_timer_sync(&ucs->timer_int_in); - - /* don't try to cancel int_in_wq from within reset as it - * might be the one requesting the reset - */ - if (message.event != PM_EVENT_ON) - cancel_work_sync(&ucs->int_in_wq); + cancel_work_sync(&ucs->int_in_wq); gig_dbg(DEBUG_SUSPEND, "suspend complete"); return 0; diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c index 483ac00ae35b..658e75f18d05 100644 --- a/drivers/isdn/gigaset/capi.c +++ b/drivers/isdn/gigaset/capi.c @@ -14,7 +14,6 @@ #include "gigaset.h" #include #include -#include #include #include #include @@ -223,14 +222,10 @@ get_appl(struct gigaset_capi_ctr *iif, u16 appl) static inline void dump_cmsg(enum debuglevel level, const char *tag, _cmsg *p) { #ifdef CONFIG_GIGASET_DEBUG - /* dump at most 20 messages in 20 secs */ - static DEFINE_RATELIMIT_STATE(msg_dump_ratelimit, 20 * HZ, 20); _cdebbuf *cdb; if (!(gigaset_debuglevel & level)) return; - if (!___ratelimit(&msg_dump_ratelimit, tag)) - return; cdb = capi_cmsg2str(p); if (cdb) { @@ -263,8 +258,6 @@ static inline void dump_rawmsg(enum debuglevel level, const char *tag, CAPIMSG_APPID(data), CAPIMSG_MSGID(data), l, CAPIMSG_CONTROL(data)); l -= 12; - if (l <= 0) - return; dbgline = kmalloc(3*l, GFP_ATOMIC); if (!dbgline) return; @@ -2064,6 +2057,12 @@ static void do_reset_b3_req(struct gigaset_capi_ctr *iif, CapiResetProcedureNotSupportedByCurrentProtocol); } +/* + * dump unsupported/ignored messages at most twice per minute, + * some apps send those very frequently + */ +static unsigned long ignored_msg_dump_time; + /* * unsupported CAPI message handler */ @@ -2073,7 +2072,8 @@ static void do_unsupported(struct gigaset_capi_ctr *iif, { /* decode message */ capi_message2cmsg(&iif->acmsg, skb->data); - dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); + if (printk_timed_ratelimit(&ignored_msg_dump_time, 30 * 1000)) + dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState); } @@ -2084,9 +2084,11 @@ static void do_nothing(struct gigaset_capi_ctr *iif, struct gigaset_capi_appl *ap, struct sk_buff *skb) { - /* decode message */ - capi_message2cmsg(&iif->acmsg, skb->data); - dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); + if (printk_timed_ratelimit(&ignored_msg_dump_time, 30 * 1000)) { + /* decode message */ + capi_message2cmsg(&iif->acmsg, skb->data); + dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); + } dev_kfree_skb_any(skb); } diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index b145b5acee9d..97988111e45a 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c @@ -2531,9 +2531,6 @@ static void _isdn_setup(struct net_device *dev) /* Setup the generic properties */ dev->flags = IFF_NOARP|IFF_POINTOPOINT; - - /* isdn prepends a header in the tx path, can't share skbs */ - dev->priv_flags &= ~IFF_TX_SKB_SHARING; dev->header_ops = NULL; dev->netdev_ops = &isdn_netdev_ops; diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c index 509135f225db..d497db0a26d0 100644 --- a/drivers/isdn/isdnloop/isdnloop.c +++ b/drivers/isdn/isdnloop/isdnloop.c @@ -16,6 +16,7 @@ #include #include "isdnloop.h" +static char *revision = "$Revision: 1.11.6.7 $"; static char *isdnloop_id = "loop0"; MODULE_DESCRIPTION("ISDN4Linux: Pseudo Driver that simulates an ISDN card"); @@ -1493,6 +1494,17 @@ isdnloop_addcard(char *id1) static int __init isdnloop_init(void) { + char *p; + char rev[10]; + + if ((p = strchr(revision, ':'))) { + strcpy(rev, p + 1); + p = strchr(rev, '$'); + *p = 0; + } else + strcpy(rev, " ??? "); + printk(KERN_NOTICE "isdnloop-ISDN-driver Rev%s\n", rev); + if (isdnloop_id) return (isdnloop_addcard(isdnloop_id)); diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index b84e46bdedce..713d43b4e563 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -466,12 +466,6 @@ config LEDS_TRIGGER_DEFAULT_ON This allows LEDs to be initialised in the ON state. If unsure, say Y. -config LEDS_TRIGGER_SLEEP - tristate "LED Sleep Mode Trigger" - depends on LEDS_TRIGGERS && HAS_EARLYSUSPEND - help - This turns LEDs on when the screen is off but the cpu still running. - comment "iptables trigger is under Netfilter config (LED target)" depends on LEDS_TRIGGERS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index cb77b9bb2f98..bbfd2e367dc0 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -54,4 +54,3 @@ obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o obj-$(CONFIG_LEDS_TRIGGER_GPIO) += ledtrig-gpio.o obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o -obj-$(CONFIG_LEDS_TRIGGER_SLEEP) += ledtrig-sleep.o diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 6d5628bb0601..dc3d3d83191a 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -267,8 +267,6 @@ void led_blink_set(struct led_classdev *led_cdev, unsigned long *delay_on, unsigned long *delay_off) { - del_timer_sync(&led_cdev->blink_timer); - if (led_cdev->blink_set && !led_cdev->blink_set(led_cdev, delay_on, delay_off)) return; diff --git a/drivers/leds/ledtrig-sleep.c b/drivers/leds/ledtrig-sleep.c deleted file mode 100644 index f16404212152..000000000000 --- a/drivers/leds/ledtrig-sleep.c +++ /dev/null @@ -1,80 +0,0 @@ -/* drivers/leds/ledtrig-sleep.c - * - * Copyright (C) 2007 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include - -static int ledtrig_sleep_pm_callback(struct notifier_block *nfb, - unsigned long action, - void *ignored); - -DEFINE_LED_TRIGGER(ledtrig_sleep) -static struct notifier_block ledtrig_sleep_pm_notifier = { - .notifier_call = ledtrig_sleep_pm_callback, - .priority = 0, -}; - -static void ledtrig_sleep_early_suspend(struct early_suspend *h) -{ - led_trigger_event(ledtrig_sleep, LED_FULL); -} - -static void ledtrig_sleep_early_resume(struct early_suspend *h) -{ - led_trigger_event(ledtrig_sleep, LED_OFF); -} - -static struct early_suspend ledtrig_sleep_early_suspend_handler = { - .suspend = ledtrig_sleep_early_suspend, - .resume = ledtrig_sleep_early_resume, -}; - -static int ledtrig_sleep_pm_callback(struct notifier_block *nfb, - unsigned long action, - void *ignored) -{ - switch (action) { - case PM_HIBERNATION_PREPARE: - case PM_SUSPEND_PREPARE: - led_trigger_event(ledtrig_sleep, LED_OFF); - return NOTIFY_OK; - case PM_POST_HIBERNATION: - case PM_POST_SUSPEND: - led_trigger_event(ledtrig_sleep, LED_FULL); - return NOTIFY_OK; - } - - return NOTIFY_DONE; -} - -static int __init ledtrig_sleep_init(void) -{ - led_trigger_register_simple("sleep", &ledtrig_sleep); - register_pm_notifier(&ledtrig_sleep_pm_notifier); - register_early_suspend(&ledtrig_sleep_early_suspend_handler); - return 0; -} - -static void __exit ledtrig_sleep_exit(void) -{ - unregister_early_suspend(&ledtrig_sleep_early_suspend_handler); - unregister_pm_notifier(&ledtrig_sleep_pm_notifier); - led_trigger_unregister_simple(ledtrig_sleep); -} - -module_init(ledtrig_sleep_init); -module_exit(ledtrig_sleep_exit); - diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c index 328c64c0841c..d87c9d02f786 100644 --- a/drivers/leds/ledtrig-timer.c +++ b/drivers/leds/ledtrig-timer.c @@ -41,7 +41,6 @@ static ssize_t led_delay_on_store(struct device *dev, if (count == size) { led_blink_set(led_cdev, &state, &led_cdev->blink_delay_off); - led_cdev->blink_delay_on = state; ret = count; } @@ -70,7 +69,6 @@ static ssize_t led_delay_off_store(struct device *dev, if (count == size) { led_blink_set(led_cdev, &led_cdev->blink_delay_on, &state); - led_cdev->blink_delay_off = state; ret = count; } diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 2eba9a12a6ab..574b09afedd3 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -1897,9 +1897,7 @@ int bitmap_load(mddev_t *mddev) * re-add of a missing device */ start = mddev->recovery_cp; - mutex_lock(&mddev->bitmap_info.mutex); err = bitmap_init_from_disk(bitmap, start); - mutex_unlock(&mddev->bitmap_info.mutex); } if (err) goto out; @@ -1984,8 +1982,6 @@ location_store(mddev_t *mddev, const char *buf, size_t len) if (mddev->pers) { mddev->pers->quiesce(mddev, 1); rv = bitmap_create(mddev); - if (!rv) - rv = bitmap_load(mddev); if (rv) { bitmap_destroy(mddev); mddev->bitmap_info.offset = 0; diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 6f906bc9328b..c8827ffd85bb 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -177,6 +177,7 @@ struct crypt_config { #define MIN_IOS 16 #define MIN_POOL_PAGES 32 +#define MIN_BIO_PAGES 8 static struct kmem_cache *_crypt_io_pool; @@ -848,11 +849,12 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size, } /* - * If additional pages cannot be allocated without waiting, - * return a partially-allocated bio. The caller will then try - * to allocate more bios while submitting this partial bio. + * if additional pages cannot be allocated without waiting, + * return a partially allocated bio, the caller will then try + * to allocate additional bios while submitting this partial bio */ - gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT; + if (i == (MIN_BIO_PAGES - 1)) + gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT; len = (size > PAGE_SIZE) ? PAGE_SIZE : size; @@ -1045,14 +1047,16 @@ static void kcryptd_queue_io(struct dm_crypt_io *io) queue_work(cc->io_queue, &io->work); } -static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io, int async) +static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io, + int error, int async) { struct bio *clone = io->ctx.bio_out; struct crypt_config *cc = io->target->private; - if (unlikely(io->error < 0)) { + if (unlikely(error < 0)) { crypt_free_buffer_pages(cc, clone); bio_put(clone); + io->error = -EIO; crypt_dec_pending(io); return; } @@ -1103,16 +1107,12 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) sector += bio_sectors(clone); crypt_inc_pending(io); - r = crypt_convert(cc, &io->ctx); - if (r < 0) - io->error = -EIO; - crypt_finished = atomic_dec_and_test(&io->ctx.pending); /* Encryption was already finished, submit io now */ if (crypt_finished) { - kcryptd_crypt_write_io_submit(io, 0); + kcryptd_crypt_write_io_submit(io, r, 0); /* * If there was an error, do not try next fragments. @@ -1163,8 +1163,11 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) crypt_dec_pending(io); } -static void kcryptd_crypt_read_done(struct dm_crypt_io *io) +static void kcryptd_crypt_read_done(struct dm_crypt_io *io, int error) { + if (unlikely(error < 0)) + io->error = -EIO; + crypt_dec_pending(io); } @@ -1179,11 +1182,9 @@ static void kcryptd_crypt_read_convert(struct dm_crypt_io *io) io->sector); r = crypt_convert(cc, &io->ctx); - if (r < 0) - io->error = -EIO; if (atomic_dec_and_test(&io->ctx.pending)) - kcryptd_crypt_read_done(io); + kcryptd_crypt_read_done(io, r); crypt_dec_pending(io); } @@ -1204,18 +1205,15 @@ static void kcryptd_async_done(struct crypto_async_request *async_req, if (!error && cc->iv_gen_ops && cc->iv_gen_ops->post) error = cc->iv_gen_ops->post(cc, iv_of_dmreq(cc, dmreq), dmreq); - if (error < 0) - io->error = -EIO; - mempool_free(req_of_dmreq(cc, dmreq), cc->req_pool); if (!atomic_dec_and_test(&ctx->pending)) return; if (bio_data_dir(io->base_bio) == READ) - kcryptd_crypt_read_done(io); + kcryptd_crypt_read_done(io, error); else - kcryptd_crypt_write_io_submit(io, 1); + kcryptd_crypt_write_io_submit(io, error, 1); } static void kcryptd_crypt(struct work_struct *work) diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c index 7344534294aa..0bdb201c2c2a 100644 --- a/drivers/md/dm-exception-store.c +++ b/drivers/md/dm-exception-store.c @@ -282,7 +282,7 @@ int dm_exception_store_init(void) return 0; persistent_fail: - dm_transient_snapshot_exit(); + dm_persistent_snapshot_exit(); transient_fail: return r; } diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index 3e90b8014f98..ea790623c30b 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c @@ -149,17 +149,8 @@ static int flakey_status(struct dm_target *ti, status_type_t type, static int flakey_ioctl(struct dm_target *ti, unsigned int cmd, unsigned long arg) { struct flakey_c *fc = ti->private; - struct dm_dev *dev = fc->dev; - int r = 0; - /* - * Only pass ioctls through if the device sizes match exactly. - */ - if (fc->start || - ti->len != i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT) - r = scsi_verify_blk_ioctl(NULL, cmd); - - return r ? : __blkdev_driver_ioctl(dev->bdev, dev->mode, cmd, arg); + return __blkdev_driver_ioctl(fc->dev->bdev, fc->dev->mode, cmd, arg); } static int flakey_merge(struct dm_target *ti, struct bvec_merge_data *bvm, diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index ea5dd289fe2a..2067288f61f9 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -38,8 +38,6 @@ struct io { struct dm_io_client *client; io_notify_fn callback; void *context; - void *vma_invalidate_address; - unsigned long vma_invalidate_size; } __attribute__((aligned(DM_IO_MAX_REGIONS))); static struct kmem_cache *_dm_io_cache; @@ -118,10 +116,6 @@ static void dec_count(struct io *io, unsigned int region, int error) set_bit(region, &io->error_bits); if (atomic_dec_and_test(&io->count)) { - if (io->vma_invalidate_size) - invalidate_kernel_vmap_range(io->vma_invalidate_address, - io->vma_invalidate_size); - if (io->sleeper) wake_up_process(io->sleeper); @@ -165,9 +159,6 @@ struct dpages { unsigned context_u; void *context_ptr; - - void *vma_invalidate_address; - unsigned long vma_invalidate_size; }; /* @@ -296,8 +287,6 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, unsigned offset; unsigned num_bvecs; sector_t remaining = where->count; - struct request_queue *q = bdev_get_queue(where->bdev); - sector_t discard_sectors; /* * where->count may be zero if rw holds a flush and we need to @@ -307,12 +296,9 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, /* * Allocate a suitably sized-bio. */ - if (rw & REQ_DISCARD) - num_bvecs = 1; - else - num_bvecs = min_t(int, bio_get_nr_vecs(where->bdev), - dm_sector_div_up(remaining, (PAGE_SIZE >> SECTOR_SHIFT))); - + num_bvecs = dm_sector_div_up(remaining, + (PAGE_SIZE >> SECTOR_SHIFT)); + num_bvecs = min_t(int, bio_get_nr_vecs(where->bdev), num_bvecs); bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios); bio->bi_sector = where->sector + (where->count - remaining); bio->bi_bdev = where->bdev; @@ -320,14 +306,10 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, bio->bi_destructor = dm_bio_destructor; store_io_and_region_in_bio(bio, io, region); - if (rw & REQ_DISCARD) { - discard_sectors = min_t(sector_t, q->limits.max_discard_sectors, remaining); - bio->bi_size = discard_sectors << SECTOR_SHIFT; - remaining -= discard_sectors; - } else while (remaining) { - /* - * Try and add as many pages as possible. - */ + /* + * Try and add as many pages as possible. + */ + while (remaining) { dp->get_page(dp, &page, &len, &offset); len = min(len, to_bytes(remaining)); if (!bio_add_page(bio, page, len, offset)) @@ -395,9 +377,6 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, io->sleeper = current; io->client = client; - io->vma_invalidate_address = dp->vma_invalidate_address; - io->vma_invalidate_size = dp->vma_invalidate_size; - dispatch_io(rw, num_regions, where, dp, io, 1); while (1) { @@ -436,21 +415,13 @@ static int async_io(struct dm_io_client *client, unsigned int num_regions, io->callback = fn; io->context = context; - io->vma_invalidate_address = dp->vma_invalidate_address; - io->vma_invalidate_size = dp->vma_invalidate_size; - dispatch_io(rw, num_regions, where, dp, io, 0); return 0; } -static int dp_init(struct dm_io_request *io_req, struct dpages *dp, - unsigned long size) +static int dp_init(struct dm_io_request *io_req, struct dpages *dp) { /* Set up dpages based on memory type */ - - dp->vma_invalidate_address = NULL; - dp->vma_invalidate_size = 0; - switch (io_req->mem.type) { case DM_IO_PAGE_LIST: list_dp_init(dp, io_req->mem.ptr.pl, io_req->mem.offset); @@ -461,11 +432,6 @@ static int dp_init(struct dm_io_request *io_req, struct dpages *dp, break; case DM_IO_VMA: - flush_kernel_vmap_range(io_req->mem.ptr.vma, size); - if ((io_req->bi_rw & RW_MASK) == READ) { - dp->vma_invalidate_address = io_req->mem.ptr.vma; - dp->vma_invalidate_size = size; - } vm_dp_init(dp, io_req->mem.ptr.vma); break; @@ -494,7 +460,7 @@ int dm_io(struct dm_io_request *io_req, unsigned num_regions, int r; struct dpages dp; - r = dp_init(io_req, &dp, (unsigned long)where->count << SECTOR_SHIFT); + r = dp_init(io_req, &dp); if (r) return r; diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index bd3b294eeadf..4cacdad2270a 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -1524,14 +1524,6 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl **param) if (copy_from_user(dmi, user, tmp.data_size)) goto bad; - /* - * Abort if something changed the ioctl data while it was being copied. - */ - if (dmi->data_size != tmp.data_size) { - DMERR("rejecting ioctl: data size modified while processing parameters"); - goto bad; - } - /* Wipe the user buffer so we do not return it to userspace */ if (secure_data && clear_user(user, tmp.data_size)) goto bad; diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index 9728839f844a..3921e3bb43c1 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c @@ -116,17 +116,7 @@ static int linear_ioctl(struct dm_target *ti, unsigned int cmd, unsigned long arg) { struct linear_c *lc = (struct linear_c *) ti->private; - struct dm_dev *dev = lc->dev; - int r = 0; - - /* - * Only pass ioctls through if the device sizes match exactly. - */ - if (lc->start || - ti->len != i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT) - r = scsi_verify_blk_ioctl(NULL, cmd); - - return r ? : __blkdev_driver_ioctl(dev->bdev, dev->mode, cmd, arg); + return __blkdev_driver_ioctl(lc->dev->bdev, lc->dev->mode, cmd, arg); } static int linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm, diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 70373bfa20bc..aa4e570c2cb5 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -807,11 +807,6 @@ static int parse_features(struct arg_set *as, struct multipath *m) if (!argc) return 0; - if (argc > as->argc) { - ti->error = "not enough arguments for features"; - return -EINVAL; - } - do { param_name = shift(as); argc--; @@ -1584,12 +1579,6 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, spin_unlock_irqrestore(&m->lock, flags); - /* - * Only pass ioctls through if the device sizes match exactly. - */ - if (!r && ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT) - r = scsi_verify_blk_ioctl(NULL, cmd); - return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg); } diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 437ae1825f13..e5d8904fc8f6 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -468,7 +468,6 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv) INIT_WORK(&rs->md.event_work, do_table_event); ti->split_io = rs->md.chunk_sectors; ti->private = rs; - ti->num_flush_requests = 1; mutex_lock(&rs->md.reconfig_mutex); ret = md_run(&rs->md); diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 42ef54f9260c..9bfd057be686 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -1210,7 +1210,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, * We need to dec pending if this was a write. */ if (rw == WRITE) { - if (!(bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))) + if (!(bio->bi_rw & REQ_FLUSH)) dm_rh_dec(ms->rh, map_context->ll); return error; } diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c index 69732e03eb34..7771ed212182 100644 --- a/drivers/md/dm-region-hash.c +++ b/drivers/md/dm-region-hash.c @@ -404,9 +404,6 @@ void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio) return; } - if (bio->bi_rw & REQ_DISCARD) - return; - /* We must inform the log that the sync count has changed. */ log->type->set_region_sync(log, region, 0); @@ -527,7 +524,7 @@ void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios) struct bio *bio; for (bio = bios->head; bio; bio = bio->bi_next) { - if (bio->bi_rw & (REQ_FLUSH | REQ_DISCARD)) + if (bio->bi_rw & REQ_FLUSH) continue; rh_inc(rh, dm_rh_bio_to_region(rh, bio)); } diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index e4ecadf0548a..135c2f1fdbfc 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c @@ -753,7 +753,7 @@ static int persistent_commit_merge(struct dm_exception_store *store, for (i = 0; i < nr_merged; i++) clear_exception(ps, ps->current_committed - 1 - i); - r = area_io(ps, WRITE_FLUSH_FUA); + r = area_io(ps, WRITE); if (r < 0) return r; diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index ebdae6e200c5..451c3bb176d2 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -1184,15 +1184,14 @@ static void dm_table_set_integrity(struct dm_table *t) return; template_disk = dm_table_get_integrity_disk(t, true); - if (template_disk) - blk_integrity_register(dm_disk(t->md), - blk_get_integrity(template_disk)); - else if (blk_integrity_is_initialized(dm_disk(t->md))) + if (!template_disk && + blk_integrity_is_initialized(dm_disk(t->md))) { DMWARN("%s: device no longer has a valid integrity profile", dm_device_name(t->md)); - else - DMWARN("%s: unable to establish an integrity profile", - dm_device_name(t->md)); + return; + } + blk_integrity_register(dm_disk(t->md), + blk_get_integrity(template_disk)); } void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 9f472d50b38d..0cf68b478878 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -37,8 +37,6 @@ static const char *_name = DM_NAME; static unsigned int major = 0; static unsigned int _major = 0; -static DEFINE_IDR(_minor_idr); - static DEFINE_SPINLOCK(_minor_lock); /* * For bio-based dm. @@ -315,12 +313,6 @@ static void __exit dm_exit(void) while (i--) _exits[i](); - - /* - * Should be empty by this point. - */ - idr_remove_all(&_minor_idr); - idr_destroy(&_minor_idr); } /* @@ -745,14 +737,8 @@ static void rq_completed(struct mapped_device *md, int rw, int run_queue) if (!md_in_flight(md)) wake_up(&md->wait); - /* - * Run this off this callpath, as drivers could invoke end_io while - * inside their request_fn (and holding the queue lock). Calling - * back into ->request_fn() could deadlock attempting to grab the - * queue lock again. - */ if (run_queue) - blk_run_queue_async(md->queue); + blk_run_queue(md->queue); /* * dm_put() must be at the end of this function. See the comment above @@ -862,14 +848,10 @@ static void dm_done(struct request *clone, int error, bool mapped) { int r = error; struct dm_rq_target_io *tio = clone->end_io_data; - dm_request_endio_fn rq_end_io = NULL; + dm_request_endio_fn rq_end_io = tio->ti->type->rq_end_io; - if (tio->ti) { - rq_end_io = tio->ti->type->rq_end_io; - - if (mapped && rq_end_io) - r = rq_end_io(tio->ti, clone, error, &tio->info); - } + if (mapped && rq_end_io) + r = rq_end_io(tio->ti, clone, error, &tio->info); if (r <= 0) /* The target wants to complete the I/O */ @@ -1572,6 +1554,15 @@ static int map_request(struct dm_target *ti, struct request *clone, int r, requeued = 0; struct dm_rq_target_io *tio = clone->end_io_data; + /* + * Hold the md reference here for the in-flight I/O. + * We can't rely on the reference count by device opener, + * because the device may be closed during the request completion + * when all bios are completed. + * See the comment in rq_completed() too. + */ + dm_get(md); + tio->ti = ti; r = ti->type->map_rq(ti, clone, &tio->info); switch (r) { @@ -1603,26 +1594,6 @@ static int map_request(struct dm_target *ti, struct request *clone, return requeued; } -static struct request *dm_start_request(struct mapped_device *md, struct request *orig) -{ - struct request *clone; - - blk_start_request(orig); - clone = orig->special; - atomic_inc(&md->pending[rq_data_dir(clone)]); - - /* - * Hold the md reference here for the in-flight I/O. - * We can't rely on the reference count by device opener, - * because the device may be closed during the request completion - * when all bios are completed. - * See the comment in rq_completed() too. - */ - dm_get(md); - - return clone; -} - /* * q->request_fn for request-based dm. * Called with the queue lock held. @@ -1652,21 +1623,14 @@ static void dm_request_fn(struct request_queue *q) pos = blk_rq_pos(rq); ti = dm_table_find_target(map, pos); - if (!dm_target_is_valid(ti)) { - /* - * Must perform setup, that dm_done() requires, - * before calling dm_kill_unmapped_request - */ - DMERR_LIMIT("request attempted access beyond the end of device"); - clone = dm_start_request(md, rq); - dm_kill_unmapped_request(clone, -EIO); - continue; - } + BUG_ON(!dm_target_is_valid(ti)); if (ti->type->busy && ti->type->busy(ti)) goto delay_and_out; - clone = dm_start_request(md, rq); + blk_start_request(rq); + clone = rq->special; + atomic_inc(&md->pending[rq_data_dir(clone)]); spin_unlock(q->queue_lock); if (map_request(ti, clone, md)) @@ -1686,6 +1650,8 @@ delay_and_out: blk_delay_queue(q, HZ / 10); out: dm_table_put(map); + + return; } int dm_underlying_device_busy(struct request_queue *q) @@ -1739,6 +1705,8 @@ static int dm_any_congested(void *congested_data, int bdi_bits) /*----------------------------------------------------------------- * An IDR is used to keep track of allocated minor numbers. *---------------------------------------------------------------*/ +static DEFINE_IDR(_minor_idr); + static void free_minor(int minor) { spin_lock(&_minor_lock); diff --git a/drivers/md/linear.h b/drivers/md/linear.h index 2f2da05b2ce9..0ce29b61605a 100644 --- a/drivers/md/linear.h +++ b/drivers/md/linear.h @@ -10,9 +10,9 @@ typedef struct dev_info dev_info_t; struct linear_private_data { - struct rcu_head rcu; sector_t array_sectors; dev_info_t disks[0]; + struct rcu_head rcu; }; diff --git a/drivers/md/md.c b/drivers/md/md.c index 98262e5336d0..91e31e260b4a 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -61,11 +61,6 @@ static void autostart_arrays(int part); #endif -/* pers_list is a list of registered personalities protected - * by pers_lock. - * pers_lock does extra service to protect accesses to - * mddev->thread when the mutex cannot be held. - */ static LIST_HEAD(pers_list); static DEFINE_SPINLOCK(pers_lock); @@ -348,8 +343,6 @@ void mddev_suspend(mddev_t *mddev) synchronize_rcu(); wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0); mddev->pers->quiesce(mddev, 1); - - del_timer_sync(&mddev->safemode_timer); } EXPORT_SYMBOL_GPL(mddev_suspend); @@ -409,7 +402,7 @@ static void submit_flushes(struct work_struct *ws) atomic_inc(&rdev->nr_pending); atomic_inc(&rdev->nr_pending); rcu_read_unlock(); - bi = bio_alloc_mddev(GFP_NOIO, 0, mddev); + bi = bio_alloc_mddev(GFP_KERNEL, 0, mddev); bi->bi_end_io = md_end_flush; bi->bi_private = rdev; bi->bi_bdev = rdev->bdev; @@ -697,12 +690,7 @@ static void mddev_unlock(mddev_t * mddev) } else mutex_unlock(&mddev->reconfig_mutex); - /* was we've dropped the mutex we need a spinlock to - * make sur the thread doesn't disappear - */ - spin_lock(&pers_lock); md_wakeup_thread(mddev->thread); - spin_unlock(&pers_lock); } static mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr) @@ -1096,14 +1084,8 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version ret = 0; } rdev->sectors = rdev->sb_start; - /* Limit to 4TB as metadata cannot record more than that. - * (not needed for Linear and RAID0 as metadata doesn't - * record this size) - */ - if (rdev->sectors >= (2ULL << 32) && sb->level >= 1) - rdev->sectors = (2ULL << 32) - 2; - if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1) + if (rdev->sectors < sb->size * 2 && sb->level > 1) /* "this cannot possibly happen" ... */ ret = -EINVAL; @@ -1137,7 +1119,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) mddev->clevel[0] = 0; mddev->layout = sb->layout; mddev->raid_disks = sb->raid_disks; - mddev->dev_sectors = ((sector_t)sb->size) * 2; + mddev->dev_sectors = sb->size * 2; mddev->events = ev1; mddev->bitmap_info.offset = 0; mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9; @@ -1379,11 +1361,6 @@ super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) rdev->sb_start = calc_dev_sboffset(rdev); if (!num_sectors || num_sectors > rdev->sb_start) num_sectors = rdev->sb_start; - /* Limit to 4TB as metadata cannot record more than that. - * 4TB == 2^32 KB, or 2*2^32 sectors. - */ - if (num_sectors >= (2ULL << 32) && rdev->mddev->level >= 1) - num_sectors = (2ULL << 32) - 2; md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, rdev->sb_page); md_super_wait(rdev->mddev); @@ -6201,18 +6178,11 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev, return thread; } -void md_unregister_thread(mdk_thread_t **threadp) +void md_unregister_thread(mdk_thread_t *thread) { - mdk_thread_t *thread = *threadp; if (!thread) return; dprintk("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk)); - /* Locking ensures that mddev_unlock does not wake_up a - * non-existent thread - */ - spin_lock(&pers_lock); - *threadp = NULL; - spin_unlock(&pers_lock); kthread_stop(thread->tsk); kfree(thread); @@ -7147,7 +7117,8 @@ static void reap_sync_thread(mddev_t *mddev) mdk_rdev_t *rdev; /* resync has finished, collect result */ - md_unregister_thread(&mddev->sync_thread); + md_unregister_thread(mddev->sync_thread); + mddev->sync_thread = NULL; if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { /* success...*/ diff --git a/drivers/md/md.h b/drivers/md/md.h index ce4e328049d3..1c26c7a08ae6 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -475,7 +475,7 @@ extern int register_md_personality(struct mdk_personality *p); extern int unregister_md_personality(struct mdk_personality *p); extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev), mddev_t *mddev, const char *name); -extern void md_unregister_thread(mdk_thread_t **threadp); +extern void md_unregister_thread(mdk_thread_t *thread); extern void md_wakeup_thread(mdk_thread_t *thread); extern void md_check_recovery(mddev_t *mddev); extern void md_write_start(mddev_t *mddev, struct bio *bi); diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index d5b5fb300171..3535c23af288 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -514,7 +514,8 @@ static int multipath_stop (mddev_t *mddev) { multipath_conf_t *conf = mddev->private; - md_unregister_thread(&mddev->thread); + md_unregister_thread(mddev->thread); + mddev->thread = NULL; blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ mempool_destroy(conf->pool); kfree(conf->multipaths); diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 36f1ed313ae3..f7431b6d8447 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -614,22 +614,9 @@ static void wait_barrier(conf_t *conf) spin_lock_irq(&conf->resync_lock); if (conf->barrier) { conf->nr_waiting++; - /* Wait for the barrier to drop. - * However if there are already pending - * requests (preventing the barrier from - * rising completely), and the - * pre-process bio queue isn't empty, - * then don't wait, as we need to empty - * that queue to get the nr_pending - * count down. - */ - wait_event_lock_irq(conf->wait_barrier, - !conf->barrier || - (conf->nr_pending && - current->bio_list && - !bio_list_empty(current->bio_list)), + wait_event_lock_irq(conf->wait_barrier, !conf->barrier, conf->resync_lock, - ); + ); conf->nr_waiting--; } conf->nr_pending++; @@ -2058,7 +2045,8 @@ static int stop(mddev_t *mddev) raise_barrier(conf); lower_barrier(conf); - md_unregister_thread(&mddev->thread); + md_unregister_thread(mddev->thread); + mddev->thread = NULL; if (conf->r1bio_pool) mempool_destroy(conf->r1bio_pool); kfree(conf->mirrors); diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index b65a7c50eb63..6e846688962f 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -667,22 +667,9 @@ static void wait_barrier(conf_t *conf) spin_lock_irq(&conf->resync_lock); if (conf->barrier) { conf->nr_waiting++; - /* Wait for the barrier to drop. - * However if there are already pending - * requests (preventing the barrier from - * rising completely), and the - * pre-process bio queue isn't empty, - * then don't wait, as we need to empty - * that queue to get the nr_pending - * count down. - */ - wait_event_lock_irq(conf->wait_barrier, - !conf->barrier || - (conf->nr_pending && - current->bio_list && - !bio_list_empty(current->bio_list)), + wait_event_lock_irq(conf->wait_barrier, !conf->barrier, conf->resync_lock, - ); + ); conf->nr_waiting--; } conf->nr_pending++; @@ -1858,12 +1845,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, /* want to reconstruct this device */ rb2 = r10_bio; sect = raid10_find_virt(conf, sector_nr, i); - if (sect >= mddev->resync_max_sectors) { - /* last stripe is not complete - don't - * try to recover this sector. - */ - continue; - } /* Unless we are doing a full sync, we only need * to recover the block if it is set in the bitmap */ @@ -2350,7 +2331,7 @@ static int run(mddev_t *mddev) return 0; out_free_conf: - md_unregister_thread(&mddev->thread); + md_unregister_thread(mddev->thread); if (conf->r10bio_pool) mempool_destroy(conf->r10bio_pool); safe_put_page(conf->tmppage); @@ -2368,7 +2349,8 @@ static int stop(mddev_t *mddev) raise_barrier(conf, 0); lower_barrier(conf); - md_unregister_thread(&mddev->thread); + md_unregister_thread(mddev->thread); + mddev->thread = NULL; blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ if (conf->r10bio_pool) mempool_destroy(conf->r10bio_pool); diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index cff955a04085..b72edf35ec54 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -199,14 +199,12 @@ static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh) BUG_ON(!list_empty(&sh->lru)); BUG_ON(atomic_read(&conf->active_stripes)==0); if (test_bit(STRIPE_HANDLE, &sh->state)) { - if (test_bit(STRIPE_DELAYED, &sh->state) && - !test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) + if (test_bit(STRIPE_DELAYED, &sh->state)) list_add_tail(&sh->lru, &conf->delayed_list); else if (test_bit(STRIPE_BIT_DELAY, &sh->state) && sh->bm_seq - conf->seq_write > 0) list_add_tail(&sh->lru, &conf->bitmap_list); else { - clear_bit(STRIPE_DELAYED, &sh->state); clear_bit(STRIPE_BIT_DELAY, &sh->state); list_add_tail(&sh->lru, &conf->handle_list); } @@ -3080,7 +3078,7 @@ static void handle_stripe5(struct stripe_head *sh) /* Not in-sync */; else if (test_bit(In_sync, &rdev->flags)) set_bit(R5_Insync, &dev->flags); - else if (!test_bit(Faulty, &rdev->flags)) { + else { /* could be in-sync depending on recovery/reshape status */ if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset) set_bit(R5_Insync, &dev->flags); @@ -3122,16 +3120,12 @@ static void handle_stripe5(struct stripe_head *sh) /* check if the array has lost two devices and, if so, some requests might * need to be failed */ - if (s.failed > 1) { - sh->check_state = 0; - sh->reconstruct_state = 0; - if (s.to_read+s.to_write+s.written) - handle_failed_stripe(conf, sh, &s, disks, &return_bi); - if (s.syncing) { - md_done_sync(conf->mddev, STRIPE_SECTORS,0); - clear_bit(STRIPE_SYNCING, &sh->state); - s.syncing = 0; - } + if (s.failed > 1 && s.to_read+s.to_write+s.written) + handle_failed_stripe(conf, sh, &s, disks, &return_bi); + if (s.failed > 1 && s.syncing) { + md_done_sync(conf->mddev, STRIPE_SECTORS,0); + clear_bit(STRIPE_SYNCING, &sh->state); + s.syncing = 0; } /* might be able to return some write requests if the parity block @@ -3375,7 +3369,7 @@ static void handle_stripe6(struct stripe_head *sh) /* Not in-sync */; else if (test_bit(In_sync, &rdev->flags)) set_bit(R5_Insync, &dev->flags); - else if (!test_bit(Faulty, &rdev->flags)) { + else { /* in sync if before recovery_offset */ if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset) set_bit(R5_Insync, &dev->flags); @@ -3418,16 +3412,12 @@ static void handle_stripe6(struct stripe_head *sh) /* check if the array has lost >2 devices and, if so, some requests * might need to be failed */ - if (s.failed > 2) { - sh->check_state = 0; - sh->reconstruct_state = 0; - if (s.to_read+s.to_write+s.written) - handle_failed_stripe(conf, sh, &s, disks, &return_bi); - if (s.syncing) { - md_done_sync(conf->mddev, STRIPE_SECTORS,0); - clear_bit(STRIPE_SYNCING, &sh->state); - s.syncing = 0; - } + if (s.failed > 2 && s.to_read+s.to_write+s.written) + handle_failed_stripe(conf, sh, &s, disks, &return_bi); + if (s.failed > 2 && s.syncing) { + md_done_sync(conf->mddev, STRIPE_SECTORS,0); + clear_bit(STRIPE_SYNCING, &sh->state); + s.syncing = 0; } /* @@ -3848,6 +3838,7 @@ static int chunk_aligned_read(mddev_t *mddev, struct bio * raid_bio) raid_bio->bi_next = (void*)rdev; align_bi->bi_bdev = rdev->bdev; align_bi->bi_flags &= ~(1 << BIO_SEG_VALID); + align_bi->bi_sector += rdev->data_offset; if (!bio_fits_rdev(align_bi)) { /* too big in some way */ @@ -3856,9 +3847,6 @@ static int chunk_aligned_read(mddev_t *mddev, struct bio * raid_bio) return 0; } - /* No reshape active, so we can trust rdev->data_offset */ - align_bi->bi_sector += rdev->data_offset; - spin_lock_irq(&conf->device_lock); wait_event_lock_irq(conf->wait_for_stripe, conf->quiesce == 0, @@ -5174,7 +5162,8 @@ static int run(mddev_t *mddev) return 0; abort: - md_unregister_thread(&mddev->thread); + md_unregister_thread(mddev->thread); + mddev->thread = NULL; if (conf) { print_raid5_conf(conf); free_conf(conf); @@ -5188,7 +5177,8 @@ static int stop(mddev_t *mddev) { raid5_conf_t *conf = mddev->private; - md_unregister_thread(&mddev->thread); + md_unregister_thread(mddev->thread); + mddev->thread = NULL; if (mddev->queue) mddev->queue->backing_dev_info.congested_fn = NULL; free_conf(conf); diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index d5cda35dcc7e..f73287775953 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c @@ -243,7 +243,6 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, if (minor == MAX_DVB_MINORS) { kfree(dvbdevfops); kfree(dvbdev); - up_write(&minor_rwsem); mutex_unlock(&dvbdev_register_lock); return -EINVAL; } diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index a224e94325b7..5eb91b4f8fd0 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -30,11 +30,6 @@ int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, struct dib0700_state *st = d->priv; int ret; - if (mutex_lock_interruptible(&d->usb_mutex) < 0) { - deb_info("could not acquire lock"); - return 0; - } - ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, @@ -51,7 +46,6 @@ int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, if (fwtype != NULL) *fwtype = (st->buf[12] << 24) | (st->buf[13] << 16) | (st->buf[14] << 8) | st->buf[15]; - mutex_unlock(&d->usb_mutex); return ret; } @@ -114,12 +108,7 @@ int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val) { struct dib0700_state *st = d->priv; - int ret; - - if (mutex_lock_interruptible(&d->usb_mutex) < 0) { - deb_info("could not acquire lock"); - return 0; - } + s16 ret; st->buf[0] = REQUEST_SET_GPIO; st->buf[1] = gpio; @@ -127,7 +116,6 @@ int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_ ret = dib0700_ctrl_wr(d, st->buf, 3); - mutex_unlock(&d->usb_mutex); return ret; } @@ -137,11 +125,6 @@ static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets) int ret; if (st->fw_version >= 0x10201) { - if (mutex_lock_interruptible(&d->usb_mutex) < 0) { - deb_info("could not acquire lock"); - return 0; - } - st->buf[0] = REQUEST_SET_USB_XFER_LEN; st->buf[1] = (nb_ts_packets >> 8) & 0xff; st->buf[2] = nb_ts_packets & 0xff; @@ -149,7 +132,6 @@ static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets) deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets); ret = dib0700_ctrl_wr(d, st->buf, 3); - mutex_unlock(&d->usb_mutex); } else { deb_info("this firmware does not allow to change the USB xfer len\n"); ret = -EIO; @@ -226,10 +208,6 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, } else { /* Write request */ - if (mutex_lock_interruptible(&d->usb_mutex) < 0) { - deb_info("could not acquire lock"); - return 0; - } st->buf[0] = REQUEST_NEW_I2C_WRITE; st->buf[1] = msg[i].addr << 1; st->buf[2] = (en_start << 7) | (en_stop << 6) | @@ -249,7 +227,6 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, st->buf, msg[i].len + 4, USB_CTRL_GET_TIMEOUT); - mutex_unlock(&d->usb_mutex); if (result < 0) { deb_info("i2c write error (status = %d)\n", result); break; @@ -272,10 +249,6 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap, if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; - if (mutex_lock_interruptible(&d->usb_mutex) < 0) { - deb_info("could not acquire lock"); - return 0; - } for (i = 0; i < num; i++) { /* fill in the address */ @@ -306,7 +279,6 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap, break; } } - mutex_unlock(&d->usb_mutex); mutex_unlock(&d->i2c_mutex); return i; @@ -365,12 +337,7 @@ static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll, u16 pll_loopdiv, u16 free_div, u16 dsuScaler) { struct dib0700_state *st = d->priv; - int ret; - - if (mutex_lock_interruptible(&d->usb_mutex) < 0) { - deb_info("could not acquire lock"); - return 0; - } + s16 ret; st->buf[0] = REQUEST_SET_CLOCK; st->buf[1] = (en_pll << 7) | (pll_src << 6) | @@ -385,7 +352,6 @@ static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll, st->buf[9] = dsuScaler & 0xff; /* LSB */ ret = dib0700_ctrl_wr(d, st->buf, 10); - mutex_unlock(&d->usb_mutex); return ret; } @@ -394,16 +360,10 @@ int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz) { struct dib0700_state *st = d->priv; u16 divider; - int ret; if (scl_kHz == 0) return -EINVAL; - if (mutex_lock_interruptible(&d->usb_mutex) < 0) { - deb_info("could not acquire lock"); - return 0; - } - st->buf[0] = REQUEST_SET_I2C_PARAM; divider = (u16) (30000 / scl_kHz); st->buf[1] = 0; @@ -419,11 +379,7 @@ int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz) deb_info("setting I2C speed: %04x %04x %04x (%d kHz).", (st->buf[2] << 8) | (st->buf[3]), (st->buf[4] << 8) | st->buf[5], (st->buf[6] << 8) | st->buf[7], scl_kHz); - - ret = dib0700_ctrl_wr(d, st->buf, 8); - mutex_unlock(&d->usb_mutex); - - return ret; + return dib0700_ctrl_wr(d, st->buf, 8); } @@ -559,11 +515,6 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) } } - if (mutex_lock_interruptible(&adap->dev->usb_mutex) < 0) { - deb_info("could not acquire lock"); - return 0; - } - st->buf[0] = REQUEST_ENABLE_VIDEO; /* this bit gives a kind of command, * rather than enabling something or not */ @@ -597,10 +548,7 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) deb_info("data for streaming: %x %x\n", st->buf[1], st->buf[2]); - ret = dib0700_ctrl_wr(adap->dev, st->buf, 4); - mutex_unlock(&adap->dev->usb_mutex); - - return ret; + return dib0700_ctrl_wr(adap->dev, st->buf, 4); } int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type) @@ -609,11 +557,6 @@ int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type) struct dib0700_state *st = d->priv; int new_proto, ret; - if (mutex_lock_interruptible(&d->usb_mutex) < 0) { - deb_info("could not acquire lock"); - return 0; - } - st->buf[0] = REQUEST_SET_RC; st->buf[1] = 0; st->buf[2] = 0; @@ -624,29 +567,23 @@ int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type) else if (rc_type == RC_TYPE_NEC) new_proto = 0; else if (rc_type == RC_TYPE_RC6) { - if (st->fw_version < 0x10200) { - ret = -EINVAL; - goto out; - } + if (st->fw_version < 0x10200) + return -EINVAL; new_proto = 2; - } else { - ret = -EINVAL; - goto out; - } + } else + return -EINVAL; st->buf[1] = new_proto; ret = dib0700_ctrl_wr(d, st->buf, 3); if (ret < 0) { err("ir protocol setup failed"); - goto out; + return ret; } d->props.rc.core.protocol = rc_type; -out: - mutex_unlock(&d->usb_mutex); return ret; } diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c index 536c16c943bd..3db89e3cb0bb 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ b/drivers/media/dvb/dvb-usb/vp7045.c @@ -224,8 +224,26 @@ static struct dvb_usb_device_properties vp7045_properties; static int vp7045_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return dvb_usb_device_init(intf, &vp7045_properties, - THIS_MODULE, NULL, adapter_nr); + struct dvb_usb_device *d; + int ret = dvb_usb_device_init(intf, &vp7045_properties, + THIS_MODULE, &d, adapter_nr); + if (ret) + return ret; + + d->priv = kmalloc(20, GFP_KERNEL); + if (!d->priv) { + dvb_usb_device_exit(intf); + return -ENOMEM; + } + + return ret; +} + +static void vp7045_usb_disconnect(struct usb_interface *intf) +{ + struct dvb_usb_device *d = usb_get_intfdata(intf); + kfree(d->priv); + dvb_usb_device_exit(intf); } static struct usb_device_id vp7045_usb_table [] = { @@ -240,7 +258,7 @@ MODULE_DEVICE_TABLE(usb, vp7045_usb_table); static struct dvb_usb_device_properties vp7045_properties = { .usb_ctrl = CYPRESS_FX2, .firmware = "dvb-usb-vp7045-01.fw", - .size_of_priv = 20, + .size_of_priv = sizeof(u8 *), .num_adapters = 1, .adapter = { @@ -287,7 +305,7 @@ static struct dvb_usb_device_properties vp7045_properties = { static struct usb_driver vp7045_usb_driver = { .name = "dvb_usb_vp7045", .probe = vp7045_usb_probe, - .disconnect = dvb_usb_device_exit, + .disconnect = vp7045_usb_disconnect, .id_table = vp7045_usb_table, }; diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c index dc1cb17a6ea7..1d47d4da7d4c 100644 --- a/drivers/media/dvb/frontends/dib0070.c +++ b/drivers/media/dvb/frontends/dib0070.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "dvb_frontend.h" @@ -79,18 +78,10 @@ struct dib0070_state { struct i2c_msg msg[2]; u8 i2c_write_buffer[3]; u8 i2c_read_buffer[2]; - struct mutex i2c_buffer_lock; }; -static u16 dib0070_read_reg(struct dib0070_state *state, u8 reg) +static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg) { - u16 ret; - - if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return 0; - } - state->i2c_write_buffer[0] = reg; memset(state->msg, 0, 2 * sizeof(struct i2c_msg)); @@ -105,23 +96,13 @@ static u16 dib0070_read_reg(struct dib0070_state *state, u8 reg) if (i2c_transfer(state->i2c, state->msg, 2) != 2) { printk(KERN_WARNING "DiB0070 I2C read failed\n"); - ret = 0; - } else - ret = (state->i2c_read_buffer[0] << 8) - | state->i2c_read_buffer[1]; - - mutex_unlock(&state->i2c_buffer_lock); - return ret; + return 0; + } + return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; } static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) { - int ret; - - if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return -EINVAL; - } state->i2c_write_buffer[0] = reg; state->i2c_write_buffer[1] = val >> 8; state->i2c_write_buffer[2] = val & 0xff; @@ -134,12 +115,9 @@ static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) if (i2c_transfer(state->i2c, state->msg, 1) != 1) { printk(KERN_WARNING "DiB0070 I2C write failed\n"); - ret = -EREMOTEIO; - } else - ret = 0; - - mutex_unlock(&state->i2c_buffer_lock); - return ret; + return -EREMOTEIO; + } + return 0; } #define HARD_RESET(state) do { \ @@ -756,7 +734,6 @@ struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter state->cfg = cfg; state->i2c = i2c; state->fe = fe; - mutex_init(&state->i2c_buffer_lock); fe->tuner_priv = state; if (dib0070_reset(fe) != 0) diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c index b174d1c78583..c9c935ae41e4 100644 --- a/drivers/media/dvb/frontends/dib0090.c +++ b/drivers/media/dvb/frontends/dib0090.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "dvb_frontend.h" @@ -197,7 +196,6 @@ struct dib0090_state { struct i2c_msg msg[2]; u8 i2c_write_buffer[3]; u8 i2c_read_buffer[2]; - struct mutex i2c_buffer_lock; }; struct dib0090_fw_state { @@ -210,18 +208,10 @@ struct dib0090_fw_state { struct i2c_msg msg; u8 i2c_write_buffer[2]; u8 i2c_read_buffer[2]; - struct mutex i2c_buffer_lock; }; static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) { - u16 ret; - - if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return 0; - } - state->i2c_write_buffer[0] = reg; memset(state->msg, 0, 2 * sizeof(struct i2c_msg)); @@ -236,24 +226,14 @@ static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) if (i2c_transfer(state->i2c, state->msg, 2) != 2) { printk(KERN_WARNING "DiB0090 I2C read failed\n"); - ret = 0; - } else - ret = (state->i2c_read_buffer[0] << 8) - | state->i2c_read_buffer[1]; + return 0; + } - mutex_unlock(&state->i2c_buffer_lock); - return ret; + return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; } static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) { - int ret; - - if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return -EINVAL; - } - state->i2c_write_buffer[0] = reg & 0xff; state->i2c_write_buffer[1] = val >> 8; state->i2c_write_buffer[2] = val & 0xff; @@ -266,23 +246,13 @@ static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) if (i2c_transfer(state->i2c, state->msg, 1) != 1) { printk(KERN_WARNING "DiB0090 I2C write failed\n"); - ret = -EREMOTEIO; - } else - ret = 0; - - mutex_unlock(&state->i2c_buffer_lock); - return ret; + return -EREMOTEIO; + } + return 0; } static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg) { - u16 ret; - - if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return 0; - } - state->i2c_write_buffer[0] = reg; memset(&state->msg, 0, sizeof(struct i2c_msg)); @@ -292,24 +262,13 @@ static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg) state->msg.len = 2; if (i2c_transfer(state->i2c, &state->msg, 1) != 1) { printk(KERN_WARNING "DiB0090 I2C read failed\n"); - ret = 0; - } else - ret = (state->i2c_read_buffer[0] << 8) - | state->i2c_read_buffer[1]; - - mutex_unlock(&state->i2c_buffer_lock); - return ret; + return 0; + } + return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; } static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val) { - int ret; - - if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return -EINVAL; - } - state->i2c_write_buffer[0] = val >> 8; state->i2c_write_buffer[1] = val & 0xff; @@ -320,12 +279,9 @@ static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val) state->msg.len = 2; if (i2c_transfer(state->i2c, &state->msg, 1) != 1) { printk(KERN_WARNING "DiB0090 I2C write failed\n"); - ret = -EREMOTEIO; - } else - ret = 0; - - mutex_unlock(&state->i2c_buffer_lock); - return ret; + return -EREMOTEIO; + } + return 0; } #define HARD_RESET(state) do { if (cfg->reset) { if (cfg->sleep) cfg->sleep(fe, 0); msleep(10); cfg->reset(fe, 1); msleep(10); cfg->reset(fe, 0); msleep(10); } } while (0) @@ -2484,7 +2440,6 @@ struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapte st->config = config; st->i2c = i2c; st->fe = fe; - mutex_init(&st->i2c_buffer_lock); fe->tuner_priv = st; if (config->wbd == NULL) @@ -2516,7 +2471,6 @@ struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_ada st->config = config; st->i2c = i2c; st->fe = fe; - mutex_init(&st->i2c_buffer_lock); fe->tuner_priv = st; if (dib0090_fw_reset_digital(fe, st->config) != 0) diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb/frontends/dib7000m.c index dbb76d75c932..79cb1c20df24 100644 --- a/drivers/media/dvb/frontends/dib7000m.c +++ b/drivers/media/dvb/frontends/dib7000m.c @@ -11,7 +11,6 @@ #include #include #include -#include #include "dvb_frontend.h" @@ -56,7 +55,6 @@ struct dib7000m_state { struct i2c_msg msg[2]; u8 i2c_write_buffer[4]; u8 i2c_read_buffer[2]; - struct mutex i2c_buffer_lock; }; enum dib7000m_power_mode { @@ -71,13 +69,6 @@ enum dib7000m_power_mode { static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg) { - u16 ret; - - if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return 0; - } - state->i2c_write_buffer[0] = (reg >> 8) | 0x80; state->i2c_write_buffer[1] = reg & 0xff; @@ -94,21 +85,11 @@ static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg) if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2) dprintk("i2c read error on %d",reg); - ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; - mutex_unlock(&state->i2c_buffer_lock); - - return ret; + return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; } static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val) { - int ret; - - if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return -EINVAL; - } - state->i2c_write_buffer[0] = (reg >> 8) & 0xff; state->i2c_write_buffer[1] = reg & 0xff; state->i2c_write_buffer[2] = (val >> 8) & 0xff; @@ -120,10 +101,7 @@ static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val) state->msg[0].buf = state->i2c_write_buffer; state->msg[0].len = 4; - ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? - -EREMOTEIO : 0); - mutex_unlock(&state->i2c_buffer_lock); - return ret; + return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0; } static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf) { @@ -1407,7 +1385,6 @@ struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, demod = &st->demod; demod->demodulator_priv = st; memcpy(&st->demod.ops, &dib7000m_ops, sizeof(struct dvb_frontend_ops)); - mutex_init(&st->i2c_buffer_lock); st->timf_default = cfg->bw->timf; diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index 292bc19746b9..0c9f40c2a251 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c @@ -10,7 +10,6 @@ #include #include #include -#include #include "dvb_math.h" #include "dvb_frontend.h" @@ -69,7 +68,6 @@ struct dib7000p_state { struct i2c_msg msg[2]; u8 i2c_write_buffer[4]; u8 i2c_read_buffer[2]; - struct mutex i2c_buffer_lock; }; enum dib7000p_power_mode { @@ -83,13 +81,6 @@ static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff); static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) { - u16 ret; - - if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return 0; - } - state->i2c_write_buffer[0] = reg >> 8; state->i2c_write_buffer[1] = reg & 0xff; @@ -106,20 +97,11 @@ static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2) dprintk("i2c read error on %d", reg); - ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; - mutex_unlock(&state->i2c_buffer_lock); - return ret; + return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; } static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val) { - int ret; - - if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return -EINVAL; - } - state->i2c_write_buffer[0] = (reg >> 8) & 0xff; state->i2c_write_buffer[1] = reg & 0xff; state->i2c_write_buffer[2] = (val >> 8) & 0xff; @@ -131,10 +113,7 @@ static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val) state->msg[0].buf = state->i2c_write_buffer; state->msg[0].len = 4; - ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? - -EREMOTEIO : 0); - mutex_unlock(&state->i2c_buffer_lock); - return ret; + return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0; } static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf) @@ -1667,7 +1646,6 @@ int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau return -ENOMEM; dpst->i2c_adap = i2c; - mutex_init(&dpst->i2c_buffer_lock); for (k = no_of_demods - 1; k >= 0; k--) { dpst->cfg = cfg[k]; @@ -2346,7 +2324,6 @@ struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, demod = &st->demod; demod->demodulator_priv = st; memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops)); - mutex_init(&st->i2c_buffer_lock); dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */ @@ -2356,9 +2333,8 @@ struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, st->version = dib7000p_read_word(st, 897); /* FIXME: make sure the dev.parent field is initialized, or else - request_firmware() will hit an OOPS (this should be moved somewhere - more common) */ - st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent; + request_firmware() will hit an OOPS (this should be moved somewhere + more common) */ dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr); diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index fe284d5292f5..7d2ea112ae2b 100644 --- a/drivers/media/dvb/frontends/dib8000.c +++ b/drivers/media/dvb/frontends/dib8000.c @@ -10,8 +10,6 @@ #include #include #include -#include - #include "dvb_math.h" #include "dvb_frontend.h" @@ -39,7 +37,6 @@ struct i2c_device { u8 addr; u8 *i2c_write_buffer; u8 *i2c_read_buffer; - struct mutex *i2c_buffer_lock; }; struct dib8000_state { @@ -80,7 +77,6 @@ struct dib8000_state { struct i2c_msg msg[2]; u8 i2c_write_buffer[4]; u8 i2c_read_buffer[2]; - struct mutex i2c_buffer_lock; }; enum dib8000_power_mode { @@ -90,39 +86,24 @@ enum dib8000_power_mode { static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg) { - u16 ret; struct i2c_msg msg[2] = { - {.addr = i2c->addr >> 1, .flags = 0, .len = 2}, - {.addr = i2c->addr >> 1, .flags = I2C_M_RD, .len = 2}, + {.addr = i2c->addr >> 1, .flags = 0, + .buf = i2c->i2c_write_buffer, .len = 2}, + {.addr = i2c->addr >> 1, .flags = I2C_M_RD, + .buf = i2c->i2c_read_buffer, .len = 2}, }; - if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return 0; - } - - msg[0].buf = i2c->i2c_write_buffer; msg[0].buf[0] = reg >> 8; msg[0].buf[1] = reg & 0xff; - msg[1].buf = i2c->i2c_read_buffer; if (i2c_transfer(i2c->adap, msg, 2) != 2) dprintk("i2c read error on %d", reg); - ret = (msg[1].buf[0] << 8) | msg[1].buf[1]; - mutex_unlock(i2c->i2c_buffer_lock); - return ret; + return (msg[1].buf[0] << 8) | msg[1].buf[1]; } static u16 dib8000_read_word(struct dib8000_state *state, u16 reg) { - u16 ret; - - if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return 0; - } - state->i2c_write_buffer[0] = reg >> 8; state->i2c_write_buffer[1] = reg & 0xff; @@ -139,10 +120,7 @@ static u16 dib8000_read_word(struct dib8000_state *state, u16 reg) if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2) dprintk("i2c read error on %d", reg); - ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; - mutex_unlock(&state->i2c_buffer_lock); - - return ret; + return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; } static u32 dib8000_read32(struct dib8000_state *state, u16 reg) @@ -157,35 +135,22 @@ static u32 dib8000_read32(struct dib8000_state *state, u16 reg) static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val) { - struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0, .len = 4}; + struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0, + .buf = i2c->i2c_write_buffer, .len = 4}; int ret = 0; - if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return -EINVAL; - } - - msg.buf = i2c->i2c_write_buffer; msg.buf[0] = (reg >> 8) & 0xff; msg.buf[1] = reg & 0xff; msg.buf[2] = (val >> 8) & 0xff; msg.buf[3] = val & 0xff; ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0; - mutex_unlock(i2c->i2c_buffer_lock); return ret; } static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val) { - int ret; - - if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return -EINVAL; - } - state->i2c_write_buffer[0] = (reg >> 8) & 0xff; state->i2c_write_buffer[1] = reg & 0xff; state->i2c_write_buffer[2] = (val >> 8) & 0xff; @@ -197,11 +162,7 @@ static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val) state->msg[0].buf = state->i2c_write_buffer; state->msg[0].len = 4; - ret = (i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ? - -EREMOTEIO : 0); - mutex_unlock(&state->i2c_buffer_lock); - - return ret; + return i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ? -EREMOTEIO : 0; } static const s16 coeff_2k_sb_1seg_dqpsk[8] = { @@ -2473,15 +2434,8 @@ int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 defau if (!client.i2c_read_buffer) { dprintk("%s: not enough memory", __func__); ret = -ENOMEM; - goto error_memory_read; - } - client.i2c_buffer_lock = kzalloc(sizeof(struct mutex), GFP_KERNEL); - if (!client.i2c_buffer_lock) { - dprintk("%s: not enough memory", __func__); - ret = -ENOMEM; - goto error_memory_lock; + goto error_memory; } - mutex_init(client.i2c_buffer_lock); for (k = no_of_demods - 1; k >= 0; k--) { /* designated i2c address */ @@ -2522,10 +2476,8 @@ int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 defau } error: - kfree(client.i2c_buffer_lock); -error_memory_lock: kfree(client.i2c_read_buffer); -error_memory_read: +error_memory: kfree(client.i2c_write_buffer); return ret; @@ -2629,8 +2581,6 @@ struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, s state->i2c.addr = i2c_addr; state->i2c.i2c_write_buffer = state->i2c_write_buffer; state->i2c.i2c_read_buffer = state->i2c_read_buffer; - mutex_init(&state->i2c_buffer_lock); - state->i2c.i2c_buffer_lock = &state->i2c_buffer_lock; state->gpio_val = cfg->gpio_val; state->gpio_dir = cfg->gpio_dir; diff --git a/drivers/media/dvb/frontends/dib9000.c b/drivers/media/dvb/frontends/dib9000.c index b931074a9521..a0855883b5ce 100644 --- a/drivers/media/dvb/frontends/dib9000.c +++ b/drivers/media/dvb/frontends/dib9000.c @@ -38,15 +38,6 @@ struct i2c_device { #define DibInitLock(lock) mutex_init(lock) #define DibFreeLock(lock) -struct dib9000_pid_ctrl { -#define DIB9000_PID_FILTER_CTRL 0 -#define DIB9000_PID_FILTER 1 - u8 cmd; - u8 id; - u16 pid; - u8 onoff; -}; - struct dib9000_state { struct i2c_device i2c; @@ -108,10 +99,6 @@ struct dib9000_state { struct i2c_msg msg[2]; u8 i2c_write_buffer[255]; u8 i2c_read_buffer[255]; - DIB_LOCK demod_lock; - u8 get_frontend_internal; - struct dib9000_pid_ctrl pid_ctrl[10]; - s8 pid_ctrl_index; /* -1: empty list; -2: do not use the list */ }; static const u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1756,56 +1743,19 @@ EXPORT_SYMBOL(dib9000_set_gpio); int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) { struct dib9000_state *state = fe->demodulator_priv; - u16 val; - int ret; - - if ((state->pid_ctrl_index != -2) && (state->pid_ctrl_index < 9)) { - /* postpone the pid filtering cmd */ - dprintk("pid filter cmd postpone"); - state->pid_ctrl_index++; - state->pid_ctrl[state->pid_ctrl_index].cmd = DIB9000_PID_FILTER_CTRL; - state->pid_ctrl[state->pid_ctrl_index].onoff = onoff; - return 0; - } - - DibAcquireLock(&state->demod_lock); - - val = dib9000_read_word(state, 294 + 1) & 0xffef; + u16 val = dib9000_read_word(state, 294 + 1) & 0xffef; val |= (onoff & 0x1) << 4; dprintk("PID filter enabled %d", onoff); - ret = dib9000_write_word(state, 294 + 1, val); - DibReleaseLock(&state->demod_lock); - return ret; - + return dib9000_write_word(state, 294 + 1, val); } EXPORT_SYMBOL(dib9000_fw_pid_filter_ctrl); int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) { struct dib9000_state *state = fe->demodulator_priv; - int ret; - - if (state->pid_ctrl_index != -2) { - /* postpone the pid filtering cmd */ - dprintk("pid filter postpone"); - if (state->pid_ctrl_index < 9) { - state->pid_ctrl_index++; - state->pid_ctrl[state->pid_ctrl_index].cmd = DIB9000_PID_FILTER; - state->pid_ctrl[state->pid_ctrl_index].id = id; - state->pid_ctrl[state->pid_ctrl_index].pid = pid; - state->pid_ctrl[state->pid_ctrl_index].onoff = onoff; - } else - dprintk("can not add any more pid ctrl cmd"); - return 0; - } - - DibAcquireLock(&state->demod_lock); dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff); - ret = dib9000_write_word(state, 300 + 1 + id, - onoff ? (1 << 13) | pid : 0); - DibReleaseLock(&state->demod_lock); - return ret; + return dib9000_write_word(state, 300 + 1 + id, onoff ? (1 << 13) | pid : 0); } EXPORT_SYMBOL(dib9000_fw_pid_filter); @@ -1828,7 +1778,6 @@ static void dib9000_release(struct dvb_frontend *demod) DibFreeLock(&state->platform.risc.mbx_lock); DibFreeLock(&state->platform.risc.mem_lock); DibFreeLock(&state->platform.risc.mem_mbx_lock); - DibFreeLock(&state->demod_lock); dibx000_exit_i2c_master(&st->i2c_master); i2c_del_adapter(&st->tuner_adap); @@ -1846,19 +1795,14 @@ static int dib9000_sleep(struct dvb_frontend *fe) { struct dib9000_state *state = fe->demodulator_priv; u8 index_frontend; - int ret = 0; + int ret; - DibAcquireLock(&state->demod_lock); for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]); if (ret < 0) - goto error; + return ret; } - ret = dib9000_mbx_send(state, OUT_MSG_FE_SLEEP, NULL, 0); - -error: - DibReleaseLock(&state->demod_lock); - return ret; + return dib9000_mbx_send(state, OUT_MSG_FE_SLEEP, NULL, 0); } static int dib9000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune) @@ -1872,10 +1816,7 @@ static int dib9000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par struct dib9000_state *state = fe->demodulator_priv; u8 index_frontend, sub_index_frontend; fe_status_t stat; - int ret = 0; - - if (state->get_frontend_internal == 0) - DibAcquireLock(&state->demod_lock); + int ret; for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat); @@ -1905,15 +1846,14 @@ static int dib9000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par state->fe[index_frontend]->dtv_property_cache.rolloff; } } - ret = 0; - goto return_value; + return 0; } } /* get the channel from master chip */ ret = dib9000_fw_get_channel(fe, fep); if (ret != 0) - goto return_value; + return ret; /* synchronize the cache with the other frontends */ for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { @@ -1926,12 +1866,8 @@ static int dib9000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par state->fe[index_frontend]->dtv_property_cache.code_rate_LP = fe->dtv_property_cache.code_rate_LP; state->fe[index_frontend]->dtv_property_cache.rolloff = fe->dtv_property_cache.rolloff; } - ret = 0; -return_value: - if (state->get_frontend_internal == 0) - DibReleaseLock(&state->demod_lock); - return ret; + return 0; } static int dib9000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state) @@ -1976,10 +1912,6 @@ static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par dprintk("dib9000: must specify bandwidth "); return 0; } - - state->pid_ctrl_index = -1; /* postpone the pid filtering cmd */ - DibAcquireLock(&state->demod_lock); - fe->dtv_property_cache.delivery_system = SYS_DVBT; /* set the master status */ @@ -2042,18 +1974,13 @@ static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par /* check the tune result */ if (exit_condition == 1) { /* tune failed */ dprintk("tune failed"); - DibReleaseLock(&state->demod_lock); - /* tune failed; put all the pid filtering cmd to junk */ - state->pid_ctrl_index = -1; return 0; } dprintk("tune success on frontend%i", index_frontend_success); /* synchronize all the channel cache */ - state->get_frontend_internal = 1; dib9000_get_frontend(state->fe[0], fep); - state->get_frontend_internal = 0; /* retune the other frontends with the found channel */ channel_status.status = CHANNEL_STATUS_PARAMETERS_SET; @@ -2098,28 +2025,6 @@ static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par /* turn off the diversity for the last frontend */ dib9000_fw_set_diversity_in(state->fe[index_frontend - 1], 0); - DibReleaseLock(&state->demod_lock); - if (state->pid_ctrl_index >= 0) { - u8 index_pid_filter_cmd; - u8 pid_ctrl_index = state->pid_ctrl_index; - - state->pid_ctrl_index = -2; - for (index_pid_filter_cmd = 0; - index_pid_filter_cmd <= pid_ctrl_index; - index_pid_filter_cmd++) { - if (state->pid_ctrl[index_pid_filter_cmd].cmd == DIB9000_PID_FILTER_CTRL) - dib9000_fw_pid_filter_ctrl(state->fe[0], - state->pid_ctrl[index_pid_filter_cmd].onoff); - else if (state->pid_ctrl[index_pid_filter_cmd].cmd == DIB9000_PID_FILTER) - dib9000_fw_pid_filter(state->fe[0], - state->pid_ctrl[index_pid_filter_cmd].id, - state->pid_ctrl[index_pid_filter_cmd].pid, - state->pid_ctrl[index_pid_filter_cmd].onoff); - } - } - /* do not postpone any more the pid filtering */ - state->pid_ctrl_index = -2; - return 0; } @@ -2136,7 +2041,6 @@ static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat) u8 index_frontend; u16 lock = 0, lock_slave = 0; - DibAcquireLock(&state->demod_lock); for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) lock_slave |= dib9000_read_lock(state->fe[index_frontend]); @@ -2155,8 +2059,6 @@ static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat) if ((lock & 0x0008) || (lock_slave & 0x0008)) *stat |= FE_HAS_LOCK; - DibReleaseLock(&state->demod_lock); - return 0; } @@ -2164,14 +2066,10 @@ static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber) { struct dib9000_state *state = fe->demodulator_priv; u16 *c; - int ret = 0; - DibAcquireLock(&state->demod_lock); DibAcquireLock(&state->platform.risc.mem_mbx_lock); - if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { - ret = -EIO; - goto error; - } + if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) + return -EIO; dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, state->i2c_read_buffer, 16 * 2); DibReleaseLock(&state->platform.risc.mem_mbx_lock); @@ -2179,10 +2077,7 @@ static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber) c = (u16 *)state->i2c_read_buffer; *ber = c[10] << 16 | c[11]; - -error: - DibReleaseLock(&state->demod_lock); - return ret; + return 0; } static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) @@ -2191,9 +2086,7 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) u8 index_frontend; u16 *c = (u16 *)state->i2c_read_buffer; u16 val; - int ret = 0; - DibAcquireLock(&state->demod_lock); *strength = 0; for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val); @@ -2204,10 +2097,8 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) } DibAcquireLock(&state->platform.risc.mem_mbx_lock); - if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { - ret = -EIO; - goto error; - } + if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) + return -EIO; dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2); DibReleaseLock(&state->platform.risc.mem_mbx_lock); @@ -2216,10 +2107,7 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) *strength = 65535; else *strength += val; - -error: - DibReleaseLock(&state->demod_lock); - return ret; + return 0; } static u32 dib9000_get_snr(struct dvb_frontend *fe) @@ -2263,7 +2151,6 @@ static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr) u8 index_frontend; u32 snr_master; - DibAcquireLock(&state->demod_lock); snr_master = dib9000_get_snr(fe); for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) snr_master += dib9000_get_snr(state->fe[index_frontend]); @@ -2274,8 +2161,6 @@ static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr) } else *snr = 0; - DibReleaseLock(&state->demod_lock); - return 0; } @@ -2283,22 +2168,15 @@ static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) { struct dib9000_state *state = fe->demodulator_priv; u16 *c = (u16 *)state->i2c_read_buffer; - int ret = 0; - DibAcquireLock(&state->demod_lock); DibAcquireLock(&state->platform.risc.mem_mbx_lock); - if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { - ret = -EIO; - goto error; - } + if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) + return -EIO; dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2); DibReleaseLock(&state->platform.risc.mem_mbx_lock); *unc = c[12]; - -error: - DibReleaseLock(&state->demod_lock); - return ret; + return 0; } int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, u8 first_addr) @@ -2444,10 +2322,6 @@ struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, c DibInitLock(&st->platform.risc.mbx_lock); DibInitLock(&st->platform.risc.mem_lock); DibInitLock(&st->platform.risc.mem_mbx_lock); - DibInitLock(&st->demod_lock); - st->get_frontend_internal = 0; - - st->pid_ctrl_index = -2; st->fe[0] = fe; fe->demodulator_priv = st; diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c index 774d507b66cc..dc5d17a67579 100644 --- a/drivers/media/dvb/frontends/dibx000_common.c +++ b/drivers/media/dvb/frontends/dibx000_common.c @@ -1,5 +1,4 @@ #include -#include #include "dibx000_common.h" @@ -11,13 +10,6 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val) { - int ret; - - if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return -EINVAL; - } - mst->i2c_write_buffer[0] = (reg >> 8) & 0xff; mst->i2c_write_buffer[1] = reg & 0xff; mst->i2c_write_buffer[2] = (val >> 8) & 0xff; @@ -29,21 +21,11 @@ static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val) mst->msg[0].buf = mst->i2c_write_buffer; mst->msg[0].len = 4; - ret = i2c_transfer(mst->i2c_adap, mst->msg, 1) != 1 ? -EREMOTEIO : 0; - mutex_unlock(&mst->i2c_buffer_lock); - - return ret; + return i2c_transfer(mst->i2c_adap, mst->msg, 1) != 1 ? -EREMOTEIO : 0; } static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg) { - u16 ret; - - if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return 0; - } - mst->i2c_write_buffer[0] = reg >> 8; mst->i2c_write_buffer[1] = reg & 0xff; @@ -60,10 +42,7 @@ static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg) if (i2c_transfer(mst->i2c_adap, mst->msg, 2) != 2) dprintk("i2c read error on %d", reg); - ret = (mst->i2c_read_buffer[0] << 8) | mst->i2c_read_buffer[1]; - mutex_unlock(&mst->i2c_buffer_lock); - - return ret; + return (mst->i2c_read_buffer[0] << 8) | mst->i2c_read_buffer[1]; } static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst) @@ -278,7 +257,6 @@ static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num) { struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap); - int ret; if (num > 32) { dprintk("%s: too much I2C message to be transmitted (%i).\ @@ -286,15 +264,10 @@ static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap, return -ENOMEM; } - dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7); - - if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return -EINVAL; - } - memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num)); + dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7); + /* open the gate */ dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1); mst->msg[0].addr = mst->i2c_addr; @@ -309,11 +282,7 @@ static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap, mst->msg[num + 1].buf = &mst->i2c_write_buffer[4]; mst->msg[num + 1].len = 4; - ret = (i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? - num : -EIO); - - mutex_unlock(&mst->i2c_buffer_lock); - return ret; + return i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? num : -EIO; } static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = { @@ -325,7 +294,6 @@ static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num) { struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap); - int ret; if (num > 32) { dprintk("%s: too much I2C message to be transmitted (%i).\ @@ -333,14 +301,10 @@ static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap, return -ENOMEM; } - dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER); - - if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return -EINVAL; - } memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num)); + dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER); + /* open the gate */ dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1); mst->msg[0].addr = mst->i2c_addr; @@ -355,10 +319,7 @@ static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap, mst->msg[num + 1].buf = &mst->i2c_write_buffer[4]; mst->msg[num + 1].len = 4; - ret = (i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? - num : -EIO); - mutex_unlock(&mst->i2c_buffer_lock); - return ret; + return i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? num : -EIO; } static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = { @@ -429,18 +390,8 @@ static int i2c_adapter_init(struct i2c_adapter *i2c_adap, int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr) { - int ret; - - mutex_init(&mst->i2c_buffer_lock); - if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return -EINVAL; - } - memset(mst->msg, 0, sizeof(struct i2c_msg)); - mst->msg[0].addr = i2c_addr >> 1; - mst->msg[0].flags = 0; - mst->msg[0].buf = mst->i2c_write_buffer; - mst->msg[0].len = 4; + u8 tx[4]; + struct i2c_msg m = {.addr = i2c_addr >> 1,.buf = tx,.len = 4 }; mst->device_rev = device_rev; mst->i2c_adap = i2c_adap; @@ -480,12 +431,9 @@ int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, "DiBX000: could not initialize the master i2c_adapter\n"); /* initialize the i2c-master by closing the gate */ - dibx000_i2c_gate_ctrl(mst, mst->i2c_write_buffer, 0, 0); - - ret = (i2c_transfer(i2c_adap, mst->msg, 1) == 1); - mutex_unlock(&mst->i2c_buffer_lock); + dibx000_i2c_gate_ctrl(mst, tx, 0, 0); - return ret; + return i2c_transfer(i2c_adap, &m, 1) == 1; } EXPORT_SYMBOL(dibx000_init_i2c_master); diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h index 5e011474be43..f031165c0459 100644 --- a/drivers/media/dvb/frontends/dibx000_common.h +++ b/drivers/media/dvb/frontends/dibx000_common.h @@ -33,7 +33,6 @@ struct dibx000_i2c_master { struct i2c_msg msg[34]; u8 i2c_write_buffer[8]; u8 i2c_read_buffer[2]; - struct mutex i2c_buffer_lock; }; extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c index aa63d687d276..43971e63baa7 100644 --- a/drivers/media/dvb/frontends/lgdt330x.c +++ b/drivers/media/dvb/frontends/lgdt330x.c @@ -104,8 +104,8 @@ static int i2c_write_demod_bytes (struct lgdt330x_state* state, * then reads the data returned for (len) bytes. */ -static int i2c_read_demod_bytes(struct lgdt330x_state *state, - enum I2C_REG reg, u8 *buf, int len) +static u8 i2c_read_demod_bytes (struct lgdt330x_state* state, + enum I2C_REG reg, u8* buf, int len) { u8 wr [] = { reg }; struct i2c_msg msg [] = { @@ -118,8 +118,6 @@ static int i2c_read_demod_bytes(struct lgdt330x_state *state, ret = i2c_transfer(state->i2c, msg, 2); if (ret != 2) { printk(KERN_WARNING "lgdt330x: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __func__, state->config->demod_address, reg, ret); - if (ret >= 0) - ret = -EIO; } else { ret = 0; } diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 3d2867d349b2..0c8164a2cc36 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -480,7 +480,7 @@ static int smsusb_resume(struct usb_interface *intf) return 0; } -static const struct usb_device_id smsusb_id_table[] = { +static const struct usb_device_id smsusb_id_table[] __devinitconst = { { USB_DEVICE(0x187f, 0x0010), .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, { USB_DEVICE(0x187f, 0x0100), @@ -541,10 +541,6 @@ static const struct usb_device_id smsusb_id_table[] = { .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { USB_DEVICE(0x2040, 0xc090), .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0xc0a0), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0xf5a0), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { } /* Terminating entry */ }; diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index 12b91ae1b208..a43ed6c41bfc 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -1017,6 +1017,22 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) spin_lock_init(&dev->hw_lock); + /* claim the resources */ + error = -EBUSY; + dev->hw_io = pnp_port_start(pnp_dev, 0); + if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) { + dev->hw_io = -1; + dev->irq = -1; + goto error; + } + + dev->irq = pnp_irq(pnp_dev, 0); + if (request_irq(dev->irq, ene_isr, + IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) { + dev->irq = -1; + goto error; + } + pnp_set_drvdata(pnp_dev, dev); dev->pnp_dev = pnp_dev; @@ -1069,22 +1085,6 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) device_set_wakeup_capable(&pnp_dev->dev, true); device_set_wakeup_enable(&pnp_dev->dev, true); - /* claim the resources */ - error = -EBUSY; - dev->hw_io = pnp_port_start(pnp_dev, 0); - if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) { - dev->hw_io = -1; - dev->irq = -1; - goto error; - } - - dev->irq = pnp_irq(pnp_dev, 0); - if (request_irq(dev->irq, ene_isr, - IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) { - dev->irq = -1; - goto error; - } - error = rc_register_device(rdev); if (error < 0) goto error; diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c index 4218f7369c52..7f7079b12f23 100644 --- a/drivers/media/rc/fintek-cir.c +++ b/drivers/media/rc/fintek-cir.c @@ -504,6 +504,16 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id spin_lock_init(&fintek->fintek_lock); + ret = -EBUSY; + /* now claim resources */ + if (!request_region(fintek->cir_addr, + fintek->cir_port_len, FINTEK_DRIVER_NAME)) + goto failure; + + if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED, + FINTEK_DRIVER_NAME, (void *)fintek)) + goto failure; + pnp_set_drvdata(pdev, fintek); fintek->pdev = pdev; @@ -538,16 +548,6 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */ rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD); - ret = -EBUSY; - /* now claim resources */ - if (!request_region(fintek->cir_addr, - fintek->cir_port_len, FINTEK_DRIVER_NAME)) - goto failure; - - if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED, - FINTEK_DRIVER_NAME, (void *)fintek)) - goto failure; - ret = rc_register_device(rdev); if (ret) goto failure; diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index d8e0b2d81c81..ecd3d0280768 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -1477,7 +1477,6 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id rdev = rc_allocate_device(); if (!rdev) goto failure; - itdev->rdev = rdev; ret = -ENODEV; @@ -1520,6 +1519,16 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id /* initialize raw event */ init_ir_raw_event(&itdev->rawir); + ret = -EBUSY; + /* now claim resources */ + if (!request_region(itdev->cir_addr, + dev_desc->io_region_size, ITE_DRIVER_NAME)) + goto failure; + + if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED, + ITE_DRIVER_NAME, (void *)itdev)) + goto failure; + /* set driver data into the pnp device */ pnp_set_drvdata(pdev, itdev); itdev->pdev = pdev; @@ -1595,20 +1604,11 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id rdev->driver_name = ITE_DRIVER_NAME; rdev->map_name = RC_MAP_RC6_MCE; - ret = -EBUSY; - /* now claim resources */ - if (!request_region(itdev->cir_addr, - dev_desc->io_region_size, ITE_DRIVER_NAME)) - goto failure; - - if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED, - ITE_DRIVER_NAME, (void *)itdev)) - goto failure; - ret = rc_register_device(rdev); if (ret) goto failure; + itdev->rdev = rdev; ite_pr(KERN_NOTICE, "driver has been successfully loaded\n"); return 0; diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index c212276202f9..ce595f9ab4c7 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -624,6 +624,7 @@ static void nvt_dump_rx_buf(struct nvt_dev *nvt) static void nvt_process_rx_ir_data(struct nvt_dev *nvt) { DEFINE_IR_RAW_EVENT(rawir); + unsigned int count; u32 carrier; u8 sample; int i; @@ -636,38 +637,65 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt) if (nvt->carrier_detect_enabled) carrier = nvt_rx_carrier_detect(nvt); - nvt_dbg_verbose("Processing buffer of len %d", nvt->pkts); + count = nvt->pkts; + nvt_dbg_verbose("Processing buffer of len %d", count); init_ir_raw_event(&rawir); - for (i = 0; i < nvt->pkts; i++) { + for (i = 0; i < count; i++) { + nvt->pkts--; sample = nvt->buf[i]; rawir.pulse = ((sample & BUF_PULSE_BIT) != 0); rawir.duration = US_TO_NS((sample & BUF_LEN_MASK) * SAMPLE_PERIOD); - nvt_dbg("Storing %s with duration %d", - rawir.pulse ? "pulse" : "space", rawir.duration); + if ((sample & BUF_LEN_MASK) == BUF_LEN_MASK) { + if (nvt->rawir.pulse == rawir.pulse) + nvt->rawir.duration += rawir.duration; + else { + nvt->rawir.duration = rawir.duration; + nvt->rawir.pulse = rawir.pulse; + } + continue; + } + + rawir.duration += nvt->rawir.duration; + + init_ir_raw_event(&nvt->rawir); + nvt->rawir.duration = 0; + nvt->rawir.pulse = rawir.pulse; + + if (sample == BUF_PULSE_BIT) + rawir.pulse = false; + + if (rawir.duration) { + nvt_dbg("Storing %s with duration %d", + rawir.pulse ? "pulse" : "space", + rawir.duration); - ir_raw_event_store_with_filter(nvt->rdev, &rawir); + ir_raw_event_store_with_filter(nvt->rdev, &rawir); + } /* * BUF_PULSE_BIT indicates end of IR data, BUF_REPEAT_BYTE * indicates end of IR signal, but new data incoming. In both * cases, it means we're ready to call ir_raw_event_handle */ - if ((sample == BUF_PULSE_BIT) && (i + 1 < nvt->pkts)) { + if ((sample == BUF_PULSE_BIT) && nvt->pkts) { nvt_dbg("Calling ir_raw_event_handle (signal end)\n"); ir_raw_event_handle(nvt->rdev); } } - nvt->pkts = 0; - nvt_dbg("Calling ir_raw_event_handle (buffer empty)\n"); ir_raw_event_handle(nvt->rdev); + if (nvt->pkts) { + nvt_dbg("Odd, pkts should be 0 now... (its %u)", nvt->pkts); + nvt->pkts = 0; + } + nvt_dbg_verbose("%s done", __func__); } @@ -1026,6 +1054,25 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) spin_lock_init(&nvt->nvt_lock); spin_lock_init(&nvt->tx.lock); + init_ir_raw_event(&nvt->rawir); + + ret = -EBUSY; + /* now claim resources */ + if (!request_region(nvt->cir_addr, + CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) + goto failure; + + if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED, + NVT_DRIVER_NAME, (void *)nvt)) + goto failure; + + if (!request_region(nvt->cir_wake_addr, + CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) + goto failure; + + if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED, + NVT_DRIVER_NAME, (void *)nvt)) + goto failure; pnp_set_drvdata(pdev, nvt); nvt->pdev = pdev; @@ -1073,24 +1120,6 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) rdev->tx_resolution = XYZ; #endif - ret = -EBUSY; - /* now claim resources */ - if (!request_region(nvt->cir_addr, - CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) - goto failure; - - if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED, - NVT_DRIVER_NAME, (void *)nvt)) - goto failure; - - if (!request_region(nvt->cir_wake_addr, - CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) - goto failure; - - if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED, - NVT_DRIVER_NAME, (void *)nvt)) - goto failure; - ret = rc_register_device(rdev); if (ret) goto failure; diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h index 0d5e0872a2ea..1241fc89a36c 100644 --- a/drivers/media/rc/nuvoton-cir.h +++ b/drivers/media/rc/nuvoton-cir.h @@ -67,6 +67,7 @@ static int debug; struct nvt_dev { struct pnp_dev *pdev; struct rc_dev *rdev; + struct ir_raw_event rawir; spinlock_t nvt_lock; diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 9cfb56d8cd82..3186ac7c2c10 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -772,11 +772,10 @@ static ssize_t show_protocols(struct device *device, if (dev->driver_type == RC_DRIVER_SCANCODE) { enabled = dev->rc_map.rc_type; allowed = dev->allowed_protos; - } else if (dev->raw) { + } else { enabled = dev->raw->enabled_protocols; allowed = ir_raw_get_allowed_protocols(); - } else - return -ENODEV; + } IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", (long long)allowed, diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index 9e55a0c9ac5e..5d06b899e859 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -1003,10 +1003,39 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) "(w: 0x%lX, e: 0x%lX, s: 0x%lX, i: %u)\n", data->wbase, data->ebase, data->sbase, data->irq); + if (!request_region(data->wbase, WAKEUP_IOMEM_LEN, DRVNAME)) { + dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", + data->wbase, data->wbase + WAKEUP_IOMEM_LEN - 1); + err = -EBUSY; + goto exit_free_data; + } + + if (!request_region(data->ebase, EHFUNC_IOMEM_LEN, DRVNAME)) { + dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", + data->ebase, data->ebase + EHFUNC_IOMEM_LEN - 1); + err = -EBUSY; + goto exit_release_wbase; + } + + if (!request_region(data->sbase, SP_IOMEM_LEN, DRVNAME)) { + dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", + data->sbase, data->sbase + SP_IOMEM_LEN - 1); + err = -EBUSY; + goto exit_release_ebase; + } + + err = request_irq(data->irq, wbcir_irq_handler, + IRQF_DISABLED, DRVNAME, device); + if (err) { + dev_err(dev, "Failed to claim IRQ %u\n", data->irq); + err = -EBUSY; + goto exit_release_sbase; + } + led_trigger_register_simple("cir-tx", &data->txtrigger); if (!data->txtrigger) { err = -ENOMEM; - goto exit_free_data; + goto exit_free_irq; } led_trigger_register_simple("cir-rx", &data->rxtrigger); @@ -1029,7 +1058,6 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) goto exit_unregister_led; } - data->dev->driver_type = RC_DRIVER_IR_RAW; data->dev->driver_name = WBCIR_NAME; data->dev->input_name = WBCIR_NAME; data->dev->input_phys = "wbcir/cir0"; @@ -1045,38 +1073,9 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) data->dev->priv = data; data->dev->dev.parent = &device->dev; - if (!request_region(data->wbase, WAKEUP_IOMEM_LEN, DRVNAME)) { - dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", - data->wbase, data->wbase + WAKEUP_IOMEM_LEN - 1); - err = -EBUSY; - goto exit_free_rc; - } - - if (!request_region(data->ebase, EHFUNC_IOMEM_LEN, DRVNAME)) { - dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", - data->ebase, data->ebase + EHFUNC_IOMEM_LEN - 1); - err = -EBUSY; - goto exit_release_wbase; - } - - if (!request_region(data->sbase, SP_IOMEM_LEN, DRVNAME)) { - dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", - data->sbase, data->sbase + SP_IOMEM_LEN - 1); - err = -EBUSY; - goto exit_release_ebase; - } - - err = request_irq(data->irq, wbcir_irq_handler, - IRQF_DISABLED, DRVNAME, device); - if (err) { - dev_err(dev, "Failed to claim IRQ %u\n", data->irq); - err = -EBUSY; - goto exit_release_sbase; - } - err = rc_register_device(data->dev); if (err) - goto exit_free_irq; + goto exit_free_rc; device_init_wakeup(&device->dev, 1); @@ -1084,14 +1083,6 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) return 0; -exit_free_irq: - free_irq(data->irq, device); -exit_release_sbase: - release_region(data->sbase, SP_IOMEM_LEN); -exit_release_ebase: - release_region(data->ebase, EHFUNC_IOMEM_LEN); -exit_release_wbase: - release_region(data->wbase, WAKEUP_IOMEM_LEN); exit_free_rc: rc_free_device(data->dev); exit_unregister_led: @@ -1100,6 +1091,14 @@ exit_unregister_rxtrigger: led_trigger_unregister_simple(data->rxtrigger); exit_unregister_txtrigger: led_trigger_unregister_simple(data->txtrigger); +exit_free_irq: + free_irq(data->irq, device); +exit_release_sbase: + release_region(data->sbase, SP_IOMEM_LEN); +exit_release_ebase: + release_region(data->ebase, EHFUNC_IOMEM_LEN); +exit_release_wbase: + release_region(data->wbase, WAKEUP_IOMEM_LEN); exit_free_data: kfree(data); pnp_set_drvdata(device, NULL); diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c index 9945aaf1bbab..c03eb29a9ee6 100644 --- a/drivers/media/video/au0828/au0828-video.c +++ b/drivers/media/video/au0828/au0828-video.c @@ -1697,18 +1697,14 @@ static int vidioc_streamoff(struct file *file, void *priv, (AUVI_INPUT(i).audio_setup)(dev, 0); } - if (res_check(fh, AU0828_RESOURCE_VIDEO)) { - videobuf_streamoff(&fh->vb_vidq); - res_free(fh, AU0828_RESOURCE_VIDEO); - } + videobuf_streamoff(&fh->vb_vidq); + res_free(fh, AU0828_RESOURCE_VIDEO); } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { dev->vbi_timeout_running = 0; del_timer_sync(&dev->vbi_timeout); - if (res_check(fh, AU0828_RESOURCE_VBI)) { - videobuf_streamoff(&fh->vb_vbiq); - res_free(fh, AU0828_RESOURCE_VBI); - } + videobuf_streamoff(&fh->vb_vbiq); + res_free(fh, AU0828_RESOURCE_VBI); } return 0; diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 2b5cd2145c39..3c315f94cc85 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -843,7 +843,7 @@ static int dvb_register(struct cx23885_tsport *port) static struct xc2028_ctrl ctl = { .fname = XC3028L_DEFAULT_FIRMWARE, .max_len = 64, - .demod = XC3028_FE_DIBCOM52, + .demod = 5000, /* This is true for all demods with v36 firmware? */ .type = XC2028_D2633, diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c index 731cd1664c44..89fec4c500af 100644 --- a/drivers/media/video/gspca/spca506.c +++ b/drivers/media/video/gspca/spca506.c @@ -685,7 +685,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] __devinitconst = { {USB_DEVICE(0x06e1, 0xa190)}, /*fixme: may be IntelPCCameraPro BRIDGE_SPCA505 {USB_DEVICE(0x0733, 0x0430)}, */ diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c index 4c0394a8afd9..514aea76eaa5 100644 --- a/drivers/media/video/hdpvr/hdpvr-video.c +++ b/drivers/media/video/hdpvr/hdpvr-video.c @@ -284,13 +284,12 @@ static int hdpvr_start_streaming(struct hdpvr_device *dev) hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00); - dev->status = STATUS_STREAMING; - INIT_WORK(&dev->worker, hdpvr_transmit_buffers); queue_work(dev->workqueue, &dev->worker); v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, "streaming started\n"); + dev->status = STATUS_STREAMING; return 0; } diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c index c4eca15baf61..e799331389b1 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c @@ -319,17 +319,7 @@ static struct tda829x_config tda829x_no_probe = { .probe_tuner = TDA829X_DONT_PROBE, }; -static struct tda18271_std_map hauppauge_tda18271_dvbt_std_map = { - .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4, - .if_lvl = 1, .rfagc_top = 0x37, }, - .dvbt_7 = { .if_freq = 3800, .agc_mode = 3, .std = 5, - .if_lvl = 1, .rfagc_top = 0x37, }, - .dvbt_8 = { .if_freq = 4300, .agc_mode = 3, .std = 6, - .if_lvl = 1, .rfagc_top = 0x37, }, -}; - static struct tda18271_config hauppauge_tda18271_dvb_config = { - .std_map = &hauppauge_tda18271_dvbt_std_map, .gate = TDA18271_GATE_ANALOG, .output_opt = TDA18271_OUTPUT_LT_OFF, }; diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index e9babcb0887c..bdf19ada9172 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -36,7 +36,7 @@ static char *fimc_clocks[MAX_FIMC_CLOCKS] = { static struct fimc_fmt fimc_formats[] = { { .name = "RGB565", - .fourcc = V4L2_PIX_FMT_RGB565, + .fourcc = V4L2_PIX_FMT_RGB565X, .depth = { 16 }, .color = S5P_FIMC_RGB565, .memplanes = 1, diff --git a/drivers/media/video/saa7164/saa7164-cards.c b/drivers/media/video/saa7164/saa7164-cards.c index c71369173fae..69822a4e7275 100644 --- a/drivers/media/video/saa7164/saa7164-cards.c +++ b/drivers/media/video/saa7164/saa7164-cards.c @@ -203,66 +203,6 @@ struct saa7164_board saa7164_boards[] = { .i2c_reg_len = REGLEN_8bit, } }, }, - [SAA7164_BOARD_HAUPPAUGE_HVR2200_4] = { - .name = "Hauppauge WinTV-HVR2200", - .porta = SAA7164_MPEG_DVB, - .portb = SAA7164_MPEG_DVB, - .portc = SAA7164_MPEG_ENCODER, - .portd = SAA7164_MPEG_ENCODER, - .porte = SAA7164_MPEG_VBI, - .portf = SAA7164_MPEG_VBI, - .chiprev = SAA7164_CHIP_REV3, - .unit = {{ - .id = 0x1d, - .type = SAA7164_UNIT_EEPROM, - .name = "4K EEPROM", - .i2c_bus_nr = SAA7164_I2C_BUS_0, - .i2c_bus_addr = 0xa0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x04, - .type = SAA7164_UNIT_TUNER, - .name = "TDA18271-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0xc0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x05, - .type = SAA7164_UNIT_ANALOG_DEMODULATOR, - .name = "TDA8290-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0x84 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x1b, - .type = SAA7164_UNIT_TUNER, - .name = "TDA18271-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0xc0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x1c, - .type = SAA7164_UNIT_ANALOG_DEMODULATOR, - .name = "TDA8290-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0x84 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x1e, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "TDA10048-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0x10 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x1f, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "TDA10048-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0x12 >> 1, - .i2c_reg_len = REGLEN_8bit, - } }, - }, [SAA7164_BOARD_HAUPPAUGE_HVR2250] = { .name = "Hauppauge WinTV-HVR2250", .porta = SAA7164_MPEG_DVB, @@ -486,10 +426,6 @@ struct saa7164_subid saa7164_subids[] = { .subvendor = 0x0070, .subdevice = 0x8851, .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2, - }, { - .subvendor = 0x0070, - .subdevice = 0x8940, - .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_4, }, }; const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids); @@ -533,7 +469,6 @@ void saa7164_gpio_setup(struct saa7164_dev *dev) case SAA7164_BOARD_HAUPPAUGE_HVR2200: case SAA7164_BOARD_HAUPPAUGE_HVR2200_2: case SAA7164_BOARD_HAUPPAUGE_HVR2200_3: - case SAA7164_BOARD_HAUPPAUGE_HVR2200_4: case SAA7164_BOARD_HAUPPAUGE_HVR2250: case SAA7164_BOARD_HAUPPAUGE_HVR2250_2: case SAA7164_BOARD_HAUPPAUGE_HVR2250_3: @@ -614,7 +549,6 @@ void saa7164_card_setup(struct saa7164_dev *dev) case SAA7164_BOARD_HAUPPAUGE_HVR2200: case SAA7164_BOARD_HAUPPAUGE_HVR2200_2: case SAA7164_BOARD_HAUPPAUGE_HVR2200_3: - case SAA7164_BOARD_HAUPPAUGE_HVR2200_4: case SAA7164_BOARD_HAUPPAUGE_HVR2250: case SAA7164_BOARD_HAUPPAUGE_HVR2250_2: case SAA7164_BOARD_HAUPPAUGE_HVR2250_3: diff --git a/drivers/media/video/saa7164/saa7164-dvb.c b/drivers/media/video/saa7164/saa7164-dvb.c index d3779379197f..f65eab63ca87 100644 --- a/drivers/media/video/saa7164/saa7164-dvb.c +++ b/drivers/media/video/saa7164/saa7164-dvb.c @@ -475,7 +475,6 @@ int saa7164_dvb_register(struct saa7164_port *port) case SAA7164_BOARD_HAUPPAUGE_HVR2200: case SAA7164_BOARD_HAUPPAUGE_HVR2200_2: case SAA7164_BOARD_HAUPPAUGE_HVR2200_3: - case SAA7164_BOARD_HAUPPAUGE_HVR2200_4: i2c_bus = &dev->i2c_bus[port->nr + 1]; switch (port->nr) { case 0: diff --git a/drivers/media/video/saa7164/saa7164.h b/drivers/media/video/saa7164/saa7164.h index 13bd27e9bd1c..16745d2fb349 100644 --- a/drivers/media/video/saa7164/saa7164.h +++ b/drivers/media/video/saa7164/saa7164.h @@ -83,7 +83,6 @@ #define SAA7164_BOARD_HAUPPAUGE_HVR2200_3 6 #define SAA7164_BOARD_HAUPPAUGE_HVR2250_2 7 #define SAA7164_BOARD_HAUPPAUGE_HVR2250_3 8 -#define SAA7164_BOARD_HAUPPAUGE_HVR2200_4 9 #define SAA7164_MAX_UNITS 8 #define SAA7164_TS_NUMBER_OF_LINES 312 diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 1f962dc3a6a9..b6eae48d7fb8 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -1960,7 +1960,7 @@ static int __uvc_resume(struct usb_interface *intf, int reset) list_for_each_entry(stream, &dev->streams, list) { if (stream->intf == intf) - return uvc_video_resume(stream, reset); + return uvc_video_resume(stream); } uvc_trace(UVC_TRACE_SUSPEND, "Resume: video streaming USB interface " diff --git a/drivers/media/video/uvc/uvc_entity.c b/drivers/media/video/uvc/uvc_entity.c index 29e239911d0e..48fea373c25a 100644 --- a/drivers/media/video/uvc/uvc_entity.c +++ b/drivers/media/video/uvc/uvc_entity.c @@ -49,7 +49,7 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain, if (remote == NULL) return -EINVAL; - source = (UVC_ENTITY_TYPE(remote) == UVC_TT_STREAMING) + source = (UVC_ENTITY_TYPE(remote) != UVC_TT_STREAMING) ? (remote->vdev ? &remote->vdev->entity : NULL) : &remote->subdev.entity; if (source == NULL) diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 5afdbb7bbea5..543a80395b7f 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c @@ -65,15 +65,6 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain, goto done; } - /* Prevent excessive memory consumption, as well as integer - * overflows. - */ - if (xmap->menu_count == 0 || - xmap->menu_count > UVC_MAX_CONTROL_MENU_ENTRIES) { - ret = -EINVAL; - goto done; - } - size = xmap->menu_count * sizeof(*map->menu_info); map->menu_info = kmalloc(size, GFP_KERNEL); if (map->menu_info == NULL) { @@ -710,7 +701,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) break; } pin = iterm->id; - } else if (index < selector->bNrInPins) { + } else if (pin < selector->bNrInPins) { pin = selector->baSourceID[index]; list_for_each_entry(iterm, &chain->entities, chain) { if (!UVC_ENTITY_IS_ITERM(iterm)) diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 6f147defcce7..49994793cc77 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -1104,18 +1104,10 @@ int uvc_video_suspend(struct uvc_streaming *stream) * buffers, making sure userspace applications are notified of the problem * instead of waiting forever. */ -int uvc_video_resume(struct uvc_streaming *stream, int reset) +int uvc_video_resume(struct uvc_streaming *stream) { int ret; - /* If the bus has been reset on resume, set the alternate setting to 0. - * This should be the default value, but some devices crash or otherwise - * misbehave if they don't receive a SET_INTERFACE request before any - * other video control request. - */ - if (reset) - usb_set_interface(stream->dev->udev, stream->intfnum, 0); - stream->frozen = 0; ret = uvc_commit_video(stream, &stream->ctrl); diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index cf2401a041ae..20107fd3574d 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -200,7 +200,6 @@ struct uvc_xu_control { /* Maximum allowed number of control mappings per device */ #define UVC_MAX_CONTROL_MAPPINGS 1024 -#define UVC_MAX_CONTROL_MENU_ENTRIES 32 /* Devices quirks */ #define UVC_QUIRK_STATUS_INTERVAL 0x00000001 @@ -640,7 +639,7 @@ extern void uvc_mc_cleanup_entity(struct uvc_entity *entity); /* Video */ extern int uvc_video_init(struct uvc_streaming *stream); extern int uvc_video_suspend(struct uvc_streaming *stream); -extern int uvc_video_resume(struct uvc_streaming *stream, int reset); +extern int uvc_video_resume(struct uvc_streaming *stream); extern int uvc_video_enable(struct uvc_streaming *stream, int enable); extern int uvc_probe_video(struct uvc_streaming *stream, struct uvc_streaming_control *probe); diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index bda252f04e8a..69e8c6ffcc49 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -2289,10 +2289,6 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size, struct v4l2_ext_controls *ctrls = parg; if (ctrls->count != 0) { - if (ctrls->count > V4L2_CID_MAX_CTRLS) { - ret = -EINVAL; - break; - } *user_ptr = (void __user *)ctrls->controls; *kernel_ptr = (void **)&ctrls->controls; *array_size = sizeof(struct v4l2_ext_control) diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index ccd81b1540a2..a20e1c41bed2 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c @@ -408,6 +408,8 @@ static irqreturn_t ab3100_irq_handler(int irq, void *data) u32 fatevent; int err; + add_interrupt_randomness(irq); + err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1, event_regs, 3); if (err) @@ -936,6 +938,9 @@ static int __devinit ab3100_probe(struct i2c_client *client, err = request_threaded_irq(client->irq, NULL, ab3100_irq_handler, IRQF_ONESHOT, "ab3100-core", ab3100); + /* This real unpredictable IRQ is of course sampled for entropy */ + rand_initialize_irq(client->irq); + if (err) goto exit_no_irq; diff --git a/drivers/mfd/ab3550-core.c b/drivers/mfd/ab3550-core.c index d69dc4bf8bbd..3d7dce671b93 100644 --- a/drivers/mfd/ab3550-core.c +++ b/drivers/mfd/ab3550-core.c @@ -1309,6 +1309,8 @@ static int __init ab3550_probe(struct i2c_client *client, err = request_threaded_irq(client->irq, NULL, ab3550_irq_handler, IRQF_ONESHOT, "ab3550-core", ab); + /* This real unpredictable IRQ is of course sampled for entropy */ + rand_initialize_irq(client->irq); if (err) goto exit_no_irq; diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c index e488a78a2fd6..155fa0407882 100644 --- a/drivers/mfd/cs5535-mfd.c +++ b/drivers/mfd/cs5535-mfd.c @@ -179,7 +179,7 @@ static struct pci_device_id cs5535_mfd_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, cs5535_mfd_pci_tbl); -static struct pci_driver cs5535_mfd_driver = { +static struct pci_driver cs5535_mfd_drv = { .name = DRV_NAME, .id_table = cs5535_mfd_pci_tbl, .probe = cs5535_mfd_probe, @@ -188,12 +188,12 @@ static struct pci_driver cs5535_mfd_driver = { static int __init cs5535_mfd_init(void) { - return pci_register_driver(&cs5535_mfd_driver); + return pci_register_driver(&cs5535_mfd_drv); } static void __exit cs5535_mfd_exit(void) { - pci_unregister_driver(&cs5535_mfd_driver); + pci_unregister_driver(&cs5535_mfd_drv); } module_init(cs5535_mfd_init); diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c index db662e2dcfa5..43a76c41cfcc 100644 --- a/drivers/mfd/ezx-pcap.c +++ b/drivers/mfd/ezx-pcap.c @@ -202,7 +202,7 @@ static void pcap_isr_work(struct work_struct *work) } local_irq_enable(); ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr); - } while (gpio_get_value(pdata->gpio)); + } while (gpio_get_value(irq_to_gpio(pcap->spi->irq))); } static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc) diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index b36aadb6e708..0902523af62d 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -18,10 +18,6 @@ #include #include -static struct device_type mfd_dev_type = { - .name = "mfd_device", -}; - int mfd_cell_enable(struct platform_device *pdev) { const struct mfd_cell *cell = mfd_get_cell(pdev); @@ -91,7 +87,6 @@ static int mfd_add_device(struct device *parent, int id, goto fail_device; pdev->dev.parent = parent; - pdev->dev.type = &mfd_dev_type; if (cell->pdata_size) { ret = platform_device_add_data(pdev, @@ -127,7 +122,7 @@ static int mfd_add_device(struct device *parent, int id, } if (!cell->ignore_resource_conflicts) { - ret = acpi_check_resource_conflict(&res[r]); + ret = acpi_check_resource_conflict(res); if (ret) goto fail_res; } @@ -187,16 +182,10 @@ EXPORT_SYMBOL(mfd_add_devices); static int mfd_remove_devices_fn(struct device *dev, void *c) { - struct platform_device *pdev; - const struct mfd_cell *cell; + struct platform_device *pdev = to_platform_device(dev); + const struct mfd_cell *cell = mfd_get_cell(pdev); atomic_t **usage_count = c; - if (dev->type != &mfd_dev_type) - return 0; - - pdev = to_platform_device(dev); - cell = mfd_get_cell(pdev); - /* find the base address of usage_count pointers (for freeing) */ if (!*usage_count || (cell->usage_count < *usage_count)) *usage_count = cell->usage_count; diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index e67c3d3e38b3..1717144fe7f4 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c @@ -676,6 +676,7 @@ static void usbhs_omap_tll_init(struct device *dev, u8 tll_channel_count) | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE); + reg |= (1 << (i + 1)); } else continue; diff --git a/drivers/mfd/tps65910-irq.c b/drivers/mfd/tps65910-irq.c index a56be931551c..2bfad5c86cc7 100644 --- a/drivers/mfd/tps65910-irq.c +++ b/drivers/mfd/tps65910-irq.c @@ -178,10 +178,8 @@ int tps65910_irq_init(struct tps65910 *tps65910, int irq, switch (tps65910_chip_id(tps65910)) { case TPS65910: tps65910->irq_num = TPS65910_NUM_IRQ; - break; case TPS65911: tps65910->irq_num = TPS65911_NUM_IRQ; - break; } /* Register with genirq */ diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index f82413a98895..b8f2a4e7f6e7 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -362,13 +362,13 @@ int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); return -EPERM; } - if (unlikely(!inuse)) { - pr_err("%s: not initialized\n", DRIVER_NAME); - return -EPERM; - } sid = twl_map[mod_no].sid; twl = &twl_modules[sid]; + if (unlikely(!inuse)) { + pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid); + return -EPERM; + } mutex_lock(&twl->xfer_lock); /* * [MSG1]: fill the register address data @@ -419,13 +419,13 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); return -EPERM; } - if (unlikely(!inuse)) { - pr_err("%s: not initialized\n", DRIVER_NAME); - return -EPERM; - } sid = twl_map[mod_no].sid; twl = &twl_modules[sid]; + if (unlikely(!inuse)) { + pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid); + return -EPERM; + } mutex_lock(&twl->xfer_lock); /* [MSG1] fill the register address data */ msg = &twl->xfer_msg[0]; diff --git a/drivers/mfd/twl4030-madc.c b/drivers/mfd/twl4030-madc.c index 834f824d3c11..3941ddcf15fe 100644 --- a/drivers/mfd/twl4030-madc.c +++ b/drivers/mfd/twl4030-madc.c @@ -510,9 +510,8 @@ int twl4030_madc_conversion(struct twl4030_madc_request *req) u8 ch_msb, ch_lsb; int ret; - if (!req || !twl4030_madc) + if (!req) return -EINVAL; - mutex_lock(&twl4030_madc->lock); if (req->method < TWL4030_MADC_RT || req->method > TWL4030_MADC_SW2) { ret = -EINVAL; @@ -531,13 +530,13 @@ int twl4030_madc_conversion(struct twl4030_madc_request *req) if (ret) { dev_err(twl4030_madc->dev, "unable to write sel register 0x%X\n", method->sel + 1); - goto out; + return ret; } ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_lsb, method->sel); if (ret) { dev_err(twl4030_madc->dev, "unable to write sel register 0x%X\n", method->sel + 1); - goto out; + return ret; } /* Select averaging for all channels if do_avg is set */ if (req->do_avg) { @@ -547,7 +546,7 @@ int twl4030_madc_conversion(struct twl4030_madc_request *req) dev_err(twl4030_madc->dev, "unable to write avg register 0x%X\n", method->avg + 1); - goto out; + return ret; } ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_lsb, method->avg); @@ -555,7 +554,7 @@ int twl4030_madc_conversion(struct twl4030_madc_request *req) dev_err(twl4030_madc->dev, "unable to write sel reg 0x%X\n", method->sel + 1); - goto out; + return ret; } } if (req->type == TWL4030_MADC_IRQ_ONESHOT && req->func_cb != NULL) { @@ -707,8 +706,6 @@ static int __devinit twl4030_madc_probe(struct platform_device *pdev) if (!madc) return -ENOMEM; - madc->dev = &pdev->dev; - /* * Phoenix provides 2 interrupt lines. The first one is connected to * the OMAP. The other one can be connected to the other processor such @@ -740,28 +737,6 @@ static int __devinit twl4030_madc_probe(struct platform_device *pdev) TWL4030_BCI_BCICTL1); goto err_i2c; } - - /* Check that MADC clock is on */ - ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, ®val, TWL4030_REG_GPBR1); - if (ret) { - dev_err(&pdev->dev, "unable to read reg GPBR1 0x%X\n", - TWL4030_REG_GPBR1); - goto err_i2c; - } - - /* If MADC clk is not on, turn it on */ - if (!(regval & TWL4030_GPBR1_MADC_HFCLK_EN)) { - dev_info(&pdev->dev, "clk disabled, enabling\n"); - regval |= TWL4030_GPBR1_MADC_HFCLK_EN; - ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, regval, - TWL4030_REG_GPBR1); - if (ret) { - dev_err(&pdev->dev, "unable to write reg GPBR1 0x%X\n", - TWL4030_REG_GPBR1); - goto err_i2c; - } - } - platform_set_drvdata(pdev, madc); mutex_init(&madc->lock); ret = request_threaded_irq(platform_get_irq(pdev, 0), NULL, diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index b0563b66d10b..eb3b5f88e566 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c @@ -145,17 +145,8 @@ static int twl6030_irq_thread(void *data) } local_irq_enable(); } - - /* - * NOTE: - * Simulation confirms that documentation is wrong w.r.t the - * interrupt status clear operation. A single *byte* write to - * any one of STS_A to STS_C register results in all three - * STS registers being reset. Since it does not matter which - * value is written, all three registers are cleared on a - * single byte write, so we just use 0x0 to clear. - */ - ret = twl_i2c_write_u8(TWL_MODULE_PIH, 0x00, REG_INT_STS_A); + ret = twl_i2c_write(TWL_MODULE_PIH, sts.bytes, + REG_INT_STS_A, 3); /* clear INT_STS_A */ if (ret) pr_warning("twl6030: I2C error in clearing PIH ISR\n"); diff --git a/drivers/mfd/wm831x-otp.c b/drivers/mfd/wm831x-otp.c index b90f3e06b6c9..f742745ff354 100644 --- a/drivers/mfd/wm831x-otp.c +++ b/drivers/mfd/wm831x-otp.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -67,7 +66,6 @@ static DEVICE_ATTR(unique_id, 0444, wm831x_unique_id_show, NULL); int wm831x_otp_init(struct wm831x *wm831x) { - char uuid[WM831X_UNIQUE_ID_LEN]; int ret; ret = device_create_file(wm831x->dev, &dev_attr_unique_id); @@ -75,12 +73,6 @@ int wm831x_otp_init(struct wm831x *wm831x) dev_err(wm831x->dev, "Unique ID attribute not created: %d\n", ret); - ret = wm831x_unique_id_read(wm831x, uuid); - if (ret == 0) - add_device_randomness(uuid, sizeof(uuid)); - else - dev_err(wm831x->dev, "Failed to read UUID: %d\n", ret); - return ret; } diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 051bfe9534aa..4e349cd98bcf 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -245,7 +245,8 @@ config SGI_XP config CS5535_MFGPT tristate "CS5535/CS5536 Geode Multi-Function General Purpose Timer (MFGPT) support" - depends on PCI && X86 && MFD_CS5535 + depends on PCI + depends on X86 default n help This driver provides access to MFGPT functionality for other @@ -391,14 +392,6 @@ config HMC6352 This driver provides support for the Honeywell HMC6352 compass, providing configuration and heading data via sysfs. -config SENSORS_AK8975 - tristate "AK8975 compass support" - default n - depends on I2C - help - If you say yes here you get support for Asahi Kasei's - orientation sensor AK8975. - config EP93XX_PWM tristate "EP93xx PWM support" depends on ARCH_EP93XX @@ -442,10 +435,6 @@ config TI_DAC7512 This driver can also be built as a module. If so, the module will be called ti_dac7512. -config UID_STAT - bool "UID based statistics tracking exported to /proc/uid_stat" - default n - config VMWARE_BALLOON tristate "VMware Balloon Driver" depends on X86 @@ -483,7 +472,7 @@ config BMP085 module will be called bmp085. config PCH_PHUB - tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) PHUB" + tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB" depends on PCI help This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of @@ -491,40 +480,16 @@ config PCH_PHUB processor. The Topcliff has MAC address and Option ROM data in SROM. This driver can access MAC address and Option ROM data in SROM. - This driver also can be used for LAPIS Semiconductor's IOH, - ML7213/ML7223/ML7831. - ML7213 which is for IVI(In-Vehicle Infotainment) use. - ML7223 IOH is for MP(Media Phone) use. - ML7831 IOH is for general purpose use. - ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series. - ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH. + This driver also can be used for OKI SEMICONDUCTOR IOH(Input/ + Output Hub), ML7213 and ML7223. + ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is + for MP(Media Phone) use. + ML7213/ML7223 is companion chip for Intel Atom E6xx series. + ML7213/ML7223 is completely compatible for Intel EG20T PCH. To compile this driver as a module, choose M here: the module will be called pch_phub. -config WL127X_RFKILL - tristate "Bluetooth power control driver for TI wl127x" - depends on RFKILL - default n - ---help--- - Creates an rfkill entry in sysfs for power control of Bluetooth - TI wl127x chips. - -config APANIC - bool "Android kernel panic diagnostics driver" - default n - ---help--- - Driver which handles kernel panics and attempts to write - critical debugging data to flash. - -config APANIC_PLABEL - string "Android panic dump flash partition label" - depends on APANIC - default "kpanic" - ---help--- - If your platform uses a different flash partition label for storing - crashdumps, enter it here. - source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 606b27f4cb2b..5f03172cc0b5 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -33,7 +33,6 @@ obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o obj-$(CONFIG_DS1682) += ds1682.o obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o -obj-$(CONFIG_UID_STAT) += uid_stat.o obj-$(CONFIG_C2PORT) += c2port/ obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/ obj-$(CONFIG_HMC6352) += hmc6352.o @@ -47,6 +46,3 @@ obj-y += ti-st/ obj-$(CONFIG_AB8500_PWM) += ab8500-pwm.o obj-y += lis3lv02d/ obj-y += carma/ -obj-$(CONFIG_WL127X_RFKILL) += wl127x-rfkill.o -obj-$(CONFIG_APANIC) += apanic.o -obj-$(CONFIG_SENSORS_AK8975) += akm8975.o diff --git a/drivers/misc/akm8975.c b/drivers/misc/akm8975.c deleted file mode 100644 index 830d2897afd6..000000000000 --- a/drivers/misc/akm8975.c +++ /dev/null @@ -1,732 +0,0 @@ -/* drivers/misc/akm8975.c - akm8975 compass driver - * - * Copyright (C) 2007-2008 HTC Corporation. - * Author: Hou-Kun Chen - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -/* - * Revised by AKM 2009/04/02 - * Revised by Motorola 2010/05/27 - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define AK8975DRV_CALL_DBG 0 -#if AK8975DRV_CALL_DBG -#define FUNCDBG(msg) pr_err("%s:%s\n", __func__, msg); -#else -#define FUNCDBG(msg) -#endif - -#define AK8975DRV_DATA_DBG 0 -#define MAX_FAILURE_COUNT 10 - -struct akm8975_data { - struct i2c_client *this_client; - struct akm8975_platform_data *pdata; - struct input_dev *input_dev; - struct work_struct work; - struct mutex flags_lock; -#ifdef CONFIG_HAS_EARLYSUSPEND - struct early_suspend early_suspend; -#endif -}; - -/* -* Because misc devices can not carry a pointer from driver register to -* open, we keep this global. This limits the driver to a single instance. -*/ -struct akm8975_data *akmd_data; - -static DECLARE_WAIT_QUEUE_HEAD(open_wq); - -static atomic_t open_flag; - -static short m_flag; -static short a_flag; -static short t_flag; -static short mv_flag; - -static short akmd_delay; - -static ssize_t akm8975_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - return sprintf(buf, "%u\n", i2c_smbus_read_byte_data(client, - AK8975_REG_CNTL)); -} -static ssize_t akm8975_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - unsigned long val; - strict_strtoul(buf, 10, &val); - if (val > 0xff) - return -EINVAL; - i2c_smbus_write_byte_data(client, AK8975_REG_CNTL, val); - return count; -} -static DEVICE_ATTR(akm_ms1, S_IWUSR | S_IRUGO, akm8975_show, akm8975_store); - -static int akm8975_i2c_rxdata(struct akm8975_data *akm, char *buf, int length) -{ - struct i2c_msg msgs[] = { - { - .addr = akm->this_client->addr, - .flags = 0, - .len = 1, - .buf = buf, - }, - { - .addr = akm->this_client->addr, - .flags = I2C_M_RD, - .len = length, - .buf = buf, - }, - }; - - FUNCDBG("called"); - - if (i2c_transfer(akm->this_client->adapter, msgs, 2) < 0) { - pr_err("akm8975_i2c_rxdata: transfer error\n"); - return EIO; - } else - return 0; -} - -static int akm8975_i2c_txdata(struct akm8975_data *akm, char *buf, int length) -{ - struct i2c_msg msgs[] = { - { - .addr = akm->this_client->addr, - .flags = 0, - .len = length, - .buf = buf, - }, - }; - - FUNCDBG("called"); - - if (i2c_transfer(akm->this_client->adapter, msgs, 1) < 0) { - pr_err("akm8975_i2c_txdata: transfer error\n"); - return -EIO; - } else - return 0; -} - -static void akm8975_ecs_report_value(struct akm8975_data *akm, short *rbuf) -{ - struct akm8975_data *data = i2c_get_clientdata(akm->this_client); - - FUNCDBG("called"); - -#if AK8975DRV_DATA_DBG - pr_info("akm8975_ecs_report_value: yaw = %d, pitch = %d, roll = %d\n", - rbuf[0], rbuf[1], rbuf[2]); - pr_info("tmp = %d, m_stat= %d, g_stat=%d\n", rbuf[3], rbuf[4], rbuf[5]); - pr_info("Acceleration: x = %d LSB, y = %d LSB, z = %d LSB\n", - rbuf[6], rbuf[7], rbuf[8]); - pr_info("Magnetic: x = %d LSB, y = %d LSB, z = %d LSB\n\n", - rbuf[9], rbuf[10], rbuf[11]); -#endif - mutex_lock(&akm->flags_lock); - /* Report magnetic sensor information */ - if (m_flag) { - input_report_abs(data->input_dev, ABS_RX, rbuf[0]); - input_report_abs(data->input_dev, ABS_RY, rbuf[1]); - input_report_abs(data->input_dev, ABS_RZ, rbuf[2]); - input_report_abs(data->input_dev, ABS_RUDDER, rbuf[4]); - } - - /* Report acceleration sensor information */ - if (a_flag) { - input_report_abs(data->input_dev, ABS_X, rbuf[6]); - input_report_abs(data->input_dev, ABS_Y, rbuf[7]); - input_report_abs(data->input_dev, ABS_Z, rbuf[8]); - input_report_abs(data->input_dev, ABS_WHEEL, rbuf[5]); - } - - /* Report temperature information */ - if (t_flag) - input_report_abs(data->input_dev, ABS_THROTTLE, rbuf[3]); - - if (mv_flag) { - input_report_abs(data->input_dev, ABS_HAT0X, rbuf[9]); - input_report_abs(data->input_dev, ABS_HAT0Y, rbuf[10]); - input_report_abs(data->input_dev, ABS_BRAKE, rbuf[11]); - } - mutex_unlock(&akm->flags_lock); - - input_sync(data->input_dev); -} - -static void akm8975_ecs_close_done(struct akm8975_data *akm) -{ - FUNCDBG("called"); - mutex_lock(&akm->flags_lock); - m_flag = 1; - a_flag = 1; - t_flag = 1; - mv_flag = 1; - mutex_unlock(&akm->flags_lock); -} - -static int akm_aot_open(struct inode *inode, struct file *file) -{ - int ret = -1; - - FUNCDBG("called"); - if (atomic_cmpxchg(&open_flag, 0, 1) == 0) { - wake_up(&open_wq); - ret = 0; - } - - ret = nonseekable_open(inode, file); - if (ret) - return ret; - - file->private_data = akmd_data; - - return ret; -} - -static int akm_aot_release(struct inode *inode, struct file *file) -{ - FUNCDBG("called"); - atomic_set(&open_flag, 0); - wake_up(&open_wq); - return 0; -} - -static int akm_aot_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - void __user *argp = (void __user *) arg; - short flag; - struct akm8975_data *akm = file->private_data; - - FUNCDBG("called"); - - switch (cmd) { - case ECS_IOCTL_APP_SET_MFLAG: - case ECS_IOCTL_APP_SET_AFLAG: - case ECS_IOCTL_APP_SET_MVFLAG: - if (copy_from_user(&flag, argp, sizeof(flag))) - return -EFAULT; - if (flag < 0 || flag > 1) - return -EINVAL; - break; - case ECS_IOCTL_APP_SET_DELAY: - if (copy_from_user(&flag, argp, sizeof(flag))) - return -EFAULT; - break; - default: - break; - } - - mutex_lock(&akm->flags_lock); - switch (cmd) { - case ECS_IOCTL_APP_SET_MFLAG: - m_flag = flag; - break; - case ECS_IOCTL_APP_GET_MFLAG: - flag = m_flag; - break; - case ECS_IOCTL_APP_SET_AFLAG: - a_flag = flag; - break; - case ECS_IOCTL_APP_GET_AFLAG: - flag = a_flag; - break; - case ECS_IOCTL_APP_SET_MVFLAG: - mv_flag = flag; - break; - case ECS_IOCTL_APP_GET_MVFLAG: - flag = mv_flag; - break; - case ECS_IOCTL_APP_SET_DELAY: - akmd_delay = flag; - break; - case ECS_IOCTL_APP_GET_DELAY: - flag = akmd_delay; - break; - default: - return -ENOTTY; - } - mutex_unlock(&akm->flags_lock); - - switch (cmd) { - case ECS_IOCTL_APP_GET_MFLAG: - case ECS_IOCTL_APP_GET_AFLAG: - case ECS_IOCTL_APP_GET_MVFLAG: - case ECS_IOCTL_APP_GET_DELAY: - if (copy_to_user(argp, &flag, sizeof(flag))) - return -EFAULT; - break; - default: - break; - } - - return 0; -} - -static int akmd_open(struct inode *inode, struct file *file) -{ - int err = 0; - - FUNCDBG("called"); - err = nonseekable_open(inode, file); - if (err) - return err; - - file->private_data = akmd_data; - return 0; -} - -static int akmd_release(struct inode *inode, struct file *file) -{ - struct akm8975_data *akm = file->private_data; - - FUNCDBG("called"); - akm8975_ecs_close_done(akm); - return 0; -} - -static int akmd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) -{ - void __user *argp = (void __user *) arg; - - char rwbuf[16]; - int ret = -1; - int status; - short value[12]; - short delay; - struct akm8975_data *akm = file->private_data; - - FUNCDBG("called"); - - switch (cmd) { - case ECS_IOCTL_READ: - case ECS_IOCTL_WRITE: - if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) - return -EFAULT; - break; - - case ECS_IOCTL_SET_YPR: - if (copy_from_user(&value, argp, sizeof(value))) - return -EFAULT; - break; - - default: - break; - } - - switch (cmd) { - case ECS_IOCTL_READ: - if (rwbuf[0] < 1) - return -EINVAL; - - ret = akm8975_i2c_rxdata(akm, &rwbuf[1], rwbuf[0]); - if (ret < 0) - return ret; - break; - - case ECS_IOCTL_WRITE: - if (rwbuf[0] < 2) - return -EINVAL; - - ret = akm8975_i2c_txdata(akm, &rwbuf[1], rwbuf[0]); - if (ret < 0) - return ret; - break; - case ECS_IOCTL_SET_YPR: - akm8975_ecs_report_value(akm, value); - break; - - case ECS_IOCTL_GET_OPEN_STATUS: - wait_event_interruptible(open_wq, - (atomic_read(&open_flag) != 0)); - status = atomic_read(&open_flag); - break; - case ECS_IOCTL_GET_CLOSE_STATUS: - wait_event_interruptible(open_wq, - (atomic_read(&open_flag) == 0)); - status = atomic_read(&open_flag); - break; - - case ECS_IOCTL_GET_DELAY: - delay = akmd_delay; - break; - - default: - FUNCDBG("Unknown cmd\n"); - return -ENOTTY; - } - - switch (cmd) { - case ECS_IOCTL_READ: - if (copy_to_user(argp, &rwbuf, sizeof(rwbuf))) - return -EFAULT; - break; - case ECS_IOCTL_GET_OPEN_STATUS: - case ECS_IOCTL_GET_CLOSE_STATUS: - if (copy_to_user(argp, &status, sizeof(status))) - return -EFAULT; - break; - case ECS_IOCTL_GET_DELAY: - if (copy_to_user(argp, &delay, sizeof(delay))) - return -EFAULT; - break; - default: - break; - } - - return 0; -} - -/* needed to clear the int. pin */ -static void akm_work_func(struct work_struct *work) -{ - struct akm8975_data *akm = - container_of(work, struct akm8975_data, work); - - FUNCDBG("called"); - enable_irq(akm->this_client->irq); -} - -static irqreturn_t akm8975_interrupt(int irq, void *dev_id) -{ - struct akm8975_data *akm = dev_id; - FUNCDBG("called"); - - disable_irq_nosync(akm->this_client->irq); - schedule_work(&akm->work); - return IRQ_HANDLED; -} - -static int akm8975_power_off(struct akm8975_data *akm) -{ -#if AK8975DRV_CALL_DBG - pr_info("%s\n", __func__); -#endif - if (akm->pdata->power_off) - akm->pdata->power_off(); - - return 0; -} - -static int akm8975_power_on(struct akm8975_data *akm) -{ - int err; - -#if AK8975DRV_CALL_DBG - pr_info("%s\n", __func__); -#endif - if (akm->pdata->power_on) { - err = akm->pdata->power_on(); - if (err < 0) - return err; - } - return 0; -} - -static int akm8975_suspend(struct i2c_client *client, pm_message_t mesg) -{ - struct akm8975_data *akm = i2c_get_clientdata(client); - -#if AK8975DRV_CALL_DBG - pr_info("%s\n", __func__); -#endif - /* TO DO: might need more work after power mgmt - is enabled */ - return akm8975_power_off(akm); -} - -static int akm8975_resume(struct i2c_client *client) -{ - struct akm8975_data *akm = i2c_get_clientdata(client); - -#if AK8975DRV_CALL_DBG - pr_info("%s\n", __func__); -#endif - /* TO DO: might need more work after power mgmt - is enabled */ - return akm8975_power_on(akm); -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void akm8975_early_suspend(struct early_suspend *handler) -{ - struct akm8975_data *akm; - akm = container_of(handler, struct akm8975_data, early_suspend); - -#if AK8975DRV_CALL_DBG - pr_info("%s\n", __func__); -#endif - akm8975_suspend(akm->this_client, PMSG_SUSPEND); -} - -static void akm8975_early_resume(struct early_suspend *handler) -{ - struct akm8975_data *akm; - akm = container_of(handler, struct akm8975_data, early_suspend); - -#if AK8975DRV_CALL_DBG - pr_info("%s\n", __func__); -#endif - akm8975_resume(akm->this_client); -} -#endif - - -static int akm8975_init_client(struct i2c_client *client) -{ - struct akm8975_data *data; - int ret; - - data = i2c_get_clientdata(client); - - ret = request_irq(client->irq, akm8975_interrupt, IRQF_TRIGGER_RISING, - "akm8975", data); - - if (ret < 0) { - pr_err("akm8975_init_client: request irq failed\n"); - goto err; - } - - init_waitqueue_head(&open_wq); - - mutex_lock(&data->flags_lock); - m_flag = 1; - a_flag = 1; - t_flag = 1; - mv_flag = 1; - mutex_unlock(&data->flags_lock); - - return 0; -err: - return ret; -} - -static const struct file_operations akmd_fops = { - .owner = THIS_MODULE, - .open = akmd_open, - .release = akmd_release, - .ioctl = akmd_ioctl, -}; - -static const struct file_operations akm_aot_fops = { - .owner = THIS_MODULE, - .open = akm_aot_open, - .release = akm_aot_release, - .ioctl = akm_aot_ioctl, -}; - -static struct miscdevice akm_aot_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "akm8975_aot", - .fops = &akm_aot_fops, -}; - -static struct miscdevice akmd_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "akm8975_dev", - .fops = &akmd_fops, -}; - -int akm8975_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct akm8975_data *akm; - int err; - FUNCDBG("called"); - - if (client->dev.platform_data == NULL) { - dev_err(&client->dev, "platform data is NULL. exiting.\n"); - err = -ENODEV; - goto exit_platform_data_null; - } - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - dev_err(&client->dev, "platform data is NULL. exiting.\n"); - err = -ENODEV; - goto exit_check_functionality_failed; - } - - akm = kzalloc(sizeof(struct akm8975_data), GFP_KERNEL); - if (!akm) { - dev_err(&client->dev, - "failed to allocate memory for module data\n"); - err = -ENOMEM; - goto exit_alloc_data_failed; - } - - akm->pdata = client->dev.platform_data; - - mutex_init(&akm->flags_lock); - INIT_WORK(&akm->work, akm_work_func); - i2c_set_clientdata(client, akm); - - err = akm8975_power_on(akm); - if (err < 0) - goto exit_power_on_failed; - - akm8975_init_client(client); - akm->this_client = client; - akmd_data = akm; - - akm->input_dev = input_allocate_device(); - if (!akm->input_dev) { - err = -ENOMEM; - dev_err(&akm->this_client->dev, - "input device allocate failed\n"); - goto exit_input_dev_alloc_failed; - } - - set_bit(EV_ABS, akm->input_dev->evbit); - - /* yaw */ - input_set_abs_params(akm->input_dev, ABS_RX, 0, 23040, 0, 0); - /* pitch */ - input_set_abs_params(akm->input_dev, ABS_RY, -11520, 11520, 0, 0); - /* roll */ - input_set_abs_params(akm->input_dev, ABS_RZ, -5760, 5760, 0, 0); - /* x-axis acceleration */ - input_set_abs_params(akm->input_dev, ABS_X, -5760, 5760, 0, 0); - /* y-axis acceleration */ - input_set_abs_params(akm->input_dev, ABS_Y, -5760, 5760, 0, 0); - /* z-axis acceleration */ - input_set_abs_params(akm->input_dev, ABS_Z, -5760, 5760, 0, 0); - /* temparature */ - input_set_abs_params(akm->input_dev, ABS_THROTTLE, -30, 85, 0, 0); - /* status of magnetic sensor */ - input_set_abs_params(akm->input_dev, ABS_RUDDER, 0, 3, 0, 0); - /* status of acceleration sensor */ - input_set_abs_params(akm->input_dev, ABS_WHEEL, 0, 3, 0, 0); - /* x-axis of raw magnetic vector */ - input_set_abs_params(akm->input_dev, ABS_HAT0X, -20480, 20479, 0, 0); - /* y-axis of raw magnetic vector */ - input_set_abs_params(akm->input_dev, ABS_HAT0Y, -20480, 20479, 0, 0); - /* z-axis of raw magnetic vector */ - input_set_abs_params(akm->input_dev, ABS_BRAKE, -20480, 20479, 0, 0); - - akm->input_dev->name = "compass"; - - err = input_register_device(akm->input_dev); - if (err) { - pr_err("akm8975_probe: Unable to register input device: %s\n", - akm->input_dev->name); - goto exit_input_register_device_failed; - } - - err = misc_register(&akmd_device); - if (err) { - pr_err("akm8975_probe: akmd_device register failed\n"); - goto exit_misc_device_register_failed; - } - - err = misc_register(&akm_aot_device); - if (err) { - pr_err("akm8975_probe: akm_aot_device register failed\n"); - goto exit_misc_device_register_failed; - } - - err = device_create_file(&client->dev, &dev_attr_akm_ms1); - -#ifdef CONFIG_HAS_EARLYSUSPEND - akm->early_suspend.suspend = akm8975_early_suspend; - akm->early_suspend.resume = akm8975_early_resume; - register_early_suspend(&akm->early_suspend); -#endif - return 0; - -exit_misc_device_register_failed: -exit_input_register_device_failed: - input_free_device(akm->input_dev); -exit_input_dev_alloc_failed: - akm8975_power_off(akm); -exit_power_on_failed: - kfree(akm); -exit_alloc_data_failed: -exit_check_functionality_failed: -exit_platform_data_null: - return err; -} - -static int __devexit akm8975_remove(struct i2c_client *client) -{ - struct akm8975_data *akm = i2c_get_clientdata(client); - FUNCDBG("called"); - free_irq(client->irq, NULL); - input_unregister_device(akm->input_dev); - misc_deregister(&akmd_device); - misc_deregister(&akm_aot_device); - akm8975_power_off(akm); - kfree(akm); - return 0; -} - -static const struct i2c_device_id akm8975_id[] = { - { "akm8975", 0 }, - { } -}; - -MODULE_DEVICE_TABLE(i2c, akm8975_id); - -static struct i2c_driver akm8975_driver = { - .probe = akm8975_probe, - .remove = akm8975_remove, -#ifndef CONFIG_HAS_EARLYSUSPEND - .resume = akm8975_resume, - .suspend = akm8975_suspend, -#endif - .id_table = akm8975_id, - .driver = { - .name = "akm8975", - }, -}; - -static int __init akm8975_init(void) -{ - pr_info("AK8975 compass driver: init\n"); - FUNCDBG("AK8975 compass driver: init\n"); - return i2c_add_driver(&akm8975_driver); -} - -static void __exit akm8975_exit(void) -{ - FUNCDBG("AK8975 compass driver: exit\n"); - i2c_del_driver(&akm8975_driver); -} - -module_init(akm8975_init); -module_exit(akm8975_exit); - -MODULE_AUTHOR("Hou-Kun Chen "); -MODULE_DESCRIPTION("AK8975 compass driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/misc/apanic.c b/drivers/misc/apanic.c deleted file mode 100644 index ca875f89da7a..000000000000 --- a/drivers/misc/apanic.c +++ /dev/null @@ -1,606 +0,0 @@ -/* drivers/misc/apanic.c - * - * Copyright (C) 2009 Google, Inc. - * Author: San Mehat - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern void ram_console_enable_console(int); - -struct panic_header { - u32 magic; -#define PANIC_MAGIC 0xdeadf00d - - u32 version; -#define PHDR_VERSION 0x01 - - u32 console_offset; - u32 console_length; - - u32 threads_offset; - u32 threads_length; -}; - -struct apanic_data { - struct mtd_info *mtd; - struct panic_header curr; - void *bounce; - struct proc_dir_entry *apanic_console; - struct proc_dir_entry *apanic_threads; -}; - -static struct apanic_data drv_ctx; -static struct work_struct proc_removal_work; -static DEFINE_MUTEX(drv_mutex); - -static unsigned int *apanic_bbt; -static unsigned int apanic_erase_blocks; -static unsigned int apanic_good_blocks; - -static void set_bb(unsigned int block, unsigned int *bbt) -{ - unsigned int flag = 1; - - BUG_ON(block >= apanic_erase_blocks); - - flag = flag << (block%32); - apanic_bbt[block/32] |= flag; - apanic_good_blocks--; -} - -static unsigned int get_bb(unsigned int block, unsigned int *bbt) -{ - unsigned int flag; - - BUG_ON(block >= apanic_erase_blocks); - - flag = 1 << (block%32); - return apanic_bbt[block/32] & flag; -} - -static void alloc_bbt(struct mtd_info *mtd, unsigned int *bbt) -{ - int bbt_size; - apanic_erase_blocks = (mtd->size)>>(mtd->erasesize_shift); - bbt_size = (apanic_erase_blocks+32)/32; - - apanic_bbt = kmalloc(bbt_size*4, GFP_KERNEL); - memset(apanic_bbt, 0, bbt_size*4); - apanic_good_blocks = apanic_erase_blocks; -} -static void scan_bbt(struct mtd_info *mtd, unsigned int *bbt) -{ - int i; - - for (i = 0; i < apanic_erase_blocks; i++) { - if (mtd->block_isbad(mtd, i*mtd->erasesize)) - set_bb(i, apanic_bbt); - } -} - -#define APANIC_INVALID_OFFSET 0xFFFFFFFF - -static unsigned int phy_offset(struct mtd_info *mtd, unsigned int offset) -{ - unsigned int logic_block = offset>>(mtd->erasesize_shift); - unsigned int phy_block; - unsigned good_block = 0; - - for (phy_block = 0; phy_block < apanic_erase_blocks; phy_block++) { - if (!get_bb(phy_block, apanic_bbt)) - good_block++; - if (good_block == (logic_block + 1)) - break; - } - - if (good_block != (logic_block + 1)) - return APANIC_INVALID_OFFSET; - - return offset + ((phy_block-logic_block)<erasesize_shift); -} - -static void apanic_erase_callback(struct erase_info *done) -{ - wait_queue_head_t *wait_q = (wait_queue_head_t *) done->priv; - wake_up(wait_q); -} - -static int apanic_proc_read(char *buffer, char **start, off_t offset, - int count, int *peof, void *dat) -{ - struct apanic_data *ctx = &drv_ctx; - size_t file_length; - off_t file_offset; - unsigned int page_no; - off_t page_offset; - int rc; - size_t len; - - if (!count) - return 0; - - mutex_lock(&drv_mutex); - - switch ((int) dat) { - case 1: /* apanic_console */ - file_length = ctx->curr.console_length; - file_offset = ctx->curr.console_offset; - break; - case 2: /* apanic_threads */ - file_length = ctx->curr.threads_length; - file_offset = ctx->curr.threads_offset; - break; - default: - pr_err("Bad dat (%d)\n", (int) dat); - mutex_unlock(&drv_mutex); - return -EINVAL; - } - - if ((offset + count) > file_length) { - mutex_unlock(&drv_mutex); - return 0; - } - - /* We only support reading a maximum of a flash page */ - if (count > ctx->mtd->writesize) - count = ctx->mtd->writesize; - - page_no = (file_offset + offset) / ctx->mtd->writesize; - page_offset = (file_offset + offset) % ctx->mtd->writesize; - - - if (phy_offset(ctx->mtd, (page_no * ctx->mtd->writesize)) - == APANIC_INVALID_OFFSET) { - pr_err("apanic: reading an invalid address\n"); - mutex_unlock(&drv_mutex); - return -EINVAL; - } - rc = ctx->mtd->read(ctx->mtd, - phy_offset(ctx->mtd, (page_no * ctx->mtd->writesize)), - ctx->mtd->writesize, - &len, ctx->bounce); - - if (page_offset) - count -= page_offset; - memcpy(buffer, ctx->bounce + page_offset, count); - - *start = count; - - if ((offset + count) == file_length) - *peof = 1; - - mutex_unlock(&drv_mutex); - return count; -} - -static void mtd_panic_erase(void) -{ - struct apanic_data *ctx = &drv_ctx; - struct erase_info erase; - DECLARE_WAITQUEUE(wait, current); - wait_queue_head_t wait_q; - int rc, i; - - init_waitqueue_head(&wait_q); - erase.mtd = ctx->mtd; - erase.callback = apanic_erase_callback; - erase.len = ctx->mtd->erasesize; - erase.priv = (u_long)&wait_q; - for (i = 0; i < ctx->mtd->size; i += ctx->mtd->erasesize) { - erase.addr = i; - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&wait_q, &wait); - - if (get_bb(erase.addr>>ctx->mtd->erasesize_shift, apanic_bbt)) { - printk(KERN_WARNING - "apanic: Skipping erase of bad " - "block @%llx\n", erase.addr); - set_current_state(TASK_RUNNING); - remove_wait_queue(&wait_q, &wait); - continue; - } - - rc = ctx->mtd->erase(ctx->mtd, &erase); - if (rc) { - set_current_state(TASK_RUNNING); - remove_wait_queue(&wait_q, &wait); - printk(KERN_ERR - "apanic: Erase of 0x%llx, 0x%llx failed\n", - (unsigned long long) erase.addr, - (unsigned long long) erase.len); - if (rc == -EIO) { - if (ctx->mtd->block_markbad(ctx->mtd, - erase.addr)) { - printk(KERN_ERR - "apanic: Err marking blk bad\n"); - goto out; - } - printk(KERN_INFO - "apanic: Marked a bad block" - " @%llx\n", erase.addr); - set_bb(erase.addr>>ctx->mtd->erasesize_shift, - apanic_bbt); - continue; - } - goto out; - } - schedule(); - remove_wait_queue(&wait_q, &wait); - } - printk(KERN_DEBUG "apanic: %s partition erased\n", - CONFIG_APANIC_PLABEL); -out: - return; -} - -static void apanic_remove_proc_work(struct work_struct *work) -{ - struct apanic_data *ctx = &drv_ctx; - - mutex_lock(&drv_mutex); - mtd_panic_erase(); - memset(&ctx->curr, 0, sizeof(struct panic_header)); - if (ctx->apanic_console) { - remove_proc_entry("apanic_console", NULL); - ctx->apanic_console = NULL; - } - if (ctx->apanic_threads) { - remove_proc_entry("apanic_threads", NULL); - ctx->apanic_threads = NULL; - } - mutex_unlock(&drv_mutex); -} - -static int apanic_proc_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) -{ - schedule_work(&proc_removal_work); - return count; -} - -static void mtd_panic_notify_add(struct mtd_info *mtd) -{ - struct apanic_data *ctx = &drv_ctx; - struct panic_header *hdr = ctx->bounce; - size_t len; - int rc; - int proc_entry_created = 0; - - if (strcmp(mtd->name, CONFIG_APANIC_PLABEL)) - return; - - ctx->mtd = mtd; - - alloc_bbt(mtd, apanic_bbt); - scan_bbt(mtd, apanic_bbt); - - if (apanic_good_blocks == 0) { - printk(KERN_ERR "apanic: no any good blocks?!\n"); - goto out_err; - } - - rc = mtd->read(mtd, phy_offset(mtd, 0), mtd->writesize, - &len, ctx->bounce); - if (rc && rc == -EBADMSG) { - printk(KERN_WARNING - "apanic: Bad ECC on block 0 (ignored)\n"); - } else if (rc && rc != -EUCLEAN) { - printk(KERN_ERR "apanic: Error reading block 0 (%d)\n", rc); - goto out_err; - } - - if (len != mtd->writesize) { - printk(KERN_ERR "apanic: Bad read size (%d)\n", rc); - goto out_err; - } - - printk(KERN_INFO "apanic: Bound to mtd partition '%s'\n", mtd->name); - - if (hdr->magic != PANIC_MAGIC) { - printk(KERN_INFO "apanic: No panic data available\n"); - mtd_panic_erase(); - return; - } - - if (hdr->version != PHDR_VERSION) { - printk(KERN_INFO "apanic: Version mismatch (%d != %d)\n", - hdr->version, PHDR_VERSION); - mtd_panic_erase(); - return; - } - - memcpy(&ctx->curr, hdr, sizeof(struct panic_header)); - - printk(KERN_INFO "apanic: c(%u, %u) t(%u, %u)\n", - hdr->console_offset, hdr->console_length, - hdr->threads_offset, hdr->threads_length); - - if (hdr->console_length) { - ctx->apanic_console = create_proc_entry("apanic_console", - S_IFREG | S_IRUGO, NULL); - if (!ctx->apanic_console) - printk(KERN_ERR "%s: failed creating procfile\n", - __func__); - else { - ctx->apanic_console->read_proc = apanic_proc_read; - ctx->apanic_console->write_proc = apanic_proc_write; - ctx->apanic_console->size = hdr->console_length; - ctx->apanic_console->data = (void *) 1; - proc_entry_created = 1; - } - } - - if (hdr->threads_length) { - ctx->apanic_threads = create_proc_entry("apanic_threads", - S_IFREG | S_IRUGO, NULL); - if (!ctx->apanic_threads) - printk(KERN_ERR "%s: failed creating procfile\n", - __func__); - else { - ctx->apanic_threads->read_proc = apanic_proc_read; - ctx->apanic_threads->write_proc = apanic_proc_write; - ctx->apanic_threads->size = hdr->threads_length; - ctx->apanic_threads->data = (void *) 2; - proc_entry_created = 1; - } - } - - if (!proc_entry_created) - mtd_panic_erase(); - - return; -out_err: - ctx->mtd = NULL; -} - -static void mtd_panic_notify_remove(struct mtd_info *mtd) -{ - struct apanic_data *ctx = &drv_ctx; - if (mtd == ctx->mtd) { - ctx->mtd = NULL; - printk(KERN_INFO "apanic: Unbound from %s\n", mtd->name); - } -} - -static struct mtd_notifier mtd_panic_notifier = { - .add = mtd_panic_notify_add, - .remove = mtd_panic_notify_remove, -}; - -static int in_panic = 0; - -static int apanic_writeflashpage(struct mtd_info *mtd, loff_t to, - const u_char *buf) -{ - int rc; - size_t wlen; - int panic = in_interrupt() | in_atomic(); - - if (panic && !mtd->panic_write) { - printk(KERN_EMERG "%s: No panic_write available\n", __func__); - return 0; - } else if (!panic && !mtd->write) { - printk(KERN_EMERG "%s: No write available\n", __func__); - return 0; - } - - to = phy_offset(mtd, to); - if (to == APANIC_INVALID_OFFSET) { - printk(KERN_EMERG "apanic: write to invalid address\n"); - return 0; - } - - if (panic) - rc = mtd->panic_write(mtd, to, mtd->writesize, &wlen, buf); - else - rc = mtd->write(mtd, to, mtd->writesize, &wlen, buf); - - if (rc) { - printk(KERN_EMERG - "%s: Error writing data to flash (%d)\n", - __func__, rc); - return rc; - } - - return wlen; -} - -extern int log_buf_copy(char *dest, int idx, int len); -extern void log_buf_clear(void); - -/* - * Writes the contents of the console to the specified offset in flash. - * Returns number of bytes written - */ -static int apanic_write_console(struct mtd_info *mtd, unsigned int off) -{ - struct apanic_data *ctx = &drv_ctx; - int saved_oip; - int idx = 0; - int rc, rc2; - unsigned int last_chunk = 0; - - while (!last_chunk) { - saved_oip = oops_in_progress; - oops_in_progress = 1; - rc = log_buf_copy(ctx->bounce, idx, mtd->writesize); - if (rc < 0) - break; - - if (rc != mtd->writesize) - last_chunk = rc; - - oops_in_progress = saved_oip; - if (rc <= 0) - break; - if (rc != mtd->writesize) - memset(ctx->bounce + rc, 0, mtd->writesize - rc); - - rc2 = apanic_writeflashpage(mtd, off, ctx->bounce); - if (rc2 <= 0) { - printk(KERN_EMERG - "apanic: Flash write failed (%d)\n", rc2); - return idx; - } - if (!last_chunk) - idx += rc2; - else - idx += last_chunk; - off += rc2; - } - return idx; -} - -static int apanic(struct notifier_block *this, unsigned long event, - void *ptr) -{ - struct apanic_data *ctx = &drv_ctx; - struct panic_header *hdr = (struct panic_header *) ctx->bounce; - int console_offset = 0; - int console_len = 0; - int threads_offset = 0; - int threads_len = 0; - int rc; - - if (in_panic) - return NOTIFY_DONE; - in_panic = 1; -#ifdef CONFIG_PREEMPT - /* Ensure that cond_resched() won't try to preempt anybody */ - add_preempt_count(PREEMPT_ACTIVE); -#endif - touch_softlockup_watchdog(); - - if (!ctx->mtd) - goto out; - - if (ctx->curr.magic) { - printk(KERN_EMERG "Crash partition in use!\n"); - goto out; - } - console_offset = ctx->mtd->writesize; - - /* - * Write out the console - */ - console_len = apanic_write_console(ctx->mtd, console_offset); - if (console_len < 0) { - printk(KERN_EMERG "Error writing console to panic log! (%d)\n", - console_len); - console_len = 0; - } - - /* - * Write out all threads - */ - threads_offset = ALIGN(console_offset + console_len, - ctx->mtd->writesize); - if (!threads_offset) - threads_offset = ctx->mtd->writesize; - - ram_console_enable_console(0); - - log_buf_clear(); - show_state_filter(0); - threads_len = apanic_write_console(ctx->mtd, threads_offset); - if (threads_len < 0) { - printk(KERN_EMERG "Error writing threads to panic log! (%d)\n", - threads_len); - threads_len = 0; - } - - /* - * Finally write the panic header - */ - memset(ctx->bounce, 0, PAGE_SIZE); - hdr->magic = PANIC_MAGIC; - hdr->version = PHDR_VERSION; - - hdr->console_offset = console_offset; - hdr->console_length = console_len; - - hdr->threads_offset = threads_offset; - hdr->threads_length = threads_len; - - rc = apanic_writeflashpage(ctx->mtd, 0, ctx->bounce); - if (rc <= 0) { - printk(KERN_EMERG "apanic: Header write failed (%d)\n", - rc); - goto out; - } - - printk(KERN_EMERG "apanic: Panic dump sucessfully written to flash\n"); - - out: -#ifdef CONFIG_PREEMPT - sub_preempt_count(PREEMPT_ACTIVE); -#endif - in_panic = 0; - return NOTIFY_DONE; -} - -static struct notifier_block panic_blk = { - .notifier_call = apanic, -}; - -static int panic_dbg_get(void *data, u64 *val) -{ - apanic(NULL, 0, NULL); - return 0; -} - -static int panic_dbg_set(void *data, u64 val) -{ - BUG(); - return -1; -} - -DEFINE_SIMPLE_ATTRIBUTE(panic_dbg_fops, panic_dbg_get, panic_dbg_set, "%llu\n"); - -int __init apanic_init(void) -{ - register_mtd_user(&mtd_panic_notifier); - atomic_notifier_chain_register(&panic_notifier_list, &panic_blk); - debugfs_create_file("apanic", 0644, NULL, NULL, &panic_dbg_fops); - memset(&drv_ctx, 0, sizeof(drv_ctx)); - drv_ctx.bounce = (void *) __get_free_page(GFP_KERNEL); - INIT_WORK(&proc_removal_work, apanic_remove_proc_work); - printk(KERN_INFO "Android kernel panic handler initialized (bind=%s)\n", - CONFIG_APANIC_PLABEL); - return 0; -} - -module_init(apanic_init); diff --git a/drivers/misc/cb710/core.c b/drivers/misc/cb710/core.c index b1f16d6084ae..efec4139c3f6 100644 --- a/drivers/misc/cb710/core.c +++ b/drivers/misc/cb710/core.c @@ -244,7 +244,6 @@ static int __devinit cb710_probe(struct pci_dev *pdev, if (err) return err; - spin_lock_init(&chip->irq_lock); chip->pdev = pdev; chip->iobase = pcim_iomap_table(pdev)[0]; diff --git a/drivers/misc/cs5535-mfgpt.c b/drivers/misc/cs5535-mfgpt.c index 87a390de054c..bc685bfc4c33 100644 --- a/drivers/misc/cs5535-mfgpt.c +++ b/drivers/misc/cs5535-mfgpt.c @@ -262,7 +262,7 @@ static void __init reset_all_timers(void) * In other cases (such as with VSAless OpenFirmware), the system firmware * leaves timers available for us to use. */ -static int __devinit scan_timers(struct cs5535_mfgpt_chip *mfgpt) +static int __init scan_timers(struct cs5535_mfgpt_chip *mfgpt) { struct cs5535_mfgpt_timer timer = { .chip = mfgpt }; unsigned long flags; diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c index cdefef231fbd..8cebec5e85ee 100644 --- a/drivers/misc/kgdbts.c +++ b/drivers/misc/kgdbts.c @@ -133,17 +133,12 @@ static int force_hwbrks; static int hwbreaks_ok; static int hw_break_val; static int hw_break_val2; -static int cont_instead_of_sstep; -static unsigned long cont_thread_id; -static unsigned long sstep_thread_id; #if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || defined(CONFIG_SPARC) static int arch_needs_sstep_emulation = 1; #else static int arch_needs_sstep_emulation; #endif -static unsigned long cont_addr; static unsigned long sstep_addr; -static int restart_from_top_after_write; static int sstep_state; /* Storage for the registers, in GDB format. */ @@ -191,8 +186,7 @@ static int kgdbts_unreg_thread(void *ptr) */ while (!final_ack) msleep_interruptible(1500); - /* Pause for any other threads to exit after final ack. */ - msleep_interruptible(1000); + if (configured) kgdb_unregister_io_module(&kgdbts_io_ops); configured = 0; @@ -216,7 +210,7 @@ static unsigned long lookup_addr(char *arg) if (!strcmp(arg, "kgdbts_break_test")) addr = (unsigned long)kgdbts_break_test; else if (!strcmp(arg, "sys_open")) - addr = (unsigned long)do_sys_open; + addr = (unsigned long)sys_open; else if (!strcmp(arg, "do_fork")) addr = (unsigned long)do_fork; else if (!strcmp(arg, "hw_break_val")) @@ -288,16 +282,6 @@ static void hw_break_val_write(void) hw_break_val++; } -static int get_thread_id_continue(char *put_str, char *arg) -{ - char *ptr = &put_str[11]; - - if (put_str[1] != 'T' || put_str[2] != '0') - return 1; - kgdb_hex2long(&ptr, &cont_thread_id); - return 0; -} - static int check_and_rewind_pc(char *put_str, char *arg) { unsigned long addr = lookup_addr(arg); @@ -314,21 +298,13 @@ static int check_and_rewind_pc(char *put_str, char *arg) if (addr + BREAK_INSTR_SIZE == ip) offset = -BREAK_INSTR_SIZE; #endif - - if (arch_needs_sstep_emulation && sstep_addr && - ip + offset == sstep_addr && - ((!strcmp(arg, "sys_open") || !strcmp(arg, "do_fork")))) { - /* This is special case for emulated single step */ - v2printk("Emul: rewind hit single step bp\n"); - restart_from_top_after_write = 1; - } else if (strcmp(arg, "silent") && ip + offset != addr) { + if (strcmp(arg, "silent") && ip + offset != addr) { eprintk("kgdbts: BP mismatch %lx expected %lx\n", ip + offset, addr); return 1; } /* Readjust the instruction pointer if needed */ ip += offset; - cont_addr = ip; #ifdef GDB_ADJUSTS_BREAK_OFFSET instruction_pointer_set(&kgdbts_regs, ip); #endif @@ -338,8 +314,6 @@ static int check_and_rewind_pc(char *put_str, char *arg) static int check_single_step(char *put_str, char *arg) { unsigned long addr = lookup_addr(arg); - static int matched_id; - /* * From an arch indepent point of view the instruction pointer * should be on a different instruction @@ -349,29 +323,6 @@ static int check_single_step(char *put_str, char *arg) gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs); v2printk("Singlestep stopped at IP: %lx\n", instruction_pointer(&kgdbts_regs)); - - if (sstep_thread_id != cont_thread_id) { - /* - * Ensure we stopped in the same thread id as before, else the - * debugger should continue until the original thread that was - * single stepped is scheduled again, emulating gdb's behavior. - */ - v2printk("ThrID does not match: %lx\n", cont_thread_id); - if (arch_needs_sstep_emulation) { - if (matched_id && - instruction_pointer(&kgdbts_regs) != addr) - goto continue_test; - matched_id++; - ts.idx -= 2; - sstep_state = 0; - return 0; - } - cont_instead_of_sstep = 1; - ts.idx -= 4; - return 0; - } -continue_test: - matched_id = 0; if (instruction_pointer(&kgdbts_regs) == addr) { eprintk("kgdbts: SingleStep failed at %lx\n", instruction_pointer(&kgdbts_regs)); @@ -413,40 +364,10 @@ static int got_break(char *put_str, char *arg) return 1; } -static void get_cont_catch(char *arg) -{ - /* Always send detach because the test is completed at this point */ - fill_get_buf("D"); -} - -static int put_cont_catch(char *put_str, char *arg) -{ - /* This is at the end of the test and we catch any and all input */ - v2printk("kgdbts: cleanup task: %lx\n", sstep_thread_id); - ts.idx--; - return 0; -} - -static int emul_reset(char *put_str, char *arg) -{ - if (strncmp(put_str, "$OK", 3)) - return 1; - if (restart_from_top_after_write) { - restart_from_top_after_write = 0; - ts.idx = -1; - } - return 0; -} - static void emul_sstep_get(char *arg) { if (!arch_needs_sstep_emulation) { - if (cont_instead_of_sstep) { - cont_instead_of_sstep = 0; - fill_get_buf("c"); - } else { - fill_get_buf(arg); - } + fill_get_buf(arg); return; } switch (sstep_state) { @@ -476,11 +397,9 @@ static void emul_sstep_get(char *arg) static int emul_sstep_put(char *put_str, char *arg) { if (!arch_needs_sstep_emulation) { - char *ptr = &put_str[11]; - if (put_str[1] != 'T' || put_str[2] != '0') - return 1; - kgdb_hex2long(&ptr, &sstep_thread_id); - return 0; + if (!strncmp(put_str+1, arg, 2)) + return 0; + return 1; } switch (sstep_state) { case 1: @@ -491,7 +410,8 @@ static int emul_sstep_put(char *put_str, char *arg) v2printk("Stopped at IP: %lx\n", instruction_pointer(&kgdbts_regs)); /* Want to stop at IP + break instruction size by default */ - sstep_addr = cont_addr + BREAK_INSTR_SIZE; + sstep_addr = instruction_pointer(&kgdbts_regs) + + BREAK_INSTR_SIZE; break; case 2: if (strncmp(put_str, "$OK", 3)) { @@ -503,9 +423,6 @@ static int emul_sstep_put(char *put_str, char *arg) if (strncmp(put_str, "$T0", 3)) { eprintk("kgdbts: failed continue sstep\n"); return 1; - } else { - char *ptr = &put_str[11]; - kgdb_hex2long(&ptr, &sstep_thread_id); } break; case 4: @@ -584,10 +501,10 @@ static struct test_struct bad_read_test[] = { static struct test_struct singlestep_break_test[] = { { "?", "S0*" }, /* Clear break points */ { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ - { "c", "T0*", NULL, get_thread_id_continue }, /* Continue */ - { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */ + { "c", "T0*", }, /* Continue */ { "g", "kgdbts_break_test", NULL, check_and_rewind_pc }, { "write", "OK", write_regs }, /* Write registers */ + { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */ { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ { "g", "kgdbts_break_test", NULL, check_single_step }, { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ @@ -605,16 +522,16 @@ static struct test_struct singlestep_break_test[] = { static struct test_struct do_fork_test[] = { { "?", "S0*" }, /* Clear break points */ { "do_fork", "OK", sw_break, }, /* set sw breakpoint */ - { "c", "T0*", NULL, get_thread_id_continue }, /* Continue */ - { "do_fork", "OK", sw_rem_break }, /*remove breakpoint */ + { "c", "T0*", }, /* Continue */ { "g", "do_fork", NULL, check_and_rewind_pc }, /* check location */ - { "write", "OK", write_regs, emul_reset }, /* Write registers */ + { "write", "OK", write_regs }, /* Write registers */ + { "do_fork", "OK", sw_rem_break }, /*remove breakpoint */ { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ { "g", "do_fork", NULL, check_single_step }, { "do_fork", "OK", sw_break, }, /* set sw breakpoint */ { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */ { "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */ - { "", "", get_cont_catch, put_cont_catch }, + { "", "" }, }; /* Test for hitting a breakpoint at sys_open for what ever the number @@ -623,16 +540,16 @@ static struct test_struct do_fork_test[] = { static struct test_struct sys_open_test[] = { { "?", "S0*" }, /* Clear break points */ { "sys_open", "OK", sw_break, }, /* set sw breakpoint */ - { "c", "T0*", NULL, get_thread_id_continue }, /* Continue */ - { "sys_open", "OK", sw_rem_break }, /*remove breakpoint */ + { "c", "T0*", }, /* Continue */ { "g", "sys_open", NULL, check_and_rewind_pc }, /* check location */ - { "write", "OK", write_regs, emul_reset }, /* Write registers */ + { "write", "OK", write_regs }, /* Write registers */ + { "sys_open", "OK", sw_rem_break }, /*remove breakpoint */ { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ { "g", "sys_open", NULL, check_single_step }, { "sys_open", "OK", sw_break, }, /* set sw breakpoint */ { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */ { "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */ - { "", "", get_cont_catch, put_cont_catch }, + { "", "" }, }; /* @@ -775,8 +692,8 @@ static int run_simple_test(int is_get_char, int chr) /* This callback is a put char which is when kgdb sends data to * this I/O module. */ - if (ts.tst[ts.idx].get[0] == '\0' && ts.tst[ts.idx].put[0] == '\0' && - !ts.tst[ts.idx].get_handler) { + if (ts.tst[ts.idx].get[0] == '\0' && + ts.tst[ts.idx].put[0] == '\0') { eprintk("kgdbts: ERROR: beyond end of test on" " '%s' line %i\n", ts.name, ts.idx); return 0; @@ -989,17 +906,6 @@ static void kgdbts_run_tests(void) if (ptr) sstep_test = simple_strtol(ptr+1, NULL, 10); - /* All HW break point tests */ - if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) { - hwbreaks_ok = 1; - v1printk("kgdbts:RUN hw breakpoint test\n"); - run_breakpoint_test(1); - v1printk("kgdbts:RUN hw write breakpoint test\n"); - run_hw_break_test(1); - v1printk("kgdbts:RUN access write breakpoint test\n"); - run_hw_break_test(0); - } - /* required internal KGDB tests */ v1printk("kgdbts:RUN plant and detach test\n"); run_plant_and_detach_test(0); @@ -1017,11 +923,35 @@ static void kgdbts_run_tests(void) /* ===Optional tests=== */ + /* All HW break point tests */ + if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) { + hwbreaks_ok = 1; + v1printk("kgdbts:RUN hw breakpoint test\n"); + run_breakpoint_test(1); + v1printk("kgdbts:RUN hw write breakpoint test\n"); + run_hw_break_test(1); + v1printk("kgdbts:RUN access write breakpoint test\n"); + run_hw_break_test(0); + } + if (nmi_sleep) { v1printk("kgdbts:RUN NMI sleep %i seconds test\n", nmi_sleep); run_nmi_sleep_test(nmi_sleep); } +#ifdef CONFIG_DEBUG_RODATA + /* Until there is an api to write to read-only text segments, use + * HW breakpoints for the remainder of any tests, else print a + * failure message if hw breakpoints do not work. + */ + if (!(arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT && hwbreaks_ok)) { + eprintk("kgdbts: HW breakpoints do not work," + "skipping remaining tests\n"); + return; + } + force_hwbrks = 1; +#endif /* CONFIG_DEBUG_RODATA */ + /* If the do_fork test is run it will be the last test that is * executed because a kernel thread will be spawned at the very * end to unregister the debug hooks. diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c index 8b51cd62d067..b928bc14e97b 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.c +++ b/drivers/misc/lis3lv02d/lis3lv02d.c @@ -375,14 +375,12 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3) * both have been read. So the value read will always be correct. * Set BOOT bit to refresh factory tuning values. */ - if (lis3->pdata) { - lis3->read(lis3, CTRL_REG2, ®); - if (lis3->whoami == WAI_12B) - reg |= CTRL2_BDU | CTRL2_BOOT; - else - reg |= CTRL2_BOOT_8B; - lis3->write(lis3, CTRL_REG2, reg); - } + lis3->read(lis3, CTRL_REG2, ®); + if (lis3->whoami == WAI_12B) + reg |= CTRL2_BDU | CTRL2_BOOT; + else + reg |= CTRL2_BOOT_8B; + lis3->write(lis3, CTRL_REG2, reg); /* LIS3 power on delay is quite long */ msleep(lis3->pwron_delay / lis3lv02d_get_odr()); diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c index f51c81e1884a..5fe79df44838 100644 --- a/drivers/misc/pch_phub.c +++ b/drivers/misc/pch_phub.c @@ -73,9 +73,6 @@ #define PCI_DEVICE_ID_ROHM_ML7223_mPHUB 0x8012 /* for Bus-m */ #define PCI_DEVICE_ID_ROHM_ML7223_nPHUB 0x8002 /* for Bus-n */ -/* Macros for ML7831 */ -#define PCI_DEVICE_ID_ROHM_ML7831_PHUB 0x8801 - /* SROM ACCESS Macro */ #define PCH_WORD_ADDR_MASK (~((1 << 2) - 1)) @@ -93,7 +90,6 @@ #define PCH_PHUB_INTPIN_REG_WPERMIT_REG3 0x002C #define PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE 0x0040 #define CLKCFG_REG_OFFSET 0x500 -#define FUNCSEL_REG_OFFSET 0x508 #define PCH_PHUB_OROM_SIZE 15360 @@ -112,13 +108,11 @@ * @intpin_reg_wpermit_reg3: INTPIN_REG_WPERMIT register 3 val * @int_reduce_control_reg: INT_REDUCE_CONTROL registers val * @clkcfg_reg: CLK CFG register val - * @funcsel_reg: Function select register value * @pch_phub_base_address: Register base address * @pch_phub_extrom_base_address: external rom base address * @pch_mac_start_address: MAC address area start address * @pch_opt_rom_start_address: Option ROM start address * @ioh_type: Save IOH type - * @pdev: pointer to pci device struct */ struct pch_phub_reg { u32 phub_id_reg; @@ -134,13 +128,11 @@ struct pch_phub_reg { u32 intpin_reg_wpermit_reg3; u32 int_reduce_control_reg[MAX_NUM_INT_REDUCE_CONTROL_REG]; u32 clkcfg_reg; - u32 funcsel_reg; void __iomem *pch_phub_base_address; void __iomem *pch_phub_extrom_base_address; u32 pch_mac_start_address; u32 pch_opt_rom_start_address; int ioh_type; - struct pci_dev *pdev; }; /* SROM SPEC for MAC address assignment offset */ @@ -219,8 +211,6 @@ static void pch_phub_save_reg_conf(struct pci_dev *pdev) __func__, i, chip->int_reduce_control_reg[i]); } chip->clkcfg_reg = ioread32(p + CLKCFG_REG_OFFSET); - if ((chip->ioh_type == 2) || (chip->ioh_type == 4)) - chip->funcsel_reg = ioread32(p + FUNCSEL_REG_OFFSET); } /* pch_phub_restore_reg_conf - restore register configuration */ @@ -281,8 +271,6 @@ static void pch_phub_restore_reg_conf(struct pci_dev *pdev) } iowrite32(chip->clkcfg_reg, p + CLKCFG_REG_OFFSET); - if ((chip->ioh_type == 2) || (chip->ioh_type == 4)) - iowrite32(chip->funcsel_reg, p + FUNCSEL_REG_OFFSET); } /** @@ -476,7 +464,7 @@ static int pch_phub_write_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data) int retval; int i; - if ((chip->ioh_type == 1) || (chip->ioh_type == 5)) /* EG20T or ML7831*/ + if (chip->ioh_type == 1) /* EG20T */ retval = pch_phub_gbe_serial_rom_conf(chip); else /* ML7223 */ retval = pch_phub_gbe_serial_rom_conf_mp(chip); @@ -503,7 +491,6 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj, unsigned int orom_size; int ret; int err; - ssize_t rom_size; struct pch_phub_reg *chip = dev_get_drvdata(container_of(kobj, struct device, kobj)); @@ -515,10 +502,6 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj, } /* Get Rom signature */ - chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); - if (!chip->pch_phub_extrom_base_address) - goto exrom_map_err; - pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address, (unsigned char *)&rom_signature); rom_signature &= 0xff; @@ -549,13 +532,10 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj, goto return_err; } return_ok: - pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); mutex_unlock(&pch_phub_mutex); return addr_offset; return_err: - pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); -exrom_map_err: mutex_unlock(&pch_phub_mutex); return_err_nomutex: return err; @@ -568,7 +548,6 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj, int err; unsigned int addr_offset; int ret; - ssize_t rom_size; struct pch_phub_reg *chip = dev_get_drvdata(container_of(kobj, struct device, kobj)); @@ -585,12 +564,6 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj, goto return_ok; } - chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); - if (!chip->pch_phub_extrom_base_address) { - err = -ENOMEM; - goto exrom_map_err; - } - for (addr_offset = 0; addr_offset < count; addr_offset++) { if (PCH_PHUB_OROM_SIZE < off + addr_offset) goto return_ok; @@ -605,14 +578,10 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj, } return_ok: - pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); mutex_unlock(&pch_phub_mutex); return addr_offset; return_err: - pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); - -exrom_map_err: mutex_unlock(&pch_phub_mutex); return err; } @@ -622,14 +591,8 @@ static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr, { u8 mac[8]; struct pch_phub_reg *chip = dev_get_drvdata(dev); - ssize_t rom_size; - - chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); - if (!chip->pch_phub_extrom_base_address) - return -ENOMEM; pch_phub_read_gbe_mac_addr(chip, mac); - pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); @@ -639,7 +602,6 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { u8 mac[6]; - ssize_t rom_size; struct pch_phub_reg *chip = dev_get_drvdata(dev); if (count != 18) @@ -649,12 +611,7 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr, (u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3], (u32 *)&mac[4], (u32 *)&mac[5]); - chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); - if (!chip->pch_phub_extrom_base_address) - return -ENOMEM; - pch_phub_write_gbe_mac_addr(chip, mac); - pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); return count; } @@ -677,6 +634,7 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev, int retval; int ret; + ssize_t rom_size; struct pch_phub_reg *chip; chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL); @@ -713,7 +671,19 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev, "in pch_phub_base_address variable is %p\n", __func__, chip->pch_phub_base_address); - chip->pdev = pdev; /* Save pci device struct */ + if (id->driver_data != 3) { + chip->pch_phub_extrom_base_address =\ + pci_map_rom(pdev, &rom_size); + if (chip->pch_phub_extrom_base_address == 0) { + dev_err(&pdev->dev, "%s: pci_map_rom FAILED", __func__); + ret = -ENOMEM; + goto err_pci_map; + } + dev_dbg(&pdev->dev, "%s : " + "pci_map_rom SUCCESS and value in " + "pch_phub_extrom_base_address variable is %p\n", + __func__, chip->pch_phub_extrom_base_address); + } if (id->driver_data == 1) { /* EG20T PCH */ retval = sysfs_create_file(&pdev->dev.kobj, @@ -762,8 +732,6 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev, * Device8(GbE) */ iowrite32(0x000a0000, chip->pch_phub_base_address + 0x14); - /* set the interrupt delay value */ - iowrite32(0x25, chip->pch_phub_base_address + 0x140); chip->pch_opt_rom_start_address =\ PCH_PHUB_ROM_START_ADDR_ML7223; chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223; @@ -781,25 +749,11 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev, * Device6(SATA 2):f */ iowrite32(0x0000ffa0, chip->pch_phub_base_address + 0x14); + /* set the interrupt delay value */ + iowrite32(0x25, chip->pch_phub_base_address + 0x140); chip->pch_opt_rom_start_address =\ PCH_PHUB_ROM_START_ADDR_ML7223; chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223; - } else if (id->driver_data == 5) { /* ML7831 */ - retval = sysfs_create_file(&pdev->dev.kobj, - &dev_attr_pch_mac.attr); - if (retval) - goto err_sysfs_create; - - retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); - if (retval) - goto exit_bin_attr; - - /* set the prefech value */ - iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14); - /* set the interrupt delay value */ - iowrite32(0x25, chip->pch_phub_base_address + 0x44); - chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T; - chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T; } chip->ioh_type = id->driver_data; @@ -810,6 +764,8 @@ exit_bin_attr: sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); err_sysfs_create: + pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address); +err_pci_map: pci_iounmap(pdev, chip->pch_phub_base_address); err_pci_iomap: pci_release_regions(pdev); @@ -827,6 +783,7 @@ static void __devexit pch_phub_remove(struct pci_dev *pdev) sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr); + pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address); pci_iounmap(pdev, chip->pch_phub_base_address); pci_release_regions(pdev); pci_disable_device(pdev); @@ -881,7 +838,6 @@ static struct pci_device_id pch_phub_pcidev_id[] = { { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2, }, { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_mPHUB), 3, }, { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_nPHUB), 4, }, - { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7831_PHUB), 5, }, { } }; MODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id); diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c index d971817182f7..8d082b46426b 100644 --- a/drivers/misc/sgi-xp/xpc_main.c +++ b/drivers/misc/sgi-xp/xpc_main.c @@ -53,10 +53,6 @@ #include #include "xpc.h" -#ifdef CONFIG_X86_64 -#include -#endif - /* define two XPC debug device structures to be used with dev_dbg() et al */ struct device_driver xpc_dbg_name = { @@ -1083,9 +1079,6 @@ xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused) return NOTIFY_DONE; } -/* Used to only allow one cpu to complete disconnect */ -static unsigned int xpc_die_disconnecting; - /* * Notify other partitions to deactivate from us by first disengaging from all * references to our memory. @@ -1099,9 +1092,6 @@ xpc_die_deactivate(void) long keep_waiting; long wait_to_print; - if (cmpxchg(&xpc_die_disconnecting, 0, 1)) - return; - /* keep xpc_hb_checker thread from doing anything (just in case) */ xpc_exiting = 1; @@ -1169,7 +1159,7 @@ xpc_die_deactivate(void) * about the lack of a heartbeat. */ static int -xpc_system_die(struct notifier_block *nb, unsigned long event, void *_die_args) +xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused) { #ifdef CONFIG_IA64 /* !!! temporary kludge */ switch (event) { @@ -1201,27 +1191,7 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *_die_args) break; } #else - struct die_args *die_args = _die_args; - - switch (event) { - case DIE_TRAP: - if (die_args->trapnr == X86_TRAP_DF) - xpc_die_deactivate(); - - if (((die_args->trapnr == X86_TRAP_MF) || - (die_args->trapnr == X86_TRAP_XF)) && - !user_mode_vm(die_args->regs)) - xpc_die_deactivate(); - - break; - case DIE_INT3: - case DIE_DEBUG: - break; - case DIE_OOPS: - case DIE_GPF: - default: - xpc_die_deactivate(); - } + xpc_die_deactivate(); #endif return NOTIFY_DONE; diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index cc2ae7ec0d22..17bbacb1b4b1 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c @@ -18,8 +18,6 @@ #include #include #include -#include -#include #include #include #include @@ -61,8 +59,6 @@ static struct xpc_heartbeat_uv *xpc_heartbeat_uv; XPC_NOTIFY_MSG_SIZE_UV) #define XPC_NOTIFY_IRQ_NAME "xpc_notify" -static int xpc_mq_node = -1; - static struct xpc_gru_mq_uv *xpc_activate_mq_uv; static struct xpc_gru_mq_uv *xpc_notify_mq_uv; @@ -113,8 +109,11 @@ xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name) #if defined CONFIG_X86_64 mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset, UV_AFFINITY_CPU); - if (mq->irq < 0) + if (mq->irq < 0) { + dev_err(xpc_part, "uv_setup_irq() returned error=%d\n", + -mq->irq); return mq->irq; + } mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset); @@ -239,9 +238,8 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, mq->mmr_blade = uv_cpu_to_blade_id(cpu); nid = cpu_to_node(cpu); - page = alloc_pages_exact_node(nid, - GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, - pg_order); + page = alloc_pages_exact_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, + pg_order); if (page == NULL) { dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " "bytes of memory on nid=%d for GRU mq\n", mq_size, nid); @@ -1733,50 +1731,9 @@ static struct xpc_arch_operations xpc_arch_ops_uv = { .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv, }; -static int -xpc_init_mq_node(int nid) -{ - int cpu; - - get_online_cpus(); - - for_each_cpu(cpu, cpumask_of_node(nid)) { - xpc_activate_mq_uv = - xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, nid, - XPC_ACTIVATE_IRQ_NAME, - xpc_handle_activate_IRQ_uv); - if (!IS_ERR(xpc_activate_mq_uv)) - break; - } - if (IS_ERR(xpc_activate_mq_uv)) { - put_online_cpus(); - return PTR_ERR(xpc_activate_mq_uv); - } - - for_each_cpu(cpu, cpumask_of_node(nid)) { - xpc_notify_mq_uv = - xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, nid, - XPC_NOTIFY_IRQ_NAME, - xpc_handle_notify_IRQ_uv); - if (!IS_ERR(xpc_notify_mq_uv)) - break; - } - if (IS_ERR(xpc_notify_mq_uv)) { - xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); - put_online_cpus(); - return PTR_ERR(xpc_notify_mq_uv); - } - - put_online_cpus(); - return 0; -} - int xpc_init_uv(void) { - int nid; - int ret = 0; - xpc_arch_ops = xpc_arch_ops_uv; if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) { @@ -1785,21 +1742,21 @@ xpc_init_uv(void) return -E2BIG; } - if (xpc_mq_node < 0) - for_each_online_node(nid) { - ret = xpc_init_mq_node(nid); - - if (!ret) - break; - } - else - ret = xpc_init_mq_node(xpc_mq_node); + xpc_activate_mq_uv = xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, 0, + XPC_ACTIVATE_IRQ_NAME, + xpc_handle_activate_IRQ_uv); + if (IS_ERR(xpc_activate_mq_uv)) + return PTR_ERR(xpc_activate_mq_uv); - if (ret < 0) - dev_err(xpc_part, "xpc_init_mq_node() returned error=%d\n", - -ret); + xpc_notify_mq_uv = xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, 0, + XPC_NOTIFY_IRQ_NAME, + xpc_handle_notify_IRQ_uv); + if (IS_ERR(xpc_notify_mq_uv)) { + xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); + return PTR_ERR(xpc_notify_mq_uv); + } - return ret; + return 0; } void @@ -1808,6 +1765,3 @@ xpc_exit_uv(void) xpc_destroy_gru_mq_uv(xpc_notify_mq_uv); xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); } - -module_param(xpc_mq_node, int, 0); -MODULE_PARM_DESC(xpc_mq_node, "Node number on which to allocate message queues."); diff --git a/drivers/misc/spear13xx_pcie_gadget.c b/drivers/misc/spear13xx_pcie_gadget.c index 43d073bc1d9c..cfbddbef11de 100644 --- a/drivers/misc/spear13xx_pcie_gadget.c +++ b/drivers/misc/spear13xx_pcie_gadget.c @@ -903,6 +903,6 @@ static void __exit spear_pcie_gadget_exit(void) } module_exit(spear_pcie_gadget_exit); -MODULE_ALIAS("platform:pcie-gadget-spear"); +MODULE_ALIAS("pcie-gadget-spear"); MODULE_AUTHOR("Pratyush Anand"); MODULE_LICENSE("GPL"); diff --git a/drivers/misc/uid_stat.c b/drivers/misc/uid_stat.c deleted file mode 100644 index 2141124a6c12..000000000000 --- a/drivers/misc/uid_stat.c +++ /dev/null @@ -1,156 +0,0 @@ -/* drivers/misc/uid_stat.c - * - * Copyright (C) 2008 - 2009 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static DEFINE_SPINLOCK(uid_lock); -static LIST_HEAD(uid_list); -static struct proc_dir_entry *parent; - -struct uid_stat { - struct list_head link; - uid_t uid; - atomic_t tcp_rcv; - atomic_t tcp_snd; -}; - -static struct uid_stat *find_uid_stat(uid_t uid) { - unsigned long flags; - struct uid_stat *entry; - - spin_lock_irqsave(&uid_lock, flags); - list_for_each_entry(entry, &uid_list, link) { - if (entry->uid == uid) { - spin_unlock_irqrestore(&uid_lock, flags); - return entry; - } - } - spin_unlock_irqrestore(&uid_lock, flags); - return NULL; -} - -static int tcp_snd_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len; - unsigned int bytes; - char *p = page; - struct uid_stat *uid_entry = (struct uid_stat *) data; - if (!data) - return 0; - - bytes = (unsigned int) (atomic_read(&uid_entry->tcp_snd) + INT_MIN); - p += sprintf(p, "%u\n", bytes); - len = (p - page) - off; - *eof = (len <= count) ? 1 : 0; - *start = page + off; - return len; -} - -static int tcp_rcv_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len; - unsigned int bytes; - char *p = page; - struct uid_stat *uid_entry = (struct uid_stat *) data; - if (!data) - return 0; - - bytes = (unsigned int) (atomic_read(&uid_entry->tcp_rcv) + INT_MIN); - p += sprintf(p, "%u\n", bytes); - len = (p - page) - off; - *eof = (len <= count) ? 1 : 0; - *start = page + off; - return len; -} - -/* Create a new entry for tracking the specified uid. */ -static struct uid_stat *create_stat(uid_t uid) { - unsigned long flags; - char uid_s[32]; - struct uid_stat *new_uid; - struct proc_dir_entry *entry; - - /* Create the uid stat struct and append it to the list. */ - if ((new_uid = kmalloc(sizeof(struct uid_stat), GFP_KERNEL)) == NULL) - return NULL; - - new_uid->uid = uid; - /* Counters start at INT_MIN, so we can track 4GB of network traffic. */ - atomic_set(&new_uid->tcp_rcv, INT_MIN); - atomic_set(&new_uid->tcp_snd, INT_MIN); - - spin_lock_irqsave(&uid_lock, flags); - list_add_tail(&new_uid->link, &uid_list); - spin_unlock_irqrestore(&uid_lock, flags); - - sprintf(uid_s, "%d", uid); - entry = proc_mkdir(uid_s, parent); - - /* Keep reference to uid_stat so we know what uid to read stats from. */ - create_proc_read_entry("tcp_snd", S_IRUGO, entry , tcp_snd_read_proc, - (void *) new_uid); - - create_proc_read_entry("tcp_rcv", S_IRUGO, entry, tcp_rcv_read_proc, - (void *) new_uid); - - return new_uid; -} - -int uid_stat_tcp_snd(uid_t uid, int size) { - struct uid_stat *entry; - activity_stats_update(); - if ((entry = find_uid_stat(uid)) == NULL && - ((entry = create_stat(uid)) == NULL)) { - return -1; - } - atomic_add(size, &entry->tcp_snd); - return 0; -} - -int uid_stat_tcp_rcv(uid_t uid, int size) { - struct uid_stat *entry; - activity_stats_update(); - if ((entry = find_uid_stat(uid)) == NULL && - ((entry = create_stat(uid)) == NULL)) { - return -1; - } - atomic_add(size, &entry->tcp_rcv); - return 0; -} - -static int __init uid_stat_init(void) -{ - parent = proc_mkdir("uid_stat", NULL); - if (!parent) { - pr_err("uid_stat: failed to create proc entry\n"); - return -1; - } - return 0; -} - -__initcall(uid_stat_init); diff --git a/drivers/misc/wl127x-rfkill.c b/drivers/misc/wl127x-rfkill.c deleted file mode 100644 index f5b95152948b..000000000000 --- a/drivers/misc/wl127x-rfkill.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Bluetooth TI wl127x rfkill power control via GPIO - * - * Copyright (C) 2009 Motorola, Inc. - * Copyright (C) 2008 Texas Instruments - * Initial code: Pavan Savoy (wl127x_power.c) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include - -static int wl127x_rfkill_set_power(void *data, enum rfkill_state state) -{ - int nshutdown_gpio = (int) data; - - switch (state) { - case RFKILL_STATE_UNBLOCKED: - gpio_set_value(nshutdown_gpio, 1); - break; - case RFKILL_STATE_SOFT_BLOCKED: - gpio_set_value(nshutdown_gpio, 0); - break; - default: - printk(KERN_ERR "invalid bluetooth rfkill state %d\n", state); - } - return 0; -} - -static int wl127x_rfkill_probe(struct platform_device *pdev) -{ - int rc = 0; - struct wl127x_rfkill_platform_data *pdata = pdev->dev.platform_data; - enum rfkill_state default_state = RFKILL_STATE_SOFT_BLOCKED; /* off */ - - rc = gpio_request(pdata->nshutdown_gpio, "wl127x_nshutdown_gpio"); - if (unlikely(rc)) - return rc; - - rc = gpio_direction_output(pdata->nshutdown_gpio, 0); - if (unlikely(rc)) - return rc; - - rfkill_set_default(RFKILL_TYPE_BLUETOOTH, default_state); - wl127x_rfkill_set_power(NULL, default_state); - - pdata->rfkill = rfkill_allocate(&pdev->dev, RFKILL_TYPE_BLUETOOTH); - if (unlikely(!pdata->rfkill)) - return -ENOMEM; - - pdata->rfkill->name = "wl127x"; - pdata->rfkill->state = default_state; - /* userspace cannot take exclusive control */ - pdata->rfkill->user_claim_unsupported = 1; - pdata->rfkill->user_claim = 0; - pdata->rfkill->data = (void *) pdata->nshutdown_gpio; - pdata->rfkill->toggle_radio = wl127x_rfkill_set_power; - - rc = rfkill_register(pdata->rfkill); - - if (unlikely(rc)) - rfkill_free(pdata->rfkill); - - return 0; -} - -static int wl127x_rfkill_remove(struct platform_device *pdev) -{ - struct wl127x_rfkill_platform_data *pdata = pdev->dev.platform_data; - - rfkill_unregister(pdata->rfkill); - rfkill_free(pdata->rfkill); - gpio_free(pdata->nshutdown_gpio); - - return 0; -} - -static struct platform_driver wl127x_rfkill_platform_driver = { - .probe = wl127x_rfkill_probe, - .remove = wl127x_rfkill_remove, - .driver = { - .name = "wl127x-rfkill", - .owner = THIS_MODULE, - }, -}; - -static int __init wl127x_rfkill_init(void) -{ - return platform_driver_register(&wl127x_rfkill_platform_driver); -} - -static void __exit wl127x_rfkill_exit(void) -{ - platform_driver_unregister(&wl127x_rfkill_platform_driver); -} - -module_init(wl127x_rfkill_init); -module_exit(wl127x_rfkill_exit); - -MODULE_ALIAS("platform:wl127x"); -MODULE_DESCRIPTION("wl127x-rfkill"); -MODULE_AUTHOR("Motorola"); -MODULE_LICENSE("GPL"); diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig index ebb4afe6c702..3b1f783bf924 100644 --- a/drivers/mmc/card/Kconfig +++ b/drivers/mmc/card/Kconfig @@ -50,15 +50,6 @@ config MMC_BLOCK_BOUNCE If unsure, say Y here. -config MMC_BLOCK_DEFERRED_RESUME - bool "Deferr MMC layer resume until I/O is requested" - depends on MMC_BLOCK - default n - help - Say Y here to enable deferred MMC resume until I/O - is requested. This will reduce overall resume latency and - save power when theres an SD card inserted but not being used. - config SDIO_UART tristate "SDIO UART/GPS class support" help diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 435f1fddfe6b..f85e42224559 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -126,7 +126,11 @@ static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) static inline int mmc_get_devidx(struct gendisk *disk) { - int devidx = disk->first_minor / perdev_minors; + int devmaj = MAJOR(disk_devt(disk)); + int devidx = MINOR(disk_devt(disk)) / perdev_minors; + + if (!devmaj) + devidx = disk->first_minor / perdev_minors; return devidx; } @@ -247,9 +251,6 @@ static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user( goto idata_err; } - if (!idata->buf_bytes) - return idata; - idata->buf = kzalloc(idata->buf_bytes, GFP_KERNEL); if (!idata->buf) { err = -ENOMEM; @@ -296,6 +297,25 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, if (IS_ERR(idata)) return PTR_ERR(idata); + cmd.opcode = idata->ic.opcode; + cmd.arg = idata->ic.arg; + cmd.flags = idata->ic.flags; + + data.sg = &sg; + data.sg_len = 1; + data.blksz = idata->ic.blksz; + data.blocks = idata->ic.blocks; + + sg_init_one(data.sg, idata->buf, idata->buf_bytes); + + if (idata->ic.write_flag) + data.flags = MMC_DATA_WRITE; + else + data.flags = MMC_DATA_READ; + + mrq.cmd = &cmd; + mrq.data = &data; + md = mmc_blk_get(bdev->bd_disk); if (!md) { err = -EINVAL; @@ -308,48 +328,6 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, goto cmd_done; } - cmd.opcode = idata->ic.opcode; - cmd.arg = idata->ic.arg; - cmd.flags = idata->ic.flags; - - if (idata->buf_bytes) { - data.sg = &sg; - data.sg_len = 1; - data.blksz = idata->ic.blksz; - data.blocks = idata->ic.blocks; - - sg_init_one(data.sg, idata->buf, idata->buf_bytes); - - if (idata->ic.write_flag) - data.flags = MMC_DATA_WRITE; - else - data.flags = MMC_DATA_READ; - - /* data.flags must already be set before doing this. */ - mmc_set_data_timeout(&data, card); - - /* Allow overriding the timeout_ns for empirical tuning. */ - if (idata->ic.data_timeout_ns) - data.timeout_ns = idata->ic.data_timeout_ns; - - if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) { - /* - * Pretend this is a data transfer and rely on the - * host driver to compute timeout. When all host - * drivers support cmd.cmd_timeout for R1B, this - * can be changed to: - * - * mrq.data = NULL; - * cmd.cmd_timeout = idata->ic.cmd_timeout_ms; - */ - data.timeout_ns = idata->ic.cmd_timeout_ms * 1000000; - } - - mrq.data = &data; - } - - mrq.cmd = &cmd; - mmc_claim_host(card->host); if (idata->ic.is_acmd) { @@ -358,6 +336,24 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, goto cmd_rel_host; } + /* data.flags must already be set before doing this. */ + mmc_set_data_timeout(&data, card); + /* Allow overriding the timeout_ns for empirical tuning. */ + if (idata->ic.data_timeout_ns) + data.timeout_ns = idata->ic.data_timeout_ns; + + if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) { + /* + * Pretend this is a data transfer and rely on the host driver + * to compute timeout. When all host drivers support + * cmd.cmd_timeout for R1B, this can be changed to: + * + * mrq.data = NULL; + * cmd.cmd_timeout = idata->ic.cmd_timeout_ms; + */ + data.timeout_ns = idata->ic.cmd_timeout_ms * 1000000; + } + mmc_wait_for_req(card->host, &mrq); if (cmd.error) { @@ -529,20 +525,7 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) return result; } -static int send_stop(struct mmc_card *card, u32 *status) -{ - struct mmc_command cmd = {0}; - int err; - - cmd.opcode = MMC_STOP_TRANSMISSION; - cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; - err = mmc_wait_for_cmd(card->host, &cmd, 5); - if (err == 0) - *status = cmd.resp[0]; - return err; -} - -static int get_card_status(struct mmc_card *card, u32 *status, int retries) +static u32 get_card_status(struct mmc_card *card, struct request *req) { struct mmc_command cmd = {0}; int err; @@ -551,145 +534,11 @@ static int get_card_status(struct mmc_card *card, u32 *status, int retries) if (!mmc_host_is_spi(card->host)) cmd.arg = card->rca << 16; cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; - err = mmc_wait_for_cmd(card->host, &cmd, retries); - if (err == 0) - *status = cmd.resp[0]; - return err; -} - -#define ERR_RETRY 2 -#define ERR_ABORT 1 -#define ERR_CONTINUE 0 - -static int mmc_blk_cmd_error(struct request *req, const char *name, int error, - bool status_valid, u32 status) -{ - switch (error) { - case -EILSEQ: - /* response crc error, retry the r/w cmd */ - pr_err("%s: %s sending %s command, card status %#x\n", - req->rq_disk->disk_name, "response CRC error", - name, status); - return ERR_RETRY; - - case -ETIMEDOUT: - pr_err("%s: %s sending %s command, card status %#x\n", - req->rq_disk->disk_name, "timed out", name, status); - - /* If the status cmd initially failed, retry the r/w cmd */ - if (!status_valid) { - pr_err("%s: status not valid, retrying timeout\n", req->rq_disk->disk_name); - return ERR_RETRY; - } - /* - * If it was a r/w cmd crc error, or illegal command - * (eg, issued in wrong state) then retry - we should - * have corrected the state problem above. - */ - if (status & (R1_COM_CRC_ERROR | R1_ILLEGAL_COMMAND)) { - pr_err("%s: command error, retrying timeout\n", req->rq_disk->disk_name); - return ERR_RETRY; - } - - /* Otherwise abort the command */ - pr_err("%s: not retrying timeout\n", req->rq_disk->disk_name); - return ERR_ABORT; - - default: - /* We don't understand the error code the driver gave us */ - pr_err("%s: unknown error %d sending read/write command, card status %#x\n", - req->rq_disk->disk_name, error, status); - return ERR_ABORT; - } -} - -/* - * Initial r/w and stop cmd error recovery. - * We don't know whether the card received the r/w cmd or not, so try to - * restore things back to a sane state. Essentially, we do this as follows: - * - Obtain card status. If the first attempt to obtain card status fails, - * the status word will reflect the failed status cmd, not the failed - * r/w cmd. If we fail to obtain card status, it suggests we can no - * longer communicate with the card. - * - Check the card state. If the card received the cmd but there was a - * transient problem with the response, it might still be in a data transfer - * mode. Try to send it a stop command. If this fails, we can't recover. - * - If the r/w cmd failed due to a response CRC error, it was probably - * transient, so retry the cmd. - * - If the r/w cmd timed out, but we didn't get the r/w cmd status, retry. - * - If the r/w cmd timed out, and the r/w cmd failed due to CRC error or - * illegal cmd, retry. - * Otherwise we don't understand what happened, so abort. - */ -static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, - struct mmc_blk_request *brq) -{ - bool prev_cmd_status_valid = true; - u32 status, stop_status = 0; - int err, retry; - - /* - * Try to get card status which indicates both the card state - * and why there was no response. If the first attempt fails, - * we can't be sure the returned status is for the r/w command. - */ - for (retry = 2; retry >= 0; retry--) { - err = get_card_status(card, &status, 0); - if (!err) - break; - - prev_cmd_status_valid = false; - pr_err("%s: error %d sending status command, %sing\n", - req->rq_disk->disk_name, err, retry ? "retry" : "abort"); - } - - /* We couldn't get a response from the card. Give up. */ + err = mmc_wait_for_cmd(card->host, &cmd, 0); if (err) - return ERR_ABORT; - - /* - * Check the current card state. If it is in some data transfer - * mode, tell it to stop (and hopefully transition back to TRAN.) - */ - if (R1_CURRENT_STATE(status) == R1_STATE_DATA || - R1_CURRENT_STATE(status) == R1_STATE_RCV) { - err = send_stop(card, &stop_status); - if (err) - pr_err("%s: error %d sending stop command\n", - req->rq_disk->disk_name, err); - - /* - * If the stop cmd also timed out, the card is probably - * not present, so abort. Other errors are bad news too. - */ - if (err) - return ERR_ABORT; - } - - /* Check for set block count errors */ - if (brq->sbc.error) - return mmc_blk_cmd_error(req, "SET_BLOCK_COUNT", brq->sbc.error, - prev_cmd_status_valid, status); - - /* Check for r/w command errors */ - if (brq->cmd.error) - return mmc_blk_cmd_error(req, "r/w cmd", brq->cmd.error, - prev_cmd_status_valid, status); - - /* Now for stop errors. These aren't fatal to the transfer. */ - pr_err("%s: error %d sending stop command, original cmd response %#x, card status %#x\n", - req->rq_disk->disk_name, brq->stop.error, - brq->cmd.resp[0], status); - - /* - * Subsitute in our own stop status as this will give the error - * state which happened during the execution of the r/w command. - */ - if (stop_status) { - brq->stop.resp[0] = stop_status; - brq->stop.error = 0; - } - return ERR_CONTINUE; + printk(KERN_ERR "%s: error %d sending status command", + req->rq_disk->disk_name, err); + return cmd.resp[0]; } static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) @@ -820,20 +669,12 @@ static inline void mmc_apply_rel_rw(struct mmc_blk_request *brq, } } -#define CMD_ERRORS \ - (R1_OUT_OF_RANGE | /* Command argument out of range */ \ - R1_ADDRESS_ERROR | /* Misaligned address */ \ - R1_BLOCK_LEN_ERROR | /* Transferred block length incorrect */\ - R1_WP_VIOLATION | /* Tried to write to protected block */ \ - R1_CC_ERROR | /* Card controller error */ \ - R1_ERROR) /* General/unknown error */ - static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) { struct mmc_blk_data *md = mq->data; struct mmc_card *card = md->queue.card; struct mmc_blk_request brq; - int ret = 1, disable_multi = 0, retry = 0; + int ret = 1, disable_multi = 0; /* * Reliable writes are used to implement Forced Unit Access and @@ -845,7 +686,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) (md->flags & MMC_BLK_REL_WR); do { - u32 readcmd, writecmd; + struct mmc_command cmd = {0}; + u32 readcmd, writecmd, status = 0; memset(&brq, 0, sizeof(struct mmc_blk_request)); brq.mrq.cmd = &brq.cmd; @@ -962,47 +804,62 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) mmc_queue_bounce_post(mq); /* - * sbc.error indicates a problem with the set block count - * command. No data will have been transferred. - * - * cmd.error indicates a problem with the r/w command. No - * data will have been transferred. - * - * stop.error indicates a problem with the stop command. Data - * may have been transferred, or may still be transferring. + * Check for errors here, but don't jump to cmd_err + * until later as we need to wait for the card to leave + * programming mode even when things go wrong. */ - if (brq.sbc.error || brq.cmd.error || brq.stop.error) { - switch (mmc_blk_cmd_recovery(card, req, &brq)) { - case ERR_RETRY: - if (retry++ < 5) - continue; - case ERR_ABORT: - goto cmd_abort; - case ERR_CONTINUE: - break; + if (brq.sbc.error || brq.cmd.error || + brq.data.error || brq.stop.error) { + if (brq.data.blocks > 1 && rq_data_dir(req) == READ) { + /* Redo read one sector at a time */ + printk(KERN_WARNING "%s: retrying using single " + "block read\n", req->rq_disk->disk_name); + disable_multi = 1; + continue; } + status = get_card_status(card, req); } - /* - * Check for errors relating to the execution of the - * initial command - such as address errors. No data - * has been transferred. - */ - if (brq.cmd.resp[0] & CMD_ERRORS) { - pr_err("%s: r/w command failed, status = %#x\n", - req->rq_disk->disk_name, brq.cmd.resp[0]); - goto cmd_abort; + if (brq.sbc.error) { + printk(KERN_ERR "%s: error %d sending SET_BLOCK_COUNT " + "command, response %#x, card status %#x\n", + req->rq_disk->disk_name, brq.sbc.error, + brq.sbc.resp[0], status); + } + + if (brq.cmd.error) { + printk(KERN_ERR "%s: error %d sending read/write " + "command, response %#x, card status %#x\n", + req->rq_disk->disk_name, brq.cmd.error, + brq.cmd.resp[0], status); + } + + if (brq.data.error) { + if (brq.data.error == -ETIMEDOUT && brq.mrq.stop) + /* 'Stop' response contains card status */ + status = brq.mrq.stop->resp[0]; + printk(KERN_ERR "%s: error %d transferring data," + " sector %u, nr %u, card status %#x\n", + req->rq_disk->disk_name, brq.data.error, + (unsigned)blk_rq_pos(req), + (unsigned)blk_rq_sectors(req), status); + } + + if (brq.stop.error) { + printk(KERN_ERR "%s: error %d sending stop command, " + "response %#x, card status %#x\n", + req->rq_disk->disk_name, brq.stop.error, + brq.stop.resp[0], status); } - /* - * Everything else is either success, or a data error of some - * kind. If it was a write, we may have transitioned to - * program mode, which we have to wait for it to complete. - */ if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { - u32 status; do { - int err = get_card_status(card, &status, 5); + int err; + + cmd.opcode = MMC_SEND_STATUS; + cmd.arg = card->rca << 16; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + err = mmc_wait_for_cmd(card->host, &cmd, 5); if (err) { printk(KERN_ERR "%s: error %d requesting status\n", req->rq_disk->disk_name, err); @@ -1013,26 +870,20 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) * so make sure to check both the busy * indication and the card state. */ - } while (!(status & R1_READY_FOR_DATA) || - (R1_CURRENT_STATE(status) == R1_STATE_PRG)); + } while (!(cmd.resp[0] & R1_READY_FOR_DATA) || + (R1_CURRENT_STATE(cmd.resp[0]) == 7)); + +#if 0 + if (cmd.resp[0] & ~0x00000900) + printk(KERN_ERR "%s: status = %08x\n", + req->rq_disk->disk_name, cmd.resp[0]); + if (mmc_decode_status(cmd.resp)) + goto cmd_err; +#endif } - if (brq.data.error) { - pr_err("%s: error %d transferring data, sector %u, nr %u, cmd response %#x, card status %#x\n", - req->rq_disk->disk_name, brq.data.error, - (unsigned)blk_rq_pos(req), - (unsigned)blk_rq_sectors(req), - brq.cmd.resp[0], brq.stop.resp[0]); - + if (brq.cmd.error || brq.stop.error || brq.data.error) { if (rq_data_dir(req) == READ) { - if (brq.data.blocks > 1) { - /* Redo read one sector at a time */ - pr_warning("%s: retrying using single block read\n", - req->rq_disk->disk_name); - disable_multi = 1; - continue; - } - /* * After an error, we redo I/O one sector at a * time, so we only reach here after trying to @@ -1042,9 +893,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) ret = __blk_end_request(req, -EIO, brq.data.blksz); spin_unlock_irq(&md->lock); continue; - } else { - goto cmd_err; } + goto cmd_err; } /* @@ -1081,7 +931,6 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) spin_unlock_irq(&md->lock); } - cmd_abort: spin_lock_irq(&md->lock); while (ret) ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req)); @@ -1090,22 +939,12 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) return 0; } -static int -mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card); - static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) { int ret; struct mmc_blk_data *md = mq->data; struct mmc_card *card = md->queue.card; -#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME - if (mmc_bus_needs_resume(card->host)) { - mmc_resume_bus(card->host); - mmc_blk_set_blksize(md, card); - } -#endif - mmc_claim_host(card->host); ret = mmc_blk_part_switch(card, md); if (ret) { @@ -1199,7 +1038,6 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, md->disk->queue = md->queue.queue; md->disk->driverfs_dev = parent; set_disk_ro(md->disk, md->read_only || default_ro); - md->disk->flags = GENHD_FL_EXT_DEVT; /* * As discussed on lkml, GENHD_FL_REMOVABLE should: @@ -1439,9 +1277,6 @@ static int mmc_blk_probe(struct mmc_card *card) mmc_set_drvdata(card, md); mmc_fixup_device(card, blk_fixups); -#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME - mmc_set_bus_resume_policy(card->host, 1); -#endif if (mmc_add_disk(md)) goto out; @@ -1467,9 +1302,6 @@ static void mmc_blk_remove(struct mmc_card *card) mmc_release_host(card->host); mmc_blk_remove_req(md); mmc_set_drvdata(card, NULL); -#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME - mmc_set_bus_resume_policy(card->host, 0); -#endif } #ifdef CONFIG_PM @@ -1493,9 +1325,7 @@ static int mmc_blk_resume(struct mmc_card *card) struct mmc_blk_data *md = mmc_get_drvdata(card); if (md) { -#ifndef CONFIG_MMC_BLOCK_DEFERRED_RESUME mmc_blk_set_blksize(md, card); -#endif /* * Resume involves the card going into idle state, diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig index 85c2e1acd156..ef103871517f 100644 --- a/drivers/mmc/core/Kconfig +++ b/drivers/mmc/core/Kconfig @@ -27,20 +27,3 @@ config MMC_CLKGATE support handling this in order for it to be of any use. If unsure, say N. - -config MMC_EMBEDDED_SDIO - boolean "MMC embedded SDIO device support (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - If you say Y here, support will be added for embedded SDIO - devices which do not contain the necessary enumeration - support in hardware to be properly detected. - -config MMC_PARANOID_SD_INIT - bool "Enable paranoid SD card initialization (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - If you say Y here, the MMC layer will be extra paranoid - about re-trying SD init requests. This can be a useful - work-around for buggy controllers and hardware. Enable - if you are experiencing issues with SD detection. diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index e07d6c90caec..393d817ed040 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -120,19 +120,18 @@ static int mmc_bus_remove(struct device *dev) return 0; } -static int mmc_bus_pm_suspend(struct device *dev) +static int mmc_bus_suspend(struct device *dev, pm_message_t state) { struct mmc_driver *drv = to_mmc_driver(dev->driver); struct mmc_card *card = mmc_dev_to_card(dev); int ret = 0; - pm_message_t state = { PM_EVENT_SUSPEND }; if (dev->driver && drv->suspend) ret = drv->suspend(card, state); return ret; } -static int mmc_bus_pm_resume(struct device *dev) +static int mmc_bus_resume(struct device *dev) { struct mmc_driver *drv = to_mmc_driver(dev->driver); struct mmc_card *card = mmc_dev_to_card(dev); @@ -144,6 +143,7 @@ static int mmc_bus_pm_resume(struct device *dev) } #ifdef CONFIG_PM_RUNTIME + static int mmc_runtime_suspend(struct device *dev) { struct mmc_card *card = mmc_dev_to_card(dev); @@ -162,13 +162,21 @@ static int mmc_runtime_idle(struct device *dev) { return pm_runtime_suspend(dev); } -#endif /* CONFIG_PM_RUNTIME */ static const struct dev_pm_ops mmc_bus_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_pm_suspend, mmc_bus_pm_resume) - SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume, mmc_runtime_idle) + .runtime_suspend = mmc_runtime_suspend, + .runtime_resume = mmc_runtime_resume, + .runtime_idle = mmc_runtime_idle, }; +#define MMC_PM_OPS_PTR (&mmc_bus_pm_ops) + +#else /* !CONFIG_PM_RUNTIME */ + +#define MMC_PM_OPS_PTR NULL + +#endif /* !CONFIG_PM_RUNTIME */ + static struct bus_type mmc_bus_type = { .name = "mmc", .dev_attrs = mmc_dev_attrs, @@ -176,7 +184,9 @@ static struct bus_type mmc_bus_type = { .uevent = mmc_bus_uevent, .probe = mmc_bus_probe, .remove = mmc_bus_remove, - .pm = &mmc_bus_pm_ops, + .suspend = mmc_bus_suspend, + .resume = mmc_bus_resume, + .pm = MMC_PM_OPS_PTR, }; int mmc_register_bus(void) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 460863422892..7843efe22359 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -133,7 +132,7 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) if (mrq->done) mrq->done(mrq); - mmc_host_clk_release(host); + mmc_host_clk_gate(host); } } @@ -192,7 +191,7 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) mrq->stop->mrq = mrq; } } - mmc_host_clk_hold(host); + mmc_host_clk_ungate(host); led_trigger_event(host->led, LED_FULL); host->ops->request(host, mrq); } @@ -635,17 +634,15 @@ static inline void mmc_set_ios(struct mmc_host *host) */ void mmc_set_chip_select(struct mmc_host *host, int mode) { - mmc_host_clk_hold(host); host->ios.chip_select = mode; mmc_set_ios(host); - mmc_host_clk_release(host); } /* * Sets the host clock to the highest possible frequency that * is below "hz". */ -static void __mmc_set_clock(struct mmc_host *host, unsigned int hz) +void mmc_set_clock(struct mmc_host *host, unsigned int hz) { WARN_ON(hz < host->f_min); @@ -656,13 +653,6 @@ static void __mmc_set_clock(struct mmc_host *host, unsigned int hz) mmc_set_ios(host); } -void mmc_set_clock(struct mmc_host *host, unsigned int hz) -{ - mmc_host_clk_hold(host); - __mmc_set_clock(host, hz); - mmc_host_clk_release(host); -} - #ifdef CONFIG_MMC_CLKGATE /* * This gates the clock by setting it to 0 Hz. @@ -695,7 +685,7 @@ void mmc_ungate_clock(struct mmc_host *host) if (host->clk_old) { BUG_ON(host->ios.clock); /* This call will also set host->clk_gated to false */ - __mmc_set_clock(host, host->clk_old); + mmc_set_clock(host, host->clk_old); } } @@ -723,10 +713,8 @@ void mmc_set_ungated(struct mmc_host *host) */ void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode) { - mmc_host_clk_hold(host); host->ios.bus_mode = mode; mmc_set_ios(host); - mmc_host_clk_release(host); } /* @@ -734,10 +722,8 @@ void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode) */ void mmc_set_bus_width(struct mmc_host *host, unsigned int width) { - mmc_host_clk_hold(host); host->ios.bus_width = width; mmc_set_ios(host); - mmc_host_clk_release(host); } /** @@ -935,10 +921,8 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) ocr &= 3 << bit; - mmc_host_clk_hold(host); host->ios.vdd = bit; mmc_set_ios(host); - mmc_host_clk_release(host); } else { pr_warning("%s: host doesn't support card's voltages\n", mmc_hostname(host)); @@ -985,10 +969,8 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11 */ void mmc_set_timing(struct mmc_host *host, unsigned int timing) { - mmc_host_clk_hold(host); host->ios.timing = timing; mmc_set_ios(host); - mmc_host_clk_release(host); } /* @@ -996,10 +978,8 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing) */ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type) { - mmc_host_clk_hold(host); host->ios.drv_type = drv_type; mmc_set_ios(host); - mmc_host_clk_release(host); } /* @@ -1017,8 +997,6 @@ static void mmc_power_up(struct mmc_host *host) { int bit; - mmc_host_clk_hold(host); - /* If ocr is set, we use it */ if (host->ocr) bit = ffs(host->ocr) - 1; @@ -1054,14 +1032,10 @@ static void mmc_power_up(struct mmc_host *host) * time required to reach a stable voltage. */ mmc_delay(10); - - mmc_host_clk_release(host); } -void mmc_power_off(struct mmc_host *host) +static void mmc_power_off(struct mmc_host *host) { - mmc_host_clk_hold(host); - host->ios.clock = 0; host->ios.vdd = 0; @@ -1079,8 +1053,6 @@ void mmc_power_off(struct mmc_host *host) host->ios.bus_width = MMC_BUS_WIDTH_1; host->ios.timing = MMC_TIMING_LEGACY; mmc_set_ios(host); - - mmc_host_clk_release(host); } /* @@ -1122,36 +1094,6 @@ static inline void mmc_bus_put(struct mmc_host *host) spin_unlock_irqrestore(&host->lock, flags); } -int mmc_resume_bus(struct mmc_host *host) -{ - unsigned long flags; - - if (!mmc_bus_needs_resume(host)) - return -EINVAL; - - printk("%s: Starting deferred resume\n", mmc_hostname(host)); - spin_lock_irqsave(&host->lock, flags); - host->bus_resume_flags &= ~MMC_BUSRESUME_NEEDS_RESUME; - host->rescan_disable = 0; - spin_unlock_irqrestore(&host->lock, flags); - - mmc_bus_get(host); - if (host->bus_ops && !host->bus_dead) { - mmc_power_up(host); - BUG_ON(!host->bus_ops->resume); - host->bus_ops->resume(host); - } - - if (host->bus_ops->detect && !host->bus_dead) - host->bus_ops->detect(host); - - mmc_bus_put(host); - printk("%s: Deferred resume completed\n", mmc_hostname(host)); - return 0; -} - -EXPORT_SYMBOL(mmc_resume_bus); - /* * Assign a mmc bus handler to a host. Only one bus handler may control a * host at any given time. @@ -1178,7 +1120,8 @@ void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops) } /* - * Remove the current bus handler from a host. + * Remove the current bus handler from a host. Assumes that there are + * no interesting cards left, so the bus is powered down. */ void mmc_detach_bus(struct mmc_host *host) { @@ -1195,6 +1138,8 @@ void mmc_detach_bus(struct mmc_host *host) spin_unlock_irqrestore(&host->lock, flags); + mmc_power_off(host); + mmc_bus_put(host); } @@ -1217,7 +1162,6 @@ void mmc_detect_change(struct mmc_host *host, unsigned long delay) spin_unlock_irqrestore(&host->lock, flags); #endif - wake_lock(&host->detect_wake_lock); mmc_schedule_delayed_work(&host->detect, delay); } @@ -1624,7 +1568,6 @@ void mmc_rescan(struct work_struct *work) struct mmc_host *host = container_of(work, struct mmc_host, detect.work); int i; - bool extend_wakelock = false; if (host->rescan_disable) return; @@ -1639,12 +1582,6 @@ void mmc_rescan(struct work_struct *work) && !(host->caps & MMC_CAP_NONREMOVABLE)) host->bus_ops->detect(host); - /* If the card was removed the bus will be marked - * as dead - extend the wakelock so userspace - * can respond */ - if (host->bus_dead) - extend_wakelock = 1; - /* * Let mmc_bus_put() free the bus/bus_ops if we've found that * the card is no longer present. @@ -1669,24 +1606,16 @@ void mmc_rescan(struct work_struct *work) mmc_claim_host(host); for (i = 0; i < ARRAY_SIZE(freqs); i++) { - if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min))) { - extend_wakelock = true; + if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min))) break; - } if (freqs[i] <= host->f_min) break; } mmc_release_host(host); out: - if (extend_wakelock) - wake_lock_timeout(&host->detect_wake_lock, HZ / 2); - else - wake_unlock(&host->detect_wake_lock); - if (host->caps & MMC_CAP_NEEDS_POLL) { - wake_lock(&host->detect_wake_lock); + if (host->caps & MMC_CAP_NEEDS_POLL) mmc_schedule_delayed_work(&host->detect, HZ); - } } void mmc_start_host(struct mmc_host *host) @@ -1706,8 +1635,7 @@ void mmc_stop_host(struct mmc_host *host) if (host->caps & MMC_CAP_DISABLE) cancel_delayed_work(&host->disable); - if (cancel_delayed_work_sync(&host->detect)) - wake_unlock(&host->detect_wake_lock); + cancel_delayed_work_sync(&host->detect); mmc_flush_scheduled_work(); /* clear pm flags now and let card drivers set them as needed */ @@ -1720,7 +1648,6 @@ void mmc_stop_host(struct mmc_host *host) mmc_claim_host(host); mmc_detach_bus(host); - mmc_power_off(host); mmc_release_host(host); mmc_bus_put(host); return; @@ -1824,13 +1751,9 @@ int mmc_suspend_host(struct mmc_host *host) { int err = 0; - if (mmc_bus_needs_resume(host)) - return 0; - if (host->caps & MMC_CAP_DISABLE) cancel_delayed_work(&host->disable); - if (cancel_delayed_work(&host->detect)) - wake_unlock(&host->detect_wake_lock); + cancel_delayed_work(&host->detect); mmc_flush_scheduled_work(); mmc_bus_get(host); @@ -1846,12 +1769,10 @@ int mmc_suspend_host(struct mmc_host *host) host->bus_ops->remove(host); mmc_claim_host(host); mmc_detach_bus(host); - mmc_power_off(host); mmc_release_host(host); host->pm_flags = 0; err = 0; } - flush_delayed_work(&host->disable); } mmc_bus_put(host); @@ -1872,12 +1793,6 @@ int mmc_resume_host(struct mmc_host *host) int err = 0; mmc_bus_get(host); - if (mmc_bus_manual_resume(host)) { - host->bus_resume_flags |= MMC_BUSRESUME_NEEDS_RESUME; - mmc_bus_put(host); - return 0; - } - if (host->bus_ops && !host->bus_dead) { if (!mmc_card_keep_power(host)) { mmc_power_up(host); @@ -1928,14 +1843,9 @@ int mmc_pm_notify(struct notifier_block *notify_block, case PM_SUSPEND_PREPARE: spin_lock_irqsave(&host->lock, flags); - if (mmc_bus_needs_resume(host)) { - spin_unlock_irqrestore(&host->lock, flags); - break; - } host->rescan_disable = 1; spin_unlock_irqrestore(&host->lock, flags); - if (cancel_delayed_work_sync(&host->detect)) - wake_unlock(&host->detect_wake_lock); + cancel_delayed_work_sync(&host->detect); if (!host->bus_ops || host->bus_ops->suspend) break; @@ -1946,7 +1856,6 @@ int mmc_pm_notify(struct notifier_block *notify_block, host->bus_ops->remove(host); mmc_detach_bus(host); - mmc_power_off(host); mmc_release_host(host); host->pm_flags = 0; break; @@ -1956,10 +1865,6 @@ int mmc_pm_notify(struct notifier_block *notify_block, case PM_POST_RESTORE: spin_lock_irqsave(&host->lock, flags); - if (mmc_bus_manual_resume(host)) { - spin_unlock_irqrestore(&host->lock, flags); - break; - } host->rescan_disable = 0; spin_unlock_irqrestore(&host->lock, flags); mmc_detect_change(host, 0); @@ -1970,22 +1875,6 @@ int mmc_pm_notify(struct notifier_block *notify_block, } #endif -#ifdef CONFIG_MMC_EMBEDDED_SDIO -void mmc_set_embedded_sdio_data(struct mmc_host *host, - struct sdio_cis *cis, - struct sdio_cccr *cccr, - struct sdio_embedded_func *funcs, - int num_funcs) -{ - host->embedded_sdio_data.cis = cis; - host->embedded_sdio_data.cccr = cccr; - host->embedded_sdio_data.funcs = funcs; - host->embedded_sdio_data.num_funcs = num_funcs; -} - -EXPORT_SYMBOL(mmc_set_embedded_sdio_data); -#endif - static int __init mmc_init(void) { int ret; diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 14664f1fb16f..d9411ed2a39b 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -43,7 +43,6 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11); void mmc_set_timing(struct mmc_host *host, unsigned int timing); void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type); -void mmc_power_off(struct mmc_host *host); static inline void mmc_delay(unsigned int ms) { diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index e09f0a7eb652..b29d3e8fd3a2 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -119,14 +119,14 @@ static void mmc_host_clk_gate_work(struct work_struct *work) } /** - * mmc_host_clk_hold - ungate hardware MCI clocks + * mmc_host_clk_ungate - ungate hardware MCI clocks * @host: host to ungate. * * Makes sure the host ios.clock is restored to a non-zero value * past this call. Increase clock reference count and ungate clock * if we're the first user. */ -void mmc_host_clk_hold(struct mmc_host *host) +void mmc_host_clk_ungate(struct mmc_host *host) { unsigned long flags; @@ -164,14 +164,14 @@ static bool mmc_host_may_gate_card(struct mmc_card *card) } /** - * mmc_host_clk_release - gate off hardware MCI clocks + * mmc_host_clk_gate - gate off hardware MCI clocks * @host: host to gate. * * Calls the host driver with ios.clock set to zero as often as possible * in order to gate off hardware MCI clocks. Decrease clock reference * count and schedule disabling of clock. */ -void mmc_host_clk_release(struct mmc_host *host) +void mmc_host_clk_gate(struct mmc_host *host) { unsigned long flags; @@ -179,7 +179,7 @@ void mmc_host_clk_release(struct mmc_host *host) host->clk_requests--; if (mmc_host_may_gate_card(host->card) && !host->clk_requests) - queue_work(system_nrt_wq, &host->clk_gate_work); + schedule_work(&host->clk_gate_work); spin_unlock_irqrestore(&host->clk_lock, flags); } @@ -231,7 +231,7 @@ static inline void mmc_host_clk_exit(struct mmc_host *host) if (cancel_work_sync(&host->clk_gate_work)) mmc_host_clk_gate_delayed(host); if (host->clk_gated) - mmc_host_clk_hold(host); + mmc_host_clk_ungate(host); /* There should be only one user now */ WARN_ON(host->clk_requests > 1); } @@ -284,8 +284,6 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) spin_lock_init(&host->lock); init_waitqueue_head(&host->wq); - wake_lock_init(&host->detect_wake_lock, WAKE_LOCK_SUSPEND, - kasprintf(GFP_KERNEL, "%s_detect", mmc_hostname(host))); INIT_DELAYED_WORK(&host->detect, mmc_rescan); INIT_DELAYED_WORK_DEFERRABLE(&host->disable, mmc_host_deeper_disable); #ifdef CONFIG_PM @@ -338,8 +336,7 @@ int mmc_add_host(struct mmc_host *host) #endif mmc_start_host(host); - if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY)) - register_pm_notifier(&host->pm_notify); + register_pm_notifier(&host->pm_notify); return 0; } @@ -356,9 +353,7 @@ EXPORT_SYMBOL(mmc_add_host); */ void mmc_remove_host(struct mmc_host *host) { - if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY)) - unregister_pm_notifier(&host->pm_notify); - + unregister_pm_notifier(&host->pm_notify); mmc_stop_host(host); #ifdef CONFIG_DEBUG_FS @@ -385,7 +380,6 @@ void mmc_free_host(struct mmc_host *host) spin_lock(&mmc_host_lock); idr_remove(&mmc_host_idr, host->index); spin_unlock(&mmc_host_lock); - wake_lock_destroy(&host->detect_wake_lock); put_device(&host->class_dev); } diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h index fb8a5cd2e4a1..de199f911928 100644 --- a/drivers/mmc/core/host.h +++ b/drivers/mmc/core/host.h @@ -16,16 +16,16 @@ int mmc_register_host_class(void); void mmc_unregister_host_class(void); #ifdef CONFIG_MMC_CLKGATE -void mmc_host_clk_hold(struct mmc_host *host); -void mmc_host_clk_release(struct mmc_host *host); +void mmc_host_clk_ungate(struct mmc_host *host); +void mmc_host_clk_gate(struct mmc_host *host); unsigned int mmc_host_clk_rate(struct mmc_host *host); #else -static inline void mmc_host_clk_hold(struct mmc_host *host) +static inline void mmc_host_clk_ungate(struct mmc_host *host) { } -static inline void mmc_host_clk_release(struct mmc_host *host) +static inline void mmc_host_clk_gate(struct mmc_host *host) { } diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index f6011802745c..aa7d1d79b8c5 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -359,7 +359,6 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) * card has the Enhanced area enabled. If so, export enhanced * area offset and size to user by adding sysfs interface. */ - card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT]; if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) && (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) { u8 hc_erase_grp_sz = @@ -406,7 +405,6 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) if (card->ext_csd.rev >= 5) card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM]; - card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT]; if (ext_csd[EXT_CSD_ERASED_MEM_CONT]) card->erased_byte = 0xFF; else @@ -830,7 +828,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, * * WARNING: eMMC rules are NOT the same as SD DDR */ - if (ddr == MMC_1_2V_DDR_MODE) { + if (ddr == EXT_CSD_CARD_TYPE_DDR_1_2V) { err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120, 0); if (err) @@ -893,7 +891,6 @@ static void mmc_detect(struct mmc_host *host) mmc_claim_host(host); mmc_detach_bus(host); - mmc_power_off(host); mmc_release_host(host); } } diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index e6629b986f05..ff2774128aa9 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -306,9 +306,6 @@ static int mmc_read_switch(struct mmc_card *card) goto out; } - if (status[13] & UHS_SDR50_BUS_SPEED) - card->sw_caps.hs_max_dtr = 50000000; - if (card->scr.sda_spec3) { card->sw_caps.sd3_bus_mode = status[13]; @@ -351,6 +348,9 @@ static int mmc_read_switch(struct mmc_card *card) } card->sw_caps.sd3_curr_limit = status[7]; + } else { + if (status[13] & 0x02) + card->sw_caps.hs_max_dtr = 50000000; } out: @@ -764,9 +764,6 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, bool reinit) { int err; -#ifdef CONFIG_MMC_PARANOID_SD_INIT - int retries; -#endif if (!reinit) { /* @@ -793,26 +790,7 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, /* * Fetch switch information from card. */ -#ifdef CONFIG_MMC_PARANOID_SD_INIT - for (retries = 1; retries <= 3; retries++) { - err = mmc_read_switch(card); - if (!err) { - if (retries > 1) { - printk(KERN_WARNING - "%s: recovered\n", - mmc_hostname(host)); - } - break; - } else { - printk(KERN_WARNING - "%s: read switch failed (attempt %d)\n", - mmc_hostname(host), retries); - } - } -#else err = mmc_read_switch(card); -#endif - if (err) return err; } @@ -1011,36 +989,18 @@ static void mmc_sd_remove(struct mmc_host *host) */ static void mmc_sd_detect(struct mmc_host *host) { - int err = 0; -#ifdef CONFIG_MMC_PARANOID_SD_INIT - int retries = 5; -#endif + int err; BUG_ON(!host); BUG_ON(!host->card); - + mmc_claim_host(host); /* * Just check if our card has been removed. */ -#ifdef CONFIG_MMC_PARANOID_SD_INIT - while(retries) { - err = mmc_send_status(host->card, NULL); - if (err) { - retries--; - udelay(5); - continue; - } - break; - } - if (!retries) { - printk(KERN_ERR "%s(%s): Unable to re-detect card (%d)\n", - __func__, mmc_hostname(host), err); - } -#else err = mmc_send_status(host->card, NULL); -#endif + mmc_release_host(host); if (err) { @@ -1048,7 +1008,6 @@ static void mmc_sd_detect(struct mmc_host *host) mmc_claim_host(host); mmc_detach_bus(host); - mmc_power_off(host); mmc_release_host(host); } } @@ -1079,31 +1038,12 @@ static int mmc_sd_suspend(struct mmc_host *host) static int mmc_sd_resume(struct mmc_host *host) { int err; -#ifdef CONFIG_MMC_PARANOID_SD_INIT - int retries; -#endif BUG_ON(!host); BUG_ON(!host->card); mmc_claim_host(host); -#ifdef CONFIG_MMC_PARANOID_SD_INIT - retries = 5; - while (retries) { - err = mmc_sd_init_card(host, host->ocr, host->card); - - if (err) { - printk(KERN_ERR "%s: Re-init card rc = %d (retries = %d)\n", - mmc_hostname(host), err, retries); - mdelay(5); - retries--; - continue; - } - break; - } -#else err = mmc_sd_init_card(host, host->ocr, host->card); -#endif mmc_release_host(host); return err; @@ -1155,9 +1095,6 @@ int mmc_attach_sd(struct mmc_host *host) { int err; u32 ocr; -#ifdef CONFIG_MMC_PARANOID_SD_INIT - int retries; -#endif BUG_ON(!host); WARN_ON(!host->claimed); @@ -1222,27 +1159,9 @@ int mmc_attach_sd(struct mmc_host *host) /* * Detect and init the card. */ -#ifdef CONFIG_MMC_PARANOID_SD_INIT - retries = 5; - while (retries) { - err = mmc_sd_init_card(host, host->ocr, NULL); - if (err) { - retries--; - continue; - } - break; - } - - if (!retries) { - printk(KERN_ERR "%s: mmc_sd_init_card() failure (err = %d)\n", - mmc_hostname(host), err); - goto err; - } -#else err = mmc_sd_init_card(host, host->ocr, NULL); if (err) goto err; -#endif mmc_release_host(host); err = mmc_add_card(host->card); diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 5d1719932664..262fff019177 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -27,10 +27,6 @@ #include "sdio_ops.h" #include "sdio_cis.h" -#ifdef CONFIG_MMC_EMBEDDED_SDIO -#include -#endif - static int sdio_read_fbr(struct sdio_func *func) { int ret; @@ -453,35 +449,19 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, goto finish; } -#ifdef CONFIG_MMC_EMBEDDED_SDIO - if (host->embedded_sdio_data.cccr) - memcpy(&card->cccr, host->embedded_sdio_data.cccr, sizeof(struct sdio_cccr)); - else { -#endif - /* - * Read the common registers. - */ - err = sdio_read_cccr(card); - if (err) - goto remove; -#ifdef CONFIG_MMC_EMBEDDED_SDIO - } -#endif + /* + * Read the common registers. + */ + err = sdio_read_cccr(card); + if (err) + goto remove; -#ifdef CONFIG_MMC_EMBEDDED_SDIO - if (host->embedded_sdio_data.cis) - memcpy(&card->cis, host->embedded_sdio_data.cis, sizeof(struct sdio_cis)); - else { -#endif - /* - * Read the common CIS tuples. - */ - err = sdio_read_common_cis(card); - if (err) - goto remove; -#ifdef CONFIG_MMC_EMBEDDED_SDIO - } -#endif + /* + * Read the common CIS tuples. + */ + err = sdio_read_common_cis(card); + if (err) + goto remove; if (oldcard) { int same = (card->cis.vendor == oldcard->cis.vendor && @@ -617,7 +597,6 @@ out: mmc_claim_host(host); mmc_detach_bus(host); - mmc_power_off(host); mmc_release_host(host); } } @@ -685,7 +664,7 @@ static int mmc_sdio_resume(struct mmc_host *host) } if (!err && host->sdio_irqs) - wake_up_process(host->sdio_irq_thread); + mmc_signal_sdio_irq(host); mmc_release_host(host); /* @@ -847,36 +826,14 @@ int mmc_attach_sdio(struct mmc_host *host) funcs = (ocr & 0x70000000) >> 28; card->sdio_funcs = 0; -#ifdef CONFIG_MMC_EMBEDDED_SDIO - if (host->embedded_sdio_data.funcs) - card->sdio_funcs = funcs = host->embedded_sdio_data.num_funcs; -#endif - /* * Initialize (but don't add) all present functions. */ for (i = 0; i < funcs; i++, card->sdio_funcs++) { -#ifdef CONFIG_MMC_EMBEDDED_SDIO - if (host->embedded_sdio_data.funcs) { - struct sdio_func *tmp; - - tmp = sdio_alloc_func(host->card); - if (IS_ERR(tmp)) - goto remove; - tmp->num = (i + 1); - card->sdio_func[i] = tmp; - tmp->class = host->embedded_sdio_data.funcs[i].f_class; - tmp->max_blksize = host->embedded_sdio_data.funcs[i].f_maxblksize; - tmp->vendor = card->cis.vendor; - tmp->device = card->cis.device; - } else { -#endif - err = sdio_init_func(host->card, i + 1); - if (err) - goto remove; -#ifdef CONFIG_MMC_EMBEDDED_SDIO - } -#endif + err = sdio_init_func(host->card, i + 1); + if (err) + goto remove; + /* * Enable Runtime PM for this func (if supported) */ @@ -924,77 +881,3 @@ err: return err; } -int sdio_reset_comm(struct mmc_card *card) -{ - struct mmc_host *host = card->host; - u32 ocr; - int err; - - printk("%s():\n", __func__); - mmc_claim_host(host); - - mmc_go_idle(host); - - mmc_set_clock(host, host->f_min); - - err = mmc_send_io_op_cond(host, 0, &ocr); - if (err) - goto err; - - host->ocr = mmc_select_voltage(host, ocr); - if (!host->ocr) { - err = -EINVAL; - goto err; - } - - err = mmc_send_io_op_cond(host, host->ocr, &ocr); - if (err) - goto err; - - if (mmc_host_is_spi(host)) { - err = mmc_spi_set_crc(host, use_spi_crc); - if (err) - goto err; - } - - if (!mmc_host_is_spi(host)) { - err = mmc_send_relative_addr(host, &card->rca); - if (err) - goto err; - mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); - } - if (!mmc_host_is_spi(host)) { - err = mmc_select_card(card); - if (err) - goto err; - } - - /* - * Switch to high-speed (if supported). - */ - err = sdio_enable_hs(card); - if (err > 0) - mmc_sd_go_highspeed(card); - else if (err) - goto err; - - /* - * Change to the card's maximum speed. - */ - mmc_set_clock(host, mmc_sdio_get_max_clock(card)); - - err = sdio_enable_4bit_bus(card); - if (err > 0) - mmc_set_bus_width(host, MMC_BUS_WIDTH_4); - else if (err) - goto err; - - mmc_release_host(host); - return 0; -err: - printk("%s: Error resetting SDIO communications (%d)\n", - mmc_hostname(host), err); - mmc_release_host(host); - return err; -} -EXPORT_SYMBOL(sdio_reset_comm); diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 52429a98201b..d2565df8a7fb 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -23,10 +23,6 @@ #include "sdio_cis.h" #include "sdio_bus.h" -#ifdef CONFIG_MMC_EMBEDDED_SDIO -#include -#endif - /* show configuration fields */ #define sdio_config_attr(field, format_string) \ static ssize_t \ @@ -264,14 +260,7 @@ static void sdio_release_func(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); -#ifdef CONFIG_MMC_EMBEDDED_SDIO - /* - * If this device is embedded then we never allocated - * cis tables for this func - */ - if (!func->card->host->embedded_sdio_data.funcs) -#endif - sdio_free_func_cis(func); + sdio_free_func_cis(func); if (func->info) kfree(func->info); diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c old mode 100755 new mode 100644 index 549a34144646..0f687cdeb064 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c @@ -382,39 +382,6 @@ u8 sdio_readb(struct sdio_func *func, unsigned int addr, int *err_ret) } EXPORT_SYMBOL_GPL(sdio_readb); -/** - * sdio_readb_ext - read a single byte from a SDIO function - * @func: SDIO function to access - * @addr: address to read - * @err_ret: optional status value from transfer - * @in: value to add to argument - * - * Reads a single byte from the address space of a given SDIO - * function. If there is a problem reading the address, 0xff - * is returned and @err_ret will contain the error code. - */ -unsigned char sdio_readb_ext(struct sdio_func *func, unsigned int addr, - int *err_ret, unsigned in) -{ - int ret; - unsigned char val; - - BUG_ON(!func); - - if (err_ret) - *err_ret = 0; - - ret = mmc_io_rw_direct(func->card, 0, func->num, addr, (u8)in, &val); - if (ret) { - if (err_ret) - *err_ret = ret; - return 0xFF; - } - - return val; -} -EXPORT_SYMBOL_GPL(sdio_readb_ext); - /** * sdio_writeb - write a single byte to a SDIO function * @func: SDIO function to access diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c index d58ae9153379..03ead028d2ce 100644 --- a/drivers/mmc/core/sdio_irq.c +++ b/drivers/mmc/core/sdio_irq.c @@ -27,20 +27,18 @@ #include "sdio_ops.h" -static int process_sdio_pending_irqs(struct mmc_host *host) +static int process_sdio_pending_irqs(struct mmc_card *card) { - struct mmc_card *card = host->card; int i, ret, count; unsigned char pending; struct sdio_func *func; /* * Optimization, if there is only 1 function interrupt registered - * and we know an IRQ was signaled then call irq handler directly. - * Otherwise do the full probe. + * call irq handler directly */ func = card->sdio_single_irq; - if (func && host->sdio_irq_pending) { + if (func) { func->irq_handler(func); return 1; } @@ -117,8 +115,7 @@ static int sdio_irq_thread(void *_host) ret = __mmc_claim_host(host, &host->sdio_irq_thread_abort); if (ret) break; - ret = process_sdio_pending_irqs(host); - host->sdio_irq_pending = false; + ret = process_sdio_pending_irqs(host->card); mmc_release_host(host); /* diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index b6cd3867f723..aa8039f473c4 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -468,14 +468,7 @@ err: static inline unsigned int ns_to_clocks(struct atmel_mci *host, unsigned int ns) { - /* - * It is easier here to use us instead of ns for the timeout, - * it prevents from overflows during calculation. - */ - unsigned int us = DIV_ROUND_UP(ns, 1000); - - /* Maximum clock frequency is host->bus_hz/2 */ - return us * (DIV_ROUND_UP(host->bus_hz, 2000000)); + return (ns * (host->bus_hz / 1000000) + 999) / 1000; } static void atmci_set_timeout(struct atmel_mci *host, diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 9394d0b77ec5..fe140724a02e 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -557,8 +557,7 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, unsigned int status) { /* First check for errors */ - if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR| - MCI_TXUNDERRUN|MCI_RXOVERRUN)) { + if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { u32 remain, success; /* Terminate the DMA transfer */ @@ -637,12 +636,8 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, } if (!cmd->data || cmd->error) { - if (host->data) { - /* Terminate the DMA transfer */ - if (dma_inprogress(host)) - mmci_dma_data_error(host); + if (host->data) mmci_stop_data(host); - } mmci_request_end(host, cmd->mrq); } else if (!(cmd->data->flags & MMC_DATA_READ)) { mmci_start_data(host, cmd->data); @@ -842,9 +837,8 @@ static irqreturn_t mmci_irq(int irq, void *dev_id) dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); data = host->data; - if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR| - MCI_TXUNDERRUN|MCI_RXOVERRUN|MCI_DATAEND| - MCI_DATABLOCKEND) && data) + if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN| + MCI_RXOVERRUN|MCI_DATAEND|MCI_DATABLOCKEND) && data) mmci_data_irq(host, data, status); cmd = host->cmd; diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index e12fbc510bbd..cc20e0259325 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -731,7 +731,6 @@ static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) "failed to config DMA channel. Falling back to PIO\n"); dma_release_channel(host->dma); host->do_dma = 0; - host->dma = NULL; } } diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index 74160eb3bf03..99d39a6a1032 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c @@ -278,11 +278,11 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id) writel(stat & MXS_MMC_IRQ_BITS, host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR); - spin_unlock(&host->lock); - if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN)) mmc_signal_sdio_irq(host->mmc); + spin_unlock(&host->lock); + if (stat & BM_SSP_CTRL1_RESP_TIMEOUT_IRQ) cmd->error = -ETIMEDOUT; else if (stat & BM_SSP_CTRL1_RESP_ERR_IRQ) @@ -564,38 +564,40 @@ static void mxs_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate) { - unsigned int ssp_clk, ssp_sck; - u32 clock_divide, clock_rate; + unsigned int ssp_rate, bit_rate; + u32 div1, div2; u32 val; - ssp_clk = clk_get_rate(host->clk); + ssp_rate = clk_get_rate(host->clk); - for (clock_divide = 2; clock_divide <= 254; clock_divide += 2) { - clock_rate = DIV_ROUND_UP(ssp_clk, rate * clock_divide); - clock_rate = (clock_rate > 0) ? clock_rate - 1 : 0; - if (clock_rate <= 255) + for (div1 = 2; div1 < 254; div1 += 2) { + div2 = ssp_rate / rate / div1; + if (div2 < 0x100) break; } - if (clock_divide > 254) { + if (div1 >= 254) { dev_err(mmc_dev(host->mmc), "%s: cannot set clock to %d\n", __func__, rate); return; } - ssp_sck = ssp_clk / clock_divide / (1 + clock_rate); + if (div2 == 0) + bit_rate = ssp_rate / div1; + else + bit_rate = ssp_rate / div1 / div2; val = readl(host->base + HW_SSP_TIMING); val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE); - val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE); - val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE); + val |= BF_SSP(div1, TIMING_CLOCK_DIVIDE); + val |= BF_SSP(div2 - 1, TIMING_CLOCK_RATE); writel(val, host->base + HW_SSP_TIMING); - host->clk_rate = ssp_sck; + host->clk_rate = bit_rate; dev_dbg(mmc_dev(host->mmc), - "%s: clock_divide %d, clock_rate %d, ssp_clk %d, rate_actual %d, rate_requested %d\n", - __func__, clock_divide, clock_rate, ssp_clk, ssp_sck, rate); + "%s: div1 %d, div2 %d, ssp %d, bit %d, rate %d\n", + __func__, div1, div2, ssp_rate, bit_rate, rate); } static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 6fe8cede4179..a19967d0bfc4 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -74,7 +74,7 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg) if (boarddata && gpio_is_valid(boarddata->cd_gpio) && gpio_get_value(boarddata->cd_gpio)) /* no card, if a valid gpio says so... */ - val &= ~SDHCI_CARD_PRESENT; + val &= SDHCI_CARD_PRESENT; else /* ... in all other cases assume card is present */ val |= SDHCI_CARD_PRESENT; @@ -139,9 +139,8 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) imx_data->scratchpad = val; return; case SDHCI_COMMAND: - if ((host->cmd->opcode == MMC_STOP_TRANSMISSION || - host->cmd->opcode == MMC_SET_BLOCK_COUNT) && - (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)) + if ((host->cmd->opcode == MMC_STOP_TRANSMISSION) + && (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)) val |= SDHCI_CMD_ABORTCMD; writel(val << 16 | imx_data->scratchpad, host->ioaddr + SDHCI_TRANSFER_MODE); @@ -245,7 +244,8 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd } pltfm_host->priv = imx_data; - host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; + if (!cpu_is_mx25()) + host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; if (cpu_is_mx25() || cpu_is_mx35()) { /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */ diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h index 62ca03af8aca..c3b08f111942 100644 --- a/drivers/mmc/host/sdhci-esdhc.h +++ b/drivers/mmc/host/sdhci-esdhc.h @@ -48,14 +48,14 @@ static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) int div = 1; u32 temp; - if (clock == 0) - goto out; - temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK); sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); + if (clock == 0) + goto out; + while (host->max_clk / pre_div / 16 > clock && pre_div < 256) pre_div *= 2; diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index d3b3115def49..936bbca19c0a 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -140,7 +140,6 @@ static const struct sdhci_pci_fixes sdhci_ene_714 = { static const struct sdhci_pci_fixes sdhci_cafe = { .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER | SDHCI_QUIRK_NO_BUSY_IRQ | - SDHCI_QUIRK_BROKEN_CARD_DETECTION | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, }; diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 4a5c50127131..69e3ee321eb5 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c @@ -301,8 +301,6 @@ static int sdhci_s3c_platform_8bit_width(struct sdhci_host *host, int width) ctrl &= ~SDHCI_CTRL_8BITBUS; break; default: - ctrl &= ~SDHCI_CTRL_4BITBUS; - ctrl &= ~SDHCI_CTRL_8BITBUS; break; } @@ -589,7 +587,7 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) sdhci_remove_host(host, 1); - for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { + for (ptr = 0; ptr < 3; ptr++) { if (sc->clk_bus[ptr]) { clk_disable(sc->clk_bus[ptr]); clk_put(sc->clk_bus[ptr]); diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 6103edad46f0..58d5436ff649 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1044,7 +1044,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) u16 clk = 0; unsigned long timeout; - if (clock && clock == host->clock) + if (clock == host->clock) return; if (host->ops->set_clock) { @@ -1340,7 +1340,8 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if ((ios->timing == MMC_TIMING_UHS_SDR50) || (ios->timing == MMC_TIMING_UHS_SDR104) || (ios->timing == MMC_TIMING_UHS_DDR50) || - (ios->timing == MMC_TIMING_UHS_SDR25)) + (ios->timing == MMC_TIMING_UHS_SDR25) || + (ios->timing == MMC_TIMING_UHS_SDR12)) ctrl |= SDHCI_CTRL_HISPD; ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); @@ -1862,6 +1863,9 @@ static void sdhci_tasklet_finish(unsigned long param) del_timer(&host->timer); + if (host->version >= SDHCI_SPEC_300) + del_timer(&host->tuning_timer); + mrq = host->mrq; /* @@ -2226,8 +2230,9 @@ int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state) /* Disable tuning since we are suspending */ if (host->version >= SDHCI_SPEC_300 && host->tuning_count && host->tuning_mode == SDHCI_TUNING_MODE_1) { - del_timer_sync(&host->tuning_timer); host->flags &= ~SDHCI_NEEDS_RETUNING; + mod_timer(&host->tuning_timer, jiffies + + host->tuning_count * HZ); } ret = mmc_suspend_host(host->mmc); @@ -2515,9 +2520,8 @@ int sdhci_add_host(struct sdhci_host *host) mmc_card_is_removable(mmc)) mmc->caps |= MMC_CAP_NEEDS_POLL; - /* Any UHS-I mode in caps implies SDR12 and SDR25 support. */ - if (caps[1] & (SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | - SDHCI_SUPPORT_DDR50)) + /* UHS-I mode(s) supported by the host controller. */ + if (host->version >= SDHCI_SPEC_300) mmc->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25; /* SDR104 supports also implies SDR50 support */ diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c index 52f4b644766a..d4455ffbefd8 100644 --- a/drivers/mmc/host/vub300.c +++ b/drivers/mmc/host/vub300.c @@ -259,7 +259,7 @@ static int firmware_rom_wait_states = 0x04; static int firmware_rom_wait_states = 0x1C; #endif -module_param(firmware_rom_wait_states, int, 0644); +module_param(firmware_rom_wait_states, bool, 0644); MODULE_PARM_DESC(firmware_rom_wait_states, "ROM wait states byte=RRRIIEEE (Reserved Internal External)"); diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 8cd983cdc643..b78f23169d4e 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -284,7 +284,6 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; dev->mtd.erasesize = erase_size; dev->mtd.writesize = 1; - dev->mtd.writebufsize = PAGE_SIZE; dev->mtd.type = MTD_RAM; dev->mtd.flags = MTD_CAP_RAM; dev->mtd.erase = block2mtd_erase; diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c index 09d5b5aaea57..772a0ff89e0f 100644 --- a/drivers/mtd/devices/lart.c +++ b/drivers/mtd/devices/lart.c @@ -636,7 +636,6 @@ static int __init lart_flash_init (void) mtd.name = module_name; mtd.type = MTD_NORFLASH; mtd.writesize = 1; - mtd.writebufsize = 4; mtd.flags = MTD_CAP_NORFLASH; mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN; mtd.erasesize = FLASH_BLOCKSIZE_MAIN; diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 9fad104d4aab..35180e475c4c 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -930,7 +930,6 @@ static int __devinit m25p_probe(struct spi_device *spi) flash->mtd.dev.parent = &spi->dev; flash->page_size = info->page_size; - flash->mtd.writebufsize = flash->page_size; if (info->addr_width) flash->addr_width = info->addr_width; diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index f38c348e00b7..e585263161b9 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c @@ -266,7 +266,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength) if (*(szlength) != '+') { devlength = simple_strtoul(szlength, &buffer, 0); - devlength = handle_unit(devlength, buffer); + devlength = handle_unit(devlength, buffer) - devstart; if (devlength < devstart) goto err_out; diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c index 867710a09a48..1e2c430aaad2 100644 --- a/drivers/mtd/devices/sst25l.c +++ b/drivers/mtd/devices/sst25l.c @@ -406,7 +406,6 @@ static int __devinit sst25l_probe(struct spi_device *spi) flash->mtd.flags = MTD_CAP_NORFLASH; flash->mtd.erasesize = flash_info->erase_size; flash->mtd.writesize = flash_info->page_size; - flash->mtd.writebufsize = flash_info->page_size; flash->mtd.size = flash_info->page_size * flash_info->nr_pages; flash->mtd.erase = sst25l_erase; flash->mtd.read = sst25l_read; diff --git a/drivers/mtd/maps/autcpu12-nvram.c b/drivers/mtd/maps/autcpu12-nvram.c index 0598d52eaf9f..e5bfd0e093bb 100644 --- a/drivers/mtd/maps/autcpu12-nvram.c +++ b/drivers/mtd/maps/autcpu12-nvram.c @@ -43,8 +43,7 @@ struct map_info autcpu12_sram_map = { static int __init init_autcpu12_sram (void) { - map_word tmp, save0, save1; - int err; + int err, save0, save1; autcpu12_sram_map.virt = ioremap(0x12000000, SZ_128K); if (!autcpu12_sram_map.virt) { @@ -52,7 +51,7 @@ static int __init init_autcpu12_sram (void) err = -EIO; goto out; } - simple_map_init(&autcpu12_sram_map); + simple_map_init(&autcpu_sram_map); /* * Check for 32K/128K @@ -62,22 +61,20 @@ static int __init init_autcpu12_sram (void) * Read and check result on ofs 0x0 * Restore contents */ - save0 = map_read(&autcpu12_sram_map, 0); - save1 = map_read(&autcpu12_sram_map, 0x10000); - tmp.x[0] = ~save0.x[0]; - map_write(&autcpu12_sram_map, tmp, 0x10000); + save0 = map_read32(&autcpu12_sram_map,0); + save1 = map_read32(&autcpu12_sram_map,0x10000); + map_write32(&autcpu12_sram_map,~save0,0x10000); /* if we find this pattern on 0x0, we have 32K size * restore contents and exit */ - tmp = map_read(&autcpu12_sram_map, 0); - if (!map_word_equal(&autcpu12_sram_map, tmp, save0)) { - map_write(&autcpu12_sram_map, save0, 0x0); + if ( map_read32(&autcpu12_sram_map,0) != save0) { + map_write32(&autcpu12_sram_map,save0,0x0); goto map; } /* We have a 128K found, restore 0x10000 and set size * to 128K */ - map_write(&autcpu12_sram_map, save1, 0x10000); + map_write32(&autcpu12_sram_map,save1,0x10000); autcpu12_sram_map.size = SZ_128K; map: diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index bff8d4671ad6..ca385697446e 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -215,7 +215,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode) mutex_lock(&dev->lock); - if (dev->open) + if (dev->open++) goto unlock; kref_get(&dev->ref); @@ -235,7 +235,6 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode) goto error_release; unlock: - dev->open++; mutex_unlock(&dev->lock); blktrans_dev_put(dev); return ret; diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 9f8658ef9467..3f92731a5b9e 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -320,7 +320,6 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count ops.mode = MTD_OOB_RAW; ops.datbuf = kbuf; ops.oobbuf = NULL; - ops.ooboffs = 0; ops.len = len; ret = mtd->write_oob(mtd, *ppos, &ops); diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index 43130e8aceac..e3e40f440323 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -253,9 +253,6 @@ static void find_next_position(struct mtdoops_context *cxt) size_t retlen; for (page = 0; page < cxt->oops_pages; page++) { - if (mtd->block_isbad && - mtd->block_isbad(mtd, page * record_size)) - continue; /* Assume the page is used */ mark_page_used(cxt, page); ret = mtd->read(mtd, page * record_size, MTDOOPS_HEADER_SIZE, @@ -372,7 +369,7 @@ static void mtdoops_notify_add(struct mtd_info *mtd) /* oops_page_used is a bit field */ cxt->oops_page_used = vmalloc(DIV_ROUND_UP(mtdoops_pages, - BITS_PER_LONG) * sizeof(unsigned long)); + BITS_PER_LONG)); if (!cxt->oops_page_used) { printk(KERN_ERR "mtdoops: could not allocate page array\n"); return; diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 43173a335e49..4c3425235adc 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -1,10 +1,3 @@ -config MTD_NAND_IDS - tristate "Include chip ids for known NAND devices." - depends on MTD - help - Useful for NAND drivers that do not use the NAND subsystem but - still like to take advantage of the known chip information. - config MTD_NAND_ECC tristate @@ -128,23 +121,6 @@ config MTD_NAND_OMAP2 help Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms. -config MTD_NAND_OMAP_PREFETCH - bool "GPMC prefetch support for NAND Flash device" - depends on MTD_NAND_OMAP2 - default y - help - The NAND device can be accessed for Read/Write using GPMC PREFETCH engine - to improve the performance. - -config MTD_NAND_OMAP_PREFETCH_DMA - depends on MTD_NAND_OMAP_PREFETCH - bool "DMA mode" - default n - help - The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode - or in DMA interrupt mode. - Say y for DMA mode or MPU mode will be used - config MTD_NAND_IDS tristate diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index f5cdc565b3ef..87ebb4e5b0c3 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c @@ -102,7 +102,7 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; static int cafe_device_ready(struct mtd_info *mtd) { struct cafe_priv *cafe = mtd->priv; - int result = !!(cafe_readl(cafe, NAND_STATUS) & 0x40000000); + int result = !!(cafe_readl(cafe, NAND_STATUS) | 0x40000000); uint32_t irqs = cafe_readl(cafe, NAND_IRQ); cafe_writel(cafe, irqs, NAND_IRQ); diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 15d71658b4f1..a46e9bb847bd 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2097,22 +2097,14 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, /** * nand_fill_oob - [Internal] Transfer client buffer to oob - * @mtd: MTD device structure + * @chip: nand chip structure * @oob: oob data buffer * @len: oob data write length * @ops: oob ops structure */ -static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len, - struct mtd_oob_ops *ops) +static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len, + struct mtd_oob_ops *ops) { - struct nand_chip *chip = mtd->priv; - - /* - * Initialise to all 0xFF, to avoid the possibility of left over OOB - * data from a previous OOB read. - */ - memset(chip->oob_poi, 0xff, mtd->oobsize); - switch (ops->mode) { case MTD_OOB_PLACE: @@ -2209,6 +2201,10 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, (chip->pagebuf << chip->page_shift) < (to + ops->len)) chip->pagebuf = -1; + /* If we're not given explicit OOB data, let it be 0xFF */ + if (likely(!oob)) + memset(chip->oob_poi, 0xff, mtd->oobsize); + /* Don't allow multipage oob writes with offset */ if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) return -EINVAL; @@ -2230,11 +2226,8 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, if (unlikely(oob)) { size_t len = min(oobwritelen, oobmaxlen); - oob = nand_fill_oob(mtd, oob, len, ops); + oob = nand_fill_oob(chip, oob, len, ops); oobwritelen -= len; - } else { - /* We still need to erase leftover OOB data */ - memset(chip->oob_poi, 0xff, mtd->oobsize); } ret = chip->write_page(mtd, chip, wbuf, page, cached, @@ -2408,8 +2401,10 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, if (page == chip->pagebuf) chip->pagebuf = -1; - nand_fill_oob(mtd, ops->oobbuf, ops->ooblen, ops); + memset(chip->oob_poi, 0xff, mtd->oobsize); + nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops); status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); + memset(chip->oob_poi, 0xff, mtd->oobsize); if (status) return status; @@ -3222,44 +3217,6 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, } EXPORT_SYMBOL(nand_scan_ident); -static void nand_panic_wait(struct mtd_info *mtd) -{ - struct nand_chip *chip = mtd->priv; - int i; - - if (chip->state != FL_READY) - for (i = 0; i < 40; i++) { - if (chip->dev_ready(mtd)) - break; - mdelay(10); - } - chip->state = FL_READY; -} - -static int nand_panic_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) -{ - struct nand_chip *chip = mtd->priv; - int ret; - - /* Do not allow reads past end of device */ - if ((to + len) > mtd->size) - return -EINVAL; - if (!len) - return 0; - - nand_panic_wait(mtd); - - chip->ops.len = len; - chip->ops.datbuf = (uint8_t *)buf; - chip->ops.oobbuf = NULL; - - ret = nand_do_write_ops(mtd, to, &chip->ops); - - *retlen = chip->ops.retlen; - return ret; -} - /** * nand_scan_tail - [NAND Interface] Scan for the NAND device @@ -3503,7 +3460,6 @@ int nand_scan_tail(struct mtd_info *mtd) mtd->panic_write = panic_nand_write; mtd->read_oob = nand_read_oob; mtd->write_oob = nand_write_oob; - mtd->panic_write = nand_panic_write; mtd->sync = nand_sync; mtd->lock = NULL; mtd->unlock = NULL; diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index c27ca6affa97..ccbeaa1e4a8e 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -360,7 +360,6 @@ static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs, buf += mtd->oobsize + mtd->writesize; len -= mtd->writesize; - offs += mtd->writesize; } return 0; } @@ -429,7 +428,7 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, /* Read the mirror version, if available */ if (md && (md->options & NAND_BBT_VERSION)) { scan_read_raw(mtd, buf, (loff_t)md->pages[0] << this->page_shift, - mtd->writesize, md); + mtd->writesize, td); md->version[0] = buf[bbt_get_ver_offs(mtd, md)]; printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]); diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 1f2b8803cca2..357e8c5252a8 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -547,6 +547,12 @@ static char *get_partition_name(int i) return kstrdup(buf, GFP_KERNEL); } +static uint64_t divide(uint64_t n, uint32_t d) +{ + do_div(n, d); + return n; +} + /* * Initialize the nandsim structure. * @@ -575,7 +581,7 @@ static int init_nandsim(struct mtd_info *mtd) ns->geom.oobsz = mtd->oobsize; ns->geom.secsz = mtd->erasesize; ns->geom.pgszoob = ns->geom.pgsz + ns->geom.oobsz; - ns->geom.pgnum = div_u64(ns->geom.totsz, ns->geom.pgsz); + ns->geom.pgnum = divide(ns->geom.totsz, ns->geom.pgsz); ns->geom.totszoob = ns->geom.totsz + (uint64_t)ns->geom.pgnum * ns->geom.oobsz; ns->geom.secshift = ffs(ns->geom.secsz) - 1; ns->geom.pgshift = chip->page_shift; @@ -918,7 +924,7 @@ static int setup_wear_reporting(struct mtd_info *mtd) if (!rptwear) return 0; - wear_eb_count = div_u64(mtd->size, mtd->erasesize); + wear_eb_count = divide(mtd->size, mtd->erasesize); mem = wear_eb_count * sizeof(unsigned long); if (mem / sizeof(unsigned long) != wear_eb_count) { NS_ERR("Too many erase blocks for wear reporting\n"); @@ -2355,7 +2361,6 @@ static int __init ns_init_module(void) uint64_t new_size = (uint64_t)nsmtd->erasesize << overridesize; if (new_size >> overridesize != nsmtd->erasesize) { NS_ERR("overridesize is too big\n"); - retval = -EINVAL; goto err_exit; } /* N.B. This relies on nand_scan not doing anything with the size before we change it */ diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 02897077f16a..0db2c0e7656a 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -1139,8 +1139,7 @@ static int omap_nand_remove(struct platform_device *pdev) /* Release NAND device, its internal structures and partitions */ nand_release(&info->mtd); iounmap(info->nand.IO_ADDR_R); - release_mem_region(info->phys_base, NAND_IO_SIZE); - kfree(info); + kfree(&info->mtd); return 0; } diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 30689cc2b3c7..1fb3b3a80581 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -685,8 +685,6 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, * OOB, ignore such double bit errors */ if (is_buf_blank(buf, mtd->writesize)) - info->retcode = ERR_NONE; - else mtd->ecc_stats.failed++; } @@ -815,7 +813,7 @@ static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) info->page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512; /* set info fields needed to read id */ info->read_id_bytes = (info->page_size == 2048) ? 4 : 2; - info->reg_ndcr = ndcr & ~NDCR_INT_MASK; + info->reg_ndcr = ndcr; info->cmdset = &default_cmdset; info->ndtr0cs0 = nand_readl(info, NDTR0CS0); @@ -884,7 +882,7 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) struct pxa3xx_nand_info *info = mtd->priv; struct platform_device *pdev = info->pdev; struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data; - struct nand_flash_dev pxa3xx_flash_ids[2], *def = NULL; + struct nand_flash_dev pxa3xx_flash_ids[2] = { {NULL,}, {NULL,} }; const struct pxa3xx_nand_flash *f = NULL; struct nand_chip *chip = mtd->priv; uint32_t id = -1; @@ -944,10 +942,8 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) pxa3xx_flash_ids[0].erasesize = f->page_size * f->page_per_block; if (f->flash_width == 16) pxa3xx_flash_ids[0].options = NAND_BUSWIDTH_16; - pxa3xx_flash_ids[1].name = NULL; - def = pxa3xx_flash_ids; KEEP_CONFIG: - if (nand_scan_ident(mtd, 1, def)) + if (nand_scan_ident(mtd, 1, pxa3xx_flash_ids)) return -ENODEV; /* calculate addressing information */ info->col_addr_cycles = (mtd->writesize >= 2048) ? 2 : 1; @@ -958,9 +954,9 @@ KEEP_CONFIG: info->row_addr_cycles = 2; mtd->name = mtd_names[0]; chip->ecc.mode = NAND_ECC_HW; - chip->ecc.size = info->page_size; + chip->ecc.size = f->page_size; - chip->options = (info->reg_ndcr & NDCR_DWIDTH_M) ? NAND_BUSWIDTH_16 : 0; + chip->options = (f->flash_width == 16) ? NAND_BUSWIDTH_16 : 0; chip->options |= NAND_NO_AUTOINCR; chip->options |= NAND_NO_READRDY; diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c index 4938bd0b024a..7a87d07cd79f 100644 --- a/drivers/mtd/redboot.c +++ b/drivers/mtd/redboot.c @@ -297,9 +297,6 @@ static struct mtd_part_parser redboot_parser = { .name = "RedBoot", }; -/* mtd parsers will request the module by parser name */ -MODULE_ALIAS("RedBoot"); - static int __init redboot_parser_init(void) { return register_mtd_parser(&redboot_parser); diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c index 0e34d564941a..ed3d6cd2c6dc 100644 --- a/drivers/mtd/sm_ftl.c +++ b/drivers/mtd/sm_ftl.c @@ -1256,7 +1256,7 @@ static void sm_remove_dev(struct mtd_blktrans_dev *dev) static struct mtd_blktrans_ops sm_ftl_ops = { .name = "smblk", - .major = 0, + .major = -1, .part_bits = SM_FTL_PARTN_BITS, .blksize = SM_SECTOR_SIZE, .getgeo = sm_getgeo, diff --git a/drivers/mtd/tests/mtd_stresstest.c b/drivers/mtd/tests/mtd_stresstest.c index 129bad2e4080..531625fc9259 100644 --- a/drivers/mtd/tests/mtd_stresstest.c +++ b/drivers/mtd/tests/mtd_stresstest.c @@ -277,12 +277,6 @@ static int __init mtd_stresstest_init(void) (unsigned long long)mtd->size, mtd->erasesize, pgsize, ebcnt, pgcnt, mtd->oobsize); - if (ebcnt < 2) { - printk(PRINT_PREF "error: need at least 2 eraseblocks\n"); - err = -ENOSPC; - goto out_put_mtd; - } - /* Read or write up 2 eraseblocks at a time */ bufsize = mtd->erasesize * 2; @@ -321,7 +315,6 @@ out: kfree(bbt); vfree(writebuf); vfree(readbuf); -out_put_mtd: put_mtd_device(mtd); if (err) printk(PRINT_PREF "error %d occurred\n", err); diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 2b351d0b1ffa..65626c1c446d 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -816,11 +816,6 @@ static int autoresize(struct ubi_device *ubi, int vol_id) struct ubi_volume *vol = ubi->volumes[vol_id]; int err, old_reserved_pebs = vol->reserved_pebs; - if (ubi->ro_mode) { - ubi_warn("skip auto-resize because of R/O mode"); - return 0; - } - /* * Clear the auto-resize flag in the volume in-memory copy of the * volume table, and 'ubi_resize_volume()' will propagate this change diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index cdea6692dea0..191f3bb3c41a 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -628,9 +628,6 @@ static int verify_mkvol_req(const struct ubi_device *ubi, if (req->alignment != 1 && n) goto bad; - if (!req->name[0] || !req->name_len) - goto bad; - if (req->name_len > UBI_VOL_NAME_MAX) { err = -ENAMETOOLONG; goto bad; diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 5f0e4c2d9cd3..3f1a09c5c438 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -51,10 +51,7 @@ struct ubi_mkvol_req; pr_debug("UBI DBG " type ": " fmt "\n", ##__VA_ARGS__) /* Just a debugging messages not related to any specific UBI subsystem */ -#define dbg_msg(fmt, ...) \ - printk(KERN_DEBUG "UBI DBG (pid %d): %s: " fmt "\n", \ - current->pid, __func__, ##__VA_ARGS__) - +#define dbg_msg(fmt, ...) ubi_dbg_msg("msg", fmt, ##__VA_ARGS__) /* General debugging messages */ #define dbg_gen(fmt, ...) ubi_dbg_msg("gen", fmt, ##__VA_ARGS__) /* Messages from the eraseblock association sub-system */ diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index c696c9481c95..4be671815014 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -1028,14 +1028,12 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, * 'ubi_wl_put_peb()' function on the @ubi->move_mutex. In turn, we are * holding @ubi->move_mutex and go sleep on the LEB lock. So, if the * LEB is already locked, we just do not move it and return - * %MOVE_RETRY. Note, we do not return %MOVE_CANCEL_RACE here because - * we do not know the reasons of the contention - it may be just a - * normal I/O on this LEB, so we want to re-try. + * %MOVE_CANCEL_RACE, which means that UBI will re-try, but later. */ err = leb_write_trylock(ubi, vol_id, lnum); if (err) { dbg_wl("contention on LEB %d:%d, cancel", vol_id, lnum); - return MOVE_RETRY; + return MOVE_CANCEL_RACE; } /* diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 0b49eadebc36..2135a53732ff 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -1174,7 +1174,7 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); if (!ech) - goto out_si; + goto out_slab; vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); if (!vidh) @@ -1235,6 +1235,8 @@ out_vidh: ubi_free_vid_hdr(ubi, vidh); out_ech: kfree(ech); +out_slab: + kmem_cache_destroy(si->scan_leb_slab); out_si: ubi_scan_destroy_si(si); return ERR_PTR(err); @@ -1323,9 +1325,7 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si) } } - if (si->scan_leb_slab) - kmem_cache_destroy(si->scan_leb_slab); - + kmem_cache_destroy(si->scan_leb_slab); kfree(si); } diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index bbfa88d459e0..c6c22295898e 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -121,7 +121,6 @@ enum { * PEB * MOVE_CANCEL_BITFLIPS: canceled because a bit-flip was detected in the * target PEB - * MOVE_RETRY: retry scrubbing the PEB */ enum { MOVE_CANCEL_RACE = 1, @@ -129,7 +128,6 @@ enum { MOVE_TARGET_RD_ERR, MOVE_TARGET_WR_ERR, MOVE_CANCEL_BITFLIPS, - MOVE_RETRY, }; /** diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 326bd9375638..fd3bf770f518 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -356,7 +356,7 @@ retry: */ err = ubi_scan_add_used(ubi, si, new_seb->pnum, new_seb->ec, vid_hdr, 0); - kmem_cache_free(si->scan_leb_slab, new_seb); + kfree(new_seb); ubi_free_vid_hdr(ubi, vid_hdr); return err; @@ -369,7 +369,7 @@ write_error: list_add(&new_seb->u.list, &si->erase); goto retry; } - kmem_cache_free(si->scan_leb_slab, new_seb); + kfree(new_seb); out_free: ubi_free_vid_hdr(ubi, vid_hdr); return err; diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 25f18e9b6432..ff2c4956eeff 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -386,7 +386,7 @@ static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int max) */ int ubi_wl_get_peb(struct ubi_device *ubi, int dtype) { - int err; + int err, medium_ec; struct ubi_wl_entry *e, *first, *last; ubi_assert(dtype == UBI_LONGTERM || dtype == UBI_SHORTTERM || @@ -424,7 +424,7 @@ retry: * For unknown data we pick a physical eraseblock with medium * erase counter. But we by no means can pick a physical * eraseblock with erase counter greater or equivalent than the - * lowest erase counter plus %WL_FREE_MAX_DIFF/2. + * lowest erase counter plus %WL_FREE_MAX_DIFF. */ first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, u.rb); @@ -433,8 +433,10 @@ retry: if (last->ec - first->ec < WL_FREE_MAX_DIFF) e = rb_entry(ubi->free.rb_node, struct ubi_wl_entry, u.rb); - else - e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF/2); + else { + medium_ec = (first->ec + WL_FREE_MAX_DIFF)/2; + e = find_wl_entry(&ubi->free, medium_ec); + } break; case UBI_SHORTTERM: /* @@ -790,10 +792,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, protect = 1; goto out_not_moved; } - if (err == MOVE_RETRY) { - scrubbing = 1; - goto out_not_moved; - } + if (err == MOVE_CANCEL_BITFLIPS || err == MOVE_TARGET_WR_ERR || err == MOVE_TARGET_RD_ERR) { /* @@ -1047,6 +1046,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, ubi_err("failed to erase PEB %d, error %d", pnum, err); kfree(wl_wrk); + kmem_cache_free(ubi_wl_entry_slab, e); if (err == -EINTR || err == -ENOMEM || err == -EAGAIN || err == -EBUSY) { @@ -1059,16 +1059,14 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, goto out_ro; } return err; - } - - kmem_cache_free(ubi_wl_entry_slab, e); - if (err != -EIO) + } else if (err != -EIO) { /* * If this is not %-EIO, we have no idea what to do. Scheduling * this physical eraseblock for erasure again would cause * errors again and again. Well, lets switch to R/O mode. */ goto out_ro; + } /* It is %-EIO, the PEB went bad */ diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 41afc408077d..8cc22568ebd3 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -1842,7 +1842,7 @@ vortex_timer(unsigned long data) ok = 1; } - if (dev->flags & IFF_SLAVE || !netif_carrier_ok(dev)) + if (!netif_carrier_ok(dev)) next_tick = 5*HZ; if (vp->medialock) diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index a8b82da3956e..10c45051caea 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -992,11 +992,6 @@ static inline void cp_start_hw (struct cp_private *cp) cpw8(Cmd, RxOn | TxOn); } -static void cp_enable_irq(struct cp_private *cp) -{ - cpw16_f(IntrMask, cp_intr_mask); -} - static void cp_init_hw (struct cp_private *cp) { struct net_device *dev = cp->dev; @@ -1036,6 +1031,8 @@ static void cp_init_hw (struct cp_private *cp) cpw16(MultiIntr, 0); + cpw16_f(IntrMask, cp_intr_mask); + cpw8_f(Cfg9346, Cfg9346_Lock); } @@ -1167,8 +1164,6 @@ static int cp_open (struct net_device *dev) if (rc) goto err_out_hw; - cp_enable_irq(cp); - netif_carrier_off(dev); mii_check_media(&cp->mii_if, netif_msg_link(cp), true); netif_start_queue(dev); @@ -2057,7 +2052,6 @@ static int cp_resume (struct pci_dev *pdev) /* FIXME: sh*t may happen if the Rx ring buffer is depleted */ cp_init_rings_index (cp); cp_init_hw (cp); - cp_enable_irq(cp); netif_start_queue (dev); spin_lock_irqsave (&cp->lock, flags); diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 5a92c48ffe59..93359fab240e 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2543,7 +2543,7 @@ config S6GMAC source "drivers/net/stmmac/Kconfig" config PCH_GBE - tristate "Intel EG20T PCH/OKI SEMICONDUCTOR IOH(ML7223/ML7831) GbE" + tristate "Intel EG20T PCH / OKI SEMICONDUCTOR ML7223 IOH GbE" depends on PCI select MII ---help--- @@ -2556,11 +2556,10 @@ config PCH_GBE This driver enables Gigabit Ethernet function. This driver also can be used for OKI SEMICONDUCTOR IOH(Input/ - Output Hub), ML7223/ML7831. - ML7223 IOH is for MP(Media Phone) use. ML7831 IOH is for general - purpose use. - ML7223/ML7831 is companion chip for Intel Atom E6xx series. - ML7223/ML7831 is completely compatible for Intel EG20T PCH. + Output Hub), ML7223. + ML7223 IOH is for MP(Media Phone) use. + ML7223 is companion chip for Intel Atom E6xx series. + ML7223 is completely compatible for Intel EG20T PCH. endif # NETDEV_1000 @@ -3324,23 +3323,6 @@ config PPPOL2TP used by ISPs and enterprises to tunnel PPP traffic over UDP tunnels. L2TP is replacing PPTP for VPN uses. -config PPPOLAC - tristate "PPP on L2TP Access Concentrator" - depends on PPP && INET - help - L2TP (RFC 2661) is a tunneling protocol widely used in virtual private - networks. This driver handles L2TP data packets between a UDP socket - and a PPP channel, but only permits one session per socket. Thus it is - fairly simple and suited for clients. - -config PPPOPNS - tristate "PPP on PPTP Network Server" - depends on PPP && INET - help - PPTP (RFC 2637) is a tunneling protocol widely used in virtual private - networks. This driver handles PPTP data packets between a RAW socket - and a PPP channel. It is fairly simple and easy to use. - config SLIP tristate "SLIP (serial line) support" ---help--- diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 366624f7ab43..776a478e6296 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -168,8 +168,6 @@ obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o obj-$(CONFIG_PPPOE) += pppox.o pppoe.o obj-$(CONFIG_PPPOL2TP) += pppox.o obj-$(CONFIG_PPTP) += pppox.o pptp.o -obj-$(CONFIG_PPPOLAC) += pppox.o pppolac.o -obj-$(CONFIG_PPPOPNS) += pppox.o pppopns.o obj-$(CONFIG_SLIP) += slip.o obj-$(CONFIG_SLHC) += slhc.o @@ -285,7 +283,6 @@ obj-$(CONFIG_USB_HSO) += usb/ obj-$(CONFIG_USB_USBNET) += usb/ obj-$(CONFIG_USB_ZD1201) += usb/ obj-$(CONFIG_USB_IPHETH) += usb/ -obj-$(CONFIG_USB_CDC_PHONET) += usb/ obj-$(CONFIG_WLAN) += wireless/ obj-$(CONFIG_NET_TULIP) += tulip/ diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 5e34e21f8889..1269ba5d6e56 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -2223,6 +2223,10 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb, dev_info(&adapter->pdev->dev, "tx locked\n"); return NETDEV_TX_LOCKED; } + if (skb->mark == 0x01) + type = atl1c_trans_high; + else + type = atl1c_trans_normal; if (atl1c_tpd_avail(adapter, type) < tpd_req) { /* no enough descriptor, just stop queue */ diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 48c27d34eacd..cd5789ff3726 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -2476,7 +2476,7 @@ static irqreturn_t atl1_intr(int irq, void *data) "pcie phy link down %x\n", status); if (netif_running(adapter->netdev)) { /* reset MAC */ iowrite32(0, adapter->hw.hw_addr + REG_IMR); - schedule_work(&adapter->reset_dev_task); + schedule_work(&adapter->pcie_dma_to_rst_task); return IRQ_HANDLED; } } @@ -2488,7 +2488,7 @@ static irqreturn_t atl1_intr(int irq, void *data) "pcie DMA r/w error (status = 0x%x)\n", status); iowrite32(0, adapter->hw.hw_addr + REG_IMR); - schedule_work(&adapter->reset_dev_task); + schedule_work(&adapter->pcie_dma_to_rst_task); return IRQ_HANDLED; } @@ -2633,10 +2633,10 @@ static void atl1_down(struct atl1_adapter *adapter) atl1_clean_rx_ring(adapter); } -static void atl1_reset_dev_task(struct work_struct *work) +static void atl1_tx_timeout_task(struct work_struct *work) { struct atl1_adapter *adapter = - container_of(work, struct atl1_adapter, reset_dev_task); + container_of(work, struct atl1_adapter, tx_timeout_task); struct net_device *netdev = adapter->netdev; netif_device_detach(netdev); @@ -3034,10 +3034,12 @@ static int __devinit atl1_probe(struct pci_dev *pdev, (unsigned long)adapter); adapter->phy_timer_pending = false; - INIT_WORK(&adapter->reset_dev_task, atl1_reset_dev_task); + INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task); INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task); + INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task); + err = register_netdev(netdev); if (err) goto err_common; diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h index c27b724a834b..68de8cbfb3ec 100644 --- a/drivers/net/atlx/atl1.h +++ b/drivers/net/atlx/atl1.h @@ -759,8 +759,9 @@ struct atl1_adapter { u16 link_speed; u16 link_duplex; spinlock_t lock; - struct work_struct reset_dev_task; + struct work_struct tx_timeout_task; struct work_struct link_chg_task; + struct work_struct pcie_dma_to_rst_task; struct timer_list phy_config_timer; bool phy_timer_pending; diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c index 2b7af060d49f..afb7f7dd1bb1 100644 --- a/drivers/net/atlx/atlx.c +++ b/drivers/net/atlx/atlx.c @@ -193,7 +193,7 @@ static void atlx_tx_timeout(struct net_device *netdev) { struct atlx_adapter *adapter = netdev_priv(netdev); /* Do the reset outside of interrupt context */ - schedule_work(&adapter->reset_dev_task); + schedule_work(&adapter->tx_timeout_task); } /* diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 2ce5db5e9c60..a485f7fdaf37 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -763,8 +763,6 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, copied = make_tx_wrbs(adapter, skb, wrb_cnt, dummy_wrb); if (copied) { - int gso_segs = skb_shinfo(skb)->gso_segs; - /* record the sent skb in the sent_skb table */ BUG_ON(tx_obj->sent_skb_list[start]); tx_obj->sent_skb_list[start] = skb; @@ -782,7 +780,8 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, be_txq_notify(adapter, txq->id, wrb_cnt); - be_tx_stats_update(adapter, wrb_cnt, copied, gso_segs, stopped); + be_tx_stats_update(adapter, wrb_cnt, copied, + skb_shinfo(skb)->gso_segs, stopped); } else { txq->head = start; dev_kfree_skb_any(skb); diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index c9b123c1608b..57d3293c65bd 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -416,9 +416,6 @@ struct cnic_eth_dev *bnx2_cnic_probe(struct net_device *dev) struct bnx2 *bp = netdev_priv(dev); struct cnic_eth_dev *cp = &bp->cnic_eth_dev; - if (!cp->max_iscsi_conn) - return NULL; - cp->drv_owner = THIS_MODULE; cp->chip_id = bp->chip_id; cp->pdev = bp->pdev; @@ -5310,7 +5307,7 @@ bnx2_free_tx_skbs(struct bnx2 *bp) int k, last; if (skb == NULL) { - j = NEXT_TX_BD(j); + j++; continue; } @@ -5322,8 +5319,8 @@ bnx2_free_tx_skbs(struct bnx2 *bp) tx_buf->skb = NULL; last = tx_buf->nr_frags; - j = NEXT_TX_BD(j); - for (k = 0; k < last; k++, j = NEXT_TX_BD(j)) { + j++; + for (k = 0; k < last; k++, j++) { tx_buf = &txr->tx_buf_ring[TX_RING_IDX(j)]; dma_unmap_page(&bp->pdev->dev, dma_unmap_addr(tx_buf, mapping), @@ -8180,10 +8177,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->timer.data = (unsigned long) bp; bp->timer.function = bnx2_timer; -#ifdef BCM_CNIC - bp->cnic_eth_dev.max_iscsi_conn = - bnx2_reg_rd_ind(bp, BNX2_FW_MAX_ISCSI_CONN); -#endif pci_save_state(pdev); return 0; diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c index d11af7cbd97b..410a49e571ac 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.c +++ b/drivers/net/bnx2x/bnx2x_dcb.c @@ -1858,7 +1858,6 @@ static u8 bnx2x_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap) break; case DCB_CAP_ATTR_DCBX: *cap = BNX2X_DCBX_CAPS; - break; default: rval = -EINVAL; break; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 04976dbd63ff..74be989f51c5 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -4138,7 +4138,7 @@ static void bnx2x_init_def_sb(struct bnx2x *bp) int igu_seg_id; int port = BP_PORT(bp); int func = BP_FUNC(bp); - int reg_offset, reg_offset_en5; + int reg_offset; u64 section; int index; struct hc_sp_status_block_data sp_sb_data; @@ -4161,8 +4161,6 @@ static void bnx2x_init_def_sb(struct bnx2x *bp) reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); - reg_offset_en5 = (port ? MISC_REG_AEU_ENABLE5_FUNC_1_OUT_0 : - MISC_REG_AEU_ENABLE5_FUNC_0_OUT_0); for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) { int sindex; /* take care of sig[0]..sig[4] */ @@ -4177,7 +4175,7 @@ static void bnx2x_init_def_sb(struct bnx2x *bp) * and not 16 between the different groups */ bp->attn_group[index].sig[4] = REG_RD(bp, - reg_offset_en5 + 0x4*index); + reg_offset + 0x10 + 0x4*index); else bp->attn_group[index].sig[4] = 0; } diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 0380b3a8f1c4..86bba25d2d3f 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -1325,18 +1325,6 @@ Latched ump_tx_parity; [31] MCP Latched scpad_parity; */ #define MISC_REG_AEU_ENABLE4_PXP_0 0xa108 #define MISC_REG_AEU_ENABLE4_PXP_1 0xa1a8 -/* [RW 32] fifth 32b for enabling the output for function 0 output0. Mapped - * as follows: [0] PGLUE config_space; [1] PGLUE misc_flr; [2] PGLUE B RBC - * attention [3] PGLUE B RBC parity; [4] ATC attention; [5] ATC parity; [6] - * mstat0 attention; [7] mstat0 parity; [8] mstat1 attention; [9] mstat1 - * parity; [31-10] Reserved; */ -#define MISC_REG_AEU_ENABLE5_FUNC_0_OUT_0 0xa688 -/* [RW 32] Fifth 32b for enabling the output for function 1 output0. Mapped - * as follows: [0] PGLUE config_space; [1] PGLUE misc_flr; [2] PGLUE B RBC - * attention [3] PGLUE B RBC parity; [4] ATC attention; [5] ATC parity; [6] - * mstat0 attention; [7] mstat0 parity; [8] mstat1 attention; [9] mstat1 - * parity; [31-10] Reserved; */ -#define MISC_REG_AEU_ENABLE5_FUNC_1_OUT_0 0xa6b0 /* [RW 1] set/clr general attention 0; this will set/clr bit 94 in the aeu 128 bit vector */ #define MISC_REG_AEU_GENERAL_ATTN_0 0xa000 diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 5e725e07d61b..2df9276720a0 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -871,12 +871,16 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]) } } -static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[]) +/* hw is a boolean parameter that determines whether we should try and + * set the hw address of the device as well as the hw address of the + * net_device + */ +static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw) { struct net_device *dev = slave->dev; struct sockaddr s_addr; - if (slave->bond->params.mode == BOND_MODE_TLB) { + if (!hw) { memcpy(dev->dev_addr, addr, dev->addr_len); return 0; } @@ -906,8 +910,8 @@ static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct u8 tmp_mac_addr[ETH_ALEN]; memcpy(tmp_mac_addr, slave1->dev->dev_addr, ETH_ALEN); - alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr); - alb_set_slave_mac_addr(slave2, tmp_mac_addr); + alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr, bond->alb_info.rlb_enabled); + alb_set_slave_mac_addr(slave2, tmp_mac_addr, bond->alb_info.rlb_enabled); } @@ -1054,7 +1058,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav /* Try setting slave mac to bond address and fall-through to code handling that situation below... */ - alb_set_slave_mac_addr(slave, bond->dev->dev_addr); + alb_set_slave_mac_addr(slave, bond->dev->dev_addr, + bond->alb_info.rlb_enabled); } /* The slave's address is equal to the address of the bond. @@ -1090,7 +1095,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav } if (free_mac_slave) { - alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr); + alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr, + bond->alb_info.rlb_enabled); pr_warning("%s: Warning: the hw address of slave %s is in use by the bond; giving it the hw address of %s\n", bond->dev->name, slave->dev->name, @@ -1446,7 +1452,8 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave) { int res; - res = alb_set_slave_mac_addr(slave, slave->perm_hwaddr); + res = alb_set_slave_mac_addr(slave, slave->perm_hwaddr, + bond->alb_info.rlb_enabled); if (res) { return res; } @@ -1597,7 +1604,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave alb_swap_mac_addr(bond, swap_slave, new_slave); } else { /* set the new_slave to the bond mac address */ - alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr); + alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr, + bond->alb_info.rlb_enabled); } if (swap_slave) { @@ -1657,7 +1665,8 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr) alb_swap_mac_addr(bond, swap_slave, bond->curr_active_slave); alb_fasten_mac_swap(bond, swap_slave, bond->curr_active_slave); } else { - alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr); + alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr, + bond->alb_info.rlb_enabled); read_lock(&bond->lock); alb_send_learning_packets(bond->curr_active_slave, bond_dev->dev_addr); diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6f8b2688d27e..63c22b0bb5ad 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -77,7 +77,6 @@ #include #include #include -#include #include "bonding.h" #include "bond_3ad.h" #include "bond_alb.h" @@ -389,6 +388,8 @@ struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr) return next; } +#define bond_queue_mapping(skb) (*(u16 *)((skb)->cb)) + /** * bond_dev_queue_xmit - Prepare skb for xmit. * @@ -402,9 +403,7 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, skb->dev = slave_dev; skb->priority = 1; - BUILD_BUG_ON(sizeof(skb->queue_mapping) != - sizeof(qdisc_skb_cb(skb)->bond_queue_mapping)); - skb->queue_mapping = qdisc_skb_cb(skb)->bond_queue_mapping; + skb->queue_mapping = bond_queue_mapping(skb); if (unlikely(netpoll_tx_running(slave_dev))) bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb); @@ -1439,8 +1438,6 @@ static void bond_compute_features(struct bonding *bond) struct net_device *bond_dev = bond->dev; u32 vlan_features = BOND_VLAN_FEATURES; unsigned short max_hard_header_len = ETH_HLEN; - unsigned int gso_max_size = GSO_MAX_SIZE; - u16 gso_max_segs = GSO_MAX_SEGS; int i; read_lock(&bond->lock); @@ -1454,16 +1451,11 @@ static void bond_compute_features(struct bonding *bond) if (slave->dev->hard_header_len > max_hard_header_len) max_hard_header_len = slave->dev->hard_header_len; - - gso_max_size = min(gso_max_size, slave->dev->gso_max_size); - gso_max_segs = min(gso_max_segs, slave->dev->gso_max_segs); } done: bond_dev->vlan_features = vlan_features; bond_dev->hard_header_len = max_hard_header_len; - bond_dev->gso_max_segs = gso_max_segs; - netif_set_gso_max_size(bond_dev, gso_max_size); read_unlock(&bond->lock); @@ -1508,8 +1500,6 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) struct sk_buff *skb = *pskb; struct slave *slave; struct bonding *bond; - void (*recv_probe)(struct sk_buff *, struct bonding *, - struct slave *); skb = skb_share_check(skb, GFP_ATOMIC); if (unlikely(!skb)) @@ -1523,12 +1513,11 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) if (bond->params.arp_interval) slave->dev->last_rx = jiffies; - recv_probe = ACCESS_ONCE(bond->recv_probe); - if (recv_probe) { + if (bond->recv_probe) { struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC); if (likely(nskb)) { - recv_probe(nskb, bond, slave); + bond->recv_probe(nskb, bond, slave); dev_kfree_skb(nskb); } } @@ -1636,10 +1625,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) if (slave_dev->type != ARPHRD_ETHER) bond_setup_by_slave(bond_dev, slave_dev); - else { + else ether_setup(bond_dev); - bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING; - } netdev_bonding_change(bond_dev, NETDEV_POST_TYPE_CHANGE); @@ -1913,7 +1900,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) "but new slave device does not support netpoll.\n", bond_dev->name); res = -EBUSY; - goto err_detach; + goto err_close; } } #endif @@ -1922,7 +1909,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) res = bond_create_slave_symlinks(bond_dev, slave_dev); if (res) - goto err_detach; + goto err_close; res = netdev_rx_handler_register(slave_dev, bond_handle_frame, new_slave); @@ -1943,11 +1930,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) err_dest_symlinks: bond_destroy_slave_symlinks(bond_dev, slave_dev); -err_detach: - write_lock_bh(&bond->lock); - bond_detach_slave(bond, new_slave); - write_unlock_bh(&bond->lock); - err_close: dev_close(slave_dev); @@ -3084,11 +3066,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks) trans_start + delta_in_ticks)) || bond->curr_active_slave != slave) { slave->link = BOND_LINK_UP; - if (bond->current_arp_slave) { - bond_set_slave_inactive_flags( - bond->current_arp_slave); - bond->current_arp_slave = NULL; - } + bond->current_arp_slave = NULL; pr_info("%s: link status definitely up for interface %s.\n", bond->dev->name, slave->dev->name); @@ -4248,7 +4226,7 @@ static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb) /* * Save the original txq to restore before passing to the driver */ - qdisc_skb_cb(skb)->bond_queue_mapping = skb->queue_mapping; + bond_queue_mapping(skb) = skb->queue_mapping; if (unlikely(txq >= dev->real_num_tx_queues)) { do { @@ -4420,7 +4398,7 @@ static void bond_setup(struct net_device *bond_dev) bond_dev->tx_queue_len = 0; bond_dev->flags |= IFF_MASTER|IFF_MULTICAST; bond_dev->priv_flags |= IFF_BONDING; - bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); + bond_dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; /* At first, we block adding VLANs. That's the only way to * prevent problems that occur when adding VLANs over an diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 8a967358a806..88fcb25e554a 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -992,7 +992,6 @@ static ssize_t bonding_store_primary(struct device *d, int i; struct slave *slave; struct bonding *bond = to_bond(d); - char ifname[IFNAMSIZ]; if (!rtnl_trylock()) return restart_syscall(); @@ -1003,33 +1002,32 @@ static ssize_t bonding_store_primary(struct device *d, if (!USES_PRIMARY(bond->params.mode)) { pr_info("%s: Unable to set primary slave; %s is in mode %d\n", bond->dev->name, bond->dev->name, bond->params.mode); - goto out; - } - - sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ + } else { + bond_for_each_slave(bond, slave, i) { + if (strnicmp + (slave->dev->name, buf, + strlen(slave->dev->name)) == 0) { + pr_info("%s: Setting %s as primary slave.\n", + bond->dev->name, slave->dev->name); + bond->primary_slave = slave; + strcpy(bond->params.primary, slave->dev->name); + bond_select_active_slave(bond); + goto out; + } + } - /* check to see if we are clearing primary */ - if (!strlen(ifname) || buf[0] == '\n') { - pr_info("%s: Setting primary slave to None.\n", - bond->dev->name); - bond->primary_slave = NULL; - bond_select_active_slave(bond); - goto out; - } + /* if we got here, then we didn't match the name of any slave */ - bond_for_each_slave(bond, slave, i) { - if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { - pr_info("%s: Setting %s as primary slave.\n", - bond->dev->name, slave->dev->name); - bond->primary_slave = slave; - strcpy(bond->params.primary, slave->dev->name); - bond_select_active_slave(bond); - goto out; + if (strlen(buf) == 0 || buf[0] == '\n') { + pr_info("%s: Setting primary slave to None.\n", + bond->dev->name); + bond->primary_slave = NULL; + bond_select_active_slave(bond); + } else { + pr_info("%s: Unable to set %.*s as primary slave as it is not a slave.\n", + bond->dev->name, (int)strlen(buf) - 1, buf); } } - - pr_info("%s: Unable to set %.*s as primary slave.\n", - bond->dev->name, (int)strlen(buf) - 1, buf); out: write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); @@ -1164,7 +1162,6 @@ static ssize_t bonding_store_active_slave(struct device *d, struct slave *old_active = NULL; struct slave *new_active = NULL; struct bonding *bond = to_bond(d); - char ifname[IFNAMSIZ]; if (!rtnl_trylock()) return restart_syscall(); @@ -1173,62 +1170,56 @@ static ssize_t bonding_store_active_slave(struct device *d, read_lock(&bond->lock); write_lock_bh(&bond->curr_slave_lock); - if (!USES_PRIMARY(bond->params.mode)) { + if (!USES_PRIMARY(bond->params.mode)) pr_info("%s: Unable to change active slave; %s is in mode %d\n", bond->dev->name, bond->dev->name, bond->params.mode); - goto out; - } - - sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ - - /* check to see if we are clearing active */ - if (!strlen(ifname) || buf[0] == '\n') { - pr_info("%s: Clearing current active slave.\n", - bond->dev->name); - bond->curr_active_slave = NULL; - bond_select_active_slave(bond); - goto out; - } - - bond_for_each_slave(bond, slave, i) { - if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { - old_active = bond->curr_active_slave; - new_active = slave; - if (new_active == old_active) { - /* do nothing */ - pr_info("%s: %s is already the current" - " active slave.\n", - bond->dev->name, - slave->dev->name); - goto out; - } - else { - if ((new_active) && - (old_active) && - (new_active->link == BOND_LINK_UP) && - IS_UP(new_active->dev)) { - pr_info("%s: Setting %s as active" - " slave.\n", + else { + bond_for_each_slave(bond, slave, i) { + if (strnicmp + (slave->dev->name, buf, + strlen(slave->dev->name)) == 0) { + old_active = bond->curr_active_slave; + new_active = slave; + if (new_active == old_active) { + /* do nothing */ + pr_info("%s: %s is already the current active slave.\n", bond->dev->name, slave->dev->name); - bond_change_active_slave(bond, - new_active); + goto out; } else { - pr_info("%s: Could not set %s as" - " active slave; either %s is" - " down or the link is down.\n", - bond->dev->name, - slave->dev->name, - slave->dev->name); + if ((new_active) && + (old_active) && + (new_active->link == BOND_LINK_UP) && + IS_UP(new_active->dev)) { + pr_info("%s: Setting %s as active slave.\n", + bond->dev->name, + slave->dev->name); + bond_change_active_slave(bond, new_active); + } + else { + pr_info("%s: Could not set %s as active slave; either %s is down or the link is down.\n", + bond->dev->name, + slave->dev->name, + slave->dev->name); + } + goto out; } - goto out; } } - } - pr_info("%s: Unable to set %.*s as active slave.\n", - bond->dev->name, (int)strlen(buf) - 1, buf); + /* if we got here, then we didn't match the name of any slave */ + + if (strlen(buf) == 0 || buf[0] == '\n') { + pr_info("%s: Setting active slave to None.\n", + bond->dev->name); + bond->primary_slave = NULL; + bond_select_active_slave(bond); + } else { + pr_info("%s: Unable to set %.*s as active slave as it is not a slave.\n", + bond->dev->name, (int)strlen(buf) - 1, buf); + } + } out: write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); @@ -1524,7 +1515,6 @@ static ssize_t bonding_store_slaves_active(struct device *d, goto out; } - read_lock(&bond->lock); bond_for_each_slave(bond, slave, i) { if (!bond_is_active_slave(slave)) { if (new_value) @@ -1533,7 +1523,6 @@ static ssize_t bonding_store_slaves_active(struct device *d, slave->inactive = 1; } } - read_unlock(&bond->lock); out: return ret; } diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index 82b1802b1d3d..3df0c0f8b8bf 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -325,9 +325,6 @@ static int ldisc_open(struct tty_struct *tty) sprintf(name, "cf%s", tty->name); dev = alloc_netdev(sizeof(*ser), name, caifdev_setup); - if (!dev) - return -ENOMEM; - ser = netdev_priv(dev); ser->tty = tty_kref_get(tty); ser->dev = dev; diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 61958684ab13..7e5cc0bd913d 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -592,8 +592,8 @@ static void c_can_chip_config(struct net_device *dev) priv->write_reg(priv, &priv->regs->control, CONTROL_ENABLE_AR); - if ((priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) && - (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)) { + if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY & + CAN_CTRLMODE_LOOPBACK)) { /* loopback + silent mode : useful for hot self-test */ priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); @@ -688,7 +688,7 @@ static int c_can_get_berr_counter(const struct net_device *dev, * * We iterate from priv->tx_echo to priv->tx_next and check if the * packet has been transmitted, echo it back to the CAN framework. - * If we discover a not yet transmitted packet, stop looking for more. + * If we discover a not yet transmitted package, stop looking for more. */ static void c_can_do_tx(struct net_device *dev) { @@ -700,7 +700,7 @@ static void c_can_do_tx(struct net_device *dev) for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) { msg_obj_no = get_tx_echo_msg_obj(priv); val = c_can_read_reg32(priv, &priv->regs->txrqst1); - if (!(val & (1 << (msg_obj_no - 1)))) { + if (!(val & (1 << msg_obj_no))) { can_get_echo_skb(dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); stats->tx_bytes += priv->read_reg(priv, @@ -708,8 +708,6 @@ static void c_can_do_tx(struct net_device *dev) & IF_MCONT_DLC_MASK; stats->tx_packets++; c_can_inval_msg_object(dev, 0, msg_obj_no); - } else { - break; } } @@ -916,7 +914,7 @@ static int c_can_handle_bus_err(struct net_device *dev, break; case LEC_ACK_ERROR: netdev_dbg(dev, "ack error\n"); - cf->data[3] |= (CAN_ERR_PROT_LOC_ACK | + cf->data[2] |= (CAN_ERR_PROT_LOC_ACK | CAN_ERR_PROT_LOC_ACK_DEL); break; case LEC_BIT1_ERROR: @@ -929,7 +927,7 @@ static int c_can_handle_bus_err(struct net_device *dev, break; case LEC_CRC_ERROR: netdev_dbg(dev, "CRC error\n"); - cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ | + cf->data[2] |= (CAN_ERR_PROT_LOC_CRC_SEQ | CAN_ERR_PROT_LOC_CRC_DEL); break; default: @@ -954,7 +952,7 @@ static int c_can_poll(struct napi_struct *napi, int quota) struct net_device *dev = napi->dev; struct c_can_priv *priv = netdev_priv(dev); - irqstatus = priv->irqstatus; + irqstatus = priv->read_reg(priv, &priv->regs->interrupt); if (!irqstatus) goto end; @@ -1032,11 +1030,12 @@ end: static irqreturn_t c_can_isr(int irq, void *dev_id) { + u16 irqstatus; struct net_device *dev = (struct net_device *)dev_id; struct c_can_priv *priv = netdev_priv(dev); - priv->irqstatus = priv->read_reg(priv, &priv->regs->interrupt); - if (!priv->irqstatus) + irqstatus = priv->read_reg(priv, &priv->regs->interrupt); + if (!irqstatus) return IRQ_NONE; /* disable all interrupts and schedule the NAPI */ @@ -1066,11 +1065,10 @@ static int c_can_open(struct net_device *dev) goto exit_irq_fail; } - napi_enable(&priv->napi); - /* start the c_can controller */ c_can_start(dev); + napi_enable(&priv->napi); netif_start_queue(dev); return 0; diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h index 5f32d34af507..9b7fbef3d09a 100644 --- a/drivers/net/can/c_can/c_can.h +++ b/drivers/net/can/c_can/c_can.h @@ -76,7 +76,6 @@ struct c_can_priv { unsigned int tx_next; unsigned int tx_echo; void *priv; /* for board-specific data */ - u16 irqstatus; }; struct net_device *alloc_c_can_dev(void); diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index cc3ea0d5fd8e..d0f8c7e67e7d 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -557,7 +557,8 @@ void close_candev(struct net_device *dev) { struct can_priv *priv = netdev_priv(dev); - del_timer_sync(&priv->restart_timer); + if (del_timer_sync(&priv->restart_timer)) + dev_put(dev); can_flush_echo_skb(dev); } EXPORT_SYMBOL_GPL(close_candev); diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c index b4159a613184..f1942cab35f6 100644 --- a/drivers/net/can/janz-ican3.c +++ b/drivers/net/can/janz-ican3.c @@ -1249,6 +1249,7 @@ static irqreturn_t ican3_irq(int irq, void *dev_id) */ static int ican3_reset_module(struct ican3_dev *mod) { + u8 val = 1 << mod->num; unsigned long start; u8 runold, runnew; @@ -1262,7 +1263,8 @@ static int ican3_reset_module(struct ican3_dev *mod) runold = ioread8(mod->dpm + TARGET_RUNNING); /* reset the module */ - iowrite8(0x00, &mod->dpmctrl->hwreset); + iowrite8(val, &mod->ctrl->reset_assert); + iowrite8(val, &mod->ctrl->reset_deassert); /* wait until the module has finished resetting and is running */ start = jiffies; diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 9bcc39a07c4b..330140ee266d 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -83,11 +83,6 @@ #define INSTRUCTION_LOAD_TXB(n) (0x40 + 2 * (n)) #define INSTRUCTION_READ_RXB(n) (((n) == 0) ? 0x90 : 0x94) #define INSTRUCTION_RESET 0xC0 -#define RTS_TXB0 0x01 -#define RTS_TXB1 0x02 -#define RTS_TXB2 0x04 -#define INSTRUCTION_RTS(n) (0x80 | ((n) & 0x07)) - /* MPC251x registers */ #define CANSTAT 0x0e @@ -402,7 +397,6 @@ static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf, static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame, int tx_buf_idx) { - struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); u32 sid, eid, exide, rtr; u8 buf[SPI_TRANSFER_BUF_LEN]; @@ -424,10 +418,7 @@ static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame, buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc; memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc); mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx); - - /* use INSTRUCTION_RTS, to avoid "repeated frame problem" */ - priv->spi_tx_buf[0] = INSTRUCTION_RTS(1 << tx_buf_idx); - mcp251x_spi_trans(priv->spi, 1); + mcp251x_write_reg(spi, TXBCTRL(tx_buf_idx), TXBCTRL_TXREQ); } static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c index d8f2b5b1b624..5fedc3375562 100644 --- a/drivers/net/can/mscan/mpc5xxx_can.c +++ b/drivers/net/can/mscan/mpc5xxx_can.c @@ -181,7 +181,7 @@ static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev, if (!clock_name || !strcmp(clock_name, "sys")) { sys_clk = clk_get(&ofdev->dev, "sys_clk"); - if (IS_ERR(sys_clk)) { + if (!sys_clk) { dev_err(&ofdev->dev, "couldn't get sys_clk\n"); goto exit_unmap; } @@ -204,7 +204,7 @@ static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev, if (clocksrc < 0) { ref_clk = clk_get(&ofdev->dev, "ref_clk"); - if (IS_ERR(ref_clk)) { + if (!ref_clk) { dev_err(&ofdev->dev, "couldn't get ref_clk\n"); goto exit_unmap; } diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index b508a6380f8b..d11fbb2b95ff 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -559,7 +559,7 @@ static void pch_can_error(struct net_device *ndev, u32 status) stats->rx_errors++; break; case PCH_CRC_ERR: - cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ | + cf->data[2] |= CAN_ERR_PROT_LOC_CRC_SEQ | CAN_ERR_PROT_LOC_CRC_DEL; priv->can.can_stats.bus_error++; stats->rx_errors++; diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index 10b23947d8f5..f7bbde9eb2cb 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -734,12 +734,12 @@ static int ti_hecc_error(struct net_device *ndev, int int_status, } if (err_status & HECC_CANES_CRCE) { hecc_set_bit(priv, HECC_CANES, HECC_CANES_CRCE); - cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ | + cf->data[2] |= CAN_ERR_PROT_LOC_CRC_SEQ | CAN_ERR_PROT_LOC_CRC_DEL; } if (err_status & HECC_CANES_ACKE) { hecc_set_bit(priv, HECC_CANES, HECC_CANES_ACKE); - cf->data[3] |= CAN_ERR_PROT_LOC_ACK | + cf->data[2] |= CAN_ERR_PROT_LOC_ACK | CAN_ERR_PROT_LOC_ACK_DEL; } } @@ -969,12 +969,12 @@ static int __devexit ti_hecc_remove(struct platform_device *pdev) struct net_device *ndev = platform_get_drvdata(pdev); struct ti_hecc_priv *priv = netdev_priv(ndev); - unregister_candev(ndev); clk_disable(priv->clk); clk_put(priv->clk); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); iounmap(priv->base); release_mem_region(res->start, resource_size(res)); + unregister_candev(ndev); free_candev(ndev); platform_set_drvdata(pdev, NULL); diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 363c7f368909..11a92afdf982 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -605,12 +605,11 @@ static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type) } EXPORT_SYMBOL(cnic_unregister_driver); -static int cnic_init_id_tbl(struct cnic_id_tbl *id_tbl, u32 size, u32 start_id, - u32 next) +static int cnic_init_id_tbl(struct cnic_id_tbl *id_tbl, u32 size, u32 start_id) { id_tbl->start = start_id; id_tbl->max = size; - id_tbl->next = next; + id_tbl->next = 0; spin_lock_init(&id_tbl->lock); id_tbl->table = kzalloc(DIV_ROUND_UP(size, 32) * 4, GFP_KERNEL); if (!id_tbl->table) @@ -2779,10 +2778,13 @@ static u32 cnic_service_bnx2_queues(struct cnic_dev *dev) /* Tell compiler that status_blk fields can change. */ barrier(); - status_idx = (u16) *cp->kcq1.status_idx_ptr; - /* status block index must be read first */ - rmb(); - cp->kwq_con_idx = *cp->kwq_con_idx_ptr; + if (status_idx != *cp->kcq1.status_idx_ptr) { + status_idx = (u16) *cp->kcq1.status_idx_ptr; + /* status block index must be read first */ + rmb(); + cp->kwq_con_idx = *cp->kwq_con_idx_ptr; + } else + break; } CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx); @@ -2906,6 +2908,8 @@ static u32 cnic_service_bnx2x_kcq(struct cnic_dev *dev, struct kcq_info *info) /* Tell compiler that sblk fields can change. */ barrier(); + if (last_status == *info->status_idx_ptr) + break; last_status = *info->status_idx_ptr; /* status block index must be read before reading the KCQ */ @@ -3768,13 +3772,7 @@ static void cnic_cm_process_kcqe(struct cnic_dev *dev, struct kcqe *kcqe) break; case L4_KCQE_OPCODE_VALUE_CLOSE_RECEIVED: - /* after we already sent CLOSE_REQ */ - if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags) && - !test_bit(SK_F_OFFLD_COMPLETE, &csk->flags) && - csk->state == L4_KCQE_OPCODE_VALUE_CLOSE_COMP) - cp->close_conn(csk, L4_KCQE_OPCODE_VALUE_RESET_COMP); - else - cnic_cm_upcall(cp, csk, opcode); + cnic_cm_upcall(cp, csk, opcode); break; } csk_put(csk); @@ -3805,17 +3803,14 @@ static void cnic_cm_free_mem(struct cnic_dev *dev) static int cnic_cm_alloc_mem(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - u32 port_id; cp->csk_tbl = kzalloc(sizeof(struct cnic_sock) * MAX_CM_SK_TBL_SZ, GFP_KERNEL); if (!cp->csk_tbl) return -ENOMEM; - get_random_bytes(&port_id, sizeof(port_id)); - port_id %= CNIC_LOCAL_PORT_RANGE; if (cnic_init_id_tbl(&cp->csk_port_tbl, CNIC_LOCAL_PORT_RANGE, - CNIC_LOCAL_PORT_MIN, port_id)) { + CNIC_LOCAL_PORT_MIN)) { cnic_cm_free_mem(dev); return -ENOMEM; } @@ -3831,14 +3826,12 @@ static int cnic_ready_to_close(struct cnic_sock *csk, u32 opcode) } /* 1. If event opcode matches the expected event in csk->state - * 2. If the expected event is CLOSE_COMP or RESET_COMP, we accept any - * event + * 2. If the expected event is CLOSE_COMP, we accept any event * 3. If the expected event is 0, meaning the connection was never * never established, we accept the opcode from cm_abort. */ if (opcode == csk->state || csk->state == 0 || - csk->state == L4_KCQE_OPCODE_VALUE_CLOSE_COMP || - csk->state == L4_KCQE_OPCODE_VALUE_RESET_COMP) { + csk->state == L4_KCQE_OPCODE_VALUE_CLOSE_COMP) { if (!test_and_set_bit(SK_F_CLOSING, &csk->flags)) { if (csk->state == 0) csk->state = opcode; @@ -4225,6 +4218,14 @@ static void cnic_enable_bnx2_int(struct cnic_dev *dev) BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | cp->last_status_idx); } +static void cnic_get_bnx2_iscsi_info(struct cnic_dev *dev) +{ + u32 max_conn; + + max_conn = cnic_reg_rd_ind(dev, BNX2_FW_MAX_ISCSI_CONN); + dev->max_iscsi_conn = max_conn; +} + static void cnic_disable_bnx2_int_sync(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; @@ -4549,6 +4550,8 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev) return err; } + cnic_get_bnx2_iscsi_info(dev); + return 0; } @@ -4823,7 +4826,7 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) pfid = cp->pfid; ret = cnic_init_id_tbl(&cp->cid_tbl, MAX_ISCSI_TBL_SZ, - cp->iscsi_start_cid, 0); + cp->iscsi_start_cid); if (ret) return -ENOMEM; @@ -4831,7 +4834,7 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) if (BNX2X_CHIP_IS_E2(cp->chip_id)) { ret = cnic_init_id_tbl(&cp->fcoe_cid_tbl, BNX2X_FCOE_NUM_CONNECTIONS, - cp->fcoe_start_cid, 0); + cp->fcoe_start_cid); if (ret) return -ENOMEM; @@ -5214,8 +5217,6 @@ static struct cnic_dev *init_bnx2_cnic(struct net_device *dev) cdev->pcidev = pdev; cp->chip_id = ethdev->chip_id; - cdev->max_iscsi_conn = ethdev->max_iscsi_conn; - cp->cnic_ops = &cnic_bnx2_ops; cp->start_hw = cnic_start_bnx2_hw; cp->stop_hw = cnic_stop_bnx2_hw; @@ -5334,7 +5335,7 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event, dev = cnic_from_netdev(netdev); - if (!dev && (event == NETDEV_REGISTER || netif_running(netdev))) { + if (!dev && (event == NETDEV_REGISTER || event == NETDEV_UP)) { /* Check for the hot-plug device */ dev = is_cnic_dev(netdev); if (dev) { @@ -5350,7 +5351,7 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event, else if (event == NETDEV_UNREGISTER) cnic_ulp_exit(dev); - if (event == NETDEV_UP || (new_dev && netif_running(netdev))) { + if (event == NETDEV_UP) { if (cnic_register_netdev(dev) != 0) { cnic_put(dev); goto done; diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index 015b5152b0de..862804f32b6e 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c @@ -971,7 +971,7 @@ static int nb_callback(struct notifier_block *self, unsigned long event, case (NETEVENT_REDIRECT):{ struct netevent_redirect *nr = ctx; cxgb_redirect(nr->old, nr->new); - cxgb_neigh_update(dst_get_neighbour(nr->new)); + cxgb_neigh_update(nr->new->neighbour); break; } default: @@ -1116,8 +1116,8 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new) struct l2t_entry *e; struct t3c_tid_entry *te; - olddev = dst_get_neighbour(old)->dev; - newdev = dst_get_neighbour(new)->dev; + olddev = old->neighbour->dev; + newdev = new->neighbour->dev; if (!is_offloading(olddev)) return; if (!is_offloading(newdev)) { @@ -1134,7 +1134,7 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new) } /* Add new L2T entry */ - e = t3_l2t_get(tdev, dst_get_neighbour(new), newdev); + e = t3_l2t_get(tdev, new->neighbour, newdev); if (!e) { printk(KERN_ERR "%s: couldn't allocate new l2t entry!\n", __func__); @@ -1149,14 +1149,12 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new) if (te && te->ctx && te->client && te->client->redirect) { update_tcb = te->client->redirect(te->ctx, old, new, e); if (update_tcb) { - rcu_read_lock(); l2t_hold(L2DATA(tdev), e); - rcu_read_unlock(); set_l2t_ix(tdev, tid, e); } } } - l2t_release(tdev, e); + l2t_release(L2DATA(tdev), e); } /* @@ -1269,7 +1267,7 @@ int cxgb3_offload_activate(struct adapter *adapter) goto out_free; err = -ENOMEM; - RCU_INIT_POINTER(dev->l2opt, t3_init_l2t(l2t_capacity)); + L2DATA(dev) = t3_init_l2t(l2t_capacity); if (!L2DATA(dev)) goto out_free; @@ -1303,24 +1301,16 @@ int cxgb3_offload_activate(struct adapter *adapter) out_free_l2t: t3_free_l2t(L2DATA(dev)); - rcu_assign_pointer(dev->l2opt, NULL); + L2DATA(dev) = NULL; out_free: kfree(t); return err; } -static void clean_l2_data(struct rcu_head *head) -{ - struct l2t_data *d = container_of(head, struct l2t_data, rcu_head); - t3_free_l2t(d); -} - - void cxgb3_offload_deactivate(struct adapter *adapter) { struct t3cdev *tdev = &adapter->tdev; struct t3c_data *t = T3C_DATA(tdev); - struct l2t_data *d; remove_adapter(adapter); if (list_empty(&adapter_list)) @@ -1328,11 +1318,8 @@ void cxgb3_offload_deactivate(struct adapter *adapter) free_tid_maps(&t->tid_maps); T3C_DATA(tdev) = NULL; - rcu_read_lock(); - d = L2DATA(tdev); - rcu_read_unlock(); - rcu_assign_pointer(tdev->l2opt, NULL); - call_rcu(&d->rcu_head, clean_l2_data); + t3_free_l2t(L2DATA(tdev)); + L2DATA(tdev) = NULL; if (t->nofail_skb) kfree_skb(t->nofail_skb); kfree(t); diff --git a/drivers/net/cxgb3/l2t.c b/drivers/net/cxgb3/l2t.c index 41540978a173..f452c4003253 100644 --- a/drivers/net/cxgb3/l2t.c +++ b/drivers/net/cxgb3/l2t.c @@ -300,21 +300,14 @@ static inline void reuse_entry(struct l2t_entry *e, struct neighbour *neigh) struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh, struct net_device *dev) { - struct l2t_entry *e = NULL; - struct l2t_data *d; - int hash; + struct l2t_entry *e; + struct l2t_data *d = L2DATA(cdev); u32 addr = *(u32 *) neigh->primary_key; int ifidx = neigh->dev->ifindex; + int hash = arp_hash(addr, ifidx, d); struct port_info *p = netdev_priv(dev); int smt_idx = p->port_id; - rcu_read_lock(); - d = L2DATA(cdev); - if (!d) - goto done_rcu; - - hash = arp_hash(addr, ifidx, d); - write_lock_bh(&d->lock); for (e = d->l2tab[hash].first; e; e = e->next) if (e->addr == addr && e->ifindex == ifidx && @@ -345,8 +338,6 @@ struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh, } done: write_unlock_bh(&d->lock); -done_rcu: - rcu_read_unlock(); return e; } diff --git a/drivers/net/cxgb3/l2t.h b/drivers/net/cxgb3/l2t.h index c4dd06689ee4..fd3eb07e3f40 100644 --- a/drivers/net/cxgb3/l2t.h +++ b/drivers/net/cxgb3/l2t.h @@ -76,7 +76,6 @@ struct l2t_data { atomic_t nfree; /* number of free entries */ rwlock_t lock; struct l2t_entry l2tab[0]; - struct rcu_head rcu_head; /* to handle rcu cleanup */ }; typedef void (*arp_failure_handler_func)(struct t3cdev * dev, @@ -100,7 +99,7 @@ static inline void set_arp_failure_handler(struct sk_buff *skb, /* * Getting to the L2 data from an offload device. */ -#define L2DATA(cdev) (rcu_dereference((cdev)->l2opt)) +#define L2DATA(dev) ((dev)->l2opt) #define W_TCB_L2T_IX 0 #define S_TCB_L2T_IX 7 @@ -127,22 +126,15 @@ static inline int l2t_send(struct t3cdev *dev, struct sk_buff *skb, return t3_l2t_send_slow(dev, skb, e); } -static inline void l2t_release(struct t3cdev *t, struct l2t_entry *e) +static inline void l2t_release(struct l2t_data *d, struct l2t_entry *e) { - struct l2t_data *d; - - rcu_read_lock(); - d = L2DATA(t); - - if (atomic_dec_and_test(&e->refcnt) && d) + if (atomic_dec_and_test(&e->refcnt)) t3_l2e_free(d, e); - - rcu_read_unlock(); } static inline void l2t_hold(struct l2t_data *d, struct l2t_entry *e) { - if (d && atomic_add_return(1, &e->refcnt) == 1) /* 0 -> 1 transition */ + if (atomic_add_return(1, &e->refcnt) == 1) /* 0 -> 1 transition */ atomic_dec(&d->nfree); } diff --git a/drivers/net/davinci_cpdma.c b/drivers/net/davinci_cpdma.c index 6b67c526c461..ae47f23ba930 100644 --- a/drivers/net/davinci_cpdma.c +++ b/drivers/net/davinci_cpdma.c @@ -849,7 +849,6 @@ int cpdma_chan_stop(struct cpdma_chan *chan) next_dma = desc_read(desc, hw_next); chan->head = desc_from_phys(pool, next_dma); - chan->count--; chan->stats.teardown_dequeue++; /* issue callback without locks held */ diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index e5efe3aec0f4..dcc4a170b0f3 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -1008,7 +1008,7 @@ static void emac_rx_handler(void *token, int len, int status) int ret; /* free and bail if we are shutting down */ - if (unlikely(!netif_running(ndev))) { + if (unlikely(!netif_running(ndev) || !netif_carrier_ok(ndev))) { dev_kfree_skb_any(skb); return; } @@ -1037,9 +1037,7 @@ static void emac_rx_handler(void *token, int len, int status) recycle: ret = cpdma_chan_submit(priv->rxchan, skb, skb->data, skb_tailroom(skb), GFP_KERNEL); - - WARN_ON(ret == -ENOMEM); - if (unlikely(ret < 0)) + if (WARN_ON(ret < 0)) dev_kfree_skb_any(skb); } diff --git a/drivers/net/davinci_mdio.c b/drivers/net/davinci_mdio.c index f470ab64b093..7615040df756 100644 --- a/drivers/net/davinci_mdio.c +++ b/drivers/net/davinci_mdio.c @@ -181,11 +181,6 @@ static inline int wait_for_user_access(struct davinci_mdio_data *data) __davinci_mdio_reset(data); return -EAGAIN; } - - reg = __raw_readl(®s->user[0].access); - if ((reg & USERACCESS_GO) == 0) - return 0; - dev_err(data->dev, "timed out waiting for user access\n"); return -ETIMEDOUT; } diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index 098ff315694f..39cf9b9bd673 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -37,7 +37,6 @@ #include #include #include -#include static int numdummies = 1; @@ -107,14 +106,14 @@ static int dummy_dev_init(struct net_device *dev) return 0; } -static void dummy_dev_uninit(struct net_device *dev) +static void dummy_dev_free(struct net_device *dev) { free_percpu(dev->dstats); + free_netdev(dev); } static const struct net_device_ops dummy_netdev_ops = { .ndo_init = dummy_dev_init, - .ndo_uninit = dummy_dev_uninit, .ndo_start_xmit = dummy_xmit, .ndo_validate_addr = eth_validate_addr, .ndo_set_multicast_list = set_multicast_list, @@ -128,7 +127,7 @@ static void dummy_setup(struct net_device *dev) /* Initialize the device structure. */ dev->netdev_ops = &dummy_netdev_ops; - dev->destructor = free_netdev; + dev->destructor = dummy_dev_free; /* Fill in device structure with ethernet-generic values. */ dev->tx_queue_len = 0; @@ -187,10 +186,8 @@ static int __init dummy_init_module(void) rtnl_lock(); err = __rtnl_link_register(&dummy_link_ops); - for (i = 0; i < numdummies && !err; i++) { + for (i = 0; i < numdummies && !err; i++) err = dummy_init_one(); - cond_resched(); - } if (err < 0) __rtnl_link_unregister(&dummy_link_ops); rtnl_unlock(); diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 2c71884eb46e..8676899120c3 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -150,8 +150,6 @@ struct e1000_buffer { unsigned long time_stamp; u16 length; u16 next_to_watch; - unsigned int segs; - unsigned int bytecount; u16 mapped_as_page; }; diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index f17aaa1bd71d..7501d977d992 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c @@ -4028,12 +4028,6 @@ s32 e1000_validate_eeprom_checksum(struct e1000_hw *hw) checksum += eeprom_data; } -#ifdef CONFIG_PARISC - /* This is a signature and not a checksum on HP c8000 */ - if ((hw->subsystem_vendor_id == 0x103C) && (eeprom_data == 0x16d6)) - return E1000_SUCCESS; - -#endif if (checksum == (u16) EEPROM_SUM) return E1000_SUCCESS; else { diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 99525f9b41b6..76e8af00d86d 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -2798,7 +2798,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, struct e1000_buffer *buffer_info; unsigned int len = skb_headlen(skb); unsigned int offset = 0, size, count = 0, i; - unsigned int f, bytecount, segs; + unsigned int f; i = tx_ring->next_to_use; @@ -2899,13 +2899,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, } } - segs = skb_shinfo(skb)->gso_segs ?: 1; - /* multiply data chunks by size of headers */ - bytecount = ((segs - 1) * skb_headlen(skb)) + skb->len; - tx_ring->buffer_info[i].skb = skb; - tx_ring->buffer_info[i].segs = segs; - tx_ring->buffer_info[i].bytecount = bytecount; tx_ring->buffer_info[first].next_to_watch = i; return count; @@ -3579,8 +3573,14 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, cleaned = (i == eop); if (cleaned) { - total_tx_packets += buffer_info->segs; - total_tx_bytes += buffer_info->bytecount; + struct sk_buff *skb = buffer_info->skb; + unsigned int segs, bytecount; + segs = skb_shinfo(skb)->gso_segs ?: 1; + /* multiply data chunks by size of headers */ + bytecount = ((segs - 1) * skb_headlen(skb)) + + skb->len; + total_tx_packets += segs; + total_tx_bytes += bytecount; } e1000_unmap_and_free_tx_resource(adapter, buffer_info); tx_desc->upper.data = 0; diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 8402d19d3d62..8295f2192439 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -1573,9 +1573,6 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) ctrl = er32(CTRL); status = er32(STATUS); rxcw = er32(RXCW); - /* SYNCH bit and IV bit are sticky */ - udelay(10); - rxcw = er32(RXCW); if ((rxcw & E1000_RXCW_SYNCH) && !(rxcw & E1000_RXCW_IV)) { @@ -1602,8 +1599,10 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) * auto-negotiation in the TXCW register and disable * forced link in the Device Control register in an * attempt to auto-negotiate with our link partner. + * If the partner code word is null, stop forcing + * and restart auto negotiation. */ - if (rxcw & E1000_RXCW_C) { + if ((rxcw & E1000_RXCW_C) || !(rxcw & E1000_RXCW_CW)) { /* Enable autoneg, and unforce link up */ ew32(TXCW, mac->txcw); ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); @@ -2088,8 +2087,7 @@ struct e1000_info e1000_82574_info = { | FLAG_HAS_AMT | FLAG_HAS_CTRLEXT_ON_LOAD, .flags2 = FLAG2_CHECK_PHY_HANG - | FLAG2_DISABLE_ASPM_L0S - | FLAG2_DISABLE_ASPM_L1, + | FLAG2_DISABLE_ASPM_L0S, .pba = 32, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_82571, diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 8a265f3528de..9549879e66a0 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -311,7 +311,6 @@ struct e1000_adapter { u32 txd_cmd; bool detect_tx_hung; - bool tx_hang_recheck; u8 tx_timeout_factor; u32 tx_int_delay; diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index ee77b94834d0..3369d1f6a39c 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -137,9 +137,8 @@ #define HV_PM_CTRL PHY_REG(770, 17) /* PHY Low Power Idle Control */ -#define I82579_LPI_CTRL PHY_REG(772, 20) -#define I82579_LPI_CTRL_ENABLE_MASK 0x6000 -#define I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT 0x80 +#define I82579_LPI_CTRL PHY_REG(772, 20) +#define I82579_LPI_CTRL_ENABLE_MASK 0x6000 /* EMI Registers */ #define I82579_EMI_ADDR 0x10 @@ -1612,7 +1611,6 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw) s32 ret_val = 0; u16 status_reg = 0; u32 mac_reg; - u16 phy_reg; if (hw->mac.type != e1000_pch2lan) goto out; @@ -1627,19 +1625,12 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw) mac_reg = er32(FEXTNVM4); mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK; - ret_val = e1e_rphy(hw, I82579_LPI_CTRL, &phy_reg); - if (ret_val) - goto out; - - if (status_reg & HV_M_STATUS_SPEED_1000) { + if (status_reg & HV_M_STATUS_SPEED_1000) mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC; - phy_reg &= ~I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT; - } else { + else mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC; - phy_reg |= I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT; - } + ew32(FEXTNVM4, mac_reg); - ret_val = e1e_wphy(hw, I82579_LPI_CTRL, phy_reg); } out: diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index 8d2860232214..dd8ab05b5590 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -190,8 +190,7 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) /* Check for LOM (vs. NIC) or one of two valid mezzanine cards */ if (!((nvm_data & NVM_COMPAT_LOM) || (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_DUAL) || - (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD) || - (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES))) + (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD))) goto out; ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 5430a9a4a28c..3310c3d477d7 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -930,7 +930,6 @@ static void e1000_print_hw_hang(struct work_struct *work) struct e1000_adapter *adapter = container_of(work, struct e1000_adapter, print_hang_task); - struct net_device *netdev = adapter->netdev; struct e1000_ring *tx_ring = adapter->tx_ring; unsigned int i = tx_ring->next_to_clean; unsigned int eop = tx_ring->buffer_info[i].next_to_watch; @@ -942,21 +941,6 @@ static void e1000_print_hw_hang(struct work_struct *work) if (test_bit(__E1000_DOWN, &adapter->state)) return; - if (!adapter->tx_hang_recheck && - (adapter->flags2 & FLAG2_DMA_BURST)) { - /* May be block on write-back, flush and detect again - * flush pending descriptor writebacks to memory - */ - ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); - /* execute the writes immediately */ - e1e_flush(); - adapter->tx_hang_recheck = true; - return; - } - /* Real hang detected */ - adapter->tx_hang_recheck = false; - netif_stop_queue(netdev); - e1e_rphy(hw, PHY_STATUS, &phy_status); e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status); e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status); @@ -1070,10 +1054,10 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) if (tx_ring->buffer_info[i].time_stamp && time_after(jiffies, tx_ring->buffer_info[i].time_stamp + (adapter->tx_timeout_factor * HZ)) && - !(er32(STATUS) & E1000_STATUS_TXOFF)) + !(er32(STATUS) & E1000_STATUS_TXOFF)) { schedule_work(&adapter->print_hang_task); - else - adapter->tx_hang_recheck = false; + netif_stop_queue(netdev); + } } adapter->total_tx_bytes += total_tx_bytes; adapter->total_tx_packets += total_tx_packets; @@ -3694,7 +3678,6 @@ static int e1000_open(struct net_device *netdev) e1000_irq_enable(adapter); - adapter->tx_hang_recheck = false; netif_start_queue(netdev); adapter->idle_check = true; diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 51fba5fe94bd..2f433fbfca0c 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1718,12 +1718,8 @@ static void enic_poll_controller(struct net_device *netdev) enic_isr_msix_rq(enic->msix_entry[intr].vector, &enic->napi[i]); } - - for (i = 0; i < enic->wq_count; i++) { - intr = enic_msix_wq_intr(enic, i); - enic_isr_msix_wq(enic->msix_entry[intr].vector, enic); - } - + intr = enic_msix_wq_intr(enic, i); + enic_isr_msix_wq(enic->msix_entry[intr].vector, enic); break; case VNIC_DEV_INTR_MODE_MSI: enic_isr_msi(enic->pdev->irq, enic); diff --git a/drivers/net/gianfar_ptp.c b/drivers/net/gianfar_ptp.c index c4134790d684..d8e175382d1d 100644 --- a/drivers/net/gianfar_ptp.c +++ b/drivers/net/gianfar_ptp.c @@ -193,9 +193,14 @@ static void set_alarm(struct etsects *etsects) /* Caller must hold etsects->lock. */ static void set_fipers(struct etsects *etsects) { - set_alarm(etsects); + u32 tmr_ctrl = gfar_read(&etsects->regs->tmr_ctrl); + + gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl & (~TE)); + gfar_write(&etsects->regs->tmr_prsc, etsects->tmr_prsc); gfar_write(&etsects->regs->tmr_fiper1, etsects->tmr_fiper1); gfar_write(&etsects->regs->tmr_fiper2, etsects->tmr_fiper2); + set_alarm(etsects); + gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl|TE); } /* @@ -506,7 +511,7 @@ static int gianfar_ptp_probe(struct platform_device *dev) gfar_write(&etsects->regs->tmr_fiper1, etsects->tmr_fiper1); gfar_write(&etsects->regs->tmr_fiper2, etsects->tmr_fiper2); set_alarm(etsects); - gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl|FS|RTPE|TE|FRD); + gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl|FS|RTPE|TE); spin_unlock_irqrestore(&etsects->lock, flags); diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 145c924e278f..b388d782c7c4 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -394,7 +394,7 @@ static inline struct sk_buff *ibmveth_rxq_get_buffer(struct ibmveth_adapter *ada } /* recycle the current buffer on the rx queue */ -static int ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) +static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) { u32 q_index = adapter->rx_queue.index; u64 correlator = adapter->rx_queue.queue_addr[q_index].correlator; @@ -402,7 +402,6 @@ static int ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) unsigned int index = correlator & 0xffffffffUL; union ibmveth_buf_desc desc; unsigned long lpar_rc; - int ret = 1; BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS); BUG_ON(index >= adapter->rx_buff_pool[pool].size); @@ -410,7 +409,7 @@ static int ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) if (!adapter->rx_buff_pool[pool].active) { ibmveth_rxq_harvest_buffer(adapter); ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[pool]); - goto out; + return; } desc.fields.flags_len = IBMVETH_BUF_VALID | @@ -423,16 +422,12 @@ static int ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) netdev_dbg(adapter->netdev, "h_add_logical_lan_buffer failed " "during recycle rc=%ld", lpar_rc); ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator); - ret = 0; } if (++adapter->rx_queue.index == adapter->rx_queue.num_slots) { adapter->rx_queue.index = 0; adapter->rx_queue.toggle = !adapter->rx_queue.toggle; } - -out: - return ret; } static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter) @@ -811,7 +806,7 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data) } else adapter->fw_ipv6_csum_support = data; - if (ret == H_SUCCESS || ret6 == H_SUCCESS) + if (ret != H_SUCCESS || ret6 != H_SUCCESS) adapter->rx_csum = data; else rc1 = -EIO; @@ -929,7 +924,6 @@ static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb, union ibmveth_buf_desc descs[6]; int last, i; int force_bounce = 0; - dma_addr_t dma_addr; /* * veth handles a maximum of 6 segments including the header, so @@ -994,16 +988,17 @@ retry_bounce: } /* Map the header */ - dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, - skb_headlen(skb), DMA_TO_DEVICE); - if (dma_mapping_error(&adapter->vdev->dev, dma_addr)) + descs[0].fields.address = dma_map_single(&adapter->vdev->dev, skb->data, + skb_headlen(skb), + DMA_TO_DEVICE); + if (dma_mapping_error(&adapter->vdev->dev, descs[0].fields.address)) goto map_failed; descs[0].fields.flags_len = desc_flags | skb_headlen(skb); - descs[0].fields.address = dma_addr; /* Map the frags */ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + unsigned long dma_addr; skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; dma_addr = dma_map_page(&adapter->vdev->dev, frag->page, @@ -1025,12 +1020,7 @@ retry_bounce: netdev->stats.tx_bytes += skb->len; } - dma_unmap_single(&adapter->vdev->dev, - descs[0].fields.address, - descs[0].fields.flags_len & IBMVETH_BUF_LEN_MASK, - DMA_TO_DEVICE); - - for (i = 1; i < skb_shinfo(skb)->nr_frags + 1; i++) + for (i = 0; i < skb_shinfo(skb)->nr_frags + 1; i++) dma_unmap_page(&adapter->vdev->dev, descs[i].fields.address, descs[i].fields.flags_len & IBMVETH_BUF_LEN_MASK, DMA_TO_DEVICE); @@ -1093,9 +1083,8 @@ restart_poll: if (rx_flush) ibmveth_flush_buffer(skb->data, length + offset); - if (!ibmveth_rxq_recycle_buffer(adapter)) - kfree_skb(skb); skb = new_skb; + ibmveth_rxq_recycle_buffer(adapter); } else { ibmveth_rxq_harvest_buffer(adapter); skb_reserve(skb, offset); diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 2b98461cb727..4fecaed67fc4 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -145,7 +145,7 @@ static void ifb_setup(struct net_device *dev) dev->flags |= IFF_NOARP; dev->flags &= ~IFF_MULTICAST; - dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); + dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; random_ether_addr(dev->dev_addr); } diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 493e331d7064..0f563c8c5ffc 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -1735,7 +1735,6 @@ static s32 igb_reset_hw_82580(struct e1000_hw *hw) ctrl |= E1000_CTRL_RST; wr32(E1000_CTRL, ctrl); - wrfl(); /* Add delay to insure DEV_RST has time to complete */ if (global_device_reset) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index a5d98a348a83..2c28621eb30b 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1985,7 +1985,7 @@ static int __devinit igb_probe(struct pci_dev *pdev, if (hw->bus.func == 0) hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data); - else if (hw->mac.type >= e1000_82580) + else if (hw->mac.type == e1000_82580) hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A + NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1, &eeprom_data); @@ -4521,13 +4521,11 @@ void igb_update_stats(struct igb_adapter *adapter, bytes = 0; packets = 0; for (i = 0; i < adapter->num_rx_queues; i++) { - u32 rqdpc = rd32(E1000_RQDPC(i)); + u32 rqdpc_tmp = rd32(E1000_RQDPC(i)) & 0x0FFF; struct igb_ring *ring = adapter->rx_ring[i]; - if (rqdpc) { - ring->rx_stats.drops += rqdpc; - net_stats->rx_fifo_errors += rqdpc; - } + ring->rx_stats.drops += rqdpc_tmp; + net_stats->rx_fifo_errors += rqdpc_tmp; do { start = u64_stats_fetch_begin_bh(&ring->rx_syncp); diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index ddec154f1b6e..efe05bb34dd8 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c @@ -221,7 +221,7 @@ static void sirdev_config_fsm(struct work_struct *work) break; case SIRDEV_STATE_DONGLE_SPEED: - if (dev->dongle_drv->set_speed) { + if (dev->dongle_drv->reset) { ret = dev->dongle_drv->set_speed(dev, fsm->param); if (ret < 0) { fsm->result = ret; diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 6a4826ad6e31..8800e1fe4129 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -515,7 +515,7 @@ static const struct net_device_ops smsc_ircc_netdev_ops = { * Try to open driver instance * */ -static int __devinit smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq) +static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq) { struct smsc_ircc_cb *self; struct net_device *dev; diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 4adce71a2663..8ee661245af3 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -360,8 +360,6 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw) case IXGBE_DEV_ID_82599_SFP_FCOE: case IXGBE_DEV_ID_82599_SFP_EM: case IXGBE_DEV_ID_82599_SFP_SF2: - case IXGBE_DEV_ID_82599EN_SFP: - case IXGBE_DEV_ID_82599_SFP_SF_QP: media_type = ixgbe_media_type_fiber; break; case IXGBE_DEV_ID_82599_CX4: diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 864403da9cd5..b894b42a741c 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -3181,7 +3181,6 @@ static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) switch (hw->device_id) { case IXGBE_DEV_ID_X540T: - case IXGBE_DEV_ID_X540T1: return 0; case IXGBE_DEV_ID_82599_T3_LOM: return 0; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index f0b0ff36e50d..08e8e25c159d 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -129,12 +129,6 @@ static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = { board_82599 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_LS), board_82599 }, - {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599EN_SFP), - board_82599 }, - {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF_QP), - board_82599 }, - {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T1), - board_X540 }, /* required last entry */ {0, } @@ -1372,8 +1366,8 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, if (ring_is_rsc_enabled(rx_ring)) pkt_is_rsc = ixgbe_get_rsc_state(rx_desc); - /* linear means we are building an skb from multiple pages */ - if (!skb_is_nonlinear(skb)) { + /* if this is a skb from previous receive DMA will be 0 */ + if (rx_buffer_info->dma) { u16 hlen; if (pkt_is_rsc && !(staterr & IXGBE_RXD_STAT_EOP) && diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 1ea15776837d..fa43f2507f43 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -59,14 +59,11 @@ #define IXGBE_SUBDEV_ID_82599_SFP 0x11A9 #define IXGBE_DEV_ID_82599_SFP_EM 0x1507 #define IXGBE_DEV_ID_82599_SFP_SF2 0x154D -#define IXGBE_DEV_ID_82599EN_SFP 0x1557 #define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC #define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8 #define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C #define IXGBE_DEV_ID_82599_LS 0x154F -#define IXGBE_DEV_ID_82599_SFP_SF_QP 0x154A #define IXGBE_DEV_ID_X540T 0x1528 -#define IXGBE_DEV_ID_X540T1 0x1560 /* General Registers */ #define IXGBE_CTRL 0x00000 diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 1d1ccec60728..b5b174a8c149 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -753,28 +753,20 @@ jme_make_new_rx_buf(struct jme_adapter *jme, int i) struct jme_ring *rxring = &(jme->rxring[0]); struct jme_buffer_info *rxbi = rxring->bufinf + i; struct sk_buff *skb; - dma_addr_t mapping; skb = netdev_alloc_skb(jme->dev, jme->dev->mtu + RX_EXTRA_LEN); if (unlikely(!skb)) return -ENOMEM; - mapping = pci_map_page(jme->pdev, virt_to_page(skb->data), - offset_in_page(skb->data), skb_tailroom(skb), - PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(jme->pdev, mapping))) { - dev_kfree_skb(skb); - return -ENOMEM; - } - - if (likely(rxbi->mapping)) - pci_unmap_page(jme->pdev, rxbi->mapping, - rxbi->len, PCI_DMA_FROMDEVICE); - rxbi->skb = skb; rxbi->len = skb_tailroom(skb); - rxbi->mapping = mapping; + rxbi->mapping = pci_map_page(jme->pdev, + virt_to_page(skb->data), + offset_in_page(skb->data), + rxbi->len, + PCI_DMA_FROMDEVICE); + return 0; } @@ -2228,11 +2220,19 @@ jme_change_mtu(struct net_device *netdev, int new_mtu) ((new_mtu) < IPV6_MIN_MTU)) return -EINVAL; + if (new_mtu > 4000) { + jme->reg_rxcs &= ~RXCS_FIFOTHNP; + jme->reg_rxcs |= RXCS_FIFOTHNP_64QW; + jme_restart_rx_engine(jme); + } else { + jme->reg_rxcs &= ~RXCS_FIFOTHNP; + jme->reg_rxcs |= RXCS_FIFOTHNP_128QW; + jme_restart_rx_engine(jme); + } netdev->mtu = new_mtu; netdev_update_features(netdev); - jme_restart_rx_engine(jme); jme_reset_link(jme); return 0; diff --git a/drivers/net/jme.h b/drivers/net/jme.h index fff885e9274e..e9aaeca96abc 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h @@ -734,7 +734,7 @@ enum jme_rxcs_values { RXCS_RETRYCNT_60 = 0x00000F00, RXCS_DEFAULT = RXCS_FIFOTHTP_128T | - RXCS_FIFOTHNP_16QW | + RXCS_FIFOTHNP_128QW | RXCS_DMAREQSZ_128B | RXCS_RETRYGAP_256ns | RXCS_RETRYCNT_32, diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c index 3eacbb4fff9a..61631cace913 100644 --- a/drivers/net/ks8851_mll.c +++ b/drivers/net/ks8851_mll.c @@ -38,7 +38,7 @@ #define DRV_NAME "ks8851_mll" static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x86, 0x95, 0x11 }; -#define MAX_RECV_FRAMES 255 +#define MAX_RECV_FRAMES 32 #define MAX_BUF_SIZE 2048 #define TX_BUF_SIZE 2000 #define RX_BUF_SIZE 2000 diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c index 95b6664e9366..41ea5920c158 100644 --- a/drivers/net/ksz884x.c +++ b/drivers/net/ksz884x.c @@ -5679,7 +5679,7 @@ static int netdev_set_mac_address(struct net_device *dev, void *addr) memcpy(hw->override_addr, mac->sa_data, MAC_ADDR_LEN); } - memcpy(dev->dev_addr, mac->sa_data, ETH_ALEN); + memcpy(dev->dev_addr, mac->sa_data, MAX_ADDR_LEN); interrupt = hw_block_intr(hw); diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index d0893e4c9330..4ce9e5f2c069 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -78,11 +78,6 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb, skb_orphan(skb); - /* Before queueing this packet to netif_rx(), - * make sure dst is refcounted. - */ - skb_dst_force(skb); - skb->protocol = eth_type_trans(skb, dev); /* it's OK to use per_cpu_ptr() because BHs are off */ diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 735f726729d9..d6aeaa5f25ea 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -239,7 +239,7 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) dest = macvlan_hash_lookup(port, eth->h_dest); if (dest && dest->mode == MACVLAN_MODE_BRIDGE) { /* send to lowerdev first for its network taps */ - dev_forward_skb(vlan->lowerdev, skb); + vlan->forward(vlan->lowerdev, skb); return NET_XMIT_SUCCESS; } @@ -247,7 +247,7 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) xmit_world: skb->ip_summed = ip_summed; - skb->dev = vlan->lowerdev; + skb_set_dev(skb, vlan->lowerdev); return dev_queue_xmit(skb); } @@ -547,7 +547,7 @@ void macvlan_common_setup(struct net_device *dev) { ether_setup(dev); - dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); + dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; dev->netdev_ops = &macvlan_netdev_ops; dev->destructor = free_netdev; dev->header_ops = &macvlan_hard_header_ops, diff --git a/drivers/net/ne.c b/drivers/net/ne.c index e8ee2bc30bab..1063093b3afc 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -814,7 +814,6 @@ static int __init ne_drv_probe(struct platform_device *pdev) dev->irq = irq[this_dev]; dev->mem_end = bad[this_dev]; } - SET_NETDEV_DEV(dev, &pdev->dev); err = do_ne_probe(dev); if (err) { free_netdev(dev); diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 4309296e8650..dfc82720065a 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -307,11 +307,6 @@ static ssize_t store_enabled(struct netconsole_target *nt, return err; if (enabled < 0 || enabled > 1) return -EINVAL; - if (enabled == nt->enabled) { - printk(KERN_INFO "netconsole: network logging has already %s\n", - nt->enabled ? "started" : "stopped"); - return -EINVAL; - } if (enabled) { /* 1 */ @@ -652,6 +647,7 @@ static int netconsole_netdev_event(struct notifier_block *this, flags); dev_put(nt->np.dev); nt->np.dev = NULL; + netconsole_target_put(nt); } nt->enabled = 0; stopped = true; diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 78d5b674757b..c0788a31ff0f 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1288,10 +1288,6 @@ static void netxen_mask_aer_correctable(struct netxen_adapter *adapter) struct pci_dev *root = pdev->bus->self; u32 aer_pos; - /* root bus? */ - if (!root) - return; - if (adapter->ahw.board_type != NETXEN_BRDTYPE_P3_4_GB_MM && adapter->ahw.board_type != NETXEN_BRDTYPE_P3_10G_TP) return; diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 2f8c351b1173..cc25bff0bd3b 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -9196,7 +9196,7 @@ static int __devinit niu_ldg_init(struct niu *np) first_chan = 0; for (i = 0; i < port; i++) - first_chan += parent->rxchan_per_port[i]; + first_chan += parent->rxchan_per_port[port]; num_chan = parent->rxchan_per_port[port]; for (i = first_chan; i < (first_chan + num_chan); i++) { @@ -9212,7 +9212,7 @@ static int __devinit niu_ldg_init(struct niu *np) first_chan = 0; for (i = 0; i < port; i++) - first_chan += parent->txchan_per_port[i]; + first_chan += parent->txchan_per_port[port]; num_chan = parent->txchan_per_port[port]; for (i = first_chan; i < (first_chan + num_chan); i++) { err = niu_ldg_assign_ldn(np, parent, diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index 236d00ec64cc..eac3c5ca9731 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c @@ -39,9 +39,6 @@ const char pch_driver_version[] = DRV_VERSION; #define PCI_VENDOR_ID_ROHM 0x10db #define PCI_DEVICE_ID_ROHM_ML7223_GBE 0x8013 -/* Macros for ML7831 */ -#define PCI_DEVICE_ID_ROHM_ML7831_GBE 0x8802 - #define PCH_GBE_TX_WEIGHT 64 #define PCH_GBE_RX_WEIGHT 64 #define PCH_GBE_RX_BUFFER_WRITE 16 @@ -720,6 +717,13 @@ static void pch_gbe_configure_rx(struct pch_gbe_adapter *adapter) iowrite32(rdba, &hw->reg->RX_DSC_BASE); iowrite32(rdlen, &hw->reg->RX_DSC_SIZE); iowrite32((rdba + rdlen), &hw->reg->RX_DSC_SW_P); + + /* Enables Receive DMA */ + rxdma = ioread32(&hw->reg->DMA_CTRL); + rxdma |= PCH_GBE_RX_DMA_EN; + iowrite32(rxdma, &hw->reg->DMA_CTRL); + /* Enables Receive */ + iowrite32(PCH_GBE_MRE_MAC_RX_EN, &hw->reg->MAC_RX_EN); } /** @@ -1093,19 +1097,6 @@ void pch_gbe_update_stats(struct pch_gbe_adapter *adapter) spin_unlock_irqrestore(&adapter->stats_lock, flags); } -static void pch_gbe_start_receive(struct pch_gbe_hw *hw) -{ - u32 rxdma; - - /* Enables Receive DMA */ - rxdma = ioread32(&hw->reg->DMA_CTRL); - rxdma |= PCH_GBE_RX_DMA_EN; - iowrite32(rxdma, &hw->reg->DMA_CTRL); - /* Enables Receive */ - iowrite32(PCH_GBE_MRE_MAC_RX_EN, &hw->reg->MAC_RX_EN); - return; -} - /** * pch_gbe_intr - Interrupt Handler * @irq: Interrupt number @@ -1710,12 +1701,6 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter) struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring; int err; - /* Ensure we have a valid MAC */ - if (!is_valid_ether_addr(adapter->hw.mac.addr)) { - pr_err("Error: Invalid MAC address\n"); - return -EINVAL; - } - /* hardware has been reset, we need to reload some things */ pch_gbe_set_multi(netdev); @@ -1732,7 +1717,6 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter) pch_gbe_alloc_tx_buffers(adapter, tx_ring); pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count); adapter->tx_queue_len = netdev->tx_queue_len; - pch_gbe_start_receive(&adapter->hw); mod_timer(&adapter->watchdog_timer, jiffies); @@ -2134,7 +2118,7 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget) /* If no Tx and not enough Rx work done, * exit the polling mode */ - if (work_done < budget) + if ((work_done < budget) || !netif_running(netdev)) poll_end_flag = true; } @@ -2408,14 +2392,9 @@ static int pch_gbe_probe(struct pci_dev *pdev, memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len); if (!is_valid_ether_addr(netdev->dev_addr)) { - /* - * If the MAC is invalid (or just missing), display a warning - * but do not abort setting up the device. pch_gbe_up will - * prevent the interface from being brought up until a valid MAC - * is set. - */ - dev_err(&pdev->dev, "Invalid MAC address, " - "interface disabled.\n"); + dev_err(&pdev->dev, "Invalid MAC Address\n"); + ret = -EIO; + goto err_free_adapter; } setup_timer(&adapter->watchdog_timer, pch_gbe_watchdog, (unsigned long)adapter); @@ -2473,13 +2452,6 @@ static DEFINE_PCI_DEVICE_TABLE(pch_gbe_pcidev_id) = { .class = (PCI_CLASS_NETWORK_ETHERNET << 8), .class_mask = (0xFFFF00) }, - {.vendor = PCI_VENDOR_ID_ROHM, - .device = PCI_DEVICE_ID_ROHM_ML7831_GBE, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .class = (PCI_CLASS_NETWORK_ETHERNET << 8), - .class_mask = (0xFFFF00) - }, /* required last entry */ {0} }; diff --git a/drivers/net/pch_gbe/pch_gbe_param.c b/drivers/net/pch_gbe/pch_gbe_param.c index fb74ef9c81a2..5b5d90a47e29 100644 --- a/drivers/net/pch_gbe/pch_gbe_param.c +++ b/drivers/net/pch_gbe/pch_gbe_param.c @@ -320,10 +320,10 @@ static void pch_gbe_check_copper_options(struct pch_gbe_adapter *adapter) pr_debug("AutoNeg specified along with Speed or Duplex, AutoNeg parameter ignored\n"); hw->phy.autoneg_advertised = opt.def; } else { - int tmp = AutoNeg; - - pch_gbe_validate_option(&tmp, &opt, adapter); - hw->phy.autoneg_advertised = tmp; + hw->phy.autoneg_advertised = AutoNeg; + pch_gbe_validate_option( + (int *)(&hw->phy.autoneg_advertised), + &opt, adapter); } } @@ -494,10 +494,9 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter) .arg = { .l = { .nr = (int)ARRAY_SIZE(fc_list), .p = fc_list } } }; - int tmp = FlowControl; - - pch_gbe_validate_option(&tmp, &opt, adapter); - hw->mac.fc = tmp; + hw->mac.fc = FlowControl; + pch_gbe_validate_option((int *)(&hw->mac.fc), + &opt, adapter); } pch_gbe_check_copper_options(adapter); diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 364cd67bb70d..2cd8dc5847b4 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -34,7 +34,8 @@ #define PAGESEL 0x13 #define LAYER4 0x02 #define LAYER2 0x01 -#define MAX_RXTS 64 +#define MAX_RXTS 4 +#define MAX_TXTS 4 #define N_EXT_TS 1 #define PSF_PTPVER 2 #define PSF_EVNT 0x4000 @@ -217,7 +218,7 @@ static void phy2rxts(struct phy_rxts *p, struct rxts *rxts) rxts->seqid = p->seqid; rxts->msgtype = (p->msgtype >> 12) & 0xf; rxts->hash = p->msgtype & 0x0fff; - rxts->tmo = jiffies + 2; + rxts->tmo = jiffies + HZ; } static u64 phy2txts(struct phy_txts *p) @@ -875,7 +876,6 @@ static void dp83640_remove(struct phy_device *phydev) struct dp83640_clock *clock; struct list_head *this, *next; struct dp83640_private *tmp, *dp83640 = phydev->priv; - struct sk_buff *skb; if (phydev->addr == BROADCAST_ADDR) return; @@ -883,12 +883,6 @@ static void dp83640_remove(struct phy_device *phydev) enable_status_frames(phydev, false); cancel_work_sync(&dp83640->ts_work); - while ((skb = skb_dequeue(&dp83640->rx_queue)) != NULL) - kfree_skb(skb); - - while ((skb = skb_dequeue(&dp83640->tx_queue)) != NULL) - skb_complete_tx_timestamp(skb, NULL); - clock = dp83640_clock_get(dp83640->clock); if (dp83640 == clock->chosen) { @@ -1067,7 +1061,7 @@ static void dp83640_txtstamp(struct phy_device *phydev, struct dp83640_private *dp83640 = phydev->priv; if (!dp83640->hwts_tx_en) { - skb_complete_tx_timestamp(skb, NULL); + kfree_skb(skb); return; } skb_queue_tail(&dp83640->tx_queue, skb); diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 2843c90f712f..47c8339a0359 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -241,7 +241,7 @@ MODULE_DEVICE_TABLE(of, mdio_ofgpio_match); static struct platform_driver mdio_ofgpio_driver = { .driver = { - .name = "mdio-ofgpio", + .name = "mdio-gpio", .owner = THIS_MODULE, .of_match_table = mdio_ofgpio_match, }, diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index b890401cab93..4609bc0e2f56 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -968,6 +968,7 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev) proto = npindex_to_proto[npi]; put_unaligned_be16(proto, pp); + netif_stop_queue(dev); skb_queue_tail(&ppp->file.xq, skb); ppp_xmit_process(ppp); return NETDEV_TX_OK; @@ -1062,8 +1063,6 @@ ppp_xmit_process(struct ppp *ppp) code that we can accept some more. */ if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq)) netif_wake_queue(ppp->dev); - else - netif_stop_queue(ppp->dev); } ppp_xmit_unlock(ppp); } @@ -2020,22 +2019,14 @@ ppp_mp_reconstruct(struct ppp *ppp) continue; } if (PPP_MP_CB(p)->sequence != seq) { - u32 oldseq; /* Fragment `seq' is missing. If it is after minseq, it might arrive later, so stop here. */ if (seq_after(seq, minseq)) break; /* Fragment `seq' is lost, keep going. */ lost = 1; - oldseq = seq; seq = seq_before(minseq, PPP_MP_CB(p)->sequence)? minseq + 1: PPP_MP_CB(p)->sequence; - - if (ppp->debug & 1) - netdev_printk(KERN_DEBUG, ppp->dev, - "lost frag %u..%u\n", - oldseq, seq-1); - goto again; } @@ -2080,10 +2071,6 @@ ppp_mp_reconstruct(struct ppp *ppp) struct sk_buff *tmp2; skb_queue_reverse_walk_from_safe(list, p, tmp2) { - if (ppp->debug & 1) - netdev_printk(KERN_DEBUG, ppp->dev, - "discarding frag %u\n", - PPP_MP_CB(p)->sequence); __skb_unlink(p, list); kfree_skb(p); } @@ -2099,17 +2086,6 @@ ppp_mp_reconstruct(struct ppp *ppp) /* If we have discarded any fragments, signal a receive error. */ if (PPP_MP_CB(head)->sequence != ppp->nextseq) { - skb_queue_walk_safe(list, p, tmp) { - if (p == head) - break; - if (ppp->debug & 1) - netdev_printk(KERN_DEBUG, ppp->dev, - "discarding frag %u\n", - PPP_MP_CB(p)->sequence); - __skb_unlink(p, list); - kfree_skb(p); - } - if (ppp->debug & 1) netdev_printk(KERN_DEBUG, ppp->dev, " missed pkts %u..%u\n", diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 11615842a57b..bc9a4bb31980 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -576,7 +576,7 @@ static int pppoe_release(struct socket *sock) po = pppox_sk(sk); - if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) { + if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) { dev_put(po->pppoe_dev); po->pppoe_dev = NULL; } diff --git a/drivers/net/pppolac.c b/drivers/net/pppolac.c deleted file mode 100644 index c94b8507d92b..000000000000 --- a/drivers/net/pppolac.c +++ /dev/null @@ -1,449 +0,0 @@ -/* drivers/net/pppolac.c - * - * Driver for PPP on L2TP Access Concentrator / PPPoLAC Socket (RFC 2661) - * - * Copyright (C) 2009 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -/* This driver handles L2TP data packets between a UDP socket and a PPP channel. - * The socket must keep connected, and only one session per socket is permitted. - * Sequencing of outgoing packets is controlled by LNS. Incoming packets with - * sequences are reordered within a sliding window of one second. Currently - * reordering only happens when a packet is received. It is done for simplicity - * since no additional locks or threads are required. This driver only works on - * IPv4 due to the lack of UDP encapsulation support in IPv6. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define L2TP_CONTROL_BIT 0x80 -#define L2TP_LENGTH_BIT 0x40 -#define L2TP_SEQUENCE_BIT 0x08 -#define L2TP_OFFSET_BIT 0x02 -#define L2TP_VERSION 0x02 -#define L2TP_VERSION_MASK 0x0F - -#define PPP_ADDR 0xFF -#define PPP_CTRL 0x03 - -union unaligned { - __u32 u32; -} __attribute__((packed)); - -static inline union unaligned *unaligned(void *ptr) -{ - return (union unaligned *)ptr; -} - -struct meta { - __u32 sequence; - __u32 timestamp; -}; - -static inline struct meta *skb_meta(struct sk_buff *skb) -{ - return (struct meta *)skb->cb; -} - -/******************************************************************************/ - -static int pppolac_recv_core(struct sock *sk_udp, struct sk_buff *skb) -{ - struct sock *sk = (struct sock *)sk_udp->sk_user_data; - struct pppolac_opt *opt = &pppox_sk(sk)->proto.lac; - struct meta *meta = skb_meta(skb); - __u32 now = jiffies; - __u8 bits; - __u8 *ptr; - - /* Drop the packet if L2TP header is missing. */ - if (skb->len < sizeof(struct udphdr) + 6) - goto drop; - - /* Put it back if it is a control packet. */ - if (skb->data[sizeof(struct udphdr)] & L2TP_CONTROL_BIT) - return opt->backlog_rcv(sk_udp, skb); - - /* Skip UDP header. */ - skb_pull(skb, sizeof(struct udphdr)); - - /* Check the version. */ - if ((skb->data[1] & L2TP_VERSION_MASK) != L2TP_VERSION) - goto drop; - bits = skb->data[0]; - ptr = &skb->data[2]; - - /* Check the length if it is present. */ - if (bits & L2TP_LENGTH_BIT) { - if ((ptr[0] << 8 | ptr[1]) != skb->len) - goto drop; - ptr += 2; - } - - /* Skip all fields including optional ones. */ - if (!skb_pull(skb, 6 + (bits & L2TP_SEQUENCE_BIT ? 4 : 0) + - (bits & L2TP_LENGTH_BIT ? 2 : 0) + - (bits & L2TP_OFFSET_BIT ? 2 : 0))) - goto drop; - - /* Skip the offset padding if it is present. */ - if (bits & L2TP_OFFSET_BIT && - !skb_pull(skb, skb->data[-2] << 8 | skb->data[-1])) - goto drop; - - /* Check the tunnel and the session. */ - if (unaligned(ptr)->u32 != opt->local) - goto drop; - - /* Check the sequence if it is present. */ - if (bits & L2TP_SEQUENCE_BIT) { - meta->sequence = ptr[4] << 8 | ptr[5]; - if ((__s16)(meta->sequence - opt->recv_sequence) < 0) - goto drop; - } - - /* Skip PPP address and control if they are present. */ - if (skb->len >= 2 && skb->data[0] == PPP_ADDR && - skb->data[1] == PPP_CTRL) - skb_pull(skb, 2); - - /* Fix PPP protocol if it is compressed. */ - if (skb->len >= 1 && skb->data[0] & 1) - skb_push(skb, 1)[0] = 0; - - /* Drop the packet if PPP protocol is missing. */ - if (skb->len < 2) - goto drop; - - /* Perform reordering if sequencing is enabled. */ - atomic_set(&opt->sequencing, bits & L2TP_SEQUENCE_BIT); - if (bits & L2TP_SEQUENCE_BIT) { - struct sk_buff *skb1; - - /* Insert the packet into receive queue in order. */ - skb_set_owner_r(skb, sk); - skb_queue_walk(&sk->sk_receive_queue, skb1) { - struct meta *meta1 = skb_meta(skb1); - __s16 order = meta->sequence - meta1->sequence; - if (order == 0) - goto drop; - if (order < 0) { - meta->timestamp = meta1->timestamp; - skb_insert(skb1, skb, &sk->sk_receive_queue); - skb = NULL; - break; - } - } - if (skb) { - meta->timestamp = now; - skb_queue_tail(&sk->sk_receive_queue, skb); - } - - /* Remove packets from receive queue as long as - * 1. the receive buffer is full, - * 2. they are queued longer than one second, or - * 3. there are no missing packets before them. */ - skb_queue_walk_safe(&sk->sk_receive_queue, skb, skb1) { - meta = skb_meta(skb); - if (atomic_read(&sk->sk_rmem_alloc) < sk->sk_rcvbuf && - now - meta->timestamp < HZ && - meta->sequence != opt->recv_sequence) - break; - skb_unlink(skb, &sk->sk_receive_queue); - opt->recv_sequence = (__u16)(meta->sequence + 1); - skb_orphan(skb); - ppp_input(&pppox_sk(sk)->chan, skb); - } - return NET_RX_SUCCESS; - } - - /* Flush receive queue if sequencing is disabled. */ - skb_queue_purge(&sk->sk_receive_queue); - skb_orphan(skb); - ppp_input(&pppox_sk(sk)->chan, skb); - return NET_RX_SUCCESS; -drop: - kfree_skb(skb); - return NET_RX_DROP; -} - -static int pppolac_recv(struct sock *sk_udp, struct sk_buff *skb) -{ - sock_hold(sk_udp); - sk_receive_skb(sk_udp, skb, 0); - return 0; -} - -static struct sk_buff_head delivery_queue; - -static void pppolac_xmit_core(struct work_struct *delivery_work) -{ - mm_segment_t old_fs = get_fs(); - struct sk_buff *skb; - - set_fs(KERNEL_DS); - while ((skb = skb_dequeue(&delivery_queue))) { - struct sock *sk_udp = skb->sk; - struct kvec iov = {.iov_base = skb->data, .iov_len = skb->len}; - struct msghdr msg = { - .msg_iov = (struct iovec *)&iov, - .msg_iovlen = 1, - .msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT, - }; - sk_udp->sk_prot->sendmsg(NULL, sk_udp, &msg, skb->len); - kfree_skb(skb); - } - set_fs(old_fs); -} - -static DECLARE_WORK(delivery_work, pppolac_xmit_core); - -static int pppolac_xmit(struct ppp_channel *chan, struct sk_buff *skb) -{ - struct sock *sk_udp = (struct sock *)chan->private; - struct pppolac_opt *opt = &pppox_sk(sk_udp->sk_user_data)->proto.lac; - - /* Install PPP address and control. */ - skb_push(skb, 2); - skb->data[0] = PPP_ADDR; - skb->data[1] = PPP_CTRL; - - /* Install L2TP header. */ - if (atomic_read(&opt->sequencing)) { - skb_push(skb, 10); - skb->data[0] = L2TP_SEQUENCE_BIT; - skb->data[6] = opt->xmit_sequence >> 8; - skb->data[7] = opt->xmit_sequence; - skb->data[8] = 0; - skb->data[9] = 0; - opt->xmit_sequence++; - } else { - skb_push(skb, 6); - skb->data[0] = 0; - } - skb->data[1] = L2TP_VERSION; - unaligned(&skb->data[2])->u32 = opt->remote; - - /* Now send the packet via the delivery queue. */ - skb_set_owner_w(skb, sk_udp); - skb_queue_tail(&delivery_queue, skb); - schedule_work(&delivery_work); - return 1; -} - -/******************************************************************************/ - -static struct ppp_channel_ops pppolac_channel_ops = { - .start_xmit = pppolac_xmit, -}; - -static int pppolac_connect(struct socket *sock, struct sockaddr *useraddr, - int addrlen, int flags) -{ - struct sock *sk = sock->sk; - struct pppox_sock *po = pppox_sk(sk); - struct sockaddr_pppolac *addr = (struct sockaddr_pppolac *)useraddr; - struct socket *sock_udp = NULL; - struct sock *sk_udp; - int error; - - if (addrlen != sizeof(struct sockaddr_pppolac) || - !addr->local.tunnel || !addr->local.session || - !addr->remote.tunnel || !addr->remote.session) { - return -EINVAL; - } - - lock_sock(sk); - error = -EALREADY; - if (sk->sk_state != PPPOX_NONE) - goto out; - - sock_udp = sockfd_lookup(addr->udp_socket, &error); - if (!sock_udp) - goto out; - sk_udp = sock_udp->sk; - lock_sock(sk_udp); - - /* Remove this check when IPv6 supports UDP encapsulation. */ - error = -EAFNOSUPPORT; - if (sk_udp->sk_family != AF_INET) - goto out; - error = -EPROTONOSUPPORT; - if (sk_udp->sk_protocol != IPPROTO_UDP) - goto out; - error = -EDESTADDRREQ; - if (sk_udp->sk_state != TCP_ESTABLISHED) - goto out; - error = -EBUSY; - if (udp_sk(sk_udp)->encap_type || sk_udp->sk_user_data) - goto out; - if (!sk_udp->sk_bound_dev_if) { - struct dst_entry *dst = sk_dst_get(sk_udp); - error = -ENODEV; - if (!dst) - goto out; - sk_udp->sk_bound_dev_if = dst->dev->ifindex; - dst_release(dst); - } - - po->chan.hdrlen = 12; - po->chan.private = sk_udp; - po->chan.ops = &pppolac_channel_ops; - po->chan.mtu = PPP_MTU - 80; - po->proto.lac.local = unaligned(&addr->local)->u32; - po->proto.lac.remote = unaligned(&addr->remote)->u32; - atomic_set(&po->proto.lac.sequencing, 1); - po->proto.lac.backlog_rcv = sk_udp->sk_backlog_rcv; - - error = ppp_register_channel(&po->chan); - if (error) - goto out; - - sk->sk_state = PPPOX_CONNECTED; - udp_sk(sk_udp)->encap_type = UDP_ENCAP_L2TPINUDP; - udp_sk(sk_udp)->encap_rcv = pppolac_recv; - sk_udp->sk_backlog_rcv = pppolac_recv_core; - sk_udp->sk_user_data = sk; -out: - if (sock_udp) { - release_sock(sk_udp); - if (error) - sockfd_put(sock_udp); - } - release_sock(sk); - return error; -} - -static int pppolac_release(struct socket *sock) -{ - struct sock *sk = sock->sk; - - if (!sk) - return 0; - - lock_sock(sk); - if (sock_flag(sk, SOCK_DEAD)) { - release_sock(sk); - return -EBADF; - } - - if (sk->sk_state != PPPOX_NONE) { - struct sock *sk_udp = (struct sock *)pppox_sk(sk)->chan.private; - lock_sock(sk_udp); - skb_queue_purge(&sk->sk_receive_queue); - pppox_unbind_sock(sk); - udp_sk(sk_udp)->encap_type = 0; - udp_sk(sk_udp)->encap_rcv = NULL; - sk_udp->sk_backlog_rcv = pppox_sk(sk)->proto.lac.backlog_rcv; - sk_udp->sk_user_data = NULL; - release_sock(sk_udp); - sockfd_put(sk_udp->sk_socket); - } - - sock_orphan(sk); - sock->sk = NULL; - release_sock(sk); - sock_put(sk); - return 0; -} - -/******************************************************************************/ - -static struct proto pppolac_proto = { - .name = "PPPOLAC", - .owner = THIS_MODULE, - .obj_size = sizeof(struct pppox_sock), -}; - -static struct proto_ops pppolac_proto_ops = { - .family = PF_PPPOX, - .owner = THIS_MODULE, - .release = pppolac_release, - .bind = sock_no_bind, - .connect = pppolac_connect, - .socketpair = sock_no_socketpair, - .accept = sock_no_accept, - .getname = sock_no_getname, - .poll = sock_no_poll, - .ioctl = pppox_ioctl, - .listen = sock_no_listen, - .shutdown = sock_no_shutdown, - .setsockopt = sock_no_setsockopt, - .getsockopt = sock_no_getsockopt, - .sendmsg = sock_no_sendmsg, - .recvmsg = sock_no_recvmsg, - .mmap = sock_no_mmap, -}; - -static int pppolac_create(struct net *net, struct socket *sock) -{ - struct sock *sk; - - sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppolac_proto); - if (!sk) - return -ENOMEM; - - sock_init_data(sock, sk); - sock->state = SS_UNCONNECTED; - sock->ops = &pppolac_proto_ops; - sk->sk_protocol = PX_PROTO_OLAC; - sk->sk_state = PPPOX_NONE; - return 0; -} - -/******************************************************************************/ - -static struct pppox_proto pppolac_pppox_proto = { - .create = pppolac_create, - .owner = THIS_MODULE, -}; - -static int __init pppolac_init(void) -{ - int error; - - error = proto_register(&pppolac_proto, 0); - if (error) - return error; - - error = register_pppox_proto(PX_PROTO_OLAC, &pppolac_pppox_proto); - if (error) - proto_unregister(&pppolac_proto); - else - skb_queue_head_init(&delivery_queue); - return error; -} - -static void __exit pppolac_exit(void) -{ - unregister_pppox_proto(PX_PROTO_OLAC); - proto_unregister(&pppolac_proto); -} - -module_init(pppolac_init); -module_exit(pppolac_exit); - -MODULE_DESCRIPTION("PPP on L2TP Access Concentrator (PPPoLAC)"); -MODULE_AUTHOR("Chia-chi Yeh "); -MODULE_LICENSE("GPL"); diff --git a/drivers/net/pppopns.c b/drivers/net/pppopns.c deleted file mode 100644 index fb8198447938..000000000000 --- a/drivers/net/pppopns.c +++ /dev/null @@ -1,428 +0,0 @@ -/* drivers/net/pppopns.c - * - * Driver for PPP on PPTP Network Server / PPPoPNS Socket (RFC 2637) - * - * Copyright (C) 2009 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -/* This driver handles PPTP data packets between a RAW socket and a PPP channel. - * The socket is created in the kernel space and connected to the same address - * of the control socket. Outgoing packets are always sent with sequences but - * without acknowledgements. Incoming packets with sequences are reordered - * within a sliding window of one second. Currently reordering only happens when - * a packet is received. It is done for simplicity since no additional locks or - * threads are required. This driver should work on both IPv4 and IPv6. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define GRE_HEADER_SIZE 8 - -#define PPTP_GRE_BITS htons(0x2001) -#define PPTP_GRE_BITS_MASK htons(0xEF7F) -#define PPTP_GRE_SEQ_BIT htons(0x1000) -#define PPTP_GRE_ACK_BIT htons(0x0080) -#define PPTP_GRE_TYPE htons(0x880B) - -#define PPP_ADDR 0xFF -#define PPP_CTRL 0x03 - -struct header { - __u16 bits; - __u16 type; - __u16 length; - __u16 call; - __u32 sequence; -} __attribute__((packed)); - -struct meta { - __u32 sequence; - __u32 timestamp; -}; - -static inline struct meta *skb_meta(struct sk_buff *skb) -{ - return (struct meta *)skb->cb; -} - -/******************************************************************************/ - -static int pppopns_recv_core(struct sock *sk_raw, struct sk_buff *skb) -{ - struct sock *sk = (struct sock *)sk_raw->sk_user_data; - struct pppopns_opt *opt = &pppox_sk(sk)->proto.pns; - struct meta *meta = skb_meta(skb); - __u32 now = jiffies; - struct header *hdr; - - /* Skip transport header */ - skb_pull(skb, skb_transport_header(skb) - skb->data); - - /* Drop the packet if GRE header is missing. */ - if (skb->len < GRE_HEADER_SIZE) - goto drop; - hdr = (struct header *)skb->data; - - /* Check the header. */ - if (hdr->type != PPTP_GRE_TYPE || hdr->call != opt->local || - (hdr->bits & PPTP_GRE_BITS_MASK) != PPTP_GRE_BITS) - goto drop; - - /* Skip all fields including optional ones. */ - if (!skb_pull(skb, GRE_HEADER_SIZE + - (hdr->bits & PPTP_GRE_SEQ_BIT ? 4 : 0) + - (hdr->bits & PPTP_GRE_ACK_BIT ? 4 : 0))) - goto drop; - - /* Check the length. */ - if (skb->len != ntohs(hdr->length)) - goto drop; - - /* Check the sequence if it is present. */ - if (hdr->bits & PPTP_GRE_SEQ_BIT) { - meta->sequence = ntohl(hdr->sequence); - if ((__s32)(meta->sequence - opt->recv_sequence) < 0) - goto drop; - } - - /* Skip PPP address and control if they are present. */ - if (skb->len >= 2 && skb->data[0] == PPP_ADDR && - skb->data[1] == PPP_CTRL) - skb_pull(skb, 2); - - /* Fix PPP protocol if it is compressed. */ - if (skb->len >= 1 && skb->data[0] & 1) - skb_push(skb, 1)[0] = 0; - - /* Drop the packet if PPP protocol is missing. */ - if (skb->len < 2) - goto drop; - - /* Perform reordering if sequencing is enabled. */ - if (hdr->bits & PPTP_GRE_SEQ_BIT) { - struct sk_buff *skb1; - - /* Insert the packet into receive queue in order. */ - skb_set_owner_r(skb, sk); - skb_queue_walk(&sk->sk_receive_queue, skb1) { - struct meta *meta1 = skb_meta(skb1); - __s32 order = meta->sequence - meta1->sequence; - if (order == 0) - goto drop; - if (order < 0) { - meta->timestamp = meta1->timestamp; - skb_insert(skb1, skb, &sk->sk_receive_queue); - skb = NULL; - break; - } - } - if (skb) { - meta->timestamp = now; - skb_queue_tail(&sk->sk_receive_queue, skb); - } - - /* Remove packets from receive queue as long as - * 1. the receive buffer is full, - * 2. they are queued longer than one second, or - * 3. there are no missing packets before them. */ - skb_queue_walk_safe(&sk->sk_receive_queue, skb, skb1) { - meta = skb_meta(skb); - if (atomic_read(&sk->sk_rmem_alloc) < sk->sk_rcvbuf && - now - meta->timestamp < HZ && - meta->sequence != opt->recv_sequence) - break; - skb_unlink(skb, &sk->sk_receive_queue); - opt->recv_sequence = meta->sequence + 1; - skb_orphan(skb); - ppp_input(&pppox_sk(sk)->chan, skb); - } - return NET_RX_SUCCESS; - } - - /* Flush receive queue if sequencing is disabled. */ - skb_queue_purge(&sk->sk_receive_queue); - skb_orphan(skb); - ppp_input(&pppox_sk(sk)->chan, skb); - return NET_RX_SUCCESS; -drop: - kfree_skb(skb); - return NET_RX_DROP; -} - -static void pppopns_recv(struct sock *sk_raw, int length) -{ - struct sk_buff *skb; - while ((skb = skb_dequeue(&sk_raw->sk_receive_queue))) { - sock_hold(sk_raw); - sk_receive_skb(sk_raw, skb, 0); - } -} - -static struct sk_buff_head delivery_queue; - -static void pppopns_xmit_core(struct work_struct *delivery_work) -{ - mm_segment_t old_fs = get_fs(); - struct sk_buff *skb; - - set_fs(KERNEL_DS); - while ((skb = skb_dequeue(&delivery_queue))) { - struct sock *sk_raw = skb->sk; - struct kvec iov = {.iov_base = skb->data, .iov_len = skb->len}; - struct msghdr msg = { - .msg_iov = (struct iovec *)&iov, - .msg_iovlen = 1, - .msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT, - }; - sk_raw->sk_prot->sendmsg(NULL, sk_raw, &msg, skb->len); - kfree_skb(skb); - } - set_fs(old_fs); -} - -static DECLARE_WORK(delivery_work, pppopns_xmit_core); - -static int pppopns_xmit(struct ppp_channel *chan, struct sk_buff *skb) -{ - struct sock *sk_raw = (struct sock *)chan->private; - struct pppopns_opt *opt = &pppox_sk(sk_raw->sk_user_data)->proto.pns; - struct header *hdr; - __u16 length; - - /* Install PPP address and control. */ - skb_push(skb, 2); - skb->data[0] = PPP_ADDR; - skb->data[1] = PPP_CTRL; - length = skb->len; - - /* Install PPTP GRE header. */ - hdr = (struct header *)skb_push(skb, 12); - hdr->bits = PPTP_GRE_BITS | PPTP_GRE_SEQ_BIT; - hdr->type = PPTP_GRE_TYPE; - hdr->length = htons(length); - hdr->call = opt->remote; - hdr->sequence = htonl(opt->xmit_sequence); - opt->xmit_sequence++; - - /* Now send the packet via the delivery queue. */ - skb_set_owner_w(skb, sk_raw); - skb_queue_tail(&delivery_queue, skb); - schedule_work(&delivery_work); - return 1; -} - -/******************************************************************************/ - -static struct ppp_channel_ops pppopns_channel_ops = { - .start_xmit = pppopns_xmit, -}; - -static int pppopns_connect(struct socket *sock, struct sockaddr *useraddr, - int addrlen, int flags) -{ - struct sock *sk = sock->sk; - struct pppox_sock *po = pppox_sk(sk); - struct sockaddr_pppopns *addr = (struct sockaddr_pppopns *)useraddr; - struct sockaddr_storage ss; - struct socket *sock_tcp = NULL; - struct socket *sock_raw = NULL; - struct sock *sk_tcp; - struct sock *sk_raw; - int error; - - if (addrlen != sizeof(struct sockaddr_pppopns)) - return -EINVAL; - - lock_sock(sk); - error = -EALREADY; - if (sk->sk_state != PPPOX_NONE) - goto out; - - sock_tcp = sockfd_lookup(addr->tcp_socket, &error); - if (!sock_tcp) - goto out; - sk_tcp = sock_tcp->sk; - error = -EPROTONOSUPPORT; - if (sk_tcp->sk_protocol != IPPROTO_TCP) - goto out; - addrlen = sizeof(struct sockaddr_storage); - error = kernel_getpeername(sock_tcp, (struct sockaddr *)&ss, &addrlen); - if (error) - goto out; - if (!sk_tcp->sk_bound_dev_if) { - struct dst_entry *dst = sk_dst_get(sk_tcp); - error = -ENODEV; - if (!dst) - goto out; - sk_tcp->sk_bound_dev_if = dst->dev->ifindex; - dst_release(dst); - } - - error = sock_create(ss.ss_family, SOCK_RAW, IPPROTO_GRE, &sock_raw); - if (error) - goto out; - sk_raw = sock_raw->sk; - sk_raw->sk_bound_dev_if = sk_tcp->sk_bound_dev_if; - error = kernel_connect(sock_raw, (struct sockaddr *)&ss, addrlen, 0); - if (error) - goto out; - - po->chan.hdrlen = 14; - po->chan.private = sk_raw; - po->chan.ops = &pppopns_channel_ops; - po->chan.mtu = PPP_MTU - 80; - po->proto.pns.local = addr->local; - po->proto.pns.remote = addr->remote; - po->proto.pns.data_ready = sk_raw->sk_data_ready; - po->proto.pns.backlog_rcv = sk_raw->sk_backlog_rcv; - - error = ppp_register_channel(&po->chan); - if (error) - goto out; - - sk->sk_state = PPPOX_CONNECTED; - lock_sock(sk_raw); - sk_raw->sk_data_ready = pppopns_recv; - sk_raw->sk_backlog_rcv = pppopns_recv_core; - sk_raw->sk_user_data = sk; - release_sock(sk_raw); -out: - if (sock_tcp) - sockfd_put(sock_tcp); - if (error && sock_raw) - sock_release(sock_raw); - release_sock(sk); - return error; -} - -static int pppopns_release(struct socket *sock) -{ - struct sock *sk = sock->sk; - - if (!sk) - return 0; - - lock_sock(sk); - if (sock_flag(sk, SOCK_DEAD)) { - release_sock(sk); - return -EBADF; - } - - if (sk->sk_state != PPPOX_NONE) { - struct sock *sk_raw = (struct sock *)pppox_sk(sk)->chan.private; - lock_sock(sk_raw); - skb_queue_purge(&sk->sk_receive_queue); - pppox_unbind_sock(sk); - sk_raw->sk_data_ready = pppox_sk(sk)->proto.pns.data_ready; - sk_raw->sk_backlog_rcv = pppox_sk(sk)->proto.pns.backlog_rcv; - sk_raw->sk_user_data = NULL; - release_sock(sk_raw); - sock_release(sk_raw->sk_socket); - } - - sock_orphan(sk); - sock->sk = NULL; - release_sock(sk); - sock_put(sk); - return 0; -} - -/******************************************************************************/ - -static struct proto pppopns_proto = { - .name = "PPPOPNS", - .owner = THIS_MODULE, - .obj_size = sizeof(struct pppox_sock), -}; - -static struct proto_ops pppopns_proto_ops = { - .family = PF_PPPOX, - .owner = THIS_MODULE, - .release = pppopns_release, - .bind = sock_no_bind, - .connect = pppopns_connect, - .socketpair = sock_no_socketpair, - .accept = sock_no_accept, - .getname = sock_no_getname, - .poll = sock_no_poll, - .ioctl = pppox_ioctl, - .listen = sock_no_listen, - .shutdown = sock_no_shutdown, - .setsockopt = sock_no_setsockopt, - .getsockopt = sock_no_getsockopt, - .sendmsg = sock_no_sendmsg, - .recvmsg = sock_no_recvmsg, - .mmap = sock_no_mmap, -}; - -static int pppopns_create(struct net *net, struct socket *sock) -{ - struct sock *sk; - - sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppopns_proto); - if (!sk) - return -ENOMEM; - - sock_init_data(sock, sk); - sock->state = SS_UNCONNECTED; - sock->ops = &pppopns_proto_ops; - sk->sk_protocol = PX_PROTO_OPNS; - sk->sk_state = PPPOX_NONE; - return 0; -} - -/******************************************************************************/ - -static struct pppox_proto pppopns_pppox_proto = { - .create = pppopns_create, - .owner = THIS_MODULE, -}; - -static int __init pppopns_init(void) -{ - int error; - - error = proto_register(&pppopns_proto, 0); - if (error) - return error; - - error = register_pppox_proto(PX_PROTO_OPNS, &pppopns_pppox_proto); - if (error) - proto_unregister(&pppopns_proto); - else - skb_queue_head_init(&delivery_queue); - return error; -} - -static void __exit pppopns_exit(void) -{ - unregister_pppox_proto(PX_PROTO_OPNS); - proto_unregister(&pppopns_proto); -} - -module_init(pppopns_init); -module_exit(pppopns_exit); - -MODULE_DESCRIPTION("PPP on PPTP Network Server (PPPoPNS)"); -MODULE_AUTHOR("Chia-chi Yeh "); -MODULE_LICENSE("GPL"); diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c index 4b3a68b69a67..1286fe212dc4 100644 --- a/drivers/net/pptp.c +++ b/drivers/net/pptp.c @@ -418,8 +418,10 @@ static int pptp_bind(struct socket *sock, struct sockaddr *uservaddr, lock_sock(sk); opt->src_addr = sp->sa_addr.pptp; - if (add_chan(po)) + if (add_chan(po)) { + release_sock(sk); error = -EBUSY; + } release_sock(sk); return error; diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 80b230e6f207..5990621fb5cd 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -58,12 +58,8 @@ #define R8169_MSG_DEFAULT \ (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN) -#define TX_SLOTS_AVAIL(tp) \ - (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx) - -/* A skbuff with nr_frags needs nr_frags+1 entries in the tx queue */ -#define TX_FRAGS_READY_FOR(tp,nr_frags) \ - (TX_SLOTS_AVAIL(tp) >= (nr_frags + 1)) +#define TX_BUFFS_AVAIL(tp) \ + (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1) /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). The RTL chips use a 64 element hash table based on the Ethernet CRC. */ @@ -75,7 +71,7 @@ static const int multicast_filter_limit = 32; #define MAX_READ_REQUEST_SHIFT 12 #define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */ #define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ -#define TX_DMA_BURST 7 /* Maximum PCI burst, '7' is unlimited */ +#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ #define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */ #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ @@ -144,101 +140,82 @@ enum rtl_tx_desc_version { RTL_TD_1 = 1, }; -#define JUMBO_1K ETH_DATA_LEN -#define JUMBO_4K (4*1024 - ETH_HLEN - 2) -#define JUMBO_6K (6*1024 - ETH_HLEN - 2) -#define JUMBO_7K (7*1024 - ETH_HLEN - 2) -#define JUMBO_9K (9*1024 - ETH_HLEN - 2) - -#define _R(NAME,TD,FW,SZ,B) { \ - .name = NAME, \ - .txd_version = TD, \ - .fw_name = FW, \ - .jumbo_max = SZ, \ - .jumbo_tx_csum = B \ -} +#define _R(NAME,TD,FW) \ + { .name = NAME, .txd_version = TD, .fw_name = FW } static const struct { const char *name; enum rtl_tx_desc_version txd_version; const char *fw_name; - u16 jumbo_max; - bool jumbo_tx_csum; } rtl_chip_infos[] = { /* PCI devices. */ [RTL_GIGA_MAC_VER_01] = - _R("RTL8169", RTL_TD_0, NULL, JUMBO_7K, true), + _R("RTL8169", RTL_TD_0, NULL), [RTL_GIGA_MAC_VER_02] = - _R("RTL8169s", RTL_TD_0, NULL, JUMBO_7K, true), + _R("RTL8169s", RTL_TD_0, NULL), [RTL_GIGA_MAC_VER_03] = - _R("RTL8110s", RTL_TD_0, NULL, JUMBO_7K, true), + _R("RTL8110s", RTL_TD_0, NULL), [RTL_GIGA_MAC_VER_04] = - _R("RTL8169sb/8110sb", RTL_TD_0, NULL, JUMBO_7K, true), + _R("RTL8169sb/8110sb", RTL_TD_0, NULL), [RTL_GIGA_MAC_VER_05] = - _R("RTL8169sc/8110sc", RTL_TD_0, NULL, JUMBO_7K, true), + _R("RTL8169sc/8110sc", RTL_TD_0, NULL), [RTL_GIGA_MAC_VER_06] = - _R("RTL8169sc/8110sc", RTL_TD_0, NULL, JUMBO_7K, true), + _R("RTL8169sc/8110sc", RTL_TD_0, NULL), /* PCI-E devices. */ [RTL_GIGA_MAC_VER_07] = - _R("RTL8102e", RTL_TD_1, NULL, JUMBO_1K, true), + _R("RTL8102e", RTL_TD_1, NULL), [RTL_GIGA_MAC_VER_08] = - _R("RTL8102e", RTL_TD_1, NULL, JUMBO_1K, true), + _R("RTL8102e", RTL_TD_1, NULL), [RTL_GIGA_MAC_VER_09] = - _R("RTL8102e", RTL_TD_1, NULL, JUMBO_1K, true), + _R("RTL8102e", RTL_TD_1, NULL), [RTL_GIGA_MAC_VER_10] = - _R("RTL8101e", RTL_TD_0, NULL, JUMBO_1K, true), + _R("RTL8101e", RTL_TD_0, NULL), [RTL_GIGA_MAC_VER_11] = - _R("RTL8168b/8111b", RTL_TD_0, NULL, JUMBO_4K, false), + _R("RTL8168b/8111b", RTL_TD_0, NULL), [RTL_GIGA_MAC_VER_12] = - _R("RTL8168b/8111b", RTL_TD_0, NULL, JUMBO_4K, false), + _R("RTL8168b/8111b", RTL_TD_0, NULL), [RTL_GIGA_MAC_VER_13] = - _R("RTL8101e", RTL_TD_0, NULL, JUMBO_1K, true), + _R("RTL8101e", RTL_TD_0, NULL), [RTL_GIGA_MAC_VER_14] = - _R("RTL8100e", RTL_TD_0, NULL, JUMBO_1K, true), + _R("RTL8100e", RTL_TD_0, NULL), [RTL_GIGA_MAC_VER_15] = - _R("RTL8100e", RTL_TD_0, NULL, JUMBO_1K, true), + _R("RTL8100e", RTL_TD_0, NULL), [RTL_GIGA_MAC_VER_16] = - _R("RTL8101e", RTL_TD_0, NULL, JUMBO_1K, true), + _R("RTL8101e", RTL_TD_0, NULL), [RTL_GIGA_MAC_VER_17] = - _R("RTL8168b/8111b", RTL_TD_1, NULL, JUMBO_4K, false), + _R("RTL8168b/8111b", RTL_TD_0, NULL), [RTL_GIGA_MAC_VER_18] = - _R("RTL8168cp/8111cp", RTL_TD_1, NULL, JUMBO_6K, false), + _R("RTL8168cp/8111cp", RTL_TD_1, NULL), [RTL_GIGA_MAC_VER_19] = - _R("RTL8168c/8111c", RTL_TD_1, NULL, JUMBO_6K, false), + _R("RTL8168c/8111c", RTL_TD_1, NULL), [RTL_GIGA_MAC_VER_20] = - _R("RTL8168c/8111c", RTL_TD_1, NULL, JUMBO_6K, false), + _R("RTL8168c/8111c", RTL_TD_1, NULL), [RTL_GIGA_MAC_VER_21] = - _R("RTL8168c/8111c", RTL_TD_1, NULL, JUMBO_6K, false), + _R("RTL8168c/8111c", RTL_TD_1, NULL), [RTL_GIGA_MAC_VER_22] = - _R("RTL8168c/8111c", RTL_TD_1, NULL, JUMBO_6K, false), + _R("RTL8168c/8111c", RTL_TD_1, NULL), [RTL_GIGA_MAC_VER_23] = - _R("RTL8168cp/8111cp", RTL_TD_1, NULL, JUMBO_6K, false), + _R("RTL8168cp/8111cp", RTL_TD_1, NULL), [RTL_GIGA_MAC_VER_24] = - _R("RTL8168cp/8111cp", RTL_TD_1, NULL, JUMBO_6K, false), + _R("RTL8168cp/8111cp", RTL_TD_1, NULL), [RTL_GIGA_MAC_VER_25] = - _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_1, - JUMBO_9K, false), + _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_1), [RTL_GIGA_MAC_VER_26] = - _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_2, - JUMBO_9K, false), + _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_2), [RTL_GIGA_MAC_VER_27] = - _R("RTL8168dp/8111dp", RTL_TD_1, NULL, JUMBO_9K, false), + _R("RTL8168dp/8111dp", RTL_TD_1, NULL), [RTL_GIGA_MAC_VER_28] = - _R("RTL8168dp/8111dp", RTL_TD_1, NULL, JUMBO_9K, false), + _R("RTL8168dp/8111dp", RTL_TD_1, NULL), [RTL_GIGA_MAC_VER_29] = - _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1, - JUMBO_1K, true), + _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1), [RTL_GIGA_MAC_VER_30] = - _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1, - JUMBO_1K, true), + _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1), [RTL_GIGA_MAC_VER_31] = - _R("RTL8168dp/8111dp", RTL_TD_1, NULL, JUMBO_9K, false), + _R("RTL8168dp/8111dp", RTL_TD_1, NULL), [RTL_GIGA_MAC_VER_32] = - _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_1, - JUMBO_9K, false), + _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_1), [RTL_GIGA_MAC_VER_33] = - _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_2, - JUMBO_9K, false) + _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_2) }; #undef _R @@ -259,7 +236,6 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_1 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, - { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4302), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_AT, 0xc107), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, { PCI_VENDOR_ID_LINKSYS, 0x1032, @@ -303,8 +279,6 @@ enum rtl_registers { Config0 = 0x51, Config1 = 0x52, Config2 = 0x53, -#define PME_SIGNAL (1 << 5) /* 8168c and later */ - Config3 = 0x54, Config4 = 0x55, Config5 = 0x56, @@ -413,7 +387,6 @@ enum rtl_register_content { RxOK = 0x0001, /* RxStatusDesc */ - RxBOVF = (1 << 24), RxFOVF = (1 << 23), RxRWT = (1 << 22), RxRES = (1 << 21), @@ -454,6 +427,7 @@ enum rtl_register_content { /* Config1 register p.24 */ LEDS1 = (1 << 7), LEDS0 = (1 << 6), + MSIEnable = (1 << 5), /* Enable Message Signaled Interrupt */ Speed_down = (1 << 4), MEMMAP = (1 << 3), IOMAP = (1 << 2), @@ -461,19 +435,14 @@ enum rtl_register_content { PMEnable = (1 << 0), /* Power Management Enable */ /* Config2 register p. 25 */ - MSIEnable = (1 << 5), /* 8169 only. Reserved in the 8168. */ PCI_Clock_66MHz = 0x01, PCI_Clock_33MHz = 0x00, /* Config3 register p.25 */ MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */ - Jumbo_En0 = (1 << 2), /* 8168 only. Reserved in the 8168b */ Beacon_en = (1 << 0), /* 8168 only. Reserved in the 8168b */ - /* Config4 register */ - Jumbo_En1 = (1 << 1), /* 8168 only. Reserved in the 8168b */ - /* Config5 register p.27 */ BWF = (1 << 6), /* Accept Broadcast wakeup frame */ MWF = (1 << 5), /* Accept Multicast wakeup frame */ @@ -682,11 +651,6 @@ struct rtl8169_private { void (*up)(struct rtl8169_private *); } pll_power_ops; - struct jumbo_ops { - void (*enable)(struct rtl8169_private *); - void (*disable)(struct rtl8169_private *); - } jumbo_ops; - int (*set_speed)(struct net_device *, u8 aneg, u16 sp, u8 dpx, u32 adv); int (*get_settings)(struct net_device *, struct ethtool_cmd *); void (*phy_reset_enable)(struct rtl8169_private *tp); @@ -701,7 +665,6 @@ struct rtl8169_private { struct mii_if_info mii; struct rtl8169_counters counters; u32 saved_wolopts; - u32 opts1_mask; const struct firmware *fw; #define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN); @@ -741,21 +704,6 @@ static int rtl8169_poll(struct napi_struct *napi, int budget); static const unsigned int rtl8169_rx_config = (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); -static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct rtl8169_private *tp = netdev_priv(dev); - int cap = tp->pcie_cap; - - if (cap) { - u16 ctl; - - pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl); - ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force; - pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl); - } -} - static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg) { void __iomem *ioaddr = tp->mmio_addr; @@ -1094,21 +1042,17 @@ static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr) return value; } -static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp) +static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr) { - void __iomem *ioaddr = tp->mmio_addr; - RTL_W16(IntrMask, 0x0000); - RTL_W16(IntrStatus, tp->intr_event); - RTL_R8(ChipCmd); + + RTL_W16(IntrStatus, 0xffff); } -static void rtl8169_asic_down(struct rtl8169_private *tp) +static void rtl8169_asic_down(void __iomem *ioaddr) { - void __iomem *ioaddr = tp->mmio_addr; - RTL_W8(ChipCmd, 0x00); - rtl8169_irq_mask_and_ack(tp); + rtl8169_irq_mask_and_ack(ioaddr); RTL_R16(CPlusCmd); } @@ -1167,7 +1111,7 @@ static void __rtl8169_check_link_status(struct net_device *dev, netif_carrier_off(dev); netif_info(tp, ifdown, dev, "link down\n"); if (pm) - pm_schedule_suspend(&tp->pci_dev->dev, 5000); + pm_schedule_suspend(&tp->pci_dev->dev, 100); } spin_unlock_irqrestore(&tp->lock, flags); } @@ -1229,6 +1173,7 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) u16 reg; u8 mask; } cfg[] = { + { WAKE_ANY, Config1, PMEnable }, { WAKE_PHY, Config3, LinkUp }, { WAKE_MAGIC, Config3, MagicPacket }, { WAKE_UCAST, Config5, UWF }, @@ -1236,32 +1181,16 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) { WAKE_MCAST, Config5, MWF }, { WAKE_ANY, Config5, LanWake } }; - u8 options; RTL_W8(Cfg9346, Cfg9346_Unlock); for (i = 0; i < ARRAY_SIZE(cfg); i++) { - options = RTL_R8(cfg[i].reg) & ~cfg[i].mask; + u8 options = RTL_R8(cfg[i].reg) & ~cfg[i].mask; if (wolopts & cfg[i].opt) options |= cfg[i].mask; RTL_W8(cfg[i].reg, options); } - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_01 ... RTL_GIGA_MAC_VER_17: - options = RTL_R8(Config1) & ~PMEnable; - if (wolopts) - options |= PMEnable; - RTL_W8(Config1, options); - break; - default: - options = RTL_R8(Config2) & ~PME_SIGNAL; - if (wolopts) - options |= PME_SIGNAL; - RTL_W8(Config2, options); - break; - } - RTL_W8(Cfg9346, Cfg9346_Lock); } @@ -1443,15 +1372,9 @@ static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) static u32 rtl8169_fix_features(struct net_device *dev, u32 features) { - struct rtl8169_private *tp = netdev_priv(dev); - if (dev->mtu > TD_MSS_MAX) features &= ~NETIF_F_ALL_TSO; - if (dev->mtu > JUMBO_1K && - !rtl_chip_infos[tp->mac_version].jumbo_tx_csum) - features &= ~NETIF_F_IP_CSUM; - return features; } @@ -3024,24 +2947,22 @@ static const struct rtl_cfg_info { }; /* Cfg9346_Unlock assumed. */ -static unsigned rtl_try_msi(struct rtl8169_private *tp, +static unsigned rtl_try_msi(struct pci_dev *pdev, void __iomem *ioaddr, const struct rtl_cfg_info *cfg) { - void __iomem *ioaddr = tp->mmio_addr; unsigned msi = 0; u8 cfg2; cfg2 = RTL_R8(Config2) & ~MSIEnable; if (cfg->features & RTL_FEATURE_MSI) { - if (pci_enable_msi(tp->pci_dev)) { - netif_info(tp, hw, tp->dev, "no MSI. Back to INTx.\n"); + if (pci_enable_msi(pdev)) { + dev_info(&pdev->dev, "no MSI. Back to INTx.\n"); } else { cfg2 |= MSIEnable; msi = RTL_FEATURE_MSI; } } - if (tp->mac_version <= RTL_GIGA_MAC_VER_06) - RTL_W8(Config2, cfg2); + RTL_W8(Config2, cfg2); return msi; } @@ -3204,10 +3125,8 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) rtl_writephy(tp, 0x1f, 0x0000); rtl_writephy(tp, MII_BMCR, 0x0000); - if (tp->mac_version == RTL_GIGA_MAC_VER_32 || - tp->mac_version == RTL_GIGA_MAC_VER_33) - RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | - AcceptMulticast | AcceptMyPhys); + RTL_W32(RxConfig, RTL_R32(RxConfig) | + AcceptBroadcast | AcceptMulticast | AcceptMyPhys); return; } @@ -3252,8 +3171,8 @@ static void r8168_pll_power_up(struct rtl8169_private *tp) r8168_phy_power_up(tp); } -static void rtl_generic_op(struct rtl8169_private *tp, - void (*op)(struct rtl8169_private *)) +static void rtl_pll_power_op(struct rtl8169_private *tp, + void (*op)(struct rtl8169_private *)) { if (op) op(tp); @@ -3261,12 +3180,12 @@ static void rtl_generic_op(struct rtl8169_private *tp, static void rtl_pll_power_down(struct rtl8169_private *tp) { - rtl_generic_op(tp, tp->pll_power_ops.down); + rtl_pll_power_op(tp, tp->pll_power_ops.down); } static void rtl_pll_power_up(struct rtl8169_private *tp) { - rtl_generic_op(tp, tp->pll_power_ops.up); + rtl_pll_power_op(tp, tp->pll_power_ops.up); } static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) @@ -3313,149 +3232,6 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) } } -static void rtl_hw_jumbo_enable(struct rtl8169_private *tp) -{ - rtl_generic_op(tp, tp->jumbo_ops.enable); -} - -static void rtl_hw_jumbo_disable(struct rtl8169_private *tp) -{ - rtl_generic_op(tp, tp->jumbo_ops.disable); -} - -static void r8168c_hw_jumbo_enable(struct rtl8169_private *tp) -{ - void __iomem *ioaddr = tp->mmio_addr; - - RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); - RTL_W8(Config4, RTL_R8(Config4) | Jumbo_En1); - rtl_tx_performance_tweak(tp->pci_dev, 0x2 << MAX_READ_REQUEST_SHIFT); -} - -static void r8168c_hw_jumbo_disable(struct rtl8169_private *tp) -{ - void __iomem *ioaddr = tp->mmio_addr; - - RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); - RTL_W8(Config4, RTL_R8(Config4) & ~Jumbo_En1); - rtl_tx_performance_tweak(tp->pci_dev, 0x5 << MAX_READ_REQUEST_SHIFT); -} - -static void r8168dp_hw_jumbo_enable(struct rtl8169_private *tp) -{ - void __iomem *ioaddr = tp->mmio_addr; - - RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); -} - -static void r8168dp_hw_jumbo_disable(struct rtl8169_private *tp) -{ - void __iomem *ioaddr = tp->mmio_addr; - - RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); -} - -static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp) -{ - void __iomem *ioaddr = tp->mmio_addr; - struct pci_dev *pdev = tp->pci_dev; - - RTL_W8(MaxTxPacketSize, 0x3f); - RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); - RTL_W8(Config4, RTL_R8(Config4) | 0x01); - pci_write_config_byte(pdev, 0x79, 0x20); -} - -static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp) -{ - void __iomem *ioaddr = tp->mmio_addr; - struct pci_dev *pdev = tp->pci_dev; - - RTL_W8(MaxTxPacketSize, 0x0c); - RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); - RTL_W8(Config4, RTL_R8(Config4) & ~0x01); - pci_write_config_byte(pdev, 0x79, 0x50); -} - -static void r8168b_0_hw_jumbo_enable(struct rtl8169_private *tp) -{ - rtl_tx_performance_tweak(tp->pci_dev, - (0x2 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN); -} - -static void r8168b_0_hw_jumbo_disable(struct rtl8169_private *tp) -{ - rtl_tx_performance_tweak(tp->pci_dev, - (0x5 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN); -} - -static void r8168b_1_hw_jumbo_enable(struct rtl8169_private *tp) -{ - void __iomem *ioaddr = tp->mmio_addr; - - r8168b_0_hw_jumbo_enable(tp); - - RTL_W8(Config4, RTL_R8(Config4) | (1 << 0)); -} - -static void r8168b_1_hw_jumbo_disable(struct rtl8169_private *tp) -{ - void __iomem *ioaddr = tp->mmio_addr; - - r8168b_0_hw_jumbo_disable(tp); - - RTL_W8(Config4, RTL_R8(Config4) & ~(1 << 0)); -} - -static void __devinit rtl_init_jumbo_ops(struct rtl8169_private *tp) -{ - struct jumbo_ops *ops = &tp->jumbo_ops; - - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_11: - ops->disable = r8168b_0_hw_jumbo_disable; - ops->enable = r8168b_0_hw_jumbo_enable; - break; - case RTL_GIGA_MAC_VER_12: - case RTL_GIGA_MAC_VER_17: - ops->disable = r8168b_1_hw_jumbo_disable; - ops->enable = r8168b_1_hw_jumbo_enable; - break; - case RTL_GIGA_MAC_VER_18: /* Wild guess. Needs info from Realtek. */ - case RTL_GIGA_MAC_VER_19: - case RTL_GIGA_MAC_VER_20: - case RTL_GIGA_MAC_VER_21: /* Wild guess. Needs info from Realtek. */ - case RTL_GIGA_MAC_VER_22: - case RTL_GIGA_MAC_VER_23: - case RTL_GIGA_MAC_VER_24: - case RTL_GIGA_MAC_VER_25: - case RTL_GIGA_MAC_VER_26: - ops->disable = r8168c_hw_jumbo_disable; - ops->enable = r8168c_hw_jumbo_enable; - break; - case RTL_GIGA_MAC_VER_27: - case RTL_GIGA_MAC_VER_28: - ops->disable = r8168dp_hw_jumbo_disable; - ops->enable = r8168dp_hw_jumbo_enable; - break; - case RTL_GIGA_MAC_VER_31: /* Wild guess. Needs info from Realtek. */ - case RTL_GIGA_MAC_VER_32: - case RTL_GIGA_MAC_VER_33: - ops->disable = r8168e_hw_jumbo_disable; - ops->enable = r8168e_hw_jumbo_enable; - break; - - /* - * No action needed for jumbo frames with 8169. - * No jumbo for 810x at all. - */ - default: - ops->disable = NULL; - ops->enable = NULL; - break; - } -} - static void rtl_hw_reset(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; @@ -3597,7 +3373,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) rtl_init_mdio_ops(tp); rtl_init_pll_power_ops(tp); - rtl_init_jumbo_ops(tp); rtl8169_print_mac_version(tp); @@ -3611,7 +3386,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->features |= RTL_FEATURE_WOL; if ((RTL_R8(Config5) & (UWF | BWF | MWF)) != 0) tp->features |= RTL_FEATURE_WOL; - tp->features |= rtl_try_msi(tp, cfg); + tp->features |= rtl_try_msi(pdev, ioaddr, cfg); RTL_W8(Cfg9346, Cfg9346_Lock); if ((tp->mac_version <= RTL_GIGA_MAC_VER_06) && @@ -3664,9 +3439,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->intr_event = cfg->intr_event; tp->napi_event = cfg->napi_event; - tp->opts1_mask = (tp->mac_version != RTL_GIGA_MAC_VER_01) ? - ~(RxBOVF | RxFOVF) : ~0; - init_timer(&tp->timer); tp->timer.data = (unsigned long) dev; tp->timer.function = rtl8169_phy_timer; @@ -3682,12 +3454,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) netif_info(tp, probe, dev, "%s at 0x%lx, %pM, XID %08x IRQ %d\n", rtl_chip_infos[chipset].name, dev->base_addr, dev->dev_addr, (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq); - if (rtl_chip_infos[chipset].jumbo_max != JUMBO_1K) { - netif_info(tp, probe, dev, "jumbo features [frames: %d bytes, " - "tx checksumming: %s]\n", - rtl_chip_infos[chipset].jumbo_max, - rtl_chip_infos[chipset].jumbo_tx_csum ? "ok" : "ko"); - } if (tp->mac_version == RTL_GIGA_MAC_VER_27 || tp->mac_version == RTL_GIGA_MAC_VER_28 || @@ -3706,7 +3472,6 @@ out: return rc; err_out_msi_4: - netif_napi_del(&tp->napi); rtl_disable_msi(pdev, tp); iounmap(ioaddr); err_out_free_res_3: @@ -3732,8 +3497,6 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) cancel_delayed_work_sync(&tp->task); - netif_napi_del(&tp->napi); - unregister_netdev(dev); rtl_release_firmware(tp); @@ -3847,7 +3610,7 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) void __iomem *ioaddr = tp->mmio_addr; /* Disable interrupts */ - rtl8169_irq_mask_and_ack(tp); + rtl8169_irq_mask_and_ack(ioaddr); if (tp->mac_version == RTL_GIGA_MAC_VER_27 || tp->mac_version == RTL_GIGA_MAC_VER_28 || @@ -4015,6 +3778,21 @@ static void rtl_hw_start_8169(struct net_device *dev) RTL_W16(IntrMask, tp->intr_event); } +static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct rtl8169_private *tp = netdev_priv(dev); + int cap = tp->pcie_cap; + + if (cap) { + u16 ctl; + + pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl); + ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force; + pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl); + } +} + static void rtl_csi_access_enable(void __iomem *ioaddr, u32 bits) { u32 csi; @@ -4314,7 +4092,8 @@ static void rtl_hw_start_8168(struct net_device *dev) RTL_W16(IntrMitigate, 0x5151); /* Work around for RxFIFO overflow. */ - if (tp->mac_version == RTL_GIGA_MAC_VER_11) { + if (tp->mac_version == RTL_GIGA_MAC_VER_11 || + tp->mac_version == RTL_GIGA_MAC_VER_22) { tp->intr_event |= RxFIFOOver | PCSTimeout; tp->intr_event &= ~RxOverflow; } @@ -4496,11 +4275,6 @@ static void rtl_hw_start_8101(struct net_device *dev) void __iomem *ioaddr = tp->mmio_addr; struct pci_dev *pdev = tp->pci_dev; - if (tp->mac_version >= RTL_GIGA_MAC_VER_30) { - tp->intr_event &= ~RxFIFOOver; - tp->napi_event &= ~RxFIFOOver; - } - if (tp->mac_version == RTL_GIGA_MAC_VER_13 || tp->mac_version == RTL_GIGA_MAC_VER_16) { int cap = tp->pcie_cap; @@ -4561,17 +4335,9 @@ static void rtl_hw_start_8101(struct net_device *dev) static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) { - struct rtl8169_private *tp = netdev_priv(dev); - - if (new_mtu < ETH_ZLEN || - new_mtu > rtl_chip_infos[tp->mac_version].jumbo_max) + if (new_mtu < ETH_ZLEN || new_mtu > SafeMtu) return -EINVAL; - if (new_mtu > ETH_DATA_LEN) - rtl_hw_jumbo_enable(tp); - else - rtl_hw_jumbo_disable(tp); - dev->mtu = new_mtu; netdev_update_features(dev); @@ -4772,7 +4538,7 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev) /* Wait for any pending NAPI task to complete */ napi_disable(&tp->napi); - rtl8169_irq_mask_and_ack(tp); + rtl8169_irq_mask_and_ack(ioaddr); tp->intr_mask = 0xffff; RTL_W16(IntrMask, tp->intr_event); @@ -4931,7 +4697,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, u32 opts[2]; int frags; - if (unlikely(!TX_FRAGS_READY_FOR(tp, skb_shinfo(skb)->nr_frags))) { + if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) { netif_err(tp, drv, dev, "BUG! Tx Ring full when queue awake!\n"); goto err_stop_0; } @@ -4979,10 +4745,10 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, RTL_W8(TxPoll, NPQ); - if (!TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) { + if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) { netif_stop_queue(dev); - smp_mb(); - if (TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) + smp_rmb(); + if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS) netif_wake_queue(dev); } @@ -5082,9 +4848,9 @@ static void rtl8169_tx_interrupt(struct net_device *dev, if (tp->dirty_tx != dirty_tx) { tp->dirty_tx = dirty_tx; - smp_mb(); + smp_wmb(); if (netif_queue_stopped(dev) && - TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) { + (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) { netif_wake_queue(dev); } /* @@ -5093,6 +4859,7 @@ static void rtl8169_tx_interrupt(struct net_device *dev, * of start_xmit activity is detected (if it is not detected, * it is slow enough). -- FR */ + smp_rmb(); if (tp->cur_tx != dirty_tx) RTL_W8(TxPoll, NPQ); } @@ -5150,7 +4917,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, u32 status; rmb(); - status = le32_to_cpu(desc->opts1) & tp->opts1_mask; + status = le32_to_cpu(desc->opts1); if (status & DescOwn) break; @@ -5170,7 +4937,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, } else { struct sk_buff *skb; dma_addr_t addr = le64_to_cpu(desc->addr); - int pkt_size = (status & 0x00003fff) - 4; + int pkt_size = (status & 0x00001FFF) - 4; /* * The driver does not support incoming fragmented @@ -5203,6 +4970,13 @@ static int rtl8169_rx_interrupt(struct net_device *dev, dev->stats.rx_bytes += pkt_size; dev->stats.rx_packets++; } + + /* Work around for AMD plateform. */ + if ((desc->opts2 & cpu_to_le32(0xfffe000)) && + (tp->mac_version == RTL_GIGA_MAC_VER_05)) { + desc->opts2 = 0; + cur_rx++; + } } count = cur_rx - tp->cur_rx; @@ -5226,17 +5000,13 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) */ status = RTL_R16(IntrStatus); while (status && status != 0xffff) { - status &= tp->intr_event; - if (!status) - break; - handled = 1; /* Handle all of the error cases first. These will reset * the chip, so just exit the loop. */ if (unlikely(!netif_running(dev))) { - rtl8169_asic_down(tp); + rtl8169_asic_down(ioaddr); break; } @@ -5244,9 +5014,27 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) switch (tp->mac_version) { /* Work around for rx fifo overflow */ case RTL_GIGA_MAC_VER_11: + case RTL_GIGA_MAC_VER_22: + case RTL_GIGA_MAC_VER_26: netif_stop_queue(dev); rtl8169_tx_timeout(dev); goto done; + /* Testers needed. */ + case RTL_GIGA_MAC_VER_17: + case RTL_GIGA_MAC_VER_19: + case RTL_GIGA_MAC_VER_20: + case RTL_GIGA_MAC_VER_21: + case RTL_GIGA_MAC_VER_23: + case RTL_GIGA_MAC_VER_24: + case RTL_GIGA_MAC_VER_27: + case RTL_GIGA_MAC_VER_28: + case RTL_GIGA_MAC_VER_31: + /* Experimental science. Pktgen proof. */ + case RTL_GIGA_MAC_VER_12: + case RTL_GIGA_MAC_VER_25: + if (status == RxFIFOOver) + goto done; + break; default: break; } @@ -5341,7 +5129,7 @@ static void rtl8169_down(struct net_device *dev) spin_lock_irq(&tp->lock); - rtl8169_asic_down(tp); + rtl8169_asic_down(ioaddr); /* * At this point device interrupts can not be enabled in any function, * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task, @@ -5587,9 +5375,6 @@ static void rtl_shutdown(struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; - struct device *d = &pdev->dev; - - pm_runtime_get_sync(d); rtl8169_net_suspend(dev); @@ -5598,16 +5383,13 @@ static void rtl_shutdown(struct pci_dev *pdev) spin_lock_irq(&tp->lock); - rtl8169_asic_down(tp); + rtl8169_asic_down(ioaddr); spin_unlock_irq(&tp->lock); if (system_state == SYSTEM_POWER_OFF) { - /* WoL fails with 8168b when the receiver is disabled. */ - if ((tp->mac_version == RTL_GIGA_MAC_VER_11 || - tp->mac_version == RTL_GIGA_MAC_VER_12 || - tp->mac_version == RTL_GIGA_MAC_VER_17) && - (tp->features & RTL_FEATURE_WOL)) { + /* WoL fails with some 8168 when the receiver is disabled. */ + if (tp->features & RTL_FEATURE_WOL) { pci_clear_master(pdev); RTL_W8(ChipCmd, CmdRxEnb); @@ -5618,8 +5400,6 @@ static void rtl_shutdown(struct pci_dev *pdev) pci_wake_from_d3(pdev, true); pci_set_power_state(pdev, PCI_D3hot); } - - pm_runtime_put_noidle(d); } static struct pci_driver rtl8169_pci_driver = { diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index 1f421d73a88f..5d3436d47edd 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -80,16 +80,16 @@ static int rionet_capable = 1; */ static struct rio_dev **rionet_active; -#define is_rionet_capable(src_ops, dst_ops) \ - ((src_ops & RIO_SRC_OPS_DATA_MSG) && \ - (dst_ops & RIO_DST_OPS_DATA_MSG) && \ +#define is_rionet_capable(pef, src_ops, dst_ops) \ + ((pef & RIO_PEF_INB_MBOX) && \ + (pef & RIO_PEF_INB_DOORBELL) && \ (src_ops & RIO_SRC_OPS_DOORBELL) && \ (dst_ops & RIO_DST_OPS_DOORBELL)) #define dev_rionet_capable(dev) \ - is_rionet_capable(dev->src_ops, dev->dst_ops) + is_rionet_capable(dev->pef, dev->src_ops, dev->dst_ops) -#define RIONET_MAC_MATCH(x) (!memcmp((x), "\00\01\00\01", 4)) -#define RIONET_GET_DESTID(x) ((*((u8 *)x + 4) << 8) | *((u8 *)x + 5)) +#define RIONET_MAC_MATCH(x) (*(u32 *)x == 0x00010001) +#define RIONET_GET_DESTID(x) (*(u16 *)(x + 4)) static int rionet_rx_clean(struct net_device *ndev) { @@ -282,6 +282,7 @@ static int rionet_open(struct net_device *ndev) { int i, rc = 0; struct rionet_peer *peer, *tmp; + u32 pwdcsr; struct rionet_private *rnet = netdev_priv(ndev); if (netif_msg_ifup(rnet)) @@ -331,8 +332,13 @@ static int rionet_open(struct net_device *ndev) continue; } - /* Send a join message */ - rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN); + /* + * If device has initialized inbound doorbells, + * send a join message + */ + rio_read_config_32(peer->rdev, RIO_WRITE_PORT_CSR, &pwdcsr); + if (pwdcsr & RIO_DOORBELL_AVAIL) + rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN); } out: @@ -486,7 +492,7 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev) static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) { int rc = -ENODEV; - u32 lsrc_ops, ldst_ops; + u32 lpef, lsrc_ops, ldst_ops; struct rionet_peer *peer; struct net_device *ndev = NULL; @@ -509,11 +515,12 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) * on later probes */ if (!rionet_check) { + rio_local_read_config_32(rdev->net->hport, RIO_PEF_CAR, &lpef); rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR, &lsrc_ops); rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR, &ldst_ops); - if (!is_rionet_capable(lsrc_ops, ldst_ops)) { + if (!is_rionet_capable(lpef, lsrc_ops, ldst_ops)) { printk(KERN_ERR "%s: local device is not network capable\n", DRV_NAME); diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index be3cade1ef49..c914729f9554 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -1051,6 +1051,7 @@ static int efx_init_io(struct efx_nic *efx) { struct pci_dev *pci_dev = efx->pci_dev; dma_addr_t dma_mask = efx->type->max_dma_mask; + bool use_wc; int rc; netif_dbg(efx, probe, efx->net_dev, "initialising I/O\n"); @@ -1101,8 +1102,21 @@ static int efx_init_io(struct efx_nic *efx) rc = -EIO; goto fail3; } - efx->membase = ioremap_nocache(efx->membase_phys, - efx->type->mem_map_size); + + /* bug22643: If SR-IOV is enabled then tx push over a write combined + * mapping is unsafe. We need to disable write combining in this case. + * MSI is unsupported when SR-IOV is enabled, and the firmware will + * have removed the MSI capability. So write combining is safe if + * there is an MSI capability. + */ + use_wc = (!EFX_WORKAROUND_22643(efx) || + pci_find_capability(pci_dev, PCI_CAP_ID_MSI)); + if (use_wc) + efx->membase = ioremap_wc(efx->membase_phys, + efx->type->mem_map_size); + else + efx->membase = ioremap_nocache(efx->membase_phys, + efx->type->mem_map_size); if (!efx->membase) { netif_err(efx, probe, efx->net_dev, "could not map memory BAR at %llx+%x\n", @@ -1383,11 +1397,6 @@ static int efx_probe_all(struct efx_nic *efx) goto fail2; } - BUILD_BUG_ON(EFX_DEFAULT_DMAQ_SIZE < EFX_RXQ_MIN_ENT); - if (WARN_ON(EFX_DEFAULT_DMAQ_SIZE < EFX_TXQ_MIN_ENT(efx))) { - rc = -EINVAL; - goto fail3; - } efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE; rc = efx_probe_channels(efx); if (rc) @@ -1947,7 +1956,6 @@ static int efx_register_netdev(struct efx_nic *efx) net_dev->irq = efx->pci_dev->irq; net_dev->netdev_ops = &efx_netdev_ops; SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops); - net_dev->gso_max_segs = EFX_TSO_MAX_SEGS; /* Clear MAC statistics */ efx->mac_op->update_stats(efx); diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index a5d1c60d536c..b0d1209ea18d 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h @@ -38,7 +38,6 @@ extern netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb); extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index); extern int efx_setup_tc(struct net_device *net_dev, u8 num_tc); -extern unsigned int efx_tx_max_skb_descs(struct efx_nic *efx); /* RX */ extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue); @@ -61,15 +60,10 @@ extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue); #define EFX_MAX_EVQ_SIZE 16384UL #define EFX_MIN_EVQ_SIZE 512UL -/* Maximum number of TCP segments we support for soft-TSO */ -#define EFX_TSO_MAX_SEGS 100 - -/* The smallest [rt]xq_entries that the driver supports. RX minimum - * is a bit arbitrary. For TX, we must have space for at least 2 - * TSO skbs. - */ -#define EFX_RXQ_MIN_ENT 128U -#define EFX_TXQ_MIN_ENT(efx) (2 * efx_tx_max_skb_descs(efx)) +/* The smallest [rt]xq_entries that the driver supports. Callers of + * efx_wake_queue() assume that they can subsequently send at least one + * skb. Falcon/A1 may require up to three descriptors per skb_frag. */ +#define EFX_MIN_RING_SIZE (roundup_pow_of_two(2 * 3 * MAX_SKB_FRAGS)) /* Filters */ extern int efx_probe_filters(struct efx_nic *efx); diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index cfaf801c66af..d229027dc363 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -677,27 +677,21 @@ static int efx_ethtool_set_ringparam(struct net_device *net_dev, struct ethtool_ringparam *ring) { struct efx_nic *efx = netdev_priv(net_dev); - u32 txq_entries; if (ring->rx_mini_pending || ring->rx_jumbo_pending || ring->rx_pending > EFX_MAX_DMAQ_SIZE || ring->tx_pending > EFX_MAX_DMAQ_SIZE) return -EINVAL; - if (ring->rx_pending < EFX_RXQ_MIN_ENT) { + if (ring->rx_pending < EFX_MIN_RING_SIZE || + ring->tx_pending < EFX_MIN_RING_SIZE) { netif_err(efx, drv, efx->net_dev, - "RX queues cannot be smaller than %u\n", - EFX_RXQ_MIN_ENT); + "TX and RX queues cannot be smaller than %ld\n", + EFX_MIN_RING_SIZE); return -EINVAL; } - txq_entries = max(ring->tx_pending, EFX_TXQ_MIN_ENT(efx)); - if (txq_entries != ring->tx_pending) - netif_warn(efx, drv, efx->net_dev, - "increasing TX queue size to minimum of %u\n", - txq_entries); - - return efx_realloc_channels(efx, ring->rx_pending, txq_entries); + return efx_realloc_channels(efx, ring->rx_pending, ring->tx_pending); } static int efx_ethtool_set_pauseparam(struct net_device *net_dev, diff --git a/drivers/net/sfc/io.h b/drivers/net/sfc/io.h index dc45110b2456..cc978803d484 100644 --- a/drivers/net/sfc/io.h +++ b/drivers/net/sfc/io.h @@ -48,9 +48,9 @@ * replacing the low 96 bits with zero does not affect functionality. * - If the host writes to the last dword address of such a register * (i.e. the high 32 bits) the underlying register will always be - * written. If the collector does not hold values for the low 96 - * bits of the register, they will be written as zero. Writing to - * the last qword does not have this effect and must not be done. + * written. If the collector and the current write together do not + * provide values for all 128 bits of the register, the low 96 bits + * will be written as zero. * - If the host writes to the address of any other part of such a * register while the collector already holds values for some other * register, the write is discarded and the collector maintains its @@ -103,6 +103,7 @@ static inline void efx_writeo(struct efx_nic *efx, efx_oword_t *value, _efx_writed(efx, value->u32[2], reg + 8); _efx_writed(efx, value->u32[3], reg + 12); #endif + wmb(); mmiowb(); spin_unlock_irqrestore(&efx->biu_lock, flags); } @@ -125,6 +126,7 @@ static inline void efx_sram_writeq(struct efx_nic *efx, void __iomem *membase, __raw_writel((__force u32)value->u32[0], membase + addr); __raw_writel((__force u32)value->u32[1], membase + addr + 4); #endif + wmb(); mmiowb(); spin_unlock_irqrestore(&efx->biu_lock, flags); } @@ -139,6 +141,7 @@ static inline void efx_writed(struct efx_nic *efx, efx_dword_t *value, /* No lock required */ _efx_writed(efx, value->u32[0], reg); + wmb(); } /* Read a 128-bit CSR, locking as appropriate. */ @@ -149,6 +152,7 @@ static inline void efx_reado(struct efx_nic *efx, efx_oword_t *value, spin_lock_irqsave(&efx->biu_lock, flags); value->u32[0] = _efx_readd(efx, reg + 0); + rmb(); value->u32[1] = _efx_readd(efx, reg + 4); value->u32[2] = _efx_readd(efx, reg + 8); value->u32[3] = _efx_readd(efx, reg + 12); @@ -171,6 +175,7 @@ static inline void efx_sram_readq(struct efx_nic *efx, void __iomem *membase, value->u64[0] = (__force __le64)__raw_readq(membase + addr); #else value->u32[0] = (__force __le32)__raw_readl(membase + addr); + rmb(); value->u32[1] = (__force __le32)__raw_readl(membase + addr + 4); #endif spin_unlock_irqrestore(&efx->biu_lock, flags); @@ -237,12 +242,14 @@ static inline void _efx_writeo_page(struct efx_nic *efx, efx_oword_t *value, #ifdef EFX_USE_QWORD_IO _efx_writeq(efx, value->u64[0], reg + 0); + _efx_writeq(efx, value->u64[1], reg + 8); #else _efx_writed(efx, value->u32[0], reg + 0); _efx_writed(efx, value->u32[1], reg + 4); -#endif _efx_writed(efx, value->u32[2], reg + 8); _efx_writed(efx, value->u32[3], reg + 12); +#endif + wmb(); } #define efx_writeo_page(efx, value, reg, page) \ _efx_writeo_page(efx, value, \ diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c index 81a425397468..3dd45ed61f0a 100644 --- a/drivers/net/sfc/mcdi.c +++ b/drivers/net/sfc/mcdi.c @@ -50,6 +50,20 @@ static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx) return &nic_data->mcdi; } +static inline void +efx_mcdi_readd(struct efx_nic *efx, efx_dword_t *value, unsigned reg) +{ + struct siena_nic_data *nic_data = efx->nic_data; + value->u32[0] = (__force __le32)__raw_readl(nic_data->mcdi_smem + reg); +} + +static inline void +efx_mcdi_writed(struct efx_nic *efx, const efx_dword_t *value, unsigned reg) +{ + struct siena_nic_data *nic_data = efx->nic_data; + __raw_writel((__force u32)value->u32[0], nic_data->mcdi_smem + reg); +} + void efx_mcdi_init(struct efx_nic *efx) { struct efx_mcdi_iface *mcdi; @@ -70,8 +84,8 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd, const u8 *inbuf, size_t inlen) { struct efx_mcdi_iface *mcdi = efx_mcdi(efx); - unsigned pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx); - unsigned doorbell = FR_CZ_MC_TREG_SMEM + MCDI_DOORBELL(efx); + unsigned pdu = MCDI_PDU(efx); + unsigned doorbell = MCDI_DOORBELL(efx); unsigned int i; efx_dword_t hdr; u32 xflags, seqno; @@ -92,29 +106,28 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd, MCDI_HEADER_SEQ, seqno, MCDI_HEADER_XFLAGS, xflags); - efx_writed(efx, &hdr, pdu); + efx_mcdi_writed(efx, &hdr, pdu); for (i = 0; i < inlen; i += 4) - _efx_writed(efx, *((__le32 *)(inbuf + i)), pdu + 4 + i); - - /* Ensure the payload is written out before the header */ - wmb(); + efx_mcdi_writed(efx, (const efx_dword_t *)(inbuf + i), + pdu + 4 + i); /* ring the doorbell with a distinctive value */ - _efx_writed(efx, (__force __le32) 0x45789abc, doorbell); + EFX_POPULATE_DWORD_1(hdr, EFX_DWORD_0, 0x45789abc); + efx_mcdi_writed(efx, &hdr, doorbell); } static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen) { struct efx_mcdi_iface *mcdi = efx_mcdi(efx); - unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx); + unsigned int pdu = MCDI_PDU(efx); int i; BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT); BUG_ON(outlen & 3 || outlen >= 0x100); for (i = 0; i < outlen; i += 4) - *((__le32 *)(outbuf + i)) = _efx_readd(efx, pdu + 4 + i); + efx_mcdi_readd(efx, (efx_dword_t *)(outbuf + i), pdu + 4 + i); } static int efx_mcdi_poll(struct efx_nic *efx) @@ -122,7 +135,7 @@ static int efx_mcdi_poll(struct efx_nic *efx) struct efx_mcdi_iface *mcdi = efx_mcdi(efx); unsigned int time, finish; unsigned int respseq, respcmd, error; - unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx); + unsigned int pdu = MCDI_PDU(efx); unsigned int rc, spins; efx_dword_t reg; @@ -148,8 +161,7 @@ static int efx_mcdi_poll(struct efx_nic *efx) time = get_seconds(); - rmb(); - efx_readd(efx, ®, pdu); + efx_mcdi_readd(efx, ®, pdu); /* All 1's indicates that shared memory is in reset (and is * not a valid header). Wait for it to come out reset before @@ -176,7 +188,7 @@ static int efx_mcdi_poll(struct efx_nic *efx) respseq, mcdi->seqno); rc = EIO; } else if (error) { - efx_readd(efx, ®, pdu + 4); + efx_mcdi_readd(efx, ®, pdu + 4); switch (EFX_DWORD_FIELD(reg, EFX_DWORD_0)) { #define TRANSLATE_ERROR(name) \ case MC_CMD_ERR_ ## name: \ @@ -210,21 +222,21 @@ out: /* Test and clear MC-rebooted flag for this port/function */ int efx_mcdi_poll_reboot(struct efx_nic *efx) { - unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_REBOOT_FLAG(efx); + unsigned int addr = MCDI_REBOOT_FLAG(efx); efx_dword_t reg; uint32_t value; if (efx_nic_rev(efx) < EFX_REV_SIENA_A0) return false; - efx_readd(efx, ®, addr); + efx_mcdi_readd(efx, ®, addr); value = EFX_DWORD_FIELD(reg, EFX_DWORD_0); if (value == 0) return 0; EFX_ZERO_DWORD(reg); - efx_writed(efx, ®, addr); + efx_mcdi_writed(efx, ®, addr); if (value == MC_STATUS_DWORD_ASSERT) return -EINTR; diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index 5ac9fa2cd3bc..f2a2b947f860 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -1935,6 +1935,13 @@ void efx_nic_get_regs(struct efx_nic *efx, void *buf) size = min_t(size_t, table->step, 16); + if (table->offset >= efx->type->mem_map_size) { + /* No longer mapped; return dummy data */ + memcpy(buf, "\xde\xc0\xad\xde", 4); + buf += table->rows * size; + continue; + } + for (i = 0; i < table->rows; i++) { switch (table->step) { case 4: /* 32-bit register or SRAM */ diff --git a/drivers/net/sfc/nic.h b/drivers/net/sfc/nic.h index d2405ceb2539..4bd1f2839dfe 100644 --- a/drivers/net/sfc/nic.h +++ b/drivers/net/sfc/nic.h @@ -65,11 +65,6 @@ enum { #define FALCON_GMAC_LOOPBACKS \ (1 << LOOPBACK_GMAC) -/* Alignment of PCIe DMA boundaries (4KB) */ -#define EFX_PAGE_SIZE 4096 -/* Size and alignment of buffer table entries (same) */ -#define EFX_BUF_SIZE EFX_PAGE_SIZE - /** * struct falcon_board_type - board operations and type information * @id: Board type id, as found in NVRAM @@ -148,10 +143,12 @@ static inline struct falcon_board *falcon_board(struct efx_nic *efx) /** * struct siena_nic_data - Siena NIC state * @mcdi: Management-Controller-to-Driver Interface + * @mcdi_smem: MCDI shared memory mapping. The mapping is always uncacheable. * @wol_filter_id: Wake-on-LAN packet filter id */ struct siena_nic_data { struct efx_mcdi_iface mcdi; + void __iomem *mcdi_smem; int wol_filter_id; }; diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 4004fc2477be..62e43649466e 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -155,10 +155,11 @@ static int efx_init_rx_buffers_skb(struct efx_rx_queue *rx_queue) if (unlikely(!skb)) return -ENOMEM; - /* Adjust the SKB for padding */ + /* Adjust the SKB for padding and checksum */ skb_reserve(skb, NET_IP_ALIGN); rx_buf->len = skb_len - NET_IP_ALIGN; rx_buf->is_page = false; + skb->ip_summed = CHECKSUM_UNNECESSARY; rx_buf->dma_addr = pci_map_single(efx->pci_dev, skb->data, rx_buf->len, @@ -497,7 +498,6 @@ static void efx_rx_packet_gro(struct efx_channel *channel, EFX_BUG_ON_PARANOID(!checksummed); rx_buf->u.skb = NULL; - skb->ip_summed = CHECKSUM_UNNECESSARY; gro_result = napi_gro_receive(napi, skb); } diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index ceac1c9907f0..fb4721f780ff 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -220,12 +220,26 @@ static int siena_probe_nic(struct efx_nic *efx) efx_reado(efx, ®, FR_AZ_CS_DEBUG); efx->net_dev->dev_id = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1; + /* Initialise MCDI */ + nic_data->mcdi_smem = ioremap_nocache(efx->membase_phys + + FR_CZ_MC_TREG_SMEM, + FR_CZ_MC_TREG_SMEM_STEP * + FR_CZ_MC_TREG_SMEM_ROWS); + if (!nic_data->mcdi_smem) { + netif_err(efx, probe, efx->net_dev, + "could not map MCDI at %llx+%x\n", + (unsigned long long)efx->membase_phys + + FR_CZ_MC_TREG_SMEM, + FR_CZ_MC_TREG_SMEM_STEP * FR_CZ_MC_TREG_SMEM_ROWS); + rc = -ENOMEM; + goto fail1; + } efx_mcdi_init(efx); /* Recover from a failed assertion before probing */ rc = efx_mcdi_handle_assertion(efx); if (rc) - goto fail1; + goto fail2; /* Let the BMC know that the driver is now in charge of link and * filter settings. We must do this before we reset the NIC */ @@ -280,6 +294,7 @@ fail4: fail3: efx_mcdi_drv_attach(efx, false, NULL); fail2: + iounmap(nic_data->mcdi_smem); fail1: kfree(efx->nic_data); return rc; @@ -359,6 +374,8 @@ static int siena_init_nic(struct efx_nic *efx) static void siena_remove_nic(struct efx_nic *efx) { + struct siena_nic_data *nic_data = efx->nic_data; + efx_nic_free_buffer(efx, &efx->irq_status); siena_reset_hw(efx, RESET_TYPE_ALL); @@ -368,7 +385,8 @@ static void siena_remove_nic(struct efx_nic *efx) efx_mcdi_drv_attach(efx, false, NULL); /* Tear down the private nic state */ - kfree(efx->nic_data); + iounmap(nic_data->mcdi_smem); + kfree(nic_data); efx->nic_data = NULL; } @@ -606,8 +624,7 @@ const struct efx_nic_type siena_a0_nic_type = { .default_mac_ops = &efx_mcdi_mac_operations, .revision = EFX_REV_SIENA_A0, - .mem_map_size = (FR_CZ_MC_TREG_SMEM + - FR_CZ_MC_TREG_SMEM_STEP * FR_CZ_MC_TREG_SMEM_ROWS), + .mem_map_size = FR_CZ_MC_TREG_SMEM, /* MC_TREG_SMEM mapped separately */ .txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL, .rxd_ptr_tbl_base = FR_BZ_RX_DESC_PTR_TBL, .buf_tbl_base = FR_BZ_BUF_FULL_TBL, diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index 6d3b68a8478c..84eb99e0f8d2 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -115,25 +115,6 @@ efx_max_tx_len(struct efx_nic *efx, dma_addr_t dma_addr) return len; } -unsigned int efx_tx_max_skb_descs(struct efx_nic *efx) -{ - /* Header and payload descriptor for each output segment, plus - * one for every input fragment boundary within a segment - */ - unsigned int max_descs = EFX_TSO_MAX_SEGS * 2 + MAX_SKB_FRAGS; - - /* Possibly one more per segment for the alignment workaround */ - if (EFX_WORKAROUND_5391(efx)) - max_descs += EFX_TSO_MAX_SEGS; - - /* Possibly more for PCIe page boundaries within input fragments */ - if (PAGE_SIZE > EFX_PAGE_SIZE) - max_descs += max_t(unsigned int, MAX_SKB_FRAGS, - DIV_ROUND_UP(GSO_MAX_SIZE, EFX_PAGE_SIZE)); - - return max_descs; -} - /* * Add a socket buffer to a TX queue * diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h index e4dd3a7f304b..99ff11400cef 100644 --- a/drivers/net/sfc/workarounds.h +++ b/drivers/net/sfc/workarounds.h @@ -38,6 +38,8 @@ #define EFX_WORKAROUND_15783 EFX_WORKAROUND_ALWAYS /* Legacy interrupt storm when interrupt fifo fills */ #define EFX_WORKAROUND_17213 EFX_WORKAROUND_SIENA +/* Write combining and sriov=enabled are incompatible */ +#define EFX_WORKAROUND_22643 EFX_WORKAROUND_SIENA /* Spurious parity errors in TSORT buffers */ #define EFX_WORKAROUND_5129 EFX_WORKAROUND_FALCON_A diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index f6d26ab30e82..b436e007eea0 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -1824,16 +1824,6 @@ static int sis190_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) generic_mii_ioctl(&tp->mii_if, if_mii(ifr), cmd, NULL); } -static int sis190_mac_addr(struct net_device *dev, void *p) -{ - int rc; - - rc = eth_mac_addr(dev, p); - if (!rc) - sis190_init_rxfilter(dev); - return rc; -} - static const struct net_device_ops sis190_netdev_ops = { .ndo_open = sis190_open, .ndo_stop = sis190_close, @@ -1842,7 +1832,7 @@ static const struct net_device_ops sis190_netdev_ops = { .ndo_tx_timeout = sis190_tx_timeout, .ndo_set_multicast_list = sis190_set_rx_mode, .ndo_change_mtu = eth_change_mtu, - .ndo_set_mac_address = sis190_mac_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = sis190_netpoll, diff --git a/drivers/net/skge.c b/drivers/net/skge.c index b446e7e5f435..f4be5c78ebfd 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -4097,13 +4097,6 @@ static struct dmi_system_id skge_32bit_dma_boards[] = { DMI_MATCH(DMI_BOARD_NAME, "nForce"), }, }, - { - .ident = "ASUS P5NSLI", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), - DMI_MATCH(DMI_BOARD_NAME, "P5NSLI") - }, - }, {} }; diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 5f93956d73a2..3ee41da130c2 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -94,10 +94,6 @@ static int disable_msi = 0; module_param(disable_msi, int, 0); MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); -static int legacy_pme = 0; -module_param(legacy_pme, int, 0); -MODULE_PARM_DESC(legacy_pme, "Legacy power management"); - static DEFINE_PCI_DEVICE_TABLE(sky2_id_table) = { { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, /* SK-9Sxx */ { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */ @@ -798,13 +794,6 @@ static void sky2_wol_init(struct sky2_port *sky2) /* Disable PiG firmware */ sky2_write16(hw, B0_CTST, Y2_HW_WOL_OFF); - /* Needed by some broken BIOSes, use PCI rather than PCI-e for WOL */ - if (legacy_pme) { - u32 reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); - reg1 |= PCI_Y2_PME_LEGACY; - sky2_pci_write32(hw, PCI_DEV_REG1, reg1); - } - /* block receiver */ sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); } @@ -2344,13 +2333,8 @@ static struct sk_buff *receive_copy(struct sky2_port *sky2, skb_copy_from_linear_data(re->skb, skb->data, length); skb->ip_summed = re->skb->ip_summed; skb->csum = re->skb->csum; - skb->rxhash = re->skb->rxhash; - skb->vlan_tci = re->skb->vlan_tci; - pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr, length, PCI_DMA_FROMDEVICE); - re->skb->vlan_tci = 0; - re->skb->rxhash = 0; re->skb->ip_summed = CHECKSUM_NONE; skb_put(skb, length); } @@ -2435,6 +2419,9 @@ static struct sk_buff *sky2_receive(struct net_device *dev, struct sk_buff *skb = NULL; u16 count = (status & GMR_FS_LEN) >> 16; + if (status & GMR_FS_VLAN) + count -= VLAN_HLEN; /* Account for vlan tag */ + netif_printk(sky2, rx_status, KERN_DEBUG, dev, "rx slot %u status 0x%x len %d\n", sky2->rx_next, status, length); @@ -2442,9 +2429,6 @@ static struct sk_buff *sky2_receive(struct net_device *dev, sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending; prefetch(sky2->rx_ring + sky2->rx_next); - if (vlan_tx_tag_present(re->skb)) - count -= VLAN_HLEN; /* Account for vlan tag */ - /* This chip has hardware problems that generates bogus status. * So do only marginal checking and expect higher level protocols * to handle crap frames. @@ -2502,8 +2486,11 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last) } static inline void sky2_skb_rx(const struct sky2_port *sky2, - struct sk_buff *skb) + u32 status, struct sk_buff *skb) { + if (status & GMR_FS_VLAN) + __vlan_hwaccel_put_tag(skb, be16_to_cpu(sky2->rx_tag)); + if (skb->ip_summed == CHECKSUM_NONE) netif_receive_skb(skb); else @@ -2557,14 +2544,6 @@ static void sky2_rx_checksum(struct sky2_port *sky2, u32 status) } } -static void sky2_rx_tag(struct sky2_port *sky2, u16 length) -{ - struct sk_buff *skb; - - skb = sky2->rx_ring[sky2->rx_next].skb; - __vlan_hwaccel_put_tag(skb, be16_to_cpu(length)); -} - static void sky2_rx_hash(struct sky2_port *sky2, u32 status) { struct sk_buff *skb; @@ -2623,7 +2602,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) } skb->protocol = eth_type_trans(skb, dev); - sky2_skb_rx(sky2, skb); + + sky2_skb_rx(sky2, status, skb); /* Stop after net poll weight */ if (++work_done >= to_do) @@ -2631,11 +2611,11 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) break; case OP_RXVLAN: - sky2_rx_tag(sky2, length); + sky2->rx_tag = length; break; case OP_RXCHKSVLAN: - sky2_rx_tag(sky2, length); + sky2->rx_tag = length; /* fall through */ case OP_RXCHKS: if (likely(dev->features & NETIF_F_RXCSUM)) @@ -2929,10 +2909,8 @@ static irqreturn_t sky2_intr(int irq, void *dev_id) /* Reading this mask interrupts as side effect */ status = sky2_read32(hw, B0_Y2_SP_ISRC2); - if (status == 0 || status == ~0) { - sky2_write32(hw, B0_Y2_SP_ICR, 2); + if (status == 0 || status == ~0) return IRQ_NONE; - } prefetch(&hw->st_le[hw->st_idx]); @@ -4208,12 +4186,10 @@ static int sky2_set_features(struct net_device *dev, u32 features) struct sky2_port *sky2 = netdev_priv(dev); u32 changed = dev->features ^ features; - if ((changed & NETIF_F_RXCSUM) && - !(sky2->hw->flags & SKY2_HW_NEW_LE)) { - sky2_write32(sky2->hw, - Q_ADDR(rxqaddr[sky2->port], Q_CSR), - (features & NETIF_F_RXCSUM) - ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); + if (changed & NETIF_F_RXCSUM) { + u32 on = features & NETIF_F_RXCSUM; + sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), + on ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); } if (changed & NETIF_F_RXHASH) diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index a79a1662ea9e..318c9ae7bf91 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -2236,6 +2236,7 @@ struct sky2_port { u16 rx_pending; u16 rx_data_size; u16 rx_nfrags; + u16 rx_tag; struct { unsigned long last; diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 3d12e8ce9393..c6d47d10590c 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -1083,8 +1083,10 @@ smsc911x_rx_counterrors(struct net_device *dev, unsigned int rxstat) /* Quickly dumps bad packets */ static void -smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktwords) +smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes) { + unsigned int pktwords = (pktbytes + NET_IP_ALIGN + 3) >> 2; + if (likely(pktwords >= 4)) { unsigned int timeout = 500; unsigned int val; @@ -1148,7 +1150,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget) continue; } - skb = netdev_alloc_skb(dev, pktwords << 2); + skb = netdev_alloc_skb(dev, pktlength + NET_IP_ALIGN); if (unlikely(!skb)) { SMSC_WARN(pdata, rx_err, "Unable to allocate skb for rx packet"); @@ -1158,12 +1160,14 @@ static int smsc911x_poll(struct napi_struct *napi, int budget) break; } - pdata->ops->rx_readfifo(pdata, - (unsigned int *)skb->data, pktwords); + skb->data = skb->head; + skb_reset_tail_pointer(skb); /* Align IP on 16B boundary */ skb_reserve(skb, NET_IP_ALIGN); skb_put(skb, pktlength - 4); + pdata->ops->rx_readfifo(pdata, + (unsigned int *)skb->head, pktwords); skb->protocol = eth_type_trans(skb, dev); skb_checksum_none_assert(skb); netif_receive_skb(skb); @@ -1386,7 +1390,7 @@ static int smsc911x_open(struct net_device *dev) smsc911x_reg_write(pdata, FIFO_INT, temp); /* set RX Data offset to 2 bytes for alignment */ - smsc911x_reg_write(pdata, RX_CFG, (NET_IP_ALIGN << 8)); + smsc911x_reg_write(pdata, RX_CFG, (2 << 8)); /* enable NAPI polling before enabling RX interrupts */ napi_enable(&pdata->napi); diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 361beb797d1e..ab5930099267 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -2363,7 +2363,7 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state) netif_device_detach(dev); /* Switch off MAC, remember WOL setting */ - gp->asleep_wol = !!gp->wake_on_lan; + gp->asleep_wol = gp->wake_on_lan; gem_do_stop(dev, gp->asleep_wol); } else gp->asleep_wol = 0; diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index eaa24fa8c191..a1f9f9eef37d 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -740,13 +740,8 @@ static inline unsigned int tg3_has_work(struct tg3_napi *tnapi) if (sblk->status & SD_STATUS_LINK_CHG) work_exists = 1; } - - /* check for TX work to do */ - if (sblk->idx[0].tx_consumer != tnapi->tx_cons) - work_exists = 1; - - /* check for RX work to do */ - if (tnapi->rx_rcb_prod_idx && + /* check for RX/TX work to do */ + if (sblk->idx[0].tx_consumer != tnapi->tx_cons || *(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr) work_exists = 1; @@ -996,26 +991,14 @@ static int tg3_phy_auxctl_write(struct tg3 *tp, int reg, u32 set) return tg3_writephy(tp, MII_TG3_AUX_CTRL, set | reg); } -static int tg3_phy_toggle_auxctl_smdsp(struct tg3 *tp, bool enable) -{ - u32 val; - int err; - - err = tg3_phy_auxctl_read(tp, MII_TG3_AUXCTL_SHDWSEL_AUXCTL, &val); - - if (err) - return err; - if (enable) +#define TG3_PHY_AUXCTL_SMDSP_ENABLE(tp) \ + tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, \ + MII_TG3_AUXCTL_ACTL_SMDSP_ENA | \ + MII_TG3_AUXCTL_ACTL_TX_6DB) - val |= MII_TG3_AUXCTL_ACTL_SMDSP_ENA; - else - val &= ~MII_TG3_AUXCTL_ACTL_SMDSP_ENA; - - err = tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, - val | MII_TG3_AUXCTL_ACTL_TX_6DB); - - return err; -} +#define TG3_PHY_AUXCTL_SMDSP_DISABLE(tp) \ + tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, \ + MII_TG3_AUXCTL_ACTL_TX_6DB); static int tg3_bmcr_reset(struct tg3 *tp) { @@ -1787,7 +1770,7 @@ static void tg3_phy_apply_otp(struct tg3 *tp) otp = tp->phy_otp; - if (tg3_phy_toggle_auxctl_smdsp(tp, true)) + if (TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) return; phy = ((otp & TG3_OTP_AGCTGT_MASK) >> TG3_OTP_AGCTGT_SHIFT); @@ -1812,7 +1795,7 @@ static void tg3_phy_apply_otp(struct tg3 *tp) ((otp & TG3_OTP_RCOFF_MASK) >> TG3_OTP_RCOFF_SHIFT); tg3_phydsp_write(tp, MII_TG3_DSP_EXP97, phy); - tg3_phy_toggle_auxctl_smdsp(tp, false); + TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); } static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up) @@ -1860,9 +1843,9 @@ static void tg3_phy_eee_enable(struct tg3 *tp) (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) && - !tg3_phy_toggle_auxctl_smdsp(tp, true)) { + !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0003); - tg3_phy_toggle_auxctl_smdsp(tp, false); + TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); } val = tr32(TG3_CPMU_EEE_MODE); @@ -2007,7 +1990,7 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) (MII_TG3_CTRL_AS_MASTER | MII_TG3_CTRL_ENABLE_AS_MASTER)); - err = tg3_phy_toggle_auxctl_smdsp(tp, true); + err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp); if (err) return err; @@ -2028,7 +2011,7 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200); tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0000); - tg3_phy_toggle_auxctl_smdsp(tp, false); + TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); tg3_writephy(tp, MII_TG3_CTRL, phy9_orig); @@ -2117,10 +2100,10 @@ static int tg3_phy_reset(struct tg3 *tp) out: if ((tp->phy_flags & TG3_PHYFLG_ADC_BUG) && - !tg3_phy_toggle_auxctl_smdsp(tp, true)) { + !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { tg3_phydsp_write(tp, 0x201f, 0x2aaa); tg3_phydsp_write(tp, 0x000a, 0x0323); - tg3_phy_toggle_auxctl_smdsp(tp, false); + TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); } if (tp->phy_flags & TG3_PHYFLG_5704_A0_BUG) { @@ -2129,14 +2112,14 @@ out: } if (tp->phy_flags & TG3_PHYFLG_BER_BUG) { - if (!tg3_phy_toggle_auxctl_smdsp(tp, true)) { + if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { tg3_phydsp_write(tp, 0x000a, 0x310b); tg3_phydsp_write(tp, 0x201f, 0x9506); tg3_phydsp_write(tp, 0x401f, 0x14e2); - tg3_phy_toggle_auxctl_smdsp(tp, false); + TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); } } else if (tp->phy_flags & TG3_PHYFLG_JITTER_BUG) { - if (!tg3_phy_toggle_auxctl_smdsp(tp, true)) { + if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a); if (tp->phy_flags & TG3_PHYFLG_ADJUST_TRIM) { tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x110b); @@ -2145,7 +2128,7 @@ out: } else tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b); - tg3_phy_toggle_auxctl_smdsp(tp, false); + TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); } } @@ -2993,7 +2976,7 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl) tw32(TG3_CPMU_EEE_MODE, tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE); - err = tg3_phy_toggle_auxctl_smdsp(tp, true); + err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp); if (!err) { u32 err2; @@ -3020,7 +3003,7 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl) val |= MDIO_AN_EEE_ADV_1000T; err = tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val); - err2 = tg3_phy_toggle_auxctl_smdsp(tp, false); + err2 = TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); if (!err) err = err2; } @@ -5233,9 +5216,6 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget) return work_done; } - if (!tnapi->rx_rcb_prod_idx) - return work_done; - /* run RX thread, within the bounds set by NAPI. * All RX "locking" is done by ensuring outside * code synchronizes with tg3->napi.poll() @@ -5674,9 +5654,6 @@ static void tg3_poll_controller(struct net_device *dev) int i; struct tg3 *tp = netdev_priv(dev); - if (tg3_irq_sync(tp)) - return; - for (i = 0; i < tp->irq_cnt; i++) tg3_interrupt(tp->napi[i].irq_vec, &tp->napi[i]); } @@ -6649,12 +6626,6 @@ static int tg3_alloc_consistent(struct tg3 *tp) */ switch (i) { default: - if (tg3_flag(tp, ENABLE_RSS)) { - tnapi->rx_rcb_prod_idx = NULL; - break; - } - /* Fall through */ - case 1: tnapi->rx_rcb_prod_idx = &sblk->idx[0].rx_producer; break; case 2: @@ -7296,11 +7267,16 @@ static int tg3_chip_reset(struct tg3 *tp) tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl); } + if (tg3_flag(tp, ENABLE_APE)) + tp->mac_mode = MAC_MODE_APE_TX_EN | + MAC_MODE_APE_RX_EN | + MAC_MODE_TDE_ENABLE; + if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) { - tp->mac_mode = MAC_MODE_PORT_MODE_TBI; + tp->mac_mode |= MAC_MODE_PORT_MODE_TBI; val = tp->mac_mode; } else if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) { - tp->mac_mode = MAC_MODE_PORT_MODE_GMII; + tp->mac_mode |= MAC_MODE_PORT_MODE_GMII; val = tp->mac_mode; } else val = 0; @@ -8432,11 +8408,12 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) udelay(10); } - tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE | - MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | - MAC_MODE_FHDE_ENABLE; if (tg3_flag(tp, ENABLE_APE)) - tp->mac_mode |= MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN; + tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN; + else + tp->mac_mode = 0; + tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE | + MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE; if (!tg3_flag(tp, 5705_PLUS) && !(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) @@ -9011,7 +8988,7 @@ static int tg3_test_interrupt(struct tg3 *tp) * Turn off MSI one shot mode. Otherwise this test has no * observable way to know whether the interrupt was delivered. */ - if (tg3_flag(tp, 57765_PLUS)) { + if (tg3_flag(tp, 57765_PLUS) && tg3_flag(tp, USING_MSI)) { val = tr32(MSGINT_MODE) | MSGINT_MODE_ONE_SHOT_DISABLE; tw32(MSGINT_MODE, val); } @@ -9039,10 +9016,6 @@ static int tg3_test_interrupt(struct tg3 *tp) break; } - if (tg3_flag(tp, 57765_PLUS) && - tnapi->hw_status->status_tag != tnapi->last_tag) - tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24); - msleep(10); } @@ -9057,7 +9030,7 @@ static int tg3_test_interrupt(struct tg3 *tp) if (intr_ok) { /* Reenable MSI one shot mode. */ - if (tg3_flag(tp, 57765_PLUS)) { + if (tg3_flag(tp, 57765_PLUS) && tg3_flag(tp, USING_MSI)) { val = tr32(MSGINT_MODE) & ~MSGINT_MODE_ONE_SHOT_DISABLE; tw32(MSGINT_MODE, val); } @@ -12974,9 +12947,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) } if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) && - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 || - (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 && + ((tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 && tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) || (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && tp->pci_chip_rev_id != CHIPREV_ID_57765_A0))) @@ -13662,13 +13633,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (tg3_flag(tp, HW_TSO_1) || tg3_flag(tp, HW_TSO_2) || tg3_flag(tp, HW_TSO_3) || - tp->fw_needed) { - /* For firmware TSO, assume ASF is disabled. - * We'll disable TSO later if we discover ASF - * is enabled in tg3_get_eeprom_hw_cfg(). - */ + (tp->fw_needed && !tg3_flag(tp, ENABLE_ASF))) tg3_flag_set(tp, TSO_CAPABLE); - } else { + else { tg3_flag_clear(tp, TSO_CAPABLE); tg3_flag_clear(tp, TSO_BUG); tp->fw_needed = NULL; @@ -13704,9 +13671,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) */ tg3_flag_set(tp, 4G_DMA_BNDRY_BUG); - if (tg3_flag(tp, 5755_PLUS) || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) - tg3_flag_set(tp, SHORT_DMA_BUG); + if (tg3_flag(tp, 5755_PLUS)) + tg3_flag_set(tp, SHORT_DMA_BUG); else tg3_flag_set(tp, 40BIT_DMA_LIMIT_BUG); @@ -13907,12 +13873,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) */ tg3_get_eeprom_hw_cfg(tp); - if (tp->fw_needed && tg3_flag(tp, ENABLE_ASF)) { - tg3_flag_clear(tp, TSO_CAPABLE); - tg3_flag_clear(tp, TSO_BUG); - tp->fw_needed = NULL; - } - if (tg3_flag(tp, ENABLE_APE)) { /* Allow reads and writes to the * APE register and memory space. @@ -14996,7 +14956,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, tp->pm_cap = pm_cap; tp->rx_mode = TG3_DEF_RX_MODE; tp->tx_mode = TG3_DEF_TX_MODE; - tp->irq_sync = 1; if (tg3_debug > 0) tp->msg_enable = tg3_debug; @@ -15319,7 +15278,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev) cancel_work_sync(&tp->reset_task); - if (tg3_flag(tp, USE_PHYLIB)) { + if (!tg3_flag(tp, USE_PHYLIB)) { tg3_phy_fini(tp); tg3_mdio_fini(tp); } diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 3cc22b9eda53..5235f48be1be 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -528,7 +528,6 @@ static void tun_net_init(struct net_device *dev) dev->netdev_ops = &tap_netdev_ops; /* Ethernet TAP Device */ ether_setup(dev); - dev->priv_flags &= ~IFF_TX_SKB_SHARING; random_ether_addr(dev->dev_addr); @@ -1239,18 +1238,10 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, int vnet_hdr_sz; int ret; -#ifdef CONFIG_ANDROID_PARANOID_NETWORK - if (cmd != TUNGETIFF && !capable(CAP_NET_ADMIN)) { - return -EPERM; - } -#endif - - if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89) { + if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89) if (copy_from_user(&ifr, argp, ifreq_len)) return -EFAULT; - } else { - memset(&ifr, 0, sizeof(ifr)); - } + if (cmd == TUNGETFEATURES) { /* Currently this just means: "what IFF flags are valid?". * This is needed because we never checked for invalid flags on diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index e2a988c457df..6998aa6b7bb7 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -314,11 +314,12 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) skb_pull(skb, 4); while (skb->len > 0) { - if ((header & 0x07ff) != ((~header >> 16) & 0x07ff)) + if ((short)(header & 0x0000ffff) != + ~((short)((header & 0xffff0000) >> 16))) { netdev_err(dev->net, "asix_rx_fixup() Bad Header Length\n"); - + } /* get the packet length */ - size = (u16) (header & 0x000007ff); + size = (u16) (header & 0x0000ffff); if ((skb->len) - ((size + 1) & 0xfffe) == 0) { u8 alignment = (unsigned long)skb->data & 0x3; @@ -371,7 +372,7 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) skb_pull(skb, (size + 1) & 0xfffe); - if (skb->len < sizeof(header)) + if (skb->len == 0) break; head = (u8 *) skb->data; @@ -398,7 +399,7 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, u32 packet_len; u32 padbytes = 0xffff0000; - padlen = ((skb->len + 4) & (dev->maxpacket - 1)) ? 0 : 4; + padlen = ((skb->len + 4) % 512) ? 0 : 4; if ((!skb_cloned(skb)) && ((headroom + tailroom) >= (4 + padlen))) { @@ -420,7 +421,7 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, cpu_to_le32s(&packet_len); skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len)); - if (padlen) { + if ((skb->len % 512) == 0) { cpu_to_le32s(&padbytes); memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes)); skb_put(skb, sizeof(padbytes)); @@ -1484,10 +1485,6 @@ static const struct usb_device_id products [] = { // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter" USB_DEVICE (0x6189, 0x182d), .driver_info = (unsigned long) &ax8817x_info, -}, { - // Sitecom LN-031 "USB 2.0 10/100/1000 Ethernet adapter" - USB_DEVICE (0x0df6, 0x0056), - .driver_info = (unsigned long) &ax88178_info, }, { // corega FEther USB2-TX USB_DEVICE (0x07aa, 0x0017), @@ -1504,10 +1501,6 @@ static const struct usb_device_id products [] = { // JVC MP-PRX1 Port Replicator USB_DEVICE (0x04f1, 0x3008), .driver_info = (unsigned long) &ax8817x_info, -}, { - // ASIX AX88772B 10/100 - USB_DEVICE (0x0b95, 0x772b), - .driver_info = (unsigned long) &ax88772_info, }, { // ASIX AX88772 10/100 USB_DEVICE (0x0b95, 0x7720), @@ -1536,10 +1529,6 @@ static const struct usb_device_id products [] = { // DLink DUB-E100 H/W Ver B1 Alternate USB_DEVICE (0x2001, 0x3c05), .driver_info = (unsigned long) &ax88772_info, -}, { - // DLink DUB-E100 H/W Ver C1 - USB_DEVICE (0x2001, 0x1a02), - .driver_info = (unsigned long) &ax88772_info, }, { // Linksys USB1000 USB_DEVICE (0x1737, 0x0039), @@ -1568,10 +1557,6 @@ static const struct usb_device_id products [] = { // ASIX 88772a USB_DEVICE(0x0db0, 0xa877), .driver_info = (unsigned long) &ax88772_info, -}, { - // Asus USB Ethernet Adapter - USB_DEVICE (0x0b95, 0x7e2b), - .driver_info = (unsigned long) &ax88772_info, }, { }, // END }; diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c index 82d43b214f93..882f53f708df 100644 --- a/drivers/net/usb/cdc_eem.c +++ b/drivers/net/usb/cdc_eem.c @@ -93,7 +93,6 @@ static int eem_bind(struct usbnet *dev, struct usb_interface *intf) /* no jumbogram (16K) support for now */ dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN; - dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; return 0; } diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 544c309e0d95..c924ea2bce07 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -83,7 +83,6 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) struct cdc_state *info = (void *) &dev->data; int status; int rndis; - bool android_rndis_quirk = false; struct usb_driver *driver = driver_of(intf); struct usb_cdc_mdlm_desc *desc = NULL; struct usb_cdc_mdlm_detail_desc *detail = NULL; @@ -196,11 +195,6 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) info->control, info->u->bSlaveInterface0, info->data); - /* fall back to hard-wiring for RNDIS */ - if (rndis) { - android_rndis_quirk = true; - goto next_desc; - } goto bad_desc; } if (info->control != intf) { @@ -277,15 +271,11 @@ next_desc: /* Microsoft ActiveSync based and some regular RNDIS devices lack the * CDC descriptors, so we'll hard-wire the interfaces and not check * for descriptors. - * - * Some Android RNDIS devices have a CDC Union descriptor pointing - * to non-existing interfaces. Ignore that and attempt the same - * hard-wired 0 and 1 interfaces. */ - if (rndis && (!info->u || android_rndis_quirk)) { + if (rndis && !info->u) { info->control = usb_ifnum_to_if(dev->udev, 0); info->data = usb_ifnum_to_if(dev->udev, 1); - if (!info->control || !info->data || info->control != intf) { + if (!info->control || !info->data) { dev_dbg(&intf->dev, "rndis: master #0/%p slave #1/%p\n", info->control, @@ -482,7 +472,6 @@ static const struct driver_info wwan_info = { /*-------------------------------------------------------------------------*/ #define HUAWEI_VENDOR_ID 0x12D1 -#define NOVATEL_VENDOR_ID 0x1410 static const struct usb_device_id products [] = { /* @@ -581,13 +570,6 @@ static const struct usb_device_id products [] = { .driver_info = (unsigned long)&wwan_info, }, -/* Logitech Harmony 900 - uses the pseudo-MDLM (BLAN) driver */ -{ - USB_DEVICE_AND_INTERFACE_INFO(0x046d, 0xc11f, USB_CLASS_COMM, - USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), - .driver_info = 0, -}, - /* * WHITELIST!!! * @@ -600,21 +582,6 @@ static const struct usb_device_id products [] = { * because of bugs/quirks in a given product (like Zaurus, above). */ { - /* Novatel USB551L */ - /* This match must come *before* the generic CDC-ETHER match so that - * we get FLAG_WWAN set on the device, since it's descriptors are - * generic CDC-ETHER. - */ - .match_flags = USB_DEVICE_ID_MATCH_VENDOR - | USB_DEVICE_ID_MATCH_PRODUCT - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = NOVATEL_VENDOR_ID, - .idProduct = 0xB001, - .bInterfaceClass = USB_CLASS_COMM, - .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, - .bInterfaceProtocol = USB_CDC_PROTO_NONE, - .driver_info = (unsigned long)&wwan_info, -}, { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), .driver_info = (unsigned long) &cdc_info, diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 6a53161102c4..f33ca6aa29e9 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -54,7 +54,7 @@ #include #include -#define DRIVER_VERSION "04-Aug-2011" +#define DRIVER_VERSION "01-June-2011" /* CDC NCM subclass 3.2.1 */ #define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 @@ -164,8 +164,35 @@ cdc_ncm_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info) usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info)); } +static int +cdc_ncm_do_request(struct cdc_ncm_ctx *ctx, struct usb_cdc_notification *req, + void *data, u16 flags, u16 *actlen, u16 timeout) +{ + int err; + + err = usb_control_msg(ctx->udev, (req->bmRequestType & USB_DIR_IN) ? + usb_rcvctrlpipe(ctx->udev, 0) : + usb_sndctrlpipe(ctx->udev, 0), + req->bNotificationType, req->bmRequestType, + req->wValue, + req->wIndex, data, + req->wLength, timeout); + + if (err < 0) { + if (actlen) + *actlen = 0; + return err; + } + + if (actlen) + *actlen = err; + + return 0; +} + static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) { + struct usb_cdc_notification req; u32 val; u8 flags; u8 iface_no; @@ -174,14 +201,14 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber; - err = usb_control_msg(ctx->udev, - usb_rcvctrlpipe(ctx->udev, 0), - USB_CDC_GET_NTB_PARAMETERS, - USB_TYPE_CLASS | USB_DIR_IN - | USB_RECIP_INTERFACE, - 0, iface_no, &ctx->ncm_parm, - sizeof(ctx->ncm_parm), 10000); - if (err < 0) { + req.bmRequestType = USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE; + req.bNotificationType = USB_CDC_GET_NTB_PARAMETERS; + req.wValue = 0; + req.wIndex = cpu_to_le16(iface_no); + req.wLength = cpu_to_le16(sizeof(ctx->ncm_parm)); + + err = cdc_ncm_do_request(ctx, &req, &ctx->ncm_parm, 0, NULL, 1000); + if (err) { pr_debug("failed GET_NTB_PARAMETERS\n"); return 1; } @@ -227,43 +254,31 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) /* inform device about NTB input size changes */ if (ctx->rx_max != le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)) { + req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | + USB_RECIP_INTERFACE; + req.bNotificationType = USB_CDC_SET_NTB_INPUT_SIZE; + req.wValue = 0; + req.wIndex = cpu_to_le16(iface_no); if (flags & USB_CDC_NCM_NCAP_NTB_INPUT_SIZE) { - struct usb_cdc_ncm_ndp_input_size *ndp_in_sz; - - ndp_in_sz = kzalloc(sizeof(*ndp_in_sz), GFP_KERNEL); - if (!ndp_in_sz) { - err = -ENOMEM; - goto size_err; - } - - err = usb_control_msg(ctx->udev, - usb_sndctrlpipe(ctx->udev, 0), - USB_CDC_SET_NTB_INPUT_SIZE, - USB_TYPE_CLASS | USB_DIR_OUT - | USB_RECIP_INTERFACE, - 0, iface_no, ndp_in_sz, 8, 1000); - kfree(ndp_in_sz); + struct usb_cdc_ncm_ndp_input_size ndp_in_sz; + + req.wLength = 8; + ndp_in_sz.dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); + ndp_in_sz.wNtbInMaxDatagrams = + cpu_to_le16(CDC_NCM_DPT_DATAGRAMS_MAX); + ndp_in_sz.wReserved = 0; + err = cdc_ncm_do_request(ctx, &req, &ndp_in_sz, 0, NULL, + 1000); } else { - __le32 *dwNtbInMaxSize; - dwNtbInMaxSize = kzalloc(sizeof(*dwNtbInMaxSize), - GFP_KERNEL); - if (!dwNtbInMaxSize) { - err = -ENOMEM; - goto size_err; - } - *dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); - - err = usb_control_msg(ctx->udev, - usb_sndctrlpipe(ctx->udev, 0), - USB_CDC_SET_NTB_INPUT_SIZE, - USB_TYPE_CLASS | USB_DIR_OUT - | USB_RECIP_INTERFACE, - 0, iface_no, dwNtbInMaxSize, 4, 1000); - kfree(dwNtbInMaxSize); + __le32 dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); + + req.wLength = 4; + err = cdc_ncm_do_request(ctx, &req, &dwNtbInMaxSize, 0, + NULL, 1000); } -size_err: - if (err < 0) + + if (err) pr_debug("Setting NTB Input Size failed\n"); } @@ -318,24 +333,29 @@ size_err: /* set CRC Mode */ if (flags & USB_CDC_NCM_NCAP_CRC_MODE) { - err = usb_control_msg(ctx->udev, usb_sndctrlpipe(ctx->udev, 0), - USB_CDC_SET_CRC_MODE, - USB_TYPE_CLASS | USB_DIR_OUT - | USB_RECIP_INTERFACE, - USB_CDC_NCM_CRC_NOT_APPENDED, - iface_no, NULL, 0, 1000); - if (err < 0) + req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | + USB_RECIP_INTERFACE; + req.bNotificationType = USB_CDC_SET_CRC_MODE; + req.wValue = cpu_to_le16(USB_CDC_NCM_CRC_NOT_APPENDED); + req.wIndex = cpu_to_le16(iface_no); + req.wLength = 0; + + err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000); + if (err) pr_debug("Setting CRC mode off failed\n"); } /* set NTB format, if both formats are supported */ if (ntb_fmt_supported & USB_CDC_NCM_NTH32_SIGN) { - err = usb_control_msg(ctx->udev, usb_sndctrlpipe(ctx->udev, 0), - USB_CDC_SET_NTB_FORMAT, USB_TYPE_CLASS - | USB_DIR_OUT | USB_RECIP_INTERFACE, - USB_CDC_NCM_NTB16_FORMAT, - iface_no, NULL, 0, 1000); - if (err < 0) + req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | + USB_RECIP_INTERFACE; + req.bNotificationType = USB_CDC_SET_NTB_FORMAT; + req.wValue = cpu_to_le16(USB_CDC_NCM_NTB16_FORMAT); + req.wIndex = cpu_to_le16(iface_no); + req.wLength = 0; + + err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000); + if (err) pr_debug("Setting NTB format to 16-bit failed\n"); } @@ -343,29 +363,23 @@ size_err: /* set Max Datagram Size (MTU) */ if (flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE) { - __le16 *max_datagram_size; + __le16 max_datagram_size; u16 eth_max_sz = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize); - max_datagram_size = kzalloc(sizeof(*max_datagram_size), - GFP_KERNEL); - if (!max_datagram_size) { - err = -ENOMEM; - goto max_dgram_err; - } + req.bmRequestType = USB_TYPE_CLASS | USB_DIR_IN | + USB_RECIP_INTERFACE; + req.bNotificationType = USB_CDC_GET_MAX_DATAGRAM_SIZE; + req.wValue = 0; + req.wIndex = cpu_to_le16(iface_no); + req.wLength = cpu_to_le16(2); - err = usb_control_msg(ctx->udev, usb_rcvctrlpipe(ctx->udev, 0), - USB_CDC_GET_MAX_DATAGRAM_SIZE, - USB_TYPE_CLASS | USB_DIR_IN - | USB_RECIP_INTERFACE, - 0, iface_no, max_datagram_size, - 2, 1000); - if (err < 0) { + err = cdc_ncm_do_request(ctx, &req, &max_datagram_size, 0, NULL, + 1000); + if (err) { pr_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n", CDC_NCM_MIN_DATAGRAM_SIZE); - kfree(max_datagram_size); } else { - ctx->max_datagram_size = - le16_to_cpu(*max_datagram_size); + ctx->max_datagram_size = le16_to_cpu(max_datagram_size); /* Check Eth descriptor value */ if (eth_max_sz < CDC_NCM_MAX_DATAGRAM_SIZE) { if (ctx->max_datagram_size > eth_max_sz) @@ -382,17 +396,17 @@ size_err: CDC_NCM_MIN_DATAGRAM_SIZE; /* if value changed, update device */ - err = usb_control_msg(ctx->udev, - usb_sndctrlpipe(ctx->udev, 0), - USB_CDC_SET_MAX_DATAGRAM_SIZE, - USB_TYPE_CLASS | USB_DIR_OUT - | USB_RECIP_INTERFACE, - 0, - iface_no, max_datagram_size, - 2, 1000); - kfree(max_datagram_size); -max_dgram_err: - if (err < 0) + req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | + USB_RECIP_INTERFACE; + req.bNotificationType = USB_CDC_SET_MAX_DATAGRAM_SIZE; + req.wValue = 0; + req.wIndex = cpu_to_le16(iface_no); + req.wLength = 2; + max_datagram_size = cpu_to_le16(ctx->max_datagram_size); + + err = cdc_ncm_do_request(ctx, &req, &max_datagram_size, + 0, NULL, 1000); + if (err) pr_debug("SET_MAX_DATAGRAM_SIZE failed\n"); } @@ -658,7 +672,7 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) u32 rem; u32 offset; u32 last_offset; - u16 n = 0, index; + u16 n = 0; u8 ready2send = 0; /* if there is a remaining skb, it gets priority */ @@ -846,8 +860,8 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) cpu_to_le16(sizeof(ctx->tx_ncm.nth16)); ctx->tx_ncm.nth16.wSequence = cpu_to_le16(ctx->tx_seq); ctx->tx_ncm.nth16.wBlockLength = cpu_to_le16(last_offset); - index = ALIGN(sizeof(struct usb_cdc_ncm_nth16), ctx->tx_ndp_modulus); - ctx->tx_ncm.nth16.wNdpIndex = cpu_to_le16(index); + ctx->tx_ncm.nth16.wNdpIndex = ALIGN(sizeof(struct usb_cdc_ncm_nth16), + ctx->tx_ndp_modulus); memcpy(skb_out->data, &(ctx->tx_ncm.nth16), sizeof(ctx->tx_ncm.nth16)); ctx->tx_seq++; @@ -860,11 +874,12 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) ctx->tx_ncm.ndp16.wLength = cpu_to_le16(rem); ctx->tx_ncm.ndp16.wNextNdpIndex = 0; /* reserved */ - memcpy(((u8 *)skb_out->data) + index, + memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wNdpIndex, &(ctx->tx_ncm.ndp16), sizeof(ctx->tx_ncm.ndp16)); - memcpy(((u8 *)skb_out->data) + index + sizeof(ctx->tx_ncm.ndp16), + memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wNdpIndex + + sizeof(ctx->tx_ncm.ndp16), &(ctx->tx_ncm.dpe16), (ctx->tx_curr_frame_num + 1) * sizeof(struct usb_cdc_ncm_dpe16)); diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index ab43674af75c..81126ff85e05 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c @@ -59,10 +59,6 @@ #define USB_PRODUCT_IPHONE_3G 0x1292 #define USB_PRODUCT_IPHONE_3GS 0x1294 #define USB_PRODUCT_IPHONE_4 0x1297 -#define USB_PRODUCT_IPAD 0x129a -#define USB_PRODUCT_IPHONE_4_VZW 0x129c -#define USB_PRODUCT_IPHONE_4S 0x12a0 -#define USB_PRODUCT_IPHONE_5 0x12a8 #define IPHETH_USBINTF_CLASS 255 #define IPHETH_USBINTF_SUBCLASS 253 @@ -102,22 +98,6 @@ static struct usb_device_id ipheth_table[] = { USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4, IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, IPHETH_USBINTF_PROTO) }, - { USB_DEVICE_AND_INTERFACE_INFO( - USB_VENDOR_APPLE, USB_PRODUCT_IPAD, - IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, - IPHETH_USBINTF_PROTO) }, - { USB_DEVICE_AND_INTERFACE_INFO( - USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4_VZW, - IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, - IPHETH_USBINTF_PROTO) }, - { USB_DEVICE_AND_INTERFACE_INFO( - USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4S, - IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, - IPHETH_USBINTF_PROTO) }, - { USB_DEVICE_AND_INTERFACE_INFO( - USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_5, - IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, - IPHETH_USBINTF_PROTO) }, { } }; MODULE_DEVICE_TABLE(usb, ipheth_table); diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 3362449a2d9b..ad0298f9b5f9 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -1308,7 +1308,7 @@ static int kaweth_internal_control_msg(struct usb_device *usb_dev, int retv; int length = 0; /* shut up GCC */ - urb = usb_alloc_urb(0, GFP_ATOMIC); + urb = usb_alloc_urb(0, GFP_NOIO); if (!urb) return -ENOMEM; diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index ef3b236b5145..041fb7d43c4f 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -977,6 +977,7 @@ static void rtl8150_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); if (dev) { set_bit(RTL8150_UNPLUG, &dev->flags); + tasklet_disable(&dev->tl); tasklet_kill(&dev->tl); unregister_netdev(dev->netdev); unlink_all_urbs(dev); diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index e7732508b8f1..ed1b43210584 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c @@ -678,7 +678,7 @@ static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap) return -EIO; } - *datap = le16_to_cpu(*attrdata); + *datap = *attrdata; kfree(attrdata); return result; @@ -943,7 +943,7 @@ struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, struct sk_buff *skb, } static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 }; -static const struct sierra_net_info_data sierra_net_info_data_direct_ip = { +static const struct sierra_net_info_data sierra_net_info_data_68A3 = { .rx_urb_size = 8 * 1024, .whitelist = { .infolen = ARRAY_SIZE(sierra_net_ifnum_list), @@ -951,7 +951,7 @@ static const struct sierra_net_info_data sierra_net_info_data_direct_ip = { } }; -static const struct driver_info sierra_net_info_direct_ip = { +static const struct driver_info sierra_net_info_68A3 = { .description = "Sierra Wireless USB-to-WWAN Modem", .flags = FLAG_WWAN | FLAG_SEND_ZLP, .bind = sierra_net_bind, @@ -959,18 +959,12 @@ static const struct driver_info sierra_net_info_direct_ip = { .status = sierra_net_status, .rx_fixup = sierra_net_rx_fixup, .tx_fixup = sierra_net_tx_fixup, - .data = (unsigned long)&sierra_net_info_data_direct_ip, + .data = (unsigned long)&sierra_net_info_data_68A3, }; static const struct usb_device_id products[] = { {USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */ - .driver_info = (unsigned long) &sierra_net_info_direct_ip}, - {USB_DEVICE(0x0F3D, 0x68A3), /* AT&T Direct IP modem */ - .driver_info = (unsigned long) &sierra_net_info_direct_ip}, - {USB_DEVICE(0x1199, 0x68AA), /* Sierra Wireless Direct IP LTE modem */ - .driver_info = (unsigned long) &sierra_net_info_direct_ip}, - {USB_DEVICE(0x0F3D, 0x68AA), /* AT&T Direct IP LTE modem */ - .driver_info = (unsigned long) &sierra_net_info_direct_ip}, + .driver_info = (unsigned long) &sierra_net_info_68A3}, {}, /* last item */ }; diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index de0de3ee6392..15b3d6888ae9 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -1049,7 +1049,6 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->ethtool_ops = &smsc75xx_ethtool_ops; dev->net->flags |= IFF_MULTICAST; dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD; - dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; return 0; } diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index e5c15bbbe62f..f74f3ce71526 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -1190,7 +1190,7 @@ static const struct driver_info smsc95xx_info = { .rx_fixup = smsc95xx_rx_fixup, .tx_fixup = smsc95xx_tx_fixup, .status = smsc95xx_status, - .flags = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR, + .flags = FLAG_ETHER | FLAG_SEND_ZLP, }; static const struct usb_device_id products[] = { diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 806372952782..ce395fe5de26 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -277,32 +277,17 @@ int usbnet_change_mtu (struct net_device *net, int new_mtu) } EXPORT_SYMBOL_GPL(usbnet_change_mtu); -/* The caller must hold list->lock */ -static void __usbnet_queue_skb(struct sk_buff_head *list, - struct sk_buff *newsk, enum skb_state state) -{ - struct skb_data *entry = (struct skb_data *) newsk->cb; - - __skb_queue_tail(list, newsk); - entry->state = state; -} - /*-------------------------------------------------------------------------*/ /* some LK 2.4 HCDs oopsed if we freed or resubmitted urbs from * completion callbacks. 2.5 should have fixed those bugs... */ -static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb, - struct sk_buff_head *list, enum skb_state state) +static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct sk_buff_head *list) { unsigned long flags; - enum skb_state old_state; - struct skb_data *entry = (struct skb_data *) skb->cb; spin_lock_irqsave(&list->lock, flags); - old_state = entry->state; - entry->state = state; __skb_unlink(skb, list); spin_unlock(&list->lock); spin_lock(&dev->done.lock); @@ -310,7 +295,6 @@ static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb, if (dev->done.qlen == 1) tasklet_schedule(&dev->bh); spin_unlock_irqrestore(&dev->done.lock, flags); - return old_state; } /* some work can't be done in tasklets, so we use keventd @@ -351,6 +335,7 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) entry = (struct skb_data *) skb->cb; entry->urb = urb; entry->dev = dev; + entry->state = rx_start; entry->length = 0; usb_fill_bulk_urb (urb, dev->udev, dev->in, @@ -382,7 +367,7 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) tasklet_schedule (&dev->bh); break; case 0: - __usbnet_queue_skb(&dev->rxq, skb, rx_start); + __skb_queue_tail (&dev->rxq, skb); } } else { netif_dbg(dev, ifdown, dev->net, "rx: stopped\n"); @@ -433,17 +418,16 @@ static void rx_complete (struct urb *urb) struct skb_data *entry = (struct skb_data *) skb->cb; struct usbnet *dev = entry->dev; int urb_status = urb->status; - enum skb_state state; skb_put (skb, urb->actual_length); - state = rx_done; + entry->state = rx_done; entry->urb = NULL; switch (urb_status) { /* success */ case 0: if (skb->len < dev->net->hard_header_len) { - state = rx_cleanup; + entry->state = rx_cleanup; dev->net->stats.rx_errors++; dev->net->stats.rx_length_errors++; netif_dbg(dev, rx_err, dev->net, @@ -482,7 +466,7 @@ static void rx_complete (struct urb *urb) "rx throttle %d\n", urb_status); } block: - state = rx_cleanup; + entry->state = rx_cleanup; entry->urb = urb; urb = NULL; break; @@ -493,18 +477,17 @@ block: // FALLTHROUGH default: - state = rx_cleanup; + entry->state = rx_cleanup; dev->net->stats.rx_errors++; netif_dbg(dev, rx_err, dev->net, "rx status %d\n", urb_status); break; } - state = defer_bh(dev, skb, &dev->rxq, state); + defer_bh(dev, skb, &dev->rxq); if (urb) { if (netif_running (dev->net) && - !test_bit (EVENT_RX_HALT, &dev->flags) && - state != unlink_start) { + !test_bit (EVENT_RX_HALT, &dev->flags)) { rx_submit (dev, urb, GFP_ATOMIC); return; } @@ -590,34 +573,18 @@ EXPORT_SYMBOL_GPL(usbnet_purge_paused_rxq); static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q) { unsigned long flags; - struct sk_buff *skb; + struct sk_buff *skb, *skbnext; int count = 0; spin_lock_irqsave (&q->lock, flags); - while (!skb_queue_empty(q)) { + skb_queue_walk_safe(q, skb, skbnext) { struct skb_data *entry; struct urb *urb; int retval; - skb_queue_walk(q, skb) { - entry = (struct skb_data *) skb->cb; - if (entry->state != unlink_start) - goto found; - } - break; -found: - entry->state = unlink_start; + entry = (struct skb_data *) skb->cb; urb = entry->urb; - /* - * Get reference count of the URB to avoid it to be - * freed during usb_unlink_urb, which may trigger - * use-after-free problem inside usb_unlink_urb since - * usb_unlink_urb is always racing with .complete - * handler(include defer_bh). - */ - usb_get_urb(urb); - spin_unlock_irqrestore(&q->lock, flags); // during some PM-driven resume scenarios, // these (async) unlinks complete immediately retval = usb_unlink_urb (urb); @@ -625,8 +592,6 @@ found: netdev_dbg(dev->net, "unlink urb err, %d\n", retval); else count++; - usb_put_urb(urb); - spin_lock_irqsave(&q->lock, flags); } spin_unlock_irqrestore (&q->lock, flags); return count; @@ -1057,7 +1022,9 @@ static void tx_complete (struct urb *urb) } usb_autopm_put_interface_async(dev->intf); - (void) defer_bh(dev, skb, &dev->txq, tx_done); + urb->dev = NULL; + entry->state = tx_done; + defer_bh(dev, skb, &dev->txq); } /*-------------------------------------------------------------------------*/ @@ -1110,6 +1077,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, entry = (struct skb_data *) skb->cb; entry->urb = urb; entry->dev = dev; + entry->state = tx_start; entry->length = length; usb_fill_bulk_urb (urb, dev->udev, dev->out, @@ -1149,7 +1117,6 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, usb_anchor_urb(urb, &dev->deferred); /* no use to process more packets */ netif_stop_queue(net); - usb_put_urb(urb); spin_unlock_irqrestore(&dev->txq.lock, flags); netdev_dbg(dev->net, "Delaying transmission for resumption\n"); goto deferred; @@ -1169,7 +1136,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, break; case 0: net->trans_start = jiffies; - __usbnet_queue_skb(&dev->txq, skb, tx_start); + __skb_queue_tail (&dev->txq, skb); if (dev->txq.qlen >= TX_QLEN (dev)) netif_stop_queue (net); } @@ -1291,8 +1258,6 @@ void usbnet_disconnect (struct usb_interface *intf) cancel_work_sync(&dev->kevent); - usb_scuttle_anchored_urbs(&dev->deferred); - if (dev->driver_info->unbind) dev->driver_info->unbind (dev, intf); diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c index c1e6a446d13c..1a2234c20514 100644 --- a/drivers/net/usb/zaurus.c +++ b/drivers/net/usb/zaurus.c @@ -332,11 +332,6 @@ static const struct usb_device_id products [] = { .driver_info = ZAURUS_PXA_INFO, }, { - /* Motorola Rokr E6 */ - USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6027, USB_CLASS_COMM, - USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), - .driver_info = (unsigned long) &bogus_mdlm_info, -}, { /* Motorola MOTOMAGX phones */ USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6425, USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), @@ -354,13 +349,6 @@ static const struct usb_device_id products [] = { ZAURUS_MASTER_INTERFACE, .driver_info = OLYMPUS_MXL_INFO, }, - -/* Logitech Harmony 900 - uses the pseudo-MDLM (BLAN) driver */ -{ - USB_DEVICE_AND_INTERFACE_INFO(0x046d, 0xc11f, USB_CLASS_COMM, - USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), - .driver_info = (unsigned long) &bogus_mdlm_info, -}, { }, // END }; MODULE_DEVICE_TABLE(usb, products); diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 6c0a3b0f0afd..8461576fa015 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -262,8 +262,6 @@ static void veth_setup(struct net_device *dev) { ether_setup(dev); - dev->priv_flags &= ~IFF_TX_SKB_SHARING; - dev->netdev_ops = &veth_netdev_ops; dev->ethtool_ops = &veth_ethtool_ops; dev->features |= NETIF_F_LLTX; @@ -421,9 +419,7 @@ static void veth_dellink(struct net_device *dev, struct list_head *head) unregister_netdevice_queue(peer, head); } -static const struct nla_policy veth_policy[VETH_INFO_MAX + 1] = { - [VETH_INFO_PEER] = { .len = sizeof(struct ifinfomsg) }, -}; +static const struct nla_policy veth_policy[VETH_INFO_MAX + 1]; static struct rtnl_link_ops veth_link_ops = { .kind = DRV_NAME, diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index c7e493461e0a..06daa9d6fee8 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -2513,6 +2513,9 @@ static int velocity_close(struct net_device *dev) if (dev->irq != 0) free_irq(dev->irq, dev); + /* Power down the chip */ + pci_set_power_state(vptr->pdev, PCI_D3hot); + velocity_free_rings(vptr); vptr->flags &= (~VELOCITY_FLAGS_OPENED); diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 0ef676dcb9c3..67402350d0df 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -830,8 +830,13 @@ vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, ctx->l4_hdr_size = ((struct tcphdr *) skb_transport_header(skb))->doff * 4; else if (iph->protocol == IPPROTO_UDP) + /* + * Use tcp header size so that bytes to + * be copied are more than required by + * the device. + */ ctx->l4_hdr_size = - sizeof(struct udphdr); + sizeof(struct tcphdr); else ctx->l4_hdr_size = 0; } else { diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index 862be0500091..e08d75e3f170 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -69,10 +69,10 @@ /* * Version numbers */ -#define VMXNET3_DRIVER_VERSION_STRING "1.1.29.0-k" +#define VMXNET3_DRIVER_VERSION_STRING "1.1.18.0-k" /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ -#define VMXNET3_DRIVER_VERSION_NUM 0x01011D00 +#define VMXNET3_DRIVER_VERSION_NUM 0x01011200 #if defined(CONFIG_PCI_MSI) /* RSS only makes sense if MSI-X is supported. */ diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c index 13f9997ede4c..fc433f28c047 100644 --- a/drivers/net/wan/hdlc_fr.c +++ b/drivers/net/wan/hdlc_fr.c @@ -1083,10 +1083,9 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type) used = pvc_is_used(pvc); - if (type == ARPHRD_ETHER) { + if (type == ARPHRD_ETHER) dev = alloc_netdev(0, "pvceth%d", ether_setup); - dev->priv_flags &= ~IFF_TX_SKB_SHARING; - } else + else dev = alloc_netdev(0, "pvc%d", pvc_setup); if (!dev) { diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index 78c51ab2e9ba..f1e1643dc3eb 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c @@ -8,7 +8,6 @@ * as published by the Free Software Foundation. */ -#include #include #include #include diff --git a/drivers/net/wimax/i2400m/i2400m-usb.h b/drivers/net/wimax/i2400m/i2400m-usb.h index 9f1e947f3557..6650fde99e1d 100644 --- a/drivers/net/wimax/i2400m/i2400m-usb.h +++ b/drivers/net/wimax/i2400m/i2400m-usb.h @@ -152,9 +152,6 @@ enum { /* Device IDs */ USB_DEVICE_ID_I6050 = 0x0186, USB_DEVICE_ID_I6050_2 = 0x0188, - USB_DEVICE_ID_I6150 = 0x07d6, - USB_DEVICE_ID_I6150_2 = 0x07d7, - USB_DEVICE_ID_I6150_3 = 0x07d9, USB_DEVICE_ID_I6250 = 0x0187, }; diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c index 0a998638e1b5..2edd8fe1c1f3 100644 --- a/drivers/net/wimax/i2400m/netdev.c +++ b/drivers/net/wimax/i2400m/netdev.c @@ -606,8 +606,7 @@ static void i2400m_get_drvinfo(struct net_device *net_dev, struct i2400m *i2400m = net_dev_to_i2400m(net_dev); strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver) - 1); - strncpy(info->fw_version, - i2400m->fw_name ? : "", sizeof(info->fw_version) - 1); + strncpy(info->fw_version, i2400m->fw_name, sizeof(info->fw_version) - 1); if (net_dev->dev.parent) strncpy(info->bus_info, dev_name(net_dev->dev.parent), sizeof(info->bus_info) - 1); diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c index 0ddc8db2a45b..298f2b0b6311 100644 --- a/drivers/net/wimax/i2400m/usb.c +++ b/drivers/net/wimax/i2400m/usb.c @@ -491,9 +491,6 @@ int i2400mu_probe(struct usb_interface *iface, switch (id->idProduct) { case USB_DEVICE_ID_I6050: case USB_DEVICE_ID_I6050_2: - case USB_DEVICE_ID_I6150: - case USB_DEVICE_ID_I6150_2: - case USB_DEVICE_ID_I6150_3: case USB_DEVICE_ID_I6250: i2400mu->i6050 = 1; break; @@ -743,9 +740,6 @@ static struct usb_device_id i2400mu_id_table[] = { { USB_DEVICE(0x8086, USB_DEVICE_ID_I6050) }, { USB_DEVICE(0x8086, USB_DEVICE_ID_I6050_2) }, - { USB_DEVICE(0x8087, USB_DEVICE_ID_I6150) }, - { USB_DEVICE(0x8087, USB_DEVICE_ID_I6150_2) }, - { USB_DEVICE(0x8087, USB_DEVICE_ID_I6150_3) }, { USB_DEVICE(0x8086, USB_DEVICE_ID_I6250) }, { USB_DEVICE(0x8086, 0x0181) }, { USB_DEVICE(0x8086, 0x1403) }, diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index f1d88c571bc4..f354bd4e121e 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -268,16 +268,9 @@ config MWL8K To compile this driver as a module, choose M here: the module will be called mwl8k. If unsure, say N. -config WIFI_CONTROL_FUNC - bool "Enable WiFi control function abstraction" - help - Enables Power/Reset/Carddetect function abstraction - source "drivers/net/wireless/ath/Kconfig" source "drivers/net/wireless/b43/Kconfig" source "drivers/net/wireless/b43legacy/Kconfig" -source "drivers/net/wireless/bcm4329/Kconfig" -source "drivers/net/wireless/bcmdhd/Kconfig" source "drivers/net/wireless/hostap/Kconfig" source "drivers/net/wireless/ipw2x00/Kconfig" source "drivers/net/wireless/iwlwifi/Kconfig" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 8ceae0a8ba0f..7bba6a82b875 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -58,6 +58,3 @@ obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/ obj-$(CONFIG_IWM) += iwmc3200wifi/ obj-$(CONFIG_MWIFIEX) += mwifiex/ - -obj-$(CONFIG_BCM4329) += bcm4329/ -obj-$(CONFIG_BCMDHD) += bcmdhd/ diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index e1b3e3c134fd..55cf71fbffe3 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -2823,7 +2823,6 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, dev->wireless_data = &ai->wireless_data; dev->irq = irq; dev->base_addr = port; - dev->priv_flags &= ~IFF_TX_SKB_SHARING; SET_NETDEV_DEV(dev, dmdev); diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 1ae8913c085c..b6c5d3715b96 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1748,8 +1748,6 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) if (dma_mapping_error(sc->dev, bf->skbaddr)) { ATH5K_ERR(sc, "beacon DMA mapping failed\n"); - dev_kfree_skb_any(skb); - bf->skb = NULL; return -EIO; } @@ -1834,6 +1832,8 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ath5k_txbuf_free_skb(sc, avf->bbuf); avf->bbuf->skb = skb; ret = ath5k_beacon_setup(sc, avf->bbuf); + if (ret) + avf->bbuf->skb = NULL; out: return ret; } @@ -1854,7 +1854,6 @@ ath5k_beacon_send(struct ath5k_softc *sc) struct ath5k_vif *avf; struct ath5k_buf *bf; struct sk_buff *skb; - int err; ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n"); @@ -1903,6 +1902,11 @@ ath5k_beacon_send(struct ath5k_softc *sc) avf = (void *)vif->drv_priv; bf = avf->bbuf; + if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION || + sc->opmode == NL80211_IFTYPE_MONITOR)) { + ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); + return; + } /* * Stop any current dma and put the new frame on the queue. @@ -1916,17 +1920,8 @@ ath5k_beacon_send(struct ath5k_softc *sc) /* refresh the beacon for AP or MESH mode */ if (sc->opmode == NL80211_IFTYPE_AP || - sc->opmode == NL80211_IFTYPE_MESH_POINT) { - err = ath5k_beacon_update(sc->hw, vif); - if (err) - return; - } - - if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION || - sc->opmode == NL80211_IFTYPE_MONITOR)) { - ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf->skb); - return; - } + sc->opmode == NL80211_IFTYPE_MESH_POINT) + ath5k_beacon_update(sc->hw, vif); trace_ath5k_tx(sc, bf->skb, &sc->txqs[sc->bhalq]); diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 4e4e7c3dcdde..bfb6481f01f9 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -502,6 +502,9 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR, ATH9K_ANI_CCK_WEAK_SIG_THR); + ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) | + ATH9K_RX_FILTER_PHYERR); + ath9k_ani_restart(ah); return; } @@ -522,6 +525,8 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, aniState->firstepLevel); + ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) & + ~ATH9K_RX_FILTER_PHYERR); ath9k_ani_restart(ah); ENABLE_REGWRITE_BUFFER(ah); diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 0f23b1a789e3..441bb33f17ad 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -489,6 +489,8 @@ static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah) ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows); ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows); ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows); + ATH_ALLOC_BANK(ah->addac5416_21, + ah->iniAddac.ia_rows * ah->iniAddac.ia_columns); ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows); return 0; @@ -517,6 +519,7 @@ static void ar5008_hw_rf_free_ext_banks(struct ath_hw *ah) ATH_FREE_BANK(ah->analogBank6Data); ATH_FREE_BANK(ah->analogBank6TPCData); ATH_FREE_BANK(ah->analogBank7Data); + ATH_FREE_BANK(ah->addac5416_21); ATH_FREE_BANK(ah->bank6Temp); #undef ATH_FREE_BANK @@ -796,7 +799,27 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO); ah->eep_ops->set_addac(ah, chan); - REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites); + if (AR_SREV_5416_22_OR_LATER(ah)) { + REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites); + } else { + struct ar5416IniArray temp; + u32 addacSize = + sizeof(u32) * ah->iniAddac.ia_rows * + ah->iniAddac.ia_columns; + + /* For AR5416 2.0/2.1 */ + memcpy(ah->addac5416_21, + ah->iniAddac.ia_array, addacSize); + + /* override CLKDRV value at [row, column] = [31, 1] */ + (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0; + + temp.ia_array = ah->addac5416_21; + temp.ia_columns = ah->iniAddac.ia_columns; + temp.ia_rows = ah->iniAddac.ia_rows; + REG_WRITE_ARRAY(&temp, 1, regWrites); + } + REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC); ENABLE_REGWRITE_BUFFER(ah); diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index 2d394af82171..2d4c0910295b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -41,8 +41,7 @@ static bool ar9002_hw_is_cal_supported(struct ath_hw *ah, case ADC_DC_CAL: /* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */ if (!IS_CHAN_B(chan) && - !((IS_CHAN_2GHZ(chan) || IS_CHAN_A_FAST_CLOCK(ah, chan)) && - IS_CHAN_HT20(chan))) + !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) supported = true; break; } diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 30bf703c0448..f344cc2b3d59 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -179,25 +179,6 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac, ARRAY_SIZE(ar5416Addac), 2); } - - /* iniAddac needs to be modified for these chips */ - if (AR_SREV_9160(ah) || !AR_SREV_5416_22_OR_LATER(ah)) { - struct ar5416IniArray *addac = &ah->iniAddac; - u32 size = sizeof(u32) * addac->ia_rows * addac->ia_columns; - u32 *data; - - data = kmalloc(size, GFP_KERNEL); - if (!data) - return; - - memcpy(data, addac->ia_array, size); - addac->ia_array = data; - - if (!AR_SREV_5416_22_OR_LATER(ah)) { - /* override CLKDRV value */ - INI_RA(addac, 31,1) = 0; - } - } } /* Support for Japan ch.14 (2484) spread */ @@ -328,7 +309,11 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, u8 i; u32 val; - if (ah->is_pciexpress != true || ah->aspm_enabled != true) + if (ah->is_pciexpress != true) + return; + + /* Do not touch SerDes registers */ + if (ah->config.pcie_powersave_enable == 2) return; /* Nothing to do on restore for 11N */ diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index c84c493a9e10..e8ac70da5ac7 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -34,98 +34,98 @@ static const u32 ar9300_2p2_radio_postamble[][5] = { static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, - {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, - {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, - {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, - {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, - {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, - {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, - {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, - {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, - {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, - {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, - {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, - {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, - {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, - {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, - {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, - {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, - {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, - {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, - {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, - {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, - {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, - {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, - {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, - {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, - {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, - {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, - {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, - {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, - {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, - {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, - {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, - {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, - {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, - {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, - {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, - {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, - {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, - {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, - {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, - {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, - {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, - {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, - {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, - {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, - {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, - {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, - {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, - {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, - {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, + {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, + {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, + {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, + {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402}, + {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, + {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, + {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, + {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, + {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, + {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, + {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, + {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, + {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, + {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, + {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861}, + {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81}, + {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83}, + {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84}, + {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3}, + {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5}, + {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9}, + {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb}, + {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, + {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, + {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, + {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, + {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, + {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, + {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402}, + {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404}, + {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, + {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, + {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, + {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, + {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, + {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, + {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, + {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, + {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, + {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861}, + {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81}, + {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83}, + {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84}, + {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3}, + {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5}, + {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9}, + {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb}, + {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, - {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, - {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, - {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, - {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, - {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, - {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, - {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000}, + {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501}, + {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501}, + {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03}, + {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04}, + {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04}, + {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, + {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, + {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, + {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, + {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, + {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, + {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, + {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, @@ -1516,7 +1516,7 @@ static const u32 ar9300_2p2_mac_core[][2] = { {0x00008258, 0x00000000}, {0x0000825c, 0x40000000}, {0x00008260, 0x00080922}, - {0x00008264, 0x9d400010}, + {0x00008264, 0x9bc00010}, {0x00008268, 0xffffffff}, {0x0000826c, 0x0000ffff}, {0x00008270, 0x00000000}, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 7c2aaad24ed0..f48051c50092 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -643,9 +643,8 @@ static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement, outlier_idx = max_idx; else outlier_idx = min_idx; - - mp_coeff[outlier_idx] = mp_avg; } + mp_coeff[outlier_idx] = mp_avg; } static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 417106b9f2b9..ff8150e46f0e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -68,7 +68,7 @@ static int ar9003_hw_power_interpolate(int32_t x, static const struct ar9300_eeprom ar9300_default = { .eepromVersion = 2, .templateVersion = 2, - .macAddr = {0, 2, 3, 4, 5, 6}, + .macAddr = {1, 2, 3, 4, 5, 6}, .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, .baseEepHeader = { @@ -306,7 +306,7 @@ static const struct ar9300_eeprom ar9300_default = { { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, - { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, @@ -883,7 +883,7 @@ static const struct ar9300_eeprom ar9300_x113 = { { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, - { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, @@ -2039,7 +2039,7 @@ static const struct ar9300_eeprom ar9300_x112 = { { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, - { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 7f7bc947e008..ab21a4915981 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -69,13 +69,13 @@ #define AR9300_BASE_ADDR 0x3ff #define AR9300_BASE_ADDR_512 0x1ff -#define AR9300_OTP_BASE (AR_SREV_9340(ah) ? 0x30000 : 0x14000) -#define AR9300_OTP_STATUS (AR_SREV_9340(ah) ? 0x30018 : 0x15f18) +#define AR9300_OTP_BASE 0x14000 +#define AR9300_OTP_STATUS 0x15f18 #define AR9300_OTP_STATUS_TYPE 0x7 #define AR9300_OTP_STATUS_VALID 0x4 #define AR9300_OTP_STATUS_ACCESS_BUSY 0x2 #define AR9300_OTP_STATUS_SM_BUSY 0x1 -#define AR9300_OTP_READ_DATA (AR_SREV_9340(ah) ? 0x3001c : 0x15f1c) +#define AR9300_OTP_READ_DATA 0x15f1c enum targetPowerHTRates { HT_TARGET_RATE_0_8_16, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 7e02fb4b4b50..392bf0f8ff16 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -351,7 +351,11 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off) { - if (ah->is_pciexpress != true || ah->aspm_enabled != true) + if (ah->is_pciexpress != true) + return; + + /* Do not touch SerDes registers */ + if (ah->config.pcie_powersave_enable == 2) return; /* Nothing to do on restore for 11N */ diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 7880dca026cf..10d71f7d3fc2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -255,6 +255,8 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, return -EIO; } + if (status & AR_TxOpExceeded) + ts->ts_status |= ATH9K_TXERR_XTXOP; ts->ts_rateindex = MS(status, AR_FinalTxIdx); ts->ts_seqnum = MS(status, AR_SeqNum); ts->tid = MS(status, AR_TxTid); @@ -265,8 +267,6 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, ts->ts_status = 0; ts->ts_flags = 0; - if (status & AR_TxOpExceeded) - ts->ts_status |= ATH9K_TXERR_XTXOP; status = ACCESS_ONCE(ads->status2); ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00); ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01); @@ -629,7 +629,8 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, rxs->rs_status |= ATH9K_RXERR_DECRYPT; else if (rxsp->status11 & AR_MichaelErr) rxs->rs_status |= ATH9K_RXERR_MIC; - else if (rxsp->status11 & AR_KeyMiss) + + if (rxsp->status11 & AR_KeyMiss) rxs->rs_status |= ATH9K_RXERR_DECRYPT; } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 2364b5f41147..443090d278e3 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -570,12 +570,12 @@ #define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300) -#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + (AR_SREV_9485(ah) ? \ - 0x3c8 : 0x448)) -#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + (AR_SREV_9485(ah) ? \ - 0x3c4 : 0x440)) -#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + (AR_SREV_9485(ah) ? \ - 0x3f0 : 0x48c)) +#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + AR_SREV_9485(ah) ? \ + 0x3c8 : 0x448) +#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + AR_SREV_9485(ah) ? \ + 0x3c4 : 0x440) +#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + AR_SREV_9485(ah) ? \ + 0x3f0 : 0x48c) #define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \ (AR_SREV_9485(ah) ? \ 0x3d0 : 0x450) + ((_i) << 2)) @@ -848,7 +848,7 @@ #define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) #define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + 0x240) #define AR_PHY_TX_IQCAL_STATUS_B1 (AR_SM1_BASE + 0x48c) -#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM1_BASE + 0x450 + ((_i) << 2)) +#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM_BASE + 0x450 + ((_i) << 2)) /* * Channel 2 Register Map diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index d16d029f81a9..611ea6ce8508 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h @@ -521,7 +521,7 @@ static const u32 ar9485_1_1_radio_postamble[][2] = { {0x000160ac, 0x24611800}, {0x000160b0, 0x03284f3e}, {0x0001610c, 0x00170000}, - {0x00016140, 0x50804008}, + {0x00016140, 0x10804008}, }; static const u32 ar9485_1_1_mac_postamble[][5] = { @@ -603,7 +603,7 @@ static const u32 ar9485_1_1_radio_core[][2] = { static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = { /* Addr allmodes */ - {0x00018c00, 0x18052e5e}, + {0x00018c00, 0x10052e5e}, {0x00018c04, 0x000801d8}, {0x00018c08, 0x0000080c}, }; @@ -776,7 +776,7 @@ static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = { static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = { /* Addr allmodes */ - {0x00018c00, 0x18013e5e}, + {0x00018c00, 0x10013e5e}, {0x00018c04, 0x000801d8}, {0x00018c08, 0x0000080c}, }; @@ -882,7 +882,7 @@ static const u32 ar9485_fast_clock_1_1_baseband_postamble[][3] = { static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = { /* Addr allmodes */ - {0x00018c00, 0x18012e5e}, + {0x00018c00, 0x10012e5e}, {0x00018c04, 0x000801d8}, {0x00018c08, 0x0000080c}, }; @@ -1021,7 +1021,7 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = { static const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = { /* Addr allmodes */ - {0x00018c00, 0x18053e5e}, + {0x00018c00, 0x10053e5e}, {0x00018c04, 0x000801d8}, {0x00018c08, 0x0000080c}, }; diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index b109c4708587..d4d8ceced89b 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -159,7 +159,6 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, skb->len, DMA_TO_DEVICE); dev_kfree_skb_any(skb); bf->bf_buf_addr = 0; - bf->bf_mpdu = NULL; } /* Get a new beacon from mac80211 */ diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 1f2f97f6038f..a1250c586e40 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -19,6 +19,7 @@ /* Common calibration code */ +#define ATH9K_NF_TOO_HIGH -60 static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer) { @@ -334,10 +335,10 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf) "NF calibrated [%s] [chain %d] is %d\n", (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]); - if (nf[i] > limit->max) { + if (nf[i] > ATH9K_NF_TOO_HIGH) { ath_dbg(common, ATH_DBG_CALIBRATE, "NF[%d] (%d) > MAX (%d), correcting to MAX\n", - i, nf[i], limit->max); + i, nf[i], ATH9K_NF_TOO_HIGH); nf[i] = limit->max; } else if (nf[i] < limit->min) { ath_dbg(common, ATH_DBG_CALIBRATE, diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 5513c0aa4c1b..260f1f37a60e 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -37,7 +37,6 @@ static struct usb_device_id ath9k_hif_usb_ids[] = { { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */ { USB_DEVICE(0x040D, 0x3801) }, /* VIA */ { USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */ - { USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */ { USB_DEVICE(0x0cf3, 0x7015), .driver_info = AR9287_USB }, /* Atheros */ diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 4f7843ae6800..1b90ed8795c3 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -342,8 +342,6 @@ void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv, skb, htc_hdr->endpoint_id, txok); - } else { - kfree_skb(skb); } } diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 9130a5aa1c9e..1be7c8bbef84 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -299,14 +299,6 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah) REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); } -static void ath9k_hw_aspm_init(struct ath_hw *ah) -{ - struct ath_common *common = ath9k_hw_common(ah); - - if (common->bus_ops->aspm_init) - common->bus_ops->aspm_init(common); -} - /* This should work for all families including legacy */ static bool ath9k_hw_chip_test(struct ath_hw *ah) { @@ -367,6 +359,7 @@ static void ath9k_hw_init_config(struct ath_hw *ah) ah->config.additional_swba_backoff = 0; ah->config.ack_6mb = 0x0; ah->config.cwm_ignore_extcca = 0; + ah->config.pcie_powersave_enable = 0; ah->config.pcie_clock_req = 0; ah->config.pcie_waen = 0; ah->config.analog_shiftreg = 1; @@ -530,7 +523,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) { if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || - ((AR_SREV_9160(ah) || AR_SREV_9280(ah) || AR_SREV_9287(ah)) && + ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) && !ah->is_pciexpress)) { ah->config.serialize_regmode = SER_REG_MODE_ON; @@ -584,7 +577,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) if (ah->is_pciexpress) - ath9k_hw_aspm_init(ah); + ath9k_hw_configpcipowersave(ah, 0, 0); else ath9k_hw_disablepcie(ah); @@ -682,25 +675,13 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) { - struct ath_common *common = ath9k_hw_common(ah); - int i = 0; - REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); udelay(100); REG_SET_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); - while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) { - + while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) udelay(100); - if (WARN_ON_ONCE(i >= 100)) { - ath_err(common, "PLL4 meaurement not done\n"); - break; - } - - i++; - } - return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3; } EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); @@ -1943,10 +1924,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->num_gpio_pins = AR9271_NUM_GPIO; else if (AR_DEVID_7010(ah)) pCap->num_gpio_pins = AR7010_NUM_GPIO; - else if (AR_SREV_9300_20_OR_LATER(ah)) - pCap->num_gpio_pins = AR9300_NUM_GPIO; - else if (AR_SREV_9287_11_OR_LATER(ah)) - pCap->num_gpio_pins = AR9287_NUM_GPIO; else if (AR_SREV_9285_12_OR_LATER(ah)) pCap->num_gpio_pins = AR9285_NUM_GPIO; else if (AR_SREV_9280_20_OR_LATER(ah)) diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 9dc2666fd1c9..4b157c53d1a8 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -215,6 +215,7 @@ struct ath9k_ops_config { int additional_swba_backoff; int ack_6mb; u32 cwm_ignore_extcca; + u8 pcie_powersave_enable; bool pcieSerDesWrite; u8 pcie_clock_req; u32 pcie_waen; @@ -670,7 +671,6 @@ struct ath_hw { bool sw_mgmt_crypto; bool is_pciexpress; - bool aspm_enabled; bool is_monitoring; bool need_an_top2_fixup; u16 tx_trig_level; @@ -763,6 +763,7 @@ struct ath_hw { u32 *analogBank6Data; u32 *analogBank6TPCData; u32 *analogBank7Data; + u32 *addac5416_21; u32 *bank6Temp; u8 txpower_limit; @@ -869,7 +870,6 @@ struct ath_bus_ops { bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); void (*bt_coex_prep)(struct ath_common *common); void (*extn_synch_en)(struct ath_common *common); - void (*aspm_init)(struct ath_common *common); }; static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 5a9fd21faf8d..45c585a337e9 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -665,10 +665,8 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band) static void ath9k_init_txpower_limits(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath9k_channel *curchan = ah->curchan; - ah->txchainmask = common->tx_chainmask; if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ); if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index b6b523a897e5..c2091f1f4096 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -645,7 +645,8 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, rs->rs_status |= ATH9K_RXERR_DECRYPT; else if (ads.ds_rxstatus8 & AR_MichaelErr) rs->rs_status |= ATH9K_RXERR_MIC; - else if (ads.ds_rxstatus8 & AR_KeyMiss) + + if (ads.ds_rxstatus8 & AR_KeyMiss) rs->rs_status |= ATH9K_RXERR_DECRYPT; } diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 633f96203e2f..2ca351fe6d3c 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -648,15 +648,6 @@ void ath_hw_pll_work(struct work_struct *work) hw_pll_work.work); u32 pll_sqsum; - /* - * ensure that the PLL WAR is executed only - * after the STA is associated (or) if the - * beaconing had started in interfaces that - * uses beacons. - */ - if (!(sc->sc_flags & SC_OP_BEACONS)) - return; - if (AR_SREV_9485(sc->sc_ah)) { ath9k_ps_wakeup(sc); @@ -1837,9 +1828,6 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw, struct ath_softc *sc = hw->priv; struct ath_node *an = (struct ath_node *) sta->drv_priv; - if (!(sc->sc_flags & SC_OP_TXAGGR)) - return; - switch (cmd) { case STA_NOTIFY_SLEEP: an->sleeping = true; @@ -2272,11 +2260,7 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) mutex_lock(&sc->mutex); ah->coverage_class = coverage_class; - - ath9k_ps_wakeup(sc); ath9k_hw_init_global_settings(ah); - ath9k_ps_restore(sc); - mutex_unlock(&sc->mutex); } diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index be4ea1329813..3bad0b2cf9a3 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -16,7 +16,6 @@ #include #include -#include #include #include "ath9k.h" @@ -116,38 +115,12 @@ static void ath_pci_extn_synch_enable(struct ath_common *common) pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl); } -static void ath_pci_aspm_init(struct ath_common *common) -{ - struct ath_softc *sc = (struct ath_softc *) common->priv; - struct ath_hw *ah = sc->sc_ah; - struct pci_dev *pdev = to_pci_dev(sc->dev); - struct pci_dev *parent; - int pos; - u8 aspm; - - if (!pci_is_pcie(pdev)) - return; - - parent = pdev->bus->self; - if (WARN_ON(!parent)) - return; - - pos = pci_pcie_cap(parent); - pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm); - if (aspm & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) { - ah->aspm_enabled = true; - /* Initialize PCIe PM and SERDES registers. */ - ath9k_hw_configpcipowersave(ah, 0, 0); - } -} - static const struct ath_bus_ops ath_pci_bus_ops = { .ath_bus_type = ATH_PCI, .read_cachesize = ath_pci_read_cachesize, .eeprom_read = ath_pci_eeprom_read, .bt_coex_prep = ath_pci_bt_coex_prep, .extn_synch_en = ath_pci_extn_synch_enable, - .aspm_init = ath_pci_aspm_init, }; static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 9d965e37b00a..ba7f36ab0a74 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1252,9 +1252,7 @@ static void ath_rc_init(struct ath_softc *sc, ath_rc_priv->max_valid_rate = k; ath_rc_sort_validrates(rate_table, ath_rc_priv); - ath_rc_priv->rate_max_phy = (k > 4) ? - ath_rc_priv->valid_rate_index[k-4] : - ath_rc_priv->valid_rate_index[k-1]; + ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4]; ath_rc_priv->rate_table = rate_table; ath_dbg(common, ATH_DBG_CONFIG, @@ -1328,7 +1326,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, fc = hdr->frame_control; for (i = 0; i < sc->hw->max_rates; i++) { struct ieee80211_tx_rate *rate = &tx_info->status.rates[i]; - if (rate->idx < 0 || !rate->count) + if (!rate->count) break; final_ts_idx = i; diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 932b3ab94072..07e35e59c9e3 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -423,9 +423,12 @@ void ath_rx_cleanup(struct ath_softc *sc) u32 ath_calcrxfilter(struct ath_softc *sc) { +#define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR) + u32 rfilt; - rfilt = ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST + rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE) + | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST | ATH9K_RX_FILTER_MCAST; if (sc->rx.rxfilter & FIF_PROBE_REQ) @@ -1697,6 +1700,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) struct ieee80211_hw *hw = sc->hw; struct ieee80211_hdr *hdr; int retval; + bool decrypt_error = false; struct ath_rx_status rs; enum ath9k_rx_qtype qtype; bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); @@ -1718,7 +1722,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) tsf_lower = tsf & 0xffffffff; do { - bool decrypt_error = false; /* If handling rx interrupt and flush is in progress => exit */ if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0)) break; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 6f6f1002e5db..33443bcaa8d9 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -272,7 +272,6 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) } bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); - bf->bf_next = NULL; list_del(&bf->list); spin_unlock_bh(&sc->tx.txbuflock); @@ -1489,7 +1488,6 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, if (tid) INCR(tid->seq_start, IEEE80211_SEQ_MAX); - bf->bf_next = NULL; bf->bf_lastbf = bf; fi = get_frame_info(bf->bf_mpdu); ath_buf_set_rate(sc, bf, fi->framelen); diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index b54966c1dcf2..54d093c2ab44 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1066,10 +1066,8 @@ static int carl9170_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, * the high througput speed in 802.11n networks. */ - if (!is_main_vif(ar, vif)) { - mutex_lock(&ar->mutex); + if (!is_main_vif(ar, vif)) goto err_softw; - } /* * While the hardware supports *catch-all* key, for offloading diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index f190f3219fc5..e94084fcf6f5 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -1245,7 +1245,6 @@ static bool carl9170_tx_ps_drop(struct ar9170 *ar, struct sk_buff *skb) atomic_dec(&ar->tx_ampdu_upload); tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; - carl9170_release_dev_space(ar, skb); carl9170_tx_status(ar, skb, false); return true; } diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 7c2e09a1cc04..eb4159686985 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1571,8 +1571,7 @@ static void handle_irq_beacon(struct b43_wldev *dev) u32 cmd, beacon0_valid, beacon1_valid; if (!b43_is_mode(wl, NL80211_IFTYPE_AP) && - !b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) && - !b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) + !b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT)) return; /* This is the bottom half of the asynchronous beacon update. */ @@ -2401,13 +2400,6 @@ static int b43_upload_microcode(struct b43_wldev *dev) b43_print_fw_helptext(dev->wl, 1); err = -EOPNOTSUPP; goto error; - } else if (fwrev >= 598) { - b43err(dev->wl, "YOUR FIRMWARE IS TOO NEW. Support for " - "firmware 598 and up requires kernel 3.2 or newer. You " - "have to install older firmware or upgrade kernel.\n"); - b43_print_fw_helptext(dev->wl, 1); - err = -EOPNOTSUPP; - goto error; } dev->fw.rev = fwrev; dev->fw.patch = fwpatch; diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 4e8b48183fee..1ab8861dd43a 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -3843,8 +3843,6 @@ static void b43legacy_remove(struct ssb_device *dev) cancel_work_sync(&wldev->restart_work); B43legacy_WARN_ON(!wl); - if (!wldev->fw.ucode) - return; /* NULL if fw never loaded */ if (wl->current_dev == wldev) ieee80211_unregister_hw(wl->hw); diff --git a/drivers/net/wireless/bcm4329/Kconfig b/drivers/net/wireless/bcm4329/Kconfig deleted file mode 100644 index ca5760d32385..000000000000 --- a/drivers/net/wireless/bcm4329/Kconfig +++ /dev/null @@ -1,27 +0,0 @@ -config BCM4329 - tristate "Broadcom 4329 wireless cards support" - depends on MMC - select WIRELESS_EXT - select WEXT_PRIV - ---help--- - This module adds support for wireless adapters based on - Broadcom 4329 chipset. - - This driver uses the kernel's wireless extensions subsystem. - - If you choose to build a module, it'll be called dhd. Say M if - unsure. - -config BCM4329_FW_PATH - depends on BCM4329 - string "Firmware path" - default "/system/etc/firmware/fw_bcm4329.bin" - ---help--- - Path to the firmware file. - -config BCM4329_NVRAM_PATH - depends on BCM4329 - string "NVRAM path" - default "/proc/calibration" - ---help--- - Path to the calibration file. diff --git a/drivers/net/wireless/bcm4329/Makefile b/drivers/net/wireless/bcm4329/Makefile deleted file mode 100644 index 5a662be7fc53..000000000000 --- a/drivers/net/wireless/bcm4329/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# bcm4329 -DHDCFLAGS = -DLINUX -DBCMDRIVER -DBCMDONGLEHOST -DDHDTHREAD -DBCMWPA2 \ - -DUNRELEASEDCHIP -Dlinux -DDHD_SDALIGN=64 -DMAX_HDR_READ=64 \ - -DDHD_FIRSTREAD=64 -DDHD_GPL -DDHD_SCHED -DBDC -DTOE -DDHD_BCMEVENTS \ - -DSHOW_EVENTS -DBCMSDIO -DDHD_GPL -DBCMLXSDMMC -DBCMPLATFORM_BUS \ - -Wall -Wstrict-prototypes -Werror -DOOB_INTR_ONLY -DCUSTOMER_HW2 \ - -DDHD_USE_STATIC_BUF -DMMC_SDIO_ABORT -DDHD_DEBUG_TRAP -DSOFTAP \ - -DEMBEDDED_PLATFORM -DARP_OFFLOAD_SUPPORT -DPKT_FILTER_SUPPORT \ - -DGET_CUSTOM_MAC_ENABLE -DSET_RANDOM_MAC_SOFTAP -DCSCAN -DHW_OOB \ - -DKEEP_ALIVE -DPNO_SUPPORT \ - -Idrivers/net/wireless/bcm4329 -Idrivers/net/wireless/bcm4329/include - -DHDOFILES = dhd_linux.o linux_osl.o bcmutils.o dhd_common.o dhd_custom_gpio.o \ - wl_iw.o siutils.o sbutils.o aiutils.o hndpmu.o bcmwifi.o dhd_sdio.o \ - dhd_linux_sched.o dhd_cdc.o bcmsdh_sdmmc.o bcmsdh.o bcmsdh_linux.o \ - bcmsdh_sdmmc_linux.o - -obj-$(CONFIG_BCM4329) += bcm4329.o -bcm4329-objs += $(DHDOFILES) -EXTRA_CFLAGS = $(DHDCFLAGS) -EXTRA_LDFLAGS += --strip-debug diff --git a/drivers/net/wireless/bcm4329/aiutils.c b/drivers/net/wireless/bcm4329/aiutils.c deleted file mode 100644 index df48ac0d83d4..000000000000 --- a/drivers/net/wireless/bcm4329/aiutils.c +++ /dev/null @@ -1,686 +0,0 @@ -/* - * Misc utility routines for accessing chip-specific features - * of the SiliconBackplane-based Broadcom chips. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: aiutils.c,v 1.6.4.7.4.6 2010/04/21 20:43:47 Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "siutils_priv.h" - -STATIC uint32 -get_asd(si_t *sih, uint32 *eromptr, uint sp, uint ad, uint st, - uint32 *addrl, uint32 *addrh, uint32 *sizel, uint32 *sizeh); - - -/* EROM parsing */ - -static uint32 -get_erom_ent(si_t *sih, uint32 *eromptr, uint32 mask, uint32 match) -{ - uint32 ent; - uint inv = 0, nom = 0; - - while (TRUE) { - ent = R_REG(si_osh(sih), (uint32 *)(uintptr)(*eromptr)); - *eromptr += sizeof(uint32); - - if (mask == 0) - break; - - if ((ent & ER_VALID) == 0) { - inv++; - continue; - } - - if (ent == (ER_END | ER_VALID)) - break; - - if ((ent & mask) == match) - break; - - nom++; - } - - SI_MSG(("%s: Returning ent 0x%08x\n", __FUNCTION__, ent)); - if (inv + nom) - SI_MSG((" after %d invalid and %d non-matching entries\n", inv, nom)); - return ent; -} - -STATIC uint32 -get_asd(si_t *sih, uint32 *eromptr, uint sp, uint ad, uint st, - uint32 *addrl, uint32 *addrh, uint32 *sizel, uint32 *sizeh) -{ - uint32 asd, sz, szd; - - asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID); - if (((asd & ER_TAG1) != ER_ADD) || - (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) || - ((asd & AD_ST_MASK) != st)) { - /* This is not what we want, "push" it back */ - *eromptr -= sizeof(uint32); - return 0; - } - *addrl = asd & AD_ADDR_MASK; - if (asd & AD_AG32) - *addrh = get_erom_ent(sih, eromptr, 0, 0); - else - *addrh = 0; - *sizeh = 0; - sz = asd & AD_SZ_MASK; - if (sz == AD_SZ_SZD) { - szd = get_erom_ent(sih, eromptr, 0, 0); - *sizel = szd & SD_SZ_MASK; - if (szd & SD_SG32) - *sizeh = get_erom_ent(sih, eromptr, 0, 0); - } else - *sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT); - - SI_MSG((" SP %d, ad %d: st = %d, 0x%08x_0x%08x @ 0x%08x_0x%08x\n", - sp, ad, st, *sizeh, *sizel, *addrh, *addrl)); - - return asd; -} - -/* parse the enumeration rom to identify all cores */ -void -ai_scan(si_t *sih, void *regs, uint devid) -{ - si_info_t *sii = SI_INFO(sih); - chipcregs_t *cc = (chipcregs_t *)regs; - uint32 erombase, eromptr, eromlim; - - erombase = R_REG(sii->osh, &cc->eromptr); - - switch (BUSTYPE(sih->bustype)) { - case SI_BUS: - eromptr = (uintptr)REG_MAP(erombase, SI_CORE_SIZE); - break; - - case PCI_BUS: - /* Set wrappers address */ - sii->curwrap = (void *)((uintptr)regs + SI_CORE_SIZE); - - /* Now point the window at the erom */ - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, erombase); - eromptr = (uint32)(uintptr)regs; - break; - - case SPI_BUS: - case SDIO_BUS: - eromptr = erombase; - break; - - case PCMCIA_BUS: - default: - SI_ERROR(("Don't know how to do AXI enumertion on bus %d\n", sih->bustype)); - ASSERT(0); - return; - } - eromlim = eromptr + ER_REMAPCONTROL; - - SI_MSG(("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%08x, eromlim = 0x%08x\n", - regs, erombase, eromptr, eromlim)); - while (eromptr < eromlim) { - uint32 cia, cib, base, cid, mfg, crev, nmw, nsw, nmp, nsp; - uint32 mpd, asd, addrl, addrh, sizel, sizeh; - uint i, j, idx; - bool br; - - br = FALSE; - - /* Grok a component */ - cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI); - if (cia == (ER_END | ER_VALID)) { - SI_MSG(("Found END of erom after %d cores\n", sii->numcores)); - return; - } - base = eromptr - sizeof(uint32); - cib = get_erom_ent(sih, &eromptr, 0, 0); - - if ((cib & ER_TAG) != ER_CI) { - SI_ERROR(("CIA not followed by CIB\n")); - goto error; - } - - cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT; - mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT; - crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT; - nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT; - nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT; - nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT; - nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT; - - SI_MSG(("Found component 0x%04x/0x%4x rev %d at erom addr 0x%08x, with nmw = %d, " - "nsw = %d, nmp = %d & nsp = %d\n", - mfg, cid, crev, base, nmw, nsw, nmp, nsp)); - - if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0)) - continue; - if ((nmw + nsw == 0)) { - /* A component which is not a core */ - if (cid == OOB_ROUTER_CORE_ID) { - asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, - &addrl, &addrh, &sizel, &sizeh); - if (asd != 0) { - sii->common_info->oob_router = addrl; - } - } - continue; - } - - idx = sii->numcores; -/* sii->eromptr[idx] = base; */ - sii->common_info->cia[idx] = cia; - sii->common_info->cib[idx] = cib; - sii->common_info->coreid[idx] = cid; - - for (i = 0; i < nmp; i++) { - mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID); - if ((mpd & ER_TAG) != ER_MP) { - SI_ERROR(("Not enough MP entries for component 0x%x\n", cid)); - goto error; - } - SI_MSG((" Master port %d, mp: %d id: %d\n", i, - (mpd & MPD_MP_MASK) >> MPD_MP_SHIFT, - (mpd & MPD_MUI_MASK) >> MPD_MUI_SHIFT)); - } - - /* First Slave Address Descriptor should be port 0: - * the main register space for the core - */ - asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh, &sizel, &sizeh); - if (asd == 0) { - /* Try again to see if it is a bridge */ - asd = get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl, &addrh, - &sizel, &sizeh); - if (asd != 0) - br = TRUE; - else - if ((addrh != 0) || (sizeh != 0) || (sizel != SI_CORE_SIZE)) { - SI_ERROR(("First Slave ASD for core 0x%04x malformed " - "(0x%08x)\n", cid, asd)); - goto error; - } - } - sii->common_info->coresba[idx] = addrl; - sii->common_info->coresba_size[idx] = sizel; - /* Get any more ASDs in port 0 */ - j = 1; - do { - asd = get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl, &addrh, - &sizel, &sizeh); - if ((asd != 0) && (j == 1) && (sizel == SI_CORE_SIZE)) - sii->common_info->coresba2[idx] = addrl; - sii->common_info->coresba2_size[idx] = sizel; - j++; - } while (asd != 0); - - /* Go through the ASDs for other slave ports */ - for (i = 1; i < nsp; i++) { - j = 0; - do { - asd = get_asd(sih, &eromptr, i, j++, AD_ST_SLAVE, &addrl, &addrh, - &sizel, &sizeh); - } while (asd != 0); - if (j == 0) { - SI_ERROR((" SP %d has no address descriptors\n", i)); - goto error; - } - } - - /* Now get master wrappers */ - for (i = 0; i < nmw; i++) { - asd = get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl, &addrh, - &sizel, &sizeh); - if (asd == 0) { - SI_ERROR(("Missing descriptor for MW %d\n", i)); - goto error; - } - if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) { - SI_ERROR(("Master wrapper %d is not 4KB\n", i)); - goto error; - } - if (i == 0) - sii->common_info->wrapba[idx] = addrl; - } - - /* And finally slave wrappers */ - for (i = 0; i < nsw; i++) { - uint fwp = (nsp == 1) ? 0 : 1; - asd = get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP, &addrl, &addrh, - &sizel, &sizeh); - if (asd == 0) { - SI_ERROR(("Missing descriptor for SW %d\n", i)); - goto error; - } - if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) { - SI_ERROR(("Slave wrapper %d is not 4KB\n", i)); - goto error; - } - if ((nmw == 0) && (i == 0)) - sii->common_info->wrapba[idx] = addrl; - } - - /* Don't record bridges */ - if (br) - continue; - - /* Done with core */ - sii->numcores++; - } - - SI_ERROR(("Reached end of erom without finding END")); - -error: - sii->numcores = 0; - return; -} - -/* This function changes the logical "focus" to the indicated core. - * Return the current core's virtual address. - */ -void * -ai_setcoreidx(si_t *sih, uint coreidx) -{ - si_info_t *sii = SI_INFO(sih); - uint32 addr = sii->common_info->coresba[coreidx]; - uint32 wrap = sii->common_info->wrapba[coreidx]; - void *regs; - - if (coreidx >= sii->numcores) - return (NULL); - - /* - * If the user has provided an interrupt mask enabled function, - * then assert interrupts are disabled before switching the core. - */ - ASSERT((sii->intrsenabled_fn == NULL) || !(*(sii)->intrsenabled_fn)((sii)->intr_arg)); - - switch (BUSTYPE(sih->bustype)) { - case SI_BUS: - /* map new one */ - if (!sii->common_info->regs[coreidx]) { - sii->common_info->regs[coreidx] = REG_MAP(addr, SI_CORE_SIZE); - ASSERT(GOODREGS(sii->common_info->regs[coreidx])); - } - sii->curmap = regs = sii->common_info->regs[coreidx]; - if (!sii->common_info->wrappers[coreidx]) { - sii->common_info->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE); - ASSERT(GOODREGS(sii->common_info->wrappers[coreidx])); - } - sii->curwrap = sii->common_info->wrappers[coreidx]; - break; - - - case SPI_BUS: - case SDIO_BUS: - sii->curmap = regs = (void *)((uintptr)addr); - sii->curwrap = (void *)((uintptr)wrap); - break; - - case PCMCIA_BUS: - default: - ASSERT(0); - regs = NULL; - break; - } - - sii->curmap = regs; - sii->curidx = coreidx; - - return regs; -} - -/* Return the number of address spaces in current core */ -int -ai_numaddrspaces(si_t *sih) -{ - return 2; -} - -/* Return the address of the nth address space in the current core */ -uint32 -ai_addrspace(si_t *sih, uint asidx) -{ - si_info_t *sii; - uint cidx; - - sii = SI_INFO(sih); - cidx = sii->curidx; - - if (asidx == 0) - return sii->common_info->coresba[cidx]; - else if (asidx == 1) - return sii->common_info->coresba2[cidx]; - else { - SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", - __FUNCTION__, asidx)); - return 0; - } -} - -/* Return the size of the nth address space in the current core */ -uint32 -ai_addrspacesize(si_t *sih, uint asidx) -{ - si_info_t *sii; - uint cidx; - - sii = SI_INFO(sih); - cidx = sii->curidx; - - if (asidx == 0) - return sii->common_info->coresba_size[cidx]; - else if (asidx == 1) - return sii->common_info->coresba2_size[cidx]; - else { - SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", - __FUNCTION__, asidx)); - return 0; - } -} - -uint -ai_flag(si_t *sih) -{ - si_info_t *sii; - aidmp_t *ai; - - sii = SI_INFO(sih); - ai = sii->curwrap; - - return (R_REG(sii->osh, &ai->oobselouta30) & 0x1f); -} - -void -ai_setint(si_t *sih, int siflag) -{ -} - -void -ai_write_wrap_reg(si_t *sih, uint32 offset, uint32 val) -{ - si_info_t *sii = SI_INFO(sih); - aidmp_t *ai = sii->curwrap; - W_REG(sii->osh, (uint32 *)((uint8 *)ai+offset), val); - return; -} - -uint -ai_corevendor(si_t *sih) -{ - si_info_t *sii; - uint32 cia; - - sii = SI_INFO(sih); - cia = sii->common_info->cia[sii->curidx]; - return ((cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT); -} - -uint -ai_corerev(si_t *sih) -{ - si_info_t *sii; - uint32 cib; - - sii = SI_INFO(sih); - cib = sii->common_info->cib[sii->curidx]; - return ((cib & CIB_REV_MASK) >> CIB_REV_SHIFT); -} - -bool -ai_iscoreup(si_t *sih) -{ - si_info_t *sii; - aidmp_t *ai; - - sii = SI_INFO(sih); - ai = sii->curwrap; - - return (((R_REG(sii->osh, &ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) == SICF_CLOCK_EN) && - ((R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) == 0)); -} - -/* - * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, - * switch back to the original core, and return the new value. - * - * When using the silicon backplane, no fidleing with interrupts or core switches are needed. - * - * Also, when using pci/pcie, we can optimize away the core switching for pci registers - * and (on newer pci cores) chipcommon registers. - */ -uint -ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) -{ - uint origidx = 0; - uint32 *r = NULL; - uint w; - uint intr_val = 0; - bool fast = FALSE; - si_info_t *sii; - - sii = SI_INFO(sih); - - ASSERT(GOODIDX(coreidx)); - ASSERT(regoff < SI_CORE_SIZE); - ASSERT((val & ~mask) == 0); - - if (coreidx >= SI_MAXCORES) - return 0; - - if (BUSTYPE(sih->bustype) == SI_BUS) { - /* If internal bus, we can always get at everything */ - fast = TRUE; - /* map if does not exist */ - if (!sii->common_info->wrappers[coreidx]) { - sii->common_info->regs[coreidx] = - REG_MAP(sii->common_info->coresba[coreidx], SI_CORE_SIZE); - ASSERT(GOODREGS(sii->common_info->regs[coreidx])); - } - r = (uint32 *)((uchar *)sii->common_info->regs[coreidx] + regoff); - } else if (BUSTYPE(sih->bustype) == PCI_BUS) { - /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */ - - if ((sii->common_info->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) { - /* Chipc registers are mapped at 12KB */ - - fast = TRUE; - r = (uint32 *)((char *)sii->curmap + PCI_16KB0_CCREGS_OFFSET + regoff); - } else if (sii->pub.buscoreidx == coreidx) { - /* pci registers are at either in the last 2KB of an 8KB window - * or, in pcie and pci rev 13 at 8KB - */ - fast = TRUE; - if (SI_FAST(sii)) - r = (uint32 *)((char *)sii->curmap + - PCI_16KB0_PCIREGS_OFFSET + regoff); - else - r = (uint32 *)((char *)sii->curmap + - ((regoff >= SBCONFIGOFF) ? - PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) + - regoff); - } - } - - if (!fast) { - INTR_OFF(sii, intr_val); - - /* save current core index */ - origidx = si_coreidx(&sii->pub); - - /* switch core */ - r = (uint32*) ((uchar*) ai_setcoreidx(&sii->pub, coreidx) + regoff); - } - ASSERT(r != NULL); - - /* mask and set */ - if (mask || val) { - w = (R_REG(sii->osh, r) & ~mask) | val; - W_REG(sii->osh, r, w); - } - - /* readback */ - w = R_REG(sii->osh, r); - - if (!fast) { - /* restore core index */ - if (origidx != coreidx) - ai_setcoreidx(&sii->pub, origidx); - - INTR_RESTORE(sii, intr_val); - } - - return (w); -} - -void -ai_core_disable(si_t *sih, uint32 bits) -{ - si_info_t *sii; - volatile uint32 dummy; - aidmp_t *ai; - - sii = SI_INFO(sih); - - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - /* if core is already in reset, just return */ - if (R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) - return; - - W_REG(sii->osh, &ai->ioctrl, bits); - dummy = R_REG(sii->osh, &ai->ioctrl); - OSL_DELAY(10); - - W_REG(sii->osh, &ai->resetctrl, AIRC_RESET); - OSL_DELAY(1); -} - -/* reset and re-enable a core - * inputs: - * bits - core specific bits that are set during and after reset sequence - * resetbits - core specific bits that are set only during reset sequence - */ -void -ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits) -{ - si_info_t *sii; - aidmp_t *ai; - volatile uint32 dummy; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - /* - * Must do the disable sequence first to work for arbitrary current core state. - */ - ai_core_disable(sih, (bits | resetbits)); - - /* - * Now do the initialization sequence. - */ - W_REG(sii->osh, &ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN)); - dummy = R_REG(sii->osh, &ai->ioctrl); - W_REG(sii->osh, &ai->resetctrl, 0); - OSL_DELAY(1); - - W_REG(sii->osh, &ai->ioctrl, (bits | SICF_CLOCK_EN)); - dummy = R_REG(sii->osh, &ai->ioctrl); - OSL_DELAY(1); -} - - -void -ai_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - aidmp_t *ai; - uint32 w; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - ASSERT((val & ~mask) == 0); - - if (mask || val) { - w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val); - W_REG(sii->osh, &ai->ioctrl, w); - } -} - -uint32 -ai_core_cflags(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - aidmp_t *ai; - uint32 w; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - ASSERT((val & ~mask) == 0); - - if (mask || val) { - w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val); - W_REG(sii->osh, &ai->ioctrl, w); - } - - return R_REG(sii->osh, &ai->ioctrl); -} - -uint32 -ai_core_sflags(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - aidmp_t *ai; - uint32 w; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - ASSERT((val & ~mask) == 0); - ASSERT((mask & ~SISF_CORE_BITS) == 0); - - if (mask || val) { - w = ((R_REG(sii->osh, &ai->iostatus) & ~mask) | val); - W_REG(sii->osh, &ai->iostatus, w); - } - - return R_REG(sii->osh, &ai->iostatus); -} diff --git a/drivers/net/wireless/bcm4329/bcmpcispi.c b/drivers/net/wireless/bcm4329/bcmpcispi.c deleted file mode 100644 index 1a8b6717f924..000000000000 --- a/drivers/net/wireless/bcm4329/bcmpcispi.c +++ /dev/null @@ -1,630 +0,0 @@ -/* - * Broadcom SPI over PCI-SPI Host Controller, low-level hardware driver - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmpcispi.c,v 1.22.2.4.4.5.6.1 2010/08/13 00:26:05 Exp $ - */ - -#include -#include - -#include /* SDIO Specs */ -#include /* bcmsdh to/from specific controller APIs */ -#include /* to get msglevel bit values */ - -#include -#include -#include -#include /* BRCM PCI-SPI Host Controller Register definitions */ - - -/* ndis_osl.h needs to do a runtime check of the osh to map - * R_REG/W_REG to bus specific access similar to linux_osl.h. - * Until then... - */ -/* linux */ - -#define SPIPCI_RREG R_REG -#define SPIPCI_WREG W_REG - - -#define SPIPCI_ANDREG(osh, r, v) SPIPCI_WREG(osh, (r), (SPIPCI_RREG(osh, r) & (v))) -#define SPIPCI_ORREG(osh, r, v) SPIPCI_WREG(osh, (r), (SPIPCI_RREG(osh, r) | (v))) - - -int bcmpcispi_dump = 0; /* Set to dump complete trace of all SPI bus transactions */ - -typedef struct spih_info_ { - uint bar0; /* BAR0 of PCI Card */ - uint bar1; /* BAR1 of PCI Card */ - osl_t *osh; /* osh handle */ - spih_pciregs_t *pciregs; /* PCI Core Registers */ - spih_regs_t *regs; /* SPI Controller Registers */ - uint8 rev; /* PCI Card Revision ID */ -} spih_info_t; - - -/* Attach to PCI-SPI Host Controller Hardware */ -bool -spi_hw_attach(sdioh_info_t *sd) -{ - osl_t *osh; - spih_info_t *si; - - sd_trace(("%s: enter\n", __FUNCTION__)); - - osh = sd->osh; - - if ((si = (spih_info_t *)MALLOC(osh, sizeof(spih_info_t))) == NULL) { - sd_err(("%s: out of memory, malloced %d bytes\n", __FUNCTION__, MALLOCED(osh))); - return FALSE; - } - - bzero(si, sizeof(spih_info_t)); - - sd->controller = si; - - si->osh = sd->osh; - si->rev = OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_REV, 4) & 0xFF; - - if (si->rev < 3) { - sd_err(("Host controller %d not supported, please upgrade to rev >= 3\n", si->rev)); - MFREE(osh, si, sizeof(spih_info_t)); - return (FALSE); - } - - sd_err(("Attaching to Generic PCI SPI Host Controller Rev %d\n", si->rev)); - - /* FPGA Revision < 3 not supported by driver anymore. */ - ASSERT(si->rev >= 3); - - si->bar0 = sd->bar0; - - /* Rev < 10 PciSpiHost has 2 BARs: - * BAR0 = PCI Core Registers - * BAR1 = PciSpiHost Registers (all other cores on backplane) - * - * Rev 10 and up use a different PCI core which only has a single - * BAR0 which contains the PciSpiHost Registers. - */ - if (si->rev < 10) { - si->pciregs = (spih_pciregs_t *)spi_reg_map(osh, - (uintptr)si->bar0, - sizeof(spih_pciregs_t)); - sd_err(("Mapped PCI Core regs to BAR0 at %p\n", si->pciregs)); - - si->bar1 = OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR1, 4); - si->regs = (spih_regs_t *)spi_reg_map(osh, - (uintptr)si->bar1, - sizeof(spih_regs_t)); - sd_err(("Mapped SPI Controller regs to BAR1 at %p\n", si->regs)); - } else { - si->regs = (spih_regs_t *)spi_reg_map(osh, - (uintptr)si->bar0, - sizeof(spih_regs_t)); - sd_err(("Mapped SPI Controller regs to BAR0 at %p\n", si->regs)); - si->pciregs = NULL; - } - /* Enable SPI Controller, 16.67MHz SPI Clock */ - SPIPCI_WREG(osh, &si->regs->spih_ctrl, 0x000000d1); - - /* Set extended feature register to defaults */ - SPIPCI_WREG(osh, &si->regs->spih_ext, 0x00000000); - - /* Set GPIO CS# High (de-asserted) */ - SPIPCI_WREG(osh, &si->regs->spih_gpio_data, SPIH_CS); - - /* set GPIO[0] to output for CS# */ - /* set GPIO[1] to output for power control */ - /* set GPIO[2] to input for card detect */ - SPIPCI_WREG(osh, &si->regs->spih_gpio_ctrl, (SPIH_CS | SPIH_SLOT_POWER)); - - /* Clear out the Read FIFO in case there is any stuff left in there from a previous run. */ - while ((SPIPCI_RREG(osh, &si->regs->spih_stat) & SPIH_RFEMPTY) == 0) { - SPIPCI_RREG(osh, &si->regs->spih_data); - } - - /* Wait for power to stabilize to the SDIO Card (100msec was insufficient) */ - OSL_DELAY(250000); - - /* Check card detect on FPGA Revision >= 4 */ - if (si->rev >= 4) { - if (SPIPCI_RREG(osh, &si->regs->spih_gpio_data) & SPIH_CARD_DETECT) { - sd_err(("%s: no card detected in SD slot\n", __FUNCTION__)); - spi_reg_unmap(osh, (uintptr)si->regs, sizeof(spih_regs_t)); - if (si->pciregs) { - spi_reg_unmap(osh, (uintptr)si->pciregs, sizeof(spih_pciregs_t)); - } - MFREE(osh, si, sizeof(spih_info_t)); - return FALSE; - } - } - - /* Interrupts are level sensitive */ - SPIPCI_WREG(osh, &si->regs->spih_int_edge, 0x80000000); - - /* Interrupts are active low. */ - SPIPCI_WREG(osh, &si->regs->spih_int_pol, 0x40000004); - - /* Enable interrupts through PCI Core. */ - if (si->pciregs) { - SPIPCI_WREG(osh, &si->pciregs->ICR, PCI_INT_PROP_EN); - } - - sd_trace(("%s: exit\n", __FUNCTION__)); - return TRUE; -} - -/* Detach and return PCI-SPI Hardware to unconfigured state */ -bool -spi_hw_detach(sdioh_info_t *sd) -{ - spih_info_t *si = (spih_info_t *)sd->controller; - osl_t *osh = si->osh; - spih_regs_t *regs = si->regs; - spih_pciregs_t *pciregs = si->pciregs; - - sd_trace(("%s: enter\n", __FUNCTION__)); - - SPIPCI_WREG(osh, ®s->spih_ctrl, 0x00000010); - SPIPCI_WREG(osh, ®s->spih_gpio_ctrl, 0x00000000); /* Disable GPIO for CS# */ - SPIPCI_WREG(osh, ®s->spih_int_mask, 0x00000000); /* Clear Intmask */ - SPIPCI_WREG(osh, ®s->spih_hex_disp, 0x0000DEAF); - SPIPCI_WREG(osh, ®s->spih_int_edge, 0x00000000); - SPIPCI_WREG(osh, ®s->spih_int_pol, 0x00000000); - SPIPCI_WREG(osh, ®s->spih_hex_disp, 0x0000DEAD); - - /* Disable interrupts through PCI Core. */ - if (si->pciregs) { - SPIPCI_WREG(osh, &pciregs->ICR, 0x00000000); - spi_reg_unmap(osh, (uintptr)pciregs, sizeof(spih_pciregs_t)); - } - spi_reg_unmap(osh, (uintptr)regs, sizeof(spih_regs_t)); - - MFREE(osh, si, sizeof(spih_info_t)); - - sd->controller = NULL; - - sd_trace(("%s: exit\n", __FUNCTION__)); - return TRUE; -} - -/* Switch between internal (PCI) and external clock oscillator */ -static bool -sdspi_switch_clock(sdioh_info_t *sd, bool ext_clk) -{ - spih_info_t *si = (spih_info_t *)sd->controller; - osl_t *osh = si->osh; - spih_regs_t *regs = si->regs; - - /* Switch to desired clock, and reset the PLL. */ - SPIPCI_WREG(osh, ®s->spih_pll_ctrl, ext_clk ? SPIH_EXT_CLK : 0); - - SPINWAIT(((SPIPCI_RREG(osh, ®s->spih_pll_status) & SPIH_PLL_LOCKED) - != SPIH_PLL_LOCKED), 1000); - if ((SPIPCI_RREG(osh, ®s->spih_pll_status) & SPIH_PLL_LOCKED) != SPIH_PLL_LOCKED) { - sd_err(("%s: timeout waiting for PLL to lock\n", __FUNCTION__)); - return (FALSE); - } - return (TRUE); - -} - -/* Configure PCI-SPI Host Controller's SPI Clock rate as a divisor into the - * base clock rate. The base clock is either the PCI Clock (33MHz) or the - * external clock oscillator at U17 on the PciSpiHost. - */ -bool -spi_start_clock(sdioh_info_t *sd, uint16 div) -{ - spih_info_t *si = (spih_info_t *)sd->controller; - osl_t *osh = si->osh; - spih_regs_t *regs = si->regs; - uint32 t, espr, disp; - uint32 disp_xtal_freq; - bool ext_clock = FALSE; - char disp_string[5]; - - if (div > 2048) { - sd_err(("%s: divisor %d too large; using max of 2048\n", __FUNCTION__, div)); - div = 2048; - } else if (div & (div - 1)) { /* Not a power of 2? */ - /* Round up to a power of 2 */ - while ((div + 1) & div) - div |= div >> 1; - div++; - } - - /* For FPGA Rev >= 5, the use of an external clock oscillator is supported. - * If the oscillator is populated, use it to provide the SPI base clock, - * otherwise, default to the PCI clock as the SPI base clock. - */ - if (si->rev >= 5) { - uint32 clk_tick; - /* Enable the External Clock Oscillator as PLL clock source. */ - if (!sdspi_switch_clock(sd, TRUE)) { - sd_err(("%s: error switching to external clock\n", __FUNCTION__)); - } - - /* Check to make sure the external clock is running. If not, then it - * is not populated on the card, so we will default to the PCI clock. - */ - clk_tick = SPIPCI_RREG(osh, ®s->spih_clk_count); - if (clk_tick == SPIPCI_RREG(osh, ®s->spih_clk_count)) { - - /* Switch back to the PCI clock as the clock source. */ - if (!sdspi_switch_clock(sd, FALSE)) { - sd_err(("%s: error switching to external clock\n", __FUNCTION__)); - } - } else { - ext_clock = TRUE; - } - } - - /* Hack to allow hot-swapping oscillators: - * 1. Force PCI clock as clock source, using sd_divisor of 0. - * 2. Swap oscillator - * 3. Set desired sd_divisor (will switch to external oscillator as clock source. - */ - if (div == 0) { - ext_clock = FALSE; - div = 2; - - /* Select PCI clock as the clock source. */ - if (!sdspi_switch_clock(sd, FALSE)) { - sd_err(("%s: error switching to external clock\n", __FUNCTION__)); - } - - sd_err(("%s: Ok to hot-swap oscillators.\n", __FUNCTION__)); - } - - /* If using the external oscillator, read the clock frequency from the controller - * The value read is in units of 10000Hz, and it's not a nice round number because - * it is calculated by the FPGA. So to make up for that, we round it off. - */ - if (ext_clock == TRUE) { - uint32 xtal_freq; - - OSL_DELAY(1000); - xtal_freq = SPIPCI_RREG(osh, ®s->spih_xtal_freq) * 10000; - - sd_info(("%s: Oscillator is %dHz\n", __FUNCTION__, xtal_freq)); - - - disp_xtal_freq = xtal_freq / 10000; - - /* Round it off to a nice number. */ - if ((disp_xtal_freq % 100) > 50) { - disp_xtal_freq += 100; - } - - disp_xtal_freq = (disp_xtal_freq / 100) * 100; - } else { - sd_err(("%s: no external oscillator installed, using PCI clock.\n", __FUNCTION__)); - disp_xtal_freq = 3333; - } - - /* Convert the SPI Clock frequency to BCD format. */ - sprintf(disp_string, "%04d", disp_xtal_freq / div); - - disp = (disp_string[0] - '0') << 12; - disp |= (disp_string[1] - '0') << 8; - disp |= (disp_string[2] - '0') << 4; - disp |= (disp_string[3] - '0'); - - /* Select the correct ESPR register value based on the divisor. */ - switch (div) { - case 1: espr = 0x0; break; - case 2: espr = 0x1; break; - case 4: espr = 0x2; break; - case 8: espr = 0x5; break; - case 16: espr = 0x3; break; - case 32: espr = 0x4; break; - case 64: espr = 0x6; break; - case 128: espr = 0x7; break; - case 256: espr = 0x8; break; - case 512: espr = 0x9; break; - case 1024: espr = 0xa; break; - case 2048: espr = 0xb; break; - default: espr = 0x0; ASSERT(0); break; - } - - t = SPIPCI_RREG(osh, ®s->spih_ctrl); - t &= ~3; - t |= espr & 3; - SPIPCI_WREG(osh, ®s->spih_ctrl, t); - - t = SPIPCI_RREG(osh, ®s->spih_ext); - t &= ~3; - t |= (espr >> 2) & 3; - SPIPCI_WREG(osh, ®s->spih_ext, t); - - SPIPCI_WREG(osh, ®s->spih_hex_disp, disp); - - /* For Rev 8, writing to the PLL_CTRL register resets - * the PLL, and it can re-acquire in 200uS. For - * Rev 7 and older, we use a software delay to allow - * the PLL to re-acquire, which takes more than 2mS. - */ - if (si->rev < 8) { - /* Wait for clock to settle. */ - OSL_DELAY(5000); - } - - sd_info(("%s: SPI_CTRL=0x%08x SPI_EXT=0x%08x\n", - __FUNCTION__, - SPIPCI_RREG(osh, ®s->spih_ctrl), - SPIPCI_RREG(osh, ®s->spih_ext))); - - return TRUE; -} - -/* Configure PCI-SPI Host Controller High-Speed Clocking mode setting */ -bool -spi_controller_highspeed_mode(sdioh_info_t *sd, bool hsmode) -{ - spih_info_t *si = (spih_info_t *)sd->controller; - osl_t *osh = si->osh; - spih_regs_t *regs = si->regs; - - if (si->rev >= 10) { - if (hsmode) { - SPIPCI_ORREG(osh, ®s->spih_ext, 0x10); - } else { - SPIPCI_ANDREG(osh, ®s->spih_ext, ~0x10); - } - } - - return TRUE; -} - -/* Disable device interrupt */ -void -spi_devintr_off(sdioh_info_t *sd) -{ - spih_info_t *si = (spih_info_t *)sd->controller; - osl_t *osh = si->osh; - spih_regs_t *regs = si->regs; - - sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints)); - if (sd->use_client_ints) { - sd->intmask &= ~SPIH_DEV_INTR; - SPIPCI_WREG(osh, ®s->spih_int_mask, sd->intmask); /* Clear Intmask */ - } -} - -/* Enable device interrupt */ -void -spi_devintr_on(sdioh_info_t *sd) -{ - spih_info_t *si = (spih_info_t *)sd->controller; - osl_t *osh = si->osh; - spih_regs_t *regs = si->regs; - - ASSERT(sd->lockcount == 0); - sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints)); - if (sd->use_client_ints) { - if (SPIPCI_RREG(osh, ®s->spih_ctrl) & 0x02) { - /* Ack in case one was pending but is no longer... */ - SPIPCI_WREG(osh, ®s->spih_int_status, SPIH_DEV_INTR); - } - sd->intmask |= SPIH_DEV_INTR; - /* Set device intr in Intmask */ - SPIPCI_WREG(osh, ®s->spih_int_mask, sd->intmask); - } -} - -/* Check to see if an interrupt belongs to the PCI-SPI Host or a SPI Device */ -bool -spi_check_client_intr(sdioh_info_t *sd, int *is_dev_intr) -{ - spih_info_t *si = (spih_info_t *)sd->controller; - osl_t *osh = si->osh; - spih_regs_t *regs = si->regs; - bool ours = FALSE; - - uint32 raw_int, cur_int; - ASSERT(sd); - - if (is_dev_intr) - *is_dev_intr = FALSE; - raw_int = SPIPCI_RREG(osh, ®s->spih_int_status); - cur_int = raw_int & sd->intmask; - if (cur_int & SPIH_DEV_INTR) { - if (sd->client_intr_enabled && sd->use_client_ints) { - sd->intrcount++; - ASSERT(sd->intr_handler); - ASSERT(sd->intr_handler_arg); - (sd->intr_handler)(sd->intr_handler_arg); - if (is_dev_intr) - *is_dev_intr = TRUE; - } else { - sd_trace(("%s: Not ready for intr: enabled %d, handler 0x%p\n", - __FUNCTION__, sd->client_intr_enabled, sd->intr_handler)); - } - SPIPCI_WREG(osh, ®s->spih_int_status, SPIH_DEV_INTR); - SPIPCI_RREG(osh, ®s->spih_int_status); - ours = TRUE; - } else if (cur_int & SPIH_CTLR_INTR) { - /* Interrupt is from SPI FIFO... just clear and ack it... */ - sd_trace(("%s: SPI CTLR interrupt: raw_int 0x%08x cur_int 0x%08x\n", - __FUNCTION__, raw_int, cur_int)); - - /* Clear the interrupt in the SPI_STAT register */ - SPIPCI_WREG(osh, ®s->spih_stat, 0x00000080); - - /* Ack the interrupt in the interrupt controller */ - SPIPCI_WREG(osh, ®s->spih_int_status, SPIH_CTLR_INTR); - SPIPCI_RREG(osh, ®s->spih_int_status); - - ours = TRUE; - } else if (cur_int & SPIH_WFIFO_INTR) { - sd_trace(("%s: SPI WR FIFO Empty interrupt: raw_int 0x%08x cur_int 0x%08x\n", - __FUNCTION__, raw_int, cur_int)); - - /* Disable the FIFO Empty Interrupt */ - sd->intmask &= ~SPIH_WFIFO_INTR; - SPIPCI_WREG(osh, ®s->spih_int_mask, sd->intmask); - - sd->local_intrcount++; - sd->got_hcint = TRUE; - ours = TRUE; - } else { - /* Not an error: can share interrupts... */ - sd_trace(("%s: Not my interrupt: raw_int 0x%08x cur_int 0x%08x\n", - __FUNCTION__, raw_int, cur_int)); - ours = FALSE; - } - - return ours; -} - -static void -hexdump(char *pfx, unsigned char *msg, int msglen) -{ - int i, col; - char buf[80]; - - ASSERT(strlen(pfx) + 49 <= sizeof(buf)); - - col = 0; - - for (i = 0; i < msglen; i++, col++) { - if (col % 16 == 0) - strcpy(buf, pfx); - sprintf(buf + strlen(buf), "%02x", msg[i]); - if ((col + 1) % 16 == 0) - printf("%s\n", buf); - else - sprintf(buf + strlen(buf), " "); - } - - if (col % 16 != 0) - printf("%s\n", buf); -} - -/* Send/Receive an SPI Packet */ -void -spi_sendrecv(sdioh_info_t *sd, uint8 *msg_out, uint8 *msg_in, int msglen) -{ - spih_info_t *si = (spih_info_t *)sd->controller; - osl_t *osh = si->osh; - spih_regs_t *regs = si->regs; - uint32 count; - uint32 spi_data_out; - uint32 spi_data_in; - bool yield; - - sd_trace(("%s: enter\n", __FUNCTION__)); - - if (bcmpcispi_dump) { - printf("SENDRECV(len=%d)\n", msglen); - hexdump(" OUT: ", msg_out, msglen); - } - -#ifdef BCMSDYIELD - /* Only yield the CPU and wait for interrupt on Rev 8 and newer FPGA images. */ - yield = ((msglen > 500) && (si->rev >= 8)); -#else - yield = FALSE; -#endif /* BCMSDYIELD */ - - ASSERT(msglen % 4 == 0); - - - SPIPCI_ANDREG(osh, ®s->spih_gpio_data, ~SPIH_CS); /* Set GPIO CS# Low (asserted) */ - - for (count = 0; count < (uint32)msglen/4; count++) { - spi_data_out = ((uint32)((uint32 *)msg_out)[count]); - SPIPCI_WREG(osh, ®s->spih_data, spi_data_out); - } - -#ifdef BCMSDYIELD - if (yield) { - /* Ack the interrupt in the interrupt controller */ - SPIPCI_WREG(osh, ®s->spih_int_status, SPIH_WFIFO_INTR); - SPIPCI_RREG(osh, ®s->spih_int_status); - - /* Enable the FIFO Empty Interrupt */ - sd->intmask |= SPIH_WFIFO_INTR; - sd->got_hcint = FALSE; - SPIPCI_WREG(osh, ®s->spih_int_mask, sd->intmask); - - } -#endif /* BCMSDYIELD */ - - /* Wait for write fifo to empty... */ - SPIPCI_ANDREG(osh, ®s->spih_gpio_data, ~0x00000020); /* Set GPIO 5 Low */ - - if (yield) { - ASSERT((SPIPCI_RREG(sd->osh, ®s->spih_stat) & SPIH_WFEMPTY) == 0); - } - - spi_waitbits(sd, yield); - SPIPCI_ORREG(osh, ®s->spih_gpio_data, 0x00000020); /* Set GPIO 5 High (de-asserted) */ - - for (count = 0; count < (uint32)msglen/4; count++) { - spi_data_in = SPIPCI_RREG(osh, ®s->spih_data); - ((uint32 *)msg_in)[count] = spi_data_in; - } - - /* Set GPIO CS# High (de-asserted) */ - SPIPCI_ORREG(osh, ®s->spih_gpio_data, SPIH_CS); - - if (bcmpcispi_dump) { - hexdump(" IN : ", msg_in, msglen); - } -} - -void -spi_spinbits(sdioh_info_t *sd) -{ - spih_info_t *si = (spih_info_t *)sd->controller; - osl_t *osh = si->osh; - spih_regs_t *regs = si->regs; - uint spin_count; /* Spin loop bound check */ - - spin_count = 0; - while ((SPIPCI_RREG(sd->osh, ®s->spih_stat) & SPIH_WFEMPTY) == 0) { - if (spin_count > SPI_SPIN_BOUND) { - sd_err(("%s: SPIH_WFEMPTY spin bits out of bound %u times \n", - __FUNCTION__, spin_count)); - ASSERT(FALSE); - } - spin_count++; - } - - /* Wait for SPI Transfer state machine to return to IDLE state. - * The state bits are only implemented in Rev >= 5 FPGA. These - * bits are hardwired to 00 for Rev < 5, so this check doesn't cause - * any problems. - */ - spin_count = 0; - while ((SPIPCI_RREG(osh, ®s->spih_stat) & SPIH_STATE_MASK) != 0) { - if (spin_count > SPI_SPIN_BOUND) { - sd_err(("%s: SPIH_STATE_MASK spin bits out of bound %u times \n", - __FUNCTION__, spin_count)); - ASSERT(FALSE); - } - spin_count++; - } -} diff --git a/drivers/net/wireless/bcm4329/bcmsdh.c b/drivers/net/wireless/bcm4329/bcmsdh.c deleted file mode 100644 index 4bf5889e5a68..000000000000 --- a/drivers/net/wireless/bcm4329/bcmsdh.c +++ /dev/null @@ -1,652 +0,0 @@ -/* - * BCMSDH interface glue - * implement bcmsdh API for SDIOH driver - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdh.c,v 1.35.2.1.4.8.6.13 2010/04/06 03:26:57 Exp $ - */ -/* ****************** BCMSDH Interface Functions *************************** */ - -#include -#include -#include -#include -#include -#include -#include - -#include /* BRCM API for SDIO clients (such as wl, dhd) */ -#include /* common SDIO/controller interface */ -#include /* BRCM sdio device core */ - -#include /* sdio spec */ - -#define SDIOH_API_ACCESS_RETRY_LIMIT 2 -const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL; - - -struct bcmsdh_info -{ - bool init_success; /* underlying driver successfully attached */ - void *sdioh; /* handler for sdioh */ - uint32 vendevid; /* Target Vendor and Device ID on SD bus */ - osl_t *osh; - bool regfail; /* Save status of last reg_read/reg_write call */ - uint32 sbwad; /* Save backplane window address */ -}; -/* local copy of bcm sd handler */ -bcmsdh_info_t * l_bcmsdh = NULL; - -#if defined(OOB_INTR_ONLY) && defined(HW_OOB) -extern int -sdioh_enable_hw_oob_intr(void *sdioh, bool enable); - -void -bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable) -{ - sdioh_enable_hw_oob_intr(sdh->sdioh, enable); -} -#endif - -bcmsdh_info_t * -bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq) -{ - bcmsdh_info_t *bcmsdh; - - if ((bcmsdh = (bcmsdh_info_t *)MALLOC(osh, sizeof(bcmsdh_info_t))) == NULL) { - BCMSDH_ERROR(("bcmsdh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh))); - return NULL; - } - bzero((char *)bcmsdh, sizeof(bcmsdh_info_t)); - - /* save the handler locally */ - l_bcmsdh = bcmsdh; - - if (!(bcmsdh->sdioh = sdioh_attach(osh, cfghdl, irq))) { - bcmsdh_detach(osh, bcmsdh); - return NULL; - } - - bcmsdh->osh = osh; - bcmsdh->init_success = TRUE; - - *regsva = (uint32 *)SI_ENUM_BASE; - - /* Report the BAR, to fix if needed */ - bcmsdh->sbwad = SI_ENUM_BASE; - return bcmsdh; -} - -int -bcmsdh_detach(osl_t *osh, void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - if (bcmsdh != NULL) { - if (bcmsdh->sdioh) { - sdioh_detach(osh, bcmsdh->sdioh); - bcmsdh->sdioh = NULL; - } - MFREE(osh, bcmsdh, sizeof(bcmsdh_info_t)); - } - - l_bcmsdh = NULL; - return 0; -} - -int -bcmsdh_iovar_op(void *sdh, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - return sdioh_iovar_op(bcmsdh->sdioh, name, params, plen, arg, len, set); -} - -bool -bcmsdh_intr_query(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - bool on; - - ASSERT(bcmsdh); - status = sdioh_interrupt_query(bcmsdh->sdioh, &on); - if (SDIOH_API_SUCCESS(status)) - return FALSE; - else - return on; -} - -int -bcmsdh_intr_enable(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - ASSERT(bcmsdh); - - status = sdioh_interrupt_set(bcmsdh->sdioh, TRUE); - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - -int -bcmsdh_intr_disable(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - ASSERT(bcmsdh); - - status = sdioh_interrupt_set(bcmsdh->sdioh, FALSE); - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - -int -bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - ASSERT(bcmsdh); - - status = sdioh_interrupt_register(bcmsdh->sdioh, fn, argh); - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - -int -bcmsdh_intr_dereg(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - ASSERT(bcmsdh); - - status = sdioh_interrupt_deregister(bcmsdh->sdioh); - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - -#if defined(DHD_DEBUG) -bool -bcmsdh_intr_pending(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - ASSERT(sdh); - return sdioh_interrupt_pending(bcmsdh->sdioh); -} -#endif - - -int -bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh) -{ - ASSERT(sdh); - - /* don't support yet */ - return BCME_UNSUPPORTED; -} - -uint8 -bcmsdh_cfg_read(void *sdh, uint fnc_num, uint32 addr, int *err) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - int32 retry = 0; -#endif - uint8 data = 0; - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - do { - if (retry) /* wait for 1 ms till bus get settled down */ - OSL_DELAY(1000); -#endif - status = sdioh_cfg_read(bcmsdh->sdioh, fnc_num, addr, (uint8 *)&data); -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - } while (!SDIOH_API_SUCCESS(status) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT)); -#endif - if (err) - *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint8data = 0x%x\n", __FUNCTION__, - fnc_num, addr, data)); - - return data; -} - -void -bcmsdh_cfg_write(void *sdh, uint fnc_num, uint32 addr, uint8 data, int *err) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - int32 retry = 0; -#endif - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - do { - if (retry) /* wait for 1 ms till bus get settled down */ - OSL_DELAY(1000); -#endif - status = sdioh_cfg_write(bcmsdh->sdioh, fnc_num, addr, (uint8 *)&data); -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - } while (!SDIOH_API_SUCCESS(status) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT)); -#endif - if (err) - *err = SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR; - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint8data = 0x%x\n", __FUNCTION__, - fnc_num, addr, data)); -} - -uint32 -bcmsdh_cfg_read_word(void *sdh, uint fnc_num, uint32 addr, int *err) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - uint32 data = 0; - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - - status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_READ, fnc_num, - addr, &data, 4); - - if (err) - *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint32data = 0x%x\n", __FUNCTION__, - fnc_num, addr, data)); - - return data; -} - -void -bcmsdh_cfg_write_word(void *sdh, uint fnc_num, uint32 addr, uint32 data, int *err) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - - status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_WRITE, fnc_num, - addr, &data, 4); - - if (err) - *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint32data = 0x%x\n", __FUNCTION__, fnc_num, - addr, data)); -} - - -int -bcmsdh_cis_read(void *sdh, uint func, uint8 *cis, uint length) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - - uint8 *tmp_buf, *tmp_ptr; - uint8 *ptr; - bool ascii = func & ~0xf; - func &= 0x7; - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - ASSERT(cis); - ASSERT(length <= SBSDIO_CIS_SIZE_LIMIT); - - status = sdioh_cis_read(bcmsdh->sdioh, func, cis, length); - - if (ascii) { - /* Move binary bits to tmp and format them into the provided buffer. */ - if ((tmp_buf = (uint8 *)MALLOC(bcmsdh->osh, length)) == NULL) { - BCMSDH_ERROR(("%s: out of memory\n", __FUNCTION__)); - return BCME_NOMEM; - } - bcopy(cis, tmp_buf, length); - for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4); tmp_ptr++) { - ptr += sprintf((char*)ptr, "%.2x ", *tmp_ptr & 0xff); - if ((((tmp_ptr - tmp_buf) + 1) & 0xf) == 0) - ptr += sprintf((char *)ptr, "\n"); - } - MFREE(bcmsdh->osh, tmp_buf, length); - } - - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - - -static int -bcmsdhsdio_set_sbaddr_window(void *sdh, uint32 address) -{ - int err = 0; - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, - (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); - if (!err) - bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, - (address >> 16) & SBSDIO_SBADDRMID_MASK, &err); - if (!err) - bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, - (address >> 24) & SBSDIO_SBADDRHIGH_MASK, &err); - - - return err; -} - -uint32 -bcmsdh_reg_read(void *sdh, uint32 addr, uint size) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - uint32 word = 0; - uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; - - BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, ", __FUNCTION__, addr)); - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - - if (bar0 != bcmsdh->sbwad) { - if (bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0)) - return 0xFFFFFFFF; - - bcmsdh->sbwad = bar0; - } - - addr &= SBSDIO_SB_OFT_ADDR_MASK; - if (size == 4) - addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - - status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, - SDIOH_READ, SDIO_FUNC_1, addr, &word, size); - - bcmsdh->regfail = !(SDIOH_API_SUCCESS(status)); - - BCMSDH_INFO(("uint32data = 0x%x\n", word)); - - /* if ok, return appropriately masked word */ - if (SDIOH_API_SUCCESS(status)) { - switch (size) { - case sizeof(uint8): - return (word & 0xff); - case sizeof(uint16): - return (word & 0xffff); - case sizeof(uint32): - return word; - default: - bcmsdh->regfail = TRUE; - - } - } - - /* otherwise, bad sdio access or invalid size */ - BCMSDH_ERROR(("%s: error reading addr 0x%04x size %d\n", __FUNCTION__, addr, size)); - return 0xFFFFFFFF; -} - -uint32 -bcmsdh_reg_write(void *sdh, uint32 addr, uint size, uint32 data) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; - int err = 0; - - BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n", - __FUNCTION__, addr, size*8, data)); - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - - if (bar0 != bcmsdh->sbwad) { - if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0))) - return err; - - bcmsdh->sbwad = bar0; - } - - addr &= SBSDIO_SB_OFT_ADDR_MASK; - if (size == 4) - addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_WRITE, SDIO_FUNC_1, - addr, &data, size); - bcmsdh->regfail = !(SDIOH_API_SUCCESS(status)); - - if (SDIOH_API_SUCCESS(status)) - return 0; - - BCMSDH_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n", - __FUNCTION__, data, addr, size)); - return 0xFFFFFFFF; -} - -bool -bcmsdh_regfail(void *sdh) -{ - return ((bcmsdh_info_t *)sdh)->regfail; -} - -int -bcmsdh_recv_buf(void *sdh, uint32 addr, uint fn, uint flags, - uint8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete, void *handle) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - uint incr_fix; - uint width; - uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; - int err = 0; - - ASSERT(bcmsdh); - ASSERT(bcmsdh->init_success); - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n", - __FUNCTION__, fn, addr, nbytes)); - - /* Async not implemented yet */ - ASSERT(!(flags & SDIO_REQ_ASYNC)); - if (flags & SDIO_REQ_ASYNC) - return BCME_UNSUPPORTED; - - if (bar0 != bcmsdh->sbwad) { - if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0))) - return err; - - bcmsdh->sbwad = bar0; - } - - addr &= SBSDIO_SB_OFT_ADDR_MASK; - - incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC; - width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; - if (width == 4) - addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - - status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix, - SDIOH_READ, fn, addr, width, nbytes, buf, pkt); - - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); -} - -int -bcmsdh_send_buf(void *sdh, uint32 addr, uint fn, uint flags, - uint8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete, void *handle) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - uint incr_fix; - uint width; - uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; - int err = 0; - - ASSERT(bcmsdh); - ASSERT(bcmsdh->init_success); - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n", - __FUNCTION__, fn, addr, nbytes)); - - /* Async not implemented yet */ - ASSERT(!(flags & SDIO_REQ_ASYNC)); - if (flags & SDIO_REQ_ASYNC) - return BCME_UNSUPPORTED; - - if (bar0 != bcmsdh->sbwad) { - if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0))) - return err; - - bcmsdh->sbwad = bar0; - } - - addr &= SBSDIO_SB_OFT_ADDR_MASK; - - incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC; - width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; - if (width == 4) - addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - - status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix, - SDIOH_WRITE, fn, addr, width, nbytes, buf, pkt); - - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - -int -bcmsdh_rwdata(void *sdh, uint rw, uint32 addr, uint8 *buf, uint nbytes) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - - ASSERT(bcmsdh); - ASSERT(bcmsdh->init_success); - ASSERT((addr & SBSDIO_SBWINDOW_MASK) == 0); - - addr &= SBSDIO_SB_OFT_ADDR_MASK; - addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - - status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, SDIOH_DATA_INC, - (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1, - addr, 4, nbytes, buf, NULL); - - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - -int -bcmsdh_abort(void *sdh, uint fn) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - return sdioh_abort(bcmsdh->sdioh, fn); -} - -int -bcmsdh_start(void *sdh, int stage) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - return sdioh_start(bcmsdh->sdioh, stage); -} - -int -bcmsdh_stop(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - return sdioh_stop(bcmsdh->sdioh); -} - - -int -bcmsdh_query_device(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - bcmsdh->vendevid = (VENDOR_BROADCOM << 16) | 0; - return (bcmsdh->vendevid); -} - -uint -bcmsdh_query_iofnum(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - return (sdioh_query_iofnum(bcmsdh->sdioh)); -} - -int -bcmsdh_reset(bcmsdh_info_t *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - return sdioh_sdio_reset(bcmsdh->sdioh); -} - -void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh) -{ - ASSERT(sdh); - return sdh->sdioh; -} - -/* Function to pass device-status bits to DHD. */ -uint32 -bcmsdh_get_dstatus(void *sdh) -{ - return 0; -} -uint32 -bcmsdh_cur_sbwad(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - return (bcmsdh->sbwad); -} - -void -bcmsdh_chipinfo(void *sdh, uint32 chip, uint32 chiprev) -{ - return; -} diff --git a/drivers/net/wireless/bcm4329/bcmsdh_linux.c b/drivers/net/wireless/bcm4329/bcmsdh_linux.c deleted file mode 100644 index 6d6097b78f7d..000000000000 --- a/drivers/net/wireless/bcm4329/bcmsdh_linux.c +++ /dev/null @@ -1,735 +0,0 @@ -/* - * SDIO access interface for drivers - linux specific (pci only) - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdh_linux.c,v 1.42.10.10.2.14.4.2 2010/09/15 00:30:11 Exp $ - */ - -/** - * @file bcmsdh_linux.c - */ - -#define __UNDEF_NO_VERSION__ - -#include -#include - -#include -#include - -#include -#include -#include -#include - -#if defined(OOB_INTR_ONLY) -#include -extern void dhdsdio_isr(void * args); -#include -#include -#include -#endif /* defined(OOB_INTR_ONLY) */ -#if defined(CONFIG_MACH_SANDGATE2G) || defined(CONFIG_MACH_LOGICPD_PXA270) -#if !defined(BCMPLATFORM_BUS) -#define BCMPLATFORM_BUS -#endif /* !defined(BCMPLATFORM_BUS) */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)) -#include -#endif /* KERNEL_VERSION(2, 6, 19) */ -#endif /* CONFIG_MACH_SANDGATE2G || CONFIG_MACH_LOGICPD_PXA270 */ - -/** - * SDIO Host Controller info - */ -typedef struct bcmsdh_hc bcmsdh_hc_t; - -struct bcmsdh_hc { - bcmsdh_hc_t *next; -#ifdef BCMPLATFORM_BUS - struct device *dev; /* platform device handle */ -#else - struct pci_dev *dev; /* pci device handle */ -#endif /* BCMPLATFORM_BUS */ - osl_t *osh; - void *regs; /* SDIO Host Controller address */ - bcmsdh_info_t *sdh; /* SDIO Host Controller handle */ - void *ch; - unsigned int oob_irq; - unsigned long oob_flags; /* OOB Host specifiction as edge and etc */ - bool oob_irq_registered; -#if defined(OOB_INTR_ONLY) - spinlock_t irq_lock; -#endif -}; -static bcmsdh_hc_t *sdhcinfo = NULL; - -/* driver info, initialized when bcmsdh_register is called */ -static bcmsdh_driver_t drvinfo = {NULL, NULL}; - -/* debugging macros */ -#define SDLX_MSG(x) - -/** - * Checks to see if vendor and device IDs match a supported SDIO Host Controller. - */ -bool -bcmsdh_chipmatch(uint16 vendor, uint16 device) -{ - /* Add other vendors and devices as required */ - -#ifdef BCMSDIOH_STD - /* Check for Arasan host controller */ - if (vendor == VENDOR_SI_IMAGE) { - return (TRUE); - } - /* Check for BRCM 27XX Standard host controller */ - if (device == BCM27XX_SDIOH_ID && vendor == VENDOR_BROADCOM) { - return (TRUE); - } - /* Check for BRCM Standard host controller */ - if (device == SDIOH_FPGA_ID && vendor == VENDOR_BROADCOM) { - return (TRUE); - } - /* Check for TI PCIxx21 Standard host controller */ - if (device == PCIXX21_SDIOH_ID && vendor == VENDOR_TI) { - return (TRUE); - } - if (device == PCIXX21_SDIOH0_ID && vendor == VENDOR_TI) { - return (TRUE); - } - /* Ricoh R5C822 Standard SDIO Host */ - if (device == R5C822_SDIOH_ID && vendor == VENDOR_RICOH) { - return (TRUE); - } - /* JMicron Standard SDIO Host */ - if (device == JMICRON_SDIOH_ID && vendor == VENDOR_JMICRON) { - return (TRUE); - } - -#endif /* BCMSDIOH_STD */ -#ifdef BCMSDIOH_SPI - /* This is the PciSpiHost. */ - if (device == SPIH_FPGA_ID && vendor == VENDOR_BROADCOM) { - printf("Found PCI SPI Host Controller\n"); - return (TRUE); - } - -#endif /* BCMSDIOH_SPI */ - - return (FALSE); -} - -#if defined(BCMPLATFORM_BUS) -#if defined(BCMLXSDMMC) -/* forward declarations */ -int bcmsdh_probe(struct device *dev); -int bcmsdh_remove(struct device *dev); - -EXPORT_SYMBOL(bcmsdh_probe); -EXPORT_SYMBOL(bcmsdh_remove); - -#else -/* forward declarations */ -static int __devinit bcmsdh_probe(struct device *dev); -static int __devexit bcmsdh_remove(struct device *dev); -#endif /* BCMLXSDMMC */ - -#ifndef BCMLXSDMMC -static struct device_driver bcmsdh_driver = { - .name = "pxa2xx-mci", - .bus = &platform_bus_type, - .probe = bcmsdh_probe, - .remove = bcmsdh_remove, - .suspend = NULL, - .resume = NULL, - }; -#endif /* BCMLXSDMMC */ - -#ifndef BCMLXSDMMC -static -#endif /* BCMLXSDMMC */ -int bcmsdh_probe(struct device *dev) -{ - osl_t *osh = NULL; - bcmsdh_hc_t *sdhc = NULL; - ulong regs = 0; - bcmsdh_info_t *sdh = NULL; -#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) - struct platform_device *pdev; - struct resource *r; -#endif /* BCMLXSDMMC */ - int irq = 0; - uint32 vendevid; - unsigned long irq_flags = 0; - -#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) - pdev = to_platform_device(dev); - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - irq = platform_get_irq(pdev, 0); - if (!r || irq == NO_IRQ) - return -ENXIO; -#endif /* BCMLXSDMMC */ - -#if defined(OOB_INTR_ONLY) -#ifdef HW_OOB - irq_flags = \ - IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE; -#else - irq_flags = IRQF_TRIGGER_FALLING; -#endif /* HW_OOB */ - irq = dhd_customer_oob_irq_map(&irq_flags); - if (irq < 0) { - SDLX_MSG(("%s: Host irq is not defined\n", __FUNCTION__)); - return 1; - } -#endif /* defined(OOB_INTR_ONLY) */ - /* allocate SDIO Host Controller state info */ - if (!(osh = osl_attach(dev, PCI_BUS, FALSE))) { - SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__)); - goto err; - } - if (!(sdhc = MALLOC(osh, sizeof(bcmsdh_hc_t)))) { - SDLX_MSG(("%s: out of memory, allocated %d bytes\n", - __FUNCTION__, - MALLOCED(osh))); - goto err; - } - bzero(sdhc, sizeof(bcmsdh_hc_t)); - sdhc->osh = osh; - - sdhc->dev = (void *)dev; - -#ifdef BCMLXSDMMC - if (!(sdh = bcmsdh_attach(osh, (void *)0, - (void **)®s, irq))) { - SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); - goto err; - } -#else - if (!(sdh = bcmsdh_attach(osh, (void *)r->start, - (void **)®s, irq))) { - SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); - goto err; - } -#endif /* BCMLXSDMMC */ - sdhc->sdh = sdh; - sdhc->oob_irq = irq; - sdhc->oob_flags = irq_flags; - sdhc->oob_irq_registered = FALSE; /* to make sure.. */ -#if defined(OOB_INTR_ONLY) - spin_lock_init(&sdhc->irq_lock); -#endif - - /* chain SDIO Host Controller info together */ - sdhc->next = sdhcinfo; - sdhcinfo = sdhc; - /* Read the vendor/device ID from the CIS */ - vendevid = bcmsdh_query_device(sdh); - - /* try to attach to the target device */ - if (!(sdhc->ch = drvinfo.attach((vendevid >> 16), - (vendevid & 0xFFFF), 0, 0, 0, 0, - (void *)regs, NULL, sdh))) { - SDLX_MSG(("%s: device attach failed\n", __FUNCTION__)); - goto err; - } - - return 0; - - /* error handling */ -err: - if (sdhc) { - if (sdhc->sdh) - bcmsdh_detach(sdhc->osh, sdhc->sdh); - MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); - } - if (osh) - osl_detach(osh); - return -ENODEV; -} - -#ifndef BCMLXSDMMC -static -#endif /* BCMLXSDMMC */ -int bcmsdh_remove(struct device *dev) -{ - bcmsdh_hc_t *sdhc, *prev; - osl_t *osh; - - sdhc = sdhcinfo; - drvinfo.detach(sdhc->ch); - bcmsdh_detach(sdhc->osh, sdhc->sdh); - /* find the SDIO Host Controller state for this pdev and take it out from the list */ - for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { - if (sdhc->dev == (void *)dev) { - if (prev) - prev->next = sdhc->next; - else - sdhcinfo = NULL; - break; - } - prev = sdhc; - } - if (!sdhc) { - SDLX_MSG(("%s: failed\n", __FUNCTION__)); - return 0; - } - - - /* release SDIO Host Controller info */ - osh = sdhc->osh; - MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); - osl_detach(osh); - -#if !defined(BCMLXSDMMC) || defined(OOB_INTR_ONLY) - dev_set_drvdata(dev, NULL); -#endif /* !defined(BCMLXSDMMC) */ - - return 0; -} - -#else /* BCMPLATFORM_BUS */ - -#if !defined(BCMLXSDMMC) -/* forward declarations for PCI probe and remove functions. */ -static int __devinit bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent); -static void __devexit bcmsdh_pci_remove(struct pci_dev *pdev); - -/** - * pci id table - */ -static struct pci_device_id bcmsdh_pci_devid[] __devinitdata = { - { vendor: PCI_ANY_ID, - device: PCI_ANY_ID, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID, - class: 0, - class_mask: 0, - driver_data: 0, - }, - { 0, } -}; -MODULE_DEVICE_TABLE(pci, bcmsdh_pci_devid); - -/** - * SDIO Host Controller pci driver info - */ -static struct pci_driver bcmsdh_pci_driver = { - node: {}, - name: "bcmsdh", - id_table: bcmsdh_pci_devid, - probe: bcmsdh_pci_probe, - remove: bcmsdh_pci_remove, -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) - save_state: NULL, -#endif - suspend: NULL, - resume: NULL, -}; - - -extern uint sd_pci_slot; /* Force detection to a particular PCI */ - /* slot only . Allows for having multiple */ - /* WL devices at once in a PC */ - /* Only one instance of dhd will be */ - /* usable at a time */ - /* Upper word is bus number, */ - /* lower word is slot number */ - /* Default value of 0xFFFFffff turns this */ - /* off */ -module_param(sd_pci_slot, uint, 0); - - -/** - * Detect supported SDIO Host Controller and attach if found. - * - * Determine if the device described by pdev is a supported SDIO Host - * Controller. If so, attach to it and attach to the target device. - */ -static int __devinit -bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - osl_t *osh = NULL; - bcmsdh_hc_t *sdhc = NULL; - ulong regs; - bcmsdh_info_t *sdh = NULL; - int rc; - - if (sd_pci_slot != 0xFFFFffff) { - if (pdev->bus->number != (sd_pci_slot>>16) || - PCI_SLOT(pdev->devfn) != (sd_pci_slot&0xffff)) { - SDLX_MSG(("%s: %s: bus %X, slot %X, vend %X, dev %X\n", - __FUNCTION__, - bcmsdh_chipmatch(pdev->vendor, pdev->device) ? - "Found compatible SDIOHC" : - "Probing unknown device", - pdev->bus->number, PCI_SLOT(pdev->devfn), - pdev->vendor, pdev->device)); - return -ENODEV; - } - SDLX_MSG(("%s: %s: bus %X, slot %X, vendor %X, device %X (good PCI location)\n", - __FUNCTION__, - bcmsdh_chipmatch(pdev->vendor, pdev->device) ? - "Using compatible SDIOHC" : - "WARNING, forced use of unkown device", - pdev->bus->number, PCI_SLOT(pdev->devfn), - pdev->vendor, pdev->device)); - } - - if ((pdev->vendor == VENDOR_TI) && ((pdev->device == PCIXX21_FLASHMEDIA_ID) || - (pdev->device == PCIXX21_FLASHMEDIA0_ID))) { - uint32 config_reg; - - SDLX_MSG(("%s: Disabling TI FlashMedia Controller.\n", __FUNCTION__)); - if (!(osh = osl_attach(pdev, PCI_BUS, FALSE))) { - SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__)); - goto err; - } - - config_reg = OSL_PCI_READ_CONFIG(osh, 0x4c, 4); - - /* - * Set MMC_SD_DIS bit in FlashMedia Controller. - * Disbling the SD/MMC Controller in the FlashMedia Controller - * allows the Standard SD Host Controller to take over control - * of the SD Slot. - */ - config_reg |= 0x02; - OSL_PCI_WRITE_CONFIG(osh, 0x4c, 4, config_reg); - osl_detach(osh); - } - /* match this pci device with what we support */ - /* we can't solely rely on this to believe it is our SDIO Host Controller! */ - if (!bcmsdh_chipmatch(pdev->vendor, pdev->device)) { - return -ENODEV; - } - - /* this is a pci device we might support */ - SDLX_MSG(("%s: Found possible SDIO Host Controller: bus %d slot %d func %d irq %d\n", - __FUNCTION__, - pdev->bus->number, PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn), pdev->irq)); - - /* use bcmsdh_query_device() to get the vendor ID of the target device so - * it will eventually appear in the Broadcom string on the console - */ - - /* allocate SDIO Host Controller state info */ - if (!(osh = osl_attach(pdev, PCI_BUS, FALSE))) { - SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__)); - goto err; - } - if (!(sdhc = MALLOC(osh, sizeof(bcmsdh_hc_t)))) { - SDLX_MSG(("%s: out of memory, allocated %d bytes\n", - __FUNCTION__, - MALLOCED(osh))); - goto err; - } - bzero(sdhc, sizeof(bcmsdh_hc_t)); - sdhc->osh = osh; - - sdhc->dev = pdev; - - /* map to address where host can access */ - pci_set_master(pdev); - rc = pci_enable_device(pdev); - if (rc) { - SDLX_MSG(("%s: Cannot enable PCI device\n", __FUNCTION__)); - goto err; - } - if (!(sdh = bcmsdh_attach(osh, (void *)(uintptr)pci_resource_start(pdev, 0), - (void **)®s, pdev->irq))) { - SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); - goto err; - } - - sdhc->sdh = sdh; - - /* try to attach to the target device */ - if (!(sdhc->ch = drvinfo.attach(VENDOR_BROADCOM, /* pdev->vendor, */ - bcmsdh_query_device(sdh) & 0xFFFF, 0, 0, 0, 0, - (void *)regs, NULL, sdh))) { - SDLX_MSG(("%s: device attach failed\n", __FUNCTION__)); - goto err; - } - - /* chain SDIO Host Controller info together */ - sdhc->next = sdhcinfo; - sdhcinfo = sdhc; - - return 0; - - /* error handling */ -err: - if (sdhc->sdh) - bcmsdh_detach(sdhc->osh, sdhc->sdh); - if (sdhc) - MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); - if (osh) - osl_detach(osh); - return -ENODEV; -} - - -/** - * Detach from target devices and SDIO Host Controller - */ -static void __devexit -bcmsdh_pci_remove(struct pci_dev *pdev) -{ - bcmsdh_hc_t *sdhc, *prev; - osl_t *osh; - - /* find the SDIO Host Controller state for this pdev and take it out from the list */ - for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { - if (sdhc->dev == pdev) { - if (prev) - prev->next = sdhc->next; - else - sdhcinfo = NULL; - break; - } - prev = sdhc; - } - if (!sdhc) - return; - - drvinfo.detach(sdhc->ch); - - bcmsdh_detach(sdhc->osh, sdhc->sdh); - - /* release SDIO Host Controller info */ - osh = sdhc->osh; - MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); - osl_detach(osh); -} -#endif /* BCMLXSDMMC */ -#endif /* BCMPLATFORM_BUS */ - -extern int sdio_function_init(void); - -int -bcmsdh_register(bcmsdh_driver_t *driver) -{ - int error = 0; - - drvinfo = *driver; - -#if defined(BCMPLATFORM_BUS) -#if defined(BCMLXSDMMC) - SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n")); - error = sdio_function_init(); -#else - SDLX_MSG(("Intel PXA270 SDIO Driver\n")); - error = driver_register(&bcmsdh_driver); -#endif /* defined(BCMLXSDMMC) */ - return error; -#endif /* defined(BCMPLATFORM_BUS) */ - -#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) - if (!(error = pci_module_init(&bcmsdh_pci_driver))) - return 0; -#else - if (!(error = pci_register_driver(&bcmsdh_pci_driver))) - return 0; -#endif - - SDLX_MSG(("%s: pci_module_init failed 0x%x\n", __FUNCTION__, error)); -#endif /* BCMPLATFORM_BUS */ - - return error; -} - -extern void sdio_function_cleanup(void); - -void -bcmsdh_unregister(void) -{ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) - if (bcmsdh_pci_driver.node.next) -#endif - -#if defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) - driver_unregister(&bcmsdh_driver); -#endif -#if defined(BCMLXSDMMC) - sdio_function_cleanup(); -#endif /* BCMLXSDMMC */ -#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) - pci_unregister_driver(&bcmsdh_pci_driver); -#endif /* BCMPLATFORM_BUS */ -} - -#if defined(OOB_INTR_ONLY) -void bcmsdh_oob_intr_set(bool enable) -{ - static bool curstate = 1; - unsigned long flags; - - spin_lock_irqsave(&sdhcinfo->irq_lock, flags); - if (curstate != enable) { - if (enable) - enable_irq(sdhcinfo->oob_irq); - else - disable_irq_nosync(sdhcinfo->oob_irq); - curstate = enable; - } - spin_unlock_irqrestore(&sdhcinfo->irq_lock, flags); -} - -static irqreturn_t wlan_oob_irq(int irq, void *dev_id) -{ - dhd_pub_t *dhdp; - - dhdp = (dhd_pub_t *)dev_get_drvdata(sdhcinfo->dev); - - bcmsdh_oob_intr_set(0); - - if (dhdp == NULL) { - SDLX_MSG(("Out of band GPIO interrupt fired way too early\n")); - return IRQ_HANDLED; - } - - dhdsdio_isr((void *)dhdp->bus); - - return IRQ_HANDLED; -} - -int bcmsdh_register_oob_intr(void * dhdp) -{ - int error = 0; - - SDLX_MSG(("%s Enter\n", __FUNCTION__)); - -/* Example of HW_OOB for HW2: please refer to your host specifiction */ -/* sdhcinfo->oob_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE; */ - - dev_set_drvdata(sdhcinfo->dev, dhdp); - - if (!sdhcinfo->oob_irq_registered) { - SDLX_MSG(("%s IRQ=%d Type=%X \n", __FUNCTION__, \ - (int)sdhcinfo->oob_irq, (int)sdhcinfo->oob_flags)); - /* Refer to customer Host IRQ docs about proper irqflags definition */ - error = request_irq(sdhcinfo->oob_irq, wlan_oob_irq, sdhcinfo->oob_flags, - "bcmsdh_sdmmc", NULL); - if (error) - return -ENODEV; - - enable_irq_wake(sdhcinfo->oob_irq); - sdhcinfo->oob_irq_registered = TRUE; - } - - return 0; -} - -void bcmsdh_set_irq(int flag) -{ - if (sdhcinfo->oob_irq_registered) { - SDLX_MSG(("%s Flag = %d", __FUNCTION__, flag)); - if (flag) { - enable_irq(sdhcinfo->oob_irq); - enable_irq_wake(sdhcinfo->oob_irq); - } else { - disable_irq_wake(sdhcinfo->oob_irq); - disable_irq(sdhcinfo->oob_irq); - } - } -} - -void bcmsdh_unregister_oob_intr(void) -{ - SDLX_MSG(("%s: Enter\n", __FUNCTION__)); - - if (sdhcinfo->oob_irq_registered) { - disable_irq_wake(sdhcinfo->oob_irq); - disable_irq(sdhcinfo->oob_irq); /* just in case.. */ - free_irq(sdhcinfo->oob_irq, NULL); - sdhcinfo->oob_irq_registered = FALSE; - } -} -#endif /* defined(OOB_INTR_ONLY) */ -/* Module parameters specific to each host-controller driver */ - -extern uint sd_msglevel; /* Debug message level */ -module_param(sd_msglevel, uint, 0); - -extern uint sd_power; /* 0 = SD Power OFF, 1 = SD Power ON. */ -module_param(sd_power, uint, 0); - -extern uint sd_clock; /* SD Clock Control, 0 = SD Clock OFF, 1 = SD Clock ON */ -module_param(sd_clock, uint, 0); - -extern uint sd_divisor; /* Divisor (-1 means external clock) */ -module_param(sd_divisor, uint, 0); - -extern uint sd_sdmode; /* Default is SD4, 0=SPI, 1=SD1, 2=SD4 */ -module_param(sd_sdmode, uint, 0); - -extern uint sd_hiok; /* Ok to use hi-speed mode */ -module_param(sd_hiok, uint, 0); - -extern uint sd_f2_blocksize; -module_param(sd_f2_blocksize, int, 0); - - -#ifdef BCMSDH_MODULE -EXPORT_SYMBOL(bcmsdh_attach); -EXPORT_SYMBOL(bcmsdh_detach); -EXPORT_SYMBOL(bcmsdh_intr_query); -EXPORT_SYMBOL(bcmsdh_intr_enable); -EXPORT_SYMBOL(bcmsdh_intr_disable); -EXPORT_SYMBOL(bcmsdh_intr_reg); -EXPORT_SYMBOL(bcmsdh_intr_dereg); - -#if defined(DHD_DEBUG) -EXPORT_SYMBOL(bcmsdh_intr_pending); -#endif - -EXPORT_SYMBOL(bcmsdh_devremove_reg); -EXPORT_SYMBOL(bcmsdh_cfg_read); -EXPORT_SYMBOL(bcmsdh_cfg_write); -EXPORT_SYMBOL(bcmsdh_cis_read); -EXPORT_SYMBOL(bcmsdh_reg_read); -EXPORT_SYMBOL(bcmsdh_reg_write); -EXPORT_SYMBOL(bcmsdh_regfail); -EXPORT_SYMBOL(bcmsdh_send_buf); -EXPORT_SYMBOL(bcmsdh_recv_buf); - -EXPORT_SYMBOL(bcmsdh_rwdata); -EXPORT_SYMBOL(bcmsdh_abort); -EXPORT_SYMBOL(bcmsdh_query_device); -EXPORT_SYMBOL(bcmsdh_query_iofnum); -EXPORT_SYMBOL(bcmsdh_iovar_op); -EXPORT_SYMBOL(bcmsdh_register); -EXPORT_SYMBOL(bcmsdh_unregister); -EXPORT_SYMBOL(bcmsdh_chipmatch); -EXPORT_SYMBOL(bcmsdh_reset); - -EXPORT_SYMBOL(bcmsdh_get_dstatus); -EXPORT_SYMBOL(bcmsdh_cfg_read_word); -EXPORT_SYMBOL(bcmsdh_cfg_write_word); -EXPORT_SYMBOL(bcmsdh_cur_sbwad); -EXPORT_SYMBOL(bcmsdh_chipinfo); - -#endif /* BCMSDH_MODULE */ diff --git a/drivers/net/wireless/bcm4329/bcmsdh_sdmmc.c b/drivers/net/wireless/bcm4329/bcmsdh_sdmmc.c deleted file mode 100644 index 031367b8f18f..000000000000 --- a/drivers/net/wireless/bcm4329/bcmsdh_sdmmc.c +++ /dev/null @@ -1,1304 +0,0 @@ -/* - * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdh_sdmmc.c,v 1.1.2.5.6.30.4.1 2010/09/02 23:12:21 Exp $ - */ -#include - -#include -#include -#include -#include -#include /* SDIO Device and Protocol Specs */ -#include /* SDIO Host Controller Specification */ -#include /* bcmsdh to/from specific controller APIs */ -#include /* ioctl/iovars */ - -#include -#include -#include - -#include -#include - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) -#include -extern volatile bool dhd_mmc_suspend; -#endif -#include "bcmsdh_sdmmc.h" - -#ifndef BCMSDH_MODULE -extern int sdio_function_init(void); -extern void sdio_function_cleanup(void); -#endif /* BCMSDH_MODULE */ - -#if !defined(OOB_INTR_ONLY) -static void IRQHandler(struct sdio_func *func); -static void IRQHandlerF2(struct sdio_func *func); -#endif /* !defined(OOB_INTR_ONLY) */ -static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, uint32 regaddr); -extern int sdio_reset_comm(struct mmc_card *card); - -extern PBCMSDH_SDMMC_INSTANCE gInstance; - -uint sd_sdmode = SDIOH_MODE_SD4; /* Use SD4 mode by default */ -uint sd_f2_blocksize = 512; /* Default blocksize */ - -uint sd_divisor = 2; /* Default 48MHz/2 = 24MHz */ - -uint sd_power = 1; /* Default to SD Slot powered ON */ -uint sd_clock = 1; /* Default to SD Clock turned ON */ -uint sd_hiok = FALSE; /* Don't use hi-speed mode by default */ -uint sd_msglevel = 0x01; -uint sd_use_dma = TRUE; -DHD_PM_RESUME_WAIT_INIT(sdioh_request_byte_wait); -DHD_PM_RESUME_WAIT_INIT(sdioh_request_word_wait); -DHD_PM_RESUME_WAIT_INIT(sdioh_request_packet_wait); -DHD_PM_RESUME_WAIT_INIT(sdioh_request_buffer_wait); - -#define DMA_ALIGN_MASK 0x03 - -int sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data); - -static int -sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd) -{ - int err_ret; - uint32 fbraddr; - uint8 func; - - sd_trace(("%s\n", __FUNCTION__)); - - /* Get the Card's common CIS address */ - sd->com_cis_ptr = sdioh_sdmmc_get_cisaddr(sd, SDIOD_CCCR_CISPTR_0); - sd->func_cis_ptr[0] = sd->com_cis_ptr; - sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __FUNCTION__, sd->com_cis_ptr)); - - /* Get the Card's function CIS (for each function) */ - for (fbraddr = SDIOD_FBR_STARTADDR, func = 1; - func <= sd->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) { - sd->func_cis_ptr[func] = sdioh_sdmmc_get_cisaddr(sd, SDIOD_FBR_CISPTR_0 + fbraddr); - sd_info(("%s: Function %d CIS Ptr = 0x%x\n", - __FUNCTION__, func, sd->func_cis_ptr[func])); - } - - sd->func_cis_ptr[0] = sd->com_cis_ptr; - sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __FUNCTION__, sd->com_cis_ptr)); - - /* Enable Function 1 */ - sdio_claim_host(gInstance->func[1]); - err_ret = sdio_enable_func(gInstance->func[1]); - sdio_release_host(gInstance->func[1]); - if (err_ret) { - sd_err(("bcmsdh_sdmmc: Failed to enable F1 Err: 0x%08x", err_ret)); - } - - return FALSE; -} - -/* - * Public entry points & extern's - */ -extern sdioh_info_t * -sdioh_attach(osl_t *osh, void *bar0, uint irq) -{ - sdioh_info_t *sd; - int err_ret; - - sd_trace(("%s\n", __FUNCTION__)); - - if (gInstance == NULL) { - sd_err(("%s: SDIO Device not present\n", __FUNCTION__)); - return NULL; - } - - if ((sd = (sdioh_info_t *)MALLOC(osh, sizeof(sdioh_info_t))) == NULL) { - sd_err(("sdioh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh))); - return NULL; - } - bzero((char *)sd, sizeof(sdioh_info_t)); - sd->osh = osh; - if (sdioh_sdmmc_osinit(sd) != 0) { - sd_err(("%s:sdioh_sdmmc_osinit() failed\n", __FUNCTION__)); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return NULL; - } - - sd->num_funcs = 2; - sd->sd_blockmode = TRUE; - sd->use_client_ints = TRUE; - sd->client_block_size[0] = 64; - - gInstance->sd = sd; - - /* Claim host controller */ - sdio_claim_host(gInstance->func[1]); - - sd->client_block_size[1] = 64; - err_ret = sdio_set_block_size(gInstance->func[1], 64); - if (err_ret) { - sd_err(("bcmsdh_sdmmc: Failed to set F1 blocksize\n")); - } - - /* Release host controller F1 */ - sdio_release_host(gInstance->func[1]); - - if (gInstance->func[2]) { - /* Claim host controller F2 */ - sdio_claim_host(gInstance->func[2]); - - sd->client_block_size[2] = sd_f2_blocksize; - err_ret = sdio_set_block_size(gInstance->func[2], sd_f2_blocksize); - if (err_ret) { - sd_err(("bcmsdh_sdmmc: Failed to set F2 blocksize to %d\n", - sd_f2_blocksize)); - } - - /* Release host controller F2 */ - sdio_release_host(gInstance->func[2]); - } - - sdioh_sdmmc_card_enablefuncs(sd); - - sd_trace(("%s: Done\n", __FUNCTION__)); - return sd; -} - - -extern SDIOH_API_RC -sdioh_detach(osl_t *osh, sdioh_info_t *sd) -{ - sd_trace(("%s\n", __FUNCTION__)); - - if (sd) { - - /* Disable Function 2 */ - sdio_claim_host(gInstance->func[2]); - sdio_disable_func(gInstance->func[2]); - sdio_release_host(gInstance->func[2]); - - /* Disable Function 1 */ - sdio_claim_host(gInstance->func[1]); - sdio_disable_func(gInstance->func[1]); - sdio_release_host(gInstance->func[1]); - - /* deregister irq */ - sdioh_sdmmc_osfree(sd); - - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - } - return SDIOH_API_RC_SUCCESS; -} - -#if defined(OOB_INTR_ONLY) && defined(HW_OOB) - -extern SDIOH_API_RC -sdioh_enable_func_intr(void) -{ - uint8 reg; - int err; - - if (gInstance->func[0]) { - sdio_claim_host(gInstance->func[0]); - - reg = sdio_readb(gInstance->func[0], SDIOD_CCCR_INTEN, &err); - if (err) { - sd_err(("%s: error for read SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err)); - sdio_release_host(gInstance->func[0]); - return SDIOH_API_RC_FAIL; - } - - /* Enable F1 and F2 interrupts, set master enable */ - reg |= (INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN | INTR_CTL_MASTER_EN); - - sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err); - sdio_release_host(gInstance->func[0]); - - if (err) { - sd_err(("%s: error for write SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err)); - return SDIOH_API_RC_FAIL; - } - } - - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_disable_func_intr(void) -{ - uint8 reg; - int err; - - if (gInstance->func[0]) { - sdio_claim_host(gInstance->func[0]); - reg = sdio_readb(gInstance->func[0], SDIOD_CCCR_INTEN, &err); - if (err) { - sd_err(("%s: error for read SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err)); - sdio_release_host(gInstance->func[0]); - return SDIOH_API_RC_FAIL; - } - - reg &= ~(INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN); - /* Disable master interrupt with the last function interrupt */ - if (!(reg & 0xFE)) - reg = 0; - sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err); - - sdio_release_host(gInstance->func[0]); - if (err) { - sd_err(("%s: error for write SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err)); - return SDIOH_API_RC_FAIL; - } - } - return SDIOH_API_RC_SUCCESS; -} -#endif /* defined(OOB_INTR_ONLY) && defined(HW_OOB) */ - -/* Configure callback to client when we recieve client interrupt */ -extern SDIOH_API_RC -sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - if (fn == NULL) { - sd_err(("%s: interrupt handler is NULL, not registering\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } -#if !defined(OOB_INTR_ONLY) - sd->intr_handler = fn; - sd->intr_handler_arg = argh; - sd->intr_handler_valid = TRUE; - - /* register and unmask irq */ - if (gInstance->func[2]) { - sdio_claim_host(gInstance->func[2]); - sdio_claim_irq(gInstance->func[2], IRQHandlerF2); - sdio_release_host(gInstance->func[2]); - } - - if (gInstance->func[1]) { - sdio_claim_host(gInstance->func[1]); - sdio_claim_irq(gInstance->func[1], IRQHandler); - sdio_release_host(gInstance->func[1]); - } -#elif defined(HW_OOB) - sdioh_enable_func_intr(); -#endif /* defined(OOB_INTR_ONLY) */ - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_interrupt_deregister(sdioh_info_t *sd) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - -#if !defined(OOB_INTR_ONLY) - if (gInstance->func[1]) { - /* register and unmask irq */ - sdio_claim_host(gInstance->func[1]); - sdio_release_irq(gInstance->func[1]); - sdio_release_host(gInstance->func[1]); - } - - if (gInstance->func[2]) { - /* Claim host controller F2 */ - sdio_claim_host(gInstance->func[2]); - sdio_release_irq(gInstance->func[2]); - /* Release host controller F2 */ - sdio_release_host(gInstance->func[2]); - } - - sd->intr_handler_valid = FALSE; - sd->intr_handler = NULL; - sd->intr_handler_arg = NULL; -#elif defined(HW_OOB) - sdioh_disable_func_intr(); -#endif /* !defined(OOB_INTR_ONLY) */ - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - *onoff = sd->client_intr_enabled; - return SDIOH_API_RC_SUCCESS; -} - -#if defined(DHD_DEBUG) -extern bool -sdioh_interrupt_pending(sdioh_info_t *sd) -{ - return (0); -} -#endif - -uint -sdioh_query_iofnum(sdioh_info_t *sd) -{ - return sd->num_funcs; -} - -/* IOVar table */ -enum { - IOV_MSGLEVEL = 1, - IOV_BLOCKMODE, - IOV_BLOCKSIZE, - IOV_DMA, - IOV_USEINTS, - IOV_NUMINTS, - IOV_NUMLOCALINTS, - IOV_HOSTREG, - IOV_DEVREG, - IOV_DIVISOR, - IOV_SDMODE, - IOV_HISPEED, - IOV_HCIREGS, - IOV_POWER, - IOV_CLOCK, - IOV_RXCHAIN -}; - -const bcm_iovar_t sdioh_iovars[] = { - {"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 }, - {"sd_blockmode", IOV_BLOCKMODE, 0, IOVT_BOOL, 0 }, - {"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0 }, /* ((fn << 16) | size) */ - {"sd_dma", IOV_DMA, 0, IOVT_BOOL, 0 }, - {"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0 }, - {"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0 }, - {"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32, 0 }, - {"sd_hostreg", IOV_HOSTREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_divisor", IOV_DIVISOR, 0, IOVT_UINT32, 0 }, - {"sd_power", IOV_POWER, 0, IOVT_UINT32, 0 }, - {"sd_clock", IOV_CLOCK, 0, IOVT_UINT32, 0 }, - {"sd_mode", IOV_SDMODE, 0, IOVT_UINT32, 100}, - {"sd_highspeed", IOV_HISPEED, 0, IOVT_UINT32, 0 }, - {"sd_rxchain", IOV_RXCHAIN, 0, IOVT_BOOL, 0 }, - {NULL, 0, 0, 0, 0 } -}; - -int -sdioh_iovar_op(sdioh_info_t *si, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - const bcm_iovar_t *vi = NULL; - int bcmerror = 0; - int val_size; - int32 int_val = 0; - bool bool_val; - uint32 actionid; - - ASSERT(name); - ASSERT(len >= 0); - - /* Get must have return space; Set does not take qualifiers */ - ASSERT(set || (arg && len)); - ASSERT(!set || (!params && !plen)); - - sd_trace(("%s: Enter (%s %s)\n", __FUNCTION__, (set ? "set" : "get"), name)); - - if ((vi = bcm_iovar_lookup(sdioh_iovars, name)) == NULL) { - bcmerror = BCME_UNSUPPORTED; - goto exit; - } - - if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, set)) != 0) - goto exit; - - /* Set up params so get and set can share the convenience variables */ - if (params == NULL) { - params = arg; - plen = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - val_size = sizeof(int); - - if (plen >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); - - bool_val = (int_val != 0) ? TRUE : FALSE; - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - switch (actionid) { - case IOV_GVAL(IOV_MSGLEVEL): - int_val = (int32)sd_msglevel; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_MSGLEVEL): - sd_msglevel = int_val; - break; - - case IOV_GVAL(IOV_BLOCKMODE): - int_val = (int32)si->sd_blockmode; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_BLOCKMODE): - si->sd_blockmode = (bool)int_val; - /* Haven't figured out how to make non-block mode with DMA */ - break; - - case IOV_GVAL(IOV_BLOCKSIZE): - if ((uint32)int_val > si->num_funcs) { - bcmerror = BCME_BADARG; - break; - } - int_val = (int32)si->client_block_size[int_val]; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_BLOCKSIZE): - { - uint func = ((uint32)int_val >> 16); - uint blksize = (uint16)int_val; - uint maxsize; - - if (func > si->num_funcs) { - bcmerror = BCME_BADARG; - break; - } - - switch (func) { - case 0: maxsize = 32; break; - case 1: maxsize = BLOCK_SIZE_4318; break; - case 2: maxsize = BLOCK_SIZE_4328; break; - default: maxsize = 0; - } - if (blksize > maxsize) { - bcmerror = BCME_BADARG; - break; - } - if (!blksize) { - blksize = maxsize; - } - - /* Now set it */ - si->client_block_size[func] = blksize; - - break; - } - - case IOV_GVAL(IOV_RXCHAIN): - int_val = FALSE; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_DMA): - int_val = (int32)si->sd_use_dma; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DMA): - si->sd_use_dma = (bool)int_val; - break; - - case IOV_GVAL(IOV_USEINTS): - int_val = (int32)si->use_client_ints; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_USEINTS): - si->use_client_ints = (bool)int_val; - if (si->use_client_ints) - si->intmask |= CLIENT_INTR; - else - si->intmask &= ~CLIENT_INTR; - - break; - - case IOV_GVAL(IOV_DIVISOR): - int_val = (uint32)sd_divisor; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DIVISOR): - sd_divisor = int_val; - break; - - case IOV_GVAL(IOV_POWER): - int_val = (uint32)sd_power; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_POWER): - sd_power = int_val; - break; - - case IOV_GVAL(IOV_CLOCK): - int_val = (uint32)sd_clock; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_CLOCK): - sd_clock = int_val; - break; - - case IOV_GVAL(IOV_SDMODE): - int_val = (uint32)sd_sdmode; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_SDMODE): - sd_sdmode = int_val; - break; - - case IOV_GVAL(IOV_HISPEED): - int_val = (uint32)sd_hiok; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_HISPEED): - sd_hiok = int_val; - break; - - case IOV_GVAL(IOV_NUMINTS): - int_val = (int32)si->intrcount; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_NUMLOCALINTS): - int_val = (int32)0; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_HOSTREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - - if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) { - sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset)); - bcmerror = BCME_BADARG; - break; - } - - sd_trace(("%s: rreg%d at offset %d\n", __FUNCTION__, - (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32), - sd_ptr->offset)); - if (sd_ptr->offset & 1) - int_val = 8; /* sdioh_sdmmc_rreg8(si, sd_ptr->offset); */ - else if (sd_ptr->offset & 2) - int_val = 16; /* sdioh_sdmmc_rreg16(si, sd_ptr->offset); */ - else - int_val = 32; /* sdioh_sdmmc_rreg(si, sd_ptr->offset); */ - - bcopy(&int_val, arg, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_HOSTREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - - if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) { - sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset)); - bcmerror = BCME_BADARG; - break; - } - - sd_trace(("%s: wreg%d value 0x%08x at offset %d\n", __FUNCTION__, sd_ptr->value, - (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32), - sd_ptr->offset)); - break; - } - - case IOV_GVAL(IOV_DEVREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - uint8 data = 0; - - if (sdioh_cfg_read(si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = BCME_SDIO_ERROR; - break; - } - - int_val = (int)data; - bcopy(&int_val, arg, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_DEVREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - uint8 data = (uint8)sd_ptr->value; - - if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = BCME_SDIO_ERROR; - break; - } - break; - } - - default: - bcmerror = BCME_UNSUPPORTED; - break; - } -exit: - - return bcmerror; -} - -#if defined(OOB_INTR_ONLY) && defined(HW_OOB) - -SDIOH_API_RC -sdioh_enable_hw_oob_intr(sdioh_info_t *sd, bool enable) -{ - SDIOH_API_RC status; - uint8 data; - - if (enable) - data = 3; /* enable hw oob interrupt */ - else - data = 4; /* disable hw oob interrupt */ - data |= 4; /* Active HIGH */ - - status = sdioh_request_byte(sd, SDIOH_WRITE, 0, 0xf2, &data); - return status; -} -#endif /* defined(OOB_INTR_ONLY) && defined(HW_OOB) */ - -extern SDIOH_API_RC -sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) -{ - SDIOH_API_RC status; - /* No lock needed since sdioh_request_byte does locking */ - status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data); - return status; -} - -extern SDIOH_API_RC -sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) -{ - /* No lock needed since sdioh_request_byte does locking */ - SDIOH_API_RC status; - status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data); - return status; -} - -static int -sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, uint32 regaddr) -{ - /* read 24 bits and return valid 17 bit addr */ - int i; - uint32 scratch, regdata; - uint8 *ptr = (uint8 *)&scratch; - for (i = 0; i < 3; i++) { - if ((sdioh_sdmmc_card_regread (sd, 0, regaddr, 1, ®data)) != SUCCESS) - sd_err(("%s: Can't read!\n", __FUNCTION__)); - - *ptr++ = (uint8) regdata; - regaddr++; - } - - /* Only the lower 17-bits are valid */ - scratch = ltoh32(scratch); - scratch &= 0x0001FFFF; - return (scratch); -} - -extern SDIOH_API_RC -sdioh_cis_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 length) -{ - uint32 count; - int offset; - uint32 foo; - uint8 *cis = cisd; - - sd_trace(("%s: Func = %d\n", __FUNCTION__, func)); - - if (!sd->func_cis_ptr[func]) { - bzero(cis, length); - sd_err(("%s: no func_cis_ptr[%d]\n", __FUNCTION__, func)); - return SDIOH_API_RC_FAIL; - } - - sd_err(("%s: func_cis_ptr[%d]=0x%04x\n", __FUNCTION__, func, sd->func_cis_ptr[func])); - - for (count = 0; count < length; count++) { - offset = sd->func_cis_ptr[func] + count; - if (sdioh_sdmmc_card_regread (sd, 0, offset, 1, &foo) < 0) { - sd_err(("%s: regread failed: Can't read CIS\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } - - *cis = (uint8)(foo & 0xff); - cis++; - } - - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte) -{ - int err_ret; - - sd_info(("%s: rw=%d, func=%d, addr=0x%05x\n", __FUNCTION__, rw, func, regaddr)); - - DHD_PM_RESUME_WAIT(sdioh_request_byte_wait); - DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); - if(rw) { /* CMD52 Write */ - if (func == 0) { - /* Can only directly write to some F0 registers. Handle F2 enable - * as a special case. - */ - if (regaddr == SDIOD_CCCR_IOEN) { - if (gInstance->func[2]) { - sdio_claim_host(gInstance->func[2]); - if (*byte & SDIO_FUNC_ENABLE_2) { - /* Enable Function 2 */ - err_ret = sdio_enable_func(gInstance->func[2]); - if (err_ret) { - sd_err(("bcmsdh_sdmmc: enable F2 failed:%d", - err_ret)); - } - } else { - /* Disable Function 2 */ - err_ret = sdio_disable_func(gInstance->func[2]); - if (err_ret) { - sd_err(("bcmsdh_sdmmc: Disab F2 failed:%d", - err_ret)); - } - } - sdio_release_host(gInstance->func[2]); - } - } -#if defined(MMC_SDIO_ABORT) - /* to allow abort command through F1 */ - else if (regaddr == SDIOD_CCCR_IOABORT) { - sdio_claim_host(gInstance->func[func]); - /* - * this sdio_f0_writeb() can be replaced with another api - * depending upon MMC driver change. - * As of this time, this is temporaray one - */ - sdio_writeb(gInstance->func[func], *byte, regaddr, &err_ret); - sdio_release_host(gInstance->func[func]); - } -#endif /* MMC_SDIO_ABORT */ - else if (regaddr < 0xF0) { - sd_err(("bcmsdh_sdmmc: F0 Wr:0x%02x: write disallowed\n", regaddr)); - } else { - /* Claim host controller, perform F0 write, and release */ - sdio_claim_host(gInstance->func[func]); - sdio_f0_writeb(gInstance->func[func], *byte, regaddr, &err_ret); - sdio_release_host(gInstance->func[func]); - } - } else { - /* Claim host controller, perform Fn write, and release */ - sdio_claim_host(gInstance->func[func]); - sdio_writeb(gInstance->func[func], *byte, regaddr, &err_ret); - sdio_release_host(gInstance->func[func]); - } - } else { /* CMD52 Read */ - /* Claim host controller, perform Fn read, and release */ - sdio_claim_host(gInstance->func[func]); - - if (func == 0) { - *byte = sdio_f0_readb(gInstance->func[func], regaddr, &err_ret); - } else { - *byte = sdio_readb(gInstance->func[func], regaddr, &err_ret); - } - - sdio_release_host(gInstance->func[func]); - } - - if (err_ret) { - sd_err(("bcmsdh_sdmmc: Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", - rw ? "Write" : "Read", func, regaddr, *byte, err_ret)); - } - - return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); -} - -extern SDIOH_API_RC -sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint addr, - uint32 *word, uint nbytes) -{ - int err_ret = SDIOH_API_RC_FAIL; - - if (func == 0) { - sd_err(("%s: Only CMD52 allowed to F0.\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } - - sd_info(("%s: cmd_type=%d, rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", - __FUNCTION__, cmd_type, rw, func, addr, nbytes)); - - DHD_PM_RESUME_WAIT(sdioh_request_word_wait); - DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); - /* Claim host controller */ - sdio_claim_host(gInstance->func[func]); - - if(rw) { /* CMD52 Write */ - if (nbytes == 4) { - sdio_writel(gInstance->func[func], *word, addr, &err_ret); - } else if (nbytes == 2) { - sdio_writew(gInstance->func[func], (*word & 0xFFFF), addr, &err_ret); - } else { - sd_err(("%s: Invalid nbytes: %d\n", __FUNCTION__, nbytes)); - } - } else { /* CMD52 Read */ - if (nbytes == 4) { - *word = sdio_readl(gInstance->func[func], addr, &err_ret); - } else if (nbytes == 2) { - *word = sdio_readw(gInstance->func[func], addr, &err_ret) & 0xFFFF; - } else { - sd_err(("%s: Invalid nbytes: %d\n", __FUNCTION__, nbytes)); - } - } - - /* Release host controller */ - sdio_release_host(gInstance->func[func]); - - if (err_ret) { - sd_err(("bcmsdh_sdmmc: Failed to %s word, Err: 0x%08x", - rw ? "Write" : "Read", err_ret)); - } - - return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); -} - -static SDIOH_API_RC -sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func, - uint addr, void *pkt) -{ - bool fifo = (fix_inc == SDIOH_DATA_FIX); - uint32 SGCount = 0; - int err_ret = 0; - - void *pnext; - - sd_trace(("%s: Enter\n", __FUNCTION__)); - - ASSERT(pkt); - DHD_PM_RESUME_WAIT(sdioh_request_packet_wait); - DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); - - /* Claim host controller */ - sdio_claim_host(gInstance->func[func]); - for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext)) { - uint pkt_len = PKTLEN(sd->osh, pnext); - pkt_len += 3; - pkt_len &= 0xFFFFFFFC; - -#ifdef CONFIG_MMC_MSM7X00A - if ((pkt_len % 64) == 32) { - sd_trace(("%s: Rounding up TX packet +=32\n", __FUNCTION__)); - pkt_len += 32; - } -#endif /* CONFIG_MMC_MSM7X00A */ - /* Make sure the packet is aligned properly. If it isn't, then this - * is the fault of sdioh_request_buffer() which is supposed to give - * us something we can work with. - */ - ASSERT(((uint32)(PKTDATA(sd->osh, pkt)) & DMA_ALIGN_MASK) == 0); - - if ((write) && (!fifo)) { - err_ret = sdio_memcpy_toio(gInstance->func[func], addr, - ((uint8*)PKTDATA(sd->osh, pnext)), - pkt_len); - } else if (write) { - err_ret = sdio_memcpy_toio(gInstance->func[func], addr, - ((uint8*)PKTDATA(sd->osh, pnext)), - pkt_len); - } else if (fifo) { - err_ret = sdio_readsb(gInstance->func[func], - ((uint8*)PKTDATA(sd->osh, pnext)), - addr, - pkt_len); - } else { - err_ret = sdio_memcpy_fromio(gInstance->func[func], - ((uint8*)PKTDATA(sd->osh, pnext)), - addr, - pkt_len); - } - - if (err_ret) { - sd_err(("%s: %s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n", - __FUNCTION__, - (write) ? "TX" : "RX", - pnext, SGCount, addr, pkt_len, err_ret)); - } else { - sd_trace(("%s: %s xfr'd %p[%d], addr=0x%05x, len=%d\n", - __FUNCTION__, - (write) ? "TX" : "RX", - pnext, SGCount, addr, pkt_len)); - } - - if (!fifo) { - addr += pkt_len; - } - SGCount ++; - - } - - /* Release host controller */ - sdio_release_host(gInstance->func[func]); - - sd_trace(("%s: Exit\n", __FUNCTION__)); - return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); -} - - -/* - * This function takes a buffer or packet, and fixes everything up so that in the - * end, a DMA-able packet is created. - * - * A buffer does not have an associated packet pointer, and may or may not be aligned. - * A packet may consist of a single packet, or a packet chain. If it is a packet chain, - * then all the packets in the chain must be properly aligned. If the packet data is not - * aligned, then there may only be one packet, and in this case, it is copied to a new - * aligned packet. - * - */ -extern SDIOH_API_RC -sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, uint func, - uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt) -{ - SDIOH_API_RC Status; - void *mypkt = NULL; - - sd_trace(("%s: Enter\n", __FUNCTION__)); - - DHD_PM_RESUME_WAIT(sdioh_request_buffer_wait); - DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); - /* Case 1: we don't have a packet. */ - if (pkt == NULL) { - sd_data(("%s: Creating new %s Packet, len=%d\n", - __FUNCTION__, write ? "TX" : "RX", buflen_u)); -#ifdef DHD_USE_STATIC_BUF - if (!(mypkt = PKTGET_STATIC(sd->osh, buflen_u, write ? TRUE : FALSE))) { -#else - if (!(mypkt = PKTGET(sd->osh, buflen_u, write ? TRUE : FALSE))) { -#endif /* DHD_USE_STATIC_BUF */ - sd_err(("%s: PKTGET failed: len %d\n", - __FUNCTION__, buflen_u)); - return SDIOH_API_RC_FAIL; - } - - /* For a write, copy the buffer data into the packet. */ - if (write) { - bcopy(buffer, PKTDATA(sd->osh, mypkt), buflen_u); - } - - Status = sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt); - - /* For a read, copy the packet data back to the buffer. */ - if (!write) { - bcopy(PKTDATA(sd->osh, mypkt), buffer, buflen_u); - } -#ifdef DHD_USE_STATIC_BUF - PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE); -#else - PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE); -#endif /* DHD_USE_STATIC_BUF */ - } else if (((uint32)(PKTDATA(sd->osh, pkt)) & DMA_ALIGN_MASK) != 0) { - /* Case 2: We have a packet, but it is unaligned. */ - - /* In this case, we cannot have a chain. */ - ASSERT(PKTNEXT(sd->osh, pkt) == NULL); - - sd_data(("%s: Creating aligned %s Packet, len=%d\n", - __FUNCTION__, write ? "TX" : "RX", PKTLEN(sd->osh, pkt))); -#ifdef DHD_USE_STATIC_BUF - if (!(mypkt = PKTGET_STATIC(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE))) { -#else - if (!(mypkt = PKTGET(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE))) { -#endif /* DHD_USE_STATIC_BUF */ - sd_err(("%s: PKTGET failed: len %d\n", - __FUNCTION__, PKTLEN(sd->osh, pkt))); - return SDIOH_API_RC_FAIL; - } - - /* For a write, copy the buffer data into the packet. */ - if (write) { - bcopy(PKTDATA(sd->osh, pkt), - PKTDATA(sd->osh, mypkt), - PKTLEN(sd->osh, pkt)); - } - - Status = sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt); - - /* For a read, copy the packet data back to the buffer. */ - if (!write) { - bcopy(PKTDATA(sd->osh, mypkt), - PKTDATA(sd->osh, pkt), - PKTLEN(sd->osh, mypkt)); - } -#ifdef DHD_USE_STATIC_BUF - PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE); -#else - PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE); -#endif /* DHD_USE_STATIC_BUF */ - } else { /* case 3: We have a packet and it is aligned. */ - sd_data(("%s: Aligned %s Packet, direct DMA\n", - __FUNCTION__, write ? "Tx" : "Rx")); - Status = sdioh_request_packet(sd, fix_inc, write, func, addr, pkt); - } - - return (Status); -} - -/* this function performs "abort" for both of host & device */ -extern int -sdioh_abort(sdioh_info_t *sd, uint func) -{ -#if defined(MMC_SDIO_ABORT) - char t_func = (char) func; -#endif /* defined(MMC_SDIO_ABORT) */ - sd_trace(("%s: Enter\n", __FUNCTION__)); - -#if defined(MMC_SDIO_ABORT) - /* issue abort cmd52 command through F1 */ - sdioh_request_byte(sd, SD_IO_OP_WRITE, SDIO_FUNC_0, SDIOD_CCCR_IOABORT, &t_func); -#endif /* defined(MMC_SDIO_ABORT) */ - - sd_trace(("%s: Exit\n", __FUNCTION__)); - return SDIOH_API_RC_SUCCESS; -} - -/* Reset and re-initialize the device */ -int sdioh_sdio_reset(sdioh_info_t *si) -{ - sd_trace(("%s: Enter\n", __FUNCTION__)); - sd_trace(("%s: Exit\n", __FUNCTION__)); - return SDIOH_API_RC_SUCCESS; -} - -/* Disable device interrupt */ -void -sdioh_sdmmc_devintr_off(sdioh_info_t *sd) -{ - sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints)); - sd->intmask &= ~CLIENT_INTR; -} - -/* Enable device interrupt */ -void -sdioh_sdmmc_devintr_on(sdioh_info_t *sd) -{ - sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints)); - sd->intmask |= CLIENT_INTR; -} - -/* Read client card reg */ -int -sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data) -{ - - if ((func == 0) || (regsize == 1)) { - uint8 temp = 0; - - sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp); - *data = temp; - *data &= 0xff; - sd_data(("%s: byte read data=0x%02x\n", - __FUNCTION__, *data)); - } else { - sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, data, regsize); - if (regsize == 2) - *data &= 0xffff; - - sd_data(("%s: word read data=0x%08x\n", - __FUNCTION__, *data)); - } - - return SUCCESS; -} - -#if !defined(OOB_INTR_ONLY) -/* bcmsdh_sdmmc interrupt handler */ -static void IRQHandler(struct sdio_func *func) -{ - sdioh_info_t *sd; - - sd_trace(("bcmsdh_sdmmc: ***IRQHandler\n")); - sd = gInstance->sd; - - ASSERT(sd != NULL); - sdio_release_host(gInstance->func[0]); - - if (sd->use_client_ints) { - sd->intrcount++; - ASSERT(sd->intr_handler); - ASSERT(sd->intr_handler_arg); - (sd->intr_handler)(sd->intr_handler_arg); - } else { - sd_err(("bcmsdh_sdmmc: ***IRQHandler\n")); - - sd_err(("%s: Not ready for intr: enabled %d, handler %p\n", - __FUNCTION__, sd->client_intr_enabled, sd->intr_handler)); - } - - sdio_claim_host(gInstance->func[0]); -} - -/* bcmsdh_sdmmc interrupt handler for F2 (dummy handler) */ -static void IRQHandlerF2(struct sdio_func *func) -{ - sdioh_info_t *sd; - - sd_trace(("bcmsdh_sdmmc: ***IRQHandlerF2\n")); - - sd = gInstance->sd; - - ASSERT(sd != NULL); -} -#endif /* !defined(OOB_INTR_ONLY) */ - -#ifdef NOTUSED -/* Write client card reg */ -static int -sdioh_sdmmc_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 data) -{ - - if ((func == 0) || (regsize == 1)) { - uint8 temp; - - temp = data & 0xff; - sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp); - sd_data(("%s: byte write data=0x%02x\n", - __FUNCTION__, data)); - } else { - if (regsize == 2) - data &= 0xffff; - - sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, &data, regsize); - - sd_data(("%s: word write data=0x%08x\n", - __FUNCTION__, data)); - } - - return SUCCESS; -} -#endif /* NOTUSED */ - -int -sdioh_start(sdioh_info_t *si, int stage) -{ - int ret; - sdioh_info_t *sd = gInstance->sd; - - /* Need to do this stages as we can't enable the interrupt till - downloading of the firmware is complete, other wise polling - sdio access will come in way - */ - if (gInstance->func[0]) { - if (stage == 0) { - /* Since the power to the chip is killed, we will have - re enumerate the device again. Set the block size - and enable the fucntion 1 for in preparation for - downloading the code - */ - /* sdio_reset_comm() - has been fixed in latest kernel/msm.git for Linux - 2.6.27. The implementation prior to that is buggy, and needs broadcom's - patch for it - */ - if ((ret = sdio_reset_comm(gInstance->func[0]->card))) - sd_err(("%s Failed, error = %d\n", __FUNCTION__, ret)); - else { - sd->num_funcs = 2; - sd->sd_blockmode = TRUE; - sd->use_client_ints = TRUE; - sd->client_block_size[0] = 64; - - /* Claim host controller */ - sdio_claim_host(gInstance->func[1]); - - sd->client_block_size[1] = 64; - if (sdio_set_block_size(gInstance->func[1], 64)) { - sd_err(("bcmsdh_sdmmc: Failed to set F1 blocksize\n")); - } - - /* Release host controller F1 */ - sdio_release_host(gInstance->func[1]); - - if (gInstance->func[2]) { - /* Claim host controller F2 */ - sdio_claim_host(gInstance->func[2]); - - sd->client_block_size[2] = sd_f2_blocksize; - if (sdio_set_block_size(gInstance->func[2], - sd_f2_blocksize)) { - sd_err(("bcmsdh_sdmmc: Failed to set F2 " - "blocksize to %d\n", sd_f2_blocksize)); - } - - /* Release host controller F2 */ - sdio_release_host(gInstance->func[2]); - } - - sdioh_sdmmc_card_enablefuncs(sd); - } - } else { -#if !defined(OOB_INTR_ONLY) - sdio_claim_host(gInstance->func[0]); - sdio_claim_irq(gInstance->func[2], IRQHandlerF2); - sdio_claim_irq(gInstance->func[1], IRQHandler); - sdio_release_host(gInstance->func[0]); -#else /* defined(OOB_INTR_ONLY) */ -#if defined(HW_OOB) - sdioh_enable_func_intr(); -#endif - bcmsdh_oob_intr_set(TRUE); -#endif /* !defined(OOB_INTR_ONLY) */ - } - } - else - sd_err(("%s Failed\n", __FUNCTION__)); - - return (0); -} - -int -sdioh_stop(sdioh_info_t *si) -{ - /* MSM7201A Android sdio stack has bug with interrupt - So internaly within SDIO stack they are polling - which cause issue when device is turned off. So - unregister interrupt with SDIO stack to stop the - polling - */ - if (gInstance->func[0]) { -#if !defined(OOB_INTR_ONLY) - sdio_claim_host(gInstance->func[0]); - sdio_release_irq(gInstance->func[1]); - sdio_release_irq(gInstance->func[2]); - sdio_release_host(gInstance->func[0]); -#else /* defined(OOB_INTR_ONLY) */ -#if defined(HW_OOB) - sdioh_disable_func_intr(); -#endif - bcmsdh_oob_intr_set(FALSE); -#endif /* !defined(OOB_INTR_ONLY) */ - } - else - sd_err(("%s Failed\n", __FUNCTION__)); - return (0); -} diff --git a/drivers/net/wireless/bcm4329/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/bcm4329/bcmsdh_sdmmc_linux.c deleted file mode 100644 index 5a1a46c93571..000000000000 --- a/drivers/net/wireless/bcm4329/bcmsdh_sdmmc_linux.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdh_sdmmc_linux.c,v 1.1.2.5.6.17 2010/08/13 00:36:19 Exp $ - */ - -#include -#include -#include /* SDIO Specs */ -#include /* bcmsdh to/from specific controller APIs */ -#include /* to get msglevel bit values */ - -#include /* request_irq() */ - -#include -#include -#include -#include - -#if !defined(SDIO_VENDOR_ID_BROADCOM) -#define SDIO_VENDOR_ID_BROADCOM 0x02d0 -#endif /* !defined(SDIO_VENDOR_ID_BROADCOM) */ - -#define SDIO_DEVICE_ID_BROADCOM_DEFAULT 0x0000 - -#if !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) -#define SDIO_DEVICE_ID_BROADCOM_4325_SDGWB 0x0492 /* BCM94325SDGWB */ -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) */ -#if !defined(SDIO_DEVICE_ID_BROADCOM_4325) -#define SDIO_DEVICE_ID_BROADCOM_4325 0x0493 -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325) */ -#if !defined(SDIO_DEVICE_ID_BROADCOM_4329) -#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */ -#if !defined(SDIO_DEVICE_ID_BROADCOM_4319) -#define SDIO_DEVICE_ID_BROADCOM_4319 0x4319 -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */ - -#include - -#include - -extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd); -extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd); - -int sdio_function_init(void); -void sdio_function_cleanup(void); - -#define DESCRIPTION "bcmsdh_sdmmc Driver" -#define AUTHOR "Broadcom Corporation" - -/* module param defaults */ -static int clockoverride = 0; - -module_param(clockoverride, int, 0644); -MODULE_PARM_DESC(clockoverride, "SDIO card clock override"); - -PBCMSDH_SDMMC_INSTANCE gInstance; - -/* Maximum number of bcmsdh_sdmmc devices supported by driver */ -#define BCMSDH_SDMMC_MAX_DEVICES 1 - -extern int bcmsdh_probe(struct device *dev); -extern int bcmsdh_remove(struct device *dev); - -static int bcmsdh_sdmmc_probe(struct sdio_func *func, - const struct sdio_device_id *id) -{ - int ret = 0; - static struct sdio_func sdio_func_0; - sd_trace(("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__)); - sd_trace(("sdio_bcmsdh: func->class=%x\n", func->class)); - sd_trace(("sdio_vendor: 0x%04x\n", func->vendor)); - sd_trace(("sdio_device: 0x%04x\n", func->device)); - sd_trace(("Function#: 0x%04x\n", func->num)); - - if (func->num == 1) { - sdio_func_0.num = 0; - sdio_func_0.card = func->card; - gInstance->func[0] = &sdio_func_0; - if(func->device == 0x4) { /* 4318 */ - gInstance->func[2] = NULL; - sd_trace(("NIC found, calling bcmsdh_probe...\n")); - ret = bcmsdh_probe(&func->dev); - } - } - - gInstance->func[func->num] = func; - - if (func->num == 2) { - sd_trace(("F2 found, calling bcmsdh_probe...\n")); - ret = bcmsdh_probe(&func->dev); - } - - return ret; -} - -static void bcmsdh_sdmmc_remove(struct sdio_func *func) -{ - sd_trace(("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__)); - sd_info(("sdio_bcmsdh: func->class=%x\n", func->class)); - sd_info(("sdio_vendor: 0x%04x\n", func->vendor)); - sd_info(("sdio_device: 0x%04x\n", func->device)); - sd_info(("Function#: 0x%04x\n", func->num)); - - if (func->num == 2) { - sd_trace(("F2 found, calling bcmsdh_remove...\n")); - bcmsdh_remove(&func->dev); - } -} - -/* devices we support, null terminated */ -static const struct sdio_device_id bcmsdh_sdmmc_ids[] = { - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_DEFAULT) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4319) }, - { /* end: all zeroes */ }, -}; - -MODULE_DEVICE_TABLE(sdio, bcmsdh_sdmmc_ids); - -static struct sdio_driver bcmsdh_sdmmc_driver = { - .probe = bcmsdh_sdmmc_probe, - .remove = bcmsdh_sdmmc_remove, - .name = "bcmsdh_sdmmc", - .id_table = bcmsdh_sdmmc_ids, - }; - -struct sdos_info { - sdioh_info_t *sd; - spinlock_t lock; -}; - - -int -sdioh_sdmmc_osinit(sdioh_info_t *sd) -{ - struct sdos_info *sdos; - - sdos = (struct sdos_info*)MALLOC(sd->osh, sizeof(struct sdos_info)); - sd->sdos_info = (void*)sdos; - if (sdos == NULL) - return BCME_NOMEM; - - sdos->sd = sd; - spin_lock_init(&sdos->lock); - return BCME_OK; -} - -void -sdioh_sdmmc_osfree(sdioh_info_t *sd) -{ - struct sdos_info *sdos; - ASSERT(sd && sd->sdos_info); - - sdos = (struct sdos_info *)sd->sdos_info; - MFREE(sd->osh, sdos, sizeof(struct sdos_info)); -} - -/* Interrupt enable/disable */ -SDIOH_API_RC -sdioh_interrupt_set(sdioh_info_t *sd, bool enable) -{ - ulong flags; - struct sdos_info *sdos; - - sd_trace(("%s: %s\n", __FUNCTION__, enable ? "Enabling" : "Disabling")); - - sdos = (struct sdos_info *)sd->sdos_info; - ASSERT(sdos); - -#if !defined(OOB_INTR_ONLY) - if (enable && !(sd->intr_handler && sd->intr_handler_arg)) { - sd_err(("%s: no handler registered, will not enable\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } -#endif /* !defined(OOB_INTR_ONLY) */ - - /* Ensure atomicity for enable/disable calls */ - spin_lock_irqsave(&sdos->lock, flags); - - sd->client_intr_enabled = enable; - if (enable) { - sdioh_sdmmc_devintr_on(sd); - } else { - sdioh_sdmmc_devintr_off(sd); - } - - spin_unlock_irqrestore(&sdos->lock, flags); - - return SDIOH_API_RC_SUCCESS; -} - - -#ifdef BCMSDH_MODULE -static int __init -bcmsdh_module_init(void) -{ - int error = 0; - sdio_function_init(); - return error; -} - -static void __exit -bcmsdh_module_cleanup(void) -{ - sdio_function_cleanup(); -} - -module_init(bcmsdh_module_init); -module_exit(bcmsdh_module_cleanup); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION(DESCRIPTION); -MODULE_AUTHOR(AUTHOR); - -#endif /* BCMSDH_MODULE */ -/* - * module init -*/ -int sdio_function_init(void) -{ - int error = 0; - sd_trace(("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__)); - - gInstance = kzalloc(sizeof(BCMSDH_SDMMC_INSTANCE), GFP_KERNEL); - if (!gInstance) - return -ENOMEM; - - error = sdio_register_driver(&bcmsdh_sdmmc_driver); - - return error; -} - -/* - * module cleanup -*/ -extern int bcmsdh_remove(struct device *dev); -void sdio_function_cleanup(void) -{ - sd_trace(("%s Enter\n", __FUNCTION__)); - - sdio_unregister_driver(&bcmsdh_sdmmc_driver); - - if (gInstance) - kfree(gInstance); -} diff --git a/drivers/net/wireless/bcm4329/bcmsdspi.c b/drivers/net/wireless/bcm4329/bcmsdspi.c deleted file mode 100644 index 636539be5ea5..000000000000 --- a/drivers/net/wireless/bcm4329/bcmsdspi.c +++ /dev/null @@ -1,1596 +0,0 @@ -/* - * Broadcom BCMSDH to SPI Protocol Conversion Layer - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdspi.c,v 1.14.4.2.4.4.6.5 2010/03/10 03:09:48 Exp $ - */ - -#include - -#include -#include -#include -#include -#include -#include /* SDIO Device and Protocol Specs */ -#include /* SDIO Host Controller Specification */ -#include /* bcmsdh to/from specific controller APIs */ -#include /* ioctl/iovars */ - -#include - - -#include -#include - -#include - -#define SD_PAGE 4096 - -/* Globals */ - -uint sd_msglevel = SDH_ERROR_VAL; -uint sd_hiok = FALSE; /* Use hi-speed mode if available? */ -uint sd_sdmode = SDIOH_MODE_SPI; /* Use SD4 mode by default */ -uint sd_f2_blocksize = 512; /* Default blocksize */ - -uint sd_divisor = 2; /* Default 33MHz/2 = 16MHz for dongle */ -uint sd_power = 1; /* Default to SD Slot powered ON */ -uint sd_clock = 1; /* Default to SD Clock turned ON */ -uint sd_crc = 0; /* Default to SPI CRC Check turned OFF */ -uint sd_pci_slot = 0xFFFFffff; /* Used to force selection of a particular PCI slot */ - -uint sd_toctl = 7; - -/* Prototypes */ -static bool sdspi_start_power(sdioh_info_t *sd); -static int sdspi_set_highspeed_mode(sdioh_info_t *sd, bool HSMode); -static int sdspi_card_enablefuncs(sdioh_info_t *sd); -static void sdspi_cmd_getrsp(sdioh_info_t *sd, uint32 *rsp_buffer, int count); -static int sdspi_cmd_issue(sdioh_info_t *sd, bool use_dma, uint32 cmd, uint32 arg, - uint32 *data, uint32 datalen); -static int sdspi_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, - int regsize, uint32 *data); -static int sdspi_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, - int regsize, uint32 data); -static int sdspi_driver_init(sdioh_info_t *sd); -static bool sdspi_reset(sdioh_info_t *sd, bool host_reset, bool client_reset); -static int sdspi_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo, - uint32 addr, int nbytes, uint32 *data); -static int sdspi_abort(sdioh_info_t *sd, uint func); - -static int set_client_block_size(sdioh_info_t *sd, int func, int blocksize); - -static uint8 sdspi_crc7(unsigned char* p, uint32 len); -static uint16 sdspi_crc16(unsigned char* p, uint32 len); -static int sdspi_crc_onoff(sdioh_info_t *sd, bool use_crc); - -/* - * Public entry points & extern's - */ -extern sdioh_info_t * -sdioh_attach(osl_t *osh, void *bar0, uint irq) -{ - sdioh_info_t *sd; - - sd_trace(("%s\n", __FUNCTION__)); - if ((sd = (sdioh_info_t *)MALLOC(osh, sizeof(sdioh_info_t))) == NULL) { - sd_err(("sdioh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh))); - return NULL; - } - bzero((char *)sd, sizeof(sdioh_info_t)); - sd->osh = osh; - - if (spi_osinit(sd) != 0) { - sd_err(("%s: spi_osinit() failed\n", __FUNCTION__)); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return NULL; - } - - sd->bar0 = (uintptr)bar0; - sd->irq = irq; - sd->intr_handler = NULL; - sd->intr_handler_arg = NULL; - sd->intr_handler_valid = FALSE; - - /* Set defaults */ - sd->sd_blockmode = FALSE; - sd->use_client_ints = TRUE; - sd->sd_use_dma = FALSE; /* DMA Not supported */ - - /* Haven't figured out how to make bytemode work with dma */ - if (!sd->sd_blockmode) - sd->sd_use_dma = 0; - - if (!spi_hw_attach(sd)) { - sd_err(("%s: spi_hw_attach() failed\n", __FUNCTION__)); - spi_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return NULL; - } - - if (sdspi_driver_init(sd) != SUCCESS) { - if (sdspi_driver_init(sd) != SUCCESS) { - sd_err(("%s:sdspi_driver_init() failed()\n", __FUNCTION__)); - spi_hw_detach(sd); - spi_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return (NULL); - } - } - - if (spi_register_irq(sd, irq) != SUCCESS) { - sd_err(("%s: spi_register_irq() failed for irq = %d\n", __FUNCTION__, irq)); - spi_hw_detach(sd); - spi_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return (NULL); - } - - sd_trace(("%s: Done\n", __FUNCTION__)); - return sd; -} - -extern SDIOH_API_RC -sdioh_detach(osl_t *osh, sdioh_info_t *sd) -{ - sd_trace(("%s\n", __FUNCTION__)); - - if (sd) { - if (sd->card_init_done) - sdspi_reset(sd, 1, 1); - - sd_info(("%s: detaching from hardware\n", __FUNCTION__)); - spi_free_irq(sd->irq, sd); - spi_hw_detach(sd); - spi_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - } - - return SDIOH_API_RC_SUCCESS; -} - -/* Configure callback to client when we recieve client interrupt */ -extern SDIOH_API_RC -sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - - sd->intr_handler = fn; - sd->intr_handler_arg = argh; - sd->intr_handler_valid = TRUE; - - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_interrupt_deregister(sdioh_info_t *sd) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - - sd->intr_handler_valid = FALSE; - sd->intr_handler = NULL; - sd->intr_handler_arg = NULL; - - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - - *onoff = sd->client_intr_enabled; - - return SDIOH_API_RC_SUCCESS; -} - -#if defined(DHD_DEBUG) -extern bool -sdioh_interrupt_pending(sdioh_info_t *sd) -{ - return 0; -} -#endif - -uint -sdioh_query_iofnum(sdioh_info_t *sd) -{ - return sd->num_funcs; -} - -/* IOVar table */ -enum { - IOV_MSGLEVEL = 1, - IOV_BLOCKMODE, - IOV_BLOCKSIZE, - IOV_DMA, - IOV_USEINTS, - IOV_NUMINTS, - IOV_NUMLOCALINTS, - IOV_HOSTREG, - IOV_DEVREG, - IOV_DIVISOR, - IOV_SDMODE, - IOV_HISPEED, - IOV_HCIREGS, - IOV_POWER, - IOV_CLOCK, - IOV_CRC -}; - -const bcm_iovar_t sdioh_iovars[] = { - {"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 }, - {"sd_blockmode", IOV_BLOCKMODE, 0, IOVT_BOOL, 0 }, - {"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0 }, /* ((fn << 16) | size) */ - {"sd_dma", IOV_DMA, 0, IOVT_BOOL, 0 }, - {"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0 }, - {"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0 }, - {"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32, 0 }, - {"sd_hostreg", IOV_HOSTREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_divisor", IOV_DIVISOR, 0, IOVT_UINT32, 0 }, - {"sd_power", IOV_POWER, 0, IOVT_UINT32, 0 }, - {"sd_clock", IOV_CLOCK, 0, IOVT_UINT32, 0 }, - {"sd_crc", IOV_CRC, 0, IOVT_UINT32, 0 }, - {"sd_mode", IOV_SDMODE, 0, IOVT_UINT32, 100}, - {"sd_highspeed", IOV_HISPEED, 0, IOVT_UINT32, 0}, - {NULL, 0, 0, 0, 0 } -}; - -int -sdioh_iovar_op(sdioh_info_t *si, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - const bcm_iovar_t *vi = NULL; - int bcmerror = 0; - int val_size; - int32 int_val = 0; - bool bool_val; - uint32 actionid; - - ASSERT(name); - ASSERT(len >= 0); - - /* Get must have return space; Set does not take qualifiers */ - ASSERT(set || (arg && len)); - ASSERT(!set || (!params && !plen)); - - sd_trace(("%s: Enter (%s %s)\n", __FUNCTION__, (set ? "set" : "get"), name)); - - if ((vi = bcm_iovar_lookup(sdioh_iovars, name)) == NULL) { - bcmerror = BCME_UNSUPPORTED; - goto exit; - } - - if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, set)) != 0) - goto exit; - - /* Set up params so get and set can share the convenience variables */ - if (params == NULL) { - params = arg; - plen = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - val_size = sizeof(int); - - if (plen >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); - - bool_val = (int_val != 0) ? TRUE : FALSE; - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - switch (actionid) { - case IOV_GVAL(IOV_MSGLEVEL): - int_val = (int32)sd_msglevel; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_MSGLEVEL): - sd_msglevel = int_val; - break; - - case IOV_GVAL(IOV_BLOCKMODE): - int_val = (int32)si->sd_blockmode; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_BLOCKMODE): - si->sd_blockmode = (bool)int_val; - /* Haven't figured out how to make non-block mode with DMA */ - if (!si->sd_blockmode) - si->sd_use_dma = 0; - break; - - case IOV_GVAL(IOV_BLOCKSIZE): - if ((uint32)int_val > si->num_funcs) { - bcmerror = BCME_BADARG; - break; - } - int_val = (int32)si->client_block_size[int_val]; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_BLOCKSIZE): - { - uint func = ((uint32)int_val >> 16); - uint blksize = (uint16)int_val; - uint maxsize; - - if (func > si->num_funcs) { - bcmerror = BCME_BADARG; - break; - } - - switch (func) { - case 0: maxsize = 32; break; - case 1: maxsize = BLOCK_SIZE_4318; break; - case 2: maxsize = BLOCK_SIZE_4328; break; - default: maxsize = 0; - } - if (blksize > maxsize) { - bcmerror = BCME_BADARG; - break; - } - if (!blksize) { - blksize = maxsize; - } - - /* Now set it */ - spi_lock(si); - bcmerror = set_client_block_size(si, func, blksize); - spi_unlock(si); - break; - } - - case IOV_GVAL(IOV_DMA): - int_val = (int32)si->sd_use_dma; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DMA): - si->sd_use_dma = (bool)int_val; - break; - - case IOV_GVAL(IOV_USEINTS): - int_val = (int32)si->use_client_ints; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_USEINTS): - break; - - case IOV_GVAL(IOV_DIVISOR): - int_val = (uint32)sd_divisor; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DIVISOR): - sd_divisor = int_val; - if (!spi_start_clock(si, (uint16)sd_divisor)) { - sd_err(("set clock failed!\n")); - bcmerror = BCME_ERROR; - } - break; - - case IOV_GVAL(IOV_POWER): - int_val = (uint32)sd_power; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_POWER): - sd_power = int_val; - break; - - case IOV_GVAL(IOV_CLOCK): - int_val = (uint32)sd_clock; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_CLOCK): - sd_clock = int_val; - break; - - case IOV_GVAL(IOV_CRC): - int_val = (uint32)sd_crc; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_CRC): - /* Apply new setting, but don't change sd_crc until - * after the CRC-mode is selected in the device. This - * is required because the software must generate a - * correct CRC for the CMD59 in order to be able to - * turn OFF the CRC. - */ - sdspi_crc_onoff(si, int_val ? 1 : 0); - sd_crc = int_val; - break; - - case IOV_GVAL(IOV_SDMODE): - int_val = (uint32)sd_sdmode; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_SDMODE): - sd_sdmode = int_val; - break; - - case IOV_GVAL(IOV_HISPEED): - int_val = (uint32)sd_hiok; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_HISPEED): - sd_hiok = int_val; - - if (!sdspi_set_highspeed_mode(si, (bool)sd_hiok)) { - sd_err(("Failed changing highspeed mode to %d.\n", sd_hiok)); - bcmerror = BCME_ERROR; - return ERROR; - } - break; - - case IOV_GVAL(IOV_NUMINTS): - int_val = (int32)si->intrcount; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_NUMLOCALINTS): - int_val = (int32)si->local_intrcount; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_HOSTREG): - { - break; - } - - case IOV_SVAL(IOV_HOSTREG): - { - sd_err(("IOV_HOSTREG unsupported\n")); - break; - } - - case IOV_GVAL(IOV_DEVREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - uint8 data; - - if (sdioh_cfg_read(si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = BCME_SDIO_ERROR; - break; - } - - int_val = (int)data; - bcopy(&int_val, arg, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_DEVREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - uint8 data = (uint8)sd_ptr->value; - - if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = BCME_SDIO_ERROR; - break; - } - break; - } - - - default: - bcmerror = BCME_UNSUPPORTED; - break; - } -exit: - - return bcmerror; -} - -extern SDIOH_API_RC -sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) -{ - SDIOH_API_RC status; - /* No lock needed since sdioh_request_byte does locking */ - status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data); - return status; -} - -extern SDIOH_API_RC -sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) -{ - /* No lock needed since sdioh_request_byte does locking */ - SDIOH_API_RC status; - status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data); - return status; -} - -extern SDIOH_API_RC -sdioh_cis_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 length) -{ - uint32 count; - int offset; - uint32 foo; - uint8 *cis = cisd; - - sd_trace(("%s: Func = %d\n", __FUNCTION__, func)); - - if (!sd->func_cis_ptr[func]) { - bzero(cis, length); - return SDIOH_API_RC_FAIL; - } - - spi_lock(sd); - *cis = 0; - for (count = 0; count < length; count++) { - offset = sd->func_cis_ptr[func] + count; - if (sdspi_card_regread (sd, 0, offset, 1, &foo) < 0) { - sd_err(("%s: regread failed: Can't read CIS\n", __FUNCTION__)); - spi_unlock(sd); - return SDIOH_API_RC_FAIL; - } - *cis = (uint8)(foo & 0xff); - cis++; - } - spi_unlock(sd); - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte) -{ - int status; - uint32 cmd_arg; - uint32 rsp5; - - spi_lock(sd); - - cmd_arg = 0; - cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, rw == SDIOH_READ ? 0 : 1); - cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0); - cmd_arg = SFIELD(cmd_arg, CMD52_DATA, rw == SDIOH_READ ? 0 : *byte); - - sd_trace(("%s: rw=%d, func=%d, regaddr=0x%08x\n", __FUNCTION__, rw, func, regaddr)); - - if ((status = sdspi_cmd_issue(sd, sd->sd_use_dma, - SDIOH_CMD_52, cmd_arg, NULL, 0)) != SUCCESS) { - spi_unlock(sd); - return status; - } - - sdspi_cmd_getrsp(sd, &rsp5, 1); - if (rsp5 != 0x00) { - sd_err(("%s: rsp5 flags is 0x%x func=%d\n", - __FUNCTION__, rsp5, func)); - /* ASSERT(0); */ - spi_unlock(sd); - return SDIOH_API_RC_FAIL; - } - - if (rw == SDIOH_READ) - *byte = sd->card_rsp_data >> 24; - - spi_unlock(sd); - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint addr, - uint32 *word, uint nbytes) -{ - int status; - - spi_lock(sd); - - if (rw == SDIOH_READ) - status = sdspi_card_regread(sd, func, addr, nbytes, word); - else - status = sdspi_card_regwrite(sd, func, addr, nbytes, *word); - - spi_unlock(sd); - return (status == SUCCESS ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); -} - -extern SDIOH_API_RC -sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint rw, uint func, - uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt) -{ - int len; - int buflen = (int)buflen_u; - bool fifo = (fix_inc == SDIOH_DATA_FIX); - - spi_lock(sd); - - ASSERT(reg_width == 4); - ASSERT(buflen_u < (1 << 30)); - ASSERT(sd->client_block_size[func]); - - sd_data(("%s: %c len %d r_cnt %d t_cnt %d, pkt @0x%p\n", - __FUNCTION__, rw == SDIOH_READ ? 'R' : 'W', - buflen_u, sd->r_cnt, sd->t_cnt, pkt)); - - /* Break buffer down into blocksize chunks: - * Bytemode: 1 block at a time. - */ - while (buflen > 0) { - if (sd->sd_blockmode) { - /* Max xfer is Page size */ - len = MIN(SD_PAGE, buflen); - - /* Round down to a block boundry */ - if (buflen > sd->client_block_size[func]) - len = (len/sd->client_block_size[func]) * - sd->client_block_size[func]; - } else { - /* Byte mode: One block at a time */ - len = MIN(sd->client_block_size[func], buflen); - } - - if (sdspi_card_buf(sd, rw, func, fifo, addr, len, (uint32 *)buffer) != SUCCESS) { - spi_unlock(sd); - return SDIOH_API_RC_FAIL; - } - buffer += len; - buflen -= len; - if (!fifo) - addr += len; - } - spi_unlock(sd); - return SDIOH_API_RC_SUCCESS; -} - -static int -sdspi_abort(sdioh_info_t *sd, uint func) -{ - uint8 spi_databuf[] = { 0x74, 0x80, 0x00, 0x0C, 0xFF, 0x95, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - uint8 spi_rspbuf[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - int err = 0; - - sd_err(("Sending SPI Abort to F%d\n", func)); - spi_databuf[4] = func & 0x7; - /* write to function 0, addr 6 (IOABORT) func # in 3 LSBs. */ - spi_sendrecv(sd, spi_databuf, spi_rspbuf, sizeof(spi_databuf)); - - return err; -} - -extern int -sdioh_abort(sdioh_info_t *sd, uint fnum) -{ - int ret; - - spi_lock(sd); - ret = sdspi_abort(sd, fnum); - spi_unlock(sd); - - return ret; -} - -int -sdioh_start(sdioh_info_t *sd, int stage) -{ - return SUCCESS; -} - -int -sdioh_stop(sdioh_info_t *sd) -{ - return SUCCESS; -} - - -/* - * Private/Static work routines - */ -static bool -sdspi_reset(sdioh_info_t *sd, bool host_reset, bool client_reset) -{ - if (!sd) - return TRUE; - - spi_lock(sd); - /* Reset client card */ - if (client_reset && (sd->adapter_slot != -1)) { - if (sdspi_card_regwrite(sd, 0, SDIOD_CCCR_IOABORT, 1, 0x8) != SUCCESS) - sd_err(("%s: Cannot write to card reg 0x%x\n", - __FUNCTION__, SDIOD_CCCR_IOABORT)); - else - sd->card_rca = 0; - } - - /* The host reset is a NOP in the sd-spi case. */ - if (host_reset) { - sd->sd_mode = SDIOH_MODE_SPI; - } - spi_unlock(sd); - return TRUE; -} - -static int -sdspi_host_init(sdioh_info_t *sd) -{ - sdspi_reset(sd, 1, 0); - - /* Default power on mode is SD1 */ - sd->sd_mode = SDIOH_MODE_SPI; - sd->polled_mode = TRUE; - sd->host_init_done = TRUE; - sd->card_init_done = FALSE; - sd->adapter_slot = 1; - - return (SUCCESS); -} - -#define CMD0_RETRIES 3 -#define CMD5_RETRIES 10 - -static int -get_ocr(sdioh_info_t *sd, uint32 *cmd_arg, uint32 *cmd_rsp) -{ - uint32 rsp5; - int retries, status; - - /* First issue a CMD0 to get the card into SPI mode. */ - for (retries = 0; retries <= CMD0_RETRIES; retries++) { - if ((status = sdspi_cmd_issue(sd, sd->sd_use_dma, - SDIOH_CMD_0, *cmd_arg, NULL, 0)) != SUCCESS) { - sd_err(("%s: No response to CMD0\n", __FUNCTION__)); - continue; - } - - sdspi_cmd_getrsp(sd, &rsp5, 1); - - if (GFIELD(rsp5, SPI_RSP_ILL_CMD)) { - printf("%s: Card already initialized (continuing)\n", __FUNCTION__); - break; - } - - if (GFIELD(rsp5, SPI_RSP_IDLE)) { - printf("%s: Card in SPI mode\n", __FUNCTION__); - break; - } - } - - if (retries > CMD0_RETRIES) { - sd_err(("%s: Too many retries for CMD0\n", __FUNCTION__)); - return ERROR; - } - - /* Get the Card's Operation Condition. */ - /* Occasionally the board takes a while to become ready. */ - for (retries = 0; retries <= CMD5_RETRIES; retries++) { - if ((status = sdspi_cmd_issue(sd, sd->sd_use_dma, - SDIOH_CMD_5, *cmd_arg, NULL, 0)) != SUCCESS) { - sd_err(("%s: No response to CMD5\n", __FUNCTION__)); - continue; - } - - printf("CMD5 response data was: 0x%08x\n", sd->card_rsp_data); - - if (GFIELD(sd->card_rsp_data, RSP4_CARD_READY)) { - printf("%s: Card ready\n", __FUNCTION__); - break; - } - } - - if (retries > CMD5_RETRIES) { - sd_err(("%s: Too many retries for CMD5\n", __FUNCTION__)); - return ERROR; - } - - *cmd_rsp = sd->card_rsp_data; - - sdspi_crc_onoff(sd, sd_crc ? 1 : 0); - - return (SUCCESS); -} - -static int -sdspi_crc_onoff(sdioh_info_t *sd, bool use_crc) -{ - uint32 args; - int status; - - args = use_crc ? 1 : 0; - if ((status = sdspi_cmd_issue(sd, sd->sd_use_dma, - SDIOH_CMD_59, args, NULL, 0)) != SUCCESS) { - sd_err(("%s: No response to CMD59\n", __FUNCTION__)); - } - - sd_info(("CMD59 response data was: 0x%08x\n", sd->card_rsp_data)); - - sd_err(("SD-SPI CRC turned %s\n", use_crc ? "ON" : "OFF")); - return (SUCCESS); -} - -static int -sdspi_client_init(sdioh_info_t *sd) -{ - uint8 fn_ints; - - sd_trace(("%s: Powering up slot %d\n", __FUNCTION__, sd->adapter_slot)); - - /* Start at ~400KHz clock rate for initialization */ - if (!spi_start_clock(sd, 128)) { - sd_err(("spi_start_clock failed\n")); - return ERROR; - } - - if (!sdspi_start_power(sd)) { - sd_err(("sdspi_start_power failed\n")); - return ERROR; - } - - if (sd->num_funcs == 0) { - sd_err(("%s: No IO funcs!\n", __FUNCTION__)); - return ERROR; - } - - sdspi_card_enablefuncs(sd); - - set_client_block_size(sd, 1, BLOCK_SIZE_4318); - fn_ints = INTR_CTL_FUNC1_EN; - - if (sd->num_funcs >= 2) { - set_client_block_size(sd, 2, sd_f2_blocksize /* BLOCK_SIZE_4328 */); - fn_ints |= INTR_CTL_FUNC2_EN; - } - - /* Enable/Disable Client interrupts */ - /* Turn on here but disable at host controller */ - if (sdspi_card_regwrite(sd, 0, SDIOD_CCCR_INTEN, 1, - (fn_ints | INTR_CTL_MASTER_EN)) != SUCCESS) { - sd_err(("%s: Could not enable ints in CCCR\n", __FUNCTION__)); - return ERROR; - } - - /* Switch to High-speed clocking mode if both host and device support it */ - sdspi_set_highspeed_mode(sd, (bool)sd_hiok); - - /* After configuring for High-Speed mode, set the desired clock rate. */ - if (!spi_start_clock(sd, (uint16)sd_divisor)) { - sd_err(("spi_start_clock failed\n")); - return ERROR; - } - - sd->card_init_done = TRUE; - - return SUCCESS; -} - -static int -sdspi_set_highspeed_mode(sdioh_info_t *sd, bool HSMode) -{ - uint32 regdata; - int status; - bool hsmode; - - if (HSMode == TRUE) { - - sd_err(("Attempting to enable High-Speed mode.\n")); - - if ((status = sdspi_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL, - 1, ®data)) != SUCCESS) { - return status; - } - if (regdata & SDIO_SPEED_SHS) { - sd_err(("Device supports High-Speed mode.\n")); - - regdata |= SDIO_SPEED_EHS; - - sd_err(("Writing %08x to Card at %08x\n", - regdata, SDIOD_CCCR_SPEED_CONTROL)); - if ((status = sdspi_card_regwrite(sd, 0, SDIOD_CCCR_SPEED_CONTROL, - 1, regdata)) != BCME_OK) { - return status; - } - - hsmode = 1; - - sd_err(("High-speed clocking mode enabled.\n")); - } - else { - sd_err(("Device does not support High-Speed Mode.\n")); - hsmode = 0; - } - } else { - if ((status = sdspi_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL, - 1, ®data)) != SUCCESS) { - return status; - } - - regdata = ~SDIO_SPEED_EHS; - - sd_err(("Writing %08x to Card at %08x\n", - regdata, SDIOD_CCCR_SPEED_CONTROL)); - if ((status = sdspi_card_regwrite(sd, 0, SDIOD_CCCR_SPEED_CONTROL, - 1, regdata)) != BCME_OK) { - return status; - } - - sd_err(("Low-speed clocking mode enabled.\n")); - hsmode = 0; - } - - spi_controller_highspeed_mode(sd, hsmode); - - return TRUE; -} - -bool -sdspi_start_power(sdioh_info_t *sd) -{ - uint32 cmd_arg; - uint32 cmd_rsp; - - sd_trace(("%s\n", __FUNCTION__)); - - /* Get the Card's Operation Condition. Occasionally the board - * takes a while to become ready - */ - - cmd_arg = 0; - if (get_ocr(sd, &cmd_arg, &cmd_rsp) != SUCCESS) { - sd_err(("%s: Failed to get OCR; bailing\n", __FUNCTION__)); - return FALSE; - } - - sd_err(("mem_present = %d\n", GFIELD(cmd_rsp, RSP4_MEM_PRESENT))); - sd_err(("num_funcs = %d\n", GFIELD(cmd_rsp, RSP4_NUM_FUNCS))); - sd_err(("card_ready = %d\n", GFIELD(cmd_rsp, RSP4_CARD_READY))); - sd_err(("OCR = 0x%x\n", GFIELD(cmd_rsp, RSP4_IO_OCR))); - - /* Verify that the card supports I/O mode */ - if (GFIELD(cmd_rsp, RSP4_NUM_FUNCS) == 0) { - sd_err(("%s: Card does not support I/O\n", __FUNCTION__)); - return ERROR; - } - - sd->num_funcs = GFIELD(cmd_rsp, RSP4_NUM_FUNCS); - - /* Examine voltage: Arasan only supports 3.3 volts, - * so look for 3.2-3.3 Volts and also 3.3-3.4 volts. - */ - - if ((GFIELD(cmd_rsp, RSP4_IO_OCR) & (0x3 << 20)) == 0) { - sd_err(("This client does not support 3.3 volts!\n")); - return ERROR; - } - - - return TRUE; -} - -static int -sdspi_driver_init(sdioh_info_t *sd) -{ - sd_trace(("%s\n", __FUNCTION__)); - - if ((sdspi_host_init(sd)) != SUCCESS) { - return ERROR; - } - - if (sdspi_client_init(sd) != SUCCESS) { - return ERROR; - } - - return SUCCESS; -} - -static int -sdspi_card_enablefuncs(sdioh_info_t *sd) -{ - int status; - uint32 regdata; - uint32 regaddr, fbraddr; - uint8 func; - uint8 *ptr; - - sd_trace(("%s\n", __FUNCTION__)); - /* Get the Card's common CIS address */ - ptr = (uint8 *) &sd->com_cis_ptr; - for (regaddr = SDIOD_CCCR_CISPTR_0; regaddr <= SDIOD_CCCR_CISPTR_2; regaddr++) { - if ((status = sdspi_card_regread (sd, 0, regaddr, 1, ®data)) != SUCCESS) - return status; - - *ptr++ = (uint8) regdata; - } - - /* Only the lower 17-bits are valid */ - sd->com_cis_ptr &= 0x0001FFFF; - sd->func_cis_ptr[0] = sd->com_cis_ptr; - sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __FUNCTION__, sd->com_cis_ptr)); - - /* Get the Card's function CIS (for each function) */ - for (fbraddr = SDIOD_FBR_STARTADDR, func = 1; - func <= sd->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) { - ptr = (uint8 *) &sd->func_cis_ptr[func]; - for (regaddr = SDIOD_FBR_CISPTR_0; regaddr <= SDIOD_FBR_CISPTR_2; regaddr++) { - if ((status = sdspi_card_regread (sd, 0, regaddr + fbraddr, 1, ®data)) - != SUCCESS) - return status; - - *ptr++ = (uint8) regdata; - } - - /* Only the lower 17-bits are valid */ - sd->func_cis_ptr[func] &= 0x0001FFFF; - sd_info(("%s: Function %d CIS Ptr = 0x%x\n", - __FUNCTION__, func, sd->func_cis_ptr[func])); - } - - sd_info(("%s: write ESCI bit\n", __FUNCTION__)); - /* Enable continuous SPI interrupt (ESCI bit) */ - sdspi_card_regwrite(sd, 0, SDIOD_CCCR_BICTRL, 1, 0x60); - - sd_info(("%s: enable f1\n", __FUNCTION__)); - /* Enable function 1 on the card */ - regdata = SDIO_FUNC_ENABLE_1; - if ((status = sdspi_card_regwrite(sd, 0, SDIOD_CCCR_IOEN, 1, regdata)) != SUCCESS) - return status; - - sd_info(("%s: done\n", __FUNCTION__)); - return SUCCESS; -} - -/* Read client card reg */ -static int -sdspi_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data) -{ - int status; - uint32 cmd_arg; - uint32 rsp5; - - cmd_arg = 0; - - if ((func == 0) || (regsize == 1)) { - cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, SDIOH_XFER_TYPE_READ); - cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0); - cmd_arg = SFIELD(cmd_arg, CMD52_DATA, 0); - - if ((status = sdspi_cmd_issue(sd, sd->sd_use_dma, SDIOH_CMD_52, cmd_arg, NULL, 0)) - != SUCCESS) - return status; - - sdspi_cmd_getrsp(sd, &rsp5, 1); - - if (rsp5 != 0x00) - sd_err(("%s: rsp5 flags is 0x%x\t %d\n", - __FUNCTION__, rsp5, func)); - - *data = sd->card_rsp_data >> 24; - } else { - cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, regsize); - cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 1); - cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 0); - cmd_arg = SFIELD(cmd_arg, CMD53_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD53_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_READ); - - sd->data_xfer_count = regsize; - - /* sdspi_cmd_issue() returns with the command complete bit - * in the ISR already cleared - */ - if ((status = sdspi_cmd_issue(sd, sd->sd_use_dma, SDIOH_CMD_53, cmd_arg, NULL, 0)) - != SUCCESS) - return status; - - sdspi_cmd_getrsp(sd, &rsp5, 1); - - if (rsp5 != 0x00) - sd_err(("%s: rsp5 flags is 0x%x\t %d\n", - __FUNCTION__, rsp5, func)); - - *data = sd->card_rsp_data; - if (regsize == 2) { - *data &= 0xffff; - } - - sd_info(("%s: CMD53 func %d, addr 0x%x, size %d, data 0x%08x\n", - __FUNCTION__, func, regaddr, regsize, *data)); - - - } - - return SUCCESS; -} - -/* write a client register */ -static int -sdspi_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 data) -{ - int status; - uint32 cmd_arg, rsp5, flags; - - cmd_arg = 0; - - if ((func == 0) || (regsize == 1)) { - cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, SDIOH_XFER_TYPE_WRITE); - cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0); - cmd_arg = SFIELD(cmd_arg, CMD52_DATA, data & 0xff); - if ((status = sdspi_cmd_issue(sd, sd->sd_use_dma, SDIOH_CMD_52, cmd_arg, NULL, 0)) - != SUCCESS) - return status; - - sdspi_cmd_getrsp(sd, &rsp5, 1); - flags = GFIELD(rsp5, RSP5_FLAGS); - if (flags && (flags != 0x10)) - sd_err(("%s: rsp5.rsp5.flags = 0x%x, expecting 0x10\n", - __FUNCTION__, flags)); - } - else { - cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, regsize); - cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 1); - cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 0); - cmd_arg = SFIELD(cmd_arg, CMD53_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD53_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_WRITE); - - sd->data_xfer_count = regsize; - sd->cmd53_wr_data = data; - - sd_info(("%s: CMD53 func %d, addr 0x%x, size %d, data 0x%08x\n", - __FUNCTION__, func, regaddr, regsize, data)); - - /* sdspi_cmd_issue() returns with the command complete bit - * in the ISR already cleared - */ - if ((status = sdspi_cmd_issue(sd, sd->sd_use_dma, SDIOH_CMD_53, cmd_arg, NULL, 0)) - != SUCCESS) - return status; - - sdspi_cmd_getrsp(sd, &rsp5, 1); - - if (rsp5 != 0x00) - sd_err(("%s: rsp5 flags = 0x%x, expecting 0x00\n", - __FUNCTION__, rsp5)); - - } - return SUCCESS; -} - -void -sdspi_cmd_getrsp(sdioh_info_t *sd, uint32 *rsp_buffer, int count /* num 32 bit words */) -{ - *rsp_buffer = sd->card_response; -} - -int max_errors = 0; - -#define SPI_MAX_PKT_LEN 768 -uint8 spi_databuf[SPI_MAX_PKT_LEN]; -uint8 spi_rspbuf[SPI_MAX_PKT_LEN]; - -/* datalen is used for CMD53 length only (0 for sd->data_xfer_count) */ -static int -sdspi_cmd_issue(sdioh_info_t *sd, bool use_dma, uint32 cmd, uint32 arg, - uint32 *data, uint32 datalen) -{ - uint32 cmd_reg; - uint32 cmd_arg = arg; - uint8 cmd_crc = 0x95; /* correct CRC for CMD0 and don't care for others. */ - uint16 dat_crc; - uint8 cmd52data = 0; - uint32 i, j; - uint32 spi_datalen = 0; - uint32 spi_pre_cmd_pad = 0; - uint32 spi_max_response_pad = 128; - - cmd_reg = 0; - cmd_reg = SFIELD(cmd_reg, SPI_DIR, 1); - cmd_reg = SFIELD(cmd_reg, SPI_CMD_INDEX, cmd); - - if (GFIELD(cmd_arg, CMD52_RW_FLAG) == 1) { /* Same for CMD52 and CMD53 */ - cmd_reg = SFIELD(cmd_reg, SPI_RW, 1); - } - - switch (cmd) { - case SDIOH_CMD_59: /* CRC_ON_OFF (SPI Mode Only) - Response R1 */ - cmd52data = arg & 0x1; - case SDIOH_CMD_0: /* Set Card to Idle State - No Response */ - case SDIOH_CMD_5: /* Send Operation condition - Response R4 */ - sd_trace(("%s: CMD%d\n", __FUNCTION__, cmd)); - spi_datalen = 44; - spi_pre_cmd_pad = 12; - spi_max_response_pad = 28; - break; - - case SDIOH_CMD_3: /* Ask card to send RCA - Response R6 */ - case SDIOH_CMD_7: /* Select card - Response R1 */ - case SDIOH_CMD_15: /* Set card to inactive state - Response None */ - sd_err(("%s: CMD%d is invalid for SPI Mode.\n", __FUNCTION__, cmd)); - return ERROR; - break; - - case SDIOH_CMD_52: /* IO R/W Direct (single byte) - Response R5 */ - cmd52data = GFIELD(cmd_arg, CMD52_DATA); - cmd_arg = arg; - cmd_reg = SFIELD(cmd_reg, SPI_FUNC, GFIELD(cmd_arg, CMD52_FUNCTION)); - cmd_reg = SFIELD(cmd_reg, SPI_ADDR, GFIELD(cmd_arg, CMD52_REG_ADDR)); - /* Display trace for byte write */ - if (GFIELD(cmd_arg, CMD52_RW_FLAG) == 1) { - sd_trace(("%s: CMD52: Wr F:%d @0x%04x=%02x\n", - __FUNCTION__, - GFIELD(cmd_arg, CMD52_FUNCTION), - GFIELD(cmd_arg, CMD52_REG_ADDR), - cmd52data)); - } - - spi_datalen = 32; - spi_max_response_pad = 28; - - break; - case SDIOH_CMD_53: /* IO R/W Extended (multiple bytes/blocks) */ - cmd_arg = arg; - cmd_reg = SFIELD(cmd_reg, SPI_FUNC, GFIELD(cmd_arg, CMD53_FUNCTION)); - cmd_reg = SFIELD(cmd_reg, SPI_ADDR, GFIELD(cmd_arg, CMD53_REG_ADDR)); - cmd_reg = SFIELD(cmd_reg, SPI_BLKMODE, 0); - cmd_reg = SFIELD(cmd_reg, SPI_OPCODE, GFIELD(cmd_arg, CMD53_OP_CODE)); - cmd_reg = SFIELD(cmd_reg, SPI_STUFF0, (sd->data_xfer_count>>8)); - cmd52data = (uint8)sd->data_xfer_count; - - /* Set upper bit in byte count if necessary, but don't set it for 512 bytes. */ - if ((sd->data_xfer_count > 255) && (sd->data_xfer_count < 512)) { - cmd_reg |= 1; - } - - if (GFIELD(cmd_reg, SPI_RW) == 1) { /* Write */ - spi_max_response_pad = 32; - spi_datalen = (sd->data_xfer_count + spi_max_response_pad) & 0xFFFC; - } else { /* Read */ - - spi_max_response_pad = 32; - spi_datalen = (sd->data_xfer_count + spi_max_response_pad) & 0xFFFC; - } - sd_trace(("%s: CMD53: %s F:%d @0x%04x len=0x%02x\n", - __FUNCTION__, - (GFIELD(cmd_reg, SPI_RW) == 1 ? "Wr" : "Rd"), - GFIELD(cmd_arg, CMD53_FUNCTION), - GFIELD(cmd_arg, CMD53_REG_ADDR), - cmd52data)); - break; - - default: - sd_err(("%s: Unknown command %d\n", __FUNCTION__, cmd)); - return ERROR; - } - - /* Set up and issue the SDIO command */ - memset(spi_databuf, SDSPI_IDLE_PAD, spi_datalen); - spi_databuf[spi_pre_cmd_pad + 0] = (cmd_reg & 0xFF000000) >> 24; - spi_databuf[spi_pre_cmd_pad + 1] = (cmd_reg & 0x00FF0000) >> 16; - spi_databuf[spi_pre_cmd_pad + 2] = (cmd_reg & 0x0000FF00) >> 8; - spi_databuf[spi_pre_cmd_pad + 3] = (cmd_reg & 0x000000FF); - spi_databuf[spi_pre_cmd_pad + 4] = cmd52data; - - /* Generate CRC7 for command, if CRC is enabled, otherwise, a - * default CRC7 of 0x95, which is correct for CMD0, is used. - */ - if (sd_crc) { - cmd_crc = sdspi_crc7(&spi_databuf[spi_pre_cmd_pad], 5); - } - spi_databuf[spi_pre_cmd_pad + 5] = cmd_crc; -#define SPI_STOP_TRAN 0xFD - - /* for CMD53 Write, put the data into the output buffer */ - if ((cmd == SDIOH_CMD_53) && (GFIELD(cmd_arg, CMD53_RW_FLAG) == 1)) { - if (datalen != 0) { - spi_databuf[spi_pre_cmd_pad + 9] = SDSPI_IDLE_PAD; - spi_databuf[spi_pre_cmd_pad + 10] = SDSPI_START_BLOCK; - - for (i = 0; i < sd->data_xfer_count; i++) { - spi_databuf[i + 11 + spi_pre_cmd_pad] = ((uint8 *)data)[i]; - } - if (sd_crc) { - dat_crc = sdspi_crc16(&spi_databuf[spi_pre_cmd_pad+11], i); - } else { - dat_crc = 0xAAAA; - } - spi_databuf[i + 11 + spi_pre_cmd_pad] = (dat_crc >> 8) & 0xFF; - spi_databuf[i + 12 + spi_pre_cmd_pad] = dat_crc & 0xFF; - } else if (sd->data_xfer_count == 2) { - spi_databuf[spi_pre_cmd_pad + 9] = SDSPI_IDLE_PAD; - spi_databuf[spi_pre_cmd_pad + 10] = SDSPI_START_BLOCK; - spi_databuf[spi_pre_cmd_pad + 11] = sd->cmd53_wr_data & 0xFF; - spi_databuf[spi_pre_cmd_pad + 12] = (sd->cmd53_wr_data & 0x0000FF00) >> 8; - if (sd_crc) { - dat_crc = sdspi_crc16(&spi_databuf[spi_pre_cmd_pad+11], 2); - } else { - dat_crc = 0x22AA; - } - spi_databuf[spi_pre_cmd_pad + 13] = (dat_crc >> 8) & 0xFF; - spi_databuf[spi_pre_cmd_pad + 14] = (dat_crc & 0xFF); - } else if (sd->data_xfer_count == 4) { - spi_databuf[spi_pre_cmd_pad + 9] = SDSPI_IDLE_PAD; - spi_databuf[spi_pre_cmd_pad + 10] = SDSPI_START_BLOCK; - spi_databuf[spi_pre_cmd_pad + 11] = sd->cmd53_wr_data & 0xFF; - spi_databuf[spi_pre_cmd_pad + 12] = (sd->cmd53_wr_data & 0x0000FF00) >> 8; - spi_databuf[spi_pre_cmd_pad + 13] = (sd->cmd53_wr_data & 0x00FF0000) >> 16; - spi_databuf[spi_pre_cmd_pad + 14] = (sd->cmd53_wr_data & 0xFF000000) >> 24; - if (sd_crc) { - dat_crc = sdspi_crc16(&spi_databuf[spi_pre_cmd_pad+11], 4); - } else { - dat_crc = 0x44AA; - } - spi_databuf[spi_pre_cmd_pad + 15] = (dat_crc >> 8) & 0xFF; - spi_databuf[spi_pre_cmd_pad + 16] = (dat_crc & 0xFF); - } else { - printf("CMD53 Write: size %d unsupported\n", sd->data_xfer_count); - } - } - - spi_sendrecv(sd, spi_databuf, spi_rspbuf, spi_datalen); - - for (i = spi_pre_cmd_pad + SDSPI_COMMAND_LEN; i < spi_max_response_pad; i++) { - if ((spi_rspbuf[i] & SDSPI_START_BIT_MASK) == 0) { - break; - } - } - - if (i == spi_max_response_pad) { - sd_err(("%s: Did not get a response for CMD%d\n", __FUNCTION__, cmd)); - return ERROR; - } - - /* Extract the response. */ - sd->card_response = spi_rspbuf[i]; - - /* for CMD53 Read, find the start of the response data... */ - if ((cmd == SDIOH_CMD_53) && (GFIELD(cmd_arg, CMD52_RW_FLAG) == 0)) { - for (; i < spi_max_response_pad; i++) { - if (spi_rspbuf[i] == SDSPI_START_BLOCK) { - break; - } - } - - if (i == spi_max_response_pad) { - printf("Did not get a start of data phase for CMD%d\n", cmd); - max_errors++; - sdspi_abort(sd, GFIELD(cmd_arg, CMD53_FUNCTION)); - } - sd->card_rsp_data = spi_rspbuf[i+1]; - sd->card_rsp_data |= spi_rspbuf[i+2] << 8; - sd->card_rsp_data |= spi_rspbuf[i+3] << 16; - sd->card_rsp_data |= spi_rspbuf[i+4] << 24; - - if (datalen != 0) { - i++; - for (j = 0; j < sd->data_xfer_count; j++) { - ((uint8 *)data)[j] = spi_rspbuf[i+j]; - } - if (sd_crc) { - uint16 recv_crc; - - recv_crc = spi_rspbuf[i+j] << 8 | spi_rspbuf[i+j+1]; - dat_crc = sdspi_crc16((uint8 *)data, datalen); - if (dat_crc != recv_crc) { - sd_err(("%s: Incorrect data CRC: expected 0x%04x, " - "received 0x%04x\n", - __FUNCTION__, dat_crc, recv_crc)); - } - } - } - return SUCCESS; - } - - sd->card_rsp_data = spi_rspbuf[i+4]; - sd->card_rsp_data |= spi_rspbuf[i+3] << 8; - sd->card_rsp_data |= spi_rspbuf[i+2] << 16; - sd->card_rsp_data |= spi_rspbuf[i+1] << 24; - - /* Display trace for byte read */ - if ((cmd == SDIOH_CMD_52) && (GFIELD(cmd_arg, CMD52_RW_FLAG) == 0)) { - sd_trace(("%s: CMD52: Rd F:%d @0x%04x=%02x\n", - __FUNCTION__, - GFIELD(cmd_arg, CMD53_FUNCTION), - GFIELD(cmd_arg, CMD53_REG_ADDR), - sd->card_rsp_data >> 24)); - } - - return SUCCESS; -} - -/* - * On entry: if single-block or non-block, buffer size <= block size. - * If multi-block, buffer size is unlimited. - * Question is how to handle the left-overs in either single- or multi-block. - * I think the caller should break the buffer up so this routine will always - * use block size == buffer size to handle the end piece of the buffer - */ - -static int -sdspi_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo, uint32 addr, int nbytes, uint32 *data) -{ - int status; - uint32 cmd_arg; - uint32 rsp5; - int num_blocks, blocksize; - bool local_blockmode, local_dma; - bool read = rw == SDIOH_READ ? 1 : 0; - - ASSERT(nbytes); - - cmd_arg = 0; - sd_data(("%s: %s 53 func %d, %s, addr 0x%x, len %d bytes, r_cnt %d t_cnt %d\n", - __FUNCTION__, read ? "Rd" : "Wr", func, fifo ? "FIXED" : "INCR", - addr, nbytes, sd->r_cnt, sd->t_cnt)); - - if (read) sd->r_cnt++; else sd->t_cnt++; - - local_blockmode = sd->sd_blockmode; - local_dma = sd->sd_use_dma; - - /* Don't bother with block mode on small xfers */ - if (nbytes < sd->client_block_size[func]) { - sd_info(("setting local blockmode to false: nbytes (%d) != block_size (%d)\n", - nbytes, sd->client_block_size[func])); - local_blockmode = FALSE; - local_dma = FALSE; - } - - if (local_blockmode) { - blocksize = MIN(sd->client_block_size[func], nbytes); - num_blocks = nbytes/blocksize; - cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, num_blocks); - cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 1); - } else { - num_blocks = 1; - blocksize = nbytes; - cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, nbytes); - cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 0); - } - - if (fifo) - cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 0); - else - cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 1); - - cmd_arg = SFIELD(cmd_arg, CMD53_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD53_REG_ADDR, addr); - if (read) - cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_READ); - else - cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_WRITE); - - sd->data_xfer_count = nbytes; - if ((func == 2) && (fifo == 1)) { - sd_data(("%s: %s 53 func %d, %s, addr 0x%x, len %d bytes, r_cnt %d t_cnt %d\n", - __FUNCTION__, read ? "Rd" : "Wr", func, fifo ? "FIXED" : "INCR", - addr, nbytes, sd->r_cnt, sd->t_cnt)); - } - - /* sdspi_cmd_issue() returns with the command complete bit - * in the ISR already cleared - */ - if ((status = sdspi_cmd_issue(sd, local_dma, - SDIOH_CMD_53, cmd_arg, - data, nbytes)) != SUCCESS) { - sd_err(("%s: cmd_issue failed for %s\n", __FUNCTION__, (read ? "read" : "write"))); - return status; - } - - sdspi_cmd_getrsp(sd, &rsp5, 1); - - if (rsp5 != 0x00) { - sd_err(("%s: rsp5 flags = 0x%x, expecting 0x00\n", - __FUNCTION__, rsp5)); - return ERROR; - } - - return SUCCESS; -} - -static int -set_client_block_size(sdioh_info_t *sd, int func, int block_size) -{ - int base; - int err = 0; - - sd_err(("%s: Setting block size %d, func %d\n", __FUNCTION__, block_size, func)); - sd->client_block_size[func] = block_size; - - /* Set the block size in the SDIO Card register */ - base = func * SDIOD_FBR_SIZE; - err = sdspi_card_regwrite(sd, 0, base + SDIOD_CCCR_BLKSIZE_0, 1, block_size & 0xff); - if (!err) { - err = sdspi_card_regwrite(sd, 0, base + SDIOD_CCCR_BLKSIZE_1, 1, - (block_size >> 8) & 0xff); - } - - /* - * Do not set the block size in the SDIO Host register; that - * is func dependent and will get done on an individual - * transaction basis. - */ - - return (err ? BCME_SDIO_ERROR : 0); -} - -/* Reset and re-initialize the device */ -int -sdioh_sdio_reset(sdioh_info_t *si) -{ - si->card_init_done = FALSE; - return sdspi_client_init(si); -} - -#define CRC7_POLYNOM 0x09 -#define CRC7_CRCHIGHBIT 0x40 - -static uint8 sdspi_crc7(unsigned char* p, uint32 len) -{ - uint8 c, j, bit, crc = 0; - uint32 i; - - for (i = 0; i < len; i++) { - c = *p++; - for (j = 0x80; j; j >>= 1) { - bit = crc & CRC7_CRCHIGHBIT; - crc <<= 1; - if (c & j) bit ^= CRC7_CRCHIGHBIT; - if (bit) crc ^= CRC7_POLYNOM; - } - } - - /* Convert the CRC7 to an 8-bit SD CRC */ - crc = (crc << 1) | 1; - - return (crc); -} - -#define CRC16_POLYNOM 0x1021 -#define CRC16_CRCHIGHBIT 0x8000 - -static uint16 sdspi_crc16(unsigned char* p, uint32 len) -{ - uint32 i; - uint16 j, c, bit; - uint16 crc = 0; - - for (i = 0; i < len; i++) { - c = *p++; - for (j = 0x80; j; j >>= 1) { - bit = crc & CRC16_CRCHIGHBIT; - crc <<= 1; - if (c & j) bit ^= CRC16_CRCHIGHBIT; - if (bit) crc ^= CRC16_POLYNOM; - } - } - - return (crc); -} diff --git a/drivers/net/wireless/bcm4329/bcmsdspi_linux.c b/drivers/net/wireless/bcm4329/bcmsdspi_linux.c deleted file mode 100644 index e2e0ca6abe46..000000000000 --- a/drivers/net/wireless/bcm4329/bcmsdspi_linux.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Broadcom SPI Host Controller Driver - Linux Per-port - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdspi_linux.c,v 1.7.2.1.4.3 2008/06/30 21:09:36 Exp $ - */ - -#include -#include -#include - -#include /* SDIO Specs */ -#include /* bcmsdh to/from specific controller APIs */ -#include /* to get msglevel bit values */ - -#include /* request_irq(), free_irq() */ - -#include -#include - -extern uint sd_crc; -module_param(sd_crc, uint, 0); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define KERNEL26 -#endif - -struct sdos_info { - sdioh_info_t *sd; - spinlock_t lock; - wait_queue_head_t intr_wait_queue; -}; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define BLOCKABLE() (!in_atomic()) -#else -#define BLOCKABLE() (!in_interrupt()) -#endif - -/* Interrupt handler */ -static irqreturn_t -sdspi_isr(int irq, void *dev_id -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) -, struct pt_regs *ptregs -#endif -) -{ - sdioh_info_t *sd; - struct sdos_info *sdos; - bool ours; - - sd = (sdioh_info_t *)dev_id; - sd->local_intrcount++; - - if (!sd->card_init_done) { - sd_err(("%s: Hey Bogus intr...not even initted: irq %d\n", __FUNCTION__, irq)); - return IRQ_RETVAL(FALSE); - } else { - ours = spi_check_client_intr(sd, NULL); - - /* For local interrupts, wake the waiting process */ - if (ours && sd->got_hcint) { - sdos = (struct sdos_info *)sd->sdos_info; - wake_up_interruptible(&sdos->intr_wait_queue); - } - - return IRQ_RETVAL(ours); - } -} - -/* Register with Linux for interrupts */ -int -spi_register_irq(sdioh_info_t *sd, uint irq) -{ - sd_trace(("Entering %s: irq == %d\n", __FUNCTION__, irq)); - if (request_irq(irq, sdspi_isr, IRQF_SHARED, "bcmsdspi", sd) < 0) { - sd_err(("%s: request_irq() failed\n", __FUNCTION__)); - return ERROR; - } - return SUCCESS; -} - -/* Free Linux irq */ -void -spi_free_irq(uint irq, sdioh_info_t *sd) -{ - free_irq(irq, sd); -} - -/* Map Host controller registers */ - -uint32 * -spi_reg_map(osl_t *osh, uintptr addr, int size) -{ - return (uint32 *)REG_MAP(addr, size); -} - -void -spi_reg_unmap(osl_t *osh, uintptr addr, int size) -{ - REG_UNMAP((void*)(uintptr)addr); -} - -int -spi_osinit(sdioh_info_t *sd) -{ - struct sdos_info *sdos; - - sdos = (struct sdos_info*)MALLOC(sd->osh, sizeof(struct sdos_info)); - sd->sdos_info = (void*)sdos; - if (sdos == NULL) - return BCME_NOMEM; - - sdos->sd = sd; - spin_lock_init(&sdos->lock); - init_waitqueue_head(&sdos->intr_wait_queue); - return BCME_OK; -} - -void -spi_osfree(sdioh_info_t *sd) -{ - struct sdos_info *sdos; - ASSERT(sd && sd->sdos_info); - - sdos = (struct sdos_info *)sd->sdos_info; - MFREE(sd->osh, sdos, sizeof(struct sdos_info)); -} - -/* Interrupt enable/disable */ -SDIOH_API_RC -sdioh_interrupt_set(sdioh_info_t *sd, bool enable) -{ - ulong flags; - struct sdos_info *sdos; - - sd_trace(("%s: %s\n", __FUNCTION__, enable ? "Enabling" : "Disabling")); - - sdos = (struct sdos_info *)sd->sdos_info; - ASSERT(sdos); - - if (!(sd->host_init_done && sd->card_init_done)) { - sd_err(("%s: Card & Host are not initted - bailing\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } - - if (enable && !(sd->intr_handler && sd->intr_handler_arg)) { - sd_err(("%s: no handler registered, will not enable\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } - - /* Ensure atomicity for enable/disable calls */ - spin_lock_irqsave(&sdos->lock, flags); - - sd->client_intr_enabled = enable; - if (enable && !sd->lockcount) - spi_devintr_on(sd); - else - spi_devintr_off(sd); - - spin_unlock_irqrestore(&sdos->lock, flags); - - return SDIOH_API_RC_SUCCESS; -} - -/* Protect against reentrancy (disable device interrupts while executing) */ -void -spi_lock(sdioh_info_t *sd) -{ - ulong flags; - struct sdos_info *sdos; - - sdos = (struct sdos_info *)sd->sdos_info; - ASSERT(sdos); - - sd_trace(("%s: %d\n", __FUNCTION__, sd->lockcount)); - - spin_lock_irqsave(&sdos->lock, flags); - if (sd->lockcount) { - sd_err(("%s: Already locked!\n", __FUNCTION__)); - ASSERT(sd->lockcount == 0); - } - spi_devintr_off(sd); - sd->lockcount++; - spin_unlock_irqrestore(&sdos->lock, flags); -} - -/* Enable client interrupt */ -void -spi_unlock(sdioh_info_t *sd) -{ - ulong flags; - struct sdos_info *sdos; - - sd_trace(("%s: %d, %d\n", __FUNCTION__, sd->lockcount, sd->client_intr_enabled)); - ASSERT(sd->lockcount > 0); - - sdos = (struct sdos_info *)sd->sdos_info; - ASSERT(sdos); - - spin_lock_irqsave(&sdos->lock, flags); - if (--sd->lockcount == 0 && sd->client_intr_enabled) { - spi_devintr_on(sd); - } - spin_unlock_irqrestore(&sdos->lock, flags); -} - -void spi_waitbits(sdioh_info_t *sd, bool yield) -{ - struct sdos_info *sdos; - - sdos = (struct sdos_info *)sd->sdos_info; - -#ifndef BCMSDYIELD - ASSERT(!yield); -#endif - sd_trace(("%s: yield %d canblock %d\n", - __FUNCTION__, yield, BLOCKABLE())); - - /* Clear the "interrupt happened" flag and last intrstatus */ - sd->got_hcint = FALSE; - -#ifdef BCMSDYIELD - if (yield && BLOCKABLE()) { - /* Wait for the indication, the interrupt will be masked when the ISR fires. */ - wait_event_interruptible(sdos->intr_wait_queue, (sd->got_hcint)); - } else -#endif /* BCMSDYIELD */ - { - spi_spinbits(sd); - } - -} diff --git a/drivers/net/wireless/bcm4329/bcmsdstd.c b/drivers/net/wireless/bcm4329/bcmsdstd.c deleted file mode 100644 index 0ca1f8ff8a24..000000000000 --- a/drivers/net/wireless/bcm4329/bcmsdstd.c +++ /dev/null @@ -1,3127 +0,0 @@ -/* - * 'Standard' SDIO HOST CONTROLLER driver - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdstd.c,v 1.64.4.1.4.4.2.18 2010/08/17 17:00:48 Exp $ - */ - -#include - -#include -#include -#include -#include -#include -#include /* SDIO Device and Protocol Specs */ -#include /* SDIO Host Controller Specification */ -#include /* bcmsdh to/from specific controller APIs */ -#include /* ioctl/iovars */ -#include - - -#define SD_PAGE_BITS 12 -#define SD_PAGE (1 << SD_PAGE_BITS) - -#include - -/* Globals */ -uint sd_msglevel = SDH_ERROR_VAL; -uint sd_hiok = TRUE; /* Use hi-speed mode if available? */ -uint sd_sdmode = SDIOH_MODE_SD4; /* Use SD4 mode by default */ -uint sd_f2_blocksize = 64; /* Default blocksize */ - -#ifdef BCMSDYIELD -bool sd_yieldcpu = TRUE; /* Allow CPU yielding for buffer requests */ -uint sd_minyield = 0; /* Minimum xfer size to allow CPU yield */ -bool sd_forcerb = FALSE; /* Force sync readback in intrs_on/off */ -#endif - -uint sd_divisor = 2; /* Default 48MHz/2 = 24MHz */ - -uint sd_power = 1; /* Default to SD Slot powered ON */ -uint sd_clock = 1; /* Default to SD Clock turned ON */ -uint sd_pci_slot = 0xFFFFffff; /* Used to force selection of a particular PCI slot */ -uint8 sd_dma_mode = DMA_MODE_SDMA; /* Default to SDMA for now */ - -uint sd_toctl = 7; - -static bool trap_errs = FALSE; - -static const char *dma_mode_description[] = { "PIO", "SDMA", "ADMA1", "32b ADMA2", "64b ADMA2" }; - -/* Prototypes */ -static bool sdstd_start_clock(sdioh_info_t *sd, uint16 divisor); -static bool sdstd_start_power(sdioh_info_t *sd); -static bool sdstd_bus_width(sdioh_info_t *sd, int width); -static int sdstd_set_highspeed_mode(sdioh_info_t *sd, bool HSMode); -static int sdstd_set_dma_mode(sdioh_info_t *sd, int8 dma_mode); -static int sdstd_card_enablefuncs(sdioh_info_t *sd); -static void sdstd_cmd_getrsp(sdioh_info_t *sd, uint32 *rsp_buffer, int count); -static int sdstd_cmd_issue(sdioh_info_t *sd, bool use_dma, uint32 cmd, uint32 arg); -static int sdstd_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, - int regsize, uint32 *data); -static int sdstd_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, - int regsize, uint32 data); -static int sdstd_driver_init(sdioh_info_t *sd); -static bool sdstd_reset(sdioh_info_t *sd, bool host_reset, bool client_reset); -static int sdstd_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo, - uint32 addr, int nbytes, uint32 *data); -static int sdstd_abort(sdioh_info_t *sd, uint func); -static int sdstd_check_errs(sdioh_info_t *sdioh_info, uint32 cmd, uint32 arg); -static int set_client_block_size(sdioh_info_t *sd, int func, int blocksize); -static void sd_map_dma(sdioh_info_t * sd); -static void sd_unmap_dma(sdioh_info_t * sd); -static void sd_clear_adma_dscr_buf(sdioh_info_t *sd); -static void sd_fill_dma_data_buf(sdioh_info_t *sd, uint8 data); -static void sd_create_adma_descriptor(sdioh_info_t *sd, - uint32 index, uint32 addr_phys, - uint16 length, uint16 flags); -static void sd_dump_adma_dscr(sdioh_info_t *sd); -static void sdstd_dumpregs(sdioh_info_t *sd); - - -/* - * Private register access routines. - */ - -/* 16 bit PCI regs */ - -extern uint16 sdstd_rreg16(sdioh_info_t *sd, uint reg); -uint16 -sdstd_rreg16(sdioh_info_t *sd, uint reg) -{ - - volatile uint16 data = *(volatile uint16 *)(sd->mem_space + reg); - sd_ctrl(("16: R Reg 0x%02x, Data 0x%x\n", reg, data)); - return data; -} - -extern void sdstd_wreg16(sdioh_info_t *sd, uint reg, uint16 data); -void -sdstd_wreg16(sdioh_info_t *sd, uint reg, uint16 data) -{ - *(volatile uint16 *)(sd->mem_space + reg) = (uint16)data; - sd_ctrl(("16: W Reg 0x%02x, Data 0x%x\n", reg, data)); -} - -static void -sdstd_or_reg16(sdioh_info_t *sd, uint reg, uint16 val) -{ - volatile uint16 data = *(volatile uint16 *)(sd->mem_space + reg); - sd_ctrl(("16: OR Reg 0x%02x, Val 0x%x\n", reg, val)); - data |= val; - *(volatile uint16 *)(sd->mem_space + reg) = (uint16)data; - -} -static void -sdstd_mod_reg16(sdioh_info_t *sd, uint reg, int16 mask, uint16 val) -{ - - volatile uint16 data = *(volatile uint16 *)(sd->mem_space + reg); - sd_ctrl(("16: MOD Reg 0x%02x, Mask 0x%x, Val 0x%x\n", reg, mask, val)); - data &= ~mask; - data |= (val & mask); - *(volatile uint16 *)(sd->mem_space + reg) = (uint16)data; -} - - -/* 32 bit PCI regs */ -static uint32 -sdstd_rreg(sdioh_info_t *sd, uint reg) -{ - volatile uint32 data = *(volatile uint32 *)(sd->mem_space + reg); - sd_ctrl(("32: R Reg 0x%02x, Data 0x%x\n", reg, data)); - return data; -} -static inline void -sdstd_wreg(sdioh_info_t *sd, uint reg, uint32 data) -{ - *(volatile uint32 *)(sd->mem_space + reg) = (uint32)data; - sd_ctrl(("32: W Reg 0x%02x, Data 0x%x\n", reg, data)); - -} - -/* 8 bit PCI regs */ -static inline void -sdstd_wreg8(sdioh_info_t *sd, uint reg, uint8 data) -{ - *(volatile uint8 *)(sd->mem_space + reg) = (uint8)data; - sd_ctrl(("08: W Reg 0x%02x, Data 0x%x\n", reg, data)); -} -static uint8 -sdstd_rreg8(sdioh_info_t *sd, uint reg) -{ - volatile uint8 data = *(volatile uint8 *)(sd->mem_space + reg); - sd_ctrl(("08: R Reg 0x%02x, Data 0x%x\n", reg, data)); - return data; -} - -/* - * Private work routines - */ - -sdioh_info_t *glob_sd; - -/* - * Public entry points & extern's - */ -extern sdioh_info_t * -sdioh_attach(osl_t *osh, void *bar0, uint irq) -{ - sdioh_info_t *sd; - - sd_trace(("%s\n", __FUNCTION__)); - if ((sd = (sdioh_info_t *)MALLOC(osh, sizeof(sdioh_info_t))) == NULL) { - sd_err(("sdioh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh))); - return NULL; - } - bzero((char *)sd, sizeof(sdioh_info_t)); - glob_sd = sd; - sd->osh = osh; - if (sdstd_osinit(sd) != 0) { - sd_err(("%s:sdstd_osinit() failed\n", __FUNCTION__)); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return NULL; - } - sd->mem_space = (volatile char *)sdstd_reg_map(osh, (uintptr)bar0, SDIOH_REG_WINSZ); - sd_init_dma(sd); - sd->irq = irq; - if (sd->mem_space == NULL) { - sd_err(("%s:ioremap() failed\n", __FUNCTION__)); - sdstd_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return NULL; - } - sd_info(("%s:sd->mem_space = %p\n", __FUNCTION__, sd->mem_space)); - sd->intr_handler = NULL; - sd->intr_handler_arg = NULL; - sd->intr_handler_valid = FALSE; - - /* Set defaults */ - sd->sd_blockmode = TRUE; - sd->use_client_ints = TRUE; - sd->sd_dma_mode = sd_dma_mode; - - if (!sd->sd_blockmode) - sd->sd_dma_mode = DMA_MODE_NONE; - - if (sdstd_driver_init(sd) != SUCCESS) { - /* If host CPU was reset without resetting SD bus or - SD device, the device will still have its RCA but - driver no longer knows what it is (since driver has been restarted). - go through once to clear the RCA and a gain reassign it. - */ - sd_info(("driver_init failed - Reset RCA and try again\n")); - if (sdstd_driver_init(sd) != SUCCESS) { - sd_err(("%s:driver_init() failed()\n", __FUNCTION__)); - if (sd->mem_space) { - sdstd_reg_unmap(osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ); - sd->mem_space = NULL; - } - sdstd_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return (NULL); - } - } - - OSL_DMADDRWIDTH(osh, 32); - - /* Always map DMA buffers, so we can switch between DMA modes. */ - sd_map_dma(sd); - - if (sdstd_register_irq(sd, irq) != SUCCESS) { - sd_err(("%s: sdstd_register_irq() failed for irq = %d\n", __FUNCTION__, irq)); - sdstd_free_irq(sd->irq, sd); - if (sd->mem_space) { - sdstd_reg_unmap(osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ); - sd->mem_space = NULL; - } - - sdstd_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return (NULL); - } - - sd_trace(("%s: Done\n", __FUNCTION__)); - return sd; -} - -extern SDIOH_API_RC -sdioh_detach(osl_t *osh, sdioh_info_t *sd) -{ - sd_trace(("%s\n", __FUNCTION__)); - if (sd) { - sd_unmap_dma(sd); - sdstd_wreg16(sd, SD_IntrSignalEnable, 0); - sd_trace(("%s: freeing irq %d\n", __FUNCTION__, sd->irq)); - sdstd_free_irq(sd->irq, sd); - if (sd->card_init_done) - sdstd_reset(sd, 1, 1); - if (sd->mem_space) { - sdstd_reg_unmap(osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ); - sd->mem_space = NULL; - } - - sdstd_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - } - return SDIOH_API_RC_SUCCESS; -} - -/* Configure callback to client when we receive client interrupt */ -extern SDIOH_API_RC -sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - sd->intr_handler = fn; - sd->intr_handler_arg = argh; - sd->intr_handler_valid = TRUE; - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_interrupt_deregister(sdioh_info_t *sd) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - sd->intr_handler_valid = FALSE; - sd->intr_handler = NULL; - sd->intr_handler_arg = NULL; - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - *onoff = sd->client_intr_enabled; - return SDIOH_API_RC_SUCCESS; -} - -#if defined(DHD_DEBUG) -extern bool -sdioh_interrupt_pending(sdioh_info_t *sd) -{ - uint16 intrstatus; - intrstatus = sdstd_rreg16(sd, SD_IntrStatus); - return !!(intrstatus & CLIENT_INTR); -} -#endif - -uint -sdioh_query_iofnum(sdioh_info_t *sd) -{ - return sd->num_funcs; -} - -/* IOVar table */ -enum { - IOV_MSGLEVEL = 1, - IOV_BLOCKMODE, - IOV_BLOCKSIZE, - IOV_DMA, - IOV_USEINTS, - IOV_NUMINTS, - IOV_NUMLOCALINTS, - IOV_HOSTREG, - IOV_DEVREG, - IOV_DIVISOR, - IOV_SDMODE, - IOV_HISPEED, - IOV_HCIREGS, - IOV_POWER, - IOV_YIELDCPU, - IOV_MINYIELD, - IOV_FORCERB, - IOV_CLOCK -}; - -const bcm_iovar_t sdioh_iovars[] = { - {"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 }, - {"sd_blockmode", IOV_BLOCKMODE, 0, IOVT_BOOL, 0 }, - {"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0 }, /* ((fn << 16) | size) */ - {"sd_dma", IOV_DMA, 0, IOVT_UINT32, 0 }, -#ifdef BCMSDYIELD - {"sd_yieldcpu", IOV_YIELDCPU, 0, IOVT_BOOL, 0 }, - {"sd_minyield", IOV_MINYIELD, 0, IOVT_UINT32, 0 }, - {"sd_forcerb", IOV_FORCERB, 0, IOVT_BOOL, 0 }, -#endif - {"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0 }, - {"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0 }, - {"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32, 0 }, - {"sd_hostreg", IOV_HOSTREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_divisor", IOV_DIVISOR, 0, IOVT_UINT32, 0 }, - {"sd_power", IOV_POWER, 0, IOVT_UINT32, 0 }, - {"sd_clock", IOV_CLOCK, 0, IOVT_UINT32, 0 }, - {"sd_mode", IOV_SDMODE, 0, IOVT_UINT32, 100}, - {"sd_highspeed", IOV_HISPEED, 0, IOVT_UINT32, 0}, - {NULL, 0, 0, 0, 0 } -}; - -int -sdioh_iovar_op(sdioh_info_t *si, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - const bcm_iovar_t *vi = NULL; - int bcmerror = 0; - int val_size; - int32 int_val = 0; - bool bool_val; - uint32 actionid; - - ASSERT(name); - ASSERT(len >= 0); - - /* Get must have return space; Set does not take qualifiers */ - ASSERT(set || (arg && len)); - ASSERT(!set || (!params && !plen)); - - sd_trace(("%s: Enter (%s %s)\n", __FUNCTION__, (set ? "set" : "get"), name)); - - if ((vi = bcm_iovar_lookup(sdioh_iovars, name)) == NULL) { - bcmerror = BCME_UNSUPPORTED; - goto exit; - } - - if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, set)) != 0) - goto exit; - - /* Set up params so get and set can share the convenience variables */ - if (params == NULL) { - params = arg; - plen = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - val_size = sizeof(int); - - if (plen >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); - - bool_val = (int_val != 0) ? TRUE : FALSE; - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - switch (actionid) { - case IOV_GVAL(IOV_MSGLEVEL): - int_val = (int32)sd_msglevel; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_MSGLEVEL): - sd_msglevel = int_val; - break; - - case IOV_GVAL(IOV_BLOCKMODE): - int_val = (int32)si->sd_blockmode; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_BLOCKMODE): - si->sd_blockmode = (bool)int_val; - /* Haven't figured out how to make non-block mode with DMA */ - if (!si->sd_blockmode) - si->sd_dma_mode = DMA_MODE_NONE; - break; - -#ifdef BCMSDYIELD - case IOV_GVAL(IOV_YIELDCPU): - int_val = sd_yieldcpu; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_YIELDCPU): - sd_yieldcpu = (bool)int_val; - break; - - case IOV_GVAL(IOV_MINYIELD): - int_val = sd_minyield; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_MINYIELD): - sd_minyield = (bool)int_val; - break; - - case IOV_GVAL(IOV_FORCERB): - int_val = sd_forcerb; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_FORCERB): - sd_forcerb = (bool)int_val; - break; -#endif /* BCMSDYIELD */ - - case IOV_GVAL(IOV_BLOCKSIZE): - if ((uint32)int_val > si->num_funcs) { - bcmerror = BCME_BADARG; - break; - } - int_val = (int32)si->client_block_size[int_val]; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_BLOCKSIZE): - { - uint func = ((uint32)int_val >> 16); - uint blksize = (uint16)int_val; - uint maxsize; - - if (func > si->num_funcs) { - bcmerror = BCME_BADARG; - break; - } - - switch (func) { - case 0: maxsize = 32; break; - case 1: maxsize = BLOCK_SIZE_4318; break; - case 2: maxsize = BLOCK_SIZE_4328; break; - default: maxsize = 0; - } - if (blksize > maxsize) { - bcmerror = BCME_BADARG; - break; - } - if (!blksize) { - blksize = maxsize; - } - - /* Now set it */ - sdstd_lock(si); - bcmerror = set_client_block_size(si, func, blksize); - sdstd_unlock(si); - break; - } - - case IOV_GVAL(IOV_DMA): - int_val = (int32)si->sd_dma_mode; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DMA): - si->sd_dma_mode = (char)int_val; - sdstd_set_dma_mode(si, si->sd_dma_mode); - break; - - case IOV_GVAL(IOV_USEINTS): - int_val = (int32)si->use_client_ints; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_USEINTS): - si->use_client_ints = (bool)int_val; - if (si->use_client_ints) - si->intmask |= CLIENT_INTR; - else - si->intmask &= ~CLIENT_INTR; - break; - - case IOV_GVAL(IOV_DIVISOR): - int_val = (uint32)sd_divisor; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DIVISOR): - sd_divisor = int_val; - if (!sdstd_start_clock(si, (uint16)sd_divisor)) { - sd_err(("set clock failed!\n")); - bcmerror = BCME_ERROR; - } - break; - - case IOV_GVAL(IOV_POWER): - int_val = (uint32)sd_power; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_POWER): - sd_power = int_val; - if (sd_power == 1) { - if (sdstd_driver_init(si) != SUCCESS) { - sd_err(("set SD Slot power failed!\n")); - bcmerror = BCME_ERROR; - } else { - sd_err(("SD Slot Powered ON.\n")); - } - } else { - uint8 pwr = 0; - - pwr = SFIELD(pwr, PWR_BUS_EN, 0); - sdstd_wreg8(si, SD_PwrCntrl, pwr); /* Set Voltage level */ - sd_err(("SD Slot Powered OFF.\n")); - } - break; - - case IOV_GVAL(IOV_CLOCK): - int_val = (uint32)sd_clock; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_CLOCK): - sd_clock = int_val; - if (sd_clock == 1) { - sd_info(("SD Clock turned ON.\n")); - if (!sdstd_start_clock(si, (uint16)sd_divisor)) { - sd_err(("sdstd_start_clock failed\n")); - bcmerror = BCME_ERROR; - } - } else { - /* turn off HC clock */ - sdstd_wreg16(si, SD_ClockCntrl, - sdstd_rreg16(si, SD_ClockCntrl) & ~((uint16)0x4)); - - sd_info(("SD Clock turned OFF.\n")); - } - break; - - case IOV_GVAL(IOV_SDMODE): - int_val = (uint32)sd_sdmode; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_SDMODE): - sd_sdmode = int_val; - - if (!sdstd_bus_width(si, sd_sdmode)) { - sd_err(("sdstd_bus_width failed\n")); - bcmerror = BCME_ERROR; - } - break; - - case IOV_GVAL(IOV_HISPEED): - int_val = (uint32)sd_hiok; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_HISPEED): - sd_hiok = int_val; - bcmerror = sdstd_set_highspeed_mode(si, (bool)sd_hiok); - break; - - case IOV_GVAL(IOV_NUMINTS): - int_val = (int32)si->intrcount; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_NUMLOCALINTS): - int_val = (int32)si->local_intrcount; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_HOSTREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - - if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) { - sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset)); - bcmerror = BCME_BADARG; - break; - } - - sd_trace(("%s: rreg%d at offset %d\n", __FUNCTION__, - (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32), - sd_ptr->offset)); - if (sd_ptr->offset & 1) - int_val = sdstd_rreg8(si, sd_ptr->offset); - else if (sd_ptr->offset & 2) - int_val = sdstd_rreg16(si, sd_ptr->offset); - else - int_val = sdstd_rreg(si, sd_ptr->offset); - - bcopy(&int_val, arg, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_HOSTREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - - if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) { - sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset)); - bcmerror = BCME_BADARG; - break; - } - - sd_trace(("%s: wreg%d value 0x%08x at offset %d\n", __FUNCTION__, sd_ptr->value, - (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32), - sd_ptr->offset)); - if (sd_ptr->offset & 1) - sdstd_wreg8(si, sd_ptr->offset, (uint8)sd_ptr->value); - else if (sd_ptr->offset & 2) - sdstd_wreg16(si, sd_ptr->offset, (uint16)sd_ptr->value); - else - sdstd_wreg(si, sd_ptr->offset, (uint32)sd_ptr->value); - - break; - } - - case IOV_GVAL(IOV_DEVREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - uint8 data; - - if (sdioh_cfg_read(si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = BCME_SDIO_ERROR; - break; - } - - int_val = (int)data; - bcopy(&int_val, arg, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_DEVREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - uint8 data = (uint8)sd_ptr->value; - - if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = BCME_SDIO_ERROR; - break; - } - break; - } - - - default: - bcmerror = BCME_UNSUPPORTED; - break; - } -exit: - - return bcmerror; -} - -extern SDIOH_API_RC -sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) -{ - SDIOH_API_RC status; - /* No lock needed since sdioh_request_byte does locking */ - status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data); - return status; -} - -extern SDIOH_API_RC -sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) -{ - /* No lock needed since sdioh_request_byte does locking */ - SDIOH_API_RC status; - status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data); - return status; -} - -extern SDIOH_API_RC -sdioh_cis_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 length) -{ - uint32 count; - int offset; - uint32 foo; - uint8 *cis = cisd; - - sd_trace(("%s: Func = %d\n", __FUNCTION__, func)); - - if (!sd->func_cis_ptr[func]) { - bzero(cis, length); - return SDIOH_API_RC_FAIL; - } - - sdstd_lock(sd); - *cis = 0; - for (count = 0; count < length; count++) { - offset = sd->func_cis_ptr[func] + count; - if (sdstd_card_regread(sd, 0, offset, 1, &foo)) { - sd_err(("%s: regread failed: Can't read CIS\n", __FUNCTION__)); - sdstd_unlock(sd); - return SDIOH_API_RC_FAIL; - } - *cis = (uint8)(foo & 0xff); - cis++; - } - sdstd_unlock(sd); - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte) -{ - int status; - uint32 cmd_arg; - uint32 rsp5; - - sdstd_lock(sd); - cmd_arg = 0; - cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, rw == SDIOH_READ ? 0 : 1); - cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0); - cmd_arg = SFIELD(cmd_arg, CMD52_DATA, rw == SDIOH_READ ? 0 : *byte); - - if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_52, cmd_arg)) != SUCCESS) { - sdstd_unlock(sd); - return status; - } - - sdstd_cmd_getrsp(sd, &rsp5, 1); - if (sdstd_rreg16 (sd, SD_ErrorIntrStatus) != 0) { - sd_err(("%s: 1: ErrorintrStatus 0x%x\n", - __FUNCTION__, sdstd_rreg16(sd, SD_ErrorIntrStatus))); - } - if (GFIELD(rsp5, RSP5_FLAGS) != 0x10) - sd_err(("%s: rsp5 flags is 0x%x\t %d\n", - __FUNCTION__, GFIELD(rsp5, RSP5_FLAGS), func)); - - if (GFIELD(rsp5, RSP5_STUFF)) - sd_err(("%s: rsp5 stuff is 0x%x: should be 0\n", - __FUNCTION__, GFIELD(rsp5, RSP5_STUFF))); - - if (rw == SDIOH_READ) - *byte = GFIELD(rsp5, RSP5_DATA); - - sdstd_unlock(sd); - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint addr, - uint32 *word, uint nbytes) -{ - int status; - bool swap = FALSE; - - sdstd_lock(sd); - - if (rw == SDIOH_READ) { - status = sdstd_card_regread(sd, func, addr, nbytes, word); - if (swap) - *word = BCMSWAP32(*word); - } else { - if (swap) - *word = BCMSWAP32(*word); - status = sdstd_card_regwrite(sd, func, addr, nbytes, *word); - } - - sdstd_unlock(sd); - return (status == SUCCESS ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); -} - -extern SDIOH_API_RC -sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint rw, uint func, - uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt) -{ - int len; - int buflen = (int)buflen_u; - bool fifo = (fix_inc == SDIOH_DATA_FIX); - uint8 *localbuf = NULL, *tmpbuf = NULL; - uint tmplen = 0; - bool local_blockmode = sd->sd_blockmode; - - sdstd_lock(sd); - - ASSERT(reg_width == 4); - ASSERT(buflen_u < (1 << 30)); - ASSERT(sd->client_block_size[func]); - - sd_data(("%s: %c len %d r_cnt %d t_cnt %d, pkt @0x%p\n", - __FUNCTION__, rw == SDIOH_READ ? 'R' : 'W', - buflen_u, sd->r_cnt, sd->t_cnt, pkt)); - - /* Break buffer down into blocksize chunks: - * Bytemode: 1 block at a time. - * Blockmode: Multiples of blocksizes at a time w/ max of SD_PAGE. - * Both: leftovers are handled last (will be sent via bytemode). - */ - while (buflen > 0) { - if (local_blockmode) { - /* Max xfer is Page size */ - len = MIN(SD_PAGE, buflen); - - /* Round down to a block boundry */ - if (buflen > sd->client_block_size[func]) - len = (len/sd->client_block_size[func]) * - sd->client_block_size[func]; - if ((func == SDIO_FUNC_1) && ((len % 4) == 3) && (rw == SDIOH_WRITE)) { - tmplen = len; - sd_err(("%s: Rounding up buffer to mod4 length.\n", __FUNCTION__)); - len++; - tmpbuf = buffer; - if ((localbuf = (uint8 *)MALLOC(sd->osh, len)) == NULL) { - sd_err(("out of memory, malloced %d bytes\n", - MALLOCED(sd->osh))); - sdstd_unlock(sd); - return SDIOH_API_RC_FAIL; - } - bcopy(buffer, localbuf, len); - buffer = localbuf; - } - } else { - /* Byte mode: One block at a time */ - len = MIN(sd->client_block_size[func], buflen); - } - - if (sdstd_card_buf(sd, rw, func, fifo, addr, len, (uint32 *)buffer) != SUCCESS) { - sdstd_unlock(sd); - return SDIOH_API_RC_FAIL; - } - - if (local_blockmode) { - if ((func == SDIO_FUNC_1) && ((tmplen % 4) == 3) && (rw == SDIOH_WRITE)) { - if (localbuf) - MFREE(sd->osh, localbuf, len); - len--; - buffer = tmpbuf; - sd_err(("%s: Restoring back buffer ptr and len.\n", __FUNCTION__)); - } - } - - buffer += len; - buflen -= len; - if (!fifo) - addr += len; - } - sdstd_unlock(sd); - return SDIOH_API_RC_SUCCESS; -} - -static -int sdstd_abort(sdioh_info_t *sd, uint func) -{ - int err = 0; - int retries; - - uint16 cmd_reg; - uint32 cmd_arg; - uint32 rsp5; - uint8 rflags; - - uint16 int_reg = 0; - uint16 plain_intstatus; - - /* Argument is write to F0 (CCCR) IOAbort with function number */ - cmd_arg = 0; - cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, SDIO_FUNC_0); - cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, SDIOD_CCCR_IOABORT); - cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, SD_IO_OP_WRITE); - cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0); - cmd_arg = SFIELD(cmd_arg, CMD52_DATA, func); - - /* Command is CMD52 write */ - cmd_reg = 0; - cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48_BUSY); - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 1); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 1); - cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_ABORT); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX, SDIOH_CMD_52); - - if (sd->sd_mode == SDIOH_MODE_SPI) { - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0); - } - - /* Wait for CMD_INHIBIT to go away as per spec section 3.6.1.1 */ - retries = RETRIES_SMALL; - while (GFIELD(sdstd_rreg(sd, SD_PresentState), PRES_CMD_INHIBIT)) { - if (retries == RETRIES_SMALL) - sd_err(("%s: Waiting for Command Inhibit, state 0x%08x\n", - __FUNCTION__, sdstd_rreg(sd, SD_PresentState))); - if (!--retries) { - sd_err(("%s: Command Inhibit timeout, state 0x%08x\n", - __FUNCTION__, sdstd_rreg(sd, SD_PresentState))); - if (trap_errs) - ASSERT(0); - err = BCME_SDIO_ERROR; - goto done; - } - } - - /* Clear errors from any previous commands */ - if ((plain_intstatus = sdstd_rreg16(sd, SD_ErrorIntrStatus)) != 0) { - sd_err(("abort: clearing errstat 0x%04x\n", plain_intstatus)); - sdstd_wreg16(sd, SD_ErrorIntrStatus, plain_intstatus); - } - plain_intstatus = sdstd_rreg16(sd, SD_IntrStatus); - if (plain_intstatus & ~(SFIELD(0, INTSTAT_CARD_INT, 1))) { - sd_err(("abort: intstatus 0x%04x\n", plain_intstatus)); - if (GFIELD(plain_intstatus, INTSTAT_CMD_COMPLETE)) { - sd_err(("SDSTD_ABORT: CMD COMPLETE SET BEFORE COMMAND GIVEN!!!\n")); - } - if (GFIELD(plain_intstatus, INTSTAT_CARD_REMOVAL)) { - sd_err(("SDSTD_ABORT: INTSTAT_CARD_REMOVAL\n")); - err = BCME_NODEVICE; - goto done; - } - } - - /* Issue the command */ - sdstd_wreg(sd, SD_Arg0, cmd_arg); - sdstd_wreg16(sd, SD_Command, cmd_reg); - - /* In interrupt mode return, expect later CMD_COMPLETE interrupt */ - if (!sd->polled_mode) - return err; - - /* Otherwise, wait for the command to complete */ - retries = RETRIES_LARGE; - do { - int_reg = sdstd_rreg16(sd, SD_IntrStatus); - } while (--retries && - (GFIELD(int_reg, INTSTAT_ERROR_INT) == 0) && - (GFIELD(int_reg, INTSTAT_CMD_COMPLETE) == 0)); - - /* If command completion fails, do a cmd reset and note the error */ - if (!retries) { - sd_err(("%s: CMD_COMPLETE timeout: intr 0x%04x err 0x%04x state 0x%08x\n", - __FUNCTION__, int_reg, - sdstd_rreg16(sd, SD_ErrorIntrStatus), - sdstd_rreg(sd, SD_PresentState))); - - sdstd_wreg8(sd, SD_SoftwareReset, SFIELD(0, SW_RESET_CMD, 1)); - retries = RETRIES_LARGE; - do { - sd_trace(("%s: waiting for CMD line reset\n", __FUNCTION__)); - } while ((GFIELD(sdstd_rreg8(sd, SD_SoftwareReset), - SW_RESET_CMD)) && retries--); - - if (!retries) { - sd_err(("%s: Timeout waiting for CMD line reset\n", __FUNCTION__)); - } - - if (trap_errs) - ASSERT(0); - - err = BCME_SDIO_ERROR; - } - - /* Clear Command Complete interrupt */ - int_reg = SFIELD(0, INTSTAT_CMD_COMPLETE, 1); - sdstd_wreg16(sd, SD_IntrStatus, int_reg); - - /* Check for Errors */ - if ((plain_intstatus = sdstd_rreg16 (sd, SD_ErrorIntrStatus)) != 0) { - sd_err(("%s: ErrorintrStatus: 0x%x, " - "(intrstatus = 0x%x, present state 0x%x) clearing\n", - __FUNCTION__, plain_intstatus, - sdstd_rreg16(sd, SD_IntrStatus), - sdstd_rreg(sd, SD_PresentState))); - - sdstd_wreg16(sd, SD_ErrorIntrStatus, plain_intstatus); - - sdstd_wreg8(sd, SD_SoftwareReset, SFIELD(0, SW_RESET_DAT, 1)); - retries = RETRIES_LARGE; - do { - sd_trace(("%s: waiting for DAT line reset\n", __FUNCTION__)); - } while ((GFIELD(sdstd_rreg8(sd, SD_SoftwareReset), - SW_RESET_DAT)) && retries--); - - if (!retries) { - sd_err(("%s: Timeout waiting for DAT line reset\n", __FUNCTION__)); - } - - if (trap_errs) - ASSERT(0); - - /* ABORT is dataless, only cmd errs count */ - if (plain_intstatus & ERRINT_CMD_ERRS) - err = BCME_SDIO_ERROR; - } - - /* If command failed don't bother looking at response */ - if (err) - goto done; - - /* Otherwise, check the response */ - sdstd_cmd_getrsp(sd, &rsp5, 1); - rflags = GFIELD(rsp5, RSP5_FLAGS); - - if (rflags & SD_RSP_R5_ERRBITS) { - sd_err(("%s: R5 flags include errbits: 0x%02x\n", __FUNCTION__, rflags)); - - /* The CRC error flag applies to the previous command */ - if (rflags & (SD_RSP_R5_ERRBITS & ~SD_RSP_R5_COM_CRC_ERROR)) { - err = BCME_SDIO_ERROR; - goto done; - } - } - - if (((rflags & (SD_RSP_R5_IO_CURRENTSTATE0 | SD_RSP_R5_IO_CURRENTSTATE1)) != 0x10) && - ((rflags & (SD_RSP_R5_IO_CURRENTSTATE0 | SD_RSP_R5_IO_CURRENTSTATE1)) != 0x20)) { - sd_err(("%s: R5 flags has bad state: 0x%02x\n", __FUNCTION__, rflags)); - err = BCME_SDIO_ERROR; - goto done; - } - - if (GFIELD(rsp5, RSP5_STUFF)) { - sd_err(("%s: rsp5 stuff is 0x%x: should be 0\n", - __FUNCTION__, GFIELD(rsp5, RSP5_STUFF))); - err = BCME_SDIO_ERROR; - goto done; - } - -done: - if (err == BCME_NODEVICE) - return err; - - sdstd_wreg8(sd, SD_SoftwareReset, - SFIELD(SFIELD(0, SW_RESET_DAT, 1), SW_RESET_CMD, 1)); - - retries = RETRIES_LARGE; - do { - rflags = sdstd_rreg8(sd, SD_SoftwareReset); - if (!GFIELD(rflags, SW_RESET_DAT) && !GFIELD(rflags, SW_RESET_CMD)) - break; - } while (--retries); - - if (!retries) { - sd_err(("%s: Timeout waiting for DAT/CMD reset: 0x%02x\n", - __FUNCTION__, rflags)); - err = BCME_SDIO_ERROR; - } - - return err; -} - -extern int -sdioh_abort(sdioh_info_t *sd, uint fnum) -{ - int ret; - - sdstd_lock(sd); - ret = sdstd_abort(sd, fnum); - sdstd_unlock(sd); - - return ret; -} - -int -sdioh_start(sdioh_info_t *sd, int stage) -{ - return SUCCESS; -} - -int -sdioh_stop(sdioh_info_t *sd) -{ - return SUCCESS; -} - -static int -sdstd_check_errs(sdioh_info_t *sdioh_info, uint32 cmd, uint32 arg) -{ - uint16 regval; - uint retries; - uint function = 0; - - /* If no errors, we're done */ - if ((regval = sdstd_rreg16(sdioh_info, SD_ErrorIntrStatus)) == 0) - return SUCCESS; - - sd_info(("%s: ErrorIntrStatus 0x%04x (clearing), IntrStatus 0x%04x PresentState 0x%08x\n", - __FUNCTION__, regval, sdstd_rreg16(sdioh_info, SD_IntrStatus), - sdstd_rreg(sdioh_info, SD_PresentState))); - sdstd_wreg16(sdioh_info, SD_ErrorIntrStatus, regval); - - /* On command error, issue CMD reset */ - if (regval & ERRINT_CMD_ERRS) { - sd_trace(("%s: issuing CMD reset\n", __FUNCTION__)); - sdstd_wreg8(sdioh_info, SD_SoftwareReset, SFIELD(0, SW_RESET_CMD, 1)); - for (retries = RETRIES_LARGE; retries; retries--) - if (!(GFIELD(sdstd_rreg8(sdioh_info, SD_SoftwareReset), SW_RESET_CMD))) - break; - if (!retries) { - sd_err(("%s: Timeout waiting for CMD line reset\n", __FUNCTION__)); - } - } - - /* On data error, issue DAT reset */ - if (regval & ERRINT_DATA_ERRS) { - sd_trace(("%s: issuing DAT reset\n", __FUNCTION__)); - sdstd_wreg8(sdioh_info, SD_SoftwareReset, SFIELD(0, SW_RESET_DAT, 1)); - for (retries = RETRIES_LARGE; retries; retries--) - if (!(GFIELD(sdstd_rreg8(sdioh_info, SD_SoftwareReset), SW_RESET_DAT))) - break; - if (!retries) { - sd_err(("%s: Timeout waiting for DAT line reset\n", __FUNCTION__)); - } - } - - /* For an IO command (CMD52 or CMD53) issue an abort to the appropriate function */ - if (cmd == SDIOH_CMD_53) - function = GFIELD(arg, CMD53_FUNCTION); - else if (cmd == SDIOH_CMD_52) - function = GFIELD(arg, CMD52_FUNCTION); - if (function) { - sd_trace(("%s: requesting abort for function %d after cmd %d\n", - __FUNCTION__, function, cmd)); - sdstd_abort(sdioh_info, function); - } - - if (trap_errs) - ASSERT(0); - - return ERROR; -} - - - -/* - * Private/Static work routines - */ -static bool -sdstd_reset(sdioh_info_t *sd, bool host_reset, bool client_reset) -{ - int retries = RETRIES_LARGE; - uchar regval; - - if (!sd) - return TRUE; - - sdstd_lock(sd); - /* Reset client card */ - if (client_reset && (sd->adapter_slot != -1)) { - if (sdstd_card_regwrite(sd, 0, SDIOD_CCCR_IOABORT, 1, 0x8) != SUCCESS) - sd_err(("%s: Cannot write to card reg 0x%x\n", - __FUNCTION__, SDIOD_CCCR_IOABORT)); - else - sd->card_rca = 0; - } - - /* Reset host controller */ - if (host_reset) { - regval = SFIELD(0, SW_RESET_ALL, 1); - sdstd_wreg8(sd, SD_SoftwareReset, regval); - do { - sd_trace(("%s: waiting for reset\n", __FUNCTION__)); - } while ((sdstd_rreg8(sd, SD_SoftwareReset) & regval) && retries--); - - if (!retries) { - sd_err(("%s: Timeout waiting for host reset\n", __FUNCTION__)); - sdstd_unlock(sd); - return (FALSE); - } - - /* A reset should reset bus back to 1 bit mode */ - sd->sd_mode = SDIOH_MODE_SD1; - sdstd_set_dma_mode(sd, sd->sd_dma_mode); - } - sdstd_unlock(sd); - return TRUE; -} - -/* Disable device interrupt */ -void -sdstd_devintr_off(sdioh_info_t *sd) -{ - sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints)); - if (sd->use_client_ints) { - sd->intmask &= ~CLIENT_INTR; - sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask); - sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */ - } -} - -/* Enable device interrupt */ -void -sdstd_devintr_on(sdioh_info_t *sd) -{ - ASSERT(sd->lockcount == 0); - sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints)); - if (sd->use_client_ints) { - uint16 status = sdstd_rreg16(sd, SD_IntrStatusEnable); - sdstd_wreg16(sd, SD_IntrStatusEnable, SFIELD(status, INTSTAT_CARD_INT, 0)); - sdstd_wreg16(sd, SD_IntrStatusEnable, status); - - sd->intmask |= CLIENT_INTR; - sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask); - sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */ - } -} - -#ifdef BCMSDYIELD -/* Enable/disable other interrupts */ -void -sdstd_intrs_on(sdioh_info_t *sd, uint16 norm, uint16 err) -{ - if (err) { - norm = SFIELD(norm, INTSTAT_ERROR_INT, 1); - sdstd_wreg16(sd, SD_ErrorIntrSignalEnable, err); - } - - sd->intmask |= norm; - sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask); - if (sd_forcerb) - sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */ -} - -void -sdstd_intrs_off(sdioh_info_t *sd, uint16 norm, uint16 err) -{ - if (err) { - norm = SFIELD(norm, INTSTAT_ERROR_INT, 1); - sdstd_wreg16(sd, SD_ErrorIntrSignalEnable, 0); - } - - sd->intmask &= ~norm; - sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask); - if (sd_forcerb) - sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */ -} -#endif /* BCMSDYIELD */ - -static int -sdstd_host_init(sdioh_info_t *sd) -{ - int num_slots, full_slot; - uint8 reg8; - - uint32 card_ins; - int slot, first_bar = 0; - bool detect_slots = FALSE; - uint bar; - - /* Check for Arasan ID */ - if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_SI_IMAGE) { - sd_info(("%s: Found Arasan Standard SDIO Host Controller\n", __FUNCTION__)); - sd->controller_type = SDIOH_TYPE_ARASAN_HDK; - detect_slots = TRUE; - } else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_BROADCOM) { - sd_info(("%s: Found Broadcom 27xx Standard SDIO Host Controller\n", __FUNCTION__)); - sd->controller_type = SDIOH_TYPE_BCM27XX; - detect_slots = FALSE; - } else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_TI) { - sd_info(("%s: Found TI PCIxx21 Standard SDIO Host Controller\n", __FUNCTION__)); - sd->controller_type = SDIOH_TYPE_TI_PCIXX21; - detect_slots = TRUE; - } else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_RICOH) { - sd_info(("%s: Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter\n", - __FUNCTION__)); - sd->controller_type = SDIOH_TYPE_RICOH_R5C822; - detect_slots = TRUE; - } else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_JMICRON) { - sd_info(("%s: JMicron Standard SDIO Host Controller\n", - __FUNCTION__)); - sd->controller_type = SDIOH_TYPE_JMICRON; - detect_slots = TRUE; - } else { - return ERROR; - } - - /* - * Determine num of slots - * Search each slot - */ - - first_bar = OSL_PCI_READ_CONFIG(sd->osh, SD_SlotInfo, 4) & 0x7; - num_slots = (OSL_PCI_READ_CONFIG(sd->osh, SD_SlotInfo, 4) & 0xff) >> 4; - num_slots &= 7; - num_slots++; /* map bits to num slots according to spec */ - - if (OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) == - ((SDIOH_FPGA_ID << 16) | VENDOR_BROADCOM)) { - sd_err(("%s: Found Broadcom Standard SDIO Host Controller FPGA\n", __FUNCTION__)); - /* Set BAR0 Window to SDIOSTH core */ - OSL_PCI_WRITE_CONFIG(sd->osh, PCI_BAR0_WIN, 4, 0x18001000); - - /* Set defaults particular to this controller. */ - detect_slots = TRUE; - num_slots = 1; - first_bar = 0; - - /* Controller supports ADMA2, so turn it on here. */ - sd->sd_dma_mode = DMA_MODE_ADMA2; - } - - /* Map in each slot on the board and query it to see if a - * card is inserted. Use the first populated slot found. - */ - if (sd->mem_space) { - sdstd_reg_unmap(sd->osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ); - sd->mem_space = NULL; - } - - full_slot = -1; - - for (slot = 0; slot < num_slots; slot++) { - bar = OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR0 + (4*(slot + first_bar)), 4); - sd->mem_space = (volatile char *)sdstd_reg_map(sd->osh, - (uintptr)bar, SDIOH_REG_WINSZ); - - sd->adapter_slot = -1; - - if (detect_slots) { - card_ins = GFIELD(sdstd_rreg(sd, SD_PresentState), PRES_CARD_PRESENT); - } else { - card_ins = TRUE; - } - - if (card_ins) { - sd_info(("%s: SDIO slot %d: Full\n", __FUNCTION__, slot)); - if (full_slot < 0) - full_slot = slot; - } else { - sd_info(("%s: SDIO slot %d: Empty\n", __FUNCTION__, slot)); - } - - if (sd->mem_space) { - sdstd_reg_unmap(sd->osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ); - sd->mem_space = NULL; - } - } - - if (full_slot < 0) { - sd_err(("No slots on SDIO controller are populated\n")); - return -1; - } - - bar = OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR0 + (4*(full_slot + first_bar)), 4); - sd->mem_space = (volatile char *)sdstd_reg_map(sd->osh, (uintptr)bar, SDIOH_REG_WINSZ); - - sd_err(("Using slot %d at BAR%d [0x%08x] mem_space 0x%p\n", - full_slot, - (full_slot + first_bar), - OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR0 + (4*(full_slot + first_bar)), 4), - sd->mem_space)); - - - sd->adapter_slot = full_slot; - - sd->version = sdstd_rreg16(sd, SD_HostControllerVersion) & 0xFF; - switch (sd->version) { - case 0: - sd_err(("Host Controller version 1.0, Vendor Revision: 0x%02x\n", - sdstd_rreg16(sd, SD_HostControllerVersion) >> 8)); - break; - case 1: - case 2: - sd_err(("Host Controller version 2.0, Vendor Revision: 0x%02x\n", - sdstd_rreg16(sd, SD_HostControllerVersion) >> 8)); - break; - default: - sd_err(("%s: Host Controller version 0x%02x not supported.\n", - __FUNCTION__, sd->version)); - break; - } - - sd->caps = sdstd_rreg(sd, SD_Capabilities); /* Cache this for later use */ - sd->curr_caps = sdstd_rreg(sd, SD_MaxCurCap); - - sdstd_set_dma_mode(sd, sd->sd_dma_mode); - - - sdstd_reset(sd, 1, 0); - - /* Read SD4/SD1 mode */ - if ((reg8 = sdstd_rreg8(sd, SD_HostCntrl))) { - if (reg8 & SD4_MODE) { - sd_err(("%s: Host cntrlr already in 4 bit mode: 0x%x\n", - __FUNCTION__, reg8)); - } - } - - /* Default power on mode is SD1 */ - sd->sd_mode = SDIOH_MODE_SD1; - sd->polled_mode = TRUE; - sd->host_init_done = TRUE; - sd->card_init_done = FALSE; - sd->adapter_slot = full_slot; - - return (SUCCESS); -} -#define CMD5_RETRIES 200 -static int -get_ocr(sdioh_info_t *sd, uint32 *cmd_arg, uint32 *cmd_rsp) -{ - int retries, status; - - /* Get the Card's Operation Condition. Occasionally the board - * takes a while to become ready - */ - retries = CMD5_RETRIES; - do { - *cmd_rsp = 0; - if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_5, *cmd_arg)) - != SUCCESS) { - sd_err(("%s: CMD5 failed\n", __FUNCTION__)); - return status; - } - sdstd_cmd_getrsp(sd, cmd_rsp, 1); - if (!GFIELD(*cmd_rsp, RSP4_CARD_READY)) - sd_trace(("%s: Waiting for card to become ready\n", __FUNCTION__)); - } while ((!GFIELD(*cmd_rsp, RSP4_CARD_READY)) && --retries); - if (!retries) - return ERROR; - - return (SUCCESS); -} - -static int -sdstd_client_init(sdioh_info_t *sd) -{ - uint32 cmd_arg, cmd_rsp; - int status; - uint8 fn_ints; - - - sd_trace(("%s: Powering up slot %d\n", __FUNCTION__, sd->adapter_slot)); - - /* Clear any pending ints */ - sdstd_wreg16(sd, SD_IntrStatus, 0x1ff); - sdstd_wreg16(sd, SD_ErrorIntrStatus, 0x0fff); - - /* Enable both Normal and Error Status. This does not enable - * interrupts, it only enables the status bits to - * become 'live' - */ - sdstd_wreg16(sd, SD_IntrStatusEnable, 0x1ff); - sdstd_wreg16(sd, SD_ErrorIntrStatusEnable, 0xffff); - - sdstd_wreg16(sd, SD_IntrSignalEnable, 0); /* Disable ints for now. */ - - /* Start at ~400KHz clock rate for initialization */ - if (!sdstd_start_clock(sd, 128)) { - sd_err(("sdstd_start_clock failed\n")); - return ERROR; - } - if (!sdstd_start_power(sd)) { - sd_err(("sdstd_start_power failed\n")); - return ERROR; - } - - if (sd->num_funcs == 0) { - sd_err(("%s: No IO funcs!\n", __FUNCTION__)); - return ERROR; - } - - /* In SPI mode, issue CMD0 first */ - if (sd->sd_mode == SDIOH_MODE_SPI) { - cmd_arg = 0; - if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_0, cmd_arg)) - != SUCCESS) { - sd_err(("BCMSDIOH: cardinit: CMD0 failed!\n")); - return status; - } - } - - if (sd->sd_mode != SDIOH_MODE_SPI) { - uint16 rsp6_status; - - /* Card is operational. Ask it to send an RCA */ - cmd_arg = 0; - if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_3, cmd_arg)) - != SUCCESS) { - sd_err(("%s: CMD3 failed!\n", __FUNCTION__)); - return status; - } - - /* Verify the card status returned with the cmd response */ - sdstd_cmd_getrsp(sd, &cmd_rsp, 1); - rsp6_status = GFIELD(cmd_rsp, RSP6_STATUS); - if (GFIELD(rsp6_status, RSP6STAT_COM_CRC_ERROR) || - GFIELD(rsp6_status, RSP6STAT_ILLEGAL_CMD) || - GFIELD(rsp6_status, RSP6STAT_ERROR)) { - sd_err(("%s: CMD3 response error. Response = 0x%x!\n", - __FUNCTION__, rsp6_status)); - return ERROR; - } - - /* Save the Card's RCA */ - sd->card_rca = GFIELD(cmd_rsp, RSP6_IO_RCA); - sd_info(("RCA is 0x%x\n", sd->card_rca)); - - if (rsp6_status) - sd_err(("raw status is 0x%x\n", rsp6_status)); - - /* Select the card */ - cmd_arg = SFIELD(0, CMD7_RCA, sd->card_rca); - if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_7, cmd_arg)) - != SUCCESS) { - sd_err(("%s: CMD7 failed!\n", __FUNCTION__)); - return status; - } - sdstd_cmd_getrsp(sd, &cmd_rsp, 1); - if (cmd_rsp != SDIOH_CMD7_EXP_STATUS) { - sd_err(("%s: CMD7 response error. Response = 0x%x!\n", - __FUNCTION__, cmd_rsp)); - return ERROR; - } - } - - sdstd_card_enablefuncs(sd); - - if (!sdstd_bus_width(sd, sd_sdmode)) { - sd_err(("sdstd_bus_width failed\n")); - return ERROR; - } - - set_client_block_size(sd, 1, BLOCK_SIZE_4318); - fn_ints = INTR_CTL_FUNC1_EN; - - if (sd->num_funcs >= 2) { - set_client_block_size(sd, 2, sd_f2_blocksize /* BLOCK_SIZE_4328 */); - fn_ints |= INTR_CTL_FUNC2_EN; - } - - /* Enable/Disable Client interrupts */ - /* Turn on here but disable at host controller? */ - if (sdstd_card_regwrite(sd, 0, SDIOD_CCCR_INTEN, 1, - (fn_ints | INTR_CTL_MASTER_EN)) != SUCCESS) { - sd_err(("%s: Could not enable ints in CCCR\n", __FUNCTION__)); - return ERROR; - } - - /* Switch to High-speed clocking mode if both host and device support it */ - sdstd_set_highspeed_mode(sd, (bool)sd_hiok); - - /* After configuring for High-Speed mode, set the desired clock rate. */ - if (!sdstd_start_clock(sd, (uint16)sd_divisor)) { - sd_err(("sdstd_start_clock failed\n")); - return ERROR; - } - - sd->card_init_done = TRUE; - - return SUCCESS; -} - -static int -sdstd_set_highspeed_mode(sdioh_info_t *sd, bool HSMode) -{ - uint32 regdata; - int status; - uint8 reg8; - - reg8 = sdstd_rreg8(sd, SD_HostCntrl); - - - if (HSMode == TRUE) { - if (sd_hiok && (GFIELD(sd->caps, CAP_HIGHSPEED)) == 0) { - sd_err(("Host Controller does not support hi-speed mode.\n")); - return BCME_ERROR; - } - - sd_info(("Attempting to enable High-Speed mode.\n")); - - if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL, - 1, ®data)) != SUCCESS) { - return BCME_SDIO_ERROR; - } - if (regdata & SDIO_SPEED_SHS) { - sd_info(("Device supports High-Speed mode.\n")); - - regdata |= SDIO_SPEED_EHS; - - sd_info(("Writing %08x to Card at %08x\n", - regdata, SDIOD_CCCR_SPEED_CONTROL)); - if ((status = sdstd_card_regwrite(sd, 0, SDIOD_CCCR_SPEED_CONTROL, - 1, regdata)) != BCME_OK) { - return BCME_SDIO_ERROR; - } - - if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL, - 1, ®data)) != BCME_OK) { - return BCME_SDIO_ERROR; - } - - sd_info(("Read %08x to Card at %08x\n", regdata, SDIOD_CCCR_SPEED_CONTROL)); - - reg8 = SFIELD(reg8, HOST_HI_SPEED_EN, 1); - - sd_err(("High-speed clocking mode enabled.\n")); - } - else { - sd_err(("Device does not support High-Speed Mode.\n")); - reg8 = SFIELD(reg8, HOST_HI_SPEED_EN, 0); - } - } else { - /* Force off device bit */ - if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL, - 1, ®data)) != BCME_OK) { - return status; - } - if (regdata & SDIO_SPEED_EHS) { - regdata &= ~SDIO_SPEED_EHS; - if ((status = sdstd_card_regwrite(sd, 0, SDIOD_CCCR_SPEED_CONTROL, - 1, regdata)) != BCME_OK) { - return status; - } - } - - sd_err(("High-speed clocking mode disabled.\n")); - reg8 = SFIELD(reg8, HOST_HI_SPEED_EN, 0); - } - - sdstd_wreg8(sd, SD_HostCntrl, reg8); - - return BCME_OK; -} - -/* Select DMA Mode: - * If dma_mode == DMA_MODE_AUTO, pick the "best" mode. - * Otherwise, pick the selected mode if supported. - * If not supported, use PIO mode. - */ -static int -sdstd_set_dma_mode(sdioh_info_t *sd, int8 dma_mode) -{ - uint8 reg8, dma_sel_bits = SDIOH_SDMA_MODE; - int8 prev_dma_mode = sd->sd_dma_mode; - - switch (prev_dma_mode) { - case DMA_MODE_AUTO: - sd_dma(("%s: Selecting best DMA mode supported by controller.\n", - __FUNCTION__)); - if (GFIELD(sd->caps, CAP_ADMA2)) { - sd->sd_dma_mode = DMA_MODE_ADMA2; - dma_sel_bits = SDIOH_ADMA2_MODE; - } else if (GFIELD(sd->caps, CAP_ADMA1)) { - sd->sd_dma_mode = DMA_MODE_ADMA1; - dma_sel_bits = SDIOH_ADMA1_MODE; - } else if (GFIELD(sd->caps, CAP_DMA)) { - sd->sd_dma_mode = DMA_MODE_SDMA; - } else { - sd->sd_dma_mode = DMA_MODE_NONE; - } - break; - case DMA_MODE_NONE: - sd->sd_dma_mode = DMA_MODE_NONE; - break; - case DMA_MODE_SDMA: - if (GFIELD(sd->caps, CAP_DMA)) { - sd->sd_dma_mode = DMA_MODE_SDMA; - } else { - sd_err(("%s: SDMA not supported by controller.\n", __FUNCTION__)); - sd->sd_dma_mode = DMA_MODE_NONE; - } - break; - case DMA_MODE_ADMA1: - if (GFIELD(sd->caps, CAP_ADMA1)) { - sd->sd_dma_mode = DMA_MODE_ADMA1; - dma_sel_bits = SDIOH_ADMA1_MODE; - } else { - sd_err(("%s: ADMA1 not supported by controller.\n", __FUNCTION__)); - sd->sd_dma_mode = DMA_MODE_NONE; - } - break; - case DMA_MODE_ADMA2: - if (GFIELD(sd->caps, CAP_ADMA2)) { - sd->sd_dma_mode = DMA_MODE_ADMA2; - dma_sel_bits = SDIOH_ADMA2_MODE; - } else { - sd_err(("%s: ADMA2 not supported by controller.\n", __FUNCTION__)); - sd->sd_dma_mode = DMA_MODE_NONE; - } - break; - case DMA_MODE_ADMA2_64: - sd_err(("%s: 64b ADMA2 not supported by driver.\n", __FUNCTION__)); - sd->sd_dma_mode = DMA_MODE_NONE; - break; - default: - sd_err(("%s: Unsupported DMA Mode %d requested.\n", __FUNCTION__, - prev_dma_mode)); - sd->sd_dma_mode = DMA_MODE_NONE; - break; - } - - /* clear SysAddr, only used for SDMA */ - sdstd_wreg(sd, SD_SysAddr, 0); - - sd_err(("%s: %s mode selected.\n", __FUNCTION__, dma_mode_description[sd->sd_dma_mode])); - - reg8 = sdstd_rreg8(sd, SD_HostCntrl); - reg8 = SFIELD(reg8, HOST_DMA_SEL, dma_sel_bits); - sdstd_wreg8(sd, SD_HostCntrl, reg8); - sd_dma(("%s: SD_HostCntrl=0x%02x\n", __FUNCTION__, reg8)); - - return BCME_OK; -} - - -bool -sdstd_start_clock(sdioh_info_t *sd, uint16 new_sd_divisor) -{ - uint rc, count; - uint16 divisor; - - /* turn off HC clock */ - sdstd_wreg16(sd, SD_ClockCntrl, - sdstd_rreg16(sd, SD_ClockCntrl) & ~((uint16)0x4)); /* Disable the HC clock */ - - /* Set divisor */ - - divisor = (new_sd_divisor >> 1) << 8; - - sd_info(("Clock control is 0x%x\n", sdstd_rreg16(sd, SD_ClockCntrl))); - sdstd_mod_reg16(sd, SD_ClockCntrl, 0xff00, divisor); - sd_info(("%s: Using clock divisor of %d (regval 0x%04x)\n", __FUNCTION__, - new_sd_divisor, divisor)); - - sd_info(("Primary Clock Freq = %d MHz\n", GFIELD(sd->caps, CAP_TO_CLKFREQ))); - - if (GFIELD(sd->caps, CAP_TO_CLKFREQ) == 50) { - sd_info(("%s: Resulting SDIO clock is %d %s\n", __FUNCTION__, - ((50 % new_sd_divisor) ? (50000 / new_sd_divisor) : (50 / new_sd_divisor)), - ((50 % new_sd_divisor) ? "KHz" : "MHz"))); - } else if (GFIELD(sd->caps, CAP_TO_CLKFREQ) == 48) { - sd_info(("%s: Resulting SDIO clock is %d %s\n", __FUNCTION__, - ((48 % new_sd_divisor) ? (48000 / new_sd_divisor) : (48 / new_sd_divisor)), - ((48 % new_sd_divisor) ? "KHz" : "MHz"))); - } else if (GFIELD(sd->caps, CAP_TO_CLKFREQ) == 33) { - sd_info(("%s: Resulting SDIO clock is %d %s\n", __FUNCTION__, - ((33 % new_sd_divisor) ? (33000 / new_sd_divisor) : (33 / new_sd_divisor)), - ((33 % new_sd_divisor) ? "KHz" : "MHz"))); - - } else if (sd->controller_type == SDIOH_TYPE_BCM27XX) { - } else { - sd_err(("Need to determine divisor for %d MHz clocks\n", - GFIELD(sd->caps, CAP_TO_CLKFREQ))); - sd_err(("Consult SD Host Controller Spec: Clock Control Register\n")); - return (FALSE); - } - - sdstd_or_reg16(sd, SD_ClockCntrl, 0x1); /* Enable the clock */ - - /* Wait for clock to stabilize */ - rc = (sdstd_rreg16(sd, SD_ClockCntrl) & 2); - count = 0; - while (!rc) { - OSL_DELAY(1); - sd_info(("Waiting for clock to become stable 0x%x\n", rc)); - rc = (sdstd_rreg16(sd, SD_ClockCntrl) & 2); - count++; - if (count > 10000) { - sd_err(("%s:Clocks failed to stabilize after %u attempts", - __FUNCTION__, count)); - return (FALSE); - } - } - /* Turn on clock */ - sdstd_or_reg16(sd, SD_ClockCntrl, 0x4); - - /* Set timeout control (adjust default value based on divisor). - * Disabling timeout interrupts during setting is advised by host spec. - */ - { - uint16 regdata; - uint toval; - - toval = sd_toctl; - divisor = new_sd_divisor; - - while (toval && !(divisor & 1)) { - toval -= 1; - divisor >>= 1; - } - - regdata = sdstd_rreg16(sd, SD_ErrorIntrStatusEnable); - sdstd_wreg16(sd, SD_ErrorIntrStatusEnable, (regdata & ~ERRINT_DATA_TIMEOUT_BIT)); - sdstd_wreg8(sd, SD_TimeoutCntrl, (uint8)toval); - sdstd_wreg16(sd, SD_ErrorIntrStatusEnable, regdata); - } - - OSL_DELAY(2); - - sd_info(("Final Clock control is 0x%x\n", sdstd_rreg16(sd, SD_ClockCntrl))); - - return TRUE; -} - -bool -sdstd_start_power(sdioh_info_t *sd) -{ - char *s; - uint32 cmd_arg; - uint32 cmd_rsp; - uint8 pwr = 0; - int volts; - - volts = 0; - s = NULL; - if (GFIELD(sd->caps, CAP_VOLT_1_8)) { - volts = 5; - s = "1.8"; - } - if (GFIELD(sd->caps, CAP_VOLT_3_0)) { - volts = 6; - s = "3.0"; - } - if (GFIELD(sd->caps, CAP_VOLT_3_3)) { - volts = 7; - s = "3.3"; - } - - pwr = SFIELD(pwr, PWR_VOLTS, volts); - pwr = SFIELD(pwr, PWR_BUS_EN, 1); - sdstd_wreg8(sd, SD_PwrCntrl, pwr); /* Set Voltage level */ - sd_info(("Setting Bus Power to %s Volts\n", s)); - - /* Wait for power to stabilize, Dongle takes longer than NIC. */ - OSL_DELAY(250000); - - /* Get the Card's Operation Condition. Occasionally the board - * takes a while to become ready - */ - cmd_arg = 0; - cmd_rsp = 0; - if (get_ocr(sd, &cmd_arg, &cmd_rsp) != SUCCESS) { - sd_err(("%s: Failed to get OCR bailing\n", __FUNCTION__)); - sdstd_reset(sd, 0, 1); - return FALSE; - } - - sd_info(("mem_present = %d\n", GFIELD(cmd_rsp, RSP4_MEM_PRESENT))); - sd_info(("num_funcs = %d\n", GFIELD(cmd_rsp, RSP4_NUM_FUNCS))); - sd_info(("card_ready = %d\n", GFIELD(cmd_rsp, RSP4_CARD_READY))); - sd_info(("OCR = 0x%x\n", GFIELD(cmd_rsp, RSP4_IO_OCR))); - - /* Verify that the card supports I/O mode */ - if (GFIELD(cmd_rsp, RSP4_NUM_FUNCS) == 0) { - sd_err(("%s: Card does not support I/O\n", __FUNCTION__)); - return ERROR; - } - sd->num_funcs = GFIELD(cmd_rsp, RSP4_NUM_FUNCS); - - /* Examine voltage: Arasan only supports 3.3 volts, - * so look for 3.2-3.3 Volts and also 3.3-3.4 volts. - */ - - if ((GFIELD(cmd_rsp, RSP4_IO_OCR) & (0x3 << 20)) == 0) { - sd_err(("This client does not support 3.3 volts!\n")); - return ERROR; - } - sd_info(("Leaving bus power at 3.3 Volts\n")); - - cmd_arg = SFIELD(0, CMD5_OCR, 0xfff000); - cmd_rsp = 0; - get_ocr(sd, &cmd_arg, &cmd_rsp); - sd_info(("OCR = 0x%x\n", GFIELD(cmd_rsp, RSP4_IO_OCR))); - return TRUE; -} - -bool -sdstd_bus_width(sdioh_info_t *sd, int new_mode) -{ - uint32 regdata; - int status; - uint8 reg8; - - sd_trace(("%s\n", __FUNCTION__)); - if (sd->sd_mode == new_mode) { - sd_info(("%s: Already at width %d\n", __FUNCTION__, new_mode)); - /* Could exit, but continue just in case... */ - } - - /* Set client side via reg 0x7 in CCCR */ - if ((status = sdstd_card_regread (sd, 0, SDIOD_CCCR_BICTRL, 1, ®data)) != SUCCESS) - return (bool)status; - regdata &= ~BUS_SD_DATA_WIDTH_MASK; - if (new_mode == SDIOH_MODE_SD4) { - sd_info(("Changing to SD4 Mode\n")); - regdata |= SD4_MODE; - } else if (new_mode == SDIOH_MODE_SD1) { - sd_info(("Changing to SD1 Mode\n")); - } else { - sd_err(("SPI Mode not supported by Standard Host Controller\n")); - } - - if ((status = sdstd_card_regwrite (sd, 0, SDIOD_CCCR_BICTRL, 1, regdata)) != SUCCESS) - return (bool)status; - - /* Set host side via Host reg */ - reg8 = sdstd_rreg8(sd, SD_HostCntrl) & ~SD4_MODE; - if (new_mode == SDIOH_MODE_SD4) - reg8 |= SD4_MODE; - sdstd_wreg8(sd, SD_HostCntrl, reg8); - - sd->sd_mode = new_mode; - - return TRUE; -} - -static int -sdstd_driver_init(sdioh_info_t *sd) -{ - sd_trace(("%s\n", __FUNCTION__)); - if ((sdstd_host_init(sd)) != SUCCESS) { - return ERROR; - } - - if (sdstd_client_init(sd) != SUCCESS) { - return ERROR; - } - - return SUCCESS; -} - -static int -sdstd_get_cisaddr(sdioh_info_t *sd, uint32 regaddr) -{ - /* read 24 bits and return valid 17 bit addr */ - int i; - uint32 scratch, regdata; - uint8 *ptr = (uint8 *)&scratch; - for (i = 0; i < 3; i++) { - if ((sdstd_card_regread (sd, 0, regaddr, 1, ®data)) != SUCCESS) - sd_err(("%s: Can't read!\n", __FUNCTION__)); - - *ptr++ = (uint8) regdata; - regaddr++; - } - /* Only the lower 17-bits are valid */ - scratch = ltoh32(scratch); - scratch &= 0x0001FFFF; - return (scratch); -} - -static int -sdstd_card_enablefuncs(sdioh_info_t *sd) -{ - int status; - uint32 regdata; - uint32 fbraddr; - uint8 func; - - sd_trace(("%s\n", __FUNCTION__)); - - /* Get the Card's common CIS address */ - sd->com_cis_ptr = sdstd_get_cisaddr(sd, SDIOD_CCCR_CISPTR_0); - sd->func_cis_ptr[0] = sd->com_cis_ptr; - sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __FUNCTION__, sd->com_cis_ptr)); - - /* Get the Card's function CIS (for each function) */ - for (fbraddr = SDIOD_FBR_STARTADDR, func = 1; - func <= sd->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) { - sd->func_cis_ptr[func] = sdstd_get_cisaddr(sd, SDIOD_FBR_CISPTR_0 + fbraddr); - sd_info(("%s: Function %d CIS Ptr = 0x%x\n", - __FUNCTION__, func, sd->func_cis_ptr[func])); - } - - /* Enable function 1 on the card */ - regdata = SDIO_FUNC_ENABLE_1; - if ((status = sdstd_card_regwrite(sd, 0, SDIOD_CCCR_IOEN, 1, regdata)) != SUCCESS) - return status; - - return SUCCESS; -} - -/* Read client card reg */ -static int -sdstd_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data) -{ - int status; - uint32 cmd_arg; - uint32 rsp5; - - - cmd_arg = 0; - - if ((func == 0) || (regsize == 1)) { - cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, SDIOH_XFER_TYPE_READ); - cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0); - cmd_arg = SFIELD(cmd_arg, CMD52_DATA, 0); - - if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_52, cmd_arg)) - != SUCCESS) - return status; - - sdstd_cmd_getrsp(sd, &rsp5, 1); - if (sdstd_rreg16(sd, SD_ErrorIntrStatus) != 0) { - sd_err(("%s: 1: ErrorintrStatus 0x%x\n", - __FUNCTION__, sdstd_rreg16(sd, SD_ErrorIntrStatus))); - } - - if (GFIELD(rsp5, RSP5_FLAGS) != 0x10) - sd_err(("%s: rsp5 flags is 0x%x\t %d\n", - __FUNCTION__, GFIELD(rsp5, RSP5_FLAGS), func)); - - if (GFIELD(rsp5, RSP5_STUFF)) - sd_err(("%s: rsp5 stuff is 0x%x: should be 0\n", - __FUNCTION__, GFIELD(rsp5, RSP5_STUFF))); - *data = GFIELD(rsp5, RSP5_DATA); - } else { - cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, regsize); - cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 1); - cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 0); - cmd_arg = SFIELD(cmd_arg, CMD53_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD53_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_READ); - - sd->data_xfer_count = regsize; - - /* sdstd_cmd_issue() returns with the command complete bit - * in the ISR already cleared - */ - if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_53, cmd_arg)) - != SUCCESS) - return status; - - sdstd_cmd_getrsp(sd, &rsp5, 1); - - if (GFIELD(rsp5, RSP5_FLAGS) != 0x10) - sd_err(("%s: rsp5 flags is 0x%x\t %d\n", - __FUNCTION__, GFIELD(rsp5, RSP5_FLAGS), func)); - - if (GFIELD(rsp5, RSP5_STUFF)) - sd_err(("%s: rsp5 stuff is 0x%x: should be 0\n", - __FUNCTION__, GFIELD(rsp5, RSP5_STUFF))); - - if (sd->polled_mode) { - volatile uint16 int_reg; - int retries = RETRIES_LARGE; - - /* Wait for Read Buffer to become ready */ - do { - int_reg = sdstd_rreg16(sd, SD_IntrStatus); - } while (--retries && (GFIELD(int_reg, INTSTAT_BUF_READ_READY) == 0)); - - if (!retries) { - sd_err(("%s: Timeout on Buf_Read_Ready: " - "intStat: 0x%x errint: 0x%x PresentState 0x%x\n", - __FUNCTION__, int_reg, - sdstd_rreg16(sd, SD_ErrorIntrStatus), - sdstd_rreg(sd, SD_PresentState))); - sdstd_check_errs(sd, SDIOH_CMD_53, cmd_arg); - return (ERROR); - } - - /* Have Buffer Ready, so clear it and read the data */ - sdstd_wreg16(sd, SD_IntrStatus, SFIELD(0, INTSTAT_BUF_READ_READY, 1)); - if (regsize == 2) - *data = sdstd_rreg16(sd, SD_BufferDataPort0); - else - *data = sdstd_rreg(sd, SD_BufferDataPort0); - - /* Check Status. - * After the data is read, the Transfer Complete bit should be on - */ - retries = RETRIES_LARGE; - do { - int_reg = sdstd_rreg16(sd, SD_IntrStatus); - } while (--retries && (GFIELD(int_reg, INTSTAT_XFER_COMPLETE) == 0)); - - /* Check for any errors from the data phase */ - if (sdstd_check_errs(sd, SDIOH_CMD_53, cmd_arg)) - return ERROR; - - if (!retries) { - sd_err(("%s: Timeout on xfer complete: " - "intr 0x%04x err 0x%04x state 0x%08x\n", - __FUNCTION__, int_reg, - sdstd_rreg16(sd, SD_ErrorIntrStatus), - sdstd_rreg(sd, SD_PresentState))); - return (ERROR); - } - - sdstd_wreg16(sd, SD_IntrStatus, SFIELD(0, INTSTAT_XFER_COMPLETE, 1)); - } - } - if (sd->polled_mode) { - if (regsize == 2) - *data &= 0xffff; - } - return SUCCESS; -} - -bool -check_client_intr(sdioh_info_t *sd) -{ - uint16 raw_int, cur_int, old_int; - - raw_int = sdstd_rreg16(sd, SD_IntrStatus); - cur_int = raw_int & sd->intmask; - - if (!cur_int) { - /* Not an error -- might share interrupts... */ - return FALSE; - } - - if (GFIELD(cur_int, INTSTAT_CARD_INT)) { - old_int = sdstd_rreg16(sd, SD_IntrStatusEnable); - sdstd_wreg16(sd, SD_IntrStatusEnable, SFIELD(old_int, INTSTAT_CARD_INT, 0)); - - if (sd->client_intr_enabled && sd->use_client_ints) { - sd->intrcount++; - ASSERT(sd->intr_handler); - ASSERT(sd->intr_handler_arg); - (sd->intr_handler)(sd->intr_handler_arg); - } else { - sd_err(("%s: Not ready for intr: enabled %d, handler %p\n", - __FUNCTION__, sd->client_intr_enabled, sd->intr_handler)); - } - sdstd_wreg16(sd, SD_IntrStatusEnable, old_int); - } else { - /* Local interrupt: disable, set flag, and save intrstatus */ - sdstd_wreg16(sd, SD_IntrSignalEnable, 0); - sdstd_wreg16(sd, SD_ErrorIntrSignalEnable, 0); - sd->local_intrcount++; - sd->got_hcint = TRUE; - sd->last_intrstatus = cur_int; - } - - return TRUE; -} - -void -sdstd_spinbits(sdioh_info_t *sd, uint16 norm, uint16 err) -{ - uint16 int_reg, err_reg; - int retries = RETRIES_LARGE; - - do { - int_reg = sdstd_rreg16(sd, SD_IntrStatus); - err_reg = sdstd_rreg16(sd, SD_ErrorIntrStatus); - } while (--retries && !(int_reg & norm) && !(err_reg & err)); - - norm |= sd->intmask; - if (err_reg & err) - norm = SFIELD(norm, INTSTAT_ERROR_INT, 1); - sd->last_intrstatus = int_reg & norm; -} - -/* write a client register */ -static int -sdstd_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 data) -{ - int status; - uint32 cmd_arg, rsp5, flags; - - cmd_arg = 0; - - if ((func == 0) || (regsize == 1)) { - cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, SDIOH_XFER_TYPE_WRITE); - cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0); - cmd_arg = SFIELD(cmd_arg, CMD52_DATA, data & 0xff); - if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_52, cmd_arg)) - != SUCCESS) - return status; - - sdstd_cmd_getrsp(sd, &rsp5, 1); - flags = GFIELD(rsp5, RSP5_FLAGS); - if (flags && (flags != 0x10)) - sd_err(("%s: rsp5.rsp5.flags = 0x%x, expecting 0x10\n", - __FUNCTION__, flags)); - } - else { - cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, regsize); - cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 1); - cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 0); - cmd_arg = SFIELD(cmd_arg, CMD53_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD53_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_WRITE); - - sd->data_xfer_count = regsize; - - /* sdstd_cmd_issue() returns with the command complete bit - * in the ISR already cleared - */ - if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_53, cmd_arg)) - != SUCCESS) - return status; - - sdstd_cmd_getrsp(sd, &rsp5, 1); - - if (GFIELD(rsp5, RSP5_FLAGS) != 0x10) - sd_err(("%s: rsp5 flags = 0x%x, expecting 0x10\n", - __FUNCTION__, GFIELD(rsp5, RSP5_FLAGS))); - if (GFIELD(rsp5, RSP5_STUFF)) - sd_err(("%s: rsp5 stuff is 0x%x: expecting 0\n", - __FUNCTION__, GFIELD(rsp5, RSP5_STUFF))); - - if (sd->polled_mode) { - uint16 int_reg; - int retries = RETRIES_LARGE; - - /* Wait for Write Buffer to become ready */ - do { - int_reg = sdstd_rreg16(sd, SD_IntrStatus); - } while (--retries && (GFIELD(int_reg, INTSTAT_BUF_WRITE_READY) == 0)); - - if (!retries) { - sd_err(("%s: Timeout on Buf_Write_Ready: intStat: 0x%x " - "errint: 0x%x PresentState 0x%x\n", - __FUNCTION__, int_reg, - sdstd_rreg16(sd, SD_ErrorIntrStatus), - sdstd_rreg(sd, SD_PresentState))); - sdstd_check_errs(sd, SDIOH_CMD_53, cmd_arg); - return (ERROR); - } - /* Clear Write Buf Ready bit */ - int_reg = 0; - int_reg = SFIELD(int_reg, INTSTAT_BUF_WRITE_READY, 1); - sdstd_wreg16(sd, SD_IntrStatus, int_reg); - - /* At this point we have Buffer Ready, so write the data */ - if (regsize == 2) - sdstd_wreg16(sd, SD_BufferDataPort0, (uint16) data); - else - sdstd_wreg(sd, SD_BufferDataPort0, data); - - /* Wait for Transfer Complete */ - retries = RETRIES_LARGE; - do { - int_reg = sdstd_rreg16(sd, SD_IntrStatus); - } while (--retries && (GFIELD(int_reg, INTSTAT_XFER_COMPLETE) == 0)); - - /* Check for any errors from the data phase */ - if (sdstd_check_errs(sd, SDIOH_CMD_53, cmd_arg)) - return ERROR; - - if (retries == 0) { - sd_err(("%s: Timeout for xfer complete; State = 0x%x, " - "intr state=0x%x, Errintstatus 0x%x rcnt %d, tcnt %d\n", - __FUNCTION__, sdstd_rreg(sd, SD_PresentState), - int_reg, sdstd_rreg16(sd, SD_ErrorIntrStatus), - sd->r_cnt, sd->t_cnt)); - } - /* Clear the status bits */ - sdstd_wreg16(sd, SD_IntrStatus, SFIELD(int_reg, INTSTAT_CARD_INT, 0)); - } - } - return SUCCESS; -} - -void -sdstd_cmd_getrsp(sdioh_info_t *sd, uint32 *rsp_buffer, int count /* num 32 bit words */) -{ - int rsp_count; - int respaddr = SD_Response0; - - if (count > 4) - count = 4; - - for (rsp_count = 0; rsp_count < count; rsp_count++) { - *rsp_buffer++ = sdstd_rreg(sd, respaddr); - respaddr += 4; - } -} - -static int -sdstd_cmd_issue(sdioh_info_t *sdioh_info, bool use_dma, uint32 cmd, uint32 arg) -{ - uint16 cmd_reg; - int retries; - uint32 cmd_arg; - uint16 xfer_reg = 0; - - - if ((sdioh_info->sd_mode == SDIOH_MODE_SPI) && - ((cmd == SDIOH_CMD_3) || (cmd == SDIOH_CMD_7) || (cmd == SDIOH_CMD_15))) { - sd_err(("%s: Cmd %d is not for SPI\n", __FUNCTION__, cmd)); - return ERROR; - } - - retries = RETRIES_SMALL; - while ((GFIELD(sdstd_rreg(sdioh_info, SD_PresentState), PRES_CMD_INHIBIT)) && --retries) { - if (retries == RETRIES_SMALL) - sd_err(("%s: Waiting for Command Inhibit cmd = %d 0x%x\n", - __FUNCTION__, cmd, sdstd_rreg(sdioh_info, SD_PresentState))); - } - if (!retries) { - sd_err(("%s: Command Inhibit timeout\n", __FUNCTION__)); - if (trap_errs) - ASSERT(0); - return ERROR; - } - - - cmd_reg = 0; - switch (cmd) { - case SDIOH_CMD_0: /* Set Card to Idle State - No Response */ - sd_data(("%s: CMD%d\n", __FUNCTION__, cmd)); - cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_NONE); - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd); - break; - - case SDIOH_CMD_3: /* Ask card to send RCA - Response R6 */ - sd_data(("%s: CMD%d\n", __FUNCTION__, cmd)); - cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48); - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd); - break; - - case SDIOH_CMD_5: /* Send Operation condition - Response R4 */ - sd_data(("%s: CMD%d\n", __FUNCTION__, cmd)); - cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48); - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd); - break; - - case SDIOH_CMD_7: /* Select card - Response R1 */ - sd_data(("%s: CMD%d\n", __FUNCTION__, cmd)); - cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48); - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 1); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 1); - cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd); - break; - - case SDIOH_CMD_15: /* Set card to inactive state - Response None */ - sd_data(("%s: CMD%d\n", __FUNCTION__, cmd)); - cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_NONE); - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd); - break; - - case SDIOH_CMD_52: /* IO R/W Direct (single byte) - Response R5 */ - - sd_data(("%s: CMD52 func(%d) addr(0x%x) %s data(0x%x)\n", - __FUNCTION__, - GFIELD(arg, CMD52_FUNCTION), - GFIELD(arg, CMD52_REG_ADDR), - GFIELD(arg, CMD52_RW_FLAG) ? "W" : "R", - GFIELD(arg, CMD52_DATA))); - - cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48); - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 1); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 1); - cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd); - break; - - case SDIOH_CMD_53: /* IO R/W Extended (multiple bytes/blocks) */ - - sd_data(("%s: CMD53 func(%d) addr(0x%x) %s mode(%s) cnt(%d), %s\n", - __FUNCTION__, - GFIELD(arg, CMD53_FUNCTION), - GFIELD(arg, CMD53_REG_ADDR), - GFIELD(arg, CMD53_RW_FLAG) ? "W" : "R", - GFIELD(arg, CMD53_BLK_MODE) ? "Block" : "Byte", - GFIELD(arg, CMD53_BYTE_BLK_CNT), - GFIELD(arg, CMD53_OP_CODE) ? "Incrementing addr" : "Single addr")); - - cmd_arg = arg; - xfer_reg = 0; - - cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48); - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 1); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 1); - cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 1); - cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd); - - use_dma = USE_DMA(sdioh_info) && GFIELD(cmd_arg, CMD53_BLK_MODE); - - if (GFIELD(cmd_arg, CMD53_BLK_MODE)) { - uint16 blocksize; - uint16 blockcount; - int func; - - ASSERT(sdioh_info->sd_blockmode); - - func = GFIELD(cmd_arg, CMD53_FUNCTION); - blocksize = MIN((int)sdioh_info->data_xfer_count, - sdioh_info->client_block_size[func]); - blockcount = GFIELD(cmd_arg, CMD53_BYTE_BLK_CNT); - - /* data_xfer_cnt is already setup so that for multiblock mode, - * it is the entire buffer length. For non-block or single block, - * it is < 64 bytes - */ - if (use_dma) { - switch (sdioh_info->sd_dma_mode) { - case DMA_MODE_SDMA: - sd_dma(("%s: SDMA: SysAddr reg was 0x%x now 0x%x\n", - __FUNCTION__, sdstd_rreg(sdioh_info, SD_SysAddr), - (uint32)sdioh_info->dma_phys)); - sdstd_wreg(sdioh_info, SD_SysAddr, sdioh_info->dma_phys); - break; - case DMA_MODE_ADMA1: - case DMA_MODE_ADMA2: - sd_dma(("%s: ADMA: Using ADMA\n", __FUNCTION__)); - sd_create_adma_descriptor(sdioh_info, 0, - sdioh_info->dma_phys, blockcount*blocksize, - ADMA2_ATTRIBUTE_VALID | ADMA2_ATTRIBUTE_END | - ADMA2_ATTRIBUTE_INT | ADMA2_ATTRIBUTE_ACT_TRAN); - /* Dump descriptor if DMA debugging is enabled. */ - if (sd_msglevel & SDH_DMA_VAL) { - sd_dump_adma_dscr(sdioh_info); - } - - sdstd_wreg(sdioh_info, SD_ADMA_SysAddr, - sdioh_info->adma2_dscr_phys); - break; - default: - sd_err(("%s: unsupported DMA mode %d.\n", - __FUNCTION__, sdioh_info->sd_dma_mode)); - break; - } - } - - sd_trace(("%s: Setting block count %d, block size %d bytes\n", - __FUNCTION__, blockcount, blocksize)); - sdstd_wreg16(sdioh_info, SD_BlockSize, blocksize); - sdstd_wreg16(sdioh_info, SD_BlockCount, blockcount); - - xfer_reg = SFIELD(xfer_reg, XFER_DMA_ENABLE, use_dma); - - if (sdioh_info->client_block_size[func] != blocksize) - set_client_block_size(sdioh_info, 1, blocksize); - - if (blockcount > 1) { - xfer_reg = SFIELD(xfer_reg, XFER_MULTI_BLOCK, 1); - xfer_reg = SFIELD(xfer_reg, XFER_BLK_COUNT_EN, 1); - xfer_reg = SFIELD(xfer_reg, XFER_CMD_12_EN, 0); - } else { - xfer_reg = SFIELD(xfer_reg, XFER_MULTI_BLOCK, 0); - xfer_reg = SFIELD(xfer_reg, XFER_BLK_COUNT_EN, 0); - xfer_reg = SFIELD(xfer_reg, XFER_CMD_12_EN, 0); - } - - if (GFIELD(cmd_arg, CMD53_RW_FLAG) == SDIOH_XFER_TYPE_READ) - xfer_reg = SFIELD(xfer_reg, XFER_DATA_DIRECTION, 1); - else - xfer_reg = SFIELD(xfer_reg, XFER_DATA_DIRECTION, 0); - - retries = RETRIES_SMALL; - while (GFIELD(sdstd_rreg(sdioh_info, SD_PresentState), - PRES_DAT_INHIBIT) && --retries) - sd_err(("%s: Waiting for Data Inhibit cmd = %d\n", - __FUNCTION__, cmd)); - if (!retries) { - sd_err(("%s: Data Inhibit timeout\n", __FUNCTION__)); - if (trap_errs) - ASSERT(0); - return ERROR; - } - sdstd_wreg16(sdioh_info, SD_TransferMode, xfer_reg); - - } else { /* Non block mode */ - uint16 bytes = GFIELD(cmd_arg, CMD53_BYTE_BLK_CNT); - /* The byte/block count field only has 9 bits, - * so, to do a 512-byte bytemode transfer, this - * field will contain 0, but we need to tell the - * controller we're transferring 512 bytes. - */ - if (bytes == 0) bytes = 512; - - if (use_dma) - sdstd_wreg(sdioh_info, SD_SysAddr, sdioh_info->dma_phys); - - /* PCI: Transfer Mode register 0x0c */ - xfer_reg = SFIELD(xfer_reg, XFER_DMA_ENABLE, bytes <= 4 ? 0 : use_dma); - xfer_reg = SFIELD(xfer_reg, XFER_CMD_12_EN, 0); - if (GFIELD(cmd_arg, CMD53_RW_FLAG) == SDIOH_XFER_TYPE_READ) - xfer_reg = SFIELD(xfer_reg, XFER_DATA_DIRECTION, 1); - else - xfer_reg = SFIELD(xfer_reg, XFER_DATA_DIRECTION, 0); - /* See table 2-8 Host Controller spec ver 1.00 */ - xfer_reg = SFIELD(xfer_reg, XFER_BLK_COUNT_EN, 0); /* Dont care */ - xfer_reg = SFIELD(xfer_reg, XFER_MULTI_BLOCK, 0); - - sdstd_wreg16(sdioh_info, SD_BlockSize, bytes); - - sdstd_wreg16(sdioh_info, SD_BlockCount, 1); - - retries = RETRIES_SMALL; - while (GFIELD(sdstd_rreg(sdioh_info, SD_PresentState), - PRES_DAT_INHIBIT) && --retries) - sd_err(("%s: Waiting for Data Inhibit cmd = %d\n", - __FUNCTION__, cmd)); - if (!retries) { - sd_err(("%s: Data Inhibit timeout\n", __FUNCTION__)); - if (trap_errs) - ASSERT(0); - return ERROR; - } - sdstd_wreg16(sdioh_info, SD_TransferMode, xfer_reg); - } - break; - - default: - sd_err(("%s: Unknown command\n", __FUNCTION__)); - return ERROR; - } - - if (sdioh_info->sd_mode == SDIOH_MODE_SPI) { - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0); - } - - /* Setup and issue the SDIO command */ - sdstd_wreg(sdioh_info, SD_Arg0, arg); - sdstd_wreg16(sdioh_info, SD_Command, cmd_reg); - - /* If we are in polled mode, wait for the command to complete. - * In interrupt mode, return immediately. The calling function will - * know that the command has completed when the CMDATDONE interrupt - * is asserted - */ - if (sdioh_info->polled_mode) { - uint16 int_reg = 0; - int retries = RETRIES_LARGE; - - do { - int_reg = sdstd_rreg16(sdioh_info, SD_IntrStatus); - } while (--retries && - (GFIELD(int_reg, INTSTAT_ERROR_INT) == 0) && - (GFIELD(int_reg, INTSTAT_CMD_COMPLETE) == 0)); - - if (!retries) { - sd_err(("%s: CMD_COMPLETE timeout: intrStatus: 0x%x " - "error stat 0x%x state 0x%x\n", - __FUNCTION__, int_reg, - sdstd_rreg16(sdioh_info, SD_ErrorIntrStatus), - sdstd_rreg(sdioh_info, SD_PresentState))); - - /* Attempt to reset CMD line when we get a CMD timeout */ - sdstd_wreg8(sdioh_info, SD_SoftwareReset, SFIELD(0, SW_RESET_CMD, 1)); - retries = RETRIES_LARGE; - do { - sd_trace(("%s: waiting for CMD line reset\n", __FUNCTION__)); - } while ((GFIELD(sdstd_rreg8(sdioh_info, SD_SoftwareReset), - SW_RESET_CMD)) && retries--); - - if (!retries) { - sd_err(("%s: Timeout waiting for CMD line reset\n", __FUNCTION__)); - } - - if (trap_errs) - ASSERT(0); - return (ERROR); - } - - /* Clear Command Complete interrupt */ - int_reg = SFIELD(0, INTSTAT_CMD_COMPLETE, 1); - sdstd_wreg16(sdioh_info, SD_IntrStatus, int_reg); - - /* Check for Errors */ - if (sdstd_check_errs(sdioh_info, cmd, arg)) { - if (trap_errs) - ASSERT(0); - return ERROR; - } - } - return SUCCESS; -} - - -static int -sdstd_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo, uint32 addr, int nbytes, uint32 *data) -{ - int status; - uint32 cmd_arg; - uint32 rsp5; - uint16 int_reg, int_bit; - uint flags; - int num_blocks, blocksize; - bool local_blockmode, local_dma; - bool read = rw == SDIOH_READ ? 1 : 0; - bool yield = FALSE; - - ASSERT(nbytes); - - cmd_arg = 0; - - sd_data(("%s: %s 53 addr 0x%x, len %d bytes, r_cnt %d t_cnt %d\n", - __FUNCTION__, read ? "Rd" : "Wr", addr, nbytes, sd->r_cnt, sd->t_cnt)); - - if (read) sd->r_cnt++; else sd->t_cnt++; - - local_blockmode = sd->sd_blockmode; - local_dma = USE_DMA(sd); - - /* Don't bother with block mode on small xfers */ - if (nbytes < sd->client_block_size[func]) { - sd_data(("setting local blockmode to false: nbytes (%d) != block_size (%d)\n", - nbytes, sd->client_block_size[func])); - local_blockmode = FALSE; - local_dma = FALSE; - } - - if (local_blockmode) { - blocksize = MIN(sd->client_block_size[func], nbytes); - num_blocks = nbytes/blocksize; - cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, num_blocks); - cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 1); - } else { - num_blocks = 1; - blocksize = nbytes; - cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, nbytes); - cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 0); - } - - if (local_dma && !read) { - bcopy(data, sd->dma_buf, nbytes); - sd_sync_dma(sd, read, nbytes); - } - - if (fifo) - cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 0); - else - cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 1); - - cmd_arg = SFIELD(cmd_arg, CMD53_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD53_REG_ADDR, addr); - if (read) - cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_READ); - else - cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_WRITE); - - sd->data_xfer_count = nbytes; - - /* sdstd_cmd_issue() returns with the command complete bit - * in the ISR already cleared - */ - if ((status = sdstd_cmd_issue(sd, local_dma, SDIOH_CMD_53, cmd_arg)) != SUCCESS) { - sd_err(("%s: cmd_issue failed for %s\n", __FUNCTION__, (read ? "read" : "write"))); - return status; - } - - sdstd_cmd_getrsp(sd, &rsp5, 1); - - if ((flags = GFIELD(rsp5, RSP5_FLAGS)) != 0x10) { - sd_err(("%s: Rsp5: nbytes %d, dma %d blockmode %d, read %d " - "numblocks %d, blocksize %d\n", - __FUNCTION__, nbytes, local_dma, local_dma, read, num_blocks, blocksize)); - - if (flags & 1) - sd_err(("%s: rsp5: Command not accepted: arg out of range 0x%x, " - "bytes %d dma %d\n", - __FUNCTION__, flags, GFIELD(cmd_arg, CMD53_BYTE_BLK_CNT), - GFIELD(cmd_arg, CMD53_BLK_MODE))); - if (flags & 0x8) - sd_err(("%s: Rsp5: General Error\n", __FUNCTION__)); - - sd_err(("%s: rsp5 flags = 0x%x, expecting 0x10 returning error\n", - __FUNCTION__, flags)); - if (trap_errs) - ASSERT(0); - return ERROR; - } - - if (GFIELD(rsp5, RSP5_STUFF)) - sd_err(("%s: rsp5 stuff is 0x%x: expecting 0\n", - __FUNCTION__, GFIELD(rsp5, RSP5_STUFF))); - -#ifdef BCMSDYIELD - yield = sd_yieldcpu && ((uint)nbytes >= sd_minyield); -#endif - - if (!local_dma) { - int bytes, i; - uint32 tmp; - for (i = 0; i < num_blocks; i++) { - int words; - - /* Decide which status bit we're waiting for */ - if (read) - int_bit = SFIELD(0, INTSTAT_BUF_READ_READY, 1); - else - int_bit = SFIELD(0, INTSTAT_BUF_WRITE_READY, 1); - - /* If not on, wait for it (or for xfer error) */ - int_reg = sdstd_rreg16(sd, SD_IntrStatus); - if (!(int_reg & int_bit)) - int_reg = sdstd_waitbits(sd, int_bit, ERRINT_TRANSFER_ERRS, yield); - - /* Confirm we got the bit w/o error */ - if (!(int_reg & int_bit) || GFIELD(int_reg, INTSTAT_ERROR_INT)) { - sd_err(("%s: Error or timeout for Buf_%s_Ready: intStat: 0x%x " - "errint: 0x%x PresentState 0x%x\n", - __FUNCTION__, read ? "Read" : "Write", int_reg, - sdstd_rreg16(sd, SD_ErrorIntrStatus), - sdstd_rreg(sd, SD_PresentState))); - sdstd_dumpregs(sd); - sdstd_check_errs(sd, SDIOH_CMD_53, cmd_arg); - return (ERROR); - } - - /* Clear Buf Ready bit */ - sdstd_wreg16(sd, SD_IntrStatus, int_bit); - - /* At this point we have Buffer Ready, write the data 4 bytes at a time */ - for (words = blocksize/4; words; words--) { - if (read) - *data = sdstd_rreg(sd, SD_BufferDataPort0); - else - sdstd_wreg(sd, SD_BufferDataPort0, *data); - data++; - } - - bytes = blocksize % 4; - - /* If no leftover bytes, go to next block */ - if (!bytes) - continue; - - switch (bytes) { - case 1: - /* R/W 8 bits */ - if (read) - *(data++) = (uint32)(sdstd_rreg8(sd, SD_BufferDataPort0)); - else - sdstd_wreg8(sd, SD_BufferDataPort0, - (uint8)(*(data++) & 0xff)); - break; - case 2: - /* R/W 16 bits */ - if (read) - *(data++) = (uint32)sdstd_rreg16(sd, SD_BufferDataPort0); - else - sdstd_wreg16(sd, SD_BufferDataPort0, (uint16)(*(data++))); - break; - case 3: - /* R/W 24 bits: - * SD_BufferDataPort0[0-15] | SD_BufferDataPort1[16-23] - */ - if (read) { - tmp = (uint32)sdstd_rreg16(sd, SD_BufferDataPort0); - tmp |= ((uint32)(sdstd_rreg8(sd, - SD_BufferDataPort1)) << 16); - *(data++) = tmp; - } else { - tmp = *(data++); - sdstd_wreg16(sd, SD_BufferDataPort0, (uint16)tmp & 0xffff); - sdstd_wreg8(sd, SD_BufferDataPort1, - (uint8)((tmp >> 16) & 0xff)); - } - break; - default: - sd_err(("%s: Unexpected bytes leftover %d\n", - __FUNCTION__, bytes)); - ASSERT(0); - break; - } - } - } /* End PIO processing */ - - /* Wait for Transfer Complete or Transfer Error */ - int_bit = SFIELD(0, INTSTAT_XFER_COMPLETE, 1); - - /* If not on, wait for it (or for xfer error) */ - int_reg = sdstd_rreg16(sd, SD_IntrStatus); - if (!(int_reg & int_bit)) - int_reg = sdstd_waitbits(sd, int_bit, ERRINT_TRANSFER_ERRS, yield); - - /* Check for any errors from the data phase */ - if (sdstd_check_errs(sd, SDIOH_CMD_53, cmd_arg)) - return ERROR; - - /* May have gotten a software timeout if not blocking? */ - int_reg = sdstd_rreg16(sd, SD_IntrStatus); - if (!(int_reg & int_bit)) { - sd_err(("%s: Error or Timeout for xfer complete; %s, dma %d, State 0x%08x, " - "intr 0x%04x, Err 0x%04x, len = %d, rcnt %d, tcnt %d\n", - __FUNCTION__, read ? "R" : "W", local_dma, - sdstd_rreg(sd, SD_PresentState), int_reg, - sdstd_rreg16(sd, SD_ErrorIntrStatus), nbytes, - sd->r_cnt, sd->t_cnt)); - sdstd_dumpregs(sd); - return ERROR; - } - - /* Clear the status bits */ - int_reg = int_bit; - if (local_dma) { - /* DMA Complete */ - /* Reads in particular don't have DMA_COMPLETE set */ - int_reg = SFIELD(int_reg, INTSTAT_DMA_INT, 1); - } - sdstd_wreg16(sd, SD_IntrStatus, int_reg); - - /* Fetch data */ - if (local_dma && read) { - sd_sync_dma(sd, read, nbytes); - bcopy(sd->dma_buf, data, nbytes); - } - return SUCCESS; -} - -static int -set_client_block_size(sdioh_info_t *sd, int func, int block_size) -{ - int base; - int err = 0; - - - sd_err(("%s: Setting block size %d, func %d\n", __FUNCTION__, block_size, func)); - sd->client_block_size[func] = block_size; - - /* Set the block size in the SDIO Card register */ - base = func * SDIOD_FBR_SIZE; - err = sdstd_card_regwrite(sd, 0, base+SDIOD_CCCR_BLKSIZE_0, 1, block_size & 0xff); - if (!err) { - err = sdstd_card_regwrite(sd, 0, base+SDIOD_CCCR_BLKSIZE_1, 1, - (block_size >> 8) & 0xff); - } - - /* Do not set the block size in the SDIO Host register, that - * is func dependent and will get done on an individual - * transaction basis - */ - - return (err ? BCME_SDIO_ERROR : 0); -} - -/* Reset and re-initialize the device */ -int -sdioh_sdio_reset(sdioh_info_t *si) -{ - uint8 hreg; - - /* Reset the attached device (use slower clock for safety) */ - sdstd_start_clock(si, 128); - sdstd_reset(si, 0, 1); - - /* Reset portions of the host state accordingly */ - hreg = sdstd_rreg8(si, SD_HostCntrl); - hreg = SFIELD(hreg, HOST_HI_SPEED_EN, 0); - hreg = SFIELD(hreg, HOST_DATA_WIDTH, 0); - si->sd_mode = SDIOH_MODE_SD1; - - /* Reinitialize the card */ - si->card_init_done = FALSE; - return sdstd_client_init(si); -} - - -static void -sd_map_dma(sdioh_info_t * sd) -{ - - void *va; - - if ((va = DMA_ALLOC_CONSISTENT(sd->osh, SD_PAGE, - &sd->dma_start_phys, 0x12, 12)) == NULL) { - sd->sd_dma_mode = DMA_MODE_NONE; - sd->dma_start_buf = 0; - sd->dma_buf = (void *)0; - sd->dma_phys = 0; - sd->alloced_dma_size = SD_PAGE; - sd_err(("%s: DMA_ALLOC failed. Disabling DMA support.\n", __FUNCTION__)); - } else { - sd->dma_start_buf = va; - sd->dma_buf = (void *)ROUNDUP((uintptr)va, SD_PAGE); - sd->dma_phys = ROUNDUP((sd->dma_start_phys), SD_PAGE); - sd->alloced_dma_size = SD_PAGE; - sd_err(("%s: Mapped DMA Buffer %dbytes @virt/phys: %p/0x%lx\n", - __FUNCTION__, sd->alloced_dma_size, sd->dma_buf, sd->dma_phys)); - sd_fill_dma_data_buf(sd, 0xA5); - } - - if ((va = DMA_ALLOC_CONSISTENT(sd->osh, SD_PAGE, - &sd->adma2_dscr_start_phys, 0x12, 12)) == NULL) { - sd->sd_dma_mode = DMA_MODE_NONE; - sd->adma2_dscr_start_buf = 0; - sd->adma2_dscr_buf = (void *)0; - sd->adma2_dscr_phys = 0; - sd->alloced_adma2_dscr_size = 0; - sd_err(("%s: DMA_ALLOC failed for descriptor buffer. " - "Disabling DMA support.\n", __FUNCTION__)); - } else { - sd->adma2_dscr_start_buf = va; - sd->adma2_dscr_buf = (void *)ROUNDUP((uintptr)va, SD_PAGE); - sd->adma2_dscr_phys = ROUNDUP((sd->adma2_dscr_start_phys), SD_PAGE); - sd->alloced_adma2_dscr_size = SD_PAGE; - } - - sd_err(("%s: Mapped ADMA2 Descriptor Buffer %dbytes @virt/phys: %p/0x%lx\n", - __FUNCTION__, sd->alloced_adma2_dscr_size, sd->adma2_dscr_buf, - sd->adma2_dscr_phys)); - sd_clear_adma_dscr_buf(sd); -} - -static void -sd_unmap_dma(sdioh_info_t * sd) -{ - if (sd->dma_start_buf) { - DMA_FREE_CONSISTENT(sd->osh, sd->dma_start_buf, sd->alloced_dma_size, - sd->dma_start_phys, 0x12); - } - - if (sd->adma2_dscr_start_buf) { - DMA_FREE_CONSISTENT(sd->osh, sd->adma2_dscr_start_buf, sd->alloced_adma2_dscr_size, - sd->adma2_dscr_start_phys, 0x12); - } -} - -static void sd_clear_adma_dscr_buf(sdioh_info_t *sd) -{ - bzero((char *)sd->adma2_dscr_buf, SD_PAGE); - sd_dump_adma_dscr(sd); -} - -static void sd_fill_dma_data_buf(sdioh_info_t *sd, uint8 data) -{ - memset((char *)sd->dma_buf, data, SD_PAGE); -} - - -static void sd_create_adma_descriptor(sdioh_info_t *sd, uint32 index, - uint32 addr_phys, uint16 length, uint16 flags) -{ - adma2_dscr_32b_t *adma2_dscr_table; - adma1_dscr_t *adma1_dscr_table; - - adma2_dscr_table = sd->adma2_dscr_buf; - adma1_dscr_table = sd->adma2_dscr_buf; - - switch (sd->sd_dma_mode) { - case DMA_MODE_ADMA2: - sd_dma(("%s: creating ADMA2 descriptor for index %d\n", - __FUNCTION__, index)); - - adma2_dscr_table[index].phys_addr = addr_phys; - adma2_dscr_table[index].len_attr = length << 16; - adma2_dscr_table[index].len_attr |= flags; - break; - case DMA_MODE_ADMA1: - /* ADMA1 requires two descriptors, one for len - * and the other for data transfer - */ - index <<= 1; - - sd_dma(("%s: creating ADMA1 descriptor for index %d\n", - __FUNCTION__, index)); - - adma1_dscr_table[index].phys_addr_attr = length << 12; - adma1_dscr_table[index].phys_addr_attr |= (ADMA1_ATTRIBUTE_ACT_SET | - ADMA2_ATTRIBUTE_VALID); - adma1_dscr_table[index+1].phys_addr_attr = addr_phys & 0xFFFFF000; - adma1_dscr_table[index+1].phys_addr_attr |= (flags & 0x3f); - break; - default: - sd_err(("%s: cannot create ADMA descriptor for DMA mode %d\n", - __FUNCTION__, sd->sd_dma_mode)); - break; - } -} - - -static void sd_dump_adma_dscr(sdioh_info_t *sd) -{ - adma2_dscr_32b_t *adma2_dscr_table; - adma1_dscr_t *adma1_dscr_table; - uint32 i = 0; - uint16 flags; - char flags_str[32]; - - ASSERT(sd->adma2_dscr_buf != NULL); - - adma2_dscr_table = sd->adma2_dscr_buf; - adma1_dscr_table = sd->adma2_dscr_buf; - - switch (sd->sd_dma_mode) { - case DMA_MODE_ADMA2: - sd_err(("ADMA2 Descriptor Table (%dbytes) @virt/phys: %p/0x%lx\n", - SD_PAGE, sd->adma2_dscr_buf, sd->adma2_dscr_phys)); - sd_err((" #[Descr VA ] Buffer PA | Len | Flags (5:4 2 1 0)" - " |\n")); - while (adma2_dscr_table->len_attr & ADMA2_ATTRIBUTE_VALID) { - flags = adma2_dscr_table->len_attr & 0xFFFF; - sprintf(flags_str, "%s%s%s%s", - ((flags & ADMA2_ATTRIBUTE_ACT_LINK) == - ADMA2_ATTRIBUTE_ACT_LINK) ? "LINK " : - ((flags & ADMA2_ATTRIBUTE_ACT_LINK) == - ADMA2_ATTRIBUTE_ACT_TRAN) ? "TRAN " : - ((flags & ADMA2_ATTRIBUTE_ACT_LINK) == - ADMA2_ATTRIBUTE_ACT_NOP) ? "NOP " : "RSV ", - (flags & ADMA2_ATTRIBUTE_INT ? "INT " : " "), - (flags & ADMA2_ATTRIBUTE_END ? "END " : " "), - (flags & ADMA2_ATTRIBUTE_VALID ? "VALID" : "")); - sd_err(("%2d[0x%p]: 0x%08x | 0x%04x | 0x%04x (%s) |\n", - i, adma2_dscr_table, adma2_dscr_table->phys_addr, - adma2_dscr_table->len_attr >> 16, flags, flags_str)); - i++; - - /* Follow LINK descriptors or skip to next. */ - if ((flags & ADMA2_ATTRIBUTE_ACT_LINK) == - ADMA2_ATTRIBUTE_ACT_LINK) { - adma2_dscr_table = phys_to_virt( - adma2_dscr_table->phys_addr); - } else { - adma2_dscr_table++; - } - - } - break; - case DMA_MODE_ADMA1: - sd_err(("ADMA1 Descriptor Table (%dbytes) @virt/phys: %p/0x%lx\n", - SD_PAGE, sd->adma2_dscr_buf, sd->adma2_dscr_phys)); - sd_err((" #[Descr VA ] Buffer PA | Flags (5:4 2 1 0) |\n")); - - for (i = 0; adma1_dscr_table->phys_addr_attr & ADMA2_ATTRIBUTE_VALID; i++) { - flags = adma1_dscr_table->phys_addr_attr & 0x3F; - sprintf(flags_str, "%s%s%s%s", - ((flags & ADMA2_ATTRIBUTE_ACT_LINK) == - ADMA2_ATTRIBUTE_ACT_LINK) ? "LINK " : - ((flags & ADMA2_ATTRIBUTE_ACT_LINK) == - ADMA2_ATTRIBUTE_ACT_TRAN) ? "TRAN " : - ((flags & ADMA2_ATTRIBUTE_ACT_LINK) == - ADMA2_ATTRIBUTE_ACT_NOP) ? "NOP " : "SET ", - (flags & ADMA2_ATTRIBUTE_INT ? "INT " : " "), - (flags & ADMA2_ATTRIBUTE_END ? "END " : " "), - (flags & ADMA2_ATTRIBUTE_VALID ? "VALID" : "")); - sd_err(("%2d[0x%p]: 0x%08x | 0x%04x | (%s) |\n", - i, adma1_dscr_table, - adma1_dscr_table->phys_addr_attr & 0xFFFFF000, - flags, flags_str)); - - /* Follow LINK descriptors or skip to next. */ - if ((flags & ADMA2_ATTRIBUTE_ACT_LINK) == - ADMA2_ATTRIBUTE_ACT_LINK) { - adma1_dscr_table = phys_to_virt( - adma1_dscr_table->phys_addr_attr & 0xFFFFF000); - } else { - adma1_dscr_table++; - } - } - break; - default: - sd_err(("Unknown DMA Descriptor Table Format.\n")); - break; - } -} - -static void sdstd_dumpregs(sdioh_info_t *sd) -{ - sd_err(("IntrStatus: 0x%04x ErrorIntrStatus 0x%04x\n", - sdstd_rreg16(sd, SD_IntrStatus), - sdstd_rreg16(sd, SD_ErrorIntrStatus))); - sd_err(("IntrStatusEnable: 0x%04x ErrorIntrStatusEnable 0x%04x\n", - sdstd_rreg16(sd, SD_IntrStatusEnable), - sdstd_rreg16(sd, SD_ErrorIntrStatusEnable))); - sd_err(("IntrSignalEnable: 0x%04x ErrorIntrSignalEnable 0x%04x\n", - sdstd_rreg16(sd, SD_IntrSignalEnable), - sdstd_rreg16(sd, SD_ErrorIntrSignalEnable))); -} diff --git a/drivers/net/wireless/bcm4329/bcmsdstd_linux.c b/drivers/net/wireless/bcm4329/bcmsdstd_linux.c deleted file mode 100644 index a8b98e2054a0..000000000000 --- a/drivers/net/wireless/bcm4329/bcmsdstd_linux.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * 'Standard' SDIO HOST CONTROLLER driver - linux portion - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdstd_linux.c,v 1.11.18.2.16.1 2010/08/17 17:03:13 Exp $ - */ - -#include -#include -#include -#include /* SDIO Specs */ -#include /* bcmsdh to/from specific controller APIs */ -#include /* to get msglevel bit values */ - -#include /* request_irq() */ - -#include - -struct sdos_info { - sdioh_info_t *sd; - spinlock_t lock; - wait_queue_head_t intr_wait_queue; -}; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define BLOCKABLE() (!in_atomic()) -#else -#define BLOCKABLE() (!in_interrupt()) -#endif - -/* Interrupt handler */ -static irqreturn_t -sdstd_isr(int irq, void *dev_id -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) -, struct pt_regs *ptregs -#endif -) -{ - sdioh_info_t *sd; - struct sdos_info *sdos; - bool ours; - - sd = (sdioh_info_t *)dev_id; - - if (!sd->card_init_done) { - sd_err(("%s: Hey Bogus intr...not even initted: irq %d\n", __FUNCTION__, irq)); - return IRQ_RETVAL(FALSE); - } else { - ours = check_client_intr(sd); - - /* For local interrupts, wake the waiting process */ - if (ours && sd->got_hcint) { - sd_trace(("INTR->WAKE\n")); - sdos = (struct sdos_info *)sd->sdos_info; - wake_up_interruptible(&sdos->intr_wait_queue); - } - return IRQ_RETVAL(ours); - } -} - -/* Register with Linux for interrupts */ -int -sdstd_register_irq(sdioh_info_t *sd, uint irq) -{ - sd_trace(("Entering %s: irq == %d\n", __FUNCTION__, irq)); - if (request_irq(irq, sdstd_isr, IRQF_SHARED, "bcmsdstd", sd) < 0) { - sd_err(("%s: request_irq() failed\n", __FUNCTION__)); - return ERROR; - } - return SUCCESS; -} - -/* Free Linux irq */ -void -sdstd_free_irq(uint irq, sdioh_info_t *sd) -{ - free_irq(irq, sd); -} - -/* Map Host controller registers */ - -uint32 * -sdstd_reg_map(osl_t *osh, int32 addr, int size) -{ - return (uint32 *)REG_MAP(addr, size); -} - -void -sdstd_reg_unmap(osl_t *osh, int32 addr, int size) -{ - REG_UNMAP((void*)(uintptr)addr); -} - -int -sdstd_osinit(sdioh_info_t *sd) -{ - struct sdos_info *sdos; - - sdos = (struct sdos_info*)MALLOC(sd->osh, sizeof(struct sdos_info)); - sd->sdos_info = (void*)sdos; - if (sdos == NULL) - return BCME_NOMEM; - - sdos->sd = sd; - spin_lock_init(&sdos->lock); - init_waitqueue_head(&sdos->intr_wait_queue); - return BCME_OK; -} - -void -sdstd_osfree(sdioh_info_t *sd) -{ - struct sdos_info *sdos; - ASSERT(sd && sd->sdos_info); - - sdos = (struct sdos_info *)sd->sdos_info; - MFREE(sd->osh, sdos, sizeof(struct sdos_info)); -} - -/* Interrupt enable/disable */ -SDIOH_API_RC -sdioh_interrupt_set(sdioh_info_t *sd, bool enable) -{ - ulong flags; - struct sdos_info *sdos; - - sd_trace(("%s: %s\n", __FUNCTION__, enable ? "Enabling" : "Disabling")); - - sdos = (struct sdos_info *)sd->sdos_info; - ASSERT(sdos); - - if (!(sd->host_init_done && sd->card_init_done)) { - sd_err(("%s: Card & Host are not initted - bailing\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } - - if (enable && !(sd->intr_handler && sd->intr_handler_arg)) { - sd_err(("%s: no handler registered, will not enable\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } - - /* Ensure atomicity for enable/disable calls */ - spin_lock_irqsave(&sdos->lock, flags); - - sd->client_intr_enabled = enable; - if (enable && !sd->lockcount) - sdstd_devintr_on(sd); - else - sdstd_devintr_off(sd); - - spin_unlock_irqrestore(&sdos->lock, flags); - - return SDIOH_API_RC_SUCCESS; -} - -/* Protect against reentrancy (disable device interrupts while executing) */ -void -sdstd_lock(sdioh_info_t *sd) -{ - ulong flags; - struct sdos_info *sdos; - - sdos = (struct sdos_info *)sd->sdos_info; - ASSERT(sdos); - - sd_trace(("%s: %d\n", __FUNCTION__, sd->lockcount)); - - spin_lock_irqsave(&sdos->lock, flags); - if (sd->lockcount) { - sd_err(("%s: Already locked! called from %p\n", - __FUNCTION__, - __builtin_return_address(0))); - ASSERT(sd->lockcount == 0); - } - sdstd_devintr_off(sd); - sd->lockcount++; - spin_unlock_irqrestore(&sdos->lock, flags); -} - -/* Enable client interrupt */ -void -sdstd_unlock(sdioh_info_t *sd) -{ - ulong flags; - struct sdos_info *sdos; - - sd_trace(("%s: %d, %d\n", __FUNCTION__, sd->lockcount, sd->client_intr_enabled)); - ASSERT(sd->lockcount > 0); - - sdos = (struct sdos_info *)sd->sdos_info; - ASSERT(sdos); - - spin_lock_irqsave(&sdos->lock, flags); - if (--sd->lockcount == 0 && sd->client_intr_enabled) { - sdstd_devintr_on(sd); - } - spin_unlock_irqrestore(&sdos->lock, flags); -} - -uint16 -sdstd_waitbits(sdioh_info_t *sd, uint16 norm, uint16 err, bool yield) -{ - struct sdos_info *sdos; - - sdos = (struct sdos_info *)sd->sdos_info; - -#ifndef BCMSDYIELD - ASSERT(!yield); -#endif - sd_trace(("%s: int 0x%02x err 0x%02x yield %d canblock %d\n", - __FUNCTION__, norm, err, yield, BLOCKABLE())); - - /* Clear the "interrupt happened" flag and last intrstatus */ - sd->got_hcint = FALSE; - sd->last_intrstatus = 0; - -#ifdef BCMSDYIELD - if (yield && BLOCKABLE()) { - /* Enable interrupts, wait for the indication, then disable */ - sdstd_intrs_on(sd, norm, err); - wait_event_interruptible(sdos->intr_wait_queue, (sd->got_hcint)); - sdstd_intrs_off(sd, norm, err); - } else -#endif /* BCMSDYIELD */ - { - sdstd_spinbits(sd, norm, err); - } - - sd_trace(("%s: last_intrstatus 0x%04x\n", __FUNCTION__, sd->last_intrstatus)); - - return sd->last_intrstatus; -} diff --git a/drivers/net/wireless/bcm4329/bcmutils.c b/drivers/net/wireless/bcm4329/bcmutils.c deleted file mode 100644 index 43c04ee92f38..000000000000 --- a/drivers/net/wireless/bcm4329/bcmutils.c +++ /dev/null @@ -1,1838 +0,0 @@ -/* - * Driver O/S-independent utility routines - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * $Id: bcmutils.c,v 1.210.4.5.2.4.6.19 2010/04/26 06:05:25 Exp $ - */ - -#include -#include -#include -#include -#ifdef BCMDRIVER -#include -#include -#else -#include -#include -/* This case for external supplicant use */ -#if defined(BCMEXTSUP) -#include -#endif - -#endif /* BCMDRIVER */ -#include -#include -#include -#include -#include -#include -#include - - -#ifdef BCMDRIVER - - -/* copy a pkt buffer chain into a buffer */ -uint -pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) -{ - uint n, ret = 0; - - if (len < 0) - len = 4096; /* "infinite" */ - - /* skip 'offset' bytes */ - for (; p && offset; p = PKTNEXT(osh, p)) { - if (offset < (uint)PKTLEN(osh, p)) - break; - offset -= PKTLEN(osh, p); - } - - if (!p) - return 0; - - /* copy the data */ - for (; p && len; p = PKTNEXT(osh, p)) { - n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); - bcopy(PKTDATA(osh, p) + offset, buf, n); - buf += n; - len -= n; - ret += n; - offset = 0; - } - - return ret; -} - -/* copy a buffer into a pkt buffer chain */ -uint -pktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf) -{ - uint n, ret = 0; - - /* skip 'offset' bytes */ - for (; p && offset; p = PKTNEXT(osh, p)) { - if (offset < (uint)PKTLEN(osh, p)) - break; - offset -= PKTLEN(osh, p); - } - - if (!p) - return 0; - - /* copy the data */ - for (; p && len; p = PKTNEXT(osh, p)) { - n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); - bcopy(buf, PKTDATA(osh, p) + offset, n); - buf += n; - len -= n; - ret += n; - offset = 0; - } - - return ret; -} - - - -/* return total length of buffer chain */ -uint -pkttotlen(osl_t *osh, void *p) -{ - uint total; - - total = 0; - for (; p; p = PKTNEXT(osh, p)) - total += PKTLEN(osh, p); - return (total); -} - -/* return the last buffer of chained pkt */ -void * -pktlast(osl_t *osh, void *p) -{ - for (; PKTNEXT(osh, p); p = PKTNEXT(osh, p)) - ; - - return (p); -} - -/* count segments of a chained packet */ -uint -pktsegcnt(osl_t *osh, void *p) -{ - uint cnt; - - for (cnt = 0; p; p = PKTNEXT(osh, p)) - cnt++; - - return cnt; -} - - -/* - * osl multiple-precedence packet queue - * hi_prec is always >= the number of the highest non-empty precedence - */ -void * -pktq_penq(struct pktq *pq, int prec, void *p) -{ - struct pktq_prec *q; - - ASSERT(prec >= 0 && prec < pq->num_prec); - ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ - - ASSERT(!pktq_full(pq)); - ASSERT(!pktq_pfull(pq, prec)); - - q = &pq->q[prec]; - - if (q->head) - PKTSETLINK(q->tail, p); - else - q->head = p; - - q->tail = p; - q->len++; - - pq->len++; - - if (pq->hi_prec < prec) - pq->hi_prec = (uint8)prec; - - return p; -} - -void * -pktq_penq_head(struct pktq *pq, int prec, void *p) -{ - struct pktq_prec *q; - - ASSERT(prec >= 0 && prec < pq->num_prec); - ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ - - ASSERT(!pktq_full(pq)); - ASSERT(!pktq_pfull(pq, prec)); - - q = &pq->q[prec]; - - if (q->head == NULL) - q->tail = p; - - PKTSETLINK(p, q->head); - q->head = p; - q->len++; - - pq->len++; - - if (pq->hi_prec < prec) - pq->hi_prec = (uint8)prec; - - return p; -} - -void * -pktq_pdeq(struct pktq *pq, int prec) -{ - struct pktq_prec *q; - void *p; - - ASSERT(prec >= 0 && prec < pq->num_prec); - - q = &pq->q[prec]; - - if ((p = q->head) == NULL) - return NULL; - - if ((q->head = PKTLINK(p)) == NULL) - q->tail = NULL; - - q->len--; - - pq->len--; - - PKTSETLINK(p, NULL); - - return p; -} - -void * -pktq_pdeq_tail(struct pktq *pq, int prec) -{ - struct pktq_prec *q; - void *p, *prev; - - ASSERT(prec >= 0 && prec < pq->num_prec); - - q = &pq->q[prec]; - - if ((p = q->head) == NULL) - return NULL; - - for (prev = NULL; p != q->tail; p = PKTLINK(p)) - prev = p; - - if (prev) - PKTSETLINK(prev, NULL); - else - q->head = NULL; - - q->tail = prev; - q->len--; - - pq->len--; - - return p; -} - -void -pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir) -{ - struct pktq_prec *q; - void *p; - - q = &pq->q[prec]; - p = q->head; - while (p) { - q->head = PKTLINK(p); - PKTSETLINK(p, NULL); - PKTFREE(osh, p, dir); - q->len--; - pq->len--; - p = q->head; - } - ASSERT(q->len == 0); - q->tail = NULL; -} - -bool -pktq_pdel(struct pktq *pq, void *pktbuf, int prec) -{ - struct pktq_prec *q; - void *p; - - ASSERT(prec >= 0 && prec < pq->num_prec); - - if (!pktbuf) - return FALSE; - - q = &pq->q[prec]; - - if (q->head == pktbuf) { - if ((q->head = PKTLINK(pktbuf)) == NULL) - q->tail = NULL; - } else { - for (p = q->head; p && PKTLINK(p) != pktbuf; p = PKTLINK(p)) - ; - if (p == NULL) - return FALSE; - - PKTSETLINK(p, PKTLINK(pktbuf)); - if (q->tail == pktbuf) - q->tail = p; - } - - q->len--; - pq->len--; - PKTSETLINK(pktbuf, NULL); - return TRUE; -} - -void -pktq_init(struct pktq *pq, int num_prec, int max_len) -{ - int prec; - - ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC); - - /* pq is variable size; only zero out what's requested */ - bzero(pq, OFFSETOF(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec)); - - pq->num_prec = (uint16)num_prec; - - pq->max = (uint16)max_len; - - for (prec = 0; prec < num_prec; prec++) - pq->q[prec].max = pq->max; -} - -void * -pktq_deq(struct pktq *pq, int *prec_out) -{ - struct pktq_prec *q; - void *p; - int prec; - - if (pq->len == 0) - return NULL; - - while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) - pq->hi_prec--; - - q = &pq->q[prec]; - - if ((p = q->head) == NULL) - return NULL; - - if ((q->head = PKTLINK(p)) == NULL) - q->tail = NULL; - - q->len--; - - pq->len--; - - if (prec_out) - *prec_out = prec; - - PKTSETLINK(p, NULL); - - return p; -} - -void * -pktq_deq_tail(struct pktq *pq, int *prec_out) -{ - struct pktq_prec *q; - void *p, *prev; - int prec; - - if (pq->len == 0) - return NULL; - - for (prec = 0; prec < pq->hi_prec; prec++) - if (pq->q[prec].head) - break; - - q = &pq->q[prec]; - - if ((p = q->head) == NULL) - return NULL; - - for (prev = NULL; p != q->tail; p = PKTLINK(p)) - prev = p; - - if (prev) - PKTSETLINK(prev, NULL); - else - q->head = NULL; - - q->tail = prev; - q->len--; - - pq->len--; - - if (prec_out) - *prec_out = prec; - - PKTSETLINK(p, NULL); - - return p; -} - -void * -pktq_peek(struct pktq *pq, int *prec_out) -{ - int prec; - - if (pq->len == 0) - return NULL; - - while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) - pq->hi_prec--; - - if (prec_out) - *prec_out = prec; - - return (pq->q[prec].head); -} - -void * -pktq_peek_tail(struct pktq *pq, int *prec_out) -{ - int prec; - - if (pq->len == 0) - return NULL; - - for (prec = 0; prec < pq->hi_prec; prec++) - if (pq->q[prec].head) - break; - - if (prec_out) - *prec_out = prec; - - return (pq->q[prec].tail); -} - -void -pktq_flush(osl_t *osh, struct pktq *pq, bool dir) -{ - int prec; - for (prec = 0; prec < pq->num_prec; prec++) - pktq_pflush(osh, pq, prec, dir); - ASSERT(pq->len == 0); -} - -/* Return sum of lengths of a specific set of precedences */ -int -pktq_mlen(struct pktq *pq, uint prec_bmp) -{ - int prec, len; - - len = 0; - - for (prec = 0; prec <= pq->hi_prec; prec++) - if (prec_bmp & (1 << prec)) - len += pq->q[prec].len; - - return len; -} - -/* Priority dequeue from a specific set of precedences */ -void * -pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out) -{ - struct pktq_prec *q; - void *p; - int prec; - - if (pq->len == 0) - return NULL; - - while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) - pq->hi_prec--; - - while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) - if (prec-- == 0) - return NULL; - - q = &pq->q[prec]; - - if ((p = q->head) == NULL) - return NULL; - - if ((q->head = PKTLINK(p)) == NULL) - q->tail = NULL; - - q->len--; - - if (prec_out) - *prec_out = prec; - - pq->len--; - - PKTSETLINK(p, NULL); - - return p; -} -#endif /* BCMDRIVER */ - - - -const unsigned char bcm_ctype[] = { - _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ - _BCM_C, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C, - _BCM_C, /* 8-15 */ - _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */ - _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */ - _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */ - _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */ - _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */ - _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */ - _BCM_P, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, - _BCM_U|_BCM_X, _BCM_U, /* 64-71 */ - _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */ - _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */ - _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */ - _BCM_P, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, - _BCM_L|_BCM_X, _BCM_L, /* 96-103 */ - _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */ - _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */ - _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128-143 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 144-159 */ - _BCM_S|_BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, - _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 160-175 */ - _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, - _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 176-191 */ - _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, - _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 192-207 */ - _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_U, _BCM_U, _BCM_U, - _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L, /* 208-223 */ - _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, - _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 224-239 */ - _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_L, _BCM_L, _BCM_L, - _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L /* 240-255 */ -}; - -ulong -bcm_strtoul(char *cp, char **endp, uint base) -{ - ulong result, last_result = 0, value; - bool minus; - - minus = FALSE; - - while (bcm_isspace(*cp)) - cp++; - - if (cp[0] == '+') - cp++; - else if (cp[0] == '-') { - minus = TRUE; - cp++; - } - - if (base == 0) { - if (cp[0] == '0') { - if ((cp[1] == 'x') || (cp[1] == 'X')) { - base = 16; - cp = &cp[2]; - } else { - base = 8; - cp = &cp[1]; - } - } else - base = 10; - } else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) { - cp = &cp[2]; - } - - result = 0; - - while (bcm_isxdigit(*cp) && - (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) { - result = result*base + value; - /* Detected overflow */ - if (result < last_result && !minus) - return (ulong)-1; - last_result = result; - cp++; - } - - if (minus) - result = (ulong)(-(long)result); - - if (endp) - *endp = (char *)cp; - - return (result); -} - -int -bcm_atoi(char *s) -{ - return (int)bcm_strtoul(s, NULL, 10); -} - -/* return pointer to location of substring 'needle' in 'haystack' */ -char* -bcmstrstr(char *haystack, char *needle) -{ - int len, nlen; - int i; - - if ((haystack == NULL) || (needle == NULL)) - return (haystack); - - nlen = strlen(needle); - len = strlen(haystack) - nlen + 1; - - for (i = 0; i < len; i++) - if (memcmp(needle, &haystack[i], nlen) == 0) - return (&haystack[i]); - return (NULL); -} - -char* -bcmstrcat(char *dest, const char *src) -{ - char *p; - - p = dest + strlen(dest); - - while ((*p++ = *src++) != '\0') - ; - - return (dest); -} - -char* -bcmstrncat(char *dest, const char *src, uint size) -{ - char *endp; - char *p; - - p = dest + strlen(dest); - endp = p + size; - - while (p != endp && (*p++ = *src++) != '\0') - ; - - return (dest); -} - - -/**************************************************************************** -* Function: bcmstrtok -* -* Purpose: -* Tokenizes a string. This function is conceptually similiar to ANSI C strtok(), -* but allows strToken() to be used by different strings or callers at the same -* time. Each call modifies '*string' by substituting a NULL character for the -* first delimiter that is encountered, and updates 'string' to point to the char -* after the delimiter. Leading delimiters are skipped. -* -* Parameters: -* string (mod) Ptr to string ptr, updated by token. -* delimiters (in) Set of delimiter characters. -* tokdelim (out) Character that delimits the returned token. (May -* be set to NULL if token delimiter is not required). -* -* Returns: Pointer to the next token found. NULL when no more tokens are found. -***************************************************************************** -*/ -char * -bcmstrtok(char **string, const char *delimiters, char *tokdelim) -{ - unsigned char *str; - unsigned long map[8]; - int count; - char *nextoken; - - if (tokdelim != NULL) { - /* Prime the token delimiter */ - *tokdelim = '\0'; - } - - /* Clear control map */ - for (count = 0; count < 8; count++) { - map[count] = 0; - } - - /* Set bits in delimiter table */ - do { - map[*delimiters >> 5] |= (1 << (*delimiters & 31)); - } - while (*delimiters++); - - str = (unsigned char*)*string; - - /* Find beginning of token (skip over leading delimiters). Note that - * there is no token iff this loop sets str to point to the terminal - * null (*str == '\0') - */ - while (((map[*str >> 5] & (1 << (*str & 31))) && *str) || (*str == ' ')) { - str++; - } - - nextoken = (char*)str; - - /* Find the end of the token. If it is not the end of the string, - * put a null there. - */ - for (; *str; str++) { - if (map[*str >> 5] & (1 << (*str & 31))) { - if (tokdelim != NULL) { - *tokdelim = *str; - } - - *str++ = '\0'; - break; - } - } - - *string = (char*)str; - - /* Determine if a token has been found. */ - if (nextoken == (char *) str) { - return NULL; - } - else { - return nextoken; - } -} - - -#define xToLower(C) \ - ((C >= 'A' && C <= 'Z') ? (char)((int)C - (int)'A' + (int)'a') : C) - - -/**************************************************************************** -* Function: bcmstricmp -* -* Purpose: Compare to strings case insensitively. -* -* Parameters: s1 (in) First string to compare. -* s2 (in) Second string to compare. -* -* Returns: Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if -* t1 > t2, when ignoring case sensitivity. -***************************************************************************** -*/ -int -bcmstricmp(const char *s1, const char *s2) -{ - char dc, sc; - - while (*s2 && *s1) { - dc = xToLower(*s1); - sc = xToLower(*s2); - if (dc < sc) return -1; - if (dc > sc) return 1; - s1++; - s2++; - } - - if (*s1 && !*s2) return 1; - if (!*s1 && *s2) return -1; - return 0; -} - - -/**************************************************************************** -* Function: bcmstrnicmp -* -* Purpose: Compare to strings case insensitively, upto a max of 'cnt' -* characters. -* -* Parameters: s1 (in) First string to compare. -* s2 (in) Second string to compare. -* cnt (in) Max characters to compare. -* -* Returns: Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if -* t1 > t2, when ignoring case sensitivity. -***************************************************************************** -*/ -int -bcmstrnicmp(const char* s1, const char* s2, int cnt) -{ - char dc, sc; - - while (*s2 && *s1 && cnt) { - dc = xToLower(*s1); - sc = xToLower(*s2); - if (dc < sc) return -1; - if (dc > sc) return 1; - s1++; - s2++; - cnt--; - } - - if (!cnt) return 0; - if (*s1 && !*s2) return 1; - if (!*s1 && *s2) return -1; - return 0; -} - -/* parse a xx:xx:xx:xx:xx:xx format ethernet address */ -int -bcm_ether_atoe(char *p, struct ether_addr *ea) -{ - int i = 0; - - for (;;) { - ea->octet[i++] = (char) bcm_strtoul(p, &p, 16); - if (!*p++ || i == 6) - break; - } - - return (i == 6); -} - - -#if defined(CONFIG_USBRNDIS_RETAIL) || defined(NDIS_MINIPORT_DRIVER) -/* registry routine buffer preparation utility functions: - * parameter order is like strncpy, but returns count - * of bytes copied. Minimum bytes copied is null char(1)/wchar(2) - */ -ulong -wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen) -{ - ulong copyct = 1; - ushort i; - - if (abuflen == 0) - return 0; - - /* wbuflen is in bytes */ - wbuflen /= sizeof(ushort); - - for (i = 0; i < wbuflen; ++i) { - if (--abuflen == 0) - break; - *abuf++ = (char) *wbuf++; - ++copyct; - } - *abuf = '\0'; - - return copyct; -} -#endif /* CONFIG_USBRNDIS_RETAIL || NDIS_MINIPORT_DRIVER */ - -char * -bcm_ether_ntoa(const struct ether_addr *ea, char *buf) -{ - static const char template[] = "%02x:%02x:%02x:%02x:%02x:%02x"; - snprintf(buf, 18, template, - ea->octet[0]&0xff, ea->octet[1]&0xff, ea->octet[2]&0xff, - ea->octet[3]&0xff, ea->octet[4]&0xff, ea->octet[5]&0xff); - return (buf); -} - -char * -bcm_ip_ntoa(struct ipv4_addr *ia, char *buf) -{ - snprintf(buf, 16, "%d.%d.%d.%d", - ia->addr[0], ia->addr[1], ia->addr[2], ia->addr[3]); - return (buf); -} - -#ifdef BCMDRIVER - -void -bcm_mdelay(uint ms) -{ - uint i; - - for (i = 0; i < ms; i++) { - OSL_DELAY(1000); - } -} - - - - - - -#if defined(DHD_DEBUG) -/* pretty hex print a pkt buffer chain */ -void -prpkt(const char *msg, osl_t *osh, void *p0) -{ - void *p; - - if (msg && (msg[0] != '\0')) - printf("%s:\n", msg); - - for (p = p0; p; p = PKTNEXT(osh, p)) - prhex(NULL, PKTDATA(osh, p), PKTLEN(osh, p)); -} -#endif - -/* Takes an Ethernet frame and sets out-of-bound PKTPRIO. - * Also updates the inplace vlan tag if requested. - * For debugging, it returns an indication of what it did. - */ -uint -pktsetprio(void *pkt, bool update_vtag) -{ - struct ether_header *eh; - struct ethervlan_header *evh; - uint8 *pktdata; - int priority = 0; - int rc = 0; - - pktdata = (uint8 *) PKTDATA(NULL, pkt); - ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16))); - - eh = (struct ether_header *) pktdata; - - if (ntoh16(eh->ether_type) == ETHER_TYPE_8021Q) { - uint16 vlan_tag; - int vlan_prio, dscp_prio = 0; - - evh = (struct ethervlan_header *)eh; - - vlan_tag = ntoh16(evh->vlan_tag); - vlan_prio = (int) (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK; - - if (ntoh16(evh->ether_type) == ETHER_TYPE_IP) { - uint8 *ip_body = pktdata + sizeof(struct ethervlan_header); - uint8 tos_tc = IP_TOS(ip_body); - dscp_prio = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); - } - - /* DSCP priority gets precedence over 802.1P (vlan tag) */ - if (dscp_prio != 0) { - priority = dscp_prio; - rc |= PKTPRIO_VDSCP; - } else { - priority = vlan_prio; - rc |= PKTPRIO_VLAN; - } - /* - * If the DSCP priority is not the same as the VLAN priority, - * then overwrite the priority field in the vlan tag, with the - * DSCP priority value. This is required for Linux APs because - * the VLAN driver on Linux, overwrites the skb->priority field - * with the priority value in the vlan tag - */ - if (update_vtag && (priority != vlan_prio)) { - vlan_tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT); - vlan_tag |= (uint16)priority << VLAN_PRI_SHIFT; - evh->vlan_tag = hton16(vlan_tag); - rc |= PKTPRIO_UPD; - } - } else if (ntoh16(eh->ether_type) == ETHER_TYPE_IP) { - uint8 *ip_body = pktdata + sizeof(struct ether_header); - uint8 tos_tc = IP_TOS(ip_body); - priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); - rc |= PKTPRIO_DSCP; - } - - ASSERT(priority >= 0 && priority <= MAXPRIO); - PKTSETPRIO(pkt, priority); - return (rc | priority); -} - -static char bcm_undeferrstr[BCME_STRLEN]; - -static const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE; - -/* Convert the error codes into related error strings */ -const char * -bcmerrorstr(int bcmerror) -{ - /* check if someone added a bcmerror code but forgot to add errorstring */ - ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1)); - - if (bcmerror > 0 || bcmerror < BCME_LAST) { - snprintf(bcm_undeferrstr, BCME_STRLEN, "Undefined error %d", bcmerror); - return bcm_undeferrstr; - } - - ASSERT(strlen(bcmerrorstrtable[-bcmerror]) < BCME_STRLEN); - - return bcmerrorstrtable[-bcmerror]; -} - - - -/* iovar table lookup */ -const bcm_iovar_t* -bcm_iovar_lookup(const bcm_iovar_t *table, const char *name) -{ - const bcm_iovar_t *vi; - const char *lookup_name; - - /* skip any ':' delimited option prefixes */ - lookup_name = strrchr(name, ':'); - if (lookup_name != NULL) - lookup_name++; - else - lookup_name = name; - - ASSERT(table != NULL); - - for (vi = table; vi->name; vi++) { - if (!strcmp(vi->name, lookup_name)) - return vi; - } - /* ran to end of table */ - - return NULL; /* var name not found */ -} - -int -bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set) -{ - int bcmerror = 0; - - /* length check on io buf */ - switch (vi->type) { - case IOVT_BOOL: - case IOVT_INT8: - case IOVT_INT16: - case IOVT_INT32: - case IOVT_UINT8: - case IOVT_UINT16: - case IOVT_UINT32: - /* all integers are int32 sized args at the ioctl interface */ - if (len < (int)sizeof(int)) { - bcmerror = BCME_BUFTOOSHORT; - } - break; - - case IOVT_BUFFER: - /* buffer must meet minimum length requirement */ - if (len < vi->minlen) { - bcmerror = BCME_BUFTOOSHORT; - } - break; - - case IOVT_VOID: - if (!set) { - /* Cannot return nil... */ - bcmerror = BCME_UNSUPPORTED; - } else if (len) { - /* Set is an action w/o parameters */ - bcmerror = BCME_BUFTOOLONG; - } - break; - - default: - /* unknown type for length check in iovar info */ - ASSERT(0); - bcmerror = BCME_UNSUPPORTED; - } - - return bcmerror; -} - -#endif /* BCMDRIVER */ - -/******************************************************************************* - * crc8 - * - * Computes a crc8 over the input data using the polynomial: - * - * x^8 + x^7 +x^6 + x^4 + x^2 + 1 - * - * The caller provides the initial value (either CRC8_INIT_VALUE - * or the previous returned value) to allow for processing of - * discontiguous blocks of data. When generating the CRC the - * caller is responsible for complementing the final return value - * and inserting it into the byte stream. When checking, a final - * return value of CRC8_GOOD_VALUE indicates a valid CRC. - * - * Reference: Dallas Semiconductor Application Note 27 - * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", - * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., - * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt - * - * **************************************************************************** - */ - -STATIC const uint8 crc8_table[256] = { - 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, - 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, - 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, - 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, - 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, - 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, - 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, - 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, - 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, - 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, - 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, - 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, - 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, - 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, - 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, - 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, - 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, - 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, - 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, - 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, - 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, - 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, - 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, - 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, - 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, - 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, - 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, - 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, - 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, - 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, - 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, - 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F -}; - -#define CRC_INNER_LOOP(n, c, x) \ - (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff] - -uint8 -hndcrc8( - uint8 *pdata, /* pointer to array of data to process */ - uint nbytes, /* number of input data bytes to process */ - uint8 crc /* either CRC8_INIT_VALUE or previous return value */ -) -{ - /* hard code the crc loop instead of using CRC_INNER_LOOP macro - * to avoid the undefined and unnecessary (uint8 >> 8) operation. - */ - while (nbytes-- > 0) - crc = crc8_table[(crc ^ *pdata++) & 0xff]; - - return crc; -} - -/******************************************************************************* - * crc16 - * - * Computes a crc16 over the input data using the polynomial: - * - * x^16 + x^12 +x^5 + 1 - * - * The caller provides the initial value (either CRC16_INIT_VALUE - * or the previous returned value) to allow for processing of - * discontiguous blocks of data. When generating the CRC the - * caller is responsible for complementing the final return value - * and inserting it into the byte stream. When checking, a final - * return value of CRC16_GOOD_VALUE indicates a valid CRC. - * - * Reference: Dallas Semiconductor Application Note 27 - * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", - * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., - * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt - * - * **************************************************************************** - */ - -static const uint16 crc16_table[256] = { - 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, - 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, - 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, - 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, - 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, - 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, - 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, - 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, - 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, - 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, - 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, - 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, - 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, - 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, - 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, - 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, - 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, - 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, - 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, - 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, - 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, - 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, - 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, - 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, - 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, - 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, - 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, - 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, - 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, - 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, - 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, - 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 -}; - -uint16 -hndcrc16( - uint8 *pdata, /* pointer to array of data to process */ - uint nbytes, /* number of input data bytes to process */ - uint16 crc /* either CRC16_INIT_VALUE or previous return value */ -) -{ - while (nbytes-- > 0) - CRC_INNER_LOOP(16, crc, *pdata++); - return crc; -} - -STATIC const uint32 crc32_table[256] = { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, - 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, - 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, - 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, - 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, - 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, - 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, - 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, - 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, - 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, - 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, - 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, - 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, - 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, - 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, - 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, - 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, - 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, - 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -}; - -uint32 -hndcrc32( - uint8 *pdata, /* pointer to array of data to process */ - uint nbytes, /* number of input data bytes to process */ - uint32 crc /* either CRC32_INIT_VALUE or previous return value */ -) -{ - uint8 *pend; -#ifdef __mips__ - uint8 tmp[4]; - ulong *tptr = (ulong *)tmp; - - /* in case the beginning of the buffer isn't aligned */ - pend = (uint8 *)((uint)(pdata + 3) & 0xfffffffc); - nbytes -= (pend - pdata); - while (pdata < pend) - CRC_INNER_LOOP(32, crc, *pdata++); - - /* handle bulk of data as 32-bit words */ - pend = pdata + (nbytes & 0xfffffffc); - while (pdata < pend) { - *tptr = *(ulong *)pdata; - pdata += sizeof(ulong *); - CRC_INNER_LOOP(32, crc, tmp[0]); - CRC_INNER_LOOP(32, crc, tmp[1]); - CRC_INNER_LOOP(32, crc, tmp[2]); - CRC_INNER_LOOP(32, crc, tmp[3]); - } - - /* 1-3 bytes at end of buffer */ - pend = pdata + (nbytes & 0x03); - while (pdata < pend) - CRC_INNER_LOOP(32, crc, *pdata++); -#else - pend = pdata + nbytes; - while (pdata < pend) - CRC_INNER_LOOP(32, crc, *pdata++); -#endif /* __mips__ */ - - return crc; -} - -#ifdef notdef -#define CLEN 1499 /* CRC Length */ -#define CBUFSIZ (CLEN+4) -#define CNBUFS 5 /* # of bufs */ - -void testcrc32(void) -{ - uint j, k, l; - uint8 *buf; - uint len[CNBUFS]; - uint32 crcr; - uint32 crc32tv[CNBUFS] = - {0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110}; - - ASSERT((buf = MALLOC(CBUFSIZ*CNBUFS)) != NULL); - - /* step through all possible alignments */ - for (l = 0; l <= 4; l++) { - for (j = 0; j < CNBUFS; j++) { - len[j] = CLEN; - for (k = 0; k < len[j]; k++) - *(buf + j*CBUFSIZ + (k+l)) = (j+k) & 0xff; - } - - for (j = 0; j < CNBUFS; j++) { - crcr = crc32(buf + j*CBUFSIZ + l, len[j], CRC32_INIT_VALUE); - ASSERT(crcr == crc32tv[j]); - } - } - - MFREE(buf, CBUFSIZ*CNBUFS); - return; -} -#endif /* notdef */ - -/* - * Advance from the current 1-byte tag/1-byte length/variable-length value - * triple, to the next, returning a pointer to the next. - * If the current or next TLV is invalid (does not fit in given buffer length), - * NULL is returned. - * *buflen is not modified if the TLV elt parameter is invalid, or is decremented - * by the TLV parameter's length if it is valid. - */ -bcm_tlv_t * -bcm_next_tlv(bcm_tlv_t *elt, int *buflen) -{ - int len; - - /* validate current elt */ - if (!bcm_valid_tlv(elt, *buflen)) - return NULL; - - /* advance to next elt */ - len = elt->len; - elt = (bcm_tlv_t*)(elt->data + len); - *buflen -= (2 + len); - - /* validate next elt */ - if (!bcm_valid_tlv(elt, *buflen)) - return NULL; - - return elt; -} - -/* - * Traverse a string of 1-byte tag/1-byte length/variable-length value - * triples, returning a pointer to the substring whose first element - * matches tag - */ -bcm_tlv_t * -bcm_parse_tlvs(void *buf, int buflen, uint key) -{ - bcm_tlv_t *elt; - int totlen; - - elt = (bcm_tlv_t*)buf; - totlen = buflen; - - /* find tagged parameter */ - while (totlen >= 2) { - int len = elt->len; - - /* validate remaining totlen */ - if ((elt->id == key) && (totlen >= (len + 2))) - return (elt); - - elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); - totlen -= (len + 2); - } - - return NULL; -} - -/* - * Traverse a string of 1-byte tag/1-byte length/variable-length value - * triples, returning a pointer to the substring whose first element - * matches tag. Stop parsing when we see an element whose ID is greater - * than the target key. - */ -bcm_tlv_t * -bcm_parse_ordered_tlvs(void *buf, int buflen, uint key) -{ - bcm_tlv_t *elt; - int totlen; - - elt = (bcm_tlv_t*)buf; - totlen = buflen; - - /* find tagged parameter */ - while (totlen >= 2) { - uint id = elt->id; - int len = elt->len; - - /* Punt if we start seeing IDs > than target key */ - if (id > key) - return (NULL); - - /* validate remaining totlen */ - if ((id == key) && (totlen >= (len + 2))) - return (elt); - - elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); - totlen -= (len + 2); - } - return NULL; -} - -#if defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || defined(WLMSG_ASSOC) || \ - defined(DHD_DEBUG) -int -bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len) -{ - int i; - char* p = buf; - char hexstr[16]; - int slen = 0; - uint32 bit; - const char* name; - - if (len < 2 || !buf) - return 0; - - buf[0] = '\0'; - len -= 1; - - for (i = 0; flags != 0; i++) { - bit = bd[i].bit; - name = bd[i].name; - if (bit == 0 && flags) { - /* print any unnamed bits */ - sprintf(hexstr, "0x%X", flags); - name = hexstr; - flags = 0; /* exit loop */ - } else if ((flags & bit) == 0) - continue; - slen += strlen(name); - if (len < slen) - break; - if (p != buf) p += sprintf(p, " "); /* btwn flag space */ - strcat(p, name); - p += strlen(name); - flags &= ~bit; - len -= slen; - slen = 1; /* account for btwn flag space */ - } - - /* indicate the str was too short */ - if (flags != 0) { - if (len == 0) - p--; /* overwrite last char */ - p += sprintf(p, ">"); - } - - return (int)(p - buf); -} - -/* print bytes formatted as hex to a string. return the resulting string length */ -int -bcm_format_hex(char *str, const void *bytes, int len) -{ - int i; - char *p = str; - const uint8 *src = (const uint8*)bytes; - - for (i = 0; i < len; i++) { - p += sprintf(p, "%02X", *src); - src++; - } - return (int)(p - str); -} - -/* pretty hex print a contiguous buffer */ -void -prhex(const char *msg, uchar *buf, uint nbytes) -{ - char line[128], *p; - uint i; - - if (msg && (msg[0] != '\0')) - printf("%s:\n", msg); - - p = line; - for (i = 0; i < nbytes; i++) { - if (i % 16 == 0) { - p += sprintf(p, " %04d: ", i); /* line prefix */ - } - p += sprintf(p, "%02x ", buf[i]); - if (i % 16 == 15) { - printf("%s\n", line); /* flush line */ - p = line; - } - } - - /* flush last partial line */ - if (p != line) - printf("%s\n", line); -} -#endif - - -/* Produce a human-readable string for boardrev */ -char * -bcm_brev_str(uint32 brev, char *buf) -{ - if (brev < 0x100) - snprintf(buf, 8, "%d.%d", (brev & 0xf0) >> 4, brev & 0xf); - else - snprintf(buf, 8, "%c%03x", ((brev & 0xf000) == 0x1000) ? 'P' : 'A', brev & 0xfff); - - return (buf); -} - -#define BUFSIZE_TODUMP_ATONCE 512 /* Buffer size */ - -/* dump large strings to console */ -void -printbig(char *buf) -{ - uint len, max_len; - char c; - - len = strlen(buf); - - max_len = BUFSIZE_TODUMP_ATONCE; - - while (len > max_len) { - c = buf[max_len]; - buf[max_len] = '\0'; - printf("%s", buf); - buf[max_len] = c; - - buf += max_len; - len -= max_len; - } - /* print the remaining string */ - printf("%s\n", buf); - return; -} - -/* routine to dump fields in a fileddesc structure */ -uint -bcmdumpfields(bcmutl_rdreg_rtn read_rtn, void *arg0, uint arg1, struct fielddesc *fielddesc_array, - char *buf, uint32 bufsize) -{ - uint filled_len; - int len; - struct fielddesc *cur_ptr; - - filled_len = 0; - cur_ptr = fielddesc_array; - - while (bufsize > 1) { - if (cur_ptr->nameandfmt == NULL) - break; - len = snprintf(buf, bufsize, cur_ptr->nameandfmt, - read_rtn(arg0, arg1, cur_ptr->offset)); - /* check for snprintf overflow or error */ - if (len < 0 || (uint32)len >= bufsize) - len = bufsize - 1; - buf += len; - bufsize -= len; - filled_len += len; - cur_ptr++; - } - return filled_len; -} - -uint -bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) -{ - uint len; - - len = strlen(name) + 1; - - if ((len + datalen) > buflen) - return 0; - - strncpy(buf, name, buflen); - - /* append data onto the end of the name string */ - memcpy(&buf[len], data, datalen); - len += datalen; - - return len; -} - -/* Quarter dBm units to mW - * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 - * Table is offset so the last entry is largest mW value that fits in - * a uint16. - */ - -#define QDBM_OFFSET 153 /* Offset for first entry */ -#define QDBM_TABLE_LEN 40 /* Table size */ - -/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET. - * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2 - */ -#define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */ - -/* Largest mW value that will round down to the last table entry, - * QDBM_OFFSET + QDBM_TABLE_LEN-1. - * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2. - */ -#define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */ - -static const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = { -/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */ -/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, -/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849, -/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119, -/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811, -/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096 -}; - -uint16 -bcm_qdbm_to_mw(uint8 qdbm) -{ - uint factor = 1; - int idx = qdbm - QDBM_OFFSET; - - if (idx >= QDBM_TABLE_LEN) { - /* clamp to max uint16 mW value */ - return 0xFFFF; - } - - /* scale the qdBm index up to the range of the table 0-40 - * where an offset of 40 qdBm equals a factor of 10 mW. - */ - while (idx < 0) { - idx += 40; - factor *= 10; - } - - /* return the mW value scaled down to the correct factor of 10, - * adding in factor/2 to get proper rounding. - */ - return ((nqdBm_to_mW_map[idx] + factor/2) / factor); -} - -uint8 -bcm_mw_to_qdbm(uint16 mw) -{ - uint8 qdbm; - int offset; - uint mw_uint = mw; - uint boundary; - - /* handle boundary case */ - if (mw_uint <= 1) - return 0; - - offset = QDBM_OFFSET; - - /* move mw into the range of the table */ - while (mw_uint < QDBM_TABLE_LOW_BOUND) { - mw_uint *= 10; - offset -= 40; - } - - for (qdbm = 0; qdbm < QDBM_TABLE_LEN-1; qdbm++) { - boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm+1] - - nqdBm_to_mW_map[qdbm])/2; - if (mw_uint < boundary) break; - } - - qdbm += (uint8)offset; - - return (qdbm); -} - - -uint -bcm_bitcount(uint8 *bitmap, uint length) -{ - uint bitcount = 0, i; - uint8 tmp; - for (i = 0; i < length; i++) { - tmp = bitmap[i]; - while (tmp) { - bitcount++; - tmp &= (tmp - 1); - } - } - return bitcount; -} - -#ifdef BCMDRIVER - -/* Initialization of bcmstrbuf structure */ -void -bcm_binit(struct bcmstrbuf *b, char *buf, uint size) -{ - b->origsize = b->size = size; - b->origbuf = b->buf = buf; -} - -/* Buffer sprintf wrapper to guard against buffer overflow */ -int -bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) -{ - va_list ap; - int r; - - va_start(ap, fmt); - r = vsnprintf(b->buf, b->size, fmt, ap); - - /* Non Ansi C99 compliant returns -1, - * Ansi compliant return r >= b->size, - * bcmstdlib returns 0, handle all - */ - if ((r == -1) || (r >= (int)b->size) || (r == 0)) { - b->size = 0; - } else { - b->size -= r; - b->buf += r; - } - - va_end(ap); - - return r; -} - -void -bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount) -{ - int i; - - for (i = 0; i < num_bytes; i++) { - num[i] += amount; - if (num[i] >= amount) - break; - amount = 1; - } -} - -int -bcm_cmp_bytes(uchar *arg1, uchar *arg2, uint8 nbytes) -{ - int i; - - for (i = nbytes - 1; i >= 0; i--) { - if (arg1[i] != arg2[i]) - return (arg1[i] - arg2[i]); - } - return 0; -} - -void -bcm_print_bytes(char *name, const uchar *data, int len) -{ - int i; - int per_line = 0; - - printf("%s: %d \n", name ? name : "", len); - for (i = 0; i < len; i++) { - printf("%02x ", *data++); - per_line++; - if (per_line == 16) { - per_line = 0; - printf("\n"); - } - } - printf("\n"); -} - -/* - * buffer length needed for wlc_format_ssid - * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. - */ - -#if defined(WLTINYDUMP) || defined(WLMSG_INFORM) || defined(WLMSG_ASSOC) || \ - defined(WLMSG_PRPKT) || defined(WLMSG_WSEC) -int -bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len) -{ - uint i, c; - char *p = buf; - char *endp = buf + SSID_FMT_BUF_LEN; - - if (ssid_len > DOT11_MAX_SSID_LEN) ssid_len = DOT11_MAX_SSID_LEN; - - for (i = 0; i < ssid_len; i++) { - c = (uint)ssid[i]; - if (c == '\\') { - *p++ = '\\'; - *p++ = '\\'; - } else if (bcm_isprint((uchar)c)) { - *p++ = (char)c; - } else { - p += snprintf(p, (endp - p), "\\x%02X", c); - } - } - *p = '\0'; - ASSERT(p < endp); - - return (int)(p - buf); -} -#endif - -#endif /* BCMDRIVER */ diff --git a/drivers/net/wireless/bcm4329/bcmwifi.c b/drivers/net/wireless/bcm4329/bcmwifi.c deleted file mode 100644 index 803acf842a29..000000000000 --- a/drivers/net/wireless/bcm4329/bcmwifi.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Misc utility routines used by kernel or app-level. - * Contents are wifi-specific, used by any kernel or app-level - * software that might want wifi things as it grows. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * $Id: bcmwifi.c,v 1.18.24.2.4.1 2009/09/25 00:32:01 Exp $ - */ - - -#include - -#ifdef BCMDRIVER -#include -#include -#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) -#define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c)) -#else -#include -#include -#include -#endif -#include - -#if defined(WIN32) && (defined(BCMDLL) || defined(WLMDLL)) -#include -#endif - - - - - -char * -wf_chspec_ntoa(chanspec_t chspec, char *buf) -{ - const char *band, *bw, *sb; - uint channel; - - band = ""; - bw = ""; - sb = ""; - channel = CHSPEC_CHANNEL(chspec); - - if ((CHSPEC_IS2G(chspec) && channel > CH_MAX_2G_CHANNEL) || - (CHSPEC_IS5G(chspec) && channel <= CH_MAX_2G_CHANNEL)) - band = (CHSPEC_IS2G(chspec)) ? "b" : "a"; - if (CHSPEC_IS40(chspec)) { - if (CHSPEC_SB_UPPER(chspec)) { - sb = "u"; - channel += CH_10MHZ_APART; - } else { - sb = "l"; - channel -= CH_10MHZ_APART; - } - } else if (CHSPEC_IS10(chspec)) { - bw = "n"; - } - - - snprintf(buf, 6, "%d%s%s%s", channel, band, bw, sb); - return (buf); -} - - -chanspec_t -wf_chspec_aton(char *a) -{ - char *endp = NULL; - uint channel, band, bw, ctl_sb; - char c; - - channel = strtoul(a, &endp, 10); - - - if (endp == a) - return 0; - - if (channel > MAXCHANNEL) - return 0; - - band = ((channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G); - bw = WL_CHANSPEC_BW_20; - ctl_sb = WL_CHANSPEC_CTL_SB_NONE; - - a = endp; - - c = tolower(a[0]); - if (c == '\0') - goto done; - - - if (c == 'a' || c == 'b') { - band = (c == 'a') ? WL_CHANSPEC_BAND_5G : WL_CHANSPEC_BAND_2G; - a++; - c = tolower(a[0]); - if (c == '\0') - goto done; - } - - - if (c == 'n') { - bw = WL_CHANSPEC_BW_10; - } else if (c == 'l') { - bw = WL_CHANSPEC_BW_40; - ctl_sb = WL_CHANSPEC_CTL_SB_LOWER; - - if (channel <= (MAXCHANNEL - CH_20MHZ_APART)) - channel += CH_10MHZ_APART; - else - return 0; - } else if (c == 'u') { - bw = WL_CHANSPEC_BW_40; - ctl_sb = WL_CHANSPEC_CTL_SB_UPPER; - - if (channel > CH_20MHZ_APART) - channel -= CH_10MHZ_APART; - else - return 0; - } else { - return 0; - } - -done: - return (channel | band | bw | ctl_sb); -} - - -int -wf_mhz2channel(uint freq, uint start_factor) -{ - int ch = -1; - uint base; - int offset; - - - if (start_factor == 0) { - if (freq >= 2400 && freq <= 2500) - start_factor = WF_CHAN_FACTOR_2_4_G; - else if (freq >= 5000 && freq <= 6000) - start_factor = WF_CHAN_FACTOR_5_G; - } - - if (freq == 2484 && start_factor == WF_CHAN_FACTOR_2_4_G) - return 14; - - base = start_factor / 2; - - - if ((freq < base) || (freq > base + 1000)) - return -1; - - offset = freq - base; - ch = offset / 5; - - - if (offset != (ch * 5)) - return -1; - - - if (start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 13)) - return -1; - - return ch; -} - - -int -wf_channel2mhz(uint ch, uint start_factor) -{ - int freq; - - if ((start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 14)) || - (ch <= 200)) - freq = -1; - if ((start_factor == WF_CHAN_FACTOR_2_4_G) && (ch == 14)) - freq = 2484; - else - freq = ch * 5 + start_factor / 2; - - return freq; -} diff --git a/drivers/net/wireless/bcm4329/dhd.h b/drivers/net/wireless/bcm4329/dhd.h deleted file mode 100644 index 0b2e9c23e3ca..000000000000 --- a/drivers/net/wireless/bcm4329/dhd.h +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Header file describing the internal (inter-module) DHD interfaces. - * - * Provides type definitions and function prototypes used to link the - * DHD OS, bus, and protocol modules. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd.h,v 1.32.4.7.2.4.14.49.4.9 2011/01/14 22:40:45 Exp $ - */ - -/**************** - * Common types * - */ - -#ifndef _dhd_h_ -#define _dhd_h_ - -#if defined(LINUX) -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* The kernel threading is sdio-specific */ -#else /* LINUX */ -#define ENOMEM 1 -#define EFAULT 2 -#define EINVAL 3 -#define EIO 4 -#define ETIMEDOUT 5 -#define ERESTARTSYS 6 -#endif /* LINUX */ - -#include - -#ifdef DHD_DEBUG -#ifndef DHD_DEBUG_TRAP -#define DHD_DEBUG_TRAP -#endif -#endif - -/* Forward decls */ -struct dhd_bus; -struct dhd_prot; -struct dhd_info; - -/* The level of bus communication with the dongle */ -enum dhd_bus_state { - DHD_BUS_DOWN, /* Not ready for frame transfers */ - DHD_BUS_LOAD, /* Download access only (CPU reset) */ - DHD_BUS_DATA /* Ready for frame transfers */ -}; - -enum dhd_bus_wake_state { - WAKE_LOCK_OFF, - WAKE_LOCK_PRIV, - WAKE_LOCK_DPC, - WAKE_LOCK_IOCTL, - WAKE_LOCK_DOWNLOAD, - WAKE_LOCK_TMOUT, - WAKE_LOCK_WATCHDOG, - WAKE_LOCK_LINK_DOWN_TMOUT, - WAKE_LOCK_PNO_FIND_TMOUT, - WAKE_LOCK_SOFTAP_SET, - WAKE_LOCK_SOFTAP_STOP, - WAKE_LOCK_SOFTAP_START, - WAKE_LOCK_SOFTAP_THREAD, - WAKE_LOCK_MAX -}; -enum dhd_prealloc_index { - DHD_PREALLOC_PROT = 0, - DHD_PREALLOC_RXBUF, - DHD_PREALLOC_DATABUF, - DHD_PREALLOC_OSL_BUF -}; -#ifdef DHD_USE_STATIC_BUF -extern void * dhd_os_prealloc(int section, unsigned long size); -#endif -/* Common structure for module and instance linkage */ -typedef struct dhd_pub { - /* Linkage ponters */ - osl_t *osh; /* OSL handle */ - struct dhd_bus *bus; /* Bus module handle */ - struct dhd_prot *prot; /* Protocol module handle */ - struct dhd_info *info; /* Info module handle */ - - /* Internal dhd items */ - bool up; /* Driver up/down (to OS) */ - bool txoff; /* Transmit flow-controlled */ - bool dongle_reset; /* TRUE = DEVRESET put dongle into reset */ - enum dhd_bus_state busstate; - uint hdrlen; /* Total DHD header length (proto + bus) */ - uint maxctl; /* Max size rxctl request from proto to bus */ - uint rxsz; /* Rx buffer size bus module should use */ - uint8 wme_dp; /* wme discard priority */ - - /* Dongle media info */ - bool iswl; /* Dongle-resident driver is wl */ - ulong drv_version; /* Version of dongle-resident driver */ - struct ether_addr mac; /* MAC address obtained from dongle */ - dngl_stats_t dstats; /* Stats for dongle-based data */ - - /* Additional stats for the bus level */ - ulong tx_packets; /* Data packets sent to dongle */ - ulong tx_multicast; /* Multicast data packets sent to dongle */ - ulong tx_errors; /* Errors in sending data to dongle */ - ulong tx_ctlpkts; /* Control packets sent to dongle */ - ulong tx_ctlerrs; /* Errors sending control frames to dongle */ - ulong rx_packets; /* Packets sent up the network interface */ - ulong rx_multicast; /* Multicast packets sent up the network interface */ - ulong rx_errors; /* Errors processing rx data packets */ - ulong rx_ctlpkts; /* Control frames processed from dongle */ - ulong rx_ctlerrs; /* Errors in processing rx control frames */ - ulong rx_dropped; /* Packets dropped locally (no memory) */ - ulong rx_flushed; /* Packets flushed due to unscheduled sendup thread */ - ulong wd_dpc_sched; /* Number of times dhd dpc scheduled by watchdog timer */ - - ulong rx_readahead_cnt; /* Number of packets where header read-ahead was used. */ - ulong tx_realloc; /* Number of tx packets we had to realloc for headroom */ - ulong fc_packets; /* Number of flow control pkts recvd */ - - /* Last error return */ - int bcmerror; - uint tickcnt; - - /* Last error from dongle */ - int dongle_error; - - /* Suspend disable flag and "in suspend" flag */ - int suspend_disable_flag; /* "1" to disable all extra powersaving during suspend */ - int in_suspend; /* flag set to 1 when early suspend called */ - int hang_was_sent; /* flag that message was send at least once */ -#ifdef PNO_SUPPORT - int pno_enable; /* pno status : "1" is pno enable */ -#endif /* PNO_SUPPORT */ - int dtim_skip; /* dtim skip , default 0 means wake each dtim */ - - /* Pkt filter defination */ - char * pktfilter[100]; - int pktfilter_count; - - wl_country_t dhd_cspec; /* Current Locale info */ - char eventmask[WL_EVENTING_MASK_LEN]; - -} dhd_pub_t; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) - - #define DHD_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); - #define _DHD_PM_RESUME_WAIT(a, b) do { \ - int retry = 0; \ - smp_mb(); \ - while (dhd_mmc_suspend && retry++ != b) { \ - wait_event_interruptible_timeout(a, FALSE, HZ/100); \ - } \ - } while (0) - #define DHD_PM_RESUME_WAIT(a) _DHD_PM_RESUME_WAIT(a, 200) - #define DHD_PM_RESUME_WAIT_FOREVER(a) _DHD_PM_RESUME_WAIT(a, ~0) - #define DHD_PM_RESUME_RETURN_ERROR(a) do { if (dhd_mmc_suspend) return a; } while (0) - #define DHD_PM_RESUME_RETURN do { if (dhd_mmc_suspend) return; } while (0) - - #define DHD_SPINWAIT_SLEEP_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); - #define SPINWAIT_SLEEP(a, exp, us) do { \ - uint countdown = (us) + 9999; \ - while ((exp) && (countdown >= 10000)) { \ - wait_event_interruptible_timeout(a, FALSE, HZ/100); \ - countdown -= 10000; \ - } \ - } while (0) - -#else - - #define DHD_PM_RESUME_WAIT_INIT(a) - #define DHD_PM_RESUME_WAIT(a) - #define DHD_PM_RESUME_WAIT_FOREVER(a) - #define DHD_PM_RESUME_RETURN_ERROR(a) - #define DHD_PM_RESUME_RETURN - - #define DHD_SPINWAIT_SLEEP_INIT(a) - #define SPINWAIT_SLEEP(a, exp, us) do { \ - uint countdown = (us) + 9; \ - while ((exp) && (countdown >= 10)) { \ - OSL_DELAY(10); \ - countdown -= 10; \ - } \ - } while (0) - -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ - -#define DHD_IF_VIF 0x01 /* Virtual IF (Hidden from user) */ - -inline static void NETIF_ADDR_LOCK(struct net_device *dev) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)) - netif_addr_lock_bh(dev); -#endif -} - -inline static void NETIF_ADDR_UNLOCK(struct net_device *dev) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)) - netif_addr_unlock_bh(dev); -#endif -} - -/* Wakelock Functions */ -extern int dhd_os_wake_lock(dhd_pub_t *pub); -extern int dhd_os_wake_unlock(dhd_pub_t *pub); -extern int dhd_os_wake_lock_timeout(dhd_pub_t *pub); -extern int dhd_os_wake_lock_timeout_enable(dhd_pub_t *pub); - -extern void dhd_os_start_lock(dhd_pub_t *pub); -extern void dhd_os_start_unlock(dhd_pub_t *pub); -extern unsigned long dhd_os_spin_lock(dhd_pub_t *pub); -extern void dhd_os_spin_unlock(dhd_pub_t *pub, unsigned long flags); - -typedef struct dhd_if_event { - uint8 ifidx; - uint8 action; - uint8 flags; - uint8 bssidx; -} dhd_if_event_t; - -/* - * Exported from dhd OS modules (dhd_linux/dhd_ndis) - */ - -/* To allow osl_attach/detach calls from os-independent modules */ -osl_t *dhd_osl_attach(void *pdev, uint bustype); -void dhd_osl_detach(osl_t *osh); - -/* Indication from bus module regarding presence/insertion of dongle. - * Return dhd_pub_t pointer, used as handle to OS module in later calls. - * Returned structure should have bus and prot pointers filled in. - * bus_hdrlen specifies required headroom for bus module header. - */ -extern dhd_pub_t *dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen); -extern int dhd_net_attach(dhd_pub_t *dhdp, int idx); - -/* Indication from bus module regarding removal/absence of dongle */ -extern void dhd_detach(dhd_pub_t *dhdp); - -/* Indication from bus module to change flow-control state */ -extern void dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool on); - -extern bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec); - -/* Receive frame for delivery to OS. Callee disposes of rxp. */ -extern void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *rxp, int numpkt); - -/* Return pointer to interface name */ -extern char *dhd_ifname(dhd_pub_t *dhdp, int idx); - -/* Request scheduling of the bus dpc */ -extern void dhd_sched_dpc(dhd_pub_t *dhdp); - -/* Notify tx completion */ -extern void dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success); - -/* Query ioctl */ -extern int dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len); - -/* OS independent layer functions */ -extern int dhd_os_proto_block(dhd_pub_t * pub); -extern int dhd_os_proto_unblock(dhd_pub_t * pub); -extern int dhd_os_ioctl_resp_wait(dhd_pub_t * pub, uint * condition, bool * pending); -extern int dhd_os_ioctl_resp_wake(dhd_pub_t * pub); -extern unsigned int dhd_os_get_ioctl_resp_timeout(void); -extern void dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec); -extern void * dhd_os_open_image(char * filename); -extern int dhd_os_get_image_block(char * buf, int len, void * image); -extern void dhd_os_close_image(void * image); -extern void dhd_os_wd_timer(void *bus, uint wdtick); -extern void dhd_os_sdlock(dhd_pub_t * pub); -extern void dhd_os_sdunlock(dhd_pub_t * pub); -extern void dhd_os_sdlock_txq(dhd_pub_t * pub); -extern void dhd_os_sdunlock_txq(dhd_pub_t * pub); -extern void dhd_os_sdlock_rxq(dhd_pub_t * pub); -extern void dhd_os_sdunlock_rxq(dhd_pub_t * pub); -extern void dhd_os_sdlock_sndup_rxq(dhd_pub_t * pub); -extern void dhd_customer_gpio_wlan_ctrl(int onoff); -extern int dhd_custom_get_mac_address(unsigned char *buf); -extern void dhd_os_sdunlock_sndup_rxq(dhd_pub_t * pub); -extern void dhd_os_sdlock_eventq(dhd_pub_t * pub); -extern void dhd_os_sdunlock_eventq(dhd_pub_t * pub); -#ifdef DHD_DEBUG -extern int write_to_file(dhd_pub_t *dhd, uint8 *buf, int size); -#endif /* DHD_DEBUG */ -#if defined(OOB_INTR_ONLY) -extern int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr); -#endif /* defined(OOB_INTR_ONLY) */ -extern void dhd_os_sdtxlock(dhd_pub_t * pub); -extern void dhd_os_sdtxunlock(dhd_pub_t * pub); - -int setScheduler(struct task_struct *p, int policy, struct sched_param *param); - -typedef struct { - uint32 limit; /* Expiration time (usec) */ - uint32 increment; /* Current expiration increment (usec) */ - uint32 elapsed; /* Current elapsed time (usec) */ - uint32 tick; /* O/S tick time (usec) */ -} dhd_timeout_t; - -extern void dhd_timeout_start(dhd_timeout_t *tmo, uint usec); -extern int dhd_timeout_expired(dhd_timeout_t *tmo); - -extern int dhd_ifname2idx(struct dhd_info *dhd, char *name); -extern uint8 *dhd_bssidx2bssid(dhd_pub_t *dhd, int idx); -extern int wl_host_event(struct dhd_info *dhd, int *idx, void *pktdata, - wl_event_msg_t *, void **data_ptr); -extern void wl_event_to_host_order(wl_event_msg_t * evt); - -extern void dhd_common_init(void); - -extern int dhd_add_if(struct dhd_info *dhd, int ifidx, void *handle, - char *name, uint8 *mac_addr, uint32 flags, uint8 bssidx); -extern void dhd_del_if(struct dhd_info *dhd, int ifidx); - -extern void dhd_vif_add(struct dhd_info *dhd, int ifidx, char * name); -extern void dhd_vif_del(struct dhd_info *dhd, int ifidx); - -extern void dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx); -extern void dhd_vif_sendup(struct dhd_info *dhd, int ifidx, uchar *cp, int len); - - -/* Send packet to dongle via data channel */ -extern int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pkt); - -/* Send event to host */ -extern void dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data); -extern int dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag); -extern uint dhd_bus_status(dhd_pub_t *dhdp); -extern int dhd_bus_start(dhd_pub_t *dhdp); - -extern void print_buf(void *pbuf, int len, int bytes_per_line); - - -typedef enum cust_gpio_modes { - WLAN_RESET_ON, - WLAN_RESET_OFF, - WLAN_POWER_ON, - WLAN_POWER_OFF -} cust_gpio_modes_t; - -extern int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag); -extern int wl_iw_send_priv_event(struct net_device *dev, char *flag); -extern int net_os_send_hang_message(struct net_device *dev); - -/* - * Insmod parameters for debug/test - */ - -/* Watchdog timer interval */ -extern uint dhd_watchdog_ms; - -#if defined(DHD_DEBUG) -/* Console output poll interval */ -extern uint dhd_console_ms; -#endif /* defined(DHD_DEBUG) */ - -/* Use interrupts */ -extern uint dhd_intr; - -/* Use polling */ -extern uint dhd_poll; - -/* ARP offload agent mode */ -extern uint dhd_arp_mode; - -/* ARP offload enable */ -extern uint dhd_arp_enable; - -/* Pkt filte enable control */ -extern uint dhd_pkt_filter_enable; - -/* Pkt filter init setup */ -extern uint dhd_pkt_filter_init; - -/* Pkt filter mode control */ -extern uint dhd_master_mode; - -/* Roaming mode control */ -extern uint dhd_roam; - -/* Roaming mode control */ -extern uint dhd_radio_up; - -/* Initial idletime ticks (may be -1 for immediate idle, 0 for no idle) */ -extern int dhd_idletime; -#define DHD_IDLETIME_TICKS 1 - -/* SDIO Drive Strength */ -extern uint dhd_sdiod_drive_strength; - -/* Override to force tx queueing all the time */ -extern uint dhd_force_tx_queueing; - -/* Default KEEP_ALIVE Period is 55 sec to prevent AP from sending Keep Alive probe frame */ -#define KEEP_ALIVE_PERIOD 55000 -#define NULL_PKT_STR "null_pkt" - -#ifdef SDTEST -/* Echo packet generator (SDIO), pkts/s */ -extern uint dhd_pktgen; - -/* Echo packet len (0 => sawtooth, max 1800) */ -extern uint dhd_pktgen_len; -#define MAX_PKTGEN_LEN 1800 -#endif - - -/* optionally set by a module_param_string() */ -#define MOD_PARAM_PATHLEN 2048 -extern char fw_path[MOD_PARAM_PATHLEN]; -extern char nv_path[MOD_PARAM_PATHLEN]; - -/* For supporting multiple interfaces */ -#define DHD_MAX_IFS 16 -#define DHD_DEL_IF -0xe -#define DHD_BAD_IF -0xf - - -extern void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar); -extern void dhd_wait_event_wakeup(dhd_pub_t*dhd); - -/* dhd_commn arp offload wrapers */ -extern void dhd_arp_cleanup(dhd_pub_t *dhd); -int dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen); -void dhd_arp_offload_add_ip(dhd_pub_t *dhd, u32 ipaddr); - -#define DHD_UNICAST_FILTER_NUM 0 -#define DHD_BROADCAST_FILTER_NUM 1 -#define DHD_MULTICAST4_FILTER_NUM 2 -#define DHD_MULTICAST6_FILTER_NUM 3 -extern int net_os_set_packet_filter(struct net_device *dev, int val); -extern int net_os_rxfilter_add_remove(struct net_device *dev, int val, int num); - -#endif /* _dhd_h_ */ diff --git a/drivers/net/wireless/bcm4329/dhd_bus.h b/drivers/net/wireless/bcm4329/dhd_bus.h deleted file mode 100644 index 97af41b313d0..000000000000 --- a/drivers/net/wireless/bcm4329/dhd_bus.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Header file describing the internal (inter-module) DHD interfaces. - * - * Provides type definitions and function prototypes used to link the - * DHD OS, bus, and protocol modules. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd_bus.h,v 1.4.6.3.2.3.6.7 2010/08/13 01:35:24 Exp $ - */ - -#ifndef _dhd_bus_h_ -#define _dhd_bus_h_ - -/* - * Exported from dhd bus module (dhd_usb, dhd_sdio) - */ - -/* Indicate (dis)interest in finding dongles. */ -extern int dhd_bus_register(void); -extern void dhd_bus_unregister(void); - -/* Download firmware image and nvram image */ -extern bool dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh, - char *fw_path, char *nv_path); - -/* Stop bus module: clear pending frames, disable data flow */ -extern void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex); - -/* Initialize bus module: prepare for communication w/dongle */ -extern int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex); - -/* Send a data frame to the dongle. Callee disposes of txp. */ -extern int dhd_bus_txdata(struct dhd_bus *bus, void *txp); - -/* Send/receive a control message to/from the dongle. - * Expects caller to enforce a single outstanding transaction. - */ -extern int dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen); -extern int dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen); - -/* Watchdog timer function */ -extern bool dhd_bus_watchdog(dhd_pub_t *dhd); - -#ifdef DHD_DEBUG -/* Device console input function */ -extern int dhd_bus_console_in(dhd_pub_t *dhd, uchar *msg, uint msglen); -#endif /* DHD_DEBUG */ - -/* Deferred processing for the bus, return TRUE requests reschedule */ -extern bool dhd_bus_dpc(struct dhd_bus *bus); -extern void dhd_bus_isr(bool * InterruptRecognized, bool * QueueMiniportHandleInterrupt, void *arg); - - -/* Check for and handle local prot-specific iovar commands */ -extern int dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name, - void *params, int plen, void *arg, int len, bool set); - -/* Add bus dump output to a buffer */ -extern void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf); - -/* Clear any bus counters */ -extern void dhd_bus_clearcounts(dhd_pub_t *dhdp); - -/* return the dongle chipid */ -extern uint dhd_bus_chip(struct dhd_bus *bus); - -/* Set user-specified nvram parameters. */ -extern void dhd_bus_set_nvram_params(struct dhd_bus * bus, const char *nvram_params); - -extern void *dhd_bus_pub(struct dhd_bus *bus); -extern void *dhd_bus_txq(struct dhd_bus *bus); -extern uint dhd_bus_hdrlen(struct dhd_bus *bus); - -#endif /* _dhd_bus_h_ */ diff --git a/drivers/net/wireless/bcm4329/dhd_cdc.c b/drivers/net/wireless/bcm4329/dhd_cdc.c deleted file mode 100644 index 4bec0b606dc9..000000000000 --- a/drivers/net/wireless/bcm4329/dhd_cdc.c +++ /dev/null @@ -1,535 +0,0 @@ -/* - * DHD Protocol Module for CDC and BDC. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd_cdc.c,v 1.22.4.2.4.7.2.41 2010/06/23 19:58:18 Exp $ - * - * BDC is like CDC, except it includes a header for data packets to convey - * packet priority over the bus, and flags (e.g. to indicate checksum status - * for dongle offload). - */ - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -extern int dhd_preinit_ioctls(dhd_pub_t *dhd); - -/* Packet alignment for most efficient SDIO (can change based on platform) */ -#ifndef DHD_SDALIGN -#define DHD_SDALIGN 32 -#endif -#if !ISPOWEROF2(DHD_SDALIGN) -#error DHD_SDALIGN is not a power of 2! -#endif - -#define RETRIES 2 /* # of retries to retrieve matching ioctl response */ -#define BUS_HEADER_LEN (16+DHD_SDALIGN) /* Must be atleast SDPCM_RESERVE - * defined in dhd_sdio.c (amount of header tha might be added) - * plus any space that might be needed for alignment padding. - */ -#define ROUND_UP_MARGIN 2048 /* Biggest SDIO block size possible for - * round off at the end of buffer - */ - -typedef struct dhd_prot { - uint16 reqid; - uint8 pending; - uint32 lastcmd; - uint8 bus_header[BUS_HEADER_LEN]; - cdc_ioctl_t msg; - unsigned char buf[WLC_IOCTL_MAXLEN + ROUND_UP_MARGIN]; -} dhd_prot_t; - -static int -dhdcdc_msg(dhd_pub_t *dhd) -{ - dhd_prot_t *prot = dhd->prot; - int len = ltoh32(prot->msg.len) + sizeof(cdc_ioctl_t); - int ret; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - dhd_os_wake_lock(dhd); - - /* NOTE : cdc->msg.len holds the desired length of the buffer to be - * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area - * is actually sent to the dongle - */ - if (len > CDC_MAX_MSG_SIZE) - len = CDC_MAX_MSG_SIZE; - - /* Send request */ - ret = dhd_bus_txctl(dhd->bus, (uchar*)&prot->msg, len); - dhd_os_wake_unlock(dhd); - return ret; -} - -static int -dhdcdc_cmplt(dhd_pub_t *dhd, uint32 id, uint32 len) -{ - int ret; - dhd_prot_t *prot = dhd->prot; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - do { - ret = dhd_bus_rxctl(dhd->bus, (uchar*)&prot->msg, len+sizeof(cdc_ioctl_t)); - if (ret < 0) - break; - } while (CDC_IOC_ID(ltoh32(prot->msg.flags)) != id); - - return ret; -} - -int -dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len) -{ - dhd_prot_t *prot = dhd->prot; - cdc_ioctl_t *msg = &prot->msg; - void *info; - int ret = 0, retries = 0; - uint32 id, flags = 0; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - DHD_CTL(("%s: cmd %d len %d\n", __FUNCTION__, cmd, len)); - - - /* Respond "bcmerror" and "bcmerrorstr" with local cache */ - if (cmd == WLC_GET_VAR && buf) - { - if (!strcmp((char *)buf, "bcmerrorstr")) - { - strncpy((char *)buf, bcmerrorstr(dhd->dongle_error), BCME_STRLEN); - goto done; - } - else if (!strcmp((char *)buf, "bcmerror")) - { - *(int *)buf = dhd->dongle_error; - goto done; - } - } - - memset(msg, 0, sizeof(cdc_ioctl_t)); - - msg->cmd = htol32(cmd); - msg->len = htol32(len); - msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT); - CDC_SET_IF_IDX(msg, ifidx); - msg->flags = htol32(msg->flags); - - if (buf) - memcpy(prot->buf, buf, len); - - if ((ret = dhdcdc_msg(dhd)) < 0) { - if (!dhd->hang_was_sent) - DHD_ERROR(("dhdcdc_query_ioctl: dhdcdc_msg failed w/status %d\n", ret)); - goto done; - } - -retry: - /* wait for interrupt and get first fragment */ - if ((ret = dhdcdc_cmplt(dhd, prot->reqid, len)) < 0) - goto done; - - flags = ltoh32(msg->flags); - id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT; - - if ((id < prot->reqid) && (++retries < RETRIES)) - goto retry; - if (id != prot->reqid) { - DHD_ERROR(("%s: %s: unexpected request id %d (expected %d)\n", - dhd_ifname(dhd, ifidx), __FUNCTION__, id, prot->reqid)); - ret = -EINVAL; - goto done; - } - - /* Check info buffer */ - info = (void*)&msg[1]; - - /* Copy info buffer */ - if (buf) - { - if (ret < (int)len) - len = ret; - memcpy(buf, info, len); - } - - /* Check the ERROR flag */ - if (flags & CDCF_IOC_ERROR) - { - ret = ltoh32(msg->status); - /* Cache error from dongle */ - dhd->dongle_error = ret; - } - -done: - return ret; -} - -int -dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len) -{ - dhd_prot_t *prot = dhd->prot; - cdc_ioctl_t *msg = &prot->msg; - int ret = 0; - uint32 flags, id; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - DHD_CTL(("%s: cmd %d len %d\n", __FUNCTION__, cmd, len)); - - if (dhd->busstate == DHD_BUS_DOWN) { - DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__)); - return -EIO; - } - - /* don't talk to the dongle if fw is about to be reloaded */ - if (dhd->hang_was_sent) { - DHD_ERROR(("%s: HANG was sent up earlier. Not talking to the chip\n", - __FUNCTION__)); - return -EIO; - } - - memset(msg, 0, sizeof(cdc_ioctl_t)); - - msg->cmd = htol32(cmd); - msg->len = htol32(len); - msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT) | CDCF_IOC_SET; - CDC_SET_IF_IDX(msg, ifidx); - msg->flags = htol32(msg->flags); - - if (buf) - memcpy(prot->buf, buf, len); - - if ((ret = dhdcdc_msg(dhd)) < 0) - goto done; - - if ((ret = dhdcdc_cmplt(dhd, prot->reqid, len)) < 0) - goto done; - - flags = ltoh32(msg->flags); - id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT; - - if (id != prot->reqid) { - DHD_ERROR(("%s: %s: unexpected request id %d (expected %d)\n", - dhd_ifname(dhd, ifidx), __FUNCTION__, id, prot->reqid)); - ret = -EINVAL; - goto done; - } - - /* Check the ERROR flag */ - if (flags & CDCF_IOC_ERROR) - { - ret = ltoh32(msg->status); - /* Cache error from dongle */ - dhd->dongle_error = ret; - } - -done: - return ret; -} - -extern int dhd_bus_interface(struct dhd_bus *bus, uint arg, void* arg2); -int -dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len) -{ - dhd_prot_t *prot = dhd->prot; - int ret = -1; - - if ((dhd->busstate == DHD_BUS_DOWN) || dhd->hang_was_sent) { - DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__)); - return ret; - } - dhd_os_proto_block(dhd); - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - ASSERT(len <= WLC_IOCTL_MAXLEN); - - if (len > WLC_IOCTL_MAXLEN) - goto done; - - if (prot->pending == TRUE) { - DHD_TRACE(("CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n", - ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd, - (unsigned long)prot->lastcmd)); - if ((ioc->cmd == WLC_SET_VAR) || (ioc->cmd == WLC_GET_VAR)) { - DHD_TRACE(("iovar cmd=%s\n", (char*)buf)); - } - goto done; - } - - prot->pending = TRUE; - prot->lastcmd = ioc->cmd; - if (ioc->set) - ret = dhdcdc_set_ioctl(dhd, ifidx, ioc->cmd, buf, len); - else { - ret = dhdcdc_query_ioctl(dhd, ifidx, ioc->cmd, buf, len); - if (ret > 0) - ioc->used = ret - sizeof(cdc_ioctl_t); - } - - /* Too many programs assume ioctl() returns 0 on success */ - if (ret >= 0) - ret = 0; - else { - cdc_ioctl_t *msg = &prot->msg; - ioc->needed = ltoh32(msg->len); /* len == needed when set/query fails from dongle */ - } - - /* Intercept the wme_dp ioctl here */ - if ((!ret) && (ioc->cmd == WLC_SET_VAR) && (!strcmp(buf, "wme_dp"))) { - int slen, val = 0; - - slen = strlen("wme_dp") + 1; - if (len >= (int)(slen + sizeof(int))) - bcopy(((char *)buf + slen), &val, sizeof(int)); - dhd->wme_dp = (uint8) ltoh32(val); - } - - prot->pending = FALSE; - -done: - dhd_os_proto_unblock(dhd); - - return ret; -} - -int -dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - return BCME_UNSUPPORTED; -} - -void -dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) -{ - bcm_bprintf(strbuf, "Protocol CDC: reqid %d\n", dhdp->prot->reqid); -} - - -void -dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *pktbuf) -{ -#ifdef BDC - struct bdc_header *h; -#endif /* BDC */ - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - -#ifdef BDC - /* Push BDC header used to convey priority for buses that don't */ - - - PKTPUSH(dhd->osh, pktbuf, BDC_HEADER_LEN); - - h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf); - - h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); - if (PKTSUMNEEDED(pktbuf)) - h->flags |= BDC_FLAG_SUM_NEEDED; - - - h->priority = (PKTPRIO(pktbuf) & BDC_PRIORITY_MASK); - h->flags2 = 0; - h->rssi = 0; -#endif /* BDC */ - BDC_SET_IF_IDX(h, ifidx); -} - - -bool -dhd_proto_fcinfo(dhd_pub_t *dhd, void *pktbuf, uint8 *fcbits) -{ -#ifdef BDC - struct bdc_header *h; - - if (PKTLEN(dhd->osh, pktbuf) < BDC_HEADER_LEN) { - DHD_ERROR(("%s: rx data too short (%d < %d)\n", - __FUNCTION__, PKTLEN(dhd->osh, pktbuf), BDC_HEADER_LEN)); - return BCME_ERROR; - } - - h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf); - - *fcbits = h->priority >> BDC_PRIORITY_FC_SHIFT; - if ((h->flags2 & BDC_FLAG2_FC_FLAG) == BDC_FLAG2_FC_FLAG) - return TRUE; -#endif - return FALSE; -} - - -int -dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, void *pktbuf) -{ -#ifdef BDC - struct bdc_header *h; -#endif - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - -#ifdef BDC - /* Pop BDC header used to convey priority for buses that don't */ - - if (PKTLEN(dhd->osh, pktbuf) < BDC_HEADER_LEN) { - DHD_ERROR(("%s: rx data too short (%d < %d)\n", __FUNCTION__, - PKTLEN(dhd->osh, pktbuf), BDC_HEADER_LEN)); - return BCME_ERROR; - } - - h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf); - - if ((*ifidx = BDC_GET_IF_IDX(h)) >= DHD_MAX_IFS) { - DHD_ERROR(("%s: rx data ifnum out of range (%d)\n", - __FUNCTION__, *ifidx)); - return BCME_ERROR; - } - - if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != BDC_PROTO_VER) { - DHD_ERROR(("%s: non-BDC packet received, flags 0x%x\n", - dhd_ifname(dhd, *ifidx), h->flags)); - return BCME_ERROR; - } - - if (h->flags & BDC_FLAG_SUM_GOOD) { - DHD_INFO(("%s: BDC packet received with good rx-csum, flags 0x%x\n", - dhd_ifname(dhd, *ifidx), h->flags)); - PKTSETSUMGOOD(pktbuf, TRUE); - } - - PKTSETPRIO(pktbuf, (h->priority & BDC_PRIORITY_MASK)); - - PKTPULL(dhd->osh, pktbuf, BDC_HEADER_LEN); -#endif /* BDC */ - - return 0; -} - -int -dhd_prot_attach(dhd_pub_t *dhd) -{ - dhd_prot_t *cdc; - -#ifndef DHD_USE_STATIC_BUF - if (!(cdc = (dhd_prot_t *)MALLOC(dhd->osh, sizeof(dhd_prot_t)))) { - DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - goto fail; - } -#else - if (!(cdc = (dhd_prot_t *)dhd_os_prealloc(DHD_PREALLOC_PROT, sizeof(dhd_prot_t)))) { - DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - goto fail; - } -#endif /* DHD_USE_STATIC_BUF */ - memset(cdc, 0, sizeof(dhd_prot_t)); - - /* ensure that the msg buf directly follows the cdc msg struct */ - if ((uintptr)(&cdc->msg + 1) != (uintptr)cdc->buf) { - DHD_ERROR(("dhd_prot_t is not correctly defined\n")); - goto fail; - } - - dhd->prot = cdc; -#ifdef BDC - dhd->hdrlen += BDC_HEADER_LEN; -#endif - dhd->maxctl = WLC_IOCTL_MAXLEN + sizeof(cdc_ioctl_t) + ROUND_UP_MARGIN; - return 0; - -fail: -#ifndef DHD_USE_STATIC_BUF - if (cdc != NULL) - MFREE(dhd->osh, cdc, sizeof(dhd_prot_t)); -#endif - return BCME_NOMEM; -} - -/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */ -void -dhd_prot_detach(dhd_pub_t *dhd) -{ -#ifndef DHD_USE_STATIC_BUF - MFREE(dhd->osh, dhd->prot, sizeof(dhd_prot_t)); -#endif - dhd->prot = NULL; -} - -void -dhd_prot_dstats(dhd_pub_t *dhd) -{ - /* No stats from dongle added yet, copy bus stats */ - dhd->dstats.tx_packets = dhd->tx_packets; - dhd->dstats.tx_errors = dhd->tx_errors; - dhd->dstats.rx_packets = dhd->rx_packets; - dhd->dstats.rx_errors = dhd->rx_errors; - dhd->dstats.rx_dropped = dhd->rx_dropped; - dhd->dstats.multicast = dhd->rx_multicast; - return; -} - -int -dhd_prot_init(dhd_pub_t *dhd) -{ - int ret = 0; - char buf[128]; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - dhd_os_proto_block(dhd); - - /* Get the device MAC address */ - strcpy(buf, "cur_etheraddr"); - ret = dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, sizeof(buf)); - if (ret < 0) { - dhd_os_proto_unblock(dhd); - return ret; - } - memcpy(dhd->mac.octet, buf, ETHER_ADDR_LEN); - - dhd_os_proto_unblock(dhd); - -#ifdef EMBEDDED_PLATFORM - ret = dhd_preinit_ioctls(dhd); -#endif /* EMBEDDED_PLATFORM */ - - /* Always assumes wl for now */ - dhd->iswl = TRUE; - - return ret; -} - -void -dhd_prot_stop(dhd_pub_t *dhd) -{ - /* Nothing to do for CDC */ -} diff --git a/drivers/net/wireless/bcm4329/dhd_common.c b/drivers/net/wireless/bcm4329/dhd_common.c deleted file mode 100644 index 8b89e390a405..000000000000 --- a/drivers/net/wireless/bcm4329/dhd_common.c +++ /dev/null @@ -1,2461 +0,0 @@ -/* - * Broadcom Dongle Host Driver (DHD), common DHD core. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd_common.c,v 1.5.6.8.2.6.6.69.4.25 2011-02-11 21:16:02 Exp $ - */ -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef SET_RANDOM_MAC_SOFTAP -#include -#include -#endif - -#ifdef GET_CUSTOM_MAC_ENABLE -int wifi_get_mac_addr(unsigned char *buf); -#endif /* GET_CUSTOM_MAC_ENABLE */ - -int dhd_msg_level; - -#include - -char fw_path[MOD_PARAM_PATHLEN]; -char nv_path[MOD_PARAM_PATHLEN]; - -/* Last connection success/failure status */ -uint32 dhd_conn_event; -uint32 dhd_conn_status; -uint32 dhd_conn_reason; - -#define htod32(i) i -#define htod16(i) i -#define dtoh32(i) i -#define dtoh16(i) i - -extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len); -extern void dhd_ind_scan_confirm(void *h, bool status); -extern int dhd_wl_ioctl(dhd_pub_t *dhd, uint cmd, char *buf, uint buflen); -void dhd_iscan_lock(void); -void dhd_iscan_unlock(void); - -#if defined(SOFTAP) -extern bool ap_fw_loaded; -#endif -#if defined(KEEP_ALIVE) -int dhd_keep_alive_onoff(dhd_pub_t *dhd, int ka_on); -#endif /* KEEP_ALIVE */ - -/* Packet alignment for most efficient SDIO (can change based on platform) */ -#ifndef DHD_SDALIGN -#define DHD_SDALIGN 32 -#endif -#if !ISPOWEROF2(DHD_SDALIGN) -#error DHD_SDALIGN is not a power of 2! -#endif - -#ifdef DHD_DEBUG -const char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR "\nCompiled on " - __DATE__ " at " __TIME__; -#else -const char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR; -#endif - -void dhd_set_timer(void *bus, uint wdtick); - -/* IOVar table */ -enum { - IOV_VERSION = 1, - IOV_MSGLEVEL, - IOV_BCMERRORSTR, - IOV_BCMERROR, - IOV_WDTICK, - IOV_DUMP, -#ifdef DHD_DEBUG - IOV_CONS, - IOV_DCONSOLE_POLL, -#endif - IOV_CLEARCOUNTS, - IOV_LOGDUMP, - IOV_LOGCAL, - IOV_LOGSTAMP, - IOV_GPIOOB, - IOV_IOCTLTIMEOUT, - IOV_LAST -}; - -const bcm_iovar_t dhd_iovars[] = { - {"version", IOV_VERSION, 0, IOVT_BUFFER, sizeof(dhd_version) }, -#ifdef DHD_DEBUG - {"msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 }, -#endif /* DHD_DEBUG */ - {"bcmerrorstr", IOV_BCMERRORSTR, 0, IOVT_BUFFER, BCME_STRLEN }, - {"bcmerror", IOV_BCMERROR, 0, IOVT_INT8, 0 }, - {"wdtick", IOV_WDTICK, 0, IOVT_UINT32, 0 }, - {"dump", IOV_DUMP, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN }, -#ifdef DHD_DEBUG - {"dconpoll", IOV_DCONSOLE_POLL, 0, IOVT_UINT32, 0 }, - {"cons", IOV_CONS, 0, IOVT_BUFFER, 0 }, -#endif - {"clearcounts", IOV_CLEARCOUNTS, 0, IOVT_VOID, 0 }, - {"gpioob", IOV_GPIOOB, 0, IOVT_UINT32, 0 }, - {"ioctl_timeout", IOV_IOCTLTIMEOUT, 0, IOVT_UINT32, 0 }, - {NULL, 0, 0, 0, 0 } -}; - -void -dhd_common_init(void) -{ - /* Init global variables at run-time, not as part of the declaration. - * This is required to support init/de-init of the driver. Initialization - * of globals as part of the declaration results in non-deterministic - * behaviour since the value of the globals may be different on the - * first time that the driver is initialized vs subsequent initializations. - */ - dhd_msg_level = DHD_ERROR_VAL; -#ifdef CONFIG_BCM4329_FW_PATH - strncpy(fw_path, CONFIG_BCM4329_FW_PATH, MOD_PARAM_PATHLEN-1); -#else - fw_path[0] = '\0'; -#endif -#ifdef CONFIG_BCM4329_NVRAM_PATH - strncpy(nv_path, CONFIG_BCM4329_NVRAM_PATH, MOD_PARAM_PATHLEN-1); -#else - nv_path[0] = '\0'; -#endif -} - -static int -dhd_dump(dhd_pub_t *dhdp, char *buf, int buflen) -{ - char eabuf[ETHER_ADDR_STR_LEN]; - - struct bcmstrbuf b; - struct bcmstrbuf *strbuf = &b; - - bcm_binit(strbuf, buf, buflen); - - /* Base DHD info */ - bcm_bprintf(strbuf, "%s\n", dhd_version); - bcm_bprintf(strbuf, "\n"); - bcm_bprintf(strbuf, "pub.up %d pub.txoff %d pub.busstate %d\n", - dhdp->up, dhdp->txoff, dhdp->busstate); - bcm_bprintf(strbuf, "pub.hdrlen %d pub.maxctl %d pub.rxsz %d\n", - dhdp->hdrlen, dhdp->maxctl, dhdp->rxsz); - bcm_bprintf(strbuf, "pub.iswl %d pub.drv_version %ld pub.mac %s\n", - dhdp->iswl, dhdp->drv_version, bcm_ether_ntoa(&dhdp->mac, eabuf)); - bcm_bprintf(strbuf, "pub.bcmerror %d tickcnt %d\n", dhdp->bcmerror, dhdp->tickcnt); - - bcm_bprintf(strbuf, "dongle stats:\n"); - bcm_bprintf(strbuf, "tx_packets %ld tx_bytes %ld tx_errors %ld tx_dropped %ld\n", - dhdp->dstats.tx_packets, dhdp->dstats.tx_bytes, - dhdp->dstats.tx_errors, dhdp->dstats.tx_dropped); - bcm_bprintf(strbuf, "rx_packets %ld rx_bytes %ld rx_errors %ld rx_dropped %ld\n", - dhdp->dstats.rx_packets, dhdp->dstats.rx_bytes, - dhdp->dstats.rx_errors, dhdp->dstats.rx_dropped); - bcm_bprintf(strbuf, "multicast %ld\n", dhdp->dstats.multicast); - - bcm_bprintf(strbuf, "bus stats:\n"); - bcm_bprintf(strbuf, "tx_packets %ld tx_multicast %ld tx_errors %ld\n", - dhdp->tx_packets, dhdp->tx_multicast, dhdp->tx_errors); - bcm_bprintf(strbuf, "tx_ctlpkts %ld tx_ctlerrs %ld\n", - dhdp->tx_ctlpkts, dhdp->tx_ctlerrs); - bcm_bprintf(strbuf, "rx_packets %ld rx_multicast %ld rx_errors %ld \n", - dhdp->rx_packets, dhdp->rx_multicast, dhdp->rx_errors); - bcm_bprintf(strbuf, "rx_ctlpkts %ld rx_ctlerrs %ld rx_dropped %ld rx_flushed %ld\n", - dhdp->rx_ctlpkts, dhdp->rx_ctlerrs, dhdp->rx_dropped, dhdp->rx_flushed); - bcm_bprintf(strbuf, "rx_readahead_cnt %ld tx_realloc %ld fc_packets %ld\n", - dhdp->rx_readahead_cnt, dhdp->tx_realloc, dhdp->fc_packets); - bcm_bprintf(strbuf, "wd_dpc_sched %ld\n", dhdp->wd_dpc_sched); - bcm_bprintf(strbuf, "\n"); - - /* Add any prot info */ - dhd_prot_dump(dhdp, strbuf); - bcm_bprintf(strbuf, "\n"); - - /* Add any bus info */ - dhd_bus_dump(dhdp, strbuf); - - return (!strbuf->size ? BCME_BUFTOOSHORT : 0); -} - -static int -dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const char *name, - void *params, int plen, void *arg, int len, int val_size) -{ - int bcmerror = 0; - int32 int_val = 0; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid))) != 0) - goto exit; - - if (plen >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); - - switch (actionid) { - case IOV_GVAL(IOV_VERSION): - /* Need to have checked buffer length */ - strncpy((char*)arg, dhd_version, len); - break; - - case IOV_GVAL(IOV_MSGLEVEL): - int_val = (int32)dhd_msg_level; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_MSGLEVEL): - dhd_msg_level = int_val; - break; - - case IOV_GVAL(IOV_BCMERRORSTR): - strncpy((char *)arg, bcmerrorstr(dhd_pub->bcmerror), BCME_STRLEN); - ((char *)arg)[BCME_STRLEN - 1] = 0x00; - break; - - case IOV_GVAL(IOV_BCMERROR): - int_val = (int32)dhd_pub->bcmerror; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_WDTICK): - int_val = (int32)dhd_watchdog_ms; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_WDTICK): - if (!dhd_pub->up) { - bcmerror = BCME_NOTUP; - break; - } - dhd_os_wd_timer(dhd_pub, (uint)int_val); - break; - - case IOV_GVAL(IOV_DUMP): - bcmerror = dhd_dump(dhd_pub, arg, len); - break; - -#ifdef DHD_DEBUG - case IOV_GVAL(IOV_DCONSOLE_POLL): - int_val = (int32)dhd_console_ms; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DCONSOLE_POLL): - dhd_console_ms = (uint)int_val; - break; - - case IOV_SVAL(IOV_CONS): - if (len > 0) - bcmerror = dhd_bus_console_in(dhd_pub, arg, len - 1); - break; -#endif - - case IOV_SVAL(IOV_CLEARCOUNTS): - dhd_pub->tx_packets = dhd_pub->rx_packets = 0; - dhd_pub->tx_errors = dhd_pub->rx_errors = 0; - dhd_pub->tx_ctlpkts = dhd_pub->rx_ctlpkts = 0; - dhd_pub->tx_ctlerrs = dhd_pub->rx_ctlerrs = 0; - dhd_pub->rx_dropped = 0; - dhd_pub->rx_readahead_cnt = 0; - dhd_pub->tx_realloc = 0; - dhd_pub->wd_dpc_sched = 0; - memset(&dhd_pub->dstats, 0, sizeof(dhd_pub->dstats)); - dhd_bus_clearcounts(dhd_pub); - break; - - - case IOV_GVAL(IOV_IOCTLTIMEOUT): { - int_val = (int32)dhd_os_get_ioctl_resp_timeout(); - bcopy(&int_val, arg, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_IOCTLTIMEOUT): { - if (int_val <= 0) - bcmerror = BCME_BADARG; - else - dhd_os_set_ioctl_resp_timeout((unsigned int)int_val); - break; - } - - - default: - bcmerror = BCME_UNSUPPORTED; - break; - } - -exit: - return bcmerror; -} - -/* Store the status of a connection attempt for later retrieval by an iovar */ -void -dhd_store_conn_status(uint32 event, uint32 status, uint32 reason) -{ - /* Do not overwrite a WLC_E_PRUNE with a WLC_E_SET_SSID - * because an encryption/rsn mismatch results in both events, and - * the important information is in the WLC_E_PRUNE. - */ - if (!(event == WLC_E_SET_SSID && status == WLC_E_STATUS_FAIL && - dhd_conn_event == WLC_E_PRUNE)) { - dhd_conn_event = event; - dhd_conn_status = status; - dhd_conn_reason = reason; - } -} - -bool -dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec) -{ - void *p; - int eprec = -1; /* precedence to evict from */ - bool discard_oldest; - - /* Fast case, precedence queue is not full and we are also not - * exceeding total queue length - */ - if (!pktq_pfull(q, prec) && !pktq_full(q)) { - pktq_penq(q, prec, pkt); - return TRUE; - } - - /* Determine precedence from which to evict packet, if any */ - if (pktq_pfull(q, prec)) - eprec = prec; - else if (pktq_full(q)) { - p = pktq_peek_tail(q, &eprec); - ASSERT(p); - if (eprec > prec) - return FALSE; - } - - /* Evict if needed */ - if (eprec >= 0) { - /* Detect queueing to unconfigured precedence */ - ASSERT(!pktq_pempty(q, eprec)); - discard_oldest = AC_BITMAP_TST(dhdp->wme_dp, eprec); - if (eprec == prec && !discard_oldest) - return FALSE; /* refuse newer (incoming) packet */ - /* Evict packet according to discard policy */ - p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q, eprec); - if (p == NULL) { - DHD_ERROR(("%s: pktq_penq() failed, oldest %d.", - __FUNCTION__, discard_oldest)); - ASSERT(p); - } - - PKTFREE(dhdp->osh, p, TRUE); - } - - /* Enqueue */ - p = pktq_penq(q, prec, pkt); - if (p == NULL) { - DHD_ERROR(("%s: pktq_penq() failed.", __FUNCTION__)); - ASSERT(p); - } - - return TRUE; -} - -static int -dhd_iovar_op(dhd_pub_t *dhd_pub, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - int bcmerror = 0; - int val_size; - const bcm_iovar_t *vi = NULL; - uint32 actionid; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - ASSERT(name); - ASSERT(len >= 0); - - /* Get MUST have return space */ - ASSERT(set || (arg && len)); - - /* Set does NOT take qualifiers */ - ASSERT(!set || (!params && !plen)); - - if ((vi = bcm_iovar_lookup(dhd_iovars, name)) == NULL) { - bcmerror = BCME_UNSUPPORTED; - goto exit; - } - - DHD_CTL(("%s: %s %s, len %d plen %d\n", __FUNCTION__, - name, (set ? "set" : "get"), len, plen)); - - /* set up 'params' pointer in case this is a set command so that - * the convenience int and bool code can be common to set and get - */ - if (params == NULL) { - params = arg; - plen = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - /* all other types are integer sized */ - val_size = sizeof(int); - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - bcmerror = dhd_doiovar(dhd_pub, vi, actionid, name, params, plen, arg, len, val_size); - -exit: - return bcmerror; -} - -int -dhd_ioctl(dhd_pub_t *dhd_pub, dhd_ioctl_t *ioc, void *buf, uint buflen) -{ - int bcmerror = 0; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (!buf) return BCME_BADARG; - - switch (ioc->cmd) { - case DHD_GET_MAGIC: - if (buflen < sizeof(int)) - bcmerror = BCME_BUFTOOSHORT; - else - *(int*)buf = DHD_IOCTL_MAGIC; - break; - - case DHD_GET_VERSION: - if (buflen < sizeof(int)) - bcmerror = -BCME_BUFTOOSHORT; - else - *(int*)buf = DHD_IOCTL_VERSION; - break; - - case DHD_GET_VAR: - case DHD_SET_VAR: { - char *arg; - uint arglen; - - /* scan past the name to any arguments */ - for (arg = buf, arglen = buflen; *arg && arglen; arg++, arglen--); - - if (*arg) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - /* account for the NUL terminator */ - arg++, arglen--; - - /* call with the appropriate arguments */ - if (ioc->cmd == DHD_GET_VAR) - bcmerror = dhd_iovar_op(dhd_pub, buf, arg, arglen, - buf, buflen, IOV_GET); - else - bcmerror = dhd_iovar_op(dhd_pub, buf, NULL, 0, arg, arglen, IOV_SET); - if (bcmerror != BCME_UNSUPPORTED) - break; - - /* not in generic table, try protocol module */ - if (ioc->cmd == DHD_GET_VAR) - bcmerror = dhd_prot_iovar_op(dhd_pub, buf, arg, - arglen, buf, buflen, IOV_GET); - else - bcmerror = dhd_prot_iovar_op(dhd_pub, buf, - NULL, 0, arg, arglen, IOV_SET); - if (bcmerror != BCME_UNSUPPORTED) - break; - - /* if still not found, try bus module */ - if (ioc->cmd == DHD_GET_VAR) - bcmerror = dhd_bus_iovar_op(dhd_pub, buf, - arg, arglen, buf, buflen, IOV_GET); - else - bcmerror = dhd_bus_iovar_op(dhd_pub, buf, - NULL, 0, arg, arglen, IOV_SET); - - break; - } - - default: - bcmerror = BCME_UNSUPPORTED; - } - - return bcmerror; -} - - -#ifdef SHOW_EVENTS -static void -wl_show_host_event(wl_event_msg_t *event, void *event_data) -{ - uint i, status, reason; - bool group = FALSE, flush_txq = FALSE, link = FALSE; - char *auth_str, *event_name; - uchar *buf; - char err_msg[256], eabuf[ETHER_ADDR_STR_LEN]; - static struct {uint event; char *event_name;} event_names[] = { - {WLC_E_SET_SSID, "SET_SSID"}, - {WLC_E_JOIN, "JOIN"}, - {WLC_E_START, "START"}, - {WLC_E_AUTH, "AUTH"}, - {WLC_E_AUTH_IND, "AUTH_IND"}, - {WLC_E_DEAUTH, "DEAUTH"}, - {WLC_E_DEAUTH_IND, "DEAUTH_IND"}, - {WLC_E_ASSOC, "ASSOC"}, - {WLC_E_ASSOC_IND, "ASSOC_IND"}, - {WLC_E_REASSOC, "REASSOC"}, - {WLC_E_REASSOC_IND, "REASSOC_IND"}, - {WLC_E_DISASSOC, "DISASSOC"}, - {WLC_E_DISASSOC_IND, "DISASSOC_IND"}, - {WLC_E_QUIET_START, "START_QUIET"}, - {WLC_E_QUIET_END, "END_QUIET"}, - {WLC_E_BEACON_RX, "BEACON_RX"}, - {WLC_E_LINK, "LINK"}, - {WLC_E_MIC_ERROR, "MIC_ERROR"}, - {WLC_E_NDIS_LINK, "NDIS_LINK"}, - {WLC_E_ROAM, "ROAM"}, - {WLC_E_TXFAIL, "TXFAIL"}, - {WLC_E_PMKID_CACHE, "PMKID_CACHE"}, - {WLC_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, - {WLC_E_PRUNE, "PRUNE"}, - {WLC_E_AUTOAUTH, "AUTOAUTH"}, - {WLC_E_EAPOL_MSG, "EAPOL_MSG"}, - {WLC_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, - {WLC_E_ADDTS_IND, "ADDTS_IND"}, - {WLC_E_DELTS_IND, "DELTS_IND"}, - {WLC_E_BCNSENT_IND, "BCNSENT_IND"}, - {WLC_E_BCNRX_MSG, "BCNRX_MSG"}, - {WLC_E_BCNLOST_MSG, "BCNLOST_MSG"}, - {WLC_E_ROAM_PREP, "ROAM_PREP"}, - {WLC_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, - {WLC_E_PFN_NET_LOST, "PNO_NET_LOST"}, - {WLC_E_RESET_COMPLETE, "RESET_COMPLETE"}, - {WLC_E_JOIN_START, "JOIN_START"}, - {WLC_E_ROAM_START, "ROAM_START"}, - {WLC_E_ASSOC_START, "ASSOC_START"}, - {WLC_E_IBSS_ASSOC, "IBSS_ASSOC"}, - {WLC_E_RADIO, "RADIO"}, - {WLC_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, - {WLC_E_PROBREQ_MSG, "PROBREQ_MSG"}, - {WLC_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, - {WLC_E_PSK_SUP, "PSK_SUP"}, - {WLC_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, - {WLC_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, - {WLC_E_ICV_ERROR, "ICV_ERROR"}, - {WLC_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, - {WLC_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, - {WLC_E_TRACE, "TRACE"}, - {WLC_E_ACTION_FRAME, "ACTION FRAME"}, - {WLC_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, - {WLC_E_IF, "IF"}, - {WLC_E_RSSI, "RSSI"}, - {WLC_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"} - }; - uint event_type, flags, auth_type, datalen; - event_type = ntoh32(event->event_type); - flags = ntoh16(event->flags); - status = ntoh32(event->status); - reason = ntoh32(event->reason); - auth_type = ntoh32(event->auth_type); - datalen = ntoh32(event->datalen); - /* debug dump of event messages */ - sprintf(eabuf, "%02x:%02x:%02x:%02x:%02x:%02x", - (uchar)event->addr.octet[0]&0xff, - (uchar)event->addr.octet[1]&0xff, - (uchar)event->addr.octet[2]&0xff, - (uchar)event->addr.octet[3]&0xff, - (uchar)event->addr.octet[4]&0xff, - (uchar)event->addr.octet[5]&0xff); - - event_name = "UNKNOWN"; - for (i = 0; i < ARRAYSIZE(event_names); i++) { - if (event_names[i].event == event_type) - event_name = event_names[i].event_name; - } - - DHD_EVENT(("EVENT: %s, event ID = %d\n", event_name, event_type)); - - if (flags & WLC_EVENT_MSG_LINK) - link = TRUE; - if (flags & WLC_EVENT_MSG_GROUP) - group = TRUE; - if (flags & WLC_EVENT_MSG_FLUSHTXQ) - flush_txq = TRUE; - - switch (event_type) { - case WLC_E_START: - case WLC_E_DEAUTH: - case WLC_E_DISASSOC: - DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); - break; - - case WLC_E_ASSOC_IND: - case WLC_E_REASSOC_IND: - DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); - break; - - case WLC_E_ASSOC: - case WLC_E_REASSOC: - if (status == WLC_E_STATUS_SUCCESS) { - DHD_EVENT(("MACEVENT: %s, MAC %s, SUCCESS\n", event_name, eabuf)); - } else if (status == WLC_E_STATUS_TIMEOUT) { - DHD_EVENT(("MACEVENT: %s, MAC %s, TIMEOUT\n", event_name, eabuf)); - } else if (status == WLC_E_STATUS_FAIL) { - DHD_EVENT(("MACEVENT: %s, MAC %s, FAILURE, reason %d\n", - event_name, eabuf, (int)reason)); - } else { - DHD_EVENT(("MACEVENT: %s, MAC %s, unexpected status %d\n", - event_name, eabuf, (int)status)); - } - break; - - case WLC_E_DEAUTH_IND: - case WLC_E_DISASSOC_IND: - DHD_EVENT(("MACEVENT: %s, MAC %s, reason %d\n", event_name, eabuf, (int)reason)); - break; - - case WLC_E_AUTH: - case WLC_E_AUTH_IND: - if (auth_type == DOT11_OPEN_SYSTEM) - auth_str = "Open System"; - else if (auth_type == DOT11_SHARED_KEY) - auth_str = "Shared Key"; - else { - sprintf(err_msg, "AUTH unknown: %d", (int)auth_type); - auth_str = err_msg; - } - if (event_type == WLC_E_AUTH_IND) { - DHD_EVENT(("MACEVENT: %s, MAC %s, %s\n", event_name, eabuf, auth_str)); - } else if (status == WLC_E_STATUS_SUCCESS) { - DHD_EVENT(("MACEVENT: %s, MAC %s, %s, SUCCESS\n", - event_name, eabuf, auth_str)); - } else if (status == WLC_E_STATUS_TIMEOUT) { - DHD_EVENT(("MACEVENT: %s, MAC %s, %s, TIMEOUT\n", - event_name, eabuf, auth_str)); - } else if (status == WLC_E_STATUS_FAIL) { - DHD_EVENT(("MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n", - event_name, eabuf, auth_str, (int)reason)); - } - - break; - - case WLC_E_JOIN: - case WLC_E_ROAM: - case WLC_E_SET_SSID: - if (status == WLC_E_STATUS_SUCCESS) { - DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); - } else if (status == WLC_E_STATUS_FAIL) { - DHD_EVENT(("MACEVENT: %s, failed\n", event_name)); - } else if (status == WLC_E_STATUS_NO_NETWORKS) { - DHD_EVENT(("MACEVENT: %s, no networks found\n", event_name)); - } else { - DHD_EVENT(("MACEVENT: %s, unexpected status %d\n", - event_name, (int)status)); - } - break; - - case WLC_E_BEACON_RX: - if (status == WLC_E_STATUS_SUCCESS) { - DHD_EVENT(("MACEVENT: %s, SUCCESS\n", event_name)); - } else if (status == WLC_E_STATUS_FAIL) { - DHD_EVENT(("MACEVENT: %s, FAIL\n", event_name)); - } else { - DHD_EVENT(("MACEVENT: %s, status %d\n", event_name, status)); - } - break; - - case WLC_E_LINK: - DHD_EVENT(("MACEVENT: %s %s\n", event_name, link?"UP":"DOWN")); - break; - - case WLC_E_MIC_ERROR: - DHD_EVENT(("MACEVENT: %s, MAC %s, Group %d, Flush %d\n", - event_name, eabuf, group, flush_txq)); - break; - - case WLC_E_ICV_ERROR: - case WLC_E_UNICAST_DECODE_ERROR: - case WLC_E_MULTICAST_DECODE_ERROR: - DHD_EVENT(("MACEVENT: %s, MAC %s\n", - event_name, eabuf)); - break; - - case WLC_E_TXFAIL: - DHD_EVENT(("MACEVENT: %s, RA %s\n", event_name, eabuf)); - break; - - case WLC_E_SCAN_COMPLETE: - case WLC_E_PMKID_CACHE: - DHD_EVENT(("MACEVENT: %s\n", event_name)); - break; - - case WLC_E_PFN_NET_FOUND: - case WLC_E_PFN_NET_LOST: - case WLC_E_PFN_SCAN_COMPLETE: - DHD_EVENT(("PNOEVENT: %s\n", event_name)); - break; - - case WLC_E_PSK_SUP: - case WLC_E_PRUNE: - DHD_EVENT(("MACEVENT: %s, status %d, reason %d\n", - event_name, (int)status, (int)reason)); - break; - - case WLC_E_TRACE: - { - static uint32 seqnum_prev = 0; - msgtrace_hdr_t hdr; - uint32 nblost; - char *s, *p; - - buf = (uchar *) event_data; - memcpy(&hdr, buf, MSGTRACE_HDRLEN); - - if (hdr.version != MSGTRACE_VERSION) { - printf("\nMACEVENT: %s [unsupported version --> " - "dhd version:%d dongle version:%d]\n", - event_name, MSGTRACE_VERSION, hdr.version); - /* Reset datalen to avoid display below */ - datalen = 0; - break; - } - - /* There are 2 bytes available at the end of data */ - buf[MSGTRACE_HDRLEN + ntoh16(hdr.len)] = '\0'; - - if (ntoh32(hdr.discarded_bytes) || ntoh32(hdr.discarded_printf)) { - printf("\nWLC_E_TRACE: [Discarded traces in dongle -->" - "discarded_bytes %d discarded_printf %d]\n", - ntoh32(hdr.discarded_bytes), ntoh32(hdr.discarded_printf)); - } - - nblost = ntoh32(hdr.seqnum) - seqnum_prev - 1; - if (nblost > 0) { - printf("\nWLC_E_TRACE: [Event lost --> seqnum %d nblost %d\n", - ntoh32(hdr.seqnum), nblost); - } - seqnum_prev = ntoh32(hdr.seqnum); - - /* Display the trace buffer. Advance from \n to \n to avoid display big - * printf (issue with Linux printk ) - */ - p = (char *)&buf[MSGTRACE_HDRLEN]; - while ((s = strstr(p, "\n")) != NULL) { - *s = '\0'; - printf("%s\n", p); - p = s + 1; - } - printf("%s\n", p); - - /* Reset datalen to avoid display below */ - datalen = 0; - } - break; - - - case WLC_E_RSSI: - DHD_EVENT(("MACEVENT: %s %d\n", event_name, ntoh32(*((int *)event_data)))); - break; - - default: - DHD_EVENT(("MACEVENT: %s %d, MAC %s, status %d, reason %d, auth %d\n", - event_name, event_type, eabuf, (int)status, (int)reason, - (int)auth_type)); - break; - } - - /* show any appended data */ - if (datalen) { - buf = (uchar *) event_data; - DHD_EVENT((" data (%d) : ", datalen)); - for (i = 0; i < datalen; i++) - DHD_EVENT((" 0x%02x ", *buf++)); - DHD_EVENT(("\n")); - } -} -#endif /* SHOW_EVENTS */ - -int -wl_host_event(struct dhd_info *dhd, int *ifidx, void *pktdata, - wl_event_msg_t *event, void **data_ptr) -{ - /* check whether packet is a BRCM event pkt */ - bcm_event_t *pvt_data = (bcm_event_t *)pktdata; - char *event_data; - uint32 type, status; - uint16 flags; - int evlen; - - if (bcmp(BRCM_OUI, &pvt_data->bcm_hdr.oui[0], DOT11_OUI_LEN)) { - DHD_ERROR(("%s: mismatched OUI, bailing\n", __FUNCTION__)); - return (BCME_ERROR); - } - - /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */ - if (ntoh16_ua((void *)&pvt_data->bcm_hdr.usr_subtype) != BCMILCP_BCM_SUBTYPE_EVENT) { - DHD_ERROR(("%s: mismatched subtype, bailing\n", __FUNCTION__)); - return (BCME_ERROR); - } - - *data_ptr = &pvt_data[1]; - event_data = *data_ptr; - - /* memcpy since BRCM event pkt may be unaligned. */ - memcpy(event, &pvt_data->event, sizeof(wl_event_msg_t)); - - type = ntoh32_ua((void *)&event->event_type); - flags = ntoh16_ua((void *)&event->flags); - status = ntoh32_ua((void *)&event->status); - evlen = ntoh32_ua((void *)&event->datalen) + sizeof(bcm_event_t); - - switch (type) { - case WLC_E_IF: - { - dhd_if_event_t *ifevent = (dhd_if_event_t *)event_data; - DHD_TRACE(("%s: if event\n", __FUNCTION__)); - - if (ifevent->ifidx > 0 && ifevent->ifidx < DHD_MAX_IFS) - { - if (ifevent->action == WLC_E_IF_ADD) - dhd_add_if(dhd, ifevent->ifidx, - NULL, event->ifname, - pvt_data->eth.ether_dhost, - ifevent->flags, ifevent->bssidx); - else - dhd_del_if(dhd, ifevent->ifidx); - } else { - DHD_ERROR(("%s: Invalid ifidx %d for %s\n", - __FUNCTION__, ifevent->ifidx, event->ifname)); - } - } - /* send up the if event: btamp user needs it */ - *ifidx = dhd_ifname2idx(dhd, event->ifname); - /* push up to external supp/auth */ - dhd_event(dhd, (char *)pvt_data, evlen, *ifidx); - break; - - -#ifdef P2P - case WLC_E_NDIS_LINK: - break; -#endif - /* fall through */ - /* These are what external supplicant/authenticator wants */ - case WLC_E_LINK: - case WLC_E_ASSOC_IND: - case WLC_E_REASSOC_IND: - case WLC_E_DISASSOC_IND: - case WLC_E_MIC_ERROR: - default: - /* Fall through: this should get _everything_ */ - - *ifidx = dhd_ifname2idx(dhd, event->ifname); - /* push up to external supp/auth */ - dhd_event(dhd, (char *)pvt_data, evlen, *ifidx); - DHD_TRACE(("%s: MAC event %d, flags %x, status %x\n", - __FUNCTION__, type, flags, status)); - - /* put it back to WLC_E_NDIS_LINK */ - if (type == WLC_E_NDIS_LINK) { - uint32 temp; - - temp = ntoh32_ua((void *)&event->event_type); - DHD_TRACE(("Converted to WLC_E_LINK type %d\n", temp)); - - temp = ntoh32(WLC_E_NDIS_LINK); - memcpy((void *)(&pvt_data->event.event_type), &temp, - sizeof(pvt_data->event.event_type)); - } - break; - } - -#ifdef SHOW_EVENTS - wl_show_host_event(event, event_data); -#endif /* SHOW_EVENTS */ - - return (BCME_OK); -} - - -void -wl_event_to_host_order(wl_event_msg_t *evt) -{ - /* Event struct members passed from dongle to host are stored in network - * byte order. Convert all members to host-order. - */ - evt->event_type = ntoh32(evt->event_type); - evt->flags = ntoh16(evt->flags); - evt->status = ntoh32(evt->status); - evt->reason = ntoh32(evt->reason); - evt->auth_type = ntoh32(evt->auth_type); - evt->datalen = ntoh32(evt->datalen); - evt->version = ntoh16(evt->version); -} - -void print_buf(void *pbuf, int len, int bytes_per_line) -{ - int i, j = 0; - unsigned char *buf = pbuf; - - if (bytes_per_line == 0) { - bytes_per_line = len; - } - - for (i = 0; i < len; i++) { - printf("%2.2x", *buf++); - j++; - if (j == bytes_per_line) { - printf("\n"); - j = 0; - } else { - printf(":"); - } - } - printf("\n"); -} - -#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) - -#ifdef PKT_FILTER_SUPPORT -/* Convert user's input in hex pattern to byte-size mask */ -static int -wl_pattern_atoh(char *src, char *dst) -{ - int i; - if (strncmp(src, "0x", 2) != 0 && - strncmp(src, "0X", 2) != 0) { - DHD_ERROR(("Mask invalid format. Needs to start with 0x\n")); - return -1; - } - src = src + 2; /* Skip past 0x */ - if (strlen(src) % 2 != 0) { - DHD_ERROR(("Mask invalid format. Needs to be of even length\n")); - return -1; - } - for (i = 0; *src != '\0'; i++) { - char num[3]; - strncpy(num, src, 2); - num[2] = '\0'; - dst[i] = (uint8)strtoul(num, NULL, 16); - src += 2; - } - return i; -} - -void -dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode) -{ - char *argv[8]; - int i = 0; - const char *str; - int buf_len; - int str_len; - char *arg_save = 0, *arg_org = 0; - int rc; - char buf[128]; - wl_pkt_filter_enable_t enable_parm; - wl_pkt_filter_enable_t * pkt_filterp; - - if (!arg) - return; - - if (!(arg_save = MALLOC(dhd->osh, strlen(arg) + 1))) { - DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - goto fail; - } - arg_org = arg_save; - memcpy(arg_save, arg, strlen(arg) + 1); - - argv[i] = bcmstrtok(&arg_save, " ", 0); - - i = 0; - if (NULL == argv[i]) { - DHD_ERROR(("No args provided\n")); - goto fail; - } - - str = "pkt_filter_enable"; - str_len = strlen(str); - strncpy(buf, str, str_len); - buf[str_len] = '\0'; - buf_len = str_len + 1; - - pkt_filterp = (wl_pkt_filter_enable_t *)(buf + str_len + 1); - - /* Parse packet filter id. */ - enable_parm.id = htod32(strtoul(argv[i], NULL, 0)); - - /* Parse enable/disable value. */ - enable_parm.enable = htod32(enable); - - buf_len += sizeof(enable_parm); - memcpy((char *)pkt_filterp, - &enable_parm, - sizeof(enable_parm)); - - /* Enable/disable the specified filter. */ - rc = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, buf_len); - rc = rc >= 0 ? 0 : rc; - if (rc) - DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", - __FUNCTION__, arg, rc)); - else - DHD_TRACE(("%s: successfully added pktfilter %s\n", - __FUNCTION__, arg)); - - /* Contorl the master mode */ - bcm_mkiovar("pkt_filter_mode", (char *)&master_mode, 4, buf, sizeof(buf)); - rc = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf)); - rc = rc >= 0 ? 0 : rc; - if (rc) - DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", - __FUNCTION__, arg, rc)); - -fail: - if (arg_org) - MFREE(dhd->osh, arg_org, strlen(arg) + 1); -} - -void -dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg) -{ - const char *str; - wl_pkt_filter_t pkt_filter; - wl_pkt_filter_t *pkt_filterp; - int buf_len; - int str_len; - int rc; - uint32 mask_size; - uint32 pattern_size; - char *argv[8], * buf = 0; - int i = 0; - char *arg_save = 0, *arg_org = 0; -#define BUF_SIZE 2048 - - if (!arg) - return; - - if (!(arg_save = MALLOC(dhd->osh, strlen(arg) + 1))) { - DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - goto fail; - } - - arg_org = arg_save; - - if (!(buf = MALLOC(dhd->osh, BUF_SIZE))) { - DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - goto fail; - } - - memcpy(arg_save, arg, strlen(arg) + 1); - - if (strlen(arg) > BUF_SIZE) { - DHD_ERROR(("Not enough buffer %d < %d\n", (int)strlen(arg), (int)sizeof(buf))); - goto fail; - } - - argv[i] = bcmstrtok(&arg_save, " ", 0); - while (argv[i++]) - argv[i] = bcmstrtok(&arg_save, " ", 0); - - i = 0; - if (NULL == argv[i]) { - DHD_ERROR(("No args provided\n")); - goto fail; - } - - str = "pkt_filter_add"; - str_len = strlen(str); - strncpy(buf, str, str_len); - buf[ str_len ] = '\0'; - buf_len = str_len + 1; - - pkt_filterp = (wl_pkt_filter_t *) (buf + str_len + 1); - - /* Parse packet filter id. */ - pkt_filter.id = htod32(strtoul(argv[i], NULL, 0)); - - if (NULL == argv[++i]) { - DHD_ERROR(("Polarity not provided\n")); - goto fail; - } - - /* Parse filter polarity. */ - pkt_filter.negate_match = htod32(strtoul(argv[i], NULL, 0)); - - if (NULL == argv[++i]) { - DHD_ERROR(("Filter type not provided\n")); - goto fail; - } - - /* Parse filter type. */ - pkt_filter.type = htod32(strtoul(argv[i], NULL, 0)); - - if (NULL == argv[++i]) { - DHD_ERROR(("Offset not provided\n")); - goto fail; - } - - /* Parse pattern filter offset. */ - pkt_filter.u.pattern.offset = htod32(strtoul(argv[i], NULL, 0)); - - if (NULL == argv[++i]) { - DHD_ERROR(("Bitmask not provided\n")); - goto fail; - } - - /* Parse pattern filter mask. */ - mask_size = - htod32(wl_pattern_atoh(argv[i], (char *) pkt_filterp->u.pattern.mask_and_pattern)); - - if (NULL == argv[++i]) { - DHD_ERROR(("Pattern not provided\n")); - goto fail; - } - - /* Parse pattern filter pattern. */ - pattern_size = - htod32(wl_pattern_atoh(argv[i], - (char *) &pkt_filterp->u.pattern.mask_and_pattern[mask_size])); - - if (mask_size != pattern_size) { - DHD_ERROR(("Mask and pattern not the same size\n")); - goto fail; - } - - pkt_filter.u.pattern.size_bytes = mask_size; - buf_len += WL_PKT_FILTER_FIXED_LEN; - buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size); - - /* Keep-alive attributes are set in local variable (keep_alive_pkt), and - ** then memcpy'ed into buffer (keep_alive_pktp) since there is no - ** guarantee that the buffer is properly aligned. - */ - memcpy((char *)pkt_filterp, - &pkt_filter, - WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN); - - rc = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, buf_len); - rc = rc >= 0 ? 0 : rc; - - if (rc) - DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", - __FUNCTION__, arg, rc)); - else - DHD_TRACE(("%s: successfully added pktfilter %s\n", - __FUNCTION__, arg)); - -fail: - if (arg_org) - MFREE(dhd->osh, arg_org, strlen(arg) + 1); - - if (buf) - MFREE(dhd->osh, buf, BUF_SIZE); -} -#endif - -#ifdef ARP_OFFLOAD_SUPPORT -void -dhd_arp_offload_set(dhd_pub_t * dhd, int arp_mode) -{ - char iovbuf[32]; - int retcode; - - bcm_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf)); - retcode = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - retcode = retcode >= 0 ? 0 : retcode; - if (retcode) - DHD_TRACE(("%s: failed to set ARP offload mode to 0x%x, retcode = %d\n", - __FUNCTION__, arp_mode, retcode)); - else - DHD_TRACE(("%s: successfully set ARP offload mode to 0x%x\n", - __FUNCTION__, arp_mode)); -} - -void -dhd_arp_offload_enable(dhd_pub_t * dhd, int arp_enable) -{ - char iovbuf[32]; - int retcode; - - bcm_mkiovar("arpoe", (char *)&arp_enable, 4, iovbuf, sizeof(iovbuf)); - retcode = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - retcode = retcode >= 0 ? 0 : retcode; - if (retcode) - DHD_TRACE(("%s: failed to enabe ARP offload to %d, retcode = %d\n", - __FUNCTION__, arp_enable, retcode)); - else - DHD_TRACE(("%s: successfully enabed ARP offload to %d\n", - __FUNCTION__, arp_enable)); -} -#endif - - -void dhd_arp_cleanup(dhd_pub_t *dhd) -{ -#ifdef ARP_OFFLOAD_SUPPORT - int ret = 0; - int iov_len = 0; - char iovbuf[128]; - - if (dhd == NULL) return; - - dhd_os_proto_block(dhd); - - iov_len = bcm_mkiovar("arp_hostip_clear", 0, 0, iovbuf, sizeof(iovbuf)); - if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, iov_len)) < 0) - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); - - iov_len = bcm_mkiovar("arp_table_clear", 0, 0, iovbuf, sizeof(iovbuf)); - if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, iov_len)) < 0) - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); - - dhd_os_proto_unblock(dhd); - -#endif /* ARP_OFFLOAD_SUPPORT */ -} - -void dhd_arp_offload_add_ip(dhd_pub_t *dhd, u32 ipaddr) -{ -#ifdef ARP_OFFLOAD_SUPPORT - int iov_len = 0; - char iovbuf[32]; - int retcode; - - dhd_os_proto_block(dhd); - - iov_len = bcm_mkiovar("arp_hostip", (char *)&ipaddr, 4, iovbuf, sizeof(iovbuf)); - retcode = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, iov_len); - - dhd_os_proto_unblock(dhd); - - if (retcode) - DHD_TRACE(("%s: ARP ip addr add failed, retcode = %d\n", - __FUNCTION__, retcode)); - else - DHD_TRACE(("%s: ARP ipaddr entry added\n", - __FUNCTION__)); -#endif /* ARP_OFFLOAD_SUPPORT */ -} - - -int dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen) -{ -#ifdef ARP_OFFLOAD_SUPPORT - int retcode; - int iov_len = 0; - - if (!buf) - return -1; - - dhd_os_proto_block(dhd); - - iov_len = bcm_mkiovar("arp_hostip", 0, 0, buf, buflen); - retcode = dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, buflen); - - dhd_os_proto_unblock(dhd); - - if (retcode) { - DHD_TRACE(("%s: ioctl WLC_GET_VAR error %d\n", - __FUNCTION__, retcode)); - - return -1; - } -#endif /* ARP_OFFLOAD_SUPPORT */ - return 0; -} - - -int -dhd_preinit_ioctls(dhd_pub_t *dhd) -{ - char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ - uint up = 0; - char buf[128], *ptr; - uint power_mode = PM_FAST; - uint32 dongle_align = DHD_SDALIGN; - uint32 glom = 0; - uint bcn_timeout = 4; - int scan_assoc_time = 40; - int scan_unassoc_time = 40; - uint32 listen_interval = LISTEN_INTERVAL; /* Default Listen Interval in Beacons */ -#if defined(SOFTAP) - uint dtim = 1; -#endif - int ret = 0; -#ifdef GET_CUSTOM_MAC_ENABLE - struct ether_addr ea_addr; -#endif /* GET_CUSTOM_MAC_ENABLE */ - - dhd_os_proto_block(dhd); - -#ifdef GET_CUSTOM_MAC_ENABLE - /* - ** Read MAC address from external customer place - ** NOTE that default mac address has to be present in otp or nvram file - ** to bring up firmware but unique per board mac address maybe provided - ** by customer code - */ - ret = dhd_custom_get_mac_address(ea_addr.octet); - if (!ret) { - bcm_mkiovar("cur_etheraddr", (void *)&ea_addr, ETHER_ADDR_LEN, buf, sizeof(buf)); - ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf)); - if (ret < 0) { - DHD_ERROR(("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret)); - } else - memcpy(dhd->mac.octet, (void *)&ea_addr, ETHER_ADDR_LEN); - } -#endif /* GET_CUSTOM_MAC_ENABLE */ - -#ifdef SET_RANDOM_MAC_SOFTAP - if (strstr(fw_path, "apsta") != NULL) { - uint rand_mac; - - srandom32((uint)jiffies); - rand_mac = random32(); - iovbuf[0] = 0x02; /* locally administered bit */ - iovbuf[1] = 0x1A; - iovbuf[2] = 0x11; - iovbuf[3] = (unsigned char)(rand_mac & 0x0F) | 0xF0; - iovbuf[4] = (unsigned char)(rand_mac >> 8); - iovbuf[5] = (unsigned char)(rand_mac >> 16); - - printk("Broadcom Dongle Host Driver mac=%02x:%02x:%02x:%02x:%02x:%02x\n", - iovbuf[0], iovbuf[1], iovbuf[2], iovbuf[3], iovbuf[4], iovbuf[5]); - - bcm_mkiovar("cur_etheraddr", (void *)iovbuf, ETHER_ADDR_LEN, buf, sizeof(buf)); - ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf)); - if (ret < 0) { - DHD_ERROR(("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret)); - } else - memcpy(dhd->mac.octet, iovbuf, ETHER_ADDR_LEN); - } -#endif /* SET_RANDOM_MAC_SOFTAP */ - - /* Set Country code */ - if (dhd->dhd_cspec.ccode[0] != 0) { - bcm_mkiovar("country", (char *)&dhd->dhd_cspec, \ - sizeof(wl_country_t), iovbuf, sizeof(iovbuf)); - if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf))) < 0) { - DHD_ERROR(("%s: country code setting failed\n", __FUNCTION__)); - } - } - - /* Set Listen Interval */ - bcm_mkiovar("assoc_listen", (char *)&listen_interval, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf))) < 0) - DHD_ERROR(("%s assoc_listen failed %d\n", __FUNCTION__, ret)); - - /* query for 'ver' to get version info from firmware */ - memset(buf, 0, sizeof(buf)); - ptr = buf; - bcm_mkiovar("ver", 0, 0, buf, sizeof(buf)); - dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, sizeof(buf)); - bcmstrtok(&ptr, "\n", 0); - /* Print fw version info */ - DHD_ERROR(("Firmware version = %s\n", buf)); - - /* Set PowerSave mode */ - dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode)); - - /* Match Host and Dongle rx alignment */ - bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - - /* disable glom option per default */ - bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - - /* Setup timeout if Beacons are lost and roam is off to report link down */ - bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - - /* Enable/Disable build-in roaming to allowed ext supplicant to take of romaing */ - bcm_mkiovar("roam_off", (char *)&dhd_roam, 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - -#if defined(SOFTAP) - if (ap_fw_loaded == TRUE) { - dhdcdc_set_ioctl(dhd, 0, WLC_SET_DTIMPRD, (char *)&dtim, sizeof(dtim)); - } -#endif - - if (dhd_roam == 0) - { - /* set internal roaming roaming parameters */ - int roam_scan_period = 30; /* in sec */ - int roam_fullscan_period = 120; /* in sec */ - int roam_trigger = -85; - int roam_delta = 15; - int band; - int band_temp_set = WLC_BAND_2G; - - if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_ROAM_SCAN_PERIOD, \ - (char *)&roam_scan_period, sizeof(roam_scan_period)) < 0) - DHD_ERROR(("%s: roam scan setup failed\n", __FUNCTION__)); - - bcm_mkiovar("fullroamperiod", (char *)&roam_fullscan_period, \ - 4, iovbuf, sizeof(iovbuf)); - if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, \ - iovbuf, sizeof(iovbuf)) < 0) - DHD_ERROR(("%s: roam fullscan setup failed\n", __FUNCTION__)); - - if (dhdcdc_query_ioctl(dhd, 0, WLC_GET_BAND, \ - (char *)&band, sizeof(band)) < 0) - DHD_ERROR(("%s: roam delta setting failed\n", __FUNCTION__)); - else { - if ((band == WLC_BAND_AUTO) || (band == WLC_BAND_ALL)) - { - /* temp set band to insert new roams values */ - if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_BAND, \ - (char *)&band_temp_set, sizeof(band_temp_set)) < 0) - DHD_ERROR(("%s: local band seting failed\n", __FUNCTION__)); - } - if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_ROAM_DELTA, \ - (char *)&roam_delta, sizeof(roam_delta)) < 0) - DHD_ERROR(("%s: roam delta setting failed\n", __FUNCTION__)); - - if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_ROAM_TRIGGER, \ - (char *)&roam_trigger, sizeof(roam_trigger)) < 0) - DHD_ERROR(("%s: roam trigger setting failed\n", __FUNCTION__)); - - /* Restore original band settinngs */ - if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_BAND, \ - (char *)&band, sizeof(band)) < 0) - DHD_ERROR(("%s: Original band restore failed\n", __FUNCTION__)); - } - } - - /* Force STA UP */ - if (dhd_radio_up) - dhdcdc_set_ioctl(dhd, 0, WLC_UP, (char *)&up, sizeof(up)); - - /* Setup event_msgs */ - bcm_mkiovar("event_msgs", dhd->eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - - dhdcdc_set_ioctl(dhd, 0, WLC_SET_SCAN_CHANNEL_TIME, (char *)&scan_assoc_time, - sizeof(scan_assoc_time)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_SCAN_UNASSOC_TIME, (char *)&scan_unassoc_time, - sizeof(scan_unassoc_time)); - -#ifdef ARP_OFFLOAD_SUPPORT - /* Set and enable ARP offload feature */ - if (dhd_arp_enable) - dhd_arp_offload_set(dhd, dhd_arp_mode); - dhd_arp_offload_enable(dhd, dhd_arp_enable); -#endif /* ARP_OFFLOAD_SUPPORT */ - -#ifdef PKT_FILTER_SUPPORT - { - int i; - /* Set up pkt filter */ - if (dhd_pkt_filter_enable) { - for (i = 0; i < dhd->pktfilter_count; i++) { - dhd_pktfilter_offload_set(dhd, dhd->pktfilter[i]); - dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i], - dhd_pkt_filter_init, dhd_master_mode); - } - } - } -#endif /* PKT_FILTER_SUPPORT */ - -#if defined(KEEP_ALIVE) - { - /* Set Keep Alive : be sure to use FW with -keepalive */ - int res; - - if (ap_fw_loaded == FALSE) { - if ((res = dhd_keep_alive_onoff(dhd, 1)) < 0) - DHD_ERROR(("%s set keeplive failed %d\n", \ - __FUNCTION__, res)); - } - } -#endif - - dhd_os_proto_unblock(dhd); - - return 0; -} - -#ifdef SIMPLE_ISCAN - -uint iscan_thread_id; -iscan_buf_t * iscan_chain = 0; - -iscan_buf_t * -dhd_iscan_allocate_buf(dhd_pub_t *dhd, iscan_buf_t **iscanbuf) -{ - iscan_buf_t *iscanbuf_alloc = 0; - iscan_buf_t *iscanbuf_head; - - dhd_iscan_lock(); - - iscanbuf_alloc = (iscan_buf_t*)MALLOC(dhd->osh, sizeof(iscan_buf_t)); - if (iscanbuf_alloc == NULL) - goto fail; - - iscanbuf_alloc->next = NULL; - iscanbuf_head = *iscanbuf; - - DHD_ISCAN(("%s: addr of allocated node = 0x%X" - "addr of iscanbuf_head = 0x%X dhd = 0x%X\n", - __FUNCTION__, iscanbuf_alloc, iscanbuf_head, dhd)); - - if (iscanbuf_head == NULL) { - *iscanbuf = iscanbuf_alloc; - DHD_ISCAN(("%s: Head is allocated\n", __FUNCTION__)); - goto fail; - } - - while (iscanbuf_head->next) - iscanbuf_head = iscanbuf_head->next; - - iscanbuf_head->next = iscanbuf_alloc; - -fail: - dhd_iscan_unlock(); - return iscanbuf_alloc; -} - -void -dhd_iscan_free_buf(void *dhdp, iscan_buf_t *iscan_delete) -{ - iscan_buf_t *iscanbuf_free = 0; - iscan_buf_t *iscanbuf_prv = 0; - iscan_buf_t *iscanbuf_cur = iscan_chain; - dhd_pub_t *dhd = dhd_bus_pub(dhdp); - - dhd_iscan_lock(); - /* If iscan_delete is null then delete the entire - * chain or else delete specific one provided - */ - if (!iscan_delete) { - while (iscanbuf_cur) { - iscanbuf_free = iscanbuf_cur; - iscanbuf_cur = iscanbuf_cur->next; - iscanbuf_free->next = 0; - MFREE(dhd->osh, iscanbuf_free, sizeof(iscan_buf_t)); - } - iscan_chain = 0; - } else { - while (iscanbuf_cur) { - if (iscanbuf_cur == iscan_delete) - break; - iscanbuf_prv = iscanbuf_cur; - iscanbuf_cur = iscanbuf_cur->next; - } - if (iscanbuf_prv) - iscanbuf_prv->next = iscan_delete->next; - - iscan_delete->next = 0; - MFREE(dhd->osh, iscan_delete, sizeof(iscan_buf_t)); - - if (!iscanbuf_prv) - iscan_chain = 0; - } - dhd_iscan_unlock(); -} - -iscan_buf_t * -dhd_iscan_result_buf(void) -{ - return iscan_chain; -} - - - -/* -* print scan cache -* print partial iscan_skip list differently -*/ -int -dhd_iscan_print_cache(iscan_buf_t *iscan_skip) -{ - int i = 0, l = 0; - iscan_buf_t *iscan_cur; - wl_iscan_results_t *list; - wl_scan_results_t *results; - wl_bss_info_t UNALIGNED *bi; - - dhd_iscan_lock(); - - iscan_cur = dhd_iscan_result_buf(); - - while (iscan_cur) { - list = (wl_iscan_results_t *)iscan_cur->iscan_buf; - if (!list) - break; - - results = (wl_scan_results_t *)&list->results; - if (!results) - break; - - if (results->version != WL_BSS_INFO_VERSION) { - DHD_ISCAN(("%s: results->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, results->version)); - goto done; - } - - bi = results->bss_info; - for (i = 0; i < results->count; i++) { - if (!bi) - break; - - DHD_ISCAN(("%s[%2.2d:%2.2d] %X:%X:%X:%X:%X:%X\n", - iscan_cur != iscan_skip?"BSS":"bss", l, i, - bi->BSSID.octet[0], bi->BSSID.octet[1], bi->BSSID.octet[2], - bi->BSSID.octet[3], bi->BSSID.octet[4], bi->BSSID.octet[5])); - - bi = (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)); - } - iscan_cur = iscan_cur->next; - l++; - } - -done: - dhd_iscan_unlock(); - return 0; -} - -/* -* delete disappeared AP from specific scan cache but skip partial list in iscan_skip -*/ -int -dhd_iscan_delete_bss(void *dhdp, void *addr, iscan_buf_t *iscan_skip) -{ - int i = 0, j = 0, l = 0; - iscan_buf_t *iscan_cur; - wl_iscan_results_t *list; - wl_scan_results_t *results; - wl_bss_info_t UNALIGNED *bi, *bi_new, *bi_next; - - uchar *s_addr = addr; - - dhd_iscan_lock(); - DHD_ISCAN(("%s: BSS to remove %X:%X:%X:%X:%X:%X\n", - __FUNCTION__, s_addr[0], s_addr[1], s_addr[2], - s_addr[3], s_addr[4], s_addr[5])); - - iscan_cur = dhd_iscan_result_buf(); - - while (iscan_cur) { - if (iscan_cur != iscan_skip) { - list = (wl_iscan_results_t *)iscan_cur->iscan_buf; - if (!list) - break; - - results = (wl_scan_results_t *)&list->results; - if (!results) - break; - - if (results->version != WL_BSS_INFO_VERSION) { - DHD_ERROR(("%s: results->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, results->version)); - goto done; - } - - bi = results->bss_info; - for (i = 0; i < results->count; i++) { - if (!bi) - break; - - if (!memcmp(bi->BSSID.octet, addr, ETHER_ADDR_LEN)) { - DHD_ISCAN(("%s: Del BSS[%2.2d:%2.2d] %X:%X:%X:%X:%X:%X\n", - __FUNCTION__, l, i, bi->BSSID.octet[0], - bi->BSSID.octet[1], bi->BSSID.octet[2], - bi->BSSID.octet[3], bi->BSSID.octet[4], - bi->BSSID.octet[5])); - - bi_new = bi; - bi = (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)); -/* - if(bi && bi_new) { - bcopy(bi, bi_new, results->buflen - - dtoh32(bi_new->length)); - results->buflen -= dtoh32(bi_new->length); - } -*/ - results->buflen -= dtoh32(bi_new->length); - results->count--; - - for (j = i; j < results->count; j++) { - if (bi && bi_new) { - DHD_ISCAN(("%s: Moved up BSS[%2.2d:%2.2d]" - "%X:%X:%X:%X:%X:%X\n", - __FUNCTION__, l, j, bi->BSSID.octet[0], - bi->BSSID.octet[1], bi->BSSID.octet[2], - bi->BSSID.octet[3], bi->BSSID.octet[4], - bi->BSSID.octet[5])); - - bi_next = (wl_bss_info_t *)((uintptr)bi + - dtoh32(bi->length)); - bcopy(bi, bi_new, dtoh32(bi->length)); - bi_new = (wl_bss_info_t *)((uintptr)bi_new + - dtoh32(bi_new->length)); - bi = bi_next; - } - } - - if (results->count == 0) { - /* Prune now empty partial scan list */ - dhd_iscan_free_buf(dhdp, iscan_cur); - goto done; - } - break; - } - bi = (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)); - } - } - iscan_cur = iscan_cur->next; - l++; - } - -done: - dhd_iscan_unlock(); - return 0; -} - -int -dhd_iscan_remove_duplicates(void * dhdp, iscan_buf_t *iscan_cur) -{ - int i = 0; - wl_iscan_results_t *list; - wl_scan_results_t *results; - wl_bss_info_t UNALIGNED *bi, *bi_new, *bi_next; - - dhd_iscan_lock(); - - DHD_ISCAN(("%s: Scan cache before delete\n", - __FUNCTION__)); - dhd_iscan_print_cache(iscan_cur); - - if (!iscan_cur) - goto done; - - list = (wl_iscan_results_t *)iscan_cur->iscan_buf; - if (!list) - goto done; - - results = (wl_scan_results_t *)&list->results; - if (!results) - goto done; - - if (results->version != WL_BSS_INFO_VERSION) { - DHD_ERROR(("%s: results->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, results->version)); - goto done; - } - - bi = results->bss_info; - for (i = 0; i < results->count; i++) { - if (!bi) - break; - - DHD_ISCAN(("%s: Find dups for BSS[%2.2d] %X:%X:%X:%X:%X:%X\n", - __FUNCTION__, i, bi->BSSID.octet[0], bi->BSSID.octet[1], bi->BSSID.octet[2], - bi->BSSID.octet[3], bi->BSSID.octet[4], bi->BSSID.octet[5])); - - dhd_iscan_delete_bss(dhdp, bi->BSSID.octet, iscan_cur); - - bi = (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)); - } - -done: - DHD_ISCAN(("%s: Scan cache after delete\n", __FUNCTION__)); - dhd_iscan_print_cache(iscan_cur); - dhd_iscan_unlock(); - return 0; -} - -void -dhd_iscan_ind_scan_confirm(void *dhdp, bool status) -{ - - dhd_ind_scan_confirm(dhdp, status); -} - -int -dhd_iscan_request(void * dhdp, uint16 action) -{ - int rc; - wl_iscan_params_t params; - dhd_pub_t *dhd = dhd_bus_pub(dhdp); - char buf[WLC_IOCTL_SMLEN]; - - - memset(¶ms, 0, sizeof(wl_iscan_params_t)); - memcpy(¶ms.params.bssid, ðer_bcast, ETHER_ADDR_LEN); - - params.params.bss_type = DOT11_BSSTYPE_ANY; - params.params.scan_type = DOT11_SCANTYPE_ACTIVE; - - params.params.nprobes = htod32(-1); - params.params.active_time = htod32(-1); - params.params.passive_time = htod32(-1); - params.params.home_time = htod32(-1); - params.params.channel_num = htod32(0); - - params.version = htod32(ISCAN_REQ_VERSION); - params.action = htod16(action); - params.scan_duration = htod16(0); - - bcm_mkiovar("iscan", (char *)¶ms, sizeof(wl_iscan_params_t), buf, WLC_IOCTL_SMLEN); - rc = dhd_wl_ioctl(dhdp, WLC_SET_VAR, buf, WLC_IOCTL_SMLEN); - - return rc; -} - -static int -dhd_iscan_get_partial_result(void *dhdp, uint *scan_count) -{ - wl_iscan_results_t *list_buf; - wl_iscan_results_t list; - wl_scan_results_t *results; - iscan_buf_t *iscan_cur; - int status = -1; - dhd_pub_t *dhd = dhd_bus_pub(dhdp); - int rc; - - - iscan_cur = dhd_iscan_allocate_buf(dhd, &iscan_chain); - if (!iscan_cur) { - DHD_ERROR(("%s: Failed to allocate node\n", __FUNCTION__)); - dhd_iscan_free_buf(dhdp, 0); - dhd_iscan_request(dhdp, WL_SCAN_ACTION_ABORT); - goto fail; - } - - dhd_iscan_lock(); - - memset(iscan_cur->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN); - list_buf = (wl_iscan_results_t*)iscan_cur->iscan_buf; - results = &list_buf->results; - results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE; - results->version = 0; - results->count = 0; - - memset(&list, 0, sizeof(list)); - list.results.buflen = htod32(WLC_IW_ISCAN_MAXLEN); - bcm_mkiovar("iscanresults", (char *)&list, WL_ISCAN_RESULTS_FIXED_SIZE, - iscan_cur->iscan_buf, WLC_IW_ISCAN_MAXLEN); - rc = dhd_wl_ioctl(dhdp, WLC_GET_VAR, iscan_cur->iscan_buf, WLC_IW_ISCAN_MAXLEN); - - results->buflen = dtoh32(results->buflen); - results->version = dtoh32(results->version); - *scan_count = results->count = dtoh32(results->count); - status = dtoh32(list_buf->status); - - dhd_iscan_unlock(); - - if (!(*scan_count)) - dhd_iscan_free_buf(dhdp, iscan_cur); - else - dhd_iscan_remove_duplicates(dhdp, iscan_cur); - - -fail: - return status; -} - -#endif - -/* - * returns = TRUE if associated, FALSE if not associated - */ -bool is_associated(dhd_pub_t *dhd, void *bss_buf) -{ - char bssid[ETHER_ADDR_LEN], zbuf[ETHER_ADDR_LEN]; - int ret = -1; - - bzero(bssid, ETHER_ADDR_LEN); - bzero(zbuf, ETHER_ADDR_LEN); - - ret = dhdcdc_set_ioctl(dhd, 0, WLC_GET_BSSID, (char *)bssid, ETHER_ADDR_LEN); - DHD_TRACE((" %s WLC_GET_BSSID ioctl res = %d\n", __FUNCTION__, ret)); - - if (ret == BCME_NOTASSOCIATED) { - DHD_TRACE(("%s: not associated! res:%d\n", __FUNCTION__, ret)); - } - - if (ret < 0) - return FALSE; - - if ((memcmp(bssid, zbuf, ETHER_ADDR_LEN) != 0)) { - /* STA is assocoated BSSID is non zero */ - - if (bss_buf) { - /* return bss if caller provided buf */ - memcpy(bss_buf, bssid, ETHER_ADDR_LEN); - } - return TRUE; - } else { - DHD_TRACE(("%s: WLC_GET_BSSID ioctl returned zero bssid\n", __FUNCTION__)); - return FALSE; - } -} - -/* Function to estimate possible DTIM_SKIP value */ -int dhd_get_dtim_skip(dhd_pub_t *dhd) -{ - int bcn_li_dtim; - char buf[128]; - int ret; - int dtim_assoc = 0; - - if ((dhd->dtim_skip == 0) || (dhd->dtim_skip == 1)) - bcn_li_dtim = 3; - else - bcn_li_dtim = dhd->dtim_skip; - - /* Read DTIM value if associated */ - memset(buf, 0, sizeof(buf)); - bcm_mkiovar("dtim_assoc", 0, 0, buf, sizeof(buf)); - if ((ret = dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, sizeof(buf))) < 0) { - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); - bcn_li_dtim = 1; - goto exit; - } - else - dtim_assoc = dtoh32(*(int *)buf); - - DHD_ERROR(("%s bcn_li_dtim=%d DTIM=%d Listen=%d\n", \ - __FUNCTION__, bcn_li_dtim, dtim_assoc, LISTEN_INTERVAL)); - - /* if not assocated just eixt */ - if (dtim_assoc == 0) { - goto exit; - } - - /* check if sta listen interval fits into AP dtim */ - if (dtim_assoc > LISTEN_INTERVAL) { - /* AP DTIM to big for our Listen Interval : no dtim skiping */ - bcn_li_dtim = 1; - DHD_ERROR(("%s DTIM=%d > Listen=%d : too big ...\n", \ - __FUNCTION__, dtim_assoc, LISTEN_INTERVAL)); - goto exit; - } - - if ((bcn_li_dtim * dtim_assoc) > LISTEN_INTERVAL) { - /* Round up dtim_skip to fit into STAs Listen Interval */ - bcn_li_dtim = (int)(LISTEN_INTERVAL / dtim_assoc); - DHD_TRACE(("%s agjust dtim_skip as %d\n", __FUNCTION__, bcn_li_dtim)); - } - -exit: - return bcn_li_dtim; -} - -#ifdef PNO_SUPPORT -int dhd_pno_clean(dhd_pub_t *dhd) -{ - char iovbuf[128]; - int pfn_enabled = 0; - int iov_len = 0; - int ret; - - /* Disable pfn */ - iov_len = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf))) >= 0) { - /* clear pfn */ - iov_len = bcm_mkiovar("pfnclear", 0, 0, iovbuf, sizeof(iovbuf)); - if (iov_len) { - if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, iov_len)) < 0) { - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); - } - } - else { - ret = -1; - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, iov_len)); - } - } - else - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); - - return ret; -} - -int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled) -{ - char iovbuf[128]; - int ret = -1; - - if ((!dhd) && ((pfn_enabled != 0) || (pfn_enabled != 1))) { - DHD_ERROR(("%s error exit\n", __FUNCTION__)); - return ret; - } - - memset(iovbuf, 0, sizeof(iovbuf)); - - /* Check if disassoc to enable pno */ - if (pfn_enabled && (is_associated(dhd, NULL) == TRUE)) { - DHD_ERROR(("%s pno enable called in assoc mode ret=%d\n", \ - __FUNCTION__, ret)); - return ret; - } - - /* Enable/disable PNO */ - if ((ret = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf))) > 0) { - if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf))) < 0) { - DHD_ERROR(("%s failed for error=%d\n", __FUNCTION__, ret)); - return ret; - } - else { - dhd->pno_enable = pfn_enabled; - DHD_TRACE(("%s set pno as %d\n", __FUNCTION__, dhd->pno_enable)); - } - } - else DHD_ERROR(("%s failed err=%d\n", __FUNCTION__, ret)); - - return ret; -} - -/* Function to execute combined scan */ -int -dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr, \ - int pno_repeat, int pno_freq_expo_max) -{ - int err = -1; - char iovbuf[128]; - int k, i; - wl_pfn_param_t pfn_param; - wl_pfn_t pfn_element; - - DHD_TRACE(("%s nssid=%d nchan=%d\n", __FUNCTION__, nssid, scan_fr)); - - if ((!dhd) && (!ssids_local)) { - DHD_ERROR(("%s error exit\n", __FUNCTION__)); - err = -1; - } - - /* Check for broadcast ssid */ - for (k = 0; k < nssid; k++) { - if (!ssids_local[k].SSID_len) { - DHD_ERROR(("%d: Broadcast SSID is ilegal for PNO setting\n", k)); - return err; - } - } -/* #define PNO_DUMP 1 */ -#ifdef PNO_DUMP - { - int j; - for (j = 0; j < nssid; j++) { - DHD_ERROR(("%d: scan for %s size =%d\n", j, - ssids_local[j].SSID, ssids_local[j].SSID_len)); - } - } -#endif /* PNO_DUMP */ - - /* clean up everything */ - if ((err = dhd_pno_clean(dhd)) < 0) { - DHD_ERROR(("%s failed error=%d\n", __FUNCTION__, err)); - return err; - } - memset(&pfn_param, 0, sizeof(pfn_param)); - memset(&pfn_element, 0, sizeof(pfn_element)); - - /* set pfn parameters */ - pfn_param.version = htod32(PFN_VERSION); - pfn_param.flags = htod16((PFN_LIST_ORDER << SORT_CRITERIA_BIT)); - - /* check and set extra pno params */ - if ((pno_repeat != 0) || (pno_freq_expo_max != 0)) { - pfn_param.flags |= htod16(ENABLE << ENABLE_ADAPTSCAN_BIT); - pfn_param.repeat_scan = htod32(pno_repeat); - pfn_param.max_freq_adjust = htod32(pno_freq_expo_max); - } - - /* set up pno scan fr */ - if (scan_fr != 0) - pfn_param.scan_freq = htod32(scan_fr); - - if (pfn_param.scan_freq > PNO_SCAN_MAX_FW_SEC) { - DHD_ERROR(("%s pno freq above %d sec\n", __FUNCTION__, PNO_SCAN_MAX_FW_SEC)); - return err; - } - if (pfn_param.scan_freq < PNO_SCAN_MIN_FW_SEC) { - DHD_ERROR(("%s pno freq less %d sec\n", __FUNCTION__, PNO_SCAN_MIN_FW_SEC)); - return err; - } - - bcm_mkiovar("pfn_set", (char *)&pfn_param, sizeof(pfn_param), iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - - /* set all pfn ssid */ - for (i = 0; i < nssid; i++) { - - pfn_element.bss_type = htod32(DOT11_BSSTYPE_INFRASTRUCTURE); - pfn_element.auth = (DOT11_OPEN_SYSTEM); - pfn_element.infra = htod32(1); - - memcpy((char *)pfn_element.ssid.SSID, ssids_local[i].SSID, ssids_local[i].SSID_len); - pfn_element.ssid.SSID_len = ssids_local[i].SSID_len; - - if ((err = - bcm_mkiovar("pfn_add", (char *)&pfn_element, - sizeof(pfn_element), iovbuf, sizeof(iovbuf))) > 0) { - if ((err = - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf))) < 0) { - DHD_ERROR(("%s failed for i=%d error=%d\n", - __FUNCTION__, i, err)); - return err; - } - else - DHD_ERROR(("%s set OK with PNO time=%d repeat=%d max_adjust=%d\n", \ - __FUNCTION__, pfn_param.scan_freq, \ - pfn_param.repeat_scan, pfn_param.max_freq_adjust)); - } - else DHD_ERROR(("%s failed err=%d\n", __FUNCTION__, err)); - } - - /* Enable PNO */ - /* dhd_pno_enable(dhd, 1); */ - return err; -} - -int dhd_pno_get_status(dhd_pub_t *dhd) -{ - int ret = -1; - - if (!dhd) - return ret; - else - return (dhd->pno_enable); -} - -#endif /* PNO_SUPPORT */ - -#if defined(KEEP_ALIVE) -int dhd_keep_alive_onoff(dhd_pub_t *dhd, int ka_on) -{ - char buf[256]; - char *buf_ptr = buf; - wl_keep_alive_pkt_t keep_alive_pkt; - char * str; - int str_len, buf_len; - int res = 0; - int keep_alive_period = KEEP_ALIVE_PERIOD; /* in ms */ - - DHD_TRACE(("%s: ka:%d\n", __FUNCTION__, ka_on)); - - if (ka_on) { /* on suspend */ - keep_alive_pkt.period_msec = keep_alive_period; - - } else { - /* on resume, turn off keep_alive packets */ - keep_alive_pkt.period_msec = 0; - } - - /* IOC var name */ - str = "keep_alive"; - str_len = strlen(str); - strncpy(buf, str, str_len); - buf[str_len] = '\0'; - buf_len = str_len + 1; - - /* set ptr to IOCTL payload after the var name */ - buf_ptr += buf_len; /* include term Z */ - - /* copy Keep-alive attributes from local var keep_alive_pkt */ - str = NULL_PKT_STR; - keep_alive_pkt.len_bytes = strlen(str); - - memcpy(buf_ptr, &keep_alive_pkt, WL_KEEP_ALIVE_FIXED_LEN); - buf_ptr += WL_KEEP_ALIVE_FIXED_LEN; - - /* copy packet data */ - memcpy(buf_ptr, str, keep_alive_pkt.len_bytes); - buf_len += (WL_KEEP_ALIVE_FIXED_LEN + keep_alive_pkt.len_bytes); - - res = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, buf_len); - return res; -} -#endif /* defined(KEEP_ALIVE) */ - -#if defined(CSCAN) - -/* Androd ComboSCAN support */ -/* - * data parsing from ComboScan tlv list -*/ -int -wl_iw_parse_data_tlv(char** list_str, void *dst, int dst_size, const char token, - int input_size, int *bytes_left) -{ - char* str = *list_str; - uint16 short_temp; - uint32 int_temp; - - if ((list_str == NULL) || (*list_str == NULL) ||(bytes_left == NULL) || (*bytes_left < 0)) { - DHD_ERROR(("%s error paramters\n", __FUNCTION__)); - return -1; - } - - /* Clean all dest bytes */ - memset(dst, 0, dst_size); - while (*bytes_left > 0) { - - if (str[0] != token) { - DHD_TRACE(("%s NOT Type=%d get=%d left_parse=%d \n", - __FUNCTION__, token, str[0], *bytes_left)); - return -1; - } - - *bytes_left -= 1; - str += 1; - - if (input_size == 1) { - memcpy(dst, str, input_size); - } - else if (input_size == 2) { - memcpy(dst, (char *)htod16(memcpy(&short_temp, str, input_size)), - input_size); - } - else if (input_size == 4) { - memcpy(dst, (char *)htod32(memcpy(&int_temp, str, input_size)), - input_size); - } - - *bytes_left -= input_size; - str += input_size; - *list_str = str; - return 1; - } - return 1; -} - -/* - * channel list parsing from cscan tlv list -*/ -int -wl_iw_parse_channel_list_tlv(char** list_str, uint16* channel_list, - int channel_num, int *bytes_left) -{ - char* str = *list_str; - int idx = 0; - - if ((list_str == NULL) || (*list_str == NULL) ||(bytes_left == NULL) || (*bytes_left < 0)) { - DHD_ERROR(("%s error paramters\n", __FUNCTION__)); - return -1; - } - - while (*bytes_left > 0) { - - if (str[0] != CSCAN_TLV_TYPE_CHANNEL_IE) { - *list_str = str; - DHD_TRACE(("End channel=%d left_parse=%d %d\n", idx, *bytes_left, str[0])); - return idx; - } - /* Get proper CSCAN_TLV_TYPE_CHANNEL_IE */ - *bytes_left -= 1; - str += 1; - - if (str[0] == 0) { - /* All channels */ - channel_list[idx] = 0x0; - } - else { - channel_list[idx] = (uint16)str[0]; - DHD_TRACE(("%s channel=%d \n", __FUNCTION__, channel_list[idx])); - } - *bytes_left -= 1; - str += 1; - - if (idx++ > 255) { - DHD_ERROR(("%s Too many channels \n", __FUNCTION__)); - return -1; - } - } - - *list_str = str; - return idx; -} - -/* - * SSIDs list parsing from cscan tlv list - */ -int -wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, int max, int *bytes_left) -{ - char* str = *list_str; - int idx = 0; - - if ((list_str == NULL) || (*list_str == NULL) || (*bytes_left < 0)) { - DHD_ERROR(("%s error paramters\n", __FUNCTION__)); - return -1; - } - - while (*bytes_left > 0) { - - if (str[0] != CSCAN_TLV_TYPE_SSID_IE) { - *list_str = str; - DHD_TRACE(("nssid=%d left_parse=%d %d\n", idx, *bytes_left, str[0])); - return idx; - } - - /* Get proper CSCAN_TLV_TYPE_SSID_IE */ - *bytes_left -= 1; - str += 1; - - if (str[0] == 0) { - /* Broadcast SSID */ - ssid[idx].SSID_len = 0; - memset((char*)ssid[idx].SSID, 0x0, DOT11_MAX_SSID_LEN); - *bytes_left -= 1; - str += 1; - - DHD_TRACE(("BROADCAST SCAN left=%d\n", *bytes_left)); - } - else if (str[0] <= DOT11_MAX_SSID_LEN) { - /* Get proper SSID size */ - ssid[idx].SSID_len = str[0]; - *bytes_left -= 1; - str += 1; - - /* Get SSID */ - if (ssid[idx].SSID_len > *bytes_left) { - DHD_ERROR(("%s out of memory range len=%d but left=%d\n", - __FUNCTION__, ssid[idx].SSID_len, *bytes_left)); - return -1; - } - - memcpy((char*)ssid[idx].SSID, str, ssid[idx].SSID_len); - - *bytes_left -= ssid[idx].SSID_len; - str += ssid[idx].SSID_len; - - DHD_TRACE(("%s :size=%d left=%d\n", - (char*)ssid[idx].SSID, ssid[idx].SSID_len, *bytes_left)); - } - else { - DHD_ERROR(("### SSID size more that %d\n", str[0])); - return -1; - } - - if (idx++ > max) { - DHD_ERROR(("%s number of SSIDs more that %d\n", __FUNCTION__, idx)); - return -1; - } - } - - *list_str = str; - return idx; -} - -/* Parse a comma-separated list from list_str into ssid array, starting - * at index idx. Max specifies size of the ssid array. Parses ssids - * and returns updated idx; if idx >= max not all fit, the excess have - * not been copied. Returns -1 on empty string, or on ssid too long. - */ -int -wl_iw_parse_ssid_list(char** list_str, wlc_ssid_t* ssid, int idx, int max) -{ - char* str, *ptr; - - if ((list_str == NULL) || (*list_str == NULL)) - return -1; - - for (str = *list_str; str != NULL; str = ptr) { - - /* check for next TAG */ - if (!strncmp(str, GET_CHANNEL, strlen(GET_CHANNEL))) { - *list_str = str + strlen(GET_CHANNEL); - return idx; - } - - if ((ptr = strchr(str, ',')) != NULL) { - *ptr++ = '\0'; - } - - if (strlen(str) > DOT11_MAX_SSID_LEN) { - DHD_ERROR(("ssid <%s> exceeds %d\n", str, DOT11_MAX_SSID_LEN)); - return -1; - } - - if (strlen(str) == 0) - ssid[idx].SSID_len = 0; - - if (idx < max) { - strcpy((char*)ssid[idx].SSID, str); - ssid[idx].SSID_len = strlen(str); - } - idx++; - } - return idx; -} - -/* - * Parse channel list from iwpriv CSCAN - */ -int -wl_iw_parse_channel_list(char** list_str, uint16* channel_list, int channel_num) -{ - int num; - int val; - char* str; - char* endptr = NULL; - - if ((list_str == NULL)||(*list_str == NULL)) - return -1; - - str = *list_str; - num = 0; - while (strncmp(str, GET_NPROBE, strlen(GET_NPROBE))) { - val = (int)strtoul(str, &endptr, 0); - if (endptr == str) { - printf("could not parse channel number starting at" - " substring \"%s\" in list:\n%s\n", - str, *list_str); - return -1; - } - str = endptr + strspn(endptr, " ,"); - - if (num == channel_num) { - DHD_ERROR(("too many channels (more than %d) in channel list:\n%s\n", - channel_num, *list_str)); - return -1; - } - - channel_list[num++] = (uint16)val; - } - *list_str = str; - return num; -} - -#endif diff --git a/drivers/net/wireless/bcm4329/dhd_custom_gpio.c b/drivers/net/wireless/bcm4329/dhd_custom_gpio.c deleted file mode 100644 index 4d32863e2982..000000000000 --- a/drivers/net/wireless/bcm4329/dhd_custom_gpio.c +++ /dev/null @@ -1,272 +0,0 @@ -/* -* Customer code to add GPIO control during WLAN start/stop -* Copyright (C) 1999-2010, Broadcom Corporation -* -* Unless you and Broadcom execute a separate written software license -* agreement governing use of this software, this software is licensed to you -* under the terms of the GNU General Public License version 2 (the "GPL"), -* available at http://www.broadcom.com/licenses/GPLv2.php, with the -* following added to such license: -* -* As a special exception, the copyright holders of this software give you -* permission to link this software with independent modules, and to copy and -* distribute the resulting executable under terms of your choice, provided that -* you also meet, for each linked independent module, the terms and conditions of -* the license of that module. An independent module is a module which is not -* derived from this software. The special exception does not apply to any -* modifications of the software. -* -* Notwithstanding the above, under no circumstances may you combine this -* software in any way with any other Broadcom software provided under a license -* other than the GPL, without Broadcom's express prior written consent. -* -* $Id: dhd_custom_gpio.c,v 1.1.4.8.4.4 2011/01/20 20:23:09 Exp $ -*/ - - -#include -#include -#include -#include - -#include -#include - -#include -#include - -#define WL_ERROR(x) printf x -#define WL_TRACE(x) - -#ifdef CUSTOMER_HW -extern void bcm_wlan_power_off(int); -extern void bcm_wlan_power_on(int); -#endif /* CUSTOMER_HW */ -#ifdef CUSTOMER_HW2 -int wifi_set_carddetect(int on); -int wifi_set_power(int on, unsigned long msec); -int wifi_get_irq_number(unsigned long *irq_flags_ptr); -int wifi_get_mac_addr(unsigned char *buf); -void *wifi_get_country_code(char *ccode); -#endif - -#if defined(OOB_INTR_ONLY) - -#if defined(BCMLXSDMMC) -extern int sdioh_mmc_irq(int irq); -#endif /* (BCMLXSDMMC) */ - -#ifdef CUSTOMER_HW3 -#include -#endif - -/* Customer specific Host GPIO defintion */ -static int dhd_oob_gpio_num = -1; /* GG 19 */ - -module_param(dhd_oob_gpio_num, int, 0644); -MODULE_PARM_DESC(dhd_oob_gpio_num, "DHD oob gpio number"); - -int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr) -{ - int host_oob_irq = 0; - -#ifdef CUSTOMER_HW2 - host_oob_irq = wifi_get_irq_number(irq_flags_ptr); - -#else /* for NOT CUSTOMER_HW2 */ -#if defined(CUSTOM_OOB_GPIO_NUM) - if (dhd_oob_gpio_num < 0) { - dhd_oob_gpio_num = CUSTOM_OOB_GPIO_NUM; - } -#endif - - if (dhd_oob_gpio_num < 0) { - WL_ERROR(("%s: ERROR customer specific Host GPIO is NOT defined \n", - __FUNCTION__)); - return (dhd_oob_gpio_num); - } - - WL_ERROR(("%s: customer specific Host GPIO number is (%d)\n", - __FUNCTION__, dhd_oob_gpio_num)); - -#if defined CUSTOMER_HW - host_oob_irq = MSM_GPIO_TO_INT(dhd_oob_gpio_num); -#elif defined CUSTOMER_HW3 - gpio_request(dhd_oob_gpio_num, "oob irq"); - host_oob_irq = gpio_to_irq(dhd_oob_gpio_num); - gpio_direction_input(dhd_oob_gpio_num); -#endif /* CUSTOMER_HW */ -#endif /* CUSTOMER_HW2 */ - - return (host_oob_irq); -} -#endif /* defined(OOB_INTR_ONLY) */ - -/* Customer function to control hw specific wlan gpios */ -void -dhd_customer_gpio_wlan_ctrl(int onoff) -{ - switch (onoff) { - case WLAN_RESET_OFF: - WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n", - __FUNCTION__)); -#ifdef CUSTOMER_HW - bcm_wlan_power_off(2); -#endif /* CUSTOMER_HW */ -#ifdef CUSTOMER_HW2 - wifi_set_power(0, 0); -#endif - WL_ERROR(("=========== WLAN placed in RESET ========\n")); - break; - - case WLAN_RESET_ON: - WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n", - __FUNCTION__)); -#ifdef CUSTOMER_HW - bcm_wlan_power_on(2); -#endif /* CUSTOMER_HW */ -#ifdef CUSTOMER_HW2 - wifi_set_power(1, 0); -#endif - WL_ERROR(("=========== WLAN going back to live ========\n")); - break; - - case WLAN_POWER_OFF: - WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n", - __FUNCTION__)); -#ifdef CUSTOMER_HW - bcm_wlan_power_off(1); -#endif /* CUSTOMER_HW */ - break; - - case WLAN_POWER_ON: - WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n", - __FUNCTION__)); -#ifdef CUSTOMER_HW - bcm_wlan_power_on(1); - /* Lets customer power to get stable */ - OSL_DELAY(50); -#endif /* CUSTOMER_HW */ - break; - } -} - -#ifdef GET_CUSTOM_MAC_ENABLE -/* Function to get custom MAC address */ -int -dhd_custom_get_mac_address(unsigned char *buf) -{ - int ret = 0; - - WL_TRACE(("%s Enter\n", __FUNCTION__)); - if (!buf) - return -EINVAL; - - /* Customer access to MAC address stored outside of DHD driver */ -#ifdef CUSTOMER_HW2 - ret = wifi_get_mac_addr(buf); -#endif - -#ifdef EXAMPLE_GET_MAC - /* EXAMPLE code */ - { - struct ether_addr ea_example = {{0x00, 0x11, 0x22, 0x33, 0x44, 0xFF}}; - bcopy((char *)&ea_example, buf, sizeof(struct ether_addr)); - } -#endif /* EXAMPLE_GET_MAC */ - - return ret; -} -#endif /* GET_CUSTOM_MAC_ENABLE */ - -/* Customized Locale table : OPTIONAL feature */ -const struct cntry_locales_custom translate_custom_table[] = { -/* Table should be filled out based on custom platform regulatory requirement */ -#ifdef EXAMPLE_TABLE - {"", "XY", 4}, /* universal */ - {"US", "US", 69}, /* input ISO "US" to : US regrev 69 */ - {"CA", "US", 69}, /* input ISO "CA" to : US regrev 69 */ - {"EU", "EU", 5}, /* European union countries */ - {"AT", "EU", 5}, - {"BE", "EU", 5}, - {"BG", "EU", 5}, - {"CY", "EU", 5}, - {"CZ", "EU", 5}, - {"DK", "EU", 5}, - {"EE", "EU", 5}, - {"FI", "EU", 5}, - {"FR", "EU", 5}, - {"DE", "EU", 5}, - {"GR", "EU", 5}, - {"HU", "EU", 5}, - {"IE", "EU", 5}, - {"IT", "EU", 5}, - {"LV", "EU", 5}, - {"LI", "EU", 5}, - {"LT", "EU", 5}, - {"LU", "EU", 5}, - {"MT", "EU", 5}, - {"NL", "EU", 5}, - {"PL", "EU", 5}, - {"PT", "EU", 5}, - {"RO", "EU", 5}, - {"SK", "EU", 5}, - {"SI", "EU", 5}, - {"ES", "EU", 5}, - {"SE", "EU", 5}, - {"GB", "EU", 5}, /* input ISO "GB" to : EU regrev 05 */ - {"IL", "IL", 0}, - {"CH", "CH", 0}, - {"TR", "TR", 0}, - {"NO", "NO", 0}, - {"KR", "XY", 3}, - {"AU", "XY", 3}, - {"CN", "XY", 3}, /* input ISO "CN" to : XY regrev 03 */ - {"TW", "XY", 3}, - {"AR", "XY", 3}, - {"MX", "XY", 3} -#endif /* EXAMPLE_TABLE */ -}; - - -/* Customized Locale convertor -* input : ISO 3166-1 country abbreviation -* output: customized cspec -*/ -void get_customized_country_code(char *country_iso_code, wl_country_t *cspec) -{ -#ifdef CUSTOMER_HW2 - struct cntry_locales_custom *cloc_ptr; - - if (!cspec) - return; - - cloc_ptr = wifi_get_country_code(country_iso_code); - if (cloc_ptr) { - strlcpy(cspec->ccode, cloc_ptr->custom_locale, WLC_CNTRY_BUF_SZ); - cspec->rev = cloc_ptr->custom_locale_rev; - } - return; -#else - int size, i; - - size = ARRAYSIZE(translate_custom_table); - - if (cspec == 0) - return; - - if (size == 0) - return; - - for (i = 0; i < size; i++) { - if (strcmp(country_iso_code, translate_custom_table[i].iso_abbrev) == 0) { - memcpy(cspec->ccode, translate_custom_table[i].custom_locale, WLC_CNTRY_BUF_SZ); - cspec->rev = translate_custom_table[i].custom_locale_rev; - return; - } - } - memcpy(cspec->ccode, translate_custom_table[0].custom_locale, WLC_CNTRY_BUF_SZ); - cspec->rev = translate_custom_table[0].custom_locale_rev; - return; -#endif -} diff --git a/drivers/net/wireless/bcm4329/dhd_dbg.h b/drivers/net/wireless/bcm4329/dhd_dbg.h deleted file mode 100644 index b48c1d70f144..000000000000 --- a/drivers/net/wireless/bcm4329/dhd_dbg.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Debug/trace/assert driver definitions for Dongle Host Driver. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd_dbg.h,v 1.5.6.2.4.2.14.10 2010/05/21 21:49:38 Exp $ - */ - -#ifndef _dhd_dbg_ -#define _dhd_dbg_ - -#ifdef DHD_DEBUG - -#define DHD_ERROR(args) do {if ((dhd_msg_level & DHD_ERROR_VAL) && (net_ratelimit())) \ - printf args;} while (0) -#define DHD_TRACE(args) do {if (dhd_msg_level & DHD_TRACE_VAL) printf args;} while (0) -#define DHD_INFO(args) do {if (dhd_msg_level & DHD_INFO_VAL) printf args;} while (0) -#define DHD_DATA(args) do {if (dhd_msg_level & DHD_DATA_VAL) printf args;} while (0) -#define DHD_CTL(args) do {if (dhd_msg_level & DHD_CTL_VAL) printf args;} while (0) -#define DHD_TIMER(args) do {if (dhd_msg_level & DHD_TIMER_VAL) printf args;} while (0) -#define DHD_HDRS(args) do {if (dhd_msg_level & DHD_HDRS_VAL) printf args;} while (0) -#define DHD_BYTES(args) do {if (dhd_msg_level & DHD_BYTES_VAL) printf args;} while (0) -#define DHD_INTR(args) do {if (dhd_msg_level & DHD_INTR_VAL) printf args;} while (0) -#define DHD_GLOM(args) do {if (dhd_msg_level & DHD_GLOM_VAL) printf args;} while (0) -#define DHD_EVENT(args) do {if (dhd_msg_level & DHD_EVENT_VAL) printf args;} while (0) -#define DHD_BTA(args) do {if (dhd_msg_level & DHD_BTA_VAL) printf args;} while (0) -#define DHD_ISCAN(args) do {if (dhd_msg_level & DHD_ISCAN_VAL) printf args;} while (0) - -#define DHD_ERROR_ON() (dhd_msg_level & DHD_ERROR_VAL) -#define DHD_TRACE_ON() (dhd_msg_level & DHD_TRACE_VAL) -#define DHD_INFO_ON() (dhd_msg_level & DHD_INFO_VAL) -#define DHD_DATA_ON() (dhd_msg_level & DHD_DATA_VAL) -#define DHD_CTL_ON() (dhd_msg_level & DHD_CTL_VAL) -#define DHD_TIMER_ON() (dhd_msg_level & DHD_TIMER_VAL) -#define DHD_HDRS_ON() (dhd_msg_level & DHD_HDRS_VAL) -#define DHD_BYTES_ON() (dhd_msg_level & DHD_BYTES_VAL) -#define DHD_INTR_ON() (dhd_msg_level & DHD_INTR_VAL) -#define DHD_GLOM_ON() (dhd_msg_level & DHD_GLOM_VAL) -#define DHD_EVENT_ON() (dhd_msg_level & DHD_EVENT_VAL) -#define DHD_BTA_ON() (dhd_msg_level & DHD_BTA_VAL) -#define DHD_ISCAN_ON() (dhd_msg_level & DHD_ISCAN_VAL) - -#else /* DHD_DEBUG */ - -#define DHD_ERROR(args) do {if (net_ratelimit()) printf args;} while (0) -#define DHD_TRACE(args) -#define DHD_INFO(args) -#define DHD_DATA(args) -#define DHD_CTL(args) -#define DHD_TIMER(args) -#define DHD_HDRS(args) -#define DHD_BYTES(args) -#define DHD_INTR(args) -#define DHD_GLOM(args) -#define DHD_EVENT(args) -#define DHD_BTA(args) -#define DHD_ISCAN(args) - -#define DHD_ERROR_ON() 0 -#define DHD_TRACE_ON() 0 -#define DHD_INFO_ON() 0 -#define DHD_DATA_ON() 0 -#define DHD_CTL_ON() 0 -#define DHD_TIMER_ON() 0 -#define DHD_HDRS_ON() 0 -#define DHD_BYTES_ON() 0 -#define DHD_INTR_ON() 0 -#define DHD_GLOM_ON() 0 -#define DHD_EVENT_ON() 0 -#define DHD_BTA_ON() 0 -#define DHD_ISCAN_ON() 0 -#endif /* DHD_DEBUG */ - -#define DHD_LOG(args) - -#define DHD_NONE(args) -extern int dhd_msg_level; - -/* Defines msg bits */ -#include - -#endif /* _dhd_dbg_ */ diff --git a/drivers/net/wireless/bcm4329/dhd_linux.c b/drivers/net/wireless/bcm4329/dhd_linux.c deleted file mode 100644 index b466d745f848..000000000000 --- a/drivers/net/wireless/bcm4329/dhd_linux.c +++ /dev/null @@ -1,3442 +0,0 @@ -/* - * Broadcom Dongle Host Driver (DHD), Linux-specific network interface - * Basically selected code segments from usb-cdc.c and usb-rndis.c - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd_linux.c,v 1.65.4.9.2.12.2.104.4.40 2011/02/03 19:55:18 Exp $ - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_WAKELOCK -#include -#endif -#ifdef CUSTOMER_HW2 -#include -#ifdef CONFIG_WIFI_CONTROL_FUNC -#include -static struct wifi_platform_data *wifi_control_data = NULL; -#endif -struct semaphore wifi_control_sem; - -static struct resource *wifi_irqres = NULL; - -int wifi_get_irq_number(unsigned long *irq_flags_ptr) -{ - if (wifi_irqres) { - *irq_flags_ptr = wifi_irqres->flags & IRQF_TRIGGER_MASK; - return (int)wifi_irqres->start; - } -#ifdef CUSTOM_OOB_GPIO_NUM - return CUSTOM_OOB_GPIO_NUM; -#else - return -1; -#endif -} - -int wifi_set_carddetect(int on) -{ - printk("%s = %d\n", __FUNCTION__, on); -#ifdef CONFIG_WIFI_CONTROL_FUNC - if (wifi_control_data && wifi_control_data->set_carddetect) { - wifi_control_data->set_carddetect(on); - } -#endif - return 0; -} - -int wifi_set_power(int on, unsigned long msec) -{ - printk("%s = %d\n", __FUNCTION__, on); -#ifdef CONFIG_WIFI_CONTROL_FUNC - if (wifi_control_data && wifi_control_data->set_power) { - wifi_control_data->set_power(on); - } -#endif - if (msec) - mdelay(msec); - return 0; -} - -int wifi_set_reset(int on, unsigned long msec) -{ - DHD_TRACE(("%s = %d\n", __FUNCTION__, on)); -#ifdef CONFIG_WIFI_CONTROL_FUNC - if (wifi_control_data && wifi_control_data->set_reset) { - wifi_control_data->set_reset(on); - } -#endif - if (msec) - mdelay(msec); - return 0; -} - -int wifi_get_mac_addr(unsigned char *buf) -{ - DHD_TRACE(("%s\n", __FUNCTION__)); - if (!buf) - return -EINVAL; -#ifdef CONFIG_WIFI_CONTROL_FUNC - if (wifi_control_data && wifi_control_data->get_mac_addr) { - return wifi_control_data->get_mac_addr(buf); - } -#endif - return -EOPNOTSUPP; -} - -void *wifi_get_country_code(char *ccode) -{ - DHD_TRACE(("%s\n", __FUNCTION__)); -#ifdef CONFIG_WIFI_CONTROL_FUNC - if (!ccode) - return NULL; - if (wifi_control_data && wifi_control_data->get_country_code) { - return wifi_control_data->get_country_code(ccode); - } -#endif - return NULL; -} - -static int wifi_probe(struct platform_device *pdev) -{ -#ifdef CONFIG_WIFI_CONTROL_FUNC - struct wifi_platform_data *wifi_ctrl = - (struct wifi_platform_data *)(pdev->dev.platform_data); - - wifi_control_data = wifi_ctrl; -#endif - - DHD_TRACE(("## %s\n", __FUNCTION__)); - wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcm4329_wlan_irq"); - - wifi_set_power(1, 0); /* Power On */ - wifi_set_carddetect(1); /* CardDetect (0->1) */ - - up(&wifi_control_sem); - return 0; -} - -static int wifi_remove(struct platform_device *pdev) -{ -#ifdef CONFIG_WIFI_CONTROL_FUNC - struct wifi_platform_data *wifi_ctrl = - (struct wifi_platform_data *)(pdev->dev.platform_data); - - wifi_control_data = wifi_ctrl; -#endif - DHD_TRACE(("## %s\n", __FUNCTION__)); - wifi_set_power(0, 0); /* Power Off */ - wifi_set_carddetect(0); /* CardDetect (1->0) */ - - up(&wifi_control_sem); - return 0; -} - -static int wifi_suspend(struct platform_device *pdev, pm_message_t state) -{ - DHD_TRACE(("##> %s\n", __FUNCTION__)); -#if defined(OOB_INTR_ONLY) - bcmsdh_oob_intr_set(0); -#endif /* (OOB_INTR_ONLY) */ - return 0; -} -static int wifi_resume(struct platform_device *pdev) -{ - DHD_TRACE(("##> %s\n", __FUNCTION__)); -#if defined(OOB_INTR_ONLY) - bcmsdh_oob_intr_set(1); -#endif /* (OOB_INTR_ONLY) */ - return 0; -} - -static struct platform_driver wifi_device = { - .probe = wifi_probe, - .remove = wifi_remove, - .suspend = wifi_suspend, - .resume = wifi_resume, - .driver = { - .name = "bcm4329_wlan", - } -}; - -int wifi_add_dev(void) -{ - DHD_TRACE(("## Calling platform_driver_register\n")); - return platform_driver_register(&wifi_device); -} - -void wifi_del_dev(void) -{ - DHD_TRACE(("## Unregister platform_driver_register\n")); - platform_driver_unregister(&wifi_device); -} -#endif /* defined(CUSTOMER_HW2) */ - -static int dhd_device_event(struct notifier_block *this, unsigned long event, - void *ptr); - -static struct notifier_block dhd_notifier = { - .notifier_call = dhd_device_event -}; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) -#include -volatile bool dhd_mmc_suspend = FALSE; -DECLARE_WAIT_QUEUE_HEAD(dhd_dpc_wait); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ - -#if defined(OOB_INTR_ONLY) -extern void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable); -#endif /* defined(OOB_INTR_ONLY) */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -MODULE_LICENSE("GPL v2"); -#endif /* LinuxVer */ - -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 15) -const char * -print_tainted() -{ - return ""; -} -#endif /* LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 15) */ - -/* Linux wireless extension support */ -#if defined(CONFIG_WIRELESS_EXT) -#include -#endif /* defined(CONFIG_WIRELESS_EXT) */ - -extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len); - -#if defined(CONFIG_HAS_EARLYSUSPEND) -#include -#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ - -#ifdef PKT_FILTER_SUPPORT -extern void dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg); -extern void dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode); -#endif - -/* Interface control information */ -typedef struct dhd_if { - struct dhd_info *info; /* back pointer to dhd_info */ - /* OS/stack specifics */ - struct net_device *net; - struct net_device_stats stats; - int idx; /* iface idx in dongle */ - int state; /* interface state */ - uint subunit; /* subunit */ - uint8 mac_addr[ETHER_ADDR_LEN]; /* assigned MAC address */ - bool attached; /* Delayed attachment when unset */ - bool txflowcontrol; /* Per interface flow control indicator */ - char name[IFNAMSIZ+1]; /* linux interface name */ -} dhd_if_t; - -/* Local private structure (extension of pub) */ -typedef struct dhd_info { -#if defined(CONFIG_WIRELESS_EXT) - wl_iw_t iw; /* wireless extensions state (must be first) */ -#endif /* defined(CONFIG_WIRELESS_EXT) */ - - dhd_pub_t pub; - - /* OS/stack specifics */ - dhd_if_t *iflist[DHD_MAX_IFS]; - - struct mutex proto_sem; - wait_queue_head_t ioctl_resp_wait; - struct timer_list timer; - bool wd_timer_valid; - struct tasklet_struct tasklet; - spinlock_t sdlock; - spinlock_t txqlock; - spinlock_t dhd_lock; - - /* Thread based operation */ - bool threads_only; - struct mutex sdsem; - long watchdog_pid; - struct semaphore watchdog_sem; - struct completion watchdog_exited; - long dpc_pid; - struct semaphore dpc_sem; - struct completion dpc_exited; - - /* Wakelocks */ -#ifdef CONFIG_HAS_WAKELOCK - struct wake_lock wl_wifi; /* Wifi wakelock */ - struct wake_lock wl_rxwake; /* Wifi rx wakelock */ -#endif - spinlock_t wl_lock; - int wl_count; - int wl_packet; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - struct mutex wl_start_lock; /* mutex when START called to prevent any other Linux calls */ -#endif - /* Thread to issue ioctl for multicast */ - long sysioc_pid; - struct semaphore sysioc_sem; - struct completion sysioc_exited; - bool set_multicast; - bool set_macaddress; - struct ether_addr macvalue; - wait_queue_head_t ctrl_wait; - atomic_t pend_8021x_cnt; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct early_suspend early_suspend; -#endif /* CONFIG_HAS_EARLYSUSPEND */ -} dhd_info_t; - -/* Definitions to provide path to the firmware and nvram - * example nvram_path[MOD_PARAM_PATHLEN]="/projects/wlan/nvram.txt" - */ -char firmware_path[MOD_PARAM_PATHLEN]; -char nvram_path[MOD_PARAM_PATHLEN]; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -struct semaphore dhd_registration_sem; -#define DHD_REGISTRATION_TIMEOUT 12000 /* msec : allowed time to finished dhd registration */ -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -/* load firmware and/or nvram values from the filesystem */ -module_param_string(firmware_path, firmware_path, MOD_PARAM_PATHLEN, 0); -module_param_string(nvram_path, nvram_path, MOD_PARAM_PATHLEN, 0); - -/* Error bits */ -module_param(dhd_msg_level, int, 0); - -/* Spawn a thread for system ioctls (set mac, set mcast) */ -uint dhd_sysioc = TRUE; -module_param(dhd_sysioc, uint, 0); - -/* Watchdog interval */ -uint dhd_watchdog_ms = 10; -module_param(dhd_watchdog_ms, uint, 0); - -#ifdef DHD_DEBUG -/* Console poll interval */ -uint dhd_console_ms = 0; -module_param(dhd_console_ms, uint, 0); -#endif /* DHD_DEBUG */ - -/* ARP offload agent mode : Enable ARP Host Auto-Reply and ARP Peer Auto-Reply */ -uint dhd_arp_mode = 0xb; -module_param(dhd_arp_mode, uint, 0); - -/* ARP offload enable */ -uint dhd_arp_enable = TRUE; -module_param(dhd_arp_enable, uint, 0); - -/* Global Pkt filter enable control */ -uint dhd_pkt_filter_enable = TRUE; -module_param(dhd_pkt_filter_enable, uint, 0); - -/* Pkt filter init setup */ -uint dhd_pkt_filter_init = 0; -module_param(dhd_pkt_filter_init, uint, 0); - -/* Pkt filter mode control */ -uint dhd_master_mode = TRUE; -module_param(dhd_master_mode, uint, 1); - -/* Watchdog thread priority, -1 to use kernel timer */ -int dhd_watchdog_prio = 97; -module_param(dhd_watchdog_prio, int, 0); - -/* DPC thread priority, -1 to use tasklet */ -int dhd_dpc_prio = 98; -module_param(dhd_dpc_prio, int, 0); - -/* DPC thread priority, -1 to use tasklet */ -extern int dhd_dongle_memsize; -module_param(dhd_dongle_memsize, int, 0); - -/* Control fw roaming */ -#ifdef CUSTOMER_HW2 -uint dhd_roam = 0; -#else -uint dhd_roam = 1; -#endif - -/* Control radio state */ -uint dhd_radio_up = 1; - -/* Network inteface name */ -char iface_name[IFNAMSIZ]; -module_param_string(iface_name, iface_name, IFNAMSIZ, 0); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define DAEMONIZE(a) daemonize(a); \ - allow_signal(SIGKILL); \ - allow_signal(SIGTERM); -#else /* Linux 2.4 (w/o preemption patch) */ -#define RAISE_RX_SOFTIRQ() \ - cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ) -#define DAEMONIZE(a) daemonize(); \ - do { if (a) \ - strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a) + 1))); \ - } while (0); -#endif /* LINUX_VERSION_CODE */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define BLOCKABLE() (!in_atomic()) -#else -#define BLOCKABLE() (!in_interrupt()) -#endif - -/* The following are specific to the SDIO dongle */ - -/* IOCTL response timeout */ -int dhd_ioctl_timeout_msec = IOCTL_RESP_TIMEOUT; - -/* Idle timeout for backplane clock */ -int dhd_idletime = DHD_IDLETIME_TICKS; -module_param(dhd_idletime, int, 0); - -/* Use polling */ -uint dhd_poll = FALSE; -module_param(dhd_poll, uint, 0); - -/* Use interrupts */ -uint dhd_intr = TRUE; -module_param(dhd_intr, uint, 0); - -/* SDIO Drive Strength (in milliamps) */ -uint dhd_sdiod_drive_strength = 6; -module_param(dhd_sdiod_drive_strength, uint, 0); - -/* Tx/Rx bounds */ -extern uint dhd_txbound; -extern uint dhd_rxbound; -module_param(dhd_txbound, uint, 0); -module_param(dhd_rxbound, uint, 0); - -/* Deferred transmits */ -extern uint dhd_deferred_tx; -module_param(dhd_deferred_tx, uint, 0); - - - -#ifdef SDTEST -/* Echo packet generator (pkts/s) */ -uint dhd_pktgen = 0; -module_param(dhd_pktgen, uint, 0); - -/* Echo packet len (0 => sawtooth, max 2040) */ -uint dhd_pktgen_len = 0; -module_param(dhd_pktgen_len, uint, 0); -#endif - -/* Version string to report */ -#ifdef DHD_DEBUG -#ifndef SRCBASE -#define SRCBASE "drivers/net/wireless/bcm4329" -#endif -#define DHD_COMPILED "\nCompiled in " SRCBASE -#else -#define DHD_COMPILED -#endif - -static char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR -#ifdef DHD_DEBUG -"\nCompiled in " SRCBASE " on " __DATE__ " at " __TIME__ -#endif -; - - -#if defined(CONFIG_WIRELESS_EXT) -struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev); -#endif /* defined(CONFIG_WIRELESS_EXT) */ - -static void dhd_dpc(ulong data); -/* forward decl */ -extern int dhd_wait_pend8021x(struct net_device *dev); - -#ifdef TOE -#ifndef BDC -#error TOE requires BDC -#endif /* !BDC */ -static int dhd_toe_get(dhd_info_t *dhd, int idx, uint32 *toe_ol); -static int dhd_toe_set(dhd_info_t *dhd, int idx, uint32 toe_ol); -#endif /* TOE */ - -static int dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, - wl_event_msg_t *event_ptr, void **data_ptr); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) -static int dhd_sleep_pm_callback(struct notifier_block *nfb, unsigned long action, void *ignored) -{ - int ret = NOTIFY_DONE; - - switch (action) { - case PM_HIBERNATION_PREPARE: - case PM_SUSPEND_PREPARE: - dhd_mmc_suspend = TRUE; - ret = NOTIFY_OK; - break; - case PM_POST_HIBERNATION: - case PM_POST_SUSPEND: - dhd_mmc_suspend = FALSE; - ret = NOTIFY_OK; - break; - } - smp_mb(); - return ret; -} - -static struct notifier_block dhd_sleep_pm_notifier = { - .notifier_call = dhd_sleep_pm_callback, - .priority = 0 -}; -extern int register_pm_notifier(struct notifier_block *nb); -extern int unregister_pm_notifier(struct notifier_block *nb); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ - -static void dhd_set_packet_filter(int value, dhd_pub_t *dhd) -{ -#ifdef PKT_FILTER_SUPPORT - DHD_TRACE(("%s: %d\n", __FUNCTION__, value)); - /* 1 - Enable packet filter, only allow unicast packet to send up */ - /* 0 - Disable packet filter */ - if (dhd_pkt_filter_enable) { - int i; - - for (i = 0; i < dhd->pktfilter_count; i++) { - dhd_pktfilter_offload_set(dhd, dhd->pktfilter[i]); - dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i], - value, dhd_master_mode); - } - } -#endif -} - - - -#if defined(CONFIG_HAS_EARLYSUSPEND) -static int dhd_set_suspend(int value, dhd_pub_t *dhd) -{ - int power_mode = PM_MAX; - /* wl_pkt_filter_enable_t enable_parm; */ - char iovbuf[32]; - int bcn_li_dtim = 3; -#ifdef CUSTOMER_HW2 - uint roamvar = 1; -#endif /* CUSTOMER_HW2 */ - - DHD_TRACE(("%s: enter, value = %d in_suspend = %d\n", - __FUNCTION__, value, dhd->in_suspend)); - - if (dhd && dhd->up) { - if (value && dhd->in_suspend) { - - /* Kernel suspended */ - DHD_TRACE(("%s: force extra Suspend setting \n", __FUNCTION__)); - - dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, - (char *)&power_mode, sizeof(power_mode)); - - /* Enable packet filter, only allow unicast packet to send up */ - dhd_set_packet_filter(1, dhd); - - /* if dtim skip setup as default force it to wake each thrid dtim - * for better power saving. - * Note that side effect is chance to miss BC/MC packet - */ - bcn_li_dtim = dhd_get_dtim_skip(dhd); - bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim, - 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); -#ifdef CUSTOMER_HW2 - /* Disable build-in roaming during suspend */ - bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); -#endif /* CUSTOMER_HW2 */ - - } else { - - /* Kernel resumed */ - DHD_TRACE(("%s: Remove extra suspend setting \n", __FUNCTION__)); - - power_mode = PM_FAST; - dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode, - sizeof(power_mode)); - - /* disable pkt filter */ - dhd_set_packet_filter(0, dhd); - - /* restore pre-suspend setting for dtim_skip */ - bcm_mkiovar("bcn_li_dtim", (char *)&dhd->dtim_skip, - 4, iovbuf, sizeof(iovbuf)); - - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); -#ifdef CUSTOMER_HW2 - roamvar = dhd_roam; - bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); -#endif /* CUSTOMER_HW2 */ - } - } - - return 0; -} - -static void dhd_suspend_resume_helper(struct dhd_info *dhd, int val) -{ - dhd_pub_t *dhdp = &dhd->pub; - - dhd_os_wake_lock(dhdp); - dhd_os_proto_block(dhdp); - /* Set flag when early suspend was called */ - dhdp->in_suspend = val; - if (!dhdp->suspend_disable_flag) - dhd_set_suspend(val, dhdp); - dhd_os_proto_unblock(dhdp); - dhd_os_wake_unlock(dhdp); -} - -static void dhd_early_suspend(struct early_suspend *h) -{ - struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend); - - DHD_TRACE(("%s: enter\n", __FUNCTION__)); - - if (dhd) - dhd_suspend_resume_helper(dhd, 1); -} - -static void dhd_late_resume(struct early_suspend *h) -{ - struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend); - - DHD_TRACE(("%s: enter\n", __FUNCTION__)); - - if (dhd) - dhd_suspend_resume_helper(dhd, 0); -} -#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ - -/* - * Generalized timeout mechanism. Uses spin sleep with exponential back-off until - * the sleep time reaches one jiffy, then switches over to task delay. Usage: - * - * dhd_timeout_start(&tmo, usec); - * while (!dhd_timeout_expired(&tmo)) - * if (poll_something()) - * break; - * if (dhd_timeout_expired(&tmo)) - * fatal(); - */ - -void -dhd_timeout_start(dhd_timeout_t *tmo, uint usec) -{ - tmo->limit = usec; - tmo->increment = 0; - tmo->elapsed = 0; - tmo->tick = 1000000 / HZ; -} - -int -dhd_timeout_expired(dhd_timeout_t *tmo) -{ - /* Does nothing the first call */ - if (tmo->increment == 0) { - tmo->increment = 1; - return 0; - } - - if (tmo->elapsed >= tmo->limit) - return 1; - - /* Add the delay that's about to take place */ - tmo->elapsed += tmo->increment; - - if (tmo->increment < tmo->tick) { - OSL_DELAY(tmo->increment); - tmo->increment *= 2; - if (tmo->increment > tmo->tick) - tmo->increment = tmo->tick; - } else { - wait_queue_head_t delay_wait; - DECLARE_WAITQUEUE(wait, current); - int pending; - init_waitqueue_head(&delay_wait); - add_wait_queue(&delay_wait, &wait); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); - pending = signal_pending(current); - remove_wait_queue(&delay_wait, &wait); - set_current_state(TASK_RUNNING); - if (pending) - return 1; /* Interrupted */ - } - - return 0; -} - -static int -dhd_net2idx(dhd_info_t *dhd, struct net_device *net) -{ - int i = 0; - - ASSERT(dhd); - while (i < DHD_MAX_IFS) { - if (dhd->iflist[i] && (dhd->iflist[i]->net == net)) - return i; - i++; - } - - return DHD_BAD_IF; -} - -int -dhd_ifname2idx(dhd_info_t *dhd, char *name) -{ - int i = DHD_MAX_IFS; - - ASSERT(dhd); - - if (name == NULL || *name == '\0') - return 0; - - while (--i > 0) - if (dhd->iflist[i] && !strncmp(dhd->iflist[i]->name, name, IFNAMSIZ)) - break; - - DHD_TRACE(("%s: return idx %d for \"%s\"\n", __FUNCTION__, i, name)); - - return i; /* default - the primary interface */ -} - -char * -dhd_ifname(dhd_pub_t *dhdp, int ifidx) -{ - dhd_info_t *dhd = (dhd_info_t *)dhdp->info; - - ASSERT(dhd); - - if (ifidx < 0 || ifidx >= DHD_MAX_IFS) { - DHD_ERROR(("%s: ifidx %d out of range\n", __FUNCTION__, ifidx)); - return ""; - } - - if (dhd->iflist[ifidx] == NULL) { - DHD_ERROR(("%s: null i/f %d\n", __FUNCTION__, ifidx)); - return ""; - } - - if (dhd->iflist[ifidx]->net) - return dhd->iflist[ifidx]->net->name; - - return ""; -} - -static void -_dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) -{ - struct net_device *dev; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) - struct netdev_hw_addr *ha; -#else - struct dev_mc_list *mclist; -#endif - uint32 allmulti, cnt; - - wl_ioctl_t ioc; - char *buf, *bufp; - uint buflen; - int ret; - - ASSERT(dhd && dhd->iflist[ifidx]); - dev = dhd->iflist[ifidx]->net; - - NETIF_ADDR_LOCK(dev); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) - cnt = netdev_mc_count(dev); -#else - cnt = dev->mc_count; -#endif - NETIF_ADDR_UNLOCK(dev); - - /* Determine initial value of allmulti flag */ - allmulti = (dev->flags & IFF_ALLMULTI) ? TRUE : FALSE; - - /* Send down the multicast list first. */ - buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETHER_ADDR_LEN); - if (!(bufp = buf = MALLOC(dhd->pub.osh, buflen))) { - DHD_ERROR(("%s: out of memory for mcast_list, cnt %d\n", - dhd_ifname(&dhd->pub, ifidx), cnt)); - return; - } - - strcpy(bufp, "mcast_list"); - bufp += strlen("mcast_list") + 1; - - cnt = htol32(cnt); - memcpy(bufp, &cnt, sizeof(cnt)); - bufp += sizeof(cnt); - - NETIF_ADDR_LOCK(dev); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) - netdev_for_each_mc_addr(ha, dev) { - if (!cnt) - break; - memcpy(bufp, ha->addr, ETHER_ADDR_LEN); - bufp += ETHER_ADDR_LEN; - cnt--; - } -#else - for (mclist = dev->mc_list; (mclist && (cnt > 0)); cnt--, mclist = mclist->next) { - memcpy(bufp, (void *)mclist->dmi_addr, ETHER_ADDR_LEN); - bufp += ETHER_ADDR_LEN; - } -#endif - NETIF_ADDR_UNLOCK(dev); - - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = WLC_SET_VAR; - ioc.buf = buf; - ioc.len = buflen; - ioc.set = TRUE; - - ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); - if (ret < 0) { - DHD_ERROR(("%s: set mcast_list failed, cnt %d\n", - dhd_ifname(&dhd->pub, ifidx), cnt)); - allmulti = cnt ? TRUE : allmulti; - } - - MFREE(dhd->pub.osh, buf, buflen); - - /* Now send the allmulti setting. This is based on the setting in the - * net_device flags, but might be modified above to be turned on if we - * were trying to set some addresses and dongle rejected it... - */ - - buflen = sizeof("allmulti") + sizeof(allmulti); - if (!(buf = MALLOC(dhd->pub.osh, buflen))) { - DHD_ERROR(("%s: out of memory for allmulti\n", dhd_ifname(&dhd->pub, ifidx))); - return; - } - allmulti = htol32(allmulti); - - if (!bcm_mkiovar("allmulti", (void*)&allmulti, sizeof(allmulti), buf, buflen)) { - DHD_ERROR(("%s: mkiovar failed for allmulti, datalen %d buflen %u\n", - dhd_ifname(&dhd->pub, ifidx), (int)sizeof(allmulti), buflen)); - MFREE(dhd->pub.osh, buf, buflen); - return; - } - - - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = WLC_SET_VAR; - ioc.buf = buf; - ioc.len = buflen; - ioc.set = TRUE; - - ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); - if (ret < 0) { - DHD_ERROR(("%s: set allmulti %d failed\n", - dhd_ifname(&dhd->pub, ifidx), ltoh32(allmulti))); - } - - MFREE(dhd->pub.osh, buf, buflen); - - /* Finally, pick up the PROMISC flag as well, like the NIC driver does */ - - allmulti = (dev->flags & IFF_PROMISC) ? TRUE : FALSE; - allmulti = htol32(allmulti); - - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = WLC_SET_PROMISC; - ioc.buf = &allmulti; - ioc.len = sizeof(allmulti); - ioc.set = TRUE; - - ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); - if (ret < 0) { - DHD_ERROR(("%s: set promisc %d failed\n", - dhd_ifname(&dhd->pub, ifidx), ltoh32(allmulti))); - } -} - -static int -_dhd_set_mac_address(dhd_info_t *dhd, int ifidx, struct ether_addr *addr) -{ - char buf[32]; - wl_ioctl_t ioc; - int ret; - - DHD_TRACE(("%s enter\n", __FUNCTION__)); - if (!bcm_mkiovar("cur_etheraddr", (char*)addr, ETHER_ADDR_LEN, buf, 32)) { - DHD_ERROR(("%s: mkiovar failed for cur_etheraddr\n", dhd_ifname(&dhd->pub, ifidx))); - return -1; - } - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = WLC_SET_VAR; - ioc.buf = buf; - ioc.len = 32; - ioc.set = TRUE; - - ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); - if (ret < 0) { - DHD_ERROR(("%s: set cur_etheraddr failed\n", dhd_ifname(&dhd->pub, ifidx))); - } else { - memcpy(dhd->iflist[ifidx]->net->dev_addr, addr, ETHER_ADDR_LEN); - } - - return ret; -} - -#ifdef SOFTAP -extern struct net_device *ap_net_dev; -/* semaphore that the soft AP CODE waits on */ -extern struct semaphore ap_eth_sema; -#endif - -static void -dhd_op_if(dhd_if_t *ifp) -{ - dhd_info_t *dhd; - int ret = 0, err = 0; -#ifdef SOFTAP - unsigned long flags; -#endif - - ASSERT(ifp && ifp->info && ifp->idx); /* Virtual interfaces only */ - - dhd = ifp->info; - - DHD_TRACE(("%s: idx %d, state %d\n", __FUNCTION__, ifp->idx, ifp->state)); - - switch (ifp->state) { - case WLC_E_IF_ADD: - /* - * Delete the existing interface before overwriting it - * in case we missed the WLC_E_IF_DEL event. - */ - if (ifp->net != NULL) { - DHD_ERROR(("%s: ERROR: netdev:%s already exists, try free & unregister \n", - __FUNCTION__, ifp->net->name)); - netif_stop_queue(ifp->net); - unregister_netdev(ifp->net); - free_netdev(ifp->net); - } - /* Allocate etherdev, including space for private structure */ - if (!(ifp->net = alloc_etherdev(sizeof(dhd)))) { - DHD_ERROR(("%s: OOM - alloc_etherdev\n", __FUNCTION__)); - ret = -ENOMEM; - } - if (ret == 0) { - strcpy(ifp->net->name, ifp->name); - memcpy(netdev_priv(ifp->net), &dhd, sizeof(dhd)); - if ((err = dhd_net_attach(&dhd->pub, ifp->idx)) != 0) { - DHD_ERROR(("%s: dhd_net_attach failed, err %d\n", - __FUNCTION__, err)); - ret = -EOPNOTSUPP; - } else { -#ifdef SOFTAP - flags = dhd_os_spin_lock(&dhd->pub); - /* save ptr to wl0.1 netdev for use in wl_iw.c */ - ap_net_dev = ifp->net; - /* signal to the SOFTAP 'sleeper' thread, wl0.1 is ready */ - up(&ap_eth_sema); - dhd_os_spin_unlock(&dhd->pub, flags); -#endif - DHD_TRACE(("\n ==== pid:%x, net_device for if:%s created ===\n\n", - current->pid, ifp->net->name)); - ifp->state = 0; - } - } - break; - case WLC_E_IF_DEL: - if (ifp->net != NULL) { - DHD_TRACE(("\n%s: got 'WLC_E_IF_DEL' state\n", __FUNCTION__)); - netif_stop_queue(ifp->net); - unregister_netdev(ifp->net); - ret = DHD_DEL_IF; /* Make sure the free_netdev() is called */ - } - break; - default: - DHD_ERROR(("%s: bad op %d\n", __FUNCTION__, ifp->state)); - ASSERT(!ifp->state); - break; - } - - if (ret < 0) { - if (ifp->net) { - free_netdev(ifp->net); - } - dhd->iflist[ifp->idx] = NULL; - MFREE(dhd->pub.osh, ifp, sizeof(*ifp)); -#ifdef SOFTAP - flags = dhd_os_spin_lock(&dhd->pub); - if (ifp->net == ap_net_dev) - ap_net_dev = NULL; /* NULL SOFTAP global as well */ - dhd_os_spin_unlock(&dhd->pub, flags); -#endif /* SOFTAP */ - } -} - -static int -_dhd_sysioc_thread(void *data) -{ - dhd_info_t *dhd = (dhd_info_t *)data; - int i; -#ifdef SOFTAP - bool in_ap = FALSE; - unsigned long flags; -#endif - - DAEMONIZE("dhd_sysioc"); - - while (down_interruptible(&dhd->sysioc_sem) == 0) { - dhd_os_start_lock(&dhd->pub); - dhd_os_wake_lock(&dhd->pub); - for (i = 0; i < DHD_MAX_IFS; i++) { - if (dhd->iflist[i]) { - DHD_TRACE(("%s: interface %d\n",__FUNCTION__, i)); -#ifdef SOFTAP - flags = dhd_os_spin_lock(&dhd->pub); - in_ap = (ap_net_dev != NULL); - dhd_os_spin_unlock(&dhd->pub, flags); -#endif /* SOFTAP */ - if (dhd->iflist[i]->state) - dhd_op_if(dhd->iflist[i]); -#ifdef SOFTAP - if (dhd->iflist[i] == NULL) { - DHD_TRACE(("%s: interface %d just been removed!\n\n", __FUNCTION__, i)); - continue; - } - - if (in_ap && dhd->set_macaddress) { - DHD_TRACE(("attempt to set MAC for %s in AP Mode blocked.\n", dhd->iflist[i]->net->name)); - dhd->set_macaddress = FALSE; - continue; - } - - if (in_ap && dhd->set_multicast) { - DHD_TRACE(("attempt to set MULTICAST list for %s in AP Mode blocked.\n", dhd->iflist[i]->net->name)); - dhd->set_multicast = FALSE; - continue; - } -#endif /* SOFTAP */ - if (dhd->set_multicast) { - dhd->set_multicast = FALSE; - _dhd_set_multicast_list(dhd, i); - } - if (dhd->set_macaddress) { - dhd->set_macaddress = FALSE; - _dhd_set_mac_address(dhd, i, &dhd->macvalue); - } - } - } - dhd_os_wake_unlock(&dhd->pub); - dhd_os_start_unlock(&dhd->pub); - } - DHD_TRACE(("%s: stopped\n",__FUNCTION__)); - complete_and_exit(&dhd->sysioc_exited, 0); -} - -static int -dhd_set_mac_address(struct net_device *dev, void *addr) -{ - int ret = 0; - - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - struct sockaddr *sa = (struct sockaddr *)addr; - int ifidx; - - DHD_TRACE(("%s: Enter\n",__FUNCTION__)); - ifidx = dhd_net2idx(dhd, dev); - if (ifidx == DHD_BAD_IF) - return -1; - - ASSERT(dhd->sysioc_pid >= 0); - memcpy(&dhd->macvalue, sa->sa_data, ETHER_ADDR_LEN); - dhd->set_macaddress = TRUE; - up(&dhd->sysioc_sem); - - return ret; -} - -static void -dhd_set_multicast_list(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ifidx; - - DHD_TRACE(("%s: Enter\n",__FUNCTION__)); - ifidx = dhd_net2idx(dhd, dev); - if (ifidx == DHD_BAD_IF) - return; - - ASSERT(dhd->sysioc_pid >= 0); - dhd->set_multicast = TRUE; - up(&dhd->sysioc_sem); -} - -int -dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf) -{ - int ret; - dhd_info_t *dhd = (dhd_info_t *)(dhdp->info); - - /* Reject if down */ - if (!dhdp->up || (dhdp->busstate == DHD_BUS_DOWN)) { - return -ENODEV; - } - - /* Update multicast statistic */ - if (PKTLEN(dhdp->osh, pktbuf) >= ETHER_ADDR_LEN) { - uint8 *pktdata = (uint8 *)PKTDATA(dhdp->osh, pktbuf); - struct ether_header *eh = (struct ether_header *)pktdata; - - if (ETHER_ISMULTI(eh->ether_dhost)) - dhdp->tx_multicast++; - if (ntoh16(eh->ether_type) == ETHER_TYPE_802_1X) - atomic_inc(&dhd->pend_8021x_cnt); - } - - /* Look into the packet and update the packet priority */ - if ((PKTPRIO(pktbuf) == 0)) - pktsetprio(pktbuf, FALSE); - - /* If the protocol uses a data header, apply it */ - dhd_prot_hdrpush(dhdp, ifidx, pktbuf); - - /* Use bus module to send data frame */ -#ifdef BCMDBUS - ret = dbus_send_pkt(dhdp->dbus, pktbuf, NULL /* pktinfo */); -#else - ret = dhd_bus_txdata(dhdp->bus, pktbuf); -#endif /* BCMDBUS */ - - return ret; -} - -static int -dhd_start_xmit(struct sk_buff *skb, struct net_device *net) -{ - int ret; - void *pktbuf; - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); - int ifidx; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - dhd_os_wake_lock(&dhd->pub); - - /* Reject if down */ - if (!dhd->pub.up || (dhd->pub.busstate == DHD_BUS_DOWN)) { - DHD_ERROR(("%s: xmit rejected pub.up=%d busstate=%d\n", - __FUNCTION__, dhd->pub.up, dhd->pub.busstate)); - netif_stop_queue(net); - /* Send Event when bus down detected during data session */ - if (dhd->pub.busstate == DHD_BUS_DOWN) { - DHD_ERROR(("%s: Event HANG send up\n", __FUNCTION__)); - net_os_send_hang_message(net); - } - dhd_os_wake_unlock(&dhd->pub); - return -ENODEV; - } - - ifidx = dhd_net2idx(dhd, net); - if (ifidx == DHD_BAD_IF) { - DHD_ERROR(("%s: bad ifidx %d\n", __FUNCTION__, ifidx)); - netif_stop_queue(net); - dhd_os_wake_unlock(&dhd->pub); - return -ENODEV; - } - - /* Make sure there's enough room for any header */ - if (skb_headroom(skb) < dhd->pub.hdrlen) { - struct sk_buff *skb2; - - DHD_INFO(("%s: insufficient headroom\n", - dhd_ifname(&dhd->pub, ifidx))); - dhd->pub.tx_realloc++; - skb2 = skb_realloc_headroom(skb, dhd->pub.hdrlen); - dev_kfree_skb(skb); - if ((skb = skb2) == NULL) { - DHD_ERROR(("%s: skb_realloc_headroom failed\n", - dhd_ifname(&dhd->pub, ifidx))); - ret = -ENOMEM; - goto done; - } - } - - /* Convert to packet */ - if (!(pktbuf = PKTFRMNATIVE(dhd->pub.osh, skb))) { - DHD_ERROR(("%s: PKTFRMNATIVE failed\n", - dhd_ifname(&dhd->pub, ifidx))); - dev_kfree_skb_any(skb); - ret = -ENOMEM; - goto done; - } - - ret = dhd_sendpkt(&dhd->pub, ifidx, pktbuf); - -done: - if (ret) - dhd->pub.dstats.tx_dropped++; - else - dhd->pub.tx_packets++; - - dhd_os_wake_unlock(&dhd->pub); - - /* Return ok: we always eat the packet */ - return 0; -} - -void -dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool state) -{ - struct net_device *net; - dhd_info_t *dhd = dhdp->info; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - dhdp->txoff = state; - ASSERT(dhd && dhd->iflist[ifidx]); - net = dhd->iflist[ifidx]->net; - if (state == ON) - netif_stop_queue(net); - else - netif_wake_queue(net); -} - -void -dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt) -{ - dhd_info_t *dhd = (dhd_info_t *)dhdp->info; - struct sk_buff *skb; - uchar *eth; - uint len; - void * data, *pnext, *save_pktbuf; - int i; - dhd_if_t *ifp; - wl_event_msg_t event; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - save_pktbuf = pktbuf; - - for (i = 0; pktbuf && i < numpkt; i++, pktbuf = pnext) { - - pnext = PKTNEXT(dhdp->osh, pktbuf); - PKTSETNEXT(wl->sh.osh, pktbuf, NULL); - - - skb = PKTTONATIVE(dhdp->osh, pktbuf); - - /* Get the protocol, maintain skb around eth_type_trans() - * The main reason for this hack is for the limitation of - * Linux 2.4 where 'eth_type_trans' uses the 'net->hard_header_len' - * to perform skb_pull inside vs ETH_HLEN. Since to avoid - * coping of the packet coming from the network stack to add - * BDC, Hardware header etc, during network interface registration - * we set the 'net->hard_header_len' to ETH_HLEN + extra space required - * for BDC, Hardware header etc. and not just the ETH_HLEN - */ - eth = skb->data; - len = skb->len; - - ifp = dhd->iflist[ifidx]; - if (ifp == NULL) - ifp = dhd->iflist[0]; - - ASSERT(ifp); - skb->dev = ifp->net; - skb->protocol = eth_type_trans(skb, skb->dev); - - if (skb->pkt_type == PACKET_MULTICAST) { - dhd->pub.rx_multicast++; - } - - skb->data = eth; - skb->len = len; - - /* Strip header, count, deliver upward */ - skb_pull(skb, ETH_HLEN); - - /* Process special event packets and then discard them */ - if (ntoh16(skb->protocol) == ETHER_TYPE_BRCM) - dhd_wl_host_event(dhd, &ifidx, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) - skb->mac_header, -#else - skb->mac.raw, -#endif - &event, - &data); - - ASSERT(ifidx < DHD_MAX_IFS && dhd->iflist[ifidx]); - if (dhd->iflist[ifidx] && !dhd->iflist[ifidx]->state) - ifp = dhd->iflist[ifidx]; - - if (ifp->net) - ifp->net->last_rx = jiffies; - - dhdp->dstats.rx_bytes += skb->len; - dhdp->rx_packets++; /* Local count */ - - if (in_interrupt()) { - netif_rx(skb); - } else { - /* If the receive is not processed inside an ISR, - * the softirqd must be woken explicitly to service - * the NET_RX_SOFTIRQ. In 2.6 kernels, this is handled - * by netif_rx_ni(), but in earlier kernels, we need - * to do it manually. - */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - netif_rx_ni(skb); -#else - ulong flags; - netif_rx(skb); - local_irq_save(flags); - RAISE_RX_SOFTIRQ(); - local_irq_restore(flags); -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) */ - } - } - dhd_os_wake_lock_timeout_enable(dhdp); -} - -void -dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx) -{ - /* Linux version has nothing to do */ - return; -} - -void -dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success) -{ - uint ifidx; - dhd_info_t *dhd = (dhd_info_t *)(dhdp->info); - struct ether_header *eh; - uint16 type; - - dhd_prot_hdrpull(dhdp, &ifidx, txp); - - eh = (struct ether_header *)PKTDATA(dhdp->osh, txp); - type = ntoh16(eh->ether_type); - - if (type == ETHER_TYPE_802_1X) - atomic_dec(&dhd->pend_8021x_cnt); - -} - -static struct net_device_stats * -dhd_get_stats(struct net_device *net) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); - dhd_if_t *ifp; - int ifidx; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - ifidx = dhd_net2idx(dhd, net); - if (ifidx == DHD_BAD_IF) - return NULL; - - ifp = dhd->iflist[ifidx]; - ASSERT(dhd && ifp); - - if (dhd->pub.up) { - /* Use the protocol to get dongle stats */ - dhd_prot_dstats(&dhd->pub); - } - - /* Copy dongle stats to net device stats */ - ifp->stats.rx_packets = dhd->pub.dstats.rx_packets; - ifp->stats.tx_packets = dhd->pub.dstats.tx_packets; - ifp->stats.rx_bytes = dhd->pub.dstats.rx_bytes; - ifp->stats.tx_bytes = dhd->pub.dstats.tx_bytes; - ifp->stats.rx_errors = dhd->pub.dstats.rx_errors; - ifp->stats.tx_errors = dhd->pub.dstats.tx_errors; - ifp->stats.rx_dropped = dhd->pub.dstats.rx_dropped; - ifp->stats.tx_dropped = dhd->pub.dstats.tx_dropped; - ifp->stats.multicast = dhd->pub.dstats.multicast; - - return &ifp->stats; -} - -static int -dhd_watchdog_thread(void *data) -{ - dhd_info_t *dhd = (dhd_info_t *)data; - - /* This thread doesn't need any user-level access, - * so get rid of all our resources - */ -#ifdef DHD_SCHED - if (dhd_watchdog_prio > 0) { - struct sched_param param; - param.sched_priority = (dhd_watchdog_prio < MAX_RT_PRIO)? - dhd_watchdog_prio:(MAX_RT_PRIO-1); - setScheduler(current, SCHED_FIFO, ¶m); - } -#endif /* DHD_SCHED */ - - DAEMONIZE("dhd_watchdog"); - - /* Run until signal received */ - while (1) { - if (down_interruptible (&dhd->watchdog_sem) == 0) { - dhd_os_sdlock(&dhd->pub); - if (dhd->pub.dongle_reset == FALSE) { - DHD_TIMER(("%s:\n", __FUNCTION__)); - /* Call the bus module watchdog */ - dhd_bus_watchdog(&dhd->pub); - - /* Count the tick for reference */ - dhd->pub.tickcnt++; - - /* Reschedule the watchdog */ - if (dhd->wd_timer_valid) - mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000); - } - dhd_os_sdunlock(&dhd->pub); - dhd_os_wake_unlock(&dhd->pub); - } else { - break; - } - } - - complete_and_exit(&dhd->watchdog_exited, 0); -} - -static void -dhd_watchdog(ulong data) -{ - dhd_info_t *dhd = (dhd_info_t *)data; - - dhd_os_wake_lock(&dhd->pub); - if (dhd->pub.dongle_reset) { - dhd_os_wake_unlock(&dhd->pub); - return; - } - - if (dhd->watchdog_pid >= 0) { - up(&dhd->watchdog_sem); - return; - } - - dhd_os_sdlock(&dhd->pub); - /* Call the bus module watchdog */ - dhd_bus_watchdog(&dhd->pub); - - /* Count the tick for reference */ - dhd->pub.tickcnt++; - - /* Reschedule the watchdog */ - if (dhd->wd_timer_valid) - mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000); - dhd_os_sdunlock(&dhd->pub); - dhd_os_wake_unlock(&dhd->pub); -} - -static int -dhd_dpc_thread(void *data) -{ - dhd_info_t *dhd = (dhd_info_t *)data; - - /* This thread doesn't need any user-level access, - * so get rid of all our resources - */ -#ifdef DHD_SCHED - if (dhd_dpc_prio > 0) - { - struct sched_param param; - param.sched_priority = (dhd_dpc_prio < MAX_RT_PRIO)?dhd_dpc_prio:(MAX_RT_PRIO-1); - setScheduler(current, SCHED_FIFO, ¶m); - } -#endif /* DHD_SCHED */ - - DAEMONIZE("dhd_dpc"); - - /* Run until signal received */ - while (1) { - if (down_interruptible(&dhd->dpc_sem) == 0) { - /* Call bus dpc unless it indicated down (then clean stop) */ - if (dhd->pub.busstate != DHD_BUS_DOWN) { - if (dhd_bus_dpc(dhd->pub.bus)) { - up(&dhd->dpc_sem); - } - else { - dhd_os_wake_unlock(&dhd->pub); - } - } else { - if (dhd->pub.up) - dhd_bus_stop(dhd->pub.bus, TRUE); - dhd_os_wake_unlock(&dhd->pub); - } - } - else - break; - } - - complete_and_exit(&dhd->dpc_exited, 0); -} - -static void -dhd_dpc(ulong data) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)data; - - /* Call bus dpc unless it indicated down (then clean stop) */ - if (dhd->pub.busstate != DHD_BUS_DOWN) { - if (dhd_bus_dpc(dhd->pub.bus)) - tasklet_schedule(&dhd->tasklet); - } else { - dhd_bus_stop(dhd->pub.bus, TRUE); - } -} - -void -dhd_sched_dpc(dhd_pub_t *dhdp) -{ - dhd_info_t *dhd = (dhd_info_t *)dhdp->info; - - dhd_os_wake_lock(dhdp); - if (dhd->dpc_pid >= 0) { - up(&dhd->dpc_sem); - return; - } - - tasklet_schedule(&dhd->tasklet); -} - -#ifdef TOE -/* Retrieve current toe component enables, which are kept as a bitmap in toe_ol iovar */ -static int -dhd_toe_get(dhd_info_t *dhd, int ifidx, uint32 *toe_ol) -{ - wl_ioctl_t ioc; - char buf[32]; - int ret; - - memset(&ioc, 0, sizeof(ioc)); - - ioc.cmd = WLC_GET_VAR; - ioc.buf = buf; - ioc.len = (uint)sizeof(buf); - ioc.set = FALSE; - - strcpy(buf, "toe_ol"); - if ((ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) { - /* Check for older dongle image that doesn't support toe_ol */ - if (ret == -EIO) { - DHD_ERROR(("%s: toe not supported by device\n", - dhd_ifname(&dhd->pub, ifidx))); - return -EOPNOTSUPP; - } - - DHD_INFO(("%s: could not get toe_ol: ret=%d\n", dhd_ifname(&dhd->pub, ifidx), ret)); - return ret; - } - - memcpy(toe_ol, buf, sizeof(uint32)); - return 0; -} - -/* Set current toe component enables in toe_ol iovar, and set toe global enable iovar */ -static int -dhd_toe_set(dhd_info_t *dhd, int ifidx, uint32 toe_ol) -{ - wl_ioctl_t ioc; - char buf[32]; - int toe, ret; - - memset(&ioc, 0, sizeof(ioc)); - - ioc.cmd = WLC_SET_VAR; - ioc.buf = buf; - ioc.len = (uint)sizeof(buf); - ioc.set = TRUE; - - /* Set toe_ol as requested */ - - strcpy(buf, "toe_ol"); - memcpy(&buf[sizeof("toe_ol")], &toe_ol, sizeof(uint32)); - - if ((ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) { - DHD_ERROR(("%s: could not set toe_ol: ret=%d\n", - dhd_ifname(&dhd->pub, ifidx), ret)); - return ret; - } - - /* Enable toe globally only if any components are enabled. */ - - toe = (toe_ol != 0); - - strcpy(buf, "toe"); - memcpy(&buf[sizeof("toe")], &toe, sizeof(uint32)); - - if ((ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) { - DHD_ERROR(("%s: could not set toe: ret=%d\n", dhd_ifname(&dhd->pub, ifidx), ret)); - return ret; - } - - return 0; -} -#endif /* TOE */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) -static void dhd_ethtool_get_drvinfo(struct net_device *net, - struct ethtool_drvinfo *info) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); - - sprintf(info->driver, "wl"); - sprintf(info->version, "%lu", dhd->pub.drv_version); -} - -struct ethtool_ops dhd_ethtool_ops = { - .get_drvinfo = dhd_ethtool_get_drvinfo -}; -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */ - - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) -static int -dhd_ethtool(dhd_info_t *dhd, void *uaddr) -{ - struct ethtool_drvinfo info; - char drvname[sizeof(info.driver)]; - uint32 cmd; -#ifdef TOE - struct ethtool_value edata; - uint32 toe_cmpnt, csum_dir; - int ret; -#endif - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* all ethtool calls start with a cmd word */ - if (copy_from_user(&cmd, uaddr, sizeof (uint32))) - return -EFAULT; - - switch (cmd) { - case ETHTOOL_GDRVINFO: - /* Copy out any request driver name */ - if (copy_from_user(&info, uaddr, sizeof(info))) - return -EFAULT; - strncpy(drvname, info.driver, sizeof(info.driver)); - drvname[sizeof(info.driver)-1] = '\0'; - - /* clear struct for return */ - memset(&info, 0, sizeof(info)); - info.cmd = cmd; - - /* if dhd requested, identify ourselves */ - if (strcmp(drvname, "?dhd") == 0) { - sprintf(info.driver, "dhd"); - strcpy(info.version, EPI_VERSION_STR); - } - - /* otherwise, require dongle to be up */ - else if (!dhd->pub.up) { - DHD_ERROR(("%s: dongle is not up\n", __FUNCTION__)); - return -ENODEV; - } - - /* finally, report dongle driver type */ - else if (dhd->pub.iswl) - sprintf(info.driver, "wl"); - else - sprintf(info.driver, "xx"); - - sprintf(info.version, "%lu", dhd->pub.drv_version); - if (copy_to_user(uaddr, &info, sizeof(info))) - return -EFAULT; - DHD_CTL(("%s: given %*s, returning %s\n", __FUNCTION__, - (int)sizeof(drvname), drvname, info.driver)); - break; - -#ifdef TOE - /* Get toe offload components from dongle */ - case ETHTOOL_GRXCSUM: - case ETHTOOL_GTXCSUM: - if ((ret = dhd_toe_get(dhd, 0, &toe_cmpnt)) < 0) - return ret; - - csum_dir = (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL; - - edata.cmd = cmd; - edata.data = (toe_cmpnt & csum_dir) ? 1 : 0; - - if (copy_to_user(uaddr, &edata, sizeof(edata))) - return -EFAULT; - break; - - /* Set toe offload components in dongle */ - case ETHTOOL_SRXCSUM: - case ETHTOOL_STXCSUM: - if (copy_from_user(&edata, uaddr, sizeof(edata))) - return -EFAULT; - - /* Read the current settings, update and write back */ - if ((ret = dhd_toe_get(dhd, 0, &toe_cmpnt)) < 0) - return ret; - - csum_dir = (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL; - - if (edata.data != 0) - toe_cmpnt |= csum_dir; - else - toe_cmpnt &= ~csum_dir; - - if ((ret = dhd_toe_set(dhd, 0, toe_cmpnt)) < 0) - return ret; - - /* If setting TX checksum mode, tell Linux the new mode */ - if (cmd == ETHTOOL_STXCSUM) { - if (edata.data) - dhd->iflist[0]->net->features |= NETIF_F_IP_CSUM; - else - dhd->iflist[0]->net->features &= ~NETIF_F_IP_CSUM; - } - - break; -#endif /* TOE */ - - default: - return -EOPNOTSUPP; - } - - return 0; -} -#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) */ - -static int -dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); - dhd_ioctl_t ioc; - int bcmerror = 0; - int buflen = 0; - void *buf = NULL; - uint driver = 0; - int ifidx; - bool is_set_key_cmd; - int ret; - - dhd_os_wake_lock(&dhd->pub); - - /* send to dongle only if we are not waiting for reload already */ - if (dhd->pub.hang_was_sent) { - DHD_ERROR(("%s: HANG was sent up earlier\n", __FUNCTION__)); - dhd_os_wake_lock_timeout_enable(&dhd->pub); - dhd_os_wake_unlock(&dhd->pub); - return OSL_ERROR(BCME_DONGLE_DOWN); - } - - ifidx = dhd_net2idx(dhd, net); - DHD_TRACE(("%s: ifidx %d, cmd 0x%04x\n", __FUNCTION__, ifidx, cmd)); - - if (ifidx == DHD_BAD_IF) { - dhd_os_wake_unlock(&dhd->pub); - return -1; - } - -#if defined(CONFIG_WIRELESS_EXT) - /* linux wireless extensions */ - if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) { - /* may recurse, do NOT lock */ - ret = wl_iw_ioctl(net, ifr, cmd); - dhd_os_wake_unlock(&dhd->pub); - return ret; - } -#endif /* defined(CONFIG_WIRELESS_EXT) */ - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) - if (cmd == SIOCETHTOOL) { - ret = dhd_ethtool(dhd, (void*)ifr->ifr_data); - dhd_os_wake_unlock(&dhd->pub); - return ret; - } -#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) */ - - if (cmd != SIOCDEVPRIVATE) { - dhd_os_wake_unlock(&dhd->pub); - return -EOPNOTSUPP; - } - - memset(&ioc, 0, sizeof(ioc)); - - /* Copy the ioc control structure part of ioctl request */ - if (copy_from_user(&ioc, ifr->ifr_data, sizeof(wl_ioctl_t))) { - bcmerror = -BCME_BADADDR; - goto done; - } - - /* Copy out any buffer passed */ - if (ioc.buf) { - buflen = MIN(ioc.len, DHD_IOCTL_MAXLEN); - /* optimization for direct ioctl calls from kernel */ - /* - if (segment_eq(get_fs(), KERNEL_DS)) { - buf = ioc.buf; - } else { - */ - { - if (!(buf = (char*)MALLOC(dhd->pub.osh, buflen))) { - bcmerror = -BCME_NOMEM; - goto done; - } - if (copy_from_user(buf, ioc.buf, buflen)) { - bcmerror = -BCME_BADADDR; - goto done; - } - } - } - - /* To differentiate between wl and dhd read 4 more byes */ - if ((copy_from_user(&driver, (char *)ifr->ifr_data + sizeof(wl_ioctl_t), - sizeof(uint)) != 0)) { - bcmerror = -BCME_BADADDR; - goto done; - } - - if (!capable(CAP_NET_ADMIN)) { - bcmerror = -BCME_EPERM; - goto done; - } - - /* check for local dhd ioctl and handle it */ - if (driver == DHD_IOCTL_MAGIC) { - bcmerror = dhd_ioctl((void *)&dhd->pub, &ioc, buf, buflen); - if (bcmerror) - dhd->pub.bcmerror = bcmerror; - goto done; - } - - /* send to dongle (must be up, and wl) */ - if (dhd->pub.busstate != DHD_BUS_DATA) { - DHD_ERROR(("%s DONGLE_DOWN\n", __FUNCTION__)); - bcmerror = BCME_DONGLE_DOWN; - goto done; - } - - if (!dhd->pub.iswl) { - bcmerror = BCME_DONGLE_DOWN; - goto done; - } - - /* Intercept WLC_SET_KEY IOCTL - serialize M4 send and set key IOCTL to - * prevent M4 encryption. - */ - is_set_key_cmd = ((ioc.cmd == WLC_SET_KEY) || - ((ioc.cmd == WLC_SET_VAR) && - !(strncmp("wsec_key", ioc.buf, 9))) || - ((ioc.cmd == WLC_SET_VAR) && - !(strncmp("bsscfg:wsec_key", ioc.buf, 15)))); - if (is_set_key_cmd) { - dhd_wait_pend8021x(net); - } - - bcmerror = dhd_prot_ioctl(&dhd->pub, ifidx, (wl_ioctl_t *)&ioc, buf, buflen); - -done: - if ((bcmerror == -ETIMEDOUT) || ((dhd->pub.busstate == DHD_BUS_DOWN) && - (!dhd->pub.dongle_reset))) { - DHD_ERROR(("%s: Event HANG send up\n", __FUNCTION__)); - net_os_send_hang_message(net); - } - - if (!bcmerror && buf && ioc.buf) { - if (copy_to_user(ioc.buf, buf, buflen)) - bcmerror = -EFAULT; - } - - if (buf) - MFREE(dhd->pub.osh, buf, buflen); - - dhd_os_wake_unlock(&dhd->pub); - - return OSL_ERROR(bcmerror); -} - -static int -dhd_stop(struct net_device *net) -{ -#if !defined(IGNORE_ETH0_DOWN) - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); - - DHD_TRACE(("%s: Enter %s\n", __FUNCTION__, net->name)); - if (dhd->pub.up == 0) { - return 0; - } - - /* Set state and stop OS transmissions */ - dhd->pub.up = 0; - netif_stop_queue(net); -#else - DHD_ERROR(("BYPASS %s:due to BRCM compilation : under investigation ...\n", __FUNCTION__)); -#endif /* !defined(IGNORE_ETH0_DOWN) */ - dhd->pub.hang_was_sent = 0; - OLD_MOD_DEC_USE_COUNT; - return 0; -} - -static int -dhd_open(struct net_device *net) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); -#ifdef TOE - uint32 toe_ol; -#endif - int ifidx; - - /* Force start if ifconfig_up gets called before START command */ - wl_control_wl_start(net); - - ifidx = dhd_net2idx(dhd, net); - DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx)); - - if (ifidx == DHD_BAD_IF) - return -1; - - if ((dhd->iflist[ifidx]) && (dhd->iflist[ifidx]->state == WLC_E_IF_DEL)) { - DHD_ERROR(("%s: Error: called when IF already deleted\n", __FUNCTION__)); - return -1; - } - - if (ifidx == 0) { /* do it only for primary eth0 */ - - atomic_set(&dhd->pend_8021x_cnt, 0); - - memcpy(net->dev_addr, dhd->pub.mac.octet, ETHER_ADDR_LEN); - -#ifdef TOE - /* Get current TOE mode from dongle */ - if (dhd_toe_get(dhd, ifidx, &toe_ol) >= 0 && (toe_ol & TOE_TX_CSUM_OL) != 0) - dhd->iflist[ifidx]->net->features |= NETIF_F_IP_CSUM; - else - dhd->iflist[ifidx]->net->features &= ~NETIF_F_IP_CSUM; -#endif - } - /* Allow transmit calls */ - netif_start_queue(net); - dhd->pub.up = 1; - - OLD_MOD_INC_USE_COUNT; - return 0; -} - -osl_t * -dhd_osl_attach(void *pdev, uint bustype) -{ - return osl_attach(pdev, bustype, TRUE); -} - -void -dhd_osl_detach(osl_t *osh) -{ - if (MALLOCED(osh)) { - DHD_ERROR(("%s: MEMORY LEAK %d bytes\n", __FUNCTION__, MALLOCED(osh))); - } - osl_detach(osh); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && 1 - up(&dhd_registration_sem); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -} - -int -dhd_add_if(dhd_info_t *dhd, int ifidx, void *handle, char *name, - uint8 *mac_addr, uint32 flags, uint8 bssidx) -{ - dhd_if_t *ifp; - - DHD_TRACE(("%s: idx %d, handle->%p\n", __FUNCTION__, ifidx, handle)); - - ASSERT(dhd && (ifidx < DHD_MAX_IFS)); - - ifp = dhd->iflist[ifidx]; - if (!ifp && !(ifp = MALLOC(dhd->pub.osh, sizeof(dhd_if_t)))) { - DHD_ERROR(("%s: OOM - dhd_if_t\n", __FUNCTION__)); - return -ENOMEM; - } - - memset(ifp, 0, sizeof(dhd_if_t)); - ifp->info = dhd; - dhd->iflist[ifidx] = ifp; - strncpy(ifp->name, name, IFNAMSIZ); - ifp->name[IFNAMSIZ] = '\0'; - if (mac_addr != NULL) - memcpy(&ifp->mac_addr, mac_addr, ETHER_ADDR_LEN); - - if (handle == NULL) { - ifp->state = WLC_E_IF_ADD; - ifp->idx = ifidx; - ASSERT(dhd->sysioc_pid >= 0); - up(&dhd->sysioc_sem); - } else - ifp->net = (struct net_device *)handle; - - return 0; -} - -void -dhd_del_if(dhd_info_t *dhd, int ifidx) -{ - dhd_if_t *ifp; - - DHD_TRACE(("%s: idx %d\n", __FUNCTION__, ifidx)); - - ASSERT(dhd && ifidx && (ifidx < DHD_MAX_IFS)); - ifp = dhd->iflist[ifidx]; - if (!ifp) { - DHD_ERROR(("%s: Null interface\n", __FUNCTION__)); - return; - } - - ifp->state = WLC_E_IF_DEL; - ifp->idx = ifidx; - ASSERT(dhd->sysioc_pid >= 0); - up(&dhd->sysioc_sem); -} - - -dhd_pub_t * -dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) -{ - dhd_info_t *dhd = NULL; - struct net_device *net; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - /* updates firmware nvram path if it was provided as module paramters */ - if ((firmware_path != NULL) && (firmware_path[0] != '\0')) - strcpy(fw_path, firmware_path); - if ((nvram_path != NULL) && (nvram_path[0] != '\0')) - strcpy(nv_path, nvram_path); - - /* Allocate etherdev, including space for private structure */ - if (!(net = alloc_etherdev(sizeof(dhd)))) { - DHD_ERROR(("%s: OOM - alloc_etherdev\n", __FUNCTION__)); - goto fail; - } - - /* Allocate primary dhd_info */ - if (!(dhd = MALLOC(osh, sizeof(dhd_info_t)))) { - DHD_ERROR(("%s: OOM - alloc dhd_info\n", __FUNCTION__)); - goto fail; - } - - memset(dhd, 0, sizeof(dhd_info_t)); - - /* - * Save the dhd_info into the priv - */ - memcpy(netdev_priv(net), &dhd, sizeof(dhd)); - dhd->pub.osh = osh; - - mutex_init(&dhd->proto_sem); - mutex_init(&dhd->sdsem); - /* Initialize other structure content */ - init_waitqueue_head(&dhd->ioctl_resp_wait); - init_waitqueue_head(&dhd->ctrl_wait); - - /* Initialize the spinlocks */ - spin_lock_init(&dhd->sdlock); - spin_lock_init(&dhd->txqlock); - spin_lock_init(&dhd->dhd_lock); - - /* Set network interface name if it was provided as module parameter */ - if (iface_name[0]) { - int len; - char ch; - strncpy(net->name, iface_name, IFNAMSIZ); - net->name[IFNAMSIZ - 1] = 0; - len = strlen(net->name); - ch = net->name[len - 1]; - if ((ch > '9' || ch < '0') && (len < IFNAMSIZ - 2)) - strcat(net->name, "%d"); - } - - if (dhd_add_if(dhd, 0, (void *)net, net->name, NULL, 0, 0) == DHD_BAD_IF) - goto fail; - -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31)) - net->open = NULL; -#else - net->netdev_ops = NULL; -#endif - - /* Initialize Wakelock stuff */ - spin_lock_init(&dhd->wl_lock); - dhd->wl_count = 0; - dhd->wl_packet = 0; -#ifdef CONFIG_HAS_WAKELOCK - wake_lock_init(&dhd->wl_wifi, WAKE_LOCK_SUSPEND, "wlan_wake"); - wake_lock_init(&dhd->wl_rxwake, WAKE_LOCK_SUSPEND, "wlan_rx_wake"); -#endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - mutex_init(&dhd->wl_start_lock); -#endif - /* Link to info module */ - dhd->pub.info = dhd; - - /* Link to bus module */ - dhd->pub.bus = bus; - dhd->pub.hdrlen = bus_hdrlen; - - /* Attach and link in the protocol */ - if (dhd_prot_attach(&dhd->pub) != 0) { - DHD_ERROR(("dhd_prot_attach failed\n")); - goto fail; - } -#if defined(CONFIG_WIRELESS_EXT) - /* Attach and link in the iw */ - if (wl_iw_attach(net, (void *)&dhd->pub) != 0) { - DHD_ERROR(("wl_iw_attach failed\n")); - goto fail; - } -#endif /* defined(CONFIG_WIRELESS_EXT) */ - - /* Set up the watchdog timer */ - init_timer(&dhd->timer); - dhd->timer.data = (ulong)dhd; - dhd->timer.function = dhd_watchdog; - - /* Initialize thread based operation and lock */ - if ((dhd_watchdog_prio >= 0) && (dhd_dpc_prio >= 0)) { - dhd->threads_only = TRUE; - } - else { - dhd->threads_only = FALSE; - } - - if (dhd_dpc_prio >= 0) { - /* Initialize watchdog thread */ - sema_init(&dhd->watchdog_sem, 0); - init_completion(&dhd->watchdog_exited); - dhd->watchdog_pid = kernel_thread(dhd_watchdog_thread, dhd, 0); - } else { - dhd->watchdog_pid = -1; - } - - /* Set up the bottom half handler */ - if (dhd_dpc_prio >= 0) { - /* Initialize DPC thread */ - sema_init(&dhd->dpc_sem, 0); - init_completion(&dhd->dpc_exited); - dhd->dpc_pid = kernel_thread(dhd_dpc_thread, dhd, 0); - } else { - tasklet_init(&dhd->tasklet, dhd_dpc, (ulong)dhd); - dhd->dpc_pid = -1; - } - - if (dhd_sysioc) { - sema_init(&dhd->sysioc_sem, 0); - init_completion(&dhd->sysioc_exited); - dhd->sysioc_pid = kernel_thread(_dhd_sysioc_thread, dhd, 0); - } else { - dhd->sysioc_pid = -1; - } - - /* - * Save the dhd_info into the priv - */ - memcpy(netdev_priv(net), &dhd, sizeof(dhd)); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) - register_pm_notifier(&dhd_sleep_pm_notifier); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ - -#ifdef CONFIG_HAS_EARLYSUSPEND - dhd->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 20; - dhd->early_suspend.suspend = dhd_early_suspend; - dhd->early_suspend.resume = dhd_late_resume; - register_early_suspend(&dhd->early_suspend); -#endif - - register_inetaddr_notifier(&dhd_notifier); - - return &dhd->pub; - -fail: - if (net) - free_netdev(net); - if (dhd) - dhd_detach(&dhd->pub); - - return NULL; -} - - -int -dhd_bus_start(dhd_pub_t *dhdp) -{ - int ret = -1; - dhd_info_t *dhd = (dhd_info_t*)dhdp->info; -#ifdef EMBEDDED_PLATFORM - char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ -#endif /* EMBEDDED_PLATFORM */ - - ASSERT(dhd); - - DHD_TRACE(("%s: \n", __FUNCTION__)); - - dhd_os_sdlock(dhdp); - - /* try to download image and nvram to the dongle */ - if (dhd->pub.busstate == DHD_BUS_DOWN) { - if (!(dhd_bus_download_firmware(dhd->pub.bus, dhd->pub.osh, - fw_path, nv_path))) { - DHD_ERROR(("%s: dhdsdio_probe_download failed. firmware = %s nvram = %s\n", - __FUNCTION__, fw_path, nv_path)); - dhd_os_sdunlock(dhdp); - return -1; - } - } - - /* Start the watchdog timer */ - dhd->pub.tickcnt = 0; - dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms); - - /* Bring up the bus */ - if ((ret = dhd_bus_init(&dhd->pub, FALSE)) != 0) { - DHD_ERROR(("%s, dhd_bus_init failed %d\n", __FUNCTION__, ret)); - dhd_os_sdunlock(dhdp); - return ret; - } -#if defined(OOB_INTR_ONLY) - /* Host registration for OOB interrupt */ - if (bcmsdh_register_oob_intr(dhdp)) { - dhd->wd_timer_valid = FALSE; - del_timer_sync(&dhd->timer); - DHD_ERROR(("%s Host failed to resgister for OOB\n", __FUNCTION__)); - dhd_os_sdunlock(dhdp); - return -ENODEV; - } - - /* Enable oob at firmware */ - dhd_enable_oob_intr(dhd->pub.bus, TRUE); -#endif /* defined(OOB_INTR_ONLY) */ - - /* If bus is not ready, can't come up */ - if (dhd->pub.busstate != DHD_BUS_DATA) { - dhd->wd_timer_valid = FALSE; - del_timer_sync(&dhd->timer); - DHD_ERROR(("%s failed bus is not ready\n", __FUNCTION__)); - dhd_os_sdunlock(dhdp); - return -ENODEV; - } - - dhd_os_sdunlock(dhdp); - -#ifdef EMBEDDED_PLATFORM - bcm_mkiovar("event_msgs", dhdp->eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); - dhdcdc_query_ioctl(dhdp, 0, WLC_GET_VAR, iovbuf, sizeof(iovbuf)); - bcopy(iovbuf, dhdp->eventmask, WL_EVENTING_MASK_LEN); - - setbit(dhdp->eventmask, WLC_E_SET_SSID); - setbit(dhdp->eventmask, WLC_E_PRUNE); - setbit(dhdp->eventmask, WLC_E_AUTH); - setbit(dhdp->eventmask, WLC_E_REASSOC); - setbit(dhdp->eventmask, WLC_E_REASSOC_IND); - setbit(dhdp->eventmask, WLC_E_DEAUTH_IND); - setbit(dhdp->eventmask, WLC_E_DISASSOC_IND); - setbit(dhdp->eventmask, WLC_E_DISASSOC); - setbit(dhdp->eventmask, WLC_E_JOIN); - setbit(dhdp->eventmask, WLC_E_ASSOC_IND); - setbit(dhdp->eventmask, WLC_E_PSK_SUP); - setbit(dhdp->eventmask, WLC_E_LINK); - setbit(dhdp->eventmask, WLC_E_NDIS_LINK); - setbit(dhdp->eventmask, WLC_E_MIC_ERROR); - setbit(dhdp->eventmask, WLC_E_PMKID_CACHE); - setbit(dhdp->eventmask, WLC_E_TXFAIL); - setbit(dhdp->eventmask, WLC_E_JOIN_START); - setbit(dhdp->eventmask, WLC_E_SCAN_COMPLETE); - setbit(dhdp->eventmask, WLC_E_RELOAD); -#ifdef PNO_SUPPORT - setbit(dhdp->eventmask, WLC_E_PFN_NET_FOUND); -#endif /* PNO_SUPPORT */ - -/* enable dongle roaming event */ - setbit(dhdp->eventmask, WLC_E_ROAM); - - dhdp->pktfilter_count = 4; - /* Setup filter to allow only unicast */ - dhdp->pktfilter[0] = "100 0 0 0 0x01 0x00"; - dhdp->pktfilter[1] = NULL; - dhdp->pktfilter[2] = NULL; - dhdp->pktfilter[3] = NULL; -#endif /* EMBEDDED_PLATFORM */ - - /* Bus is ready, do any protocol initialization */ - if ((ret = dhd_prot_init(&dhd->pub)) < 0) - return ret; - - return 0; -} - -int -dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf, uint cmd_len, int set) -{ - char buf[strlen(name) + 1 + cmd_len]; - int len = sizeof(buf); - wl_ioctl_t ioc; - int ret; - - len = bcm_mkiovar(name, cmd_buf, cmd_len, buf, len); - - memset(&ioc, 0, sizeof(ioc)); - - ioc.cmd = set? WLC_SET_VAR : WLC_GET_VAR; - ioc.buf = buf; - ioc.len = len; - ioc.set = set; - - ret = dhd_prot_ioctl(pub, ifidx, &ioc, ioc.buf, ioc.len); - if (!set && ret >= 0) - memcpy(cmd_buf, buf, cmd_len); - - return ret; -} - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31)) -static struct net_device_ops dhd_ops_pri = { - .ndo_open = dhd_open, - .ndo_stop = dhd_stop, - .ndo_get_stats = dhd_get_stats, - .ndo_do_ioctl = dhd_ioctl_entry, - .ndo_start_xmit = dhd_start_xmit, - .ndo_set_mac_address = dhd_set_mac_address, - .ndo_set_multicast_list = dhd_set_multicast_list, -}; - -static struct net_device_ops dhd_ops_virt = { - .ndo_get_stats = dhd_get_stats, - .ndo_do_ioctl = dhd_ioctl_entry, - .ndo_start_xmit = dhd_start_xmit, - .ndo_set_mac_address = dhd_set_mac_address, - .ndo_set_multicast_list = dhd_set_multicast_list, -}; -#endif - -static int dhd_device_event(struct notifier_block *this, unsigned long event, - void *ptr) -{ - struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; - dhd_info_t *dhd; - dhd_pub_t *dhd_pub; - - if (!ifa) - return NOTIFY_DONE; - - dhd = *(dhd_info_t **)netdev_priv(ifa->ifa_dev->dev); - dhd_pub = &dhd->pub; - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31)) - if (ifa->ifa_dev->dev->netdev_ops == &dhd_ops_pri) { -#else - if (ifa->ifa_dev->dev->open == &dhd_open) { -#endif - switch (event) { - case NETDEV_UP: - DHD_TRACE(("%s: [%s] Up IP: 0x%x\n", - __FUNCTION__, ifa->ifa_label, ifa->ifa_address)); - - dhd_arp_cleanup(dhd_pub); - break; - - case NETDEV_DOWN: - DHD_TRACE(("%s: [%s] Down IP: 0x%x\n", - __FUNCTION__, ifa->ifa_label, ifa->ifa_address)); - - dhd_arp_cleanup(dhd_pub); - break; - - default: - DHD_TRACE(("%s: [%s] Event: %lu\n", - __FUNCTION__, ifa->ifa_label, event)); - break; - } - } - return NOTIFY_DONE; -} - -int -dhd_net_attach(dhd_pub_t *dhdp, int ifidx) -{ - dhd_info_t *dhd = (dhd_info_t *)dhdp->info; - struct net_device *net; - uint8 temp_addr[ETHER_ADDR_LEN] = { 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33 }; - - DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx)); - - ASSERT(dhd && dhd->iflist[ifidx]); - net = dhd->iflist[ifidx]->net; - - ASSERT(net); -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31)) - ASSERT(!net->open); - net->get_stats = dhd_get_stats; - net->do_ioctl = dhd_ioctl_entry; - net->hard_start_xmit = dhd_start_xmit; - net->set_mac_address = dhd_set_mac_address; - net->set_multicast_list = dhd_set_multicast_list; - net->open = net->stop = NULL; -#else - ASSERT(!net->netdev_ops); - net->netdev_ops = &dhd_ops_virt; -#endif - -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31)) - net->open = dhd_open; - net->stop = dhd_stop; -#else - net->netdev_ops = &dhd_ops_pri; -#endif - - /* - * We have to use the primary MAC for virtual interfaces - */ - if (ifidx != 0) { - /* for virtual interfaces use the primary MAC */ - memcpy(temp_addr, dhd->pub.mac.octet, ETHER_ADDR_LEN); - } - - if (ifidx == 1) { - DHD_TRACE(("%s ACCESS POINT MAC: \n", __FUNCTION__)); - /* ACCESSPOINT INTERFACE CASE */ - temp_addr[0] |= 0x02; /* set bit 2 , - Locally Administered address */ - } - net->hard_header_len = ETH_HLEN + dhd->pub.hdrlen; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) - net->ethtool_ops = &dhd_ethtool_ops; -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */ - -#if defined(CONFIG_WIRELESS_EXT) -#if WIRELESS_EXT < 19 - net->get_wireless_stats = dhd_get_wireless_stats; -#endif /* WIRELESS_EXT < 19 */ -#if WIRELESS_EXT > 12 - net->wireless_handlers = (struct iw_handler_def *)&wl_iw_handler_def; -#endif /* WIRELESS_EXT > 12 */ -#endif /* defined(CONFIG_WIRELESS_EXT) */ - - dhd->pub.rxsz = net->mtu + net->hard_header_len + dhd->pub.hdrlen; - - memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN); - - if (register_netdev(net) != 0) { - DHD_ERROR(("%s: couldn't register the net device\n", __FUNCTION__)); - goto fail; - } - - printf("%s: Broadcom Dongle Host Driver mac=%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", net->name, - dhd->pub.mac.octet[0], dhd->pub.mac.octet[1], dhd->pub.mac.octet[2], - dhd->pub.mac.octet[3], dhd->pub.mac.octet[4], dhd->pub.mac.octet[5]); - - -#if defined(CONFIG_WIRELESS_EXT) -#if defined(CONFIG_FIRST_SCAN) -#ifdef SOFTAP - if (ifidx == 0) - /* Don't call for SOFTAP Interface in SOFTAP MODE */ - wl_iw_iscan_set_scan_broadcast_prep(net, 1); -#else - wl_iw_iscan_set_scan_broadcast_prep(net, 1); -#endif /* SOFTAP */ -#endif /* CONFIG_FIRST_SCAN */ -#endif /* CONFIG_WIRELESS_EXT */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - up(&dhd_registration_sem); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ - return 0; - -fail: -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31)) - net->open = NULL; -#else - net->netdev_ops = NULL; -#endif - return BCME_ERROR; -} - -void -dhd_bus_detach(dhd_pub_t *dhdp) -{ - dhd_info_t *dhd; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (dhdp) { - dhd = (dhd_info_t *)dhdp->info; - if (dhd) { - /* Stop the protocol module */ - dhd_prot_stop(&dhd->pub); - - /* Stop the bus module */ - dhd_bus_stop(dhd->pub.bus, TRUE); -#if defined(OOB_INTR_ONLY) - bcmsdh_unregister_oob_intr(); -#endif /* defined(OOB_INTR_ONLY) */ - - /* Clear the watchdog timer */ - dhd->wd_timer_valid = FALSE; - del_timer_sync(&dhd->timer); - } - } -} - -void -dhd_detach(dhd_pub_t *dhdp) -{ - dhd_info_t *dhd; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (dhdp) { - dhd = (dhd_info_t *)dhdp->info; - if (dhd) { - dhd_if_t *ifp; - int i; - - unregister_inetaddr_notifier(&dhd_notifier); - -#if defined(CONFIG_HAS_EARLYSUSPEND) - if (dhd->early_suspend.suspend) - unregister_early_suspend(&dhd->early_suspend); -#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ -#if defined(CONFIG_WIRELESS_EXT) - /* Attach and link in the iw */ - wl_iw_detach(); -#endif - if (dhd->sysioc_pid >= 0) { - KILL_PROC(dhd->sysioc_pid, SIGTERM); - wait_for_completion(&dhd->sysioc_exited); - } - - for (i = 1; i < DHD_MAX_IFS; i++) - if (dhd->iflist[i]) { - dhd->iflist[i]->state = WLC_E_IF_DEL; - dhd->iflist[i]->idx = i; - dhd_op_if(dhd->iflist[i]); - } - - ifp = dhd->iflist[0]; - ASSERT(ifp); -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31)) - if (ifp->net->open) { -#else - if (ifp->net->netdev_ops == &dhd_ops_pri) { -#endif - dhd_stop(ifp->net); - unregister_netdev(ifp->net); - } - - if (dhd->watchdog_pid >= 0) - { - KILL_PROC(dhd->watchdog_pid, SIGTERM); - wait_for_completion(&dhd->watchdog_exited); - } - - if (dhd->dpc_pid >= 0) - { - KILL_PROC(dhd->dpc_pid, SIGTERM); - wait_for_completion(&dhd->dpc_exited); - } - else - tasklet_kill(&dhd->tasklet); - - dhd_bus_detach(dhdp); - - if (dhdp->prot) - dhd_prot_detach(dhdp); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) - unregister_pm_notifier(&dhd_sleep_pm_notifier); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ - free_netdev(ifp->net); -#ifdef CONFIG_HAS_WAKELOCK - wake_lock_destroy(&dhd->wl_wifi); - wake_lock_destroy(&dhd->wl_rxwake); -#endif - MFREE(dhd->pub.osh, ifp, sizeof(*ifp)); - MFREE(dhd->pub.osh, dhd, sizeof(*dhd)); - } - } -} - -static void __exit -dhd_module_cleanup(void) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - dhd_bus_unregister(); -#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) - wifi_del_dev(); -#endif - /* Call customer gpio to turn off power with WL_REG_ON signal */ - dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF); -} - -static int __init -dhd_module_init(void) -{ - int error; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* Sanity check on the module parameters */ - do { - /* Both watchdog and DPC as tasklets are ok */ - if ((dhd_watchdog_prio < 0) && (dhd_dpc_prio < 0)) - break; - - /* If both watchdog and DPC are threads, TX must be deferred */ - if ((dhd_watchdog_prio >= 0) && (dhd_dpc_prio >= 0) && dhd_deferred_tx) - break; - - DHD_ERROR(("Invalid module parameters.\n")); - return -EINVAL; - } while (0); - - /* Call customer gpio to turn on power with WL_REG_ON signal */ - dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON); - -#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) - sema_init(&wifi_control_sem, 0); - - error = wifi_add_dev(); - if (error) { - DHD_ERROR(("%s: platform_driver_register failed\n", __FUNCTION__)); - goto fail_0; - } - - /* Waiting callback after platform_driver_register is done or exit with error */ - if (down_timeout(&wifi_control_sem, msecs_to_jiffies(5000)) != 0) { - error = -EINVAL; - DHD_ERROR(("%s: platform_driver_register timeout\n", __FUNCTION__)); - goto fail_1; - } -#endif /* #if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - sema_init(&dhd_registration_sem, 0); -#endif - - error = dhd_bus_register(); - - if (!error) - printf("\n%s\n", dhd_version); - else { - DHD_ERROR(("%s: sdio_register_driver failed\n", __FUNCTION__)); - goto fail_1; - } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - /* - * Wait till MMC sdio_register_driver callback called and made driver attach. - * It's needed to make sync up exit from dhd insmod and - * Kernel MMC sdio device callback registration - */ - if (down_timeout(&dhd_registration_sem, msecs_to_jiffies(DHD_REGISTRATION_TIMEOUT)) != 0) { - error = -EINVAL; - DHD_ERROR(("%s: sdio_register_driver timeout\n", __FUNCTION__)); - goto fail_2; - } -#endif - return error; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -fail_2: - dhd_bus_unregister(); -#endif -fail_1: -#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) - wifi_del_dev(); -fail_0: -#endif /* defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */ - - /* Call customer gpio to turn off power with WL_REG_ON signal */ - dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF); - - return error; -} - -module_init(dhd_module_init); -module_exit(dhd_module_cleanup); - -/* - * OS specific functions required to implement DHD driver in OS independent way - */ -int -dhd_os_proto_block(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - - if (dhd) { - mutex_lock(&dhd->proto_sem); - return 1; - } - - return 0; -} - -int -dhd_os_proto_unblock(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - - if (dhd) { - mutex_unlock(&dhd->proto_sem); - return 1; - } - - return 0; -} - -unsigned int -dhd_os_get_ioctl_resp_timeout(void) -{ - return ((unsigned int)dhd_ioctl_timeout_msec); -} - -void -dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec) -{ - dhd_ioctl_timeout_msec = (int)timeout_msec; -} - -int -dhd_os_ioctl_resp_wait(dhd_pub_t *pub, uint *condition, bool *pending) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - DECLARE_WAITQUEUE(wait, current); - int timeout = dhd_ioctl_timeout_msec; - - /* Convert timeout in millsecond to jiffies */ - /* timeout = timeout * HZ / 1000; */ - timeout = msecs_to_jiffies(timeout); - - /* Wait until control frame is available */ - add_wait_queue(&dhd->ioctl_resp_wait, &wait); - set_current_state(TASK_INTERRUPTIBLE); - smp_mb(); - while (!(*condition) && (!signal_pending(current) && timeout)) { - timeout = schedule_timeout(timeout); - smp_mb(); - } - - if (signal_pending(current)) - *pending = TRUE; - - set_current_state(TASK_RUNNING); - remove_wait_queue(&dhd->ioctl_resp_wait, &wait); - - return timeout; -} - -int -dhd_os_ioctl_resp_wake(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - - if (waitqueue_active(&dhd->ioctl_resp_wait)) { - wake_up_interruptible(&dhd->ioctl_resp_wait); - } - - return 0; -} - -void -dhd_os_wd_timer(void *bus, uint wdtick) -{ - dhd_pub_t *pub = bus; - dhd_info_t *dhd = (dhd_info_t *)pub->info; - unsigned long flags; - int del_timer_flag = FALSE; - - flags = dhd_os_spin_lock(pub); - - /* don't start the wd until fw is loaded */ - if (pub->busstate != DHD_BUS_DOWN) { - if (wdtick) { - dhd_watchdog_ms = (uint)wdtick; - dhd->wd_timer_valid = TRUE; - /* Re arm the timer, at last watchdog period */ - mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000); - } else if (dhd->wd_timer_valid == TRUE) { - /* Totally stop the timer */ - dhd->wd_timer_valid = FALSE; - del_timer_flag = TRUE; - } - } - dhd_os_spin_unlock(pub, flags); - if (del_timer_flag) { - del_timer_sync(&dhd->timer); - } -} - -void * -dhd_os_open_image(char *filename) -{ - struct file *fp; - - fp = filp_open(filename, O_RDONLY, 0); - /* - * 2.6.11 (FC4) supports filp_open() but later revs don't? - * Alternative: - * fp = open_namei(AT_FDCWD, filename, O_RD, 0); - * ??? - */ - if (IS_ERR(fp)) - fp = NULL; - - return fp; -} - -int -dhd_os_get_image_block(char *buf, int len, void *image) -{ - struct file *fp = (struct file *)image; - int rdlen; - - if (!image) - return 0; - - rdlen = kernel_read(fp, fp->f_pos, buf, len); - if (rdlen > 0) - fp->f_pos += rdlen; - - return rdlen; -} - -void -dhd_os_close_image(void *image) -{ - if (image) - filp_close((struct file *)image, NULL); -} - - -void -dhd_os_sdlock(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)(pub->info); - - if (dhd->threads_only) - mutex_lock(&dhd->sdsem); - else - spin_lock_bh(&dhd->sdlock); -} - -void -dhd_os_sdunlock(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)(pub->info); - - if (dhd->threads_only) - mutex_unlock(&dhd->sdsem); - else - spin_unlock_bh(&dhd->sdlock); -} - -void -dhd_os_sdlock_txq(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)(pub->info); - spin_lock_bh(&dhd->txqlock); -} - -void -dhd_os_sdunlock_txq(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)(pub->info); - spin_unlock_bh(&dhd->txqlock); -} -void -dhd_os_sdlock_rxq(dhd_pub_t *pub) -{ -} -void -dhd_os_sdunlock_rxq(dhd_pub_t *pub) -{ -} - -void -dhd_os_sdtxlock(dhd_pub_t *pub) -{ - dhd_os_sdlock(pub); -} - -void -dhd_os_sdtxunlock(dhd_pub_t *pub) -{ - dhd_os_sdunlock(pub); -} - -#ifdef DHD_USE_STATIC_BUF -void * dhd_os_prealloc(int section, unsigned long size) -{ -#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) - void *alloc_ptr = NULL; - if (wifi_control_data && wifi_control_data->mem_prealloc) - { - alloc_ptr = wifi_control_data->mem_prealloc(section, size); - if (alloc_ptr) - { - DHD_INFO(("success alloc section %d\n", section)); - bzero(alloc_ptr, size); - return alloc_ptr; - } - } - - DHD_ERROR(("can't alloc section %d\n", section)); - return 0; -#else -return MALLOC(0, size); -#endif /* #if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */ -} -#endif /* DHD_USE_STATIC_BUF */ -#if defined(CONFIG_WIRELESS_EXT) -struct iw_statistics * -dhd_get_wireless_stats(struct net_device *dev) -{ - int res = 0; - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - res = wl_iw_get_wireless_stats(dev, &dhd->iw.wstats); - - if (res == 0) - return &dhd->iw.wstats; - else - return NULL; -} -#endif /* defined(CONFIG_WIRELESS_EXT) */ - -static int -dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, - wl_event_msg_t *event, void **data) -{ - int bcmerror = 0; - - ASSERT(dhd != NULL); - - bcmerror = wl_host_event(dhd, ifidx, pktdata, event, data); - if (bcmerror != BCME_OK) - return (bcmerror); - -#if defined(CONFIG_WIRELESS_EXT) - ASSERT(dhd->iflist[*ifidx] != NULL); - - if (ntoh32(event->event_type) == WLC_E_IF) { - DHD_INFO(("<0> interface:%d OP:%d don't pass to wext," - "net_device might not be created yet\n", - *ifidx, ntoh32(event->event_type))); - return bcmerror; - } - - ASSERT(dhd->iflist[*ifidx]->net != NULL); - - if (dhd->iflist[*ifidx]->net) - wl_iw_event(dhd->iflist[*ifidx]->net, event, *data); -#endif /* defined(CONFIG_WIRELESS_EXT) */ - - return (bcmerror); -} - -/* send up locally generated event */ -void -dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data) -{ - switch (ntoh32(event->event_type)) { - default: - break; - } -} - -void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) - struct dhd_info *dhdinfo = dhd->info; - dhd_os_sdunlock(dhd); - wait_event_interruptible_timeout(dhdinfo->ctrl_wait, (*lockvar == FALSE), HZ * 2); - dhd_os_sdlock(dhd); -#endif - return; -} - -void dhd_wait_event_wakeup(dhd_pub_t *dhd) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) - struct dhd_info *dhdinfo = dhd->info; - if (waitqueue_active(&dhdinfo->ctrl_wait)) - wake_up_interruptible(&dhdinfo->ctrl_wait); -#endif - return; -} - -int -dhd_dev_reset(struct net_device *dev, uint8 flag) -{ - int ret; - - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - ret = dhd_bus_devreset(&dhd->pub, flag); - if (ret) { - DHD_ERROR(("%s: dhd_bus_devreset: %d\n", __FUNCTION__, ret)); - return ret; - } - DHD_ERROR(("%s: WLAN %s DONE\n", __FUNCTION__, flag ? "OFF" : "ON")); - - return ret; -} - -int net_os_set_suspend_disable(struct net_device *dev, int val) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) { - ret = dhd->pub.suspend_disable_flag; - dhd->pub.suspend_disable_flag = val; - } - return ret; -} - -int net_os_set_suspend(struct net_device *dev, int val) -{ - int ret = 0; -#if defined(CONFIG_HAS_EARLYSUSPEND) - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - if (dhd) { - dhd_os_proto_block(&dhd->pub); - ret = dhd_set_suspend(val, &dhd->pub); - dhd_os_proto_unblock(&dhd->pub); - } -#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ - return ret; -} - -int net_os_set_dtim_skip(struct net_device *dev, int val) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - if (dhd) - dhd->pub.dtim_skip = val; - - return 0; -} - -int net_os_rxfilter_add_remove(struct net_device *dev, int add_remove, int num) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - char *filterp = NULL; - int ret = 0; - - if (!dhd || (num == DHD_UNICAST_FILTER_NUM)) - return ret; - if (num >= dhd->pub.pktfilter_count) - return -EINVAL; - if (add_remove) { - switch (num) { - case DHD_BROADCAST_FILTER_NUM: - filterp = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF"; - break; - case DHD_MULTICAST4_FILTER_NUM: - filterp = "102 0 0 0 0xFFFFFF 0x01005E"; - break; - case DHD_MULTICAST6_FILTER_NUM: - filterp = "103 0 0 0 0xFFFF 0x3333"; - break; - default: - return -EINVAL; - } - } - dhd->pub.pktfilter[num] = filterp; - return ret; -} - -int net_os_set_packet_filter(struct net_device *dev, int val) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - /* Packet filtering is set only if we still in early-suspend and - * we need either to turn it ON or turn it OFF - * We can always turn it OFF in case of early-suspend, but we turn it - * back ON only if suspend_disable_flag was not set - */ - if (dhd && dhd->pub.up) { - dhd_os_proto_block(&dhd->pub); - if (dhd->pub.in_suspend) { - if (!val || (val && !dhd->pub.suspend_disable_flag)) - dhd_set_packet_filter(val, &dhd->pub); - } - dhd_os_proto_unblock(&dhd->pub); - } - return ret; -} - - -void -dhd_dev_init_ioctl(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - dhd_preinit_ioctls(&dhd->pub); -} - -#ifdef PNO_SUPPORT -/* Linux wrapper to call common dhd_pno_clean */ -int -dhd_dev_pno_reset(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return (dhd_pno_clean(&dhd->pub)); -} - - -/* Linux wrapper to call common dhd_pno_enable */ -int -dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return (dhd_pno_enable(&dhd->pub, pfn_enabled)); -} - - -/* Linux wrapper to call common dhd_pno_set */ -int -dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid, - ushort scan_fr, int pno_repeat, int pno_freq_expo_max) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return (dhd_pno_set(&dhd->pub, ssids_local, nssid, scan_fr, pno_repeat, pno_freq_expo_max)); -} - -/* Linux wrapper to get pno status */ -int -dhd_dev_get_pno_status(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return (dhd_pno_get_status(&dhd->pub)); -} - -#endif /* PNO_SUPPORT */ - -int net_os_send_hang_message(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) { - if (!dhd->pub.hang_was_sent) { - dhd->pub.hang_was_sent = 1; - ret = wl_iw_send_priv_event(dev, "HANG"); - } - } - return ret; -} - -void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - if (dhd && dhd->pub.up) - memcpy(&dhd->pub.dhd_cspec, cspec, sizeof(wl_country_t)); -} - -char *dhd_bus_country_get(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - if (dhd && (dhd->pub.dhd_cspec.ccode[0] != 0)) - return dhd->pub.dhd_cspec.ccode; - return NULL; -} - -void dhd_os_start_lock(dhd_pub_t *pub) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - - if (dhd) - mutex_lock(&dhd->wl_start_lock); -#endif -} - -void dhd_os_start_unlock(dhd_pub_t *pub) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - - if (dhd) - mutex_unlock(&dhd->wl_start_lock); -#endif -} - -static int -dhd_get_pend_8021x_cnt(dhd_info_t *dhd) -{ - return (atomic_read(&dhd->pend_8021x_cnt)); -} - -#define MAX_WAIT_FOR_8021X_TX 10 - -int -dhd_wait_pend8021x(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int timeout = 10 * HZ / 1000; - int ntimes = MAX_WAIT_FOR_8021X_TX; - int pend = dhd_get_pend_8021x_cnt(dhd); - - while (ntimes && pend) { - if (pend) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(timeout); - set_current_state(TASK_RUNNING); - ntimes--; - } - pend = dhd_get_pend_8021x_cnt(dhd); - } - return pend; -} - -#ifdef DHD_DEBUG -int -write_to_file(dhd_pub_t *dhd, uint8 *buf, int size) -{ - int ret = 0; - struct file *fp; - mm_segment_t old_fs; - loff_t pos = 0; - - /* change to KERNEL_DS address limit */ - old_fs = get_fs(); - set_fs(KERNEL_DS); - - /* open file to write */ - fp = filp_open("/tmp/mem_dump", O_WRONLY|O_CREAT, 0640); - if (!fp) { - printf("%s: open file error\n", __FUNCTION__); - ret = -1; - goto exit; - } - - /* Write buf to file */ - fp->f_op->write(fp, buf, size, &pos); - -exit: - /* free buf before return */ - MFREE(dhd->osh, buf, size); - /* close file before return */ - if (fp) - filp_close(fp, current->files); - /* restore previous address limit */ - set_fs(old_fs); - - return ret; -} -#endif /* DHD_DEBUG */ - -int dhd_os_wake_lock_timeout(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags; - int ret = 0; - - if (dhd) { - spin_lock_irqsave(&dhd->wl_lock, flags); - ret = dhd->wl_packet; -#ifdef CONFIG_HAS_WAKELOCK - if (dhd->wl_packet) - wake_lock_timeout(&dhd->wl_rxwake, HZ); -#endif - dhd->wl_packet = 0; - spin_unlock_irqrestore(&dhd->wl_lock, flags); - } - /* printk("%s: %d\n", __FUNCTION__, ret); */ - return ret; -} - -int net_os_wake_lock_timeout(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) - ret = dhd_os_wake_lock_timeout(&dhd->pub); - return ret; -} - -int dhd_os_wake_lock_timeout_enable(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags; - - if (dhd) { - spin_lock_irqsave(&dhd->wl_lock, flags); - dhd->wl_packet = 1; - spin_unlock_irqrestore(&dhd->wl_lock, flags); - } - /* printk("%s\n",__func__); */ - return 0; -} - -int net_os_wake_lock_timeout_enable(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) - ret = dhd_os_wake_lock_timeout_enable(&dhd->pub); - return ret; -} - -int dhd_os_wake_lock(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags; - int ret = 0; - - if (dhd) { - spin_lock_irqsave(&dhd->wl_lock, flags); -#ifdef CONFIG_HAS_WAKELOCK - if (!dhd->wl_count) - wake_lock(&dhd->wl_wifi); -#endif - dhd->wl_count++; - ret = dhd->wl_count; - spin_unlock_irqrestore(&dhd->wl_lock, flags); - } - /* printk("%s: %d\n", __FUNCTION__, ret); */ - return ret; -} - -int net_os_wake_lock(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) - ret = dhd_os_wake_lock(&dhd->pub); - return ret; -} - -int dhd_os_wake_unlock(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags; - int ret = 0; - - dhd_os_wake_lock_timeout(pub); - if (dhd) { - spin_lock_irqsave(&dhd->wl_lock, flags); - if (dhd->wl_count) { - dhd->wl_count--; -#ifdef CONFIG_HAS_WAKELOCK - if (!dhd->wl_count) - wake_unlock(&dhd->wl_wifi); -#endif - ret = dhd->wl_count; - } - spin_unlock_irqrestore(&dhd->wl_lock, flags); - } - /* printk("%s: %d\n", __FUNCTION__, ret); */ - return ret; -} - -int net_os_wake_unlock(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) - ret = dhd_os_wake_unlock(&dhd->pub); - return ret; -} - -unsigned long dhd_os_spin_lock(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags = 0; - - if (dhd) - spin_lock_irqsave(&dhd->dhd_lock, flags); - - return flags; -} - -void dhd_os_spin_unlock(dhd_pub_t *pub, unsigned long flags) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - - if (dhd) - spin_unlock_irqrestore(&dhd->dhd_lock, flags); -} diff --git a/drivers/net/wireless/bcm4329/dhd_linux_sched.c b/drivers/net/wireless/bcm4329/dhd_linux_sched.c deleted file mode 100644 index 480b416657ee..000000000000 --- a/drivers/net/wireless/bcm4329/dhd_linux_sched.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Expose some of the kernel scheduler routines - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd_linux_sched.c,v 1.1.34.1.6.1 2009/01/16 01:17:40 Exp $ - */ -#include -#include -#include -#include - -int setScheduler(struct task_struct *p, int policy, struct sched_param *param) -{ - int rc = 0; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) - rc = sched_setscheduler(p, policy, param); -#endif /* LinuxVer */ - return rc; -} diff --git a/drivers/net/wireless/bcm4329/dhd_proto.h b/drivers/net/wireless/bcm4329/dhd_proto.h deleted file mode 100644 index 7ef6929a5bf7..000000000000 --- a/drivers/net/wireless/bcm4329/dhd_proto.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Header file describing the internal (inter-module) DHD interfaces. - * - * Provides type definitions and function prototypes used to link the - * DHD OS, bus, and protocol modules. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd_proto.h,v 1.2.82.1.4.1.16.7 2010/05/10 12:54:59 Exp $ - */ - -#ifndef _dhd_proto_h_ -#define _dhd_proto_h_ - -#include -#include - -#ifndef IOCTL_RESP_TIMEOUT -#define IOCTL_RESP_TIMEOUT 3000 /* In milli second */ -#endif - -#ifndef IOCTL_CHIP_ACTIVE_TIMEOUT -#define IOCTL_CHIP_ACTIVE_TIMEOUT 10 /* In milli second */ -#endif - -/* - * Exported from the dhd protocol module (dhd_cdc, dhd_rndis) - */ - -/* Linkage, sets prot link and updates hdrlen in pub */ -extern int dhd_prot_attach(dhd_pub_t *dhdp); - -/* Unlink, frees allocated protocol memory (including dhd_prot) */ -extern void dhd_prot_detach(dhd_pub_t *dhdp); - -/* Initialize protocol: sync w/dongle state. - * Sets dongle media info (iswl, drv_version, mac address). - */ -extern int dhd_prot_init(dhd_pub_t *dhdp); - -/* Stop protocol: sync w/dongle state. */ -extern void dhd_prot_stop(dhd_pub_t *dhdp); - -extern bool dhd_proto_fcinfo(dhd_pub_t *dhd, void *pktbuf, uint8 *fcbits); - -/* Add any protocol-specific data header. - * Caller must reserve prot_hdrlen prepend space. - */ -extern void dhd_prot_hdrpush(dhd_pub_t *, int ifidx, void *txp); - -/* Remove any protocol-specific data header. */ -extern int dhd_prot_hdrpull(dhd_pub_t *, int *ifidx, void *rxp); - -/* Use protocol to issue ioctl to dongle */ -extern int dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len); - -/* Check for and handle local prot-specific iovar commands */ -extern int dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name, - void *params, int plen, void *arg, int len, bool set); - -/* Add prot dump output to a buffer */ -extern void dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf); - -/* Update local copy of dongle statistics */ -extern void dhd_prot_dstats(dhd_pub_t *dhdp); - -extern int dhd_ioctl(dhd_pub_t * dhd_pub, dhd_ioctl_t *ioc, void * buf, uint buflen); - -extern int dhd_preinit_ioctls(dhd_pub_t *dhd); - -/******************************** - * For version-string expansion * - */ -#if defined(BDC) -#define DHD_PROTOCOL "bdc" -#elif defined(CDC) -#define DHD_PROTOCOL "cdc" -#elif defined(RNDIS) -#define DHD_PROTOCOL "rndis" -#else -#define DHD_PROTOCOL "unknown" -#endif /* proto */ - -#endif /* _dhd_proto_h_ */ diff --git a/drivers/net/wireless/bcm4329/dhd_sdio.c b/drivers/net/wireless/bcm4329/dhd_sdio.c deleted file mode 100644 index e9093e810624..000000000000 --- a/drivers/net/wireless/bcm4329/dhd_sdio.c +++ /dev/null @@ -1,5824 +0,0 @@ -/* - * DHD Bus Module for SDIO - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd_sdio.c,v 1.157.2.27.2.33.2.129.4.1 2010/09/02 23:13:16 Exp $ - */ - -#include -#include -#include - -#ifdef BCMEMBEDIMAGE -#include BCMEMBEDIMAGE -#endif /* BCMEMBEDIMAGE */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef DHD_DEBUG -#include -#endif /* DHD_DEBUG */ -#ifdef DHD_DEBUG_TRAP -#include -#endif /* DHD_DEBUG_TRAP */ - -#define QLEN 256 /* bulk rx and tx queue lengths */ -#define FCHI (QLEN - 10) -#define FCLOW (FCHI / 2) -#define PRIOMASK 7 - -#define TXRETRIES 2 /* # of retries for tx frames */ - -#if defined(CONFIG_MACH_SANDGATE2G) -#define DHD_RXBOUND 250 /* Default for max rx frames in one scheduling */ -#else -#define DHD_RXBOUND 50 /* Default for max rx frames in one scheduling */ -#endif /* defined(CONFIG_MACH_SANDGATE2G) */ - -#define DHD_TXBOUND 20 /* Default for max tx frames in one scheduling */ - -#define DHD_TXMINMAX 1 /* Max tx frames if rx still pending */ - -#define MEMBLOCK 2048 /* Block size used for downloading of dongle image */ -#define MAX_DATA_BUF (32 * 1024) /* Must be large enough to hold biggest possible glom */ - -/* Packet alignment for most efficient SDIO (can change based on platform) */ -#ifndef DHD_SDALIGN -#define DHD_SDALIGN 32 -#endif -#if !ISPOWEROF2(DHD_SDALIGN) -#error DHD_SDALIGN is not a power of 2! -#endif - -#ifndef DHD_FIRSTREAD -#define DHD_FIRSTREAD 32 -#endif -#if !ISPOWEROF2(DHD_FIRSTREAD) -#error DHD_FIRSTREAD is not a power of 2! -#endif - -/* Total length of frame header for dongle protocol */ -#define SDPCM_HDRLEN (SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN) -#ifdef SDTEST -#define SDPCM_RESERVE (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN) -#else -#define SDPCM_RESERVE (SDPCM_HDRLEN + DHD_SDALIGN) -#endif - -/* Space for header read, limit for data packets */ -#ifndef MAX_HDR_READ -#define MAX_HDR_READ 32 -#endif -#if !ISPOWEROF2(MAX_HDR_READ) -#error MAX_HDR_READ is not a power of 2! -#endif - -#define MAX_RX_DATASZ 2048 - -/* Maximum milliseconds to wait for F2 to come up */ -#define DHD_WAIT_F2RDY 3000 - -/* Bump up limit on waiting for HT to account for first startup; - * if the image is doing a CRC calculation before programming the PMU - * for HT availability, it could take a couple hundred ms more, so - * max out at a 1 second (1000000us). - */ -#if (PMU_MAX_TRANSITION_DLY < 1000000) -#undef PMU_MAX_TRANSITION_DLY -#define PMU_MAX_TRANSITION_DLY 1000000 -#endif - -/* Value for ChipClockCSR during initial setup */ -#define DHD_INIT_CLKCTL1 (SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ) -#define DHD_INIT_CLKCTL2 (SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP) - -/* Flags for SDH calls */ -#define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED) - -/* Packet free applicable unconditionally for sdio and sdspi. Conditional if - * bufpool was present for gspi bus. - */ -#define PKTFREE2() if ((bus->bus != SPI_BUS) || bus->usebufpool) \ - PKTFREE(bus->dhd->osh, pkt, FALSE); -DHD_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep); -extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len); - -extern void bcmsdh_set_irq(int flag); - -#ifdef DHD_DEBUG -/* Device console log buffer state */ -typedef struct dhd_console { - uint count; /* Poll interval msec counter */ - uint log_addr; /* Log struct address (fixed) */ - hndrte_log_t log; /* Log struct (host copy) */ - uint bufsize; /* Size of log buffer */ - uint8 *buf; /* Log buffer (host copy) */ - uint last; /* Last buffer read index */ -} dhd_console_t; -#endif /* DHD_DEBUG */ - -/* Private data for SDIO bus interaction */ -typedef struct dhd_bus { - dhd_pub_t *dhd; - - bcmsdh_info_t *sdh; /* Handle for BCMSDH calls */ - si_t *sih; /* Handle for SI calls */ - char *vars; /* Variables (from CIS and/or other) */ - uint varsz; /* Size of variables buffer */ - uint32 sbaddr; /* Current SB window pointer (-1, invalid) */ - - sdpcmd_regs_t *regs; /* Registers for SDIO core */ - uint sdpcmrev; /* SDIO core revision */ - uint armrev; /* CPU core revision */ - uint ramrev; /* SOCRAM core revision */ - uint32 ramsize; /* Size of RAM in SOCRAM (bytes) */ - uint32 orig_ramsize; /* Size of RAM in SOCRAM (bytes) */ - - uint32 bus; /* gSPI or SDIO bus */ - uint32 hostintmask; /* Copy of Host Interrupt Mask */ - uint32 intstatus; /* Intstatus bits (events) pending */ - bool dpc_sched; /* Indicates DPC schedule (intrpt rcvd) */ - bool fcstate; /* State of dongle flow-control */ - - uint16 cl_devid; /* cached devid for dhdsdio_probe_attach() */ - char *fw_path; /* module_param: path to firmware image */ - char *nv_path; /* module_param: path to nvram vars file */ - const char *nvram_params; /* user specified nvram params. */ - - uint blocksize; /* Block size of SDIO transfers */ - uint roundup; /* Max roundup limit */ - - struct pktq txq; /* Queue length used for flow-control */ - uint8 flowcontrol; /* per prio flow control bitmask */ - uint8 tx_seq; /* Transmit sequence number (next) */ - uint8 tx_max; /* Maximum transmit sequence allowed */ - - uint8 hdrbuf[MAX_HDR_READ + DHD_SDALIGN]; - uint8 *rxhdr; /* Header of current rx frame (in hdrbuf) */ - uint16 nextlen; /* Next Read Len from last header */ - uint8 rx_seq; /* Receive sequence number (expected) */ - bool rxskip; /* Skip receive (awaiting NAK ACK) */ - - void *glomd; /* Packet containing glomming descriptor */ - void *glom; /* Packet chain for glommed superframe */ - uint glomerr; /* Glom packet read errors */ - - uint8 *rxbuf; /* Buffer for receiving control packets */ - uint rxblen; /* Allocated length of rxbuf */ - uint8 *rxctl; /* Aligned pointer into rxbuf */ - uint8 *databuf; /* Buffer for receiving big glom packet */ - uint8 *dataptr; /* Aligned pointer into databuf */ - uint rxlen; /* Length of valid data in buffer */ - - uint8 sdpcm_ver; /* Bus protocol reported by dongle */ - - bool intr; /* Use interrupts */ - bool poll; /* Use polling */ - bool ipend; /* Device interrupt is pending */ - bool intdis; /* Interrupts disabled by isr */ - uint intrcount; /* Count of device interrupt callbacks */ - uint lastintrs; /* Count as of last watchdog timer */ - uint spurious; /* Count of spurious interrupts */ - uint pollrate; /* Ticks between device polls */ - uint polltick; /* Tick counter */ - uint pollcnt; /* Count of active polls */ - -#ifdef DHD_DEBUG - dhd_console_t console; /* Console output polling support */ - uint console_addr; /* Console address from shared struct */ -#endif /* DHD_DEBUG */ - - uint regfails; /* Count of R_REG/W_REG failures */ - - uint clkstate; /* State of sd and backplane clock(s) */ - bool activity; /* Activity flag for clock down */ - int32 idletime; /* Control for activity timeout */ - int32 idlecount; /* Activity timeout counter */ - int32 idleclock; /* How to set bus driver when idle */ - int32 sd_divisor; /* Speed control to bus driver */ - int32 sd_mode; /* Mode control to bus driver */ - int32 sd_rxchain; /* If bcmsdh api accepts PKT chains */ - bool use_rxchain; /* If dhd should use PKT chains */ - bool sleeping; /* Is SDIO bus sleeping? */ - bool rxflow_mode; /* Rx flow control mode */ - bool rxflow; /* Is rx flow control on */ - uint prev_rxlim_hit; /* Is prev rx limit exceeded (per dpc schedule) */ - bool alp_only; /* Don't use HT clock (ALP only) */ - /* Field to decide if rx of control frames happen in rxbuf or lb-pool */ - bool usebufpool; - -#ifdef SDTEST - /* external loopback */ - bool ext_loop; - uint8 loopid; - - /* pktgen configuration */ - uint pktgen_freq; /* Ticks between bursts */ - uint pktgen_count; /* Packets to send each burst */ - uint pktgen_print; /* Bursts between count displays */ - uint pktgen_total; /* Stop after this many */ - uint pktgen_minlen; /* Minimum packet data len */ - uint pktgen_maxlen; /* Maximum packet data len */ - uint pktgen_mode; /* Configured mode: tx, rx, or echo */ - uint pktgen_stop; /* Number of tx failures causing stop */ - - /* active pktgen fields */ - uint pktgen_tick; /* Tick counter for bursts */ - uint pktgen_ptick; /* Burst counter for printing */ - uint pktgen_sent; /* Number of test packets generated */ - uint pktgen_rcvd; /* Number of test packets received */ - uint pktgen_fail; /* Number of failed send attempts */ - uint16 pktgen_len; /* Length of next packet to send */ -#endif /* SDTEST */ - - /* Some additional counters */ - uint tx_sderrs; /* Count of tx attempts with sd errors */ - uint fcqueued; /* Tx packets that got queued */ - uint rxrtx; /* Count of rtx requests (NAK to dongle) */ - uint rx_toolong; /* Receive frames too long to receive */ - uint rxc_errors; /* SDIO errors when reading control frames */ - uint rx_hdrfail; /* SDIO errors on header reads */ - uint rx_badhdr; /* Bad received headers (roosync?) */ - uint rx_badseq; /* Mismatched rx sequence number */ - uint fc_rcvd; /* Number of flow-control events received */ - uint fc_xoff; /* Number which turned on flow-control */ - uint fc_xon; /* Number which turned off flow-control */ - uint rxglomfail; /* Failed deglom attempts */ - uint rxglomframes; /* Number of glom frames (superframes) */ - uint rxglompkts; /* Number of packets from glom frames */ - uint f2rxhdrs; /* Number of header reads */ - uint f2rxdata; /* Number of frame data reads */ - uint f2txdata; /* Number of f2 frame writes */ - uint f1regdata; /* Number of f1 register accesses */ - - uint8 *ctrl_frame_buf; - uint32 ctrl_frame_len; - bool ctrl_frame_stat; -} dhd_bus_t; - -/* clkstate */ -#define CLK_NONE 0 -#define CLK_SDONLY 1 -#define CLK_PENDING 2 /* Not used yet */ -#define CLK_AVAIL 3 - -#define DHD_NOPMU(dhd) (FALSE) - -#ifdef DHD_DEBUG -static int qcount[NUMPRIO]; -static int tx_packets[NUMPRIO]; -#endif /* DHD_DEBUG */ - -/* Deferred transmit */ -const uint dhd_deferred_tx = 1; - -extern uint dhd_watchdog_ms; -extern void dhd_os_wd_timer(void *bus, uint wdtick); - -/* Tx/Rx bounds */ -uint dhd_txbound; -uint dhd_rxbound; -uint dhd_txminmax; - -/* override the RAM size if possible */ -#define DONGLE_MIN_MEMSIZE (128 *1024) -int dhd_dongle_memsize; - -static bool dhd_doflow; -static bool dhd_alignctl; - -static bool sd1idle; - -static bool retrydata; -#define RETRYCHAN(chan) (((chan) == SDPCM_EVENT_CHANNEL) || retrydata) - -static const uint watermark = 8; -static const uint firstread = DHD_FIRSTREAD; - -#define HDATLEN (firstread - (SDPCM_HDRLEN)) - -/* Retry count for register access failures */ -static const uint retry_limit = 2; - -/* Force even SD lengths (some host controllers mess up on odd bytes) */ -static bool forcealign; - -#define ALIGNMENT 4 - -#if defined(OOB_INTR_ONLY) && defined(HW_OOB) -extern void bcmsdh_enable_hw_oob_intr(void *sdh, bool enable); -#endif - -#if defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD) -#error OOB_INTR_ONLY is NOT working with SDIO_ISR_THREAD -#endif /* defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD) */ -#define PKTALIGN(osh, p, len, align) \ - do { \ - uint datalign; \ - datalign = (uintptr)PKTDATA((osh), (p)); \ - datalign = ROUNDUP(datalign, (align)) - datalign; \ - ASSERT(datalign < (align)); \ - ASSERT(PKTLEN((osh), (p)) >= ((len) + datalign)); \ - if (datalign) \ - PKTPULL((osh), (p), datalign); \ - PKTSETLEN((osh), (p), (len)); \ - } while (0) - -/* Limit on rounding up frames */ -static const uint max_roundup = 512; - -/* Try doing readahead */ -static bool dhd_readahead; - - -/* To check if there's window offered */ -#define DATAOK(bus) \ - (((uint8)(bus->tx_max - bus->tx_seq) != 0) && \ - (((uint8)(bus->tx_max - bus->tx_seq) & 0x80) == 0)) - -/* Macros to get register read/write status */ -/* NOTE: these assume a local dhdsdio_bus_t *bus! */ -#define R_SDREG(regvar, regaddr, retryvar) \ -do { \ - retryvar = 0; \ - do { \ - regvar = R_REG(bus->dhd->osh, regaddr); \ - } while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \ - if (retryvar) { \ - bus->regfails += (retryvar-1); \ - if (retryvar > retry_limit) { \ - DHD_ERROR(("%s: FAILED" #regvar "READ, LINE %d\n", \ - __FUNCTION__, __LINE__)); \ - regvar = 0; \ - } \ - } \ -} while (0) - -#define W_SDREG(regval, regaddr, retryvar) \ -do { \ - retryvar = 0; \ - do { \ - W_REG(bus->dhd->osh, regaddr, regval); \ - } while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \ - if (retryvar) { \ - bus->regfails += (retryvar-1); \ - if (retryvar > retry_limit) \ - DHD_ERROR(("%s: FAILED REGISTER WRITE, LINE %d\n", \ - __FUNCTION__, __LINE__)); \ - } \ -} while (0) - - -#define DHD_BUS SDIO_BUS - -#define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND) - -#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE) - -#define GSPI_PR55150_BAILOUT - - -#ifdef SDTEST -static void dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq); -static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start); -#endif - -#ifdef DHD_DEBUG_TRAP -static int dhdsdio_checkdied(dhd_bus_t *bus, uint8 *data, uint size); -#endif /* DHD_DEBUG_TRAP */ -static int dhdsdio_download_state(dhd_bus_t *bus, bool enter); - -static void dhdsdio_release(dhd_bus_t *bus, osl_t *osh); -static void dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh); -static void dhdsdio_disconnect(void *ptr); -static bool dhdsdio_chipmatch(uint16 chipid); -static bool dhdsdio_probe_attach(dhd_bus_t *bus, osl_t *osh, void *sdh, - void * regsva, uint16 devid); -static bool dhdsdio_probe_malloc(dhd_bus_t *bus, osl_t *osh, void *sdh); -static bool dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh); -static void dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh, int reset_flag); - -static uint process_nvram_vars(char *varbuf, uint len); - -static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size); -static int dhd_bcmsdh_recv_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, - uint8 *buf, uint nbytes, - void *pkt, bcmsdh_cmplt_fn_t complete, void *handle); -static int dhd_bcmsdh_send_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, - uint8 *buf, uint nbytes, - void *pkt, bcmsdh_cmplt_fn_t complete, void *handle); - -static bool dhdsdio_download_firmware(struct dhd_bus *bus, osl_t *osh, void *sdh); -static int _dhdsdio_download_firmware(struct dhd_bus *bus); - -static int dhdsdio_download_code_file(struct dhd_bus *bus, char *image_path); -static int dhdsdio_download_nvram(struct dhd_bus *bus); -#ifdef BCMEMBEDIMAGE -static int dhdsdio_download_code_array(struct dhd_bus *bus); -#endif - - -static void -dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size) -{ - int32 min_size = DONGLE_MIN_MEMSIZE; - /* Restrict the memsize to user specified limit */ - DHD_ERROR(("user: Restrict the dongle ram size to %d, min accepted %d\n", - dhd_dongle_memsize, min_size)); - if ((dhd_dongle_memsize > min_size) && - (dhd_dongle_memsize < (int32)bus->orig_ramsize)) - bus->ramsize = dhd_dongle_memsize; -} - -static int -dhdsdio_set_siaddr_window(dhd_bus_t *bus, uint32 address) -{ - int err = 0; - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, - (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); - if (!err) - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, - (address >> 16) & SBSDIO_SBADDRMID_MASK, &err); - if (!err) - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, - (address >> 24) & SBSDIO_SBADDRHIGH_MASK, &err); - return err; -} - - -/* Turn backplane clock on or off */ -static int -dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) -{ - int err; - uint8 clkctl, clkreq, devctl; - bcmsdh_info_t *sdh; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - -#if defined(OOB_INTR_ONLY) - pendok = FALSE; -#endif - clkctl = 0; - sdh = bus->sdh; - - - if (on) { - /* Request HT Avail */ - clkreq = bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ; - - if ((bus->sih->chip == BCM4329_CHIP_ID) && (bus->sih->chiprev == 0)) - clkreq |= SBSDIO_FORCE_ALP; - - - - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); - if (err) { - DHD_ERROR(("%s: HT Avail request error: %d\n", __FUNCTION__, err)); - return BCME_ERROR; - } - - if (pendok && - ((bus->sih->buscoretype == PCMCIA_CORE_ID) && (bus->sih->buscorerev == 9))) { - uint32 dummy, retries; - R_SDREG(dummy, &bus->regs->clockctlstatus, retries); - } - - /* Check current status */ - clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); - if (err) { - DHD_ERROR(("%s: HT Avail read error: %d\n", __FUNCTION__, err)); - return BCME_ERROR; - } - - /* Go to pending and await interrupt if appropriate */ - if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) { - /* Allow only clock-available interrupt */ - devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); - if (err) { - DHD_ERROR(("%s: Devctl access error setting CA: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - - devctl |= SBSDIO_DEVCTL_CA_INT_ONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); - DHD_INFO(("CLKCTL: set PENDING\n")); - bus->clkstate = CLK_PENDING; - return BCME_OK; - } else if (bus->clkstate == CLK_PENDING) { - /* Cancel CA-only interrupt filter */ - devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); - devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); - } - - /* Otherwise, wait here (polling) for HT Avail */ - if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { - SPINWAIT_SLEEP(sdioh_spinwait_sleep, - ((clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_CHIPCLKCSR, &err)), - !SBSDIO_CLKAV(clkctl, bus->alp_only)), PMU_MAX_TRANSITION_DLY); - } - if (err) { - DHD_ERROR(("%s: HT Avail request error: %d\n", __FUNCTION__, err)); - return BCME_ERROR; - } - if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { - DHD_ERROR(("%s: HT Avail timeout (%d): clkctl 0x%02x\n", - __FUNCTION__, PMU_MAX_TRANSITION_DLY, clkctl)); - return BCME_ERROR; - } - - - /* Mark clock available */ - bus->clkstate = CLK_AVAIL; - DHD_INFO(("CLKCTL: turned ON\n")); - -#if defined(DHD_DEBUG) - if (bus->alp_only == TRUE) { -#if !defined(BCMLXSDMMC) - if (!SBSDIO_ALPONLY(clkctl)) { - DHD_ERROR(("%s: HT Clock, when ALP Only\n", __FUNCTION__)); - } -#endif /* !defined(BCMLXSDMMC) */ - } else { - if (SBSDIO_ALPONLY(clkctl)) { - DHD_ERROR(("%s: HT Clock should be on.\n", __FUNCTION__)); - } - } -#endif /* defined (DHD_DEBUG) */ - - bus->activity = TRUE; - } else { - clkreq = 0; - - if (bus->clkstate == CLK_PENDING) { - /* Cancel CA-only interrupt filter */ - devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); - devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); - } - - bus->clkstate = CLK_SDONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); - DHD_INFO(("CLKCTL: turned OFF\n")); - if (err) { - DHD_ERROR(("%s: Failed access turning clock off: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - } - return BCME_OK; -} - -/* Change idle/active SD state */ -static int -dhdsdio_sdclk(dhd_bus_t *bus, bool on) -{ - int err; - int32 iovalue; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (on) { - if (bus->idleclock == DHD_IDLE_STOP) { - /* Turn on clock and restore mode */ - iovalue = 1; - err = bcmsdh_iovar_op(bus->sdh, "sd_clock", NULL, 0, - &iovalue, sizeof(iovalue), TRUE); - if (err) { - DHD_ERROR(("%s: error enabling sd_clock: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - - iovalue = bus->sd_mode; - err = bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0, - &iovalue, sizeof(iovalue), TRUE); - if (err) { - DHD_ERROR(("%s: error changing sd_mode: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - } else if (bus->idleclock != DHD_IDLE_ACTIVE) { - /* Restore clock speed */ - iovalue = bus->sd_divisor; - err = bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0, - &iovalue, sizeof(iovalue), TRUE); - if (err) { - DHD_ERROR(("%s: error restoring sd_divisor: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - } - bus->clkstate = CLK_SDONLY; - } else { - /* Stop or slow the SD clock itself */ - if ((bus->sd_divisor == -1) || (bus->sd_mode == -1)) { - DHD_TRACE(("%s: can't idle clock, divisor %d mode %d\n", - __FUNCTION__, bus->sd_divisor, bus->sd_mode)); - return BCME_ERROR; - } - if (bus->idleclock == DHD_IDLE_STOP) { - if (sd1idle) { - /* Change to SD1 mode and turn off clock */ - iovalue = 1; - err = bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0, - &iovalue, sizeof(iovalue), TRUE); - if (err) { - DHD_ERROR(("%s: error changing sd_clock: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - } - - iovalue = 0; - err = bcmsdh_iovar_op(bus->sdh, "sd_clock", NULL, 0, - &iovalue, sizeof(iovalue), TRUE); - if (err) { - DHD_ERROR(("%s: error disabling sd_clock: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - } else if (bus->idleclock != DHD_IDLE_ACTIVE) { - /* Set divisor to idle value */ - iovalue = bus->idleclock; - err = bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0, - &iovalue, sizeof(iovalue), TRUE); - if (err) { - DHD_ERROR(("%s: error changing sd_divisor: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - } - bus->clkstate = CLK_NONE; - } - - return BCME_OK; -} - -/* Transition SD and backplane clock readiness */ -static int -dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok) -{ - int ret = BCME_OK; -#ifdef DHD_DEBUG - uint oldstate = bus->clkstate; -#endif /* DHD_DEBUG */ - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* Early exit if we're already there */ - if (bus->clkstate == target) { - if (target == CLK_AVAIL) { - dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); - bus->activity = TRUE; - } - return ret; - } - - switch (target) { - case CLK_AVAIL: - /* Make sure SD clock is available */ - if (bus->clkstate == CLK_NONE) - dhdsdio_sdclk(bus, TRUE); - /* Now request HT Avail on the backplane */ - ret = dhdsdio_htclk(bus, TRUE, pendok); - if (ret == BCME_OK) { - dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); - bus->activity = TRUE; - } - break; - - case CLK_SDONLY: - /* Remove HT request, or bring up SD clock */ - if (bus->clkstate == CLK_NONE) - ret = dhdsdio_sdclk(bus, TRUE); - else if (bus->clkstate == CLK_AVAIL) - ret = dhdsdio_htclk(bus, FALSE, FALSE); - else - DHD_ERROR(("dhdsdio_clkctl: request for %d -> %d\n", - bus->clkstate, target)); - if (ret == BCME_OK) - dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); - break; - - case CLK_NONE: - /* Make sure to remove HT request */ - if (bus->clkstate == CLK_AVAIL) - ret = dhdsdio_htclk(bus, FALSE, FALSE); - /* Now remove the SD clock */ - ret = dhdsdio_sdclk(bus, FALSE); - dhd_os_wd_timer(bus->dhd, 0); - break; - } -#ifdef DHD_DEBUG - DHD_INFO(("dhdsdio_clkctl: %d -> %d\n", oldstate, bus->clkstate)); -#endif /* DHD_DEBUG */ - - return ret; -} - -int -dhdsdio_bussleep(dhd_bus_t *bus, bool sleep) -{ - bcmsdh_info_t *sdh = bus->sdh; - sdpcmd_regs_t *regs = bus->regs; - uint retries = 0; - - DHD_INFO(("dhdsdio_bussleep: request %s (currently %s)\n", - (sleep ? "SLEEP" : "WAKE"), - (bus->sleeping ? "SLEEP" : "WAKE"))); - - /* Done if we're already in the requested state */ - if (sleep == bus->sleeping) - return BCME_OK; - - /* Going to sleep: set the alarm and turn off the lights... */ - if (sleep) { - /* Don't sleep if something is pending */ - if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq)) - return BCME_BUSY; - - - /* Disable SDIO interrupts (no longer interested) */ - bcmsdh_intr_disable(bus->sdh); - - /* Make sure the controller has the bus up */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - /* Tell device to start using OOB wakeup */ - W_SDREG(SMB_USE_OOB, ®s->tosbmailbox, retries); - if (retries > retry_limit) - DHD_ERROR(("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n")); - - /* Turn off our contribution to the HT clock request */ - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - SBSDIO_FORCE_HW_CLKREQ_OFF, NULL); - - /* Isolate the bus */ - if (bus->sih->chip != BCM4329_CHIP_ID && bus->sih->chip != BCM4319_CHIP_ID) { - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, - SBSDIO_DEVCTL_PADS_ISO, NULL); - } - - /* Change state */ - bus->sleeping = TRUE; - - } else { - /* Waking up: bus power up is ok, set local state */ - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - 0, NULL); - - /* Force pad isolation off if possible (in case power never toggled) */ - if ((bus->sih->buscoretype == PCMCIA_CORE_ID) && (bus->sih->buscorerev >= 10)) - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, 0, NULL); - - - /* Make sure the controller has the bus up */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - /* Send misc interrupt to indicate OOB not needed */ - W_SDREG(0, ®s->tosbmailboxdata, retries); - if (retries <= retry_limit) - W_SDREG(SMB_DEV_INT, ®s->tosbmailbox, retries); - - if (retries > retry_limit) - DHD_ERROR(("CANNOT SIGNAL CHIP TO CLEAR OOB!!\n")); - - /* Make sure we have SD bus access */ - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); - - /* Change state */ - bus->sleeping = FALSE; - - /* Enable interrupts again */ - if (bus->intr && (bus->dhd->busstate == DHD_BUS_DATA)) { - bus->intdis = FALSE; - bcmsdh_intr_enable(bus->sdh); - } - } - - return BCME_OK; -} -#if defined(OOB_INTR_ONLY) -void -dhd_enable_oob_intr(struct dhd_bus *bus, bool enable) -{ -#if defined(HW_OOB) - bcmsdh_enable_hw_oob_intr(bus->sdh, enable); -#else - sdpcmd_regs_t *regs = bus->regs; - uint retries = 0; - - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - if (enable == TRUE) { - - /* Tell device to start using OOB wakeup */ - W_SDREG(SMB_USE_OOB, ®s->tosbmailbox, retries); - if (retries > retry_limit) - DHD_ERROR(("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n")); - - } else { - /* Send misc interrupt to indicate OOB not needed */ - W_SDREG(0, ®s->tosbmailboxdata, retries); - if (retries <= retry_limit) - W_SDREG(SMB_DEV_INT, ®s->tosbmailbox, retries); - } - - /* Turn off our contribution to the HT clock request */ - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); -#endif /* !defined(HW_OOB) */ -} -#endif /* defined(OOB_INTR_ONLY) */ - -#define BUS_WAKE(bus) \ - do { \ - if ((bus)->sleeping) \ - dhdsdio_bussleep((bus), FALSE); \ - } while (0); - - -/* Writes a HW/SW header into the packet and sends it. */ -/* Assumes: (a) header space already there, (b) caller holds lock */ -static int -dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, uint chan, bool free_pkt) -{ - int ret; - osl_t *osh; - uint8 *frame; - uint16 len, pad = 0; - uint32 swheader; - uint retries = 0; - bcmsdh_info_t *sdh; - void *new; - int i; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - sdh = bus->sdh; - osh = bus->dhd->osh; - - if (bus->dhd->dongle_reset) { - ret = BCME_NOTREADY; - goto done; - } - - frame = (uint8*)PKTDATA(osh, pkt); - - /* Add alignment padding, allocate new packet if needed */ - if ((pad = ((uintptr)frame % DHD_SDALIGN))) { - if (PKTHEADROOM(osh, pkt) < pad) { - DHD_INFO(("%s: insufficient headroom %d for %d pad\n", - __FUNCTION__, (int)PKTHEADROOM(osh, pkt), pad)); - bus->dhd->tx_realloc++; - new = PKTGET(osh, (PKTLEN(osh, pkt) + DHD_SDALIGN), TRUE); - if (!new) { - DHD_ERROR(("%s: couldn't allocate new %d-byte packet\n", - __FUNCTION__, PKTLEN(osh, pkt) + DHD_SDALIGN)); - ret = BCME_NOMEM; - goto done; - } - - PKTALIGN(osh, new, PKTLEN(osh, pkt), DHD_SDALIGN); - bcopy(PKTDATA(osh, pkt), PKTDATA(osh, new), PKTLEN(osh, pkt)); - if (free_pkt) - PKTFREE(osh, pkt, TRUE); - /* free the pkt if canned one is not used */ - free_pkt = TRUE; - pkt = new; - frame = (uint8*)PKTDATA(osh, pkt); - ASSERT(((uintptr)frame % DHD_SDALIGN) == 0); - pad = 0; - } else { - PKTPUSH(osh, pkt, pad); - frame = (uint8*)PKTDATA(osh, pkt); - - ASSERT((pad + SDPCM_HDRLEN) <= (int) PKTLEN(osh, pkt)); - bzero(frame, pad + SDPCM_HDRLEN); - } - } - ASSERT(pad < DHD_SDALIGN); - - /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ - len = (uint16)PKTLEN(osh, pkt); - *(uint16*)frame = htol16(len); - *(((uint16*)frame) + 1) = htol16(~len); - - /* Software tag: channel, sequence number, data offset */ - swheader = ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | bus->tx_seq | - (((pad + SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK); - htol32_ua_store(swheader, frame + SDPCM_FRAMETAG_LEN); - htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); - -#ifdef DHD_DEBUG - tx_packets[PKTPRIO(pkt)]++; - if (DHD_BYTES_ON() && - (((DHD_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) || - (DHD_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) { - prhex("Tx Frame", frame, len); - } else if (DHD_HDRS_ON()) { - prhex("TxHdr", frame, MIN(len, 16)); - } -#endif - - /* Raise len to next SDIO block to eliminate tail command */ - if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { - uint16 pad = bus->blocksize - (len % bus->blocksize); - if ((pad <= bus->roundup) && (pad < bus->blocksize)) -#ifdef NOTUSED - if (pad <= PKTTAILROOM(osh, pkt)) -#endif /* NOTUSED */ - len += pad; - } else if (len % DHD_SDALIGN) { - len += DHD_SDALIGN - (len % DHD_SDALIGN); - } - - /* Some controllers have trouble with odd bytes -- round to even */ - if (forcealign && (len & (ALIGNMENT - 1))) { -#ifdef NOTUSED - if (PKTTAILROOM(osh, pkt)) -#endif - len = ROUNDUP(len, ALIGNMENT); -#ifdef NOTUSED - else - DHD_ERROR(("%s: sending unrounded %d-byte packet\n", __FUNCTION__, len)); -#endif - } - - do { - ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - frame, len, pkt, NULL, NULL); - bus->f2txdata++; - ASSERT(ret != BCME_PENDING); - - if (ret < 0) { - /* On failure, abort the command and terminate the frame */ - DHD_INFO(("%s: sdio error %d, abort command and terminate frame.\n", - __FUNCTION__, ret)); - bus->tx_sderrs++; - - bcmsdh_abort(sdh, SDIO_FUNC_2); - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, - SFC_WF_TERM, NULL); - bus->f1regdata++; - - for (i = 0; i < 3; i++) { - uint8 hi, lo; - hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCLO, NULL); - bus->f1regdata += 2; - if ((hi == 0) && (lo == 0)) - break; - } - - } - if (ret == 0) { - bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; - } - } while ((ret < 0) && retrydata && retries++ < TXRETRIES); - -done: - /* restore pkt buffer pointer before calling tx complete routine */ - PKTPULL(osh, pkt, SDPCM_HDRLEN + pad); - dhd_os_sdunlock(bus->dhd); - dhd_txcomplete(bus->dhd, pkt, ret != 0); - dhd_os_sdlock(bus->dhd); - - if (free_pkt) - PKTFREE(osh, pkt, TRUE); - - return ret; -} - -int -dhd_bus_txdata(struct dhd_bus *bus, void *pkt) -{ - int ret = BCME_ERROR; - osl_t *osh; - uint datalen, prec; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - osh = bus->dhd->osh; - datalen = PKTLEN(osh, pkt); - -#ifdef SDTEST - /* Push the test header if doing loopback */ - if (bus->ext_loop) { - uint8* data; - PKTPUSH(osh, pkt, SDPCM_TEST_HDRLEN); - data = PKTDATA(osh, pkt); - *data++ = SDPCM_TEST_ECHOREQ; - *data++ = (uint8)bus->loopid++; - *data++ = (datalen >> 0); - *data++ = (datalen >> 8); - datalen += SDPCM_TEST_HDRLEN; - } -#endif /* SDTEST */ - - /* Add space for the header */ - PKTPUSH(osh, pkt, SDPCM_HDRLEN); - ASSERT(ISALIGNED((uintptr)PKTDATA(osh, pkt), 2)); - - prec = PRIO2PREC((PKTPRIO(pkt) & PRIOMASK)); - - - /* Check for existing queue, current flow-control, pending event, or pending clock */ - if (dhd_deferred_tx || bus->fcstate || pktq_len(&bus->txq) || bus->dpc_sched || - (!DATAOK(bus)) || (bus->flowcontrol & NBITVAL(prec)) || - (bus->clkstate != CLK_AVAIL)) { - DHD_TRACE(("%s: deferring pktq len %d\n", __FUNCTION__, - pktq_len(&bus->txq))); - bus->fcqueued++; - - /* Priority based enq */ - dhd_os_sdlock_txq(bus->dhd); - if (dhd_prec_enq(bus->dhd, &bus->txq, pkt, prec) == FALSE) { - PKTPULL(osh, pkt, SDPCM_HDRLEN); - dhd_txcomplete(bus->dhd, pkt, FALSE); - PKTFREE(osh, pkt, TRUE); - DHD_ERROR(("%s: out of bus->txq !!!\n", __FUNCTION__)); - ret = BCME_NORESOURCE; - } else { - ret = BCME_OK; - } - dhd_os_sdunlock_txq(bus->dhd); - - if ((pktq_len(&bus->txq) >= FCHI) && dhd_doflow) - dhd_txflowcontrol(bus->dhd, 0, ON); - -#ifdef DHD_DEBUG - if (pktq_plen(&bus->txq, prec) > qcount[prec]) - qcount[prec] = pktq_plen(&bus->txq, prec); -#endif - /* Schedule DPC if needed to send queued packet(s) */ - if (dhd_deferred_tx && !bus->dpc_sched) { - bus->dpc_sched = TRUE; - dhd_sched_dpc(bus->dhd); - } - } else { - /* Lock: we're about to use shared data/code (and SDIO) */ - dhd_os_sdlock(bus->dhd); - - /* Otherwise, send it now */ - BUS_WAKE(bus); - /* Make sure back plane ht clk is on, no pending allowed */ - dhdsdio_clkctl(bus, CLK_AVAIL, TRUE); - -#ifndef SDTEST - DHD_TRACE(("%s: calling txpkt\n", __FUNCTION__)); - ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, TRUE); -#else - ret = dhdsdio_txpkt(bus, pkt, - (bus->ext_loop ? SDPCM_TEST_CHANNEL : SDPCM_DATA_CHANNEL), TRUE); -#endif - if (ret) - bus->dhd->tx_errors++; - else - bus->dhd->dstats.tx_bytes += datalen; - - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, TRUE); - } - - dhd_os_sdunlock(bus->dhd); - } - - - return ret; -} - -static uint -dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes) -{ - void *pkt; - uint32 intstatus = 0; - uint retries = 0; - int ret = 0, prec_out; - uint cnt = 0; - uint datalen; - uint8 tx_prec_map; - - dhd_pub_t *dhd = bus->dhd; - sdpcmd_regs_t *regs = bus->regs; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - tx_prec_map = ~bus->flowcontrol; - - /* Send frames until the limit or some other event */ - for (cnt = 0; (cnt < maxframes) && DATAOK(bus); cnt++) { - dhd_os_sdlock_txq(bus->dhd); - if ((pkt = pktq_mdeq(&bus->txq, tx_prec_map, &prec_out)) == NULL) { - dhd_os_sdunlock_txq(bus->dhd); - break; - } - dhd_os_sdunlock_txq(bus->dhd); - datalen = PKTLEN(bus->dhd->osh, pkt) - SDPCM_HDRLEN; - -#ifndef SDTEST - ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, TRUE); -#else - ret = dhdsdio_txpkt(bus, pkt, - (bus->ext_loop ? SDPCM_TEST_CHANNEL : SDPCM_DATA_CHANNEL), TRUE); -#endif - if (ret) - bus->dhd->tx_errors++; - else - bus->dhd->dstats.tx_bytes += datalen; - - /* In poll mode, need to check for other events */ - if (!bus->intr && cnt) - { - /* Check device status, signal pending interrupt */ - R_SDREG(intstatus, ®s->intstatus, retries); - bus->f2txdata++; - if (bcmsdh_regfail(bus->sdh)) - break; - if (intstatus & bus->hostintmask) - bus->ipend = TRUE; - } - } - - /* Deflow-control stack if needed */ - if (dhd_doflow && dhd->up && (dhd->busstate == DHD_BUS_DATA) && - dhd->txoff && (pktq_len(&bus->txq) < FCLOW)) - dhd_txflowcontrol(dhd, 0, OFF); - - return cnt; -} - -int -dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen) -{ - uint8 *frame; - uint16 len; - uint32 swheader; - uint retries = 0; - bcmsdh_info_t *sdh = bus->sdh; - uint8 doff = 0; - int ret = -1; - int i; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (bus->dhd->dongle_reset) - return -EIO; - - /* Back the pointer to make a room for bus header */ - frame = msg - SDPCM_HDRLEN; - len = (msglen += SDPCM_HDRLEN); - - /* Add alignment padding (optional for ctl frames) */ - if (dhd_alignctl) { - if ((doff = ((uintptr)frame % DHD_SDALIGN))) { - frame -= doff; - len += doff; - msglen += doff; - bzero(frame, doff + SDPCM_HDRLEN); - } - ASSERT(doff < DHD_SDALIGN); - } - doff += SDPCM_HDRLEN; - - /* Round send length to next SDIO block */ - if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { - uint16 pad = bus->blocksize - (len % bus->blocksize); - if ((pad <= bus->roundup) && (pad < bus->blocksize)) - len += pad; - } else if (len % DHD_SDALIGN) { - len += DHD_SDALIGN - (len % DHD_SDALIGN); - } - - /* Satisfy length-alignment requirements */ - if (forcealign && (len & (ALIGNMENT - 1))) - len = ROUNDUP(len, ALIGNMENT); - - ASSERT(ISALIGNED((uintptr)frame, 2)); - - - /* Need to lock here to protect txseq and SDIO tx calls */ - dhd_os_sdlock(bus->dhd); - - BUS_WAKE(bus); - - /* Make sure backplane clock is on */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ - *(uint16*)frame = htol16((uint16)msglen); - *(((uint16*)frame) + 1) = htol16(~msglen); - - /* Software tag: channel, sequence number, data offset */ - swheader = ((SDPCM_CONTROL_CHANNEL << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) - | bus->tx_seq | ((doff << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK); - htol32_ua_store(swheader, frame + SDPCM_FRAMETAG_LEN); - htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); - - if (!DATAOK(bus)) { - DHD_INFO(("%s: No bus credit bus->tx_max %d, bus->tx_seq %d\n", - __FUNCTION__, bus->tx_max, bus->tx_seq)); - bus->ctrl_frame_stat = TRUE; - /* Send from dpc */ - bus->ctrl_frame_buf = frame; - bus->ctrl_frame_len = len; - - dhd_wait_for_event(bus->dhd, &bus->ctrl_frame_stat); - - if (bus->ctrl_frame_stat == FALSE) { - DHD_INFO(("%s: ctrl_frame_stat == FALSE\n", __FUNCTION__)); - ret = 0; - } else { - if (!bus->dhd->hang_was_sent) - DHD_ERROR(("%s: ctrl_frame_stat == TRUE\n", __FUNCTION__)); - ret = -1; - } - } - - if (ret == -1) { -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_CTL_ON()) { - prhex("Tx Frame", frame, len); - } else if (DHD_HDRS_ON()) { - prhex("TxHdr", frame, MIN(len, 16)); - } -#endif - - do { - bus->ctrl_frame_stat = FALSE; - ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - frame, len, NULL, NULL, NULL); - ASSERT(ret != BCME_PENDING); - - if (ret < 0) { - /* On failure, abort the command and terminate the frame */ - DHD_INFO(("%s: sdio error %d, abort command and terminate frame.\n", - __FUNCTION__, ret)); - bus->tx_sderrs++; - - bcmsdh_abort(sdh, SDIO_FUNC_2); - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, - SFC_WF_TERM, NULL); - bus->f1regdata++; - - for (i = 0; i < 3; i++) { - uint8 hi, lo; - hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCLO, NULL); - bus->f1regdata += 2; - if ((hi == 0) && (lo == 0)) - break; - } - - } - if (ret == 0) { - bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; - } - } while ((ret < 0) && retries++ < TXRETRIES); - } - - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, TRUE); - } - - dhd_os_sdunlock(bus->dhd); - - if (ret) - bus->dhd->tx_ctlerrs++; - else - bus->dhd->tx_ctlpkts++; - - return ret ? -EIO : 0; -} - -int -dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen) -{ - int timeleft; - uint rxlen = 0; - bool pending; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (bus->dhd->dongle_reset) - return -EIO; - - /* Wait until control frame is available */ - timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->rxlen, &pending); - - dhd_os_sdlock(bus->dhd); - rxlen = bus->rxlen; - bcopy(bus->rxctl, msg, MIN(msglen, rxlen)); - bus->rxlen = 0; - dhd_os_sdunlock(bus->dhd); - - if (rxlen) { - DHD_CTL(("%s: resumed on rxctl frame, got %d expected %d\n", - __FUNCTION__, rxlen, msglen)); - } else if (timeleft == 0) { - DHD_ERROR(("%s: resumed on timeout\n", __FUNCTION__)); -#ifdef DHD_DEBUG_TRAP - dhd_os_sdlock(bus->dhd); - dhdsdio_checkdied(bus, NULL, 0); - dhd_os_sdunlock(bus->dhd); -#endif /* DHD_DEBUG_TRAP */ - } else if (pending == TRUE) { - DHD_CTL(("%s: cancelled\n", __FUNCTION__)); - return -ERESTARTSYS; - } else { - DHD_CTL(("%s: resumed for unknown reason?\n", __FUNCTION__)); -#ifdef DHD_DEBUG_TRAP - dhd_os_sdlock(bus->dhd); - dhdsdio_checkdied(bus, NULL, 0); - dhd_os_sdunlock(bus->dhd); -#endif /* DHD_DEBUG_TRAP */ - } - - if (rxlen) - bus->dhd->rx_ctlpkts++; - else - bus->dhd->rx_ctlerrs++; - - return rxlen ? (int)rxlen : -ETIMEDOUT; -} - -/* IOVar table */ -enum { - IOV_INTR = 1, - IOV_POLLRATE, - IOV_SDREG, - IOV_SBREG, - IOV_SDCIS, - IOV_MEMBYTES, - IOV_MEMSIZE, -#ifdef DHD_DEBUG_TRAP - IOV_CHECKDIED, -#endif - IOV_DOWNLOAD, - IOV_FORCEEVEN, - IOV_SDIOD_DRIVE, - IOV_READAHEAD, - IOV_SDRXCHAIN, - IOV_ALIGNCTL, - IOV_SDALIGN, - IOV_DEVRESET, - IOV_CPU, -#ifdef SDTEST - IOV_PKTGEN, - IOV_EXTLOOP, -#endif /* SDTEST */ - IOV_SPROM, - IOV_TXBOUND, - IOV_RXBOUND, - IOV_TXMINMAX, - IOV_IDLETIME, - IOV_IDLECLOCK, - IOV_SD1IDLE, - IOV_SLEEP, - IOV_VARS -}; - -const bcm_iovar_t dhdsdio_iovars[] = { - {"intr", IOV_INTR, 0, IOVT_BOOL, 0 }, - {"sleep", IOV_SLEEP, 0, IOVT_BOOL, 0 }, - {"pollrate", IOV_POLLRATE, 0, IOVT_UINT32, 0 }, - {"idletime", IOV_IDLETIME, 0, IOVT_INT32, 0 }, - {"idleclock", IOV_IDLECLOCK, 0, IOVT_INT32, 0 }, - {"sd1idle", IOV_SD1IDLE, 0, IOVT_BOOL, 0 }, - {"membytes", IOV_MEMBYTES, 0, IOVT_BUFFER, 2 * sizeof(int) }, - {"memsize", IOV_MEMSIZE, 0, IOVT_UINT32, 0 }, - {"download", IOV_DOWNLOAD, 0, IOVT_BOOL, 0 }, - {"vars", IOV_VARS, 0, IOVT_BUFFER, 0 }, - {"sdiod_drive", IOV_SDIOD_DRIVE, 0, IOVT_UINT32, 0 }, - {"readahead", IOV_READAHEAD, 0, IOVT_BOOL, 0 }, - {"sdrxchain", IOV_SDRXCHAIN, 0, IOVT_BOOL, 0 }, - {"alignctl", IOV_ALIGNCTL, 0, IOVT_BOOL, 0 }, - {"sdalign", IOV_SDALIGN, 0, IOVT_BOOL, 0 }, - {"devreset", IOV_DEVRESET, 0, IOVT_BOOL, 0 }, -#ifdef DHD_DEBUG - {"sdreg", IOV_SDREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sbreg", IOV_SBREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_cis", IOV_SDCIS, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN }, - {"forcealign", IOV_FORCEEVEN, 0, IOVT_BOOL, 0 }, - {"txbound", IOV_TXBOUND, 0, IOVT_UINT32, 0 }, - {"rxbound", IOV_RXBOUND, 0, IOVT_UINT32, 0 }, - {"txminmax", IOV_TXMINMAX, 0, IOVT_UINT32, 0 }, - {"cpu", IOV_CPU, 0, IOVT_BOOL, 0 }, -#endif /* DHD_DEBUG */ -#ifdef DHD_DEBUG_TRAP - {"checkdied", IOV_CHECKDIED, 0, IOVT_BUFFER, 0 }, -#endif /* DHD_DEBUG_TRAP */ -#ifdef SDTEST - {"extloop", IOV_EXTLOOP, 0, IOVT_BOOL, 0 }, - {"pktgen", IOV_PKTGEN, 0, IOVT_BUFFER, sizeof(dhd_pktgen_t) }, -#endif /* SDTEST */ - - {NULL, 0, 0, 0, 0 } -}; - -static void -dhd_dump_pct(struct bcmstrbuf *strbuf, char *desc, uint num, uint div) -{ - uint q1, q2; - - if (!div) { - bcm_bprintf(strbuf, "%s N/A", desc); - } else { - q1 = num / div; - q2 = (100 * (num - (q1 * div))) / div; - bcm_bprintf(strbuf, "%s %d.%02d", desc, q1, q2); - } -} - -void -dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) -{ - dhd_bus_t *bus = dhdp->bus; - - bcm_bprintf(strbuf, "Bus SDIO structure:\n"); - bcm_bprintf(strbuf, "hostintmask 0x%08x intstatus 0x%08x sdpcm_ver %d\n", - bus->hostintmask, bus->intstatus, bus->sdpcm_ver); - bcm_bprintf(strbuf, "fcstate %d qlen %d tx_seq %d, max %d, rxskip %d rxlen %d rx_seq %d\n", - bus->fcstate, pktq_len(&bus->txq), bus->tx_seq, bus->tx_max, bus->rxskip, - bus->rxlen, bus->rx_seq); - bcm_bprintf(strbuf, "intr %d intrcount %d lastintrs %d spurious %d\n", - bus->intr, bus->intrcount, bus->lastintrs, bus->spurious); - bcm_bprintf(strbuf, "pollrate %d pollcnt %d regfails %d\n", - bus->pollrate, bus->pollcnt, bus->regfails); - - bcm_bprintf(strbuf, "\nAdditional counters:\n"); - bcm_bprintf(strbuf, "tx_sderrs %d fcqueued %d rxrtx %d rx_toolong %d rxc_errors %d\n", - bus->tx_sderrs, bus->fcqueued, bus->rxrtx, bus->rx_toolong, - bus->rxc_errors); - bcm_bprintf(strbuf, "rx_hdrfail %d badhdr %d badseq %d\n", - bus->rx_hdrfail, bus->rx_badhdr, bus->rx_badseq); - bcm_bprintf(strbuf, "fc_rcvd %d, fc_xoff %d, fc_xon %d\n", - bus->fc_rcvd, bus->fc_xoff, bus->fc_xon); - bcm_bprintf(strbuf, "rxglomfail %d, rxglomframes %d, rxglompkts %d\n", - bus->rxglomfail, bus->rxglomframes, bus->rxglompkts); - bcm_bprintf(strbuf, "f2rx (hdrs/data) %d (%d/%d), f2tx %d f1regs %d\n", - (bus->f2rxhdrs + bus->f2rxdata), bus->f2rxhdrs, bus->f2rxdata, - bus->f2txdata, bus->f1regdata); - { - dhd_dump_pct(strbuf, "\nRx: pkts/f2rd", bus->dhd->rx_packets, - (bus->f2rxhdrs + bus->f2rxdata)); - dhd_dump_pct(strbuf, ", pkts/f1sd", bus->dhd->rx_packets, bus->f1regdata); - dhd_dump_pct(strbuf, ", pkts/sd", bus->dhd->rx_packets, - (bus->f2rxhdrs + bus->f2rxdata + bus->f1regdata)); - dhd_dump_pct(strbuf, ", pkts/int", bus->dhd->rx_packets, bus->intrcount); - bcm_bprintf(strbuf, "\n"); - - dhd_dump_pct(strbuf, "Rx: glom pct", (100 * bus->rxglompkts), - bus->dhd->rx_packets); - dhd_dump_pct(strbuf, ", pkts/glom", bus->rxglompkts, bus->rxglomframes); - bcm_bprintf(strbuf, "\n"); - - dhd_dump_pct(strbuf, "Tx: pkts/f2wr", bus->dhd->tx_packets, bus->f2txdata); - dhd_dump_pct(strbuf, ", pkts/f1sd", bus->dhd->tx_packets, bus->f1regdata); - dhd_dump_pct(strbuf, ", pkts/sd", bus->dhd->tx_packets, - (bus->f2txdata + bus->f1regdata)); - dhd_dump_pct(strbuf, ", pkts/int", bus->dhd->tx_packets, bus->intrcount); - bcm_bprintf(strbuf, "\n"); - - dhd_dump_pct(strbuf, "Total: pkts/f2rw", - (bus->dhd->tx_packets + bus->dhd->rx_packets), - (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata)); - dhd_dump_pct(strbuf, ", pkts/f1sd", - (bus->dhd->tx_packets + bus->dhd->rx_packets), bus->f1regdata); - dhd_dump_pct(strbuf, ", pkts/sd", - (bus->dhd->tx_packets + bus->dhd->rx_packets), - (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata + bus->f1regdata)); - dhd_dump_pct(strbuf, ", pkts/int", - (bus->dhd->tx_packets + bus->dhd->rx_packets), bus->intrcount); - bcm_bprintf(strbuf, "\n\n"); - } - -#ifdef SDTEST - if (bus->pktgen_count) { - bcm_bprintf(strbuf, "pktgen config and count:\n"); - bcm_bprintf(strbuf, "freq %d count %d print %d total %d min %d len %d\n", - bus->pktgen_freq, bus->pktgen_count, bus->pktgen_print, - bus->pktgen_total, bus->pktgen_minlen, bus->pktgen_maxlen); - bcm_bprintf(strbuf, "send attempts %d rcvd %d fail %d\n", - bus->pktgen_sent, bus->pktgen_rcvd, bus->pktgen_fail); - } -#endif /* SDTEST */ -#ifdef DHD_DEBUG - bcm_bprintf(strbuf, "dpc_sched %d host interrupt%spending\n", - bus->dpc_sched, (bcmsdh_intr_pending(bus->sdh) ? " " : " not ")); - bcm_bprintf(strbuf, "blocksize %d roundup %d\n", bus->blocksize, bus->roundup); -#endif /* DHD_DEBUG */ - bcm_bprintf(strbuf, "clkstate %d activity %d idletime %d idlecount %d sleeping %d\n", - bus->clkstate, bus->activity, bus->idletime, bus->idlecount, bus->sleeping); -} - -void -dhd_bus_clearcounts(dhd_pub_t *dhdp) -{ - dhd_bus_t *bus = (dhd_bus_t *)dhdp->bus; - - bus->intrcount = bus->lastintrs = bus->spurious = bus->regfails = 0; - bus->rxrtx = bus->rx_toolong = bus->rxc_errors = 0; - bus->rx_hdrfail = bus->rx_badhdr = bus->rx_badseq = 0; - bus->tx_sderrs = bus->fc_rcvd = bus->fc_xoff = bus->fc_xon = 0; - bus->rxglomfail = bus->rxglomframes = bus->rxglompkts = 0; - bus->f2rxhdrs = bus->f2rxdata = bus->f2txdata = bus->f1regdata = 0; -} - -#ifdef SDTEST -static int -dhdsdio_pktgen_get(dhd_bus_t *bus, uint8 *arg) -{ - dhd_pktgen_t pktgen; - - pktgen.version = DHD_PKTGEN_VERSION; - pktgen.freq = bus->pktgen_freq; - pktgen.count = bus->pktgen_count; - pktgen.print = bus->pktgen_print; - pktgen.total = bus->pktgen_total; - pktgen.minlen = bus->pktgen_minlen; - pktgen.maxlen = bus->pktgen_maxlen; - pktgen.numsent = bus->pktgen_sent; - pktgen.numrcvd = bus->pktgen_rcvd; - pktgen.numfail = bus->pktgen_fail; - pktgen.mode = bus->pktgen_mode; - pktgen.stop = bus->pktgen_stop; - - bcopy(&pktgen, arg, sizeof(pktgen)); - - return 0; -} - -static int -dhdsdio_pktgen_set(dhd_bus_t *bus, uint8 *arg) -{ - dhd_pktgen_t pktgen; - uint oldcnt, oldmode; - - bcopy(arg, &pktgen, sizeof(pktgen)); - if (pktgen.version != DHD_PKTGEN_VERSION) - return BCME_BADARG; - - oldcnt = bus->pktgen_count; - oldmode = bus->pktgen_mode; - - bus->pktgen_freq = pktgen.freq; - bus->pktgen_count = pktgen.count; - bus->pktgen_print = pktgen.print; - bus->pktgen_total = pktgen.total; - bus->pktgen_minlen = pktgen.minlen; - bus->pktgen_maxlen = pktgen.maxlen; - bus->pktgen_mode = pktgen.mode; - bus->pktgen_stop = pktgen.stop; - - bus->pktgen_tick = bus->pktgen_ptick = 0; - bus->pktgen_len = MAX(bus->pktgen_len, bus->pktgen_minlen); - bus->pktgen_len = MIN(bus->pktgen_len, bus->pktgen_maxlen); - - /* Clear counts for a new pktgen (mode change, or was stopped) */ - if (bus->pktgen_count && (!oldcnt || oldmode != bus->pktgen_mode)) - bus->pktgen_sent = bus->pktgen_rcvd = bus->pktgen_fail = 0; - - return 0; -} -#endif /* SDTEST */ - -static int -dhdsdio_membytes(dhd_bus_t *bus, bool write, uint32 address, uint8 *data, uint size) -{ - int bcmerror = 0; - uint32 sdaddr; - uint dsize; - - /* Determine initial transfer parameters */ - sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK; - if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK) - dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr); - else - dsize = size; - - /* Set the backplane window to include the start address */ - if ((bcmerror = dhdsdio_set_siaddr_window(bus, address))) { - DHD_ERROR(("%s: window change failed\n", __FUNCTION__)); - goto xfer_done; - } - - /* Do the transfer(s) */ - while (size) { - DHD_INFO(("%s: %s %d bytes at offset 0x%08x in window 0x%08x\n", - __FUNCTION__, (write ? "write" : "read"), dsize, sdaddr, - (address & SBSDIO_SBWINDOW_MASK))); - if ((bcmerror = bcmsdh_rwdata(bus->sdh, write, sdaddr, data, dsize))) { - DHD_ERROR(("%s: membytes transfer failed\n", __FUNCTION__)); - break; - } - - /* Adjust for next transfer (if any) */ - if ((size -= dsize)) { - data += dsize; - address += dsize; - if ((bcmerror = dhdsdio_set_siaddr_window(bus, address))) { - DHD_ERROR(("%s: window change failed\n", __FUNCTION__)); - break; - } - sdaddr = 0; - dsize = MIN(SBSDIO_SB_OFT_ADDR_LIMIT, size); - } - } - -xfer_done: - /* Return the window to backplane enumeration space for core access */ - if (dhdsdio_set_siaddr_window(bus, bcmsdh_cur_sbwad(bus->sdh))) { - DHD_ERROR(("%s: FAILED to set window back to 0x%x\n", __FUNCTION__, - bcmsdh_cur_sbwad(bus->sdh))); - } - - return bcmerror; -} - -#ifdef DHD_DEBUG_TRAP -static int -dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh) -{ - uint32 addr; - int rv; - - /* Read last word in memory to determine address of sdpcm_shared structure */ - if ((rv = dhdsdio_membytes(bus, FALSE, bus->ramsize - 4, (uint8 *)&addr, 4)) < 0) - return rv; - - addr = ltoh32(addr); - - DHD_INFO(("sdpcm_shared address 0x%08X\n", addr)); - - /* - * Check if addr is valid. - * NVRAM length at the end of memory should have been overwritten. - */ - if (addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)) { - DHD_ERROR(("%s: address (0x%08x) of sdpcm_shared invalid\n", __FUNCTION__, addr)); - return BCME_ERROR; - } - - /* Read hndrte_shared structure */ - if ((rv = dhdsdio_membytes(bus, FALSE, addr, (uint8 *)sh, sizeof(sdpcm_shared_t))) < 0) - return rv; - - /* Endianness */ - sh->flags = ltoh32(sh->flags); - sh->trap_addr = ltoh32(sh->trap_addr); - sh->assert_exp_addr = ltoh32(sh->assert_exp_addr); - sh->assert_file_addr = ltoh32(sh->assert_file_addr); - sh->assert_line = ltoh32(sh->assert_line); - sh->console_addr = ltoh32(sh->console_addr); - sh->msgtrace_addr = ltoh32(sh->msgtrace_addr); - - if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) { - DHD_ERROR(("%s: sdpcm_shared version %d in dhd " - "is different than sdpcm_shared version %d in dongle\n", - __FUNCTION__, SDPCM_SHARED_VERSION, - sh->flags & SDPCM_SHARED_VERSION_MASK)); - return BCME_ERROR; - } - - return BCME_OK; -} - -static int -dhdsdio_checkdied(dhd_bus_t *bus, uint8 *data, uint size) -{ - int bcmerror = 0; - uint msize = 512; - char *mbuffer = NULL; - uint maxstrlen = 256; - char *str = NULL; - trap_t tr; - sdpcm_shared_t sdpcm_shared; - struct bcmstrbuf strbuf; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (data == NULL) { - /* - * Called after a rx ctrl timeout. "data" is NULL. - * allocate memory to trace the trap or assert. - */ - size = msize; - mbuffer = data = MALLOC(bus->dhd->osh, msize); - if (mbuffer == NULL) { - DHD_ERROR(("%s: MALLOC(%d) failed \n", __FUNCTION__, msize)); - bcmerror = BCME_NOMEM; - goto done; - } - } - - if ((str = MALLOC(bus->dhd->osh, maxstrlen)) == NULL) { - DHD_ERROR(("%s: MALLOC(%d) failed \n", __FUNCTION__, maxstrlen)); - bcmerror = BCME_NOMEM; - goto done; - } - - if ((bcmerror = dhdsdio_readshared(bus, &sdpcm_shared)) < 0) - goto done; - - bcm_binit(&strbuf, data, size); - - bcm_bprintf(&strbuf, "msgtrace address : 0x%08X\nconsole address : 0x%08X\n", - sdpcm_shared.msgtrace_addr, sdpcm_shared.console_addr); - - if ((sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) == 0) { - /* NOTE: Misspelled assert is intentional - DO NOT FIX. - * (Avoids conflict with real asserts for programmatic parsing of output.) - */ - bcm_bprintf(&strbuf, "Assrt not built in dongle\n"); - } - - if ((sdpcm_shared.flags & (SDPCM_SHARED_ASSERT|SDPCM_SHARED_TRAP)) == 0) { - /* NOTE: Misspelled assert is intentional - DO NOT FIX. - * (Avoids conflict with real asserts for programmatic parsing of output.) - */ - bcm_bprintf(&strbuf, "No trap%s in dongle", - (sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) - ?"/assrt" :""); - } else { - if (sdpcm_shared.flags & SDPCM_SHARED_ASSERT) { - /* Download assert */ - bcm_bprintf(&strbuf, "Dongle assert"); - if (sdpcm_shared.assert_exp_addr != 0) { - str[0] = '\0'; - if ((bcmerror = dhdsdio_membytes(bus, FALSE, - sdpcm_shared.assert_exp_addr, - (uint8 *)str, maxstrlen)) < 0) - goto done; - - str[maxstrlen - 1] = '\0'; - bcm_bprintf(&strbuf, " expr \"%s\"", str); - } - - if (sdpcm_shared.assert_file_addr != 0) { - str[0] = '\0'; - if ((bcmerror = dhdsdio_membytes(bus, FALSE, - sdpcm_shared.assert_file_addr, - (uint8 *)str, maxstrlen)) < 0) - goto done; - - str[maxstrlen - 1] = '\0'; - bcm_bprintf(&strbuf, " file \"%s\"", str); - } - - bcm_bprintf(&strbuf, " line %d ", sdpcm_shared.assert_line); - } - - if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) { - if ((bcmerror = dhdsdio_membytes(bus, FALSE, - sdpcm_shared.trap_addr, - (uint8*)&tr, sizeof(trap_t))) < 0) - goto done; - - bcm_bprintf(&strbuf, - "Dongle trap type 0x%x @ epc 0x%x, cpsr 0x%x, spsr 0x%x, sp 0x%x," - "lp 0x%x, rpc 0x%x Trap offset 0x%x, " - "r0 0x%x, r1 0x%x, r2 0x%x, r3 0x%x, r4 0x%x, r5 0x%x, r6 0x%x, r7 0x%x\n", - tr.type, tr.epc, tr.cpsr, tr.spsr, tr.r13, tr.r14, tr.pc, - sdpcm_shared.trap_addr, - tr.r0, tr.r1, tr.r2, tr.r3, tr.r4, tr.r5, tr.r6, tr.r7); - } - } - - if (sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP)) { - DHD_ERROR(("%s: %s\n", __FUNCTION__, strbuf.origbuf)); - } - -done: - if (mbuffer) - MFREE(bus->dhd->osh, mbuffer, msize); - if (str) - MFREE(bus->dhd->osh, str, maxstrlen); - - return bcmerror; -} -#endif /* DHD_DEBUG_TRAP */ - -#ifdef DHD_DEBUG -#define CONSOLE_LINE_MAX 192 - -static int -dhdsdio_readconsole(dhd_bus_t *bus) -{ - dhd_console_t *c = &bus->console; - uint8 line[CONSOLE_LINE_MAX], ch; - uint32 n, idx, addr; - int rv; - - /* Don't do anything until FWREADY updates console address */ - if (bus->console_addr == 0) - return 0; - - /* Read console log struct */ - addr = bus->console_addr + OFFSETOF(hndrte_cons_t, log); - if ((rv = dhdsdio_membytes(bus, FALSE, addr, (uint8 *)&c->log, sizeof(c->log))) < 0) - return rv; - - /* Allocate console buffer (one time only) */ - if (c->buf == NULL) { - c->bufsize = ltoh32(c->log.buf_size); - if ((c->buf = MALLOC(bus->dhd->osh, c->bufsize)) == NULL) - return BCME_NOMEM; - } - - idx = ltoh32(c->log.idx); - - /* Protect against corrupt value */ - if (idx > c->bufsize) - return BCME_ERROR; - - /* Skip reading the console buffer if the index pointer has not moved */ - if (idx == c->last) - return BCME_OK; - - /* Read the console buffer */ - addr = ltoh32(c->log.buf); - if ((rv = dhdsdio_membytes(bus, FALSE, addr, c->buf, c->bufsize)) < 0) - return rv; - - while (c->last != idx) { - for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) { - if (c->last == idx) { - /* This would output a partial line. Instead, back up - * the buffer pointer and output this line next time around. - */ - if (c->last >= n) - c->last -= n; - else - c->last = c->bufsize - n; - goto break2; - } - ch = c->buf[c->last]; - c->last = (c->last + 1) % c->bufsize; - if (ch == '\n') - break; - line[n] = ch; - } - - if (n > 0) { - if (line[n - 1] == '\r') - n--; - line[n] = 0; - printf("CONSOLE: %s\n", line); - } - } -break2: - - return BCME_OK; -} -#endif /* DHD_DEBUG */ - -int -dhdsdio_downloadvars(dhd_bus_t *bus, void *arg, int len) -{ - int bcmerror = BCME_OK; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* Basic sanity checks */ - if (bus->dhd->up) { - bcmerror = BCME_NOTDOWN; - goto err; - } - if (!len) { - bcmerror = BCME_BUFTOOSHORT; - goto err; - } - - /* Free the old ones and replace with passed variables */ - if (bus->vars) - MFREE(bus->dhd->osh, bus->vars, bus->varsz); - - bus->vars = MALLOC(bus->dhd->osh, len); - bus->varsz = bus->vars ? len : 0; - if (bus->vars == NULL) { - bcmerror = BCME_NOMEM; - goto err; - } - - /* Copy the passed variables, which should include the terminating double-null */ - bcopy(arg, bus->vars, bus->varsz); -err: - return bcmerror; -} - -static int -dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const char *name, - void *params, int plen, void *arg, int len, int val_size) -{ - int bcmerror = 0; - int32 int_val = 0; - bool bool_val = 0; - - DHD_TRACE(("%s: Enter, action %d name %s params %p plen %d arg %p len %d val_size %d\n", - __FUNCTION__, actionid, name, params, plen, arg, len, val_size)); - - if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid))) != 0) - goto exit; - - if (plen >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); - - bool_val = (int_val != 0) ? TRUE : FALSE; - - - /* Some ioctls use the bus */ - dhd_os_sdlock(bus->dhd); - - /* Check if dongle is in reset. If so, only allow DEVRESET iovars */ - if (bus->dhd->dongle_reset && !(actionid == IOV_SVAL(IOV_DEVRESET) || - actionid == IOV_GVAL(IOV_DEVRESET))) { - bcmerror = BCME_NOTREADY; - goto exit; - } - - /* Handle sleep stuff before any clock mucking */ - if (vi->varid == IOV_SLEEP) { - if (IOV_ISSET(actionid)) { - bcmerror = dhdsdio_bussleep(bus, bool_val); - } else { - int_val = (int32)bus->sleeping; - bcopy(&int_val, arg, val_size); - } - goto exit; - } - - /* Request clock to allow SDIO accesses */ - if (!bus->dhd->dongle_reset) { - BUS_WAKE(bus); - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - } - - switch (actionid) { - case IOV_GVAL(IOV_INTR): - int_val = (int32)bus->intr; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_INTR): - bus->intr = bool_val; - bus->intdis = FALSE; - if (bus->dhd->up) { - if (bus->intr) { - DHD_INTR(("%s: enable SDIO device interrupts\n", __FUNCTION__)); - bcmsdh_intr_enable(bus->sdh); - } else { - DHD_INTR(("%s: disable SDIO interrupts\n", __FUNCTION__)); - bcmsdh_intr_disable(bus->sdh); - } - } - break; - - case IOV_GVAL(IOV_POLLRATE): - int_val = (int32)bus->pollrate; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_POLLRATE): - bus->pollrate = (uint)int_val; - bus->poll = (bus->pollrate != 0); - break; - - case IOV_GVAL(IOV_IDLETIME): - int_val = bus->idletime; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_IDLETIME): - if ((int_val < 0) && (int_val != DHD_IDLE_IMMEDIATE)) { - bcmerror = BCME_BADARG; - } else { - bus->idletime = int_val; - } - break; - - case IOV_GVAL(IOV_IDLECLOCK): - int_val = (int32)bus->idleclock; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_IDLECLOCK): - bus->idleclock = int_val; - break; - - case IOV_GVAL(IOV_SD1IDLE): - int_val = (int32)sd1idle; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_SD1IDLE): - sd1idle = bool_val; - break; - - - case IOV_SVAL(IOV_MEMBYTES): - case IOV_GVAL(IOV_MEMBYTES): - { - uint32 address; - uint size, dsize; - uint8 *data; - - bool set = (actionid == IOV_SVAL(IOV_MEMBYTES)); - - ASSERT(plen >= 2*sizeof(int)); - - address = (uint32)int_val; - bcopy((char *)params + sizeof(int_val), &int_val, sizeof(int_val)); - size = (uint)int_val; - - /* Do some validation */ - dsize = set ? plen - (2 * sizeof(int)) : len; - if (dsize < size) { - DHD_ERROR(("%s: error on %s membytes, addr 0x%08x size %d dsize %d\n", - __FUNCTION__, (set ? "set" : "get"), address, size, dsize)); - bcmerror = BCME_BADARG; - break; - } - - DHD_INFO(("%s: Request to %s %d bytes at address 0x%08x\n", __FUNCTION__, - (set ? "write" : "read"), size, address)); - - /* If we know about SOCRAM, check for a fit */ - if ((bus->orig_ramsize) && - ((address > bus->orig_ramsize) || (address + size > bus->orig_ramsize))) { - DHD_ERROR(("%s: ramsize 0x%08x doesn't have %d bytes at 0x%08x\n", - __FUNCTION__, bus->orig_ramsize, size, address)); - bcmerror = BCME_BADARG; - break; - } - - /* Generate the actual data pointer */ - data = set ? (uint8*)params + 2 * sizeof(int): (uint8*)arg; - - /* Call to do the transfer */ - bcmerror = dhdsdio_membytes(bus, set, address, data, size); - - break; - } - - case IOV_GVAL(IOV_MEMSIZE): - int_val = (int32)bus->ramsize; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_SDIOD_DRIVE): - int_val = (int32)dhd_sdiod_drive_strength; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_SDIOD_DRIVE): - dhd_sdiod_drive_strength = int_val; - si_sdiod_drive_strength_init(bus->sih, bus->dhd->osh, dhd_sdiod_drive_strength); - break; - - case IOV_SVAL(IOV_DOWNLOAD): - bcmerror = dhdsdio_download_state(bus, bool_val); - break; - - case IOV_SVAL(IOV_VARS): - bcmerror = dhdsdio_downloadvars(bus, arg, len); - break; - - case IOV_GVAL(IOV_READAHEAD): - int_val = (int32)dhd_readahead; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_READAHEAD): - if (bool_val && !dhd_readahead) - bus->nextlen = 0; - dhd_readahead = bool_val; - break; - - case IOV_GVAL(IOV_SDRXCHAIN): - int_val = (int32)bus->use_rxchain; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_SDRXCHAIN): - if (bool_val && !bus->sd_rxchain) - bcmerror = BCME_UNSUPPORTED; - else - bus->use_rxchain = bool_val; - break; - case IOV_GVAL(IOV_ALIGNCTL): - int_val = (int32)dhd_alignctl; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_ALIGNCTL): - dhd_alignctl = bool_val; - break; - - case IOV_GVAL(IOV_SDALIGN): - int_val = DHD_SDALIGN; - bcopy(&int_val, arg, val_size); - break; - -#ifdef DHD_DEBUG - case IOV_GVAL(IOV_VARS): - if (bus->varsz < (uint)len) - bcopy(bus->vars, arg, bus->varsz); - else - bcmerror = BCME_BUFTOOSHORT; - break; -#endif /* DHD_DEBUG */ - -#ifdef DHD_DEBUG - case IOV_GVAL(IOV_SDREG): - { - sdreg_t *sd_ptr; - uint32 addr, size; - - sd_ptr = (sdreg_t *)params; - - addr = (uintptr)bus->regs + sd_ptr->offset; - size = sd_ptr->func; - int_val = (int32)bcmsdh_reg_read(bus->sdh, addr, size); - if (bcmsdh_regfail(bus->sdh)) - bcmerror = BCME_SDIO_ERROR; - bcopy(&int_val, arg, sizeof(int32)); - break; - } - - case IOV_SVAL(IOV_SDREG): - { - sdreg_t *sd_ptr; - uint32 addr, size; - - sd_ptr = (sdreg_t *)params; - - addr = (uintptr)bus->regs + sd_ptr->offset; - size = sd_ptr->func; - bcmsdh_reg_write(bus->sdh, addr, size, sd_ptr->value); - if (bcmsdh_regfail(bus->sdh)) - bcmerror = BCME_SDIO_ERROR; - break; - } - - /* Same as above, but offset is not backplane (not SDIO core) */ - case IOV_GVAL(IOV_SBREG): - { - sdreg_t sdreg; - uint32 addr, size; - - bcopy(params, &sdreg, sizeof(sdreg)); - - addr = SI_ENUM_BASE + sdreg.offset; - size = sdreg.func; - int_val = (int32)bcmsdh_reg_read(bus->sdh, addr, size); - if (bcmsdh_regfail(bus->sdh)) - bcmerror = BCME_SDIO_ERROR; - bcopy(&int_val, arg, sizeof(int32)); - break; - } - - case IOV_SVAL(IOV_SBREG): - { - sdreg_t sdreg; - uint32 addr, size; - - bcopy(params, &sdreg, sizeof(sdreg)); - - addr = SI_ENUM_BASE + sdreg.offset; - size = sdreg.func; - bcmsdh_reg_write(bus->sdh, addr, size, sdreg.value); - if (bcmsdh_regfail(bus->sdh)) - bcmerror = BCME_SDIO_ERROR; - break; - } - - case IOV_GVAL(IOV_SDCIS): - { - *(char *)arg = 0; - - bcmstrcat(arg, "\nFunc 0\n"); - bcmsdh_cis_read(bus->sdh, 0x10, (uint8 *)arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT); - bcmstrcat(arg, "\nFunc 1\n"); - bcmsdh_cis_read(bus->sdh, 0x11, (uint8 *)arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT); - bcmstrcat(arg, "\nFunc 2\n"); - bcmsdh_cis_read(bus->sdh, 0x12, (uint8 *)arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT); - break; - } - - case IOV_GVAL(IOV_FORCEEVEN): - int_val = (int32)forcealign; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_FORCEEVEN): - forcealign = bool_val; - break; - - case IOV_GVAL(IOV_TXBOUND): - int_val = (int32)dhd_txbound; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_TXBOUND): - dhd_txbound = (uint)int_val; - break; - - case IOV_GVAL(IOV_RXBOUND): - int_val = (int32)dhd_rxbound; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_RXBOUND): - dhd_rxbound = (uint)int_val; - break; - - case IOV_GVAL(IOV_TXMINMAX): - int_val = (int32)dhd_txminmax; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_TXMINMAX): - dhd_txminmax = (uint)int_val; - break; - - - -#endif /* DHD_DEBUG */ - - -#ifdef SDTEST - case IOV_GVAL(IOV_EXTLOOP): - int_val = (int32)bus->ext_loop; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_EXTLOOP): - bus->ext_loop = bool_val; - break; - - case IOV_GVAL(IOV_PKTGEN): - bcmerror = dhdsdio_pktgen_get(bus, arg); - break; - - case IOV_SVAL(IOV_PKTGEN): - bcmerror = dhdsdio_pktgen_set(bus, arg); - break; -#endif /* SDTEST */ - - - case IOV_SVAL(IOV_DEVRESET): - DHD_TRACE(("%s: Called set IOV_DEVRESET=%d dongle_reset=%d busstate=%d\n", - __FUNCTION__, bool_val, bus->dhd->dongle_reset, - bus->dhd->busstate)); - - ASSERT(bus->dhd->osh); - /* ASSERT(bus->cl_devid); */ - - dhd_bus_devreset(bus->dhd, (uint8)bool_val); - - break; - - case IOV_GVAL(IOV_DEVRESET): - DHD_TRACE(("%s: Called get IOV_DEVRESET\n", __FUNCTION__)); - - /* Get its status */ - int_val = (bool) bus->dhd->dongle_reset; - bcopy(&int_val, arg, val_size); - - break; - - default: - bcmerror = BCME_UNSUPPORTED; - break; - } - -exit: - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, TRUE); - } - - dhd_os_sdunlock(bus->dhd); - - if (actionid == IOV_SVAL(IOV_DEVRESET) && bool_val == FALSE) - dhd_preinit_ioctls((dhd_pub_t *) bus->dhd); - - return bcmerror; -} - -static int -dhdsdio_write_vars(dhd_bus_t *bus) -{ - int bcmerror = 0; - uint32 varsize; - uint32 varaddr; - uint8 *vbuffer; - uint32 varsizew; -#ifdef DHD_DEBUG - char *nvram_ularray; -#endif /* DHD_DEBUG */ - - /* Even if there are no vars are to be written, we still need to set the ramsize. */ - varsize = bus->varsz ? ROUNDUP(bus->varsz, 4) : 0; - varaddr = (bus->ramsize - 4) - varsize; - - if (bus->vars) { - vbuffer = (uint8 *)MALLOC(bus->dhd->osh, varsize); - if (!vbuffer) - return BCME_NOMEM; - - bzero(vbuffer, varsize); - bcopy(bus->vars, vbuffer, bus->varsz); - - /* Write the vars list */ - bcmerror = dhdsdio_membytes(bus, TRUE, varaddr, vbuffer, varsize); -#ifdef DHD_DEBUG - /* Verify NVRAM bytes */ - DHD_INFO(("Compare NVRAM dl & ul; varsize=%d\n", varsize)); - nvram_ularray = (char*)MALLOC(bus->dhd->osh, varsize); - if (!nvram_ularray) - return BCME_NOMEM; - - /* Upload image to verify downloaded contents. */ - memset(nvram_ularray, 0xaa, varsize); - - /* Read the vars list to temp buffer for comparison */ - bcmerror = dhdsdio_membytes(bus, FALSE, varaddr, nvram_ularray, varsize); - if (bcmerror) { - DHD_ERROR(("%s: error %d on reading %d nvram bytes at 0x%08x\n", - __FUNCTION__, bcmerror, varsize, varaddr)); - } - /* Compare the org NVRAM with the one read from RAM */ - if (memcmp(vbuffer, nvram_ularray, varsize)) { - DHD_ERROR(("%s: Downloaded NVRAM image is corrupted.\n", __FUNCTION__)); - } else - DHD_ERROR(("%s: Download, Upload and compare of NVRAM succeeded.\n", - __FUNCTION__)); - - MFREE(bus->dhd->osh, nvram_ularray, varsize); -#endif /* DHD_DEBUG */ - - MFREE(bus->dhd->osh, vbuffer, varsize); - } - - /* adjust to the user specified RAM */ - DHD_INFO(("Physical memory size: %d, usable memory size: %d\n", - bus->orig_ramsize, bus->ramsize)); - DHD_INFO(("Vars are at %d, orig varsize is %d\n", - varaddr, varsize)); - varsize = ((bus->orig_ramsize - 4) - varaddr); - - /* - * Determine the length token: - * Varsize, converted to words, in lower 16-bits, checksum in upper 16-bits. - */ - if (bcmerror) { - varsizew = 0; - } else { - varsizew = varsize / 4; - varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF); - varsizew = htol32(varsizew); - } - - DHD_INFO(("New varsize is %d, length token=0x%08x\n", varsize, varsizew)); - - /* Write the length token to the last word */ - bcmerror = dhdsdio_membytes(bus, TRUE, (bus->orig_ramsize - 4), - (uint8*)&varsizew, 4); - - return bcmerror; -} - -static int -dhdsdio_download_state(dhd_bus_t *bus, bool enter) -{ - uint retries; - int bcmerror = 0; - - /* To enter download state, disable ARM and reset SOCRAM. - * To exit download state, simply reset ARM (default is RAM boot). - */ - if (enter) { - - bus->alp_only = TRUE; - - if (!(si_setcore(bus->sih, ARM7S_CORE_ID, 0)) && - !(si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find ARM core!\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } - - si_core_disable(bus->sih, 0); - if (bcmsdh_regfail(bus->sdh)) { - bcmerror = BCME_SDIO_ERROR; - goto fail; - } - - if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find SOCRAM core!\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } - - si_core_reset(bus->sih, 0, 0); - if (bcmsdh_regfail(bus->sdh)) { - DHD_ERROR(("%s: Failure trying reset SOCRAM core?\n", __FUNCTION__)); - bcmerror = BCME_SDIO_ERROR; - goto fail; - } - - /* Clear the top bit of memory */ - if (bus->ramsize) { - uint32 zeros = 0; - dhdsdio_membytes(bus, TRUE, bus->ramsize - 4, (uint8*)&zeros, 4); - } - } else { - if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find SOCRAM core!\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } - - if (!si_iscoreup(bus->sih)) { - DHD_ERROR(("%s: SOCRAM core is down after reset?\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } - - if ((bcmerror = dhdsdio_write_vars(bus))) { - DHD_ERROR(("%s: no vars written to RAM\n", __FUNCTION__)); - bcmerror = 0; - } - - if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0) && - !si_setcore(bus->sih, SDIOD_CORE_ID, 0)) { - DHD_ERROR(("%s: Can't change back to SDIO core?\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } - W_SDREG(0xFFFFFFFF, &bus->regs->intstatus, retries); - - - if (!(si_setcore(bus->sih, ARM7S_CORE_ID, 0)) && - !(si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find ARM core!\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } - - si_core_reset(bus->sih, 0, 0); - if (bcmsdh_regfail(bus->sdh)) { - DHD_ERROR(("%s: Failure trying to reset ARM core?\n", __FUNCTION__)); - bcmerror = BCME_SDIO_ERROR; - goto fail; - } - - /* Allow HT Clock now that the ARM is running. */ - bus->alp_only = FALSE; - - bus->dhd->busstate = DHD_BUS_LOAD; - } - -fail: - /* Always return to SDIOD core */ - if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0)) - si_setcore(bus->sih, SDIOD_CORE_ID, 0); - - return bcmerror; -} - -int -dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - dhd_bus_t *bus = dhdp->bus; - const bcm_iovar_t *vi = NULL; - int bcmerror = 0; - int val_size; - uint32 actionid; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - ASSERT(name); - ASSERT(len >= 0); - - /* Get MUST have return space */ - ASSERT(set || (arg && len)); - - /* Set does NOT take qualifiers */ - ASSERT(!set || (!params && !plen)); - - /* Look up var locally; if not found pass to host driver */ - if ((vi = bcm_iovar_lookup(dhdsdio_iovars, name)) == NULL) { - dhd_os_sdlock(bus->dhd); - - BUS_WAKE(bus); - - /* Turn on clock in case SD command needs backplane */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - bcmerror = bcmsdh_iovar_op(bus->sdh, name, params, plen, arg, len, set); - - /* Check for bus configuration changes of interest */ - - /* If it was divisor change, read the new one */ - if (set && strcmp(name, "sd_divisor") == 0) { - if (bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0, - &bus->sd_divisor, sizeof(int32), FALSE) != BCME_OK) { - bus->sd_divisor = -1; - DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__, name)); - } else { - DHD_INFO(("%s: noted %s update, value now %d\n", - __FUNCTION__, name, bus->sd_divisor)); - } - } - /* If it was a mode change, read the new one */ - if (set && strcmp(name, "sd_mode") == 0) { - if (bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0, - &bus->sd_mode, sizeof(int32), FALSE) != BCME_OK) { - bus->sd_mode = -1; - DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__, name)); - } else { - DHD_INFO(("%s: noted %s update, value now %d\n", - __FUNCTION__, name, bus->sd_mode)); - } - } - /* Similar check for blocksize change */ - if (set && strcmp(name, "sd_blocksize") == 0) { - int32 fnum = 2; - if (bcmsdh_iovar_op(bus->sdh, "sd_blocksize", &fnum, sizeof(int32), - &bus->blocksize, sizeof(int32), FALSE) != BCME_OK) { - bus->blocksize = 0; - DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__, "sd_blocksize")); - } else { - DHD_INFO(("%s: noted %s update, value now %d\n", - __FUNCTION__, "sd_blocksize", bus->blocksize)); - } - } - bus->roundup = MIN(max_roundup, bus->blocksize); - - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, TRUE); - } - - dhd_os_sdunlock(bus->dhd); - goto exit; - } - - DHD_CTL(("%s: %s %s, len %d plen %d\n", __FUNCTION__, - name, (set ? "set" : "get"), len, plen)); - - /* set up 'params' pointer in case this is a set command so that - * the convenience int and bool code can be common to set and get - */ - if (params == NULL) { - params = arg; - plen = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - /* all other types are integer sized */ - val_size = sizeof(int); - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - bcmerror = dhdsdio_doiovar(bus, vi, actionid, name, params, plen, arg, len, val_size); - -exit: - return bcmerror; -} - -void -dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex) -{ - osl_t *osh = bus->dhd->osh; - uint32 local_hostintmask; - uint8 saveclk; - uint retries; - int err; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (enforce_mutex) - dhd_os_sdlock(bus->dhd); - - BUS_WAKE(bus); - - /* Change our idea of bus state */ - bus->dhd->busstate = DHD_BUS_DOWN; - - /* Enable clock for device interrupts */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - /* Disable and clear interrupts at the chip level also */ - W_SDREG(0, &bus->regs->hostintmask, retries); - local_hostintmask = bus->hostintmask; - bus->hostintmask = 0; - - /* Force clocks on backplane to be sure F2 interrupt propagates */ - saveclk = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); - if (!err) { - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - (saveclk | SBSDIO_FORCE_HT), &err); - } - if (err) { - DHD_ERROR(("%s: Failed to force clock for F2: err %d\n", __FUNCTION__, err)); - } - - /* Turn off the bus (F2), free any pending packets */ - DHD_INTR(("%s: disable SDIO interrupts\n", __FUNCTION__)); - bcmsdh_intr_disable(bus->sdh); - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, SDIO_FUNC_ENABLE_1, NULL); - - /* Clear any pending interrupts now that F2 is disabled */ - W_SDREG(local_hostintmask, &bus->regs->intstatus, retries); - - /* Turn off the backplane clock (only) */ - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); - - /* Clear the data packet queues */ - pktq_flush(osh, &bus->txq, TRUE); - - /* Clear any held glomming stuff */ - if (bus->glomd) - PKTFREE(osh, bus->glomd, FALSE); - - if (bus->glom) - PKTFREE(osh, bus->glom, FALSE); - - bus->glom = bus->glomd = NULL; - - /* Clear rx control and wake any waiters */ - bus->rxlen = 0; - dhd_os_ioctl_resp_wake(bus->dhd); - - /* Reset some F2 state stuff */ - bus->rxskip = FALSE; - bus->tx_seq = bus->rx_seq = 0; - - if (enforce_mutex) - dhd_os_sdunlock(bus->dhd); -} - -int -dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex) -{ - dhd_bus_t *bus = dhdp->bus; - dhd_timeout_t tmo; - uint retries = 0; - uint8 ready, enable; - int err, ret = BCME_ERROR; - uint8 saveclk; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - ASSERT(bus->dhd); - if (!bus->dhd) - return BCME_OK; - - if (enforce_mutex) - dhd_os_sdlock(bus->dhd); - - /* Make sure backplane clock is on, needed to generate F2 interrupt */ - err = dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - if ((err != BCME_OK) || (bus->clkstate != CLK_AVAIL)) { - DHD_ERROR(("%s: Failed to set backplane clock: err %d\n", __FUNCTION__, err)); - goto exit; - } - - /* Force clocks on backplane to be sure F2 interrupt propagates */ - saveclk = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); - if (!err) { - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - (saveclk | SBSDIO_FORCE_HT), &err); - } - if (err) { - DHD_ERROR(("%s: Failed to force clock for F2: err %d\n", __FUNCTION__, err)); - goto exit; - } - - /* Enable function 2 (frame transfers) */ - W_SDREG((SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT), - &bus->regs->tosbmailboxdata, retries); - enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2); - - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable, NULL); - - /* Give the dongle some time to do its thing and set IOR2 */ - dhd_timeout_start(&tmo, DHD_WAIT_F2RDY * 1000); - - ready = 0; - while (ready != enable && !dhd_timeout_expired(&tmo)) - ready = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IORDY, NULL); - - - DHD_INFO(("%s: enable 0x%02x, ready 0x%02x (waited %uus)\n", - __FUNCTION__, enable, ready, tmo.elapsed)); - - - /* If F2 successfully enabled, set core and enable interrupts */ - if (ready == enable) { - /* Make sure we're talking to the core. */ - if (!(bus->regs = si_setcore(bus->sih, PCMCIA_CORE_ID, 0))) - bus->regs = si_setcore(bus->sih, SDIOD_CORE_ID, 0); - - /* Set up the interrupt mask and enable interrupts */ - bus->hostintmask = HOSTINTMASK; - W_SDREG(bus->hostintmask, &bus->regs->hostintmask, retries); - - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK, (uint8)watermark, &err); - - /* Set bus state according to enable result */ - dhdp->busstate = DHD_BUS_DATA; - - /* bcmsdh_intr_unmask(bus->sdh); */ - - bus->intdis = FALSE; - if (bus->intr) { - DHD_INTR(("%s: enable SDIO device interrupts\n", __FUNCTION__)); - bcmsdh_intr_enable(bus->sdh); - } else { - DHD_INTR(("%s: disable SDIO interrupts\n", __FUNCTION__)); - bcmsdh_intr_disable(bus->sdh); - } - - } - - - else { - /* Disable F2 again */ - enable = SDIO_FUNC_ENABLE_1; - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable, NULL); - } - - /* Restore previous clock setting */ - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err); - - - /* If we didn't come up, turn off backplane clock */ - if (dhdp->busstate != DHD_BUS_DATA) - dhdsdio_clkctl(bus, CLK_NONE, FALSE); - - ret = BCME_OK; -exit: - if (enforce_mutex) - dhd_os_sdunlock(bus->dhd); - - return ret; -} - -static void -dhdsdio_rxfail(dhd_bus_t *bus, bool abort, bool rtx) -{ - bcmsdh_info_t *sdh = bus->sdh; - sdpcmd_regs_t *regs = bus->regs; - uint retries = 0; - uint16 lastrbc; - uint8 hi, lo; - int err; - - DHD_ERROR(("%s: %sterminate frame%s\n", __FUNCTION__, - (abort ? "abort command, " : ""), (rtx ? ", send NAK" : ""))); - - if (abort) { - bcmsdh_abort(sdh, SDIO_FUNC_2); - } - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM, &err); - bus->f1regdata++; - - /* Wait until the packet has been flushed (device/FIFO stable) */ - for (lastrbc = retries = 0xffff; retries > 0; retries--) { - hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCHI, NULL); - lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCLO, NULL); - bus->f1regdata += 2; - - if ((hi == 0) && (lo == 0)) - break; - - if ((hi > (lastrbc >> 8)) && (lo > (lastrbc & 0x00ff))) { - DHD_ERROR(("%s: count growing: last 0x%04x now 0x%04x\n", - __FUNCTION__, lastrbc, ((hi << 8) + lo))); - } - lastrbc = (hi << 8) + lo; - } - - if (!retries) { - DHD_ERROR(("%s: count never zeroed: last 0x%04x\n", __FUNCTION__, lastrbc)); - } else { - DHD_INFO(("%s: flush took %d iterations\n", __FUNCTION__, (0xffff - retries))); - } - - if (rtx) { - bus->rxrtx++; - W_SDREG(SMB_NAK, ®s->tosbmailbox, retries); - bus->f1regdata++; - if (retries <= retry_limit) { - bus->rxskip = TRUE; - } - } - - /* Clear partial in any case */ - bus->nextlen = 0; - - /* If we can't reach the device, signal failure */ - if (err || bcmsdh_regfail(sdh)) - bus->dhd->busstate = DHD_BUS_DOWN; -} - -static void -dhdsdio_read_control(dhd_bus_t *bus, uint8 *hdr, uint len, uint doff) -{ - bcmsdh_info_t *sdh = bus->sdh; - uint rdlen, pad; - - int sdret; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* Control data already received in aligned rxctl */ - if ((bus->bus == SPI_BUS) && (!bus->usebufpool)) - goto gotpkt; - - ASSERT(bus->rxbuf); - /* Set rxctl for frame (w/optional alignment) */ - bus->rxctl = bus->rxbuf; - if (dhd_alignctl) { - bus->rxctl += firstread; - if ((pad = ((uintptr)bus->rxctl % DHD_SDALIGN))) - bus->rxctl += (DHD_SDALIGN - pad); - bus->rxctl -= firstread; - } - ASSERT(bus->rxctl >= bus->rxbuf); - - /* Copy the already-read portion over */ - bcopy(hdr, bus->rxctl, firstread); - if (len <= firstread) - goto gotpkt; - - /* Copy the full data pkt in gSPI case and process ioctl. */ - if (bus->bus == SPI_BUS) { - bcopy(hdr, bus->rxctl, len); - goto gotpkt; - } - - /* Raise rdlen to next SDIO block to avoid tail command */ - rdlen = len - firstread; - if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) { - pad = bus->blocksize - (rdlen % bus->blocksize); - if ((pad <= bus->roundup) && (pad < bus->blocksize) && - ((len + pad) < bus->dhd->maxctl)) - rdlen += pad; - } else if (rdlen % DHD_SDALIGN) { - rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN); - } - - /* Satisfy length-alignment requirements */ - if (forcealign && (rdlen & (ALIGNMENT - 1))) - rdlen = ROUNDUP(rdlen, ALIGNMENT); - - /* Drop if the read is too big or it exceeds our maximum */ - if ((rdlen + firstread) > bus->dhd->maxctl) { - DHD_ERROR(("%s: %d-byte control read exceeds %d-byte buffer\n", - __FUNCTION__, rdlen, bus->dhd->maxctl)); - bus->dhd->rx_errors++; - dhdsdio_rxfail(bus, FALSE, FALSE); - goto done; - } - - if ((len - doff) > bus->dhd->maxctl) { - DHD_ERROR(("%s: %d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n", - __FUNCTION__, len, (len - doff), bus->dhd->maxctl)); - bus->dhd->rx_errors++; bus->rx_toolong++; - dhdsdio_rxfail(bus, FALSE, FALSE); - goto done; - } - - - /* Read remainder of frame body into the rxctl buffer */ - sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - (bus->rxctl + firstread), rdlen, NULL, NULL, NULL); - bus->f2rxdata++; - ASSERT(sdret != BCME_PENDING); - - /* Control frame failures need retransmission */ - if (sdret < 0) { - DHD_ERROR(("%s: read %d control bytes failed: %d\n", __FUNCTION__, rdlen, sdret)); - bus->rxc_errors++; /* dhd.rx_ctlerrs is higher level */ - dhdsdio_rxfail(bus, TRUE, TRUE); - goto done; - } - -gotpkt: - -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_CTL_ON()) { - prhex("RxCtrl", bus->rxctl, len); - } -#endif - - /* Point to valid data and indicate its length */ - bus->rxctl += doff; - bus->rxlen = len - doff; - -done: - /* Awake any waiters */ - dhd_os_ioctl_resp_wake(bus->dhd); -} - -static uint8 -dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq) -{ - uint16 dlen, totlen; - uint8 *dptr, num = 0; - - uint16 sublen, check; - void *pfirst, *plast, *pnext, *save_pfirst; - osl_t *osh = bus->dhd->osh; - - int errcode; - uint8 chan, seq, doff, sfdoff; - uint8 txmax; - - int ifidx = 0; - bool usechain = bus->use_rxchain; - - /* If packets, issue read(s) and send up packet chain */ - /* Return sequence numbers consumed? */ - - DHD_TRACE(("dhdsdio_rxglom: start: glomd %p glom %p\n", bus->glomd, bus->glom)); - - /* If there's a descriptor, generate the packet chain */ - if (bus->glomd) { - dhd_os_sdlock_rxq(bus->dhd); - - pfirst = plast = pnext = NULL; - dlen = (uint16)PKTLEN(osh, bus->glomd); - dptr = PKTDATA(osh, bus->glomd); - if (!dlen || (dlen & 1)) { - DHD_ERROR(("%s: bad glomd len (%d), ignore descriptor\n", - __FUNCTION__, dlen)); - dlen = 0; - } - - for (totlen = num = 0; dlen; num++) { - /* Get (and move past) next length */ - sublen = ltoh16_ua(dptr); - dlen -= sizeof(uint16); - dptr += sizeof(uint16); - if ((sublen < SDPCM_HDRLEN) || - ((num == 0) && (sublen < (2 * SDPCM_HDRLEN)))) { - DHD_ERROR(("%s: descriptor len %d bad: %d\n", - __FUNCTION__, num, sublen)); - pnext = NULL; - break; - } - if (sublen % DHD_SDALIGN) { - DHD_ERROR(("%s: sublen %d not a multiple of %d\n", - __FUNCTION__, sublen, DHD_SDALIGN)); - usechain = FALSE; - } - totlen += sublen; - - /* For last frame, adjust read len so total is a block multiple */ - if (!dlen) { - sublen += (ROUNDUP(totlen, bus->blocksize) - totlen); - totlen = ROUNDUP(totlen, bus->blocksize); - } - - /* Allocate/chain packet for next subframe */ - if ((pnext = PKTGET(osh, sublen + DHD_SDALIGN, FALSE)) == NULL) { - DHD_ERROR(("%s: PKTGET failed, num %d len %d\n", - __FUNCTION__, num, sublen)); - break; - } - ASSERT(!PKTLINK(pnext)); - if (!pfirst) { - ASSERT(!plast); - pfirst = plast = pnext; - } else { - ASSERT(plast); - PKTSETNEXT(osh, plast, pnext); - plast = pnext; - } - - /* Adhere to start alignment requirements */ - PKTALIGN(osh, pnext, sublen, DHD_SDALIGN); - } - - /* If all allocations succeeded, save packet chain in bus structure */ - if (pnext) { - DHD_GLOM(("%s: allocated %d-byte packet chain for %d subframes\n", - __FUNCTION__, totlen, num)); - if (DHD_GLOM_ON() && bus->nextlen) { - if (totlen != bus->nextlen) { - DHD_GLOM(("%s: glomdesc mismatch: nextlen %d glomdesc %d " - "rxseq %d\n", __FUNCTION__, bus->nextlen, - totlen, rxseq)); - } - } - bus->glom = pfirst; - pfirst = pnext = NULL; - } else { - if (pfirst) - PKTFREE(osh, pfirst, FALSE); - bus->glom = NULL; - num = 0; - } - - /* Done with descriptor packet */ - PKTFREE(osh, bus->glomd, FALSE); - bus->glomd = NULL; - bus->nextlen = 0; - - dhd_os_sdunlock_rxq(bus->dhd); - } - - /* Ok -- either we just generated a packet chain, or had one from before */ - if (bus->glom) { - if (DHD_GLOM_ON()) { - DHD_GLOM(("%s: attempt superframe read, packet chain:\n", __FUNCTION__)); - for (pnext = bus->glom; pnext; pnext = PKTNEXT(osh, pnext)) { - DHD_GLOM((" %p: %p len 0x%04x (%d)\n", - pnext, (uint8*)PKTDATA(osh, pnext), - PKTLEN(osh, pnext), PKTLEN(osh, pnext))); - } - } - - pfirst = bus->glom; - dlen = (uint16)pkttotlen(osh, pfirst); - - /* Do an SDIO read for the superframe. Configurable iovar to - * read directly into the chained packet, or allocate a large - * packet and and copy into the chain. - */ - if (usechain) { - errcode = dhd_bcmsdh_recv_buf(bus, - bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2, - F2SYNC, (uint8*)PKTDATA(osh, pfirst), - dlen, pfirst, NULL, NULL); - } else if (bus->dataptr) { - errcode = dhd_bcmsdh_recv_buf(bus, - bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2, - F2SYNC, bus->dataptr, - dlen, NULL, NULL, NULL); - sublen = (uint16)pktfrombuf(osh, pfirst, 0, dlen, bus->dataptr); - if (sublen != dlen) { - DHD_ERROR(("%s: FAILED TO COPY, dlen %d sublen %d\n", - __FUNCTION__, dlen, sublen)); - errcode = -1; - } - pnext = NULL; - } else { - DHD_ERROR(("COULDN'T ALLOC %d-BYTE GLOM, FORCE FAILURE\n", dlen)); - errcode = -1; - } - bus->f2rxdata++; - ASSERT(errcode != BCME_PENDING); - - /* On failure, kill the superframe, allow a couple retries */ - if (errcode < 0) { - DHD_ERROR(("%s: glom read of %d bytes failed: %d\n", - __FUNCTION__, dlen, errcode)); - bus->dhd->rx_errors++; - - if (bus->glomerr++ < 3) { - dhdsdio_rxfail(bus, TRUE, TRUE); - } else { - bus->glomerr = 0; - dhdsdio_rxfail(bus, TRUE, FALSE); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(osh, bus->glom, FALSE); - dhd_os_sdunlock_rxq(bus->dhd); - bus->rxglomfail++; - bus->glom = NULL; - } - return 0; - } - -#ifdef DHD_DEBUG - if (DHD_GLOM_ON()) { - prhex("SUPERFRAME", PKTDATA(osh, pfirst), - MIN(PKTLEN(osh, pfirst), 48)); - } -#endif - - - /* Validate the superframe header */ - dptr = (uint8 *)PKTDATA(osh, pfirst); - sublen = ltoh16_ua(dptr); - check = ltoh16_ua(dptr + sizeof(uint16)); - - chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); - seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); - bus->nextlen = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; - if ((bus->nextlen << 4) > MAX_RX_DATASZ) { - DHD_INFO(("%s: got frame w/nextlen too large (%d) seq %d\n", - __FUNCTION__, bus->nextlen, seq)); - bus->nextlen = 0; - } - doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); - txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); - - errcode = 0; - if ((uint16)~(sublen^check)) { - DHD_ERROR(("%s (superframe): HW hdr error: len/check 0x%04x/0x%04x\n", - __FUNCTION__, sublen, check)); - errcode = -1; - } else if (ROUNDUP(sublen, bus->blocksize) != dlen) { - DHD_ERROR(("%s (superframe): len 0x%04x, rounded 0x%04x, expect 0x%04x\n", - __FUNCTION__, sublen, ROUNDUP(sublen, bus->blocksize), dlen)); - errcode = -1; - } else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) != SDPCM_GLOM_CHANNEL) { - DHD_ERROR(("%s (superframe): bad channel %d\n", __FUNCTION__, - SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]))); - errcode = -1; - } else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) { - DHD_ERROR(("%s (superframe): got second descriptor?\n", __FUNCTION__)); - errcode = -1; - } else if ((doff < SDPCM_HDRLEN) || - (doff > (PKTLEN(osh, pfirst) - SDPCM_HDRLEN))) { - DHD_ERROR(("%s (superframe): Bad data offset %d: HW %d pkt %d min %d\n", - __FUNCTION__, doff, sublen, PKTLEN(osh, pfirst), SDPCM_HDRLEN)); - errcode = -1; - } - - /* Check sequence number of superframe SW header */ - if (rxseq != seq) { - DHD_INFO(("%s: (superframe) rx_seq %d, expected %d\n", - __FUNCTION__, seq, rxseq)); - bus->rx_badseq++; - rxseq = seq; - } - - /* Check window for sanity */ - if ((uint8)(txmax - bus->tx_seq) > 0x40) { - DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n", - __FUNCTION__, txmax, bus->tx_seq)); - txmax = bus->tx_seq + 2; - } - bus->tx_max = txmax; - - /* Remove superframe header, remember offset */ - PKTPULL(osh, pfirst, doff); - sfdoff = doff; - - /* Validate all the subframe headers */ - for (num = 0, pnext = pfirst; pnext && !errcode; - num++, pnext = PKTNEXT(osh, pnext)) { - dptr = (uint8 *)PKTDATA(osh, pnext); - dlen = (uint16)PKTLEN(osh, pnext); - sublen = ltoh16_ua(dptr); - check = ltoh16_ua(dptr + sizeof(uint16)); - chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); - doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); -#ifdef DHD_DEBUG - if (DHD_GLOM_ON()) { - prhex("subframe", dptr, 32); - } -#endif - - if ((uint16)~(sublen^check)) { - DHD_ERROR(("%s (subframe %d): HW hdr error: " - "len/check 0x%04x/0x%04x\n", - __FUNCTION__, num, sublen, check)); - errcode = -1; - } else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN)) { - DHD_ERROR(("%s (subframe %d): length mismatch: " - "len 0x%04x, expect 0x%04x\n", - __FUNCTION__, num, sublen, dlen)); - errcode = -1; - } else if ((chan != SDPCM_DATA_CHANNEL) && - (chan != SDPCM_EVENT_CHANNEL)) { - DHD_ERROR(("%s (subframe %d): bad channel %d\n", - __FUNCTION__, num, chan)); - errcode = -1; - } else if ((doff < SDPCM_HDRLEN) || (doff > sublen)) { - DHD_ERROR(("%s (subframe %d): Bad data offset %d: HW %d min %d\n", - __FUNCTION__, num, doff, sublen, SDPCM_HDRLEN)); - errcode = -1; - } - } - - if (errcode) { - /* Terminate frame on error, request a couple retries */ - if (bus->glomerr++ < 3) { - /* Restore superframe header space */ - PKTPUSH(osh, pfirst, sfdoff); - dhdsdio_rxfail(bus, TRUE, TRUE); - } else { - bus->glomerr = 0; - dhdsdio_rxfail(bus, TRUE, FALSE); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(osh, bus->glom, FALSE); - dhd_os_sdunlock_rxq(bus->dhd); - bus->rxglomfail++; - bus->glom = NULL; - } - bus->nextlen = 0; - return 0; - } - - /* Basic SD framing looks ok - process each packet (header) */ - save_pfirst = pfirst; - bus->glom = NULL; - plast = NULL; - - dhd_os_sdlock_rxq(bus->dhd); - for (num = 0; pfirst; rxseq++, pfirst = pnext) { - pnext = PKTNEXT(osh, pfirst); - PKTSETNEXT(osh, pfirst, NULL); - - dptr = (uint8 *)PKTDATA(osh, pfirst); - sublen = ltoh16_ua(dptr); - chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); - seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); - doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); - - DHD_GLOM(("%s: Get subframe %d, %p(%p/%d), sublen %d chan %d seq %d\n", - __FUNCTION__, num, pfirst, PKTDATA(osh, pfirst), - PKTLEN(osh, pfirst), sublen, chan, seq)); - - ASSERT((chan == SDPCM_DATA_CHANNEL) || (chan == SDPCM_EVENT_CHANNEL)); - - if (rxseq != seq) { - DHD_GLOM(("%s: rx_seq %d, expected %d\n", - __FUNCTION__, seq, rxseq)); - bus->rx_badseq++; - rxseq = seq; - } - -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) { - prhex("Rx Subframe Data", dptr, dlen); - } -#endif - - PKTSETLEN(osh, pfirst, sublen); - PKTPULL(osh, pfirst, doff); - - if (PKTLEN(osh, pfirst) == 0) { - PKTFREE(bus->dhd->osh, pfirst, FALSE); - if (plast) { - PKTSETNEXT(osh, plast, pnext); - } else { - ASSERT(save_pfirst == pfirst); - save_pfirst = pnext; - } - continue; - } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pfirst) != 0) { - DHD_ERROR(("%s: rx protocol error\n", __FUNCTION__)); - bus->dhd->rx_errors++; - PKTFREE(osh, pfirst, FALSE); - if (plast) { - PKTSETNEXT(osh, plast, pnext); - } else { - ASSERT(save_pfirst == pfirst); - save_pfirst = pnext; - } - continue; - } - - /* this packet will go up, link back into chain and count it */ - PKTSETNEXT(osh, pfirst, pnext); - plast = pfirst; - num++; - -#ifdef DHD_DEBUG - if (DHD_GLOM_ON()) { - DHD_GLOM(("%s subframe %d to stack, %p(%p/%d) nxt/lnk %p/%p\n", - __FUNCTION__, num, pfirst, - PKTDATA(osh, pfirst), PKTLEN(osh, pfirst), - PKTNEXT(osh, pfirst), PKTLINK(pfirst))); - prhex("", (uint8 *)PKTDATA(osh, pfirst), - MIN(PKTLEN(osh, pfirst), 32)); - } -#endif /* DHD_DEBUG */ - } - dhd_os_sdunlock_rxq(bus->dhd); - if (num) { - dhd_os_sdunlock(bus->dhd); - dhd_rx_frame(bus->dhd, ifidx, save_pfirst, num); - dhd_os_sdlock(bus->dhd); - } - - bus->rxglomframes++; - bus->rxglompkts += num; - } - return num; -} - -/* Return TRUE if there may be more frames to read */ -static uint -dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) -{ - osl_t *osh = bus->dhd->osh; - bcmsdh_info_t *sdh = bus->sdh; - - uint16 len, check; /* Extracted hardware header fields */ - uint8 chan, seq, doff; /* Extracted software header fields */ - uint8 fcbits; /* Extracted fcbits from software header */ - uint8 delta; - - void *pkt; /* Packet for event or data frames */ - uint16 pad; /* Number of pad bytes to read */ - uint16 rdlen; /* Total number of bytes to read */ - uint8 rxseq; /* Next sequence number to expect */ - uint rxleft = 0; /* Remaining number of frames allowed */ - int sdret; /* Return code from bcmsdh calls */ - uint8 txmax; /* Maximum tx sequence offered */ - bool len_consistent; /* Result of comparing readahead len and len from hw-hdr */ - uint8 *rxbuf; - int ifidx = 0; - uint rxcount = 0; /* Total frames read */ - -#if defined(DHD_DEBUG) || defined(SDTEST) - bool sdtest = FALSE; /* To limit message spew from test mode */ -#endif - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - ASSERT(maxframes); - -#ifdef SDTEST - /* Allow pktgen to override maxframes */ - if (bus->pktgen_count && (bus->pktgen_mode == DHD_PKTGEN_RECV)) { - maxframes = bus->pktgen_count; - sdtest = TRUE; - } -#endif - - /* Not finished unless we encounter no more frames indication */ - *finished = FALSE; - - - for (rxseq = bus->rx_seq, rxleft = maxframes; - !bus->rxskip && rxleft && bus->dhd->busstate != DHD_BUS_DOWN; - rxseq++, rxleft--) { - - /* Handle glomming separately */ - if (bus->glom || bus->glomd) { - uint8 cnt; - DHD_GLOM(("%s: calling rxglom: glomd %p, glom %p\n", - __FUNCTION__, bus->glomd, bus->glom)); - cnt = dhdsdio_rxglom(bus, rxseq); - DHD_GLOM(("%s: rxglom returned %d\n", __FUNCTION__, cnt)); - rxseq += cnt - 1; - rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1; - continue; - } - - /* Try doing single read if we can */ - if (dhd_readahead && bus->nextlen) { - uint16 nextlen = bus->nextlen; - bus->nextlen = 0; - - if (bus->bus == SPI_BUS) { - rdlen = len = nextlen; - } - else { - rdlen = len = nextlen << 4; - - /* Pad read to blocksize for efficiency */ - if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) { - pad = bus->blocksize - (rdlen % bus->blocksize); - if ((pad <= bus->roundup) && (pad < bus->blocksize) && - ((rdlen + pad + firstread) < MAX_RX_DATASZ)) - rdlen += pad; - } else if (rdlen % DHD_SDALIGN) { - rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN); - } - } - - /* We use bus->rxctl buffer in WinXP for initial control pkt receives. - * Later we use buffer-poll for data as well as control packets. - * This is required becuase dhd receives full frame in gSPI unlike SDIO. - * After the frame is received we have to distinguish whether it is data - * or non-data frame. - */ - /* Allocate a packet buffer */ - dhd_os_sdlock_rxq(bus->dhd); - if (!(pkt = PKTGET(osh, rdlen + DHD_SDALIGN, FALSE))) { - if (bus->bus == SPI_BUS) { - bus->usebufpool = FALSE; - bus->rxctl = bus->rxbuf; - if (dhd_alignctl) { - bus->rxctl += firstread; - if ((pad = ((uintptr)bus->rxctl % DHD_SDALIGN))) - bus->rxctl += (DHD_SDALIGN - pad); - bus->rxctl -= firstread; - } - ASSERT(bus->rxctl >= bus->rxbuf); - rxbuf = bus->rxctl; - /* Read the entire frame */ - sdret = dhd_bcmsdh_recv_buf(bus, - bcmsdh_cur_sbwad(sdh), - SDIO_FUNC_2, - F2SYNC, rxbuf, rdlen, - NULL, NULL, NULL); - bus->f2rxdata++; - ASSERT(sdret != BCME_PENDING); - - - /* Control frame failures need retransmission */ - if (sdret < 0) { - DHD_ERROR(("%s: read %d control bytes failed: %d\n", - __FUNCTION__, rdlen, sdret)); - /* dhd.rx_ctlerrs is higher level */ - bus->rxc_errors++; - dhd_os_sdunlock_rxq(bus->dhd); - dhdsdio_rxfail(bus, TRUE, - (bus->bus == SPI_BUS) ? FALSE : TRUE); - continue; - } - } else { - /* Give up on data, request rtx of events */ - DHD_ERROR(("%s (nextlen): PKTGET failed: len %d rdlen %d " - "expected rxseq %d\n", - __FUNCTION__, len, rdlen, rxseq)); - /* Just go try again w/normal header read */ - dhd_os_sdunlock_rxq(bus->dhd); - continue; - } - } else { - if (bus->bus == SPI_BUS) - bus->usebufpool = TRUE; - - ASSERT(!PKTLINK(pkt)); - PKTALIGN(osh, pkt, rdlen, DHD_SDALIGN); - rxbuf = (uint8 *)PKTDATA(osh, pkt); - /* Read the entire frame */ - sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), - SDIO_FUNC_2, - F2SYNC, rxbuf, rdlen, - pkt, NULL, NULL); - bus->f2rxdata++; - ASSERT(sdret != BCME_PENDING); - - if (sdret < 0) { - DHD_ERROR(("%s (nextlen): read %d bytes failed: %d\n", - __FUNCTION__, rdlen, sdret)); - PKTFREE(bus->dhd->osh, pkt, FALSE); - bus->dhd->rx_errors++; - dhd_os_sdunlock_rxq(bus->dhd); - /* Force retry w/normal header read. Don't attemp NAK for - * gSPI - */ - dhdsdio_rxfail(bus, TRUE, - (bus->bus == SPI_BUS) ? FALSE : TRUE); - continue; - } - } - dhd_os_sdunlock_rxq(bus->dhd); - - /* Now check the header */ - bcopy(rxbuf, bus->rxhdr, SDPCM_HDRLEN); - - /* Extract hardware header fields */ - len = ltoh16_ua(bus->rxhdr); - check = ltoh16_ua(bus->rxhdr + sizeof(uint16)); - - /* All zeros means readahead info was bad */ - if (!(len|check)) { - DHD_INFO(("%s (nextlen): read zeros in HW header???\n", - __FUNCTION__)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - GSPI_PR55150_BAILOUT; - continue; - } - - /* Validate check bytes */ - if ((uint16)~(len^check)) { - DHD_ERROR(("%s (nextlen): HW hdr error: nextlen/len/check" - " 0x%04x/0x%04x/0x%04x\n", __FUNCTION__, nextlen, - len, check)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - bus->rx_badhdr++; - dhdsdio_rxfail(bus, FALSE, FALSE); - GSPI_PR55150_BAILOUT; - continue; - } - - /* Validate frame length */ - if (len < SDPCM_HDRLEN) { - DHD_ERROR(("%s (nextlen): HW hdr length invalid: %d\n", - __FUNCTION__, len)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - GSPI_PR55150_BAILOUT; - continue; - } - - /* Check for consistency with readahead info */ - len_consistent = (nextlen != (ROUNDUP(len, 16) >> 4)); - if (len_consistent) { - /* Mismatch, force retry w/normal header (may be >4K) */ - DHD_ERROR(("%s (nextlen): mismatch, nextlen %d len %d rnd %d; " - "expected rxseq %d\n", - __FUNCTION__, nextlen, len, ROUNDUP(len, 16), rxseq)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - dhdsdio_rxfail(bus, TRUE, (bus->bus == SPI_BUS) ? FALSE : TRUE); - GSPI_PR55150_BAILOUT; - continue; - } - - - /* Extract software header fields */ - chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - - bus->nextlen = - bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; - if ((bus->nextlen << 4) > MAX_RX_DATASZ) { - DHD_INFO(("%s (nextlen): got frame w/nextlen too large" - " (%d), seq %d\n", __FUNCTION__, bus->nextlen, - seq)); - bus->nextlen = 0; - } - - bus->dhd->rx_readahead_cnt ++; - /* Handle Flow Control */ - fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - - delta = 0; - if (~bus->flowcontrol & fcbits) { - bus->fc_xoff++; - delta = 1; - } - if (bus->flowcontrol & ~fcbits) { - bus->fc_xon++; - delta = 1; - } - - if (delta) { - bus->fc_rcvd++; - bus->flowcontrol = fcbits; - } - - /* Check and update sequence number */ - if (rxseq != seq) { - DHD_INFO(("%s (nextlen): rx_seq %d, expected %d\n", - __FUNCTION__, seq, rxseq)); - bus->rx_badseq++; - rxseq = seq; - } - - /* Check window for sanity */ - if ((uint8)(txmax - bus->tx_seq) > 0x40) { - DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n", - __FUNCTION__, txmax, bus->tx_seq)); - txmax = bus->tx_seq + 2; - } - bus->tx_max = txmax; - -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) { - prhex("Rx Data", rxbuf, len); - } else if (DHD_HDRS_ON()) { - prhex("RxHdr", bus->rxhdr, SDPCM_HDRLEN); - } -#endif - - if (chan == SDPCM_CONTROL_CHANNEL) { - if (bus->bus == SPI_BUS) { - dhdsdio_read_control(bus, rxbuf, len, doff); - if (bus->usebufpool) { - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(bus->dhd->osh, pkt, FALSE); - dhd_os_sdunlock_rxq(bus->dhd); - } - continue; - } else { - DHD_ERROR(("%s (nextlen): readahead on control" - " packet %d?\n", __FUNCTION__, seq)); - /* Force retry w/normal header read */ - bus->nextlen = 0; - dhdsdio_rxfail(bus, FALSE, TRUE); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - continue; - } - } - - if ((bus->bus == SPI_BUS) && !bus->usebufpool) { - DHD_ERROR(("Received %d bytes on %d channel. Running out of " - "rx pktbuf's or not yet malloced.\n", len, chan)); - continue; - } - - /* Validate data offset */ - if ((doff < SDPCM_HDRLEN) || (doff > len)) { - DHD_ERROR(("%s (nextlen): bad data offset %d: HW len %d min %d\n", - __FUNCTION__, doff, len, SDPCM_HDRLEN)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - ASSERT(0); - dhdsdio_rxfail(bus, FALSE, FALSE); - continue; - } - - /* All done with this one -- now deliver the packet */ - goto deliver; - } - /* gSPI frames should not be handled in fractions */ - if (bus->bus == SPI_BUS) { - break; - } - - /* Read frame header (hardware and software) */ - sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - bus->rxhdr, firstread, NULL, NULL, NULL); - bus->f2rxhdrs++; - ASSERT(sdret != BCME_PENDING); - - if (sdret < 0) { - DHD_ERROR(("%s: RXHEADER FAILED: %d\n", __FUNCTION__, sdret)); - bus->rx_hdrfail++; - dhdsdio_rxfail(bus, TRUE, TRUE); - continue; - } - -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() || DHD_HDRS_ON()) { - prhex("RxHdr", bus->rxhdr, SDPCM_HDRLEN); - } -#endif - - /* Extract hardware header fields */ - len = ltoh16_ua(bus->rxhdr); - check = ltoh16_ua(bus->rxhdr + sizeof(uint16)); - - /* All zeros means no more frames */ - if (!(len|check)) { - *finished = TRUE; - break; - } - - /* Validate check bytes */ - if ((uint16)~(len^check)) { - DHD_ERROR(("%s: HW hdr error: len/check 0x%04x/0x%04x\n", - __FUNCTION__, len, check)); - bus->rx_badhdr++; - dhdsdio_rxfail(bus, FALSE, FALSE); - continue; - } - - /* Validate frame length */ - if (len < SDPCM_HDRLEN) { - DHD_ERROR(("%s: HW hdr length invalid: %d\n", __FUNCTION__, len)); - continue; - } - - /* Extract software header fields */ - chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - - /* Validate data offset */ - if ((doff < SDPCM_HDRLEN) || (doff > len)) { - DHD_ERROR(("%s: Bad data offset %d: HW len %d, min %d seq %d\n", - __FUNCTION__, doff, len, SDPCM_HDRLEN, seq)); - bus->rx_badhdr++; - ASSERT(0); - dhdsdio_rxfail(bus, FALSE, FALSE); - continue; - } - - /* Save the readahead length if there is one */ - bus->nextlen = bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; - if ((bus->nextlen << 4) > MAX_RX_DATASZ) { - DHD_INFO(("%s (nextlen): got frame w/nextlen too large (%d), seq %d\n", - __FUNCTION__, bus->nextlen, seq)); - bus->nextlen = 0; - } - - /* Handle Flow Control */ - fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - - delta = 0; - if (~bus->flowcontrol & fcbits) { - bus->fc_xoff++; - delta = 1; - } - if (bus->flowcontrol & ~fcbits) { - bus->fc_xon++; - delta = 1; - } - - if (delta) { - bus->fc_rcvd++; - bus->flowcontrol = fcbits; - } - - /* Check and update sequence number */ - if (rxseq != seq) { - DHD_INFO(("%s: rx_seq %d, expected %d\n", __FUNCTION__, seq, rxseq)); - bus->rx_badseq++; - rxseq = seq; - } - - /* Check window for sanity */ - if ((uint8)(txmax - bus->tx_seq) > 0x40) { - DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n", - __FUNCTION__, txmax, bus->tx_seq)); - txmax = bus->tx_seq + 2; - } - bus->tx_max = txmax; - - /* Call a separate function for control frames */ - if (chan == SDPCM_CONTROL_CHANNEL) { - dhdsdio_read_control(bus, bus->rxhdr, len, doff); - continue; - } - - ASSERT((chan == SDPCM_DATA_CHANNEL) || (chan == SDPCM_EVENT_CHANNEL) || - (chan == SDPCM_TEST_CHANNEL) || (chan == SDPCM_GLOM_CHANNEL)); - - /* Length to read */ - rdlen = (len > firstread) ? (len - firstread) : 0; - - /* May pad read to blocksize for efficiency */ - if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) { - pad = bus->blocksize - (rdlen % bus->blocksize); - if ((pad <= bus->roundup) && (pad < bus->blocksize) && - ((rdlen + pad + firstread) < MAX_RX_DATASZ)) - rdlen += pad; - } else if (rdlen % DHD_SDALIGN) { - rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN); - } - - /* Satisfy length-alignment requirements */ - if (forcealign && (rdlen & (ALIGNMENT - 1))) - rdlen = ROUNDUP(rdlen, ALIGNMENT); - - if ((rdlen + firstread) > MAX_RX_DATASZ) { - /* Too long -- skip this frame */ - DHD_ERROR(("%s: too long: len %d rdlen %d\n", __FUNCTION__, len, rdlen)); - bus->dhd->rx_errors++; bus->rx_toolong++; - dhdsdio_rxfail(bus, FALSE, FALSE); - continue; - } - - dhd_os_sdlock_rxq(bus->dhd); - if (!(pkt = PKTGET(osh, (rdlen + firstread + DHD_SDALIGN), FALSE))) { - /* Give up on data, request rtx of events */ - DHD_ERROR(("%s: PKTGET failed: rdlen %d chan %d\n", - __FUNCTION__, rdlen, chan)); - bus->dhd->rx_dropped++; - dhd_os_sdunlock_rxq(bus->dhd); - dhdsdio_rxfail(bus, FALSE, RETRYCHAN(chan)); - continue; - } - dhd_os_sdunlock_rxq(bus->dhd); - - ASSERT(!PKTLINK(pkt)); - - /* Leave room for what we already read, and align remainder */ - ASSERT(firstread < (PKTLEN(osh, pkt))); - PKTPULL(osh, pkt, firstread); - PKTALIGN(osh, pkt, rdlen, DHD_SDALIGN); - - /* Read the remaining frame data */ - sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - ((uint8 *)PKTDATA(osh, pkt)), rdlen, pkt, NULL, NULL); - bus->f2rxdata++; - ASSERT(sdret != BCME_PENDING); - - if (sdret < 0) { - DHD_ERROR(("%s: read %d %s bytes failed: %d\n", __FUNCTION__, rdlen, - ((chan == SDPCM_EVENT_CHANNEL) ? "event" : - ((chan == SDPCM_DATA_CHANNEL) ? "data" : "test")), sdret)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(bus->dhd->osh, pkt, FALSE); - dhd_os_sdunlock_rxq(bus->dhd); - bus->dhd->rx_errors++; - dhdsdio_rxfail(bus, TRUE, RETRYCHAN(chan)); - continue; - } - - /* Copy the already-read portion */ - PKTPUSH(osh, pkt, firstread); - bcopy(bus->rxhdr, PKTDATA(osh, pkt), firstread); - -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) { - prhex("Rx Data", PKTDATA(osh, pkt), len); - } -#endif - -deliver: - /* Save superframe descriptor and allocate packet frame */ - if (chan == SDPCM_GLOM_CHANNEL) { - if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) { - DHD_GLOM(("%s: got glom descriptor, %d bytes:\n", - __FUNCTION__, len)); -#ifdef DHD_DEBUG - if (DHD_GLOM_ON()) { - prhex("Glom Data", PKTDATA(osh, pkt), len); - } -#endif - PKTSETLEN(osh, pkt, len); - ASSERT(doff == SDPCM_HDRLEN); - PKTPULL(osh, pkt, SDPCM_HDRLEN); - bus->glomd = pkt; - } else { - DHD_ERROR(("%s: glom superframe w/o descriptor!\n", __FUNCTION__)); - dhdsdio_rxfail(bus, FALSE, FALSE); - } - continue; - } - - /* Fill in packet len and prio, deliver upward */ - PKTSETLEN(osh, pkt, len); - PKTPULL(osh, pkt, doff); - -#ifdef SDTEST - /* Test channel packets are processed separately */ - if (chan == SDPCM_TEST_CHANNEL) { - dhdsdio_testrcv(bus, pkt, seq); - continue; - } -#endif /* SDTEST */ - - if (PKTLEN(osh, pkt) == 0) { - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(bus->dhd->osh, pkt, FALSE); - dhd_os_sdunlock_rxq(bus->dhd); - continue; - } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pkt) != 0) { - DHD_ERROR(("%s: rx protocol error\n", __FUNCTION__)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(bus->dhd->osh, pkt, FALSE); - dhd_os_sdunlock_rxq(bus->dhd); - bus->dhd->rx_errors++; - continue; - } - - - /* Unlock during rx call */ - dhd_os_sdunlock(bus->dhd); - dhd_rx_frame(bus->dhd, ifidx, pkt, 1); - dhd_os_sdlock(bus->dhd); - } - rxcount = maxframes - rxleft; -#ifdef DHD_DEBUG - /* Message if we hit the limit */ - if (!rxleft && !sdtest) - DHD_DATA(("%s: hit rx limit of %d frames\n", __FUNCTION__, maxframes)); - else -#endif /* DHD_DEBUG */ - DHD_DATA(("%s: processed %d frames\n", __FUNCTION__, rxcount)); - /* Back off rxseq if awaiting rtx, update rx_seq */ - if (bus->rxskip) - rxseq--; - bus->rx_seq = rxseq; - - return rxcount; -} - -static uint32 -dhdsdio_hostmail(dhd_bus_t *bus) -{ - sdpcmd_regs_t *regs = bus->regs; - uint32 intstatus = 0; - uint32 hmb_data; - uint8 fcbits; - uint retries = 0; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* Read mailbox data and ack that we did so */ - R_SDREG(hmb_data, ®s->tohostmailboxdata, retries); - if (retries <= retry_limit) - W_SDREG(SMB_INT_ACK, ®s->tosbmailbox, retries); - bus->f1regdata += 2; - - /* Dongle recomposed rx frames, accept them again */ - if (hmb_data & HMB_DATA_NAKHANDLED) { - DHD_INFO(("Dongle reports NAK handled, expect rtx of %d\n", bus->rx_seq)); - if (!bus->rxskip) { - DHD_ERROR(("%s: unexpected NAKHANDLED!\n", __FUNCTION__)); - } - bus->rxskip = FALSE; - intstatus |= I_HMB_FRAME_IND; - } - - /* - * DEVREADY does not occur with gSPI. - */ - if (hmb_data & (HMB_DATA_DEVREADY | HMB_DATA_FWREADY)) { - bus->sdpcm_ver = (hmb_data & HMB_DATA_VERSION_MASK) >> HMB_DATA_VERSION_SHIFT; - if (bus->sdpcm_ver != SDPCM_PROT_VERSION) - DHD_ERROR(("Version mismatch, dongle reports %d, expecting %d\n", - bus->sdpcm_ver, SDPCM_PROT_VERSION)); - else - DHD_INFO(("Dongle ready, protocol version %d\n", bus->sdpcm_ver)); - } - - /* - * Flow Control has been moved into the RX headers and this out of band - * method isn't used any more. Leae this here for possibly remaining backward - * compatible with older dongles - */ - if (hmb_data & HMB_DATA_FC) { - fcbits = (hmb_data & HMB_DATA_FCDATA_MASK) >> HMB_DATA_FCDATA_SHIFT; - - if (fcbits & ~bus->flowcontrol) - bus->fc_xoff++; - if (bus->flowcontrol & ~fcbits) - bus->fc_xon++; - - bus->fc_rcvd++; - bus->flowcontrol = fcbits; - } - - /* Shouldn't be any others */ - if (hmb_data & ~(HMB_DATA_DEVREADY | - HMB_DATA_NAKHANDLED | - HMB_DATA_FC | - HMB_DATA_FWREADY | - HMB_DATA_FCDATA_MASK | - HMB_DATA_VERSION_MASK)) { - DHD_ERROR(("Unknown mailbox data content: 0x%02x\n", hmb_data)); - } - - return intstatus; -} - -bool -dhdsdio_dpc(dhd_bus_t *bus) -{ - bcmsdh_info_t *sdh = bus->sdh; - sdpcmd_regs_t *regs = bus->regs; - uint32 intstatus, newstatus = 0; - uint retries = 0; - uint rxlimit = dhd_rxbound; /* Rx frames to read before resched */ - uint txlimit = dhd_txbound; /* Tx frames to send before resched */ - uint framecnt = 0; /* Temporary counter of tx/rx frames */ - bool rxdone = TRUE; /* Flag for no more read data */ - bool resched = FALSE; /* Flag indicating resched wanted */ - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* Start with leftover status bits */ - intstatus = bus->intstatus; - - dhd_os_sdlock(bus->dhd); - - /* If waiting for HTAVAIL, check status */ - if (bus->clkstate == CLK_PENDING) { - int err; - uint8 clkctl, devctl = 0; - -#ifdef DHD_DEBUG - /* Check for inconsistent device control */ - devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); - if (err) { - DHD_ERROR(("%s: error reading DEVCTL: %d\n", __FUNCTION__, err)); - bus->dhd->busstate = DHD_BUS_DOWN; - } else { - ASSERT(devctl & SBSDIO_DEVCTL_CA_INT_ONLY); - } -#endif /* DHD_DEBUG */ - - /* Read CSR, if clock on switch to AVAIL, else ignore */ - clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); - if (err) { - DHD_ERROR(("%s: error reading CSR: %d\n", __FUNCTION__, err)); - bus->dhd->busstate = DHD_BUS_DOWN; - } - - DHD_INFO(("DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", devctl, clkctl)); - - if (SBSDIO_HTAV(clkctl)) { - devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); - if (err) { - DHD_ERROR(("%s: error reading DEVCTL: %d\n", - __FUNCTION__, err)); - bus->dhd->busstate = DHD_BUS_DOWN; - } - devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); - if (err) { - DHD_ERROR(("%s: error writing DEVCTL: %d\n", - __FUNCTION__, err)); - bus->dhd->busstate = DHD_BUS_DOWN; - } - bus->clkstate = CLK_AVAIL; - } else { - goto clkwait; - } - } - - BUS_WAKE(bus); - - /* Make sure backplane clock is on */ - dhdsdio_clkctl(bus, CLK_AVAIL, TRUE); - if (bus->clkstate == CLK_PENDING) - goto clkwait; - - /* Pending interrupt indicates new device status */ - if (bus->ipend) { - bus->ipend = FALSE; - R_SDREG(newstatus, ®s->intstatus, retries); - bus->f1regdata++; - if (bcmsdh_regfail(bus->sdh)) - newstatus = 0; - newstatus &= bus->hostintmask; - bus->fcstate = !!(newstatus & I_HMB_FC_STATE); - if (newstatus) { - W_SDREG(newstatus, ®s->intstatus, retries); - bus->f1regdata++; - } - } - - /* Merge new bits with previous */ - intstatus |= newstatus; - bus->intstatus = 0; - - /* Handle flow-control change: read new state in case our ack - * crossed another change interrupt. If change still set, assume - * FC ON for safety, let next loop through do the debounce. - */ - if (intstatus & I_HMB_FC_CHANGE) { - intstatus &= ~I_HMB_FC_CHANGE; - W_SDREG(I_HMB_FC_CHANGE, ®s->intstatus, retries); - R_SDREG(newstatus, ®s->intstatus, retries); - bus->f1regdata += 2; - bus->fcstate = !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)); - intstatus |= (newstatus & bus->hostintmask); - } - - /* Handle host mailbox indication */ - if (intstatus & I_HMB_HOST_INT) { - intstatus &= ~I_HMB_HOST_INT; - intstatus |= dhdsdio_hostmail(bus); - } - - /* Generally don't ask for these, can get CRC errors... */ - if (intstatus & I_WR_OOSYNC) { - DHD_ERROR(("Dongle reports WR_OOSYNC\n")); - intstatus &= ~I_WR_OOSYNC; - } - - if (intstatus & I_RD_OOSYNC) { - DHD_ERROR(("Dongle reports RD_OOSYNC\n")); - intstatus &= ~I_RD_OOSYNC; - } - - if (intstatus & I_SBINT) { - DHD_ERROR(("Dongle reports SBINT\n")); - intstatus &= ~I_SBINT; - } - - /* Would be active due to wake-wlan in gSPI */ - if (intstatus & I_CHIPACTIVE) { - DHD_INFO(("Dongle reports CHIPACTIVE\n")); - intstatus &= ~I_CHIPACTIVE; - } - - /* Ignore frame indications if rxskip is set */ - if (bus->rxskip) - intstatus &= ~I_HMB_FRAME_IND; - - /* On frame indication, read available frames */ - if (PKT_AVAILABLE()) { - framecnt = dhdsdio_readframes(bus, rxlimit, &rxdone); - if (rxdone || bus->rxskip) - intstatus &= ~I_HMB_FRAME_IND; - rxlimit -= MIN(framecnt, rxlimit); - } - - /* Keep still-pending events for next scheduling */ - bus->intstatus = intstatus; - -clkwait: - /* Re-enable interrupts to detect new device events (mailbox, rx frame) - * or clock availability. (Allows tx loop to check ipend if desired.) - * (Unless register access seems hosed, as we may not be able to ACK...) - */ - if (bus->intr && bus->intdis && !bcmsdh_regfail(sdh)) { - DHD_INTR(("%s: enable SDIO interrupts, rxdone %d framecnt %d\n", - __FUNCTION__, rxdone, framecnt)); - bus->intdis = FALSE; -#if defined(OOB_INTR_ONLY) - bcmsdh_oob_intr_set(1); -#endif /* (OOB_INTR_ONLY) */ - bcmsdh_intr_enable(sdh); - } - - if (DATAOK(bus) && bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL)) { - int ret, i; - - ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - (uint8 *)bus->ctrl_frame_buf, (uint32)bus->ctrl_frame_len, - NULL, NULL, NULL); - ASSERT(ret != BCME_PENDING); - - if (ret < 0) { - /* On failure, abort the command and terminate the frame */ - DHD_INFO(("%s: sdio error %d, abort command and terminate frame.\n", - __FUNCTION__, ret)); - bus->tx_sderrs++; - - bcmsdh_abort(sdh, SDIO_FUNC_2); - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, - SFC_WF_TERM, NULL); - bus->f1regdata++; - - for (i = 0; i < 3; i++) { - uint8 hi, lo; - hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCLO, NULL); - bus->f1regdata += 2; - if ((hi == 0) && (lo == 0)) - break; - } - - } - if (ret == 0) { - bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; - } - - printf("Return_dpc value is : %d\n", ret); - bus->ctrl_frame_stat = FALSE; - dhd_wait_event_wakeup(bus->dhd); - } - /* Send queued frames (limit 1 if rx may still be pending) */ - else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate && - pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit && DATAOK(bus)) { - framecnt = rxdone ? txlimit : MIN(txlimit, dhd_txminmax); - framecnt = dhdsdio_sendfromq(bus, framecnt); - txlimit -= framecnt; - } - - /* Resched if events or tx frames are pending, else await next interrupt */ - /* On failed register access, all bets are off: no resched or interrupts */ - if ((bus->dhd->busstate == DHD_BUS_DOWN) || bcmsdh_regfail(sdh)) { - DHD_ERROR(("%s: failed backplane access over SDIO, halting operation %d \n", - __FUNCTION__, bcmsdh_regfail(sdh))); - bus->dhd->busstate = DHD_BUS_DOWN; - bus->intstatus = 0; - } else if (bus->clkstate == CLK_PENDING) { - DHD_INFO(("%s: rescheduled due to CLK_PENDING awaiting \ - I_CHIPACTIVE interrupt", __FUNCTION__)); - resched = TRUE; - } else if (bus->intstatus || bus->ipend || - (!bus->fcstate && pktq_mlen(&bus->txq, ~bus->flowcontrol) && DATAOK(bus)) || - PKT_AVAILABLE()) { /* Read multiple frames */ - resched = TRUE; - } - - - bus->dpc_sched = resched; - - /* If we're done for now, turn off clock request. */ - if ((bus->clkstate != CLK_PENDING) && bus->idletime == DHD_IDLE_IMMEDIATE) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, FALSE); - } - - dhd_os_sdunlock(bus->dhd); - - return resched; -} - -bool -dhd_bus_dpc(struct dhd_bus *bus) -{ - bool resched; - - /* Call the DPC directly. */ - DHD_TRACE(("Calling dhdsdio_dpc() from %s\n", __FUNCTION__)); - resched = dhdsdio_dpc(bus); - - return resched; -} - -void -dhdsdio_isr(void *arg) -{ - dhd_bus_t *bus = (dhd_bus_t*)arg; - bcmsdh_info_t *sdh; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (!bus) { - DHD_ERROR(("%s : bus is null pointer , exit \n", __FUNCTION__)); - return; - } - sdh = bus->sdh; - - if (bus->dhd->busstate == DHD_BUS_DOWN) { - DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__)); - return; - } - /* Count the interrupt call */ - bus->intrcount++; - bus->ipend = TRUE; - - /* Shouldn't get this interrupt if we're sleeping? */ - if (bus->sleeping) { - DHD_ERROR(("INTERRUPT WHILE SLEEPING??\n")); - return; - } - - /* Disable additional interrupts (is this needed now)? */ - if (bus->intr) { - DHD_INTR(("%s: disable SDIO interrupts\n", __FUNCTION__)); - } else { - DHD_ERROR(("dhdsdio_isr() w/o interrupt configured!\n")); - } - - bcmsdh_intr_disable(sdh); - bus->intdis = TRUE; - -#if defined(SDIO_ISR_THREAD) - DHD_TRACE(("Calling dhdsdio_dpc() from %s\n", __FUNCTION__)); - dhd_os_wake_lock(bus->dhd); - while (dhdsdio_dpc(bus)); - dhd_os_wake_unlock(bus->dhd); -#else - bus->dpc_sched = TRUE; - dhd_sched_dpc(bus->dhd); -#endif - -} - -#ifdef SDTEST -static void -dhdsdio_pktgen_init(dhd_bus_t *bus) -{ - /* Default to specified length, or full range */ - if (dhd_pktgen_len) { - bus->pktgen_maxlen = MIN(dhd_pktgen_len, MAX_PKTGEN_LEN); - bus->pktgen_minlen = bus->pktgen_maxlen; - } else { - bus->pktgen_maxlen = MAX_PKTGEN_LEN; - bus->pktgen_minlen = 0; - } - bus->pktgen_len = (uint16)bus->pktgen_minlen; - - /* Default to per-watchdog burst with 10s print time */ - bus->pktgen_freq = 1; - bus->pktgen_print = 10000 / dhd_watchdog_ms; - bus->pktgen_count = (dhd_pktgen * dhd_watchdog_ms + 999) / 1000; - - /* Default to echo mode */ - bus->pktgen_mode = DHD_PKTGEN_ECHO; - bus->pktgen_stop = 1; -} - -static void -dhdsdio_pktgen(dhd_bus_t *bus) -{ - void *pkt; - uint8 *data; - uint pktcount; - uint fillbyte; - osl_t *osh = bus->dhd->osh; - uint16 len; - - /* Display current count if appropriate */ - if (bus->pktgen_print && (++bus->pktgen_ptick >= bus->pktgen_print)) { - bus->pktgen_ptick = 0; - printf("%s: send attempts %d rcvd %d\n", - __FUNCTION__, bus->pktgen_sent, bus->pktgen_rcvd); - } - - /* For recv mode, just make sure dongle has started sending */ - if (bus->pktgen_mode == DHD_PKTGEN_RECV) { - if (!bus->pktgen_rcvd) - dhdsdio_sdtest_set(bus, TRUE); - return; - } - - /* Otherwise, generate or request the specified number of packets */ - for (pktcount = 0; pktcount < bus->pktgen_count; pktcount++) { - /* Stop if total has been reached */ - if (bus->pktgen_total && (bus->pktgen_sent >= bus->pktgen_total)) { - bus->pktgen_count = 0; - break; - } - - /* Allocate an appropriate-sized packet */ - len = bus->pktgen_len; - if (!(pkt = PKTGET(osh, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN), - TRUE))) {; - DHD_ERROR(("%s: PKTGET failed!\n", __FUNCTION__)); - break; - } - PKTALIGN(osh, pkt, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN); - data = (uint8*)PKTDATA(osh, pkt) + SDPCM_HDRLEN; - - /* Write test header cmd and extra based on mode */ - switch (bus->pktgen_mode) { - case DHD_PKTGEN_ECHO: - *data++ = SDPCM_TEST_ECHOREQ; - *data++ = (uint8)bus->pktgen_sent; - break; - - case DHD_PKTGEN_SEND: - *data++ = SDPCM_TEST_DISCARD; - *data++ = (uint8)bus->pktgen_sent; - break; - - case DHD_PKTGEN_RXBURST: - *data++ = SDPCM_TEST_BURST; - *data++ = (uint8)bus->pktgen_count; - break; - - default: - DHD_ERROR(("Unrecognized pktgen mode %d\n", bus->pktgen_mode)); - PKTFREE(osh, pkt, TRUE); - bus->pktgen_count = 0; - return; - } - - /* Write test header length field */ - *data++ = (len >> 0); - *data++ = (len >> 8); - - /* Then fill in the remainder -- N/A for burst, but who cares... */ - for (fillbyte = 0; fillbyte < len; fillbyte++) - *data++ = SDPCM_TEST_FILL(fillbyte, (uint8)bus->pktgen_sent); - -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) { - data = (uint8*)PKTDATA(osh, pkt) + SDPCM_HDRLEN; - prhex("dhdsdio_pktgen: Tx Data", data, PKTLEN(osh, pkt) - SDPCM_HDRLEN); - } -#endif - - /* Send it */ - if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, TRUE)) { - bus->pktgen_fail++; - if (bus->pktgen_stop && bus->pktgen_stop == bus->pktgen_fail) - bus->pktgen_count = 0; - } - bus->pktgen_sent++; - - /* Bump length if not fixed, wrap at max */ - if (++bus->pktgen_len > bus->pktgen_maxlen) - bus->pktgen_len = (uint16)bus->pktgen_minlen; - - /* Special case for burst mode: just send one request! */ - if (bus->pktgen_mode == DHD_PKTGEN_RXBURST) - break; - } -} - -static void -dhdsdio_sdtest_set(dhd_bus_t *bus, bool start) -{ - void *pkt; - uint8 *data; - osl_t *osh = bus->dhd->osh; - - /* Allocate the packet */ - if (!(pkt = PKTGET(osh, SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN, TRUE))) { - DHD_ERROR(("%s: PKTGET failed!\n", __FUNCTION__)); - return; - } - PKTALIGN(osh, pkt, (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN); - data = (uint8*)PKTDATA(osh, pkt) + SDPCM_HDRLEN; - - /* Fill in the test header */ - *data++ = SDPCM_TEST_SEND; - *data++ = start; - *data++ = (bus->pktgen_maxlen >> 0); - *data++ = (bus->pktgen_maxlen >> 8); - - /* Send it */ - if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, TRUE)) - bus->pktgen_fail++; -} - - -static void -dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq) -{ - osl_t *osh = bus->dhd->osh; - uint8 *data; - uint pktlen; - - uint8 cmd; - uint8 extra; - uint16 len; - uint16 offset; - - /* Check for min length */ - if ((pktlen = PKTLEN(osh, pkt)) < SDPCM_TEST_HDRLEN) { - DHD_ERROR(("dhdsdio_restrcv: toss runt frame, pktlen %d\n", pktlen)); - PKTFREE(osh, pkt, FALSE); - return; - } - - /* Extract header fields */ - data = PKTDATA(osh, pkt); - cmd = *data++; - extra = *data++; - len = *data++; len += *data++ << 8; - - /* Check length for relevant commands */ - if (cmd == SDPCM_TEST_DISCARD || cmd == SDPCM_TEST_ECHOREQ || cmd == SDPCM_TEST_ECHORSP) { - if (pktlen != len + SDPCM_TEST_HDRLEN) { - DHD_ERROR(("dhdsdio_testrcv: frame length mismatch, pktlen %d seq %d" - " cmd %d extra %d len %d\n", pktlen, seq, cmd, extra, len)); - PKTFREE(osh, pkt, FALSE); - return; - } - } - - /* Process as per command */ - switch (cmd) { - case SDPCM_TEST_ECHOREQ: - /* Rx->Tx turnaround ok (even on NDIS w/current implementation) */ - *(uint8 *)(PKTDATA(osh, pkt)) = SDPCM_TEST_ECHORSP; - if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, TRUE) == 0) { - bus->pktgen_sent++; - } else { - bus->pktgen_fail++; - PKTFREE(osh, pkt, FALSE); - } - bus->pktgen_rcvd++; - break; - - case SDPCM_TEST_ECHORSP: - if (bus->ext_loop) { - PKTFREE(osh, pkt, FALSE); - bus->pktgen_rcvd++; - break; - } - - for (offset = 0; offset < len; offset++, data++) { - if (*data != SDPCM_TEST_FILL(offset, extra)) { - DHD_ERROR(("dhdsdio_testrcv: echo data mismatch: " - "offset %d (len %d) expect 0x%02x rcvd 0x%02x\n", - offset, len, SDPCM_TEST_FILL(offset, extra), *data)); - break; - } - } - PKTFREE(osh, pkt, FALSE); - bus->pktgen_rcvd++; - break; - - case SDPCM_TEST_DISCARD: - PKTFREE(osh, pkt, FALSE); - bus->pktgen_rcvd++; - break; - - case SDPCM_TEST_BURST: - case SDPCM_TEST_SEND: - default: - DHD_INFO(("dhdsdio_testrcv: unsupported or unknown command, pktlen %d seq %d" - " cmd %d extra %d len %d\n", pktlen, seq, cmd, extra, len)); - PKTFREE(osh, pkt, FALSE); - break; - } - - /* For recv mode, stop at limie (and tell dongle to stop sending) */ - if (bus->pktgen_mode == DHD_PKTGEN_RECV) { - if (bus->pktgen_total && (bus->pktgen_rcvd >= bus->pktgen_total)) { - bus->pktgen_count = 0; - dhdsdio_sdtest_set(bus, FALSE); - } - } -} -#endif /* SDTEST */ - -extern bool -dhd_bus_watchdog(dhd_pub_t *dhdp) -{ - dhd_bus_t *bus; - - DHD_TIMER(("%s: Enter\n", __FUNCTION__)); - - bus = dhdp->bus; - - if (bus->dhd->dongle_reset) - return FALSE; - - /* Ignore the timer if simulating bus down */ - if (bus->sleeping) - return FALSE; - - /* Poll period: check device if appropriate. */ - if (bus->poll && (++bus->polltick >= bus->pollrate)) { - uint32 intstatus = 0; - - /* Reset poll tick */ - bus->polltick = 0; - - /* Check device if no interrupts */ - if (!bus->intr || (bus->intrcount == bus->lastintrs)) { - - if (!bus->dpc_sched) { - uint8 devpend; - devpend = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, - SDIOD_CCCR_INTPEND, NULL); - intstatus = devpend & (INTR_STATUS_FUNC1 | INTR_STATUS_FUNC2); - } - - /* If there is something, make like the ISR and schedule the DPC */ - if (intstatus) { - bus->pollcnt++; - bus->ipend = TRUE; - if (bus->intr) { - bcmsdh_intr_disable(bus->sdh); - } - bus->dpc_sched = TRUE; - dhd_sched_dpc(bus->dhd); - - } - } - - /* Update interrupt tracking */ - bus->lastintrs = bus->intrcount; - } - -#ifdef DHD_DEBUG - /* Poll for console output periodically */ - if (dhdp->busstate == DHD_BUS_DATA && dhd_console_ms != 0) { - bus->console.count += dhd_watchdog_ms; - if (bus->console.count >= dhd_console_ms) { - bus->console.count -= dhd_console_ms; - /* Make sure backplane clock is on */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - if (dhdsdio_readconsole(bus) < 0) - dhd_console_ms = 0; /* On error, stop trying */ - } - } -#endif /* DHD_DEBUG */ - -#ifdef SDTEST - /* Generate packets if configured */ - if (bus->pktgen_count && (++bus->pktgen_tick >= bus->pktgen_freq)) { - /* Make sure backplane clock is on */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - bus->pktgen_tick = 0; - dhdsdio_pktgen(bus); - } -#endif - - /* On idle timeout clear activity flag and/or turn off clock */ - if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) { - if (++bus->idlecount >= bus->idletime) { - bus->idlecount = 0; - if (bus->activity) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, FALSE); - } - } - } - - return bus->ipend; -} - -#ifdef DHD_DEBUG -extern int -dhd_bus_console_in(dhd_pub_t *dhdp, uchar *msg, uint msglen) -{ - dhd_bus_t *bus = dhdp->bus; - uint32 addr, val; - int rv; - void *pkt; - - /* Address could be zero if CONSOLE := 0 in dongle Makefile */ - if (bus->console_addr == 0) - return BCME_UNSUPPORTED; - - /* Exclusive bus access */ - dhd_os_sdlock(bus->dhd); - - /* Don't allow input if dongle is in reset */ - if (bus->dhd->dongle_reset) { - dhd_os_sdunlock(bus->dhd); - return BCME_NOTREADY; - } - - /* Request clock to allow SDIO accesses */ - BUS_WAKE(bus); - /* No pend allowed since txpkt is called later, ht clk has to be on */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - /* Zero cbuf_index */ - addr = bus->console_addr + OFFSETOF(hndrte_cons_t, cbuf_idx); - val = htol32(0); - if ((rv = dhdsdio_membytes(bus, TRUE, addr, (uint8 *)&val, sizeof(val))) < 0) - goto done; - - /* Write message into cbuf */ - addr = bus->console_addr + OFFSETOF(hndrte_cons_t, cbuf); - if ((rv = dhdsdio_membytes(bus, TRUE, addr, (uint8 *)msg, msglen)) < 0) - goto done; - - /* Write length into vcons_in */ - addr = bus->console_addr + OFFSETOF(hndrte_cons_t, vcons_in); - val = htol32(msglen); - if ((rv = dhdsdio_membytes(bus, TRUE, addr, (uint8 *)&val, sizeof(val))) < 0) - goto done; - - /* Bump dongle by sending an empty event pkt. - * sdpcm_sendup (RX) checks for virtual console input. - */ - if (((pkt = PKTGET(bus->dhd->osh, 4 + SDPCM_RESERVE, TRUE)) != NULL) && - bus->clkstate == CLK_AVAIL) - dhdsdio_txpkt(bus, pkt, SDPCM_EVENT_CHANNEL, TRUE); - -done: - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, TRUE); - } - - dhd_os_sdunlock(bus->dhd); - - return rv; -} -#endif /* DHD_DEBUG */ - -#ifdef DHD_DEBUG -static void -dhd_dump_cis(uint fn, uint8 *cis) -{ - uint byte, tag, tdata; - DHD_INFO(("Function %d CIS:\n", fn)); - - for (tdata = byte = 0; byte < SBSDIO_CIS_SIZE_LIMIT; byte++) { - if ((byte % 16) == 0) - DHD_INFO((" ")); - DHD_INFO(("%02x ", cis[byte])); - if ((byte % 16) == 15) - DHD_INFO(("\n")); - if (!tdata--) { - tag = cis[byte]; - if (tag == 0xff) - break; - else if (!tag) - tdata = 0; - else if ((byte + 1) < SBSDIO_CIS_SIZE_LIMIT) - tdata = cis[byte + 1] + 1; - else - DHD_INFO(("]")); - } - } - if ((byte % 16) != 15) - DHD_INFO(("\n")); -} -#endif /* DHD_DEBUG */ - -static bool -dhdsdio_chipmatch(uint16 chipid) -{ - if (chipid == BCM4325_CHIP_ID) - return TRUE; - if (chipid == BCM4329_CHIP_ID) - return TRUE; - if (chipid == BCM4315_CHIP_ID) - return TRUE; - if (chipid == BCM4319_CHIP_ID) - return TRUE; - return FALSE; -} - -static void * -dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot, - uint16 func, uint bustype, void *regsva, osl_t * osh, void *sdh) -{ - int ret; - dhd_bus_t *bus; - - /* Init global variables at run-time, not as part of the declaration. - * This is required to support init/de-init of the driver. Initialization - * of globals as part of the declaration results in non-deterministic - * behavior since the value of the globals may be different on the - * first time that the driver is initialized vs subsequent initializations. - */ - dhd_txbound = DHD_TXBOUND; - dhd_rxbound = DHD_RXBOUND; - dhd_alignctl = TRUE; - sd1idle = TRUE; - dhd_readahead = TRUE; - retrydata = FALSE; - dhd_doflow = FALSE; - dhd_dongle_memsize = 0; - dhd_txminmax = DHD_TXMINMAX; - - forcealign = TRUE; - - - dhd_common_init(); - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - DHD_INFO(("%s: venid 0x%04x devid 0x%04x\n", __FUNCTION__, venid, devid)); - - /* We make assumptions about address window mappings */ - ASSERT((uintptr)regsva == SI_ENUM_BASE); - - /* BCMSDH passes venid and devid based on CIS parsing -- but low-power start - * means early parse could fail, so here we should get either an ID - * we recognize OR (-1) indicating we must request power first. - */ - /* Check the Vendor ID */ - switch (venid) { - case 0x0000: - case VENDOR_BROADCOM: - break; - default: - DHD_ERROR(("%s: unknown vendor: 0x%04x\n", - __FUNCTION__, venid)); - return NULL; - } - - /* Check the Device ID and make sure it's one that we support */ - switch (devid) { - case BCM4325_D11DUAL_ID: /* 4325 802.11a/g id */ - case BCM4325_D11G_ID: /* 4325 802.11g 2.4Ghz band id */ - case BCM4325_D11A_ID: /* 4325 802.11a 5Ghz band id */ - DHD_INFO(("%s: found 4325 Dongle\n", __FUNCTION__)); - break; - case BCM4329_D11NDUAL_ID: /* 4329 802.11n dualband device */ - case BCM4329_D11N2G_ID: /* 4329 802.11n 2.4G device */ - case BCM4329_D11N5G_ID: /* 4329 802.11n 5G device */ - case 0x4329: - DHD_INFO(("%s: found 4329 Dongle\n", __FUNCTION__)); - break; - case BCM4315_D11DUAL_ID: /* 4315 802.11a/g id */ - case BCM4315_D11G_ID: /* 4315 802.11g id */ - case BCM4315_D11A_ID: /* 4315 802.11a id */ - DHD_INFO(("%s: found 4315 Dongle\n", __FUNCTION__)); - break; - case BCM4319_D11N_ID: /* 4319 802.11n id */ - case BCM4319_D11N2G_ID: /* 4319 802.11n2g id */ - case BCM4319_D11N5G_ID: /* 4319 802.11n5g id */ - DHD_INFO(("%s: found 4319 Dongle\n", __FUNCTION__)); - break; - case 0: - DHD_INFO(("%s: allow device id 0, will check chip internals\n", - __FUNCTION__)); - break; - - default: - DHD_ERROR(("%s: skipping 0x%04x/0x%04x, not a dongle\n", - __FUNCTION__, venid, devid)); - return NULL; - } - - if (osh == NULL) { - /* Ask the OS interface part for an OSL handle */ - if (!(osh = dhd_osl_attach(sdh, DHD_BUS))) { - DHD_ERROR(("%s: osl_attach failed!\n", __FUNCTION__)); - return NULL; - } - } - - /* Allocate private bus interface state */ - if (!(bus = MALLOC(osh, sizeof(dhd_bus_t)))) { - DHD_ERROR(("%s: MALLOC of dhd_bus_t failed\n", __FUNCTION__)); - goto fail; - } - bzero(bus, sizeof(dhd_bus_t)); - bus->sdh = sdh; - bus->cl_devid = (uint16)devid; - bus->bus = DHD_BUS; - bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1; - bus->usebufpool = FALSE; /* Use bufpool if allocated, else use locally malloced rxbuf */ - - /* attempt to attach to the dongle */ - if (!(dhdsdio_probe_attach(bus, osh, sdh, regsva, devid))) { - DHD_ERROR(("%s: dhdsdio_probe_attach failed\n", __FUNCTION__)); - goto fail; - } - - /* Attach to the dhd/OS/network interface */ - if (!(bus->dhd = dhd_attach(osh, bus, SDPCM_RESERVE))) { - DHD_ERROR(("%s: dhd_attach failed\n", __FUNCTION__)); - goto fail; - } - - /* Allocate buffers */ - if (!(dhdsdio_probe_malloc(bus, osh, sdh))) { - DHD_ERROR(("%s: dhdsdio_probe_malloc failed\n", __FUNCTION__)); - goto fail; - } - - if (!(dhdsdio_probe_init(bus, osh, sdh))) { - DHD_ERROR(("%s: dhdsdio_probe_init failed\n", __FUNCTION__)); - goto fail; - } - - /* Register interrupt callback, but mask it (not operational yet). */ - DHD_INTR(("%s: disable SDIO interrupts (not interested yet)\n", __FUNCTION__)); - bcmsdh_intr_disable(sdh); - if ((ret = bcmsdh_intr_reg(sdh, dhdsdio_isr, bus)) != 0) { - DHD_ERROR(("%s: FAILED: bcmsdh_intr_reg returned %d\n", - __FUNCTION__, ret)); - goto fail; - } - DHD_INTR(("%s: registered SDIO interrupt function ok\n", __FUNCTION__)); - - DHD_INFO(("%s: completed!!\n", __FUNCTION__)); - - - /* if firmware path present try to download and bring up bus */ - if ((ret = dhd_bus_start(bus->dhd)) != 0) { -#if 1 - DHD_ERROR(("%s: failed\n", __FUNCTION__)); - goto fail; -#else - if (ret == BCME_NOTUP) { - DHD_ERROR(("%s: dongle is not responding\n", __FUNCTION__)); - goto fail; - } -#endif - } - /* Ok, have the per-port tell the stack we're open for business */ - if (dhd_net_attach(bus->dhd, 0) != 0) { - DHD_ERROR(("%s: Net attach failed!!\n", __FUNCTION__)); - goto fail; - } - - return bus; - -fail: - dhdsdio_release(bus, osh); - return NULL; -} - - -static bool -dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva, - uint16 devid) -{ - uint8 clkctl = 0; - int err = 0; - - bus->alp_only = TRUE; - - /* Return the window to backplane enumeration space for core access */ - if (dhdsdio_set_siaddr_window(bus, SI_ENUM_BASE)) { - DHD_ERROR(("%s: FAILED to return to SI_ENUM_BASE\n", __FUNCTION__)); - } - -#ifdef DHD_DEBUG - printf("F1 signature read @0x18000000=0x%4x\n", - bcmsdh_reg_read(bus->sdh, SI_ENUM_BASE, 4)); - - -#endif /* DHD_DEBUG */ - - - /* Force PLL off until si_attach() programs PLL control regs */ - - - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, DHD_INIT_CLKCTL1, &err); - if (!err) - clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); - - if (err || ((clkctl & ~SBSDIO_AVBITS) != DHD_INIT_CLKCTL1)) { - DHD_ERROR(("dhdsdio_probe: ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n", - err, DHD_INIT_CLKCTL1, clkctl)); - goto fail; - } - - -#ifdef DHD_DEBUG - if (DHD_INFO_ON()) { - uint fn, numfn; - uint8 *cis[SDIOD_MAX_IOFUNCS]; - int err = 0; - - numfn = bcmsdh_query_iofnum(sdh); - ASSERT(numfn <= SDIOD_MAX_IOFUNCS); - - /* Make sure ALP is available before trying to read CIS */ - SPINWAIT(((clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_CHIPCLKCSR, NULL)), - !SBSDIO_ALPAV(clkctl)), PMU_MAX_TRANSITION_DLY); - - /* Now request ALP be put on the bus */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - DHD_INIT_CLKCTL2, &err); - OSL_DELAY(65); - - for (fn = 0; fn <= numfn; fn++) { - if (!(cis[fn] = MALLOC(osh, SBSDIO_CIS_SIZE_LIMIT))) { - DHD_INFO(("dhdsdio_probe: fn %d cis malloc failed\n", fn)); - break; - } - bzero(cis[fn], SBSDIO_CIS_SIZE_LIMIT); - - if ((err = bcmsdh_cis_read(sdh, fn, cis[fn], SBSDIO_CIS_SIZE_LIMIT))) { - DHD_INFO(("dhdsdio_probe: fn %d cis read err %d\n", fn, err)); - MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT); - break; - } - dhd_dump_cis(fn, cis[fn]); - } - - while (fn-- > 0) { - ASSERT(cis[fn]); - MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT); - } - - if (err) { - DHD_ERROR(("dhdsdio_probe: failure reading or parsing CIS\n")); - goto fail; - } - } -#endif /* DHD_DEBUG */ - - /* si_attach() will provide an SI handle and scan the backplane */ - if (!(bus->sih = si_attach((uint)devid, osh, regsva, DHD_BUS, sdh, - &bus->vars, &bus->varsz))) { - DHD_ERROR(("%s: si_attach failed!\n", __FUNCTION__)); - goto fail; - } - - bcmsdh_chipinfo(sdh, bus->sih->chip, bus->sih->chiprev); - - if (!dhdsdio_chipmatch((uint16)bus->sih->chip)) { - DHD_ERROR(("%s: unsupported chip: 0x%04x\n", - __FUNCTION__, bus->sih->chip)); - goto fail; - } - - si_sdiod_drive_strength_init(bus->sih, osh, dhd_sdiod_drive_strength); - - - /* Get info on the ARM and SOCRAM cores... */ - if (!DHD_NOPMU(bus)) { - if ((si_setcore(bus->sih, ARM7S_CORE_ID, 0)) || - (si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) { - bus->armrev = si_corerev(bus->sih); - } else { - DHD_ERROR(("%s: failed to find ARM core!\n", __FUNCTION__)); - goto fail; - } - if (!(bus->orig_ramsize = si_socram_size(bus->sih))) { - DHD_ERROR(("%s: failed to find SOCRAM memory!\n", __FUNCTION__)); - goto fail; - } - bus->ramsize = bus->orig_ramsize; - if (dhd_dongle_memsize) - dhd_dongle_setmemsize(bus, dhd_dongle_memsize); - - DHD_ERROR(("DHD: dongle ram size is set to %d(orig %d)\n", - bus->ramsize, bus->orig_ramsize)); - } - - /* ...but normally deal with the SDPCMDEV core */ - if (!(bus->regs = si_setcore(bus->sih, PCMCIA_CORE_ID, 0)) && - !(bus->regs = si_setcore(bus->sih, SDIOD_CORE_ID, 0))) { - DHD_ERROR(("%s: failed to find SDIODEV core!\n", __FUNCTION__)); - goto fail; - } - bus->sdpcmrev = si_corerev(bus->sih); - - /* Set core control so an SDIO reset does a backplane reset */ - OR_REG(osh, &bus->regs->corecontrol, CC_BPRESEN); - - pktq_init(&bus->txq, (PRIOMASK + 1), QLEN); - - /* Locate an appropriately-aligned portion of hdrbuf */ - bus->rxhdr = (uint8 *)ROUNDUP((uintptr)&bus->hdrbuf[0], DHD_SDALIGN); - - /* Set the poll and/or interrupt flags */ - bus->intr = (bool)dhd_intr; - if ((bus->poll = (bool)dhd_poll)) - bus->pollrate = 1; - - return TRUE; - -fail: - return FALSE; -} - -static bool -dhdsdio_probe_malloc(dhd_bus_t *bus, osl_t *osh, void *sdh) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - -#ifndef DHD_USE_STATIC_BUF - if (bus->dhd->maxctl) { - bus->rxblen = ROUNDUP((bus->dhd->maxctl + SDPCM_HDRLEN), ALIGNMENT) + DHD_SDALIGN; - if (!(bus->rxbuf = MALLOC(osh, bus->rxblen))) { - DHD_ERROR(("%s: MALLOC of %d-byte rxbuf failed\n", - __FUNCTION__, bus->rxblen)); - goto fail; - } - } - - /* Allocate buffer to receive glomed packet */ - if (!(bus->databuf = MALLOC(osh, MAX_DATA_BUF))) { - DHD_ERROR(("%s: MALLOC of %d-byte databuf failed\n", - __FUNCTION__, MAX_DATA_BUF)); - /* release rxbuf which was already located as above */ - if (!bus->rxblen) MFREE(osh, bus->rxbuf, bus->rxblen); - goto fail; - } -#else - if (bus->dhd->maxctl) { - bus->rxblen = ROUNDUP((bus->dhd->maxctl + SDPCM_HDRLEN), ALIGNMENT) + DHD_SDALIGN; - if (!(bus->rxbuf = dhd_os_prealloc(DHD_PREALLOC_RXBUF, bus->rxblen))) { - DHD_ERROR(("%s: MALLOC of %d-byte rxbuf failed\n", - __FUNCTION__, bus->rxblen)); - goto fail; - } - } - /* Allocate buffer to receive glomed packet */ - if (!(bus->databuf = dhd_os_prealloc(DHD_PREALLOC_DATABUF, MAX_DATA_BUF))) { - DHD_ERROR(("%s: MALLOC of %d-byte databuf failed\n", - __FUNCTION__, MAX_DATA_BUF)); - goto fail; - } -#endif /* DHD_USE_STATIC_BUF */ - - /* Align the buffer */ - if ((uintptr)bus->databuf % DHD_SDALIGN) - bus->dataptr = bus->databuf + (DHD_SDALIGN - ((uintptr)bus->databuf % DHD_SDALIGN)); - else - bus->dataptr = bus->databuf; - - return TRUE; - -fail: - return FALSE; -} - - -static bool -dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh) -{ - int32 fnum; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - -#ifdef SDTEST - dhdsdio_pktgen_init(bus); -#endif /* SDTEST */ - - /* Disable F2 to clear any intermediate frame state on the dongle */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, SDIO_FUNC_ENABLE_1, NULL); - - bus->dhd->busstate = DHD_BUS_DOWN; - bus->sleeping = FALSE; - bus->rxflow = FALSE; - bus->prev_rxlim_hit = 0; - - - /* Done with backplane-dependent accesses, can drop clock... */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); - - /* ...and initialize clock/power states */ - bus->clkstate = CLK_SDONLY; - bus->idletime = (int32)dhd_idletime; - bus->idleclock = DHD_IDLE_ACTIVE; - - /* Query the SD clock speed */ - if (bcmsdh_iovar_op(sdh, "sd_divisor", NULL, 0, - &bus->sd_divisor, sizeof(int32), FALSE) != BCME_OK) { - DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__, "sd_divisor")); - bus->sd_divisor = -1; - } else { - DHD_INFO(("%s: Initial value for %s is %d\n", - __FUNCTION__, "sd_divisor", bus->sd_divisor)); - } - - /* Query the SD bus mode */ - if (bcmsdh_iovar_op(sdh, "sd_mode", NULL, 0, - &bus->sd_mode, sizeof(int32), FALSE) != BCME_OK) { - DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__, "sd_mode")); - bus->sd_mode = -1; - } else { - DHD_INFO(("%s: Initial value for %s is %d\n", - __FUNCTION__, "sd_mode", bus->sd_mode)); - } - - /* Query the F2 block size, set roundup accordingly */ - fnum = 2; - if (bcmsdh_iovar_op(sdh, "sd_blocksize", &fnum, sizeof(int32), - &bus->blocksize, sizeof(int32), FALSE) != BCME_OK) { - bus->blocksize = 0; - DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__, "sd_blocksize")); - } else { - DHD_INFO(("%s: Initial value for %s is %d\n", - __FUNCTION__, "sd_blocksize", bus->blocksize)); - } - bus->roundup = MIN(max_roundup, bus->blocksize); - - /* Query if bus module supports packet chaining, default to use if supported */ - if (bcmsdh_iovar_op(sdh, "sd_rxchain", NULL, 0, - &bus->sd_rxchain, sizeof(int32), FALSE) != BCME_OK) { - bus->sd_rxchain = FALSE; - } else { - DHD_INFO(("%s: bus module (through bcmsdh API) %s chaining\n", - __FUNCTION__, (bus->sd_rxchain ? "supports" : "does not support"))); - } - bus->use_rxchain = (bool)bus->sd_rxchain; - - return TRUE; -} - -bool -dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh, - char *fw_path, char *nv_path) -{ - bool ret; - bus->fw_path = fw_path; - bus->nv_path = nv_path; - - ret = dhdsdio_download_firmware(bus, osh, bus->sdh); - - return ret; -} - -static bool -dhdsdio_download_firmware(struct dhd_bus *bus, osl_t *osh, void *sdh) -{ - bool ret; - - /* Download the firmware */ - dhd_os_wake_lock(bus->dhd); - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - ret = _dhdsdio_download_firmware(bus) == 0; - - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); - dhd_os_wake_unlock(bus->dhd); - return ret; -} - -/* Detach and free everything */ -static void -dhdsdio_release(dhd_bus_t *bus, osl_t *osh) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (bus) { - ASSERT(osh); - - - /* De-register interrupt handler */ - bcmsdh_intr_disable(bus->sdh); - bcmsdh_intr_dereg(bus->sdh); - - if (bus->dhd) { - - dhdsdio_release_dongle(bus, osh, TRUE); - - dhd_detach(bus->dhd); - bus->dhd = NULL; - } - - dhdsdio_release_malloc(bus, osh); - - - MFREE(osh, bus, sizeof(dhd_bus_t)); - } - - if (osh) - dhd_osl_detach(osh); - - DHD_TRACE(("%s: Disconnected\n", __FUNCTION__)); -} - -static void -dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (bus->dhd && bus->dhd->dongle_reset) - return; - - if (bus->rxbuf) { -#ifndef DHD_USE_STATIC_BUF - MFREE(osh, bus->rxbuf, bus->rxblen); -#endif - bus->rxctl = bus->rxbuf = NULL; - bus->rxlen = 0; - } - - if (bus->databuf) { -#ifndef DHD_USE_STATIC_BUF - MFREE(osh, bus->databuf, MAX_DATA_BUF); -#endif - bus->databuf = NULL; - } -} - - -static void -dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh, int reset_flag) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if ((bus->dhd && bus->dhd->dongle_reset) && reset_flag) - return; - - if (bus->sih) { - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); -#if !defined(BCMLXSDMMC) - si_watchdog(bus->sih, 4); -#endif /* !defined(BCMLXSDMMC) */ - dhdsdio_clkctl(bus, CLK_NONE, FALSE); - si_detach(bus->sih); - if (bus->vars && bus->varsz) - MFREE(osh, bus->vars, bus->varsz); - bus->vars = NULL; - } - - DHD_TRACE(("%s: Disconnected\n", __FUNCTION__)); -} - -static void -dhdsdio_disconnect(void *ptr) -{ - dhd_bus_t *bus = (dhd_bus_t *)ptr; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (bus) { - ASSERT(bus->dhd); - dhdsdio_release(bus, bus->dhd->osh); - } - - DHD_TRACE(("%s: Disconnected\n", __FUNCTION__)); -} - - -/* Register/Unregister functions are called by the main DHD entry - * point (e.g. module insertion) to link with the bus driver, in - * order to look for or await the device. - */ - -static bcmsdh_driver_t dhd_sdio = { - dhdsdio_probe, - dhdsdio_disconnect -}; - -int -dhd_bus_register(void) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - return bcmsdh_register(&dhd_sdio); -} - -void -dhd_bus_unregister(void) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - bcmsdh_unregister(); -} - -#ifdef BCMEMBEDIMAGE -static int -dhdsdio_download_code_array(struct dhd_bus *bus) -{ - int bcmerror = -1; - int offset = 0; - - DHD_INFO(("%s: download embedded firmware...\n", __FUNCTION__)); - - /* Download image */ - while ((offset + MEMBLOCK) < sizeof(dlarray)) { - bcmerror = dhdsdio_membytes(bus, TRUE, offset, dlarray + offset, MEMBLOCK); - if (bcmerror) { - DHD_ERROR(("%s: error %d on writing %d membytes at 0x%08x\n", - __FUNCTION__, bcmerror, MEMBLOCK, offset)); - goto err; - } - - offset += MEMBLOCK; - } - - if (offset < sizeof(dlarray)) { - bcmerror = dhdsdio_membytes(bus, TRUE, offset, - dlarray + offset, sizeof(dlarray) - offset); - if (bcmerror) { - DHD_ERROR(("%s: error %d on writing %d membytes at 0x%08x\n", - __FUNCTION__, bcmerror, sizeof(dlarray) - offset, offset)); - goto err; - } - } - -#ifdef DHD_DEBUG - /* Upload and compare the downloaded code */ - { - unsigned char *ularray; - - ularray = MALLOC(bus->dhd->osh, bus->ramsize); - /* Upload image to verify downloaded contents. */ - offset = 0; - memset(ularray, 0xaa, bus->ramsize); - while ((offset + MEMBLOCK) < sizeof(dlarray)) { - bcmerror = dhdsdio_membytes(bus, FALSE, offset, ularray + offset, MEMBLOCK); - if (bcmerror) { - DHD_ERROR(("%s: error %d on reading %d membytes at 0x%08x\n", - __FUNCTION__, bcmerror, MEMBLOCK, offset)); - goto err; - } - - offset += MEMBLOCK; - } - - if (offset < sizeof(dlarray)) { - bcmerror = dhdsdio_membytes(bus, FALSE, offset, - ularray + offset, sizeof(dlarray) - offset); - if (bcmerror) { - DHD_ERROR(("%s: error %d on reading %d membytes at 0x%08x\n", - __FUNCTION__, bcmerror, sizeof(dlarray) - offset, offset)); - goto err; - } - } - - if (memcmp(dlarray, ularray, sizeof(dlarray))) { - DHD_ERROR(("%s: Downloaded image is corrupted.\n", __FUNCTION__)); - ASSERT(0); - goto err; - } else - DHD_ERROR(("%s: Download, Upload and compare succeeded.\n", __FUNCTION__)); - - MFREE(bus->dhd->osh, ularray, bus->ramsize); - } -#endif /* DHD_DEBUG */ - -err: - return bcmerror; -} -#endif /* BCMEMBEDIMAGE */ - -static int -dhdsdio_download_code_file(struct dhd_bus *bus, char *fw_path) -{ - int bcmerror = -1; - int offset = 0; - uint len; - void *image = NULL; - uint8 *memblock = NULL, *memptr; - - DHD_INFO(("%s: download firmware %s\n", __FUNCTION__, fw_path)); - - image = dhd_os_open_image(fw_path); - if (image == NULL) - goto err; - - memptr = memblock = MALLOC(bus->dhd->osh, MEMBLOCK + DHD_SDALIGN); - if (memblock == NULL) { - DHD_ERROR(("%s: Failed to allocate memory %d bytes\n", __FUNCTION__, MEMBLOCK)); - goto err; - } - if ((uint32)(uintptr)memblock % DHD_SDALIGN) - memptr += (DHD_SDALIGN - ((uint32)(uintptr)memblock % DHD_SDALIGN)); - - /* Download image */ - while ((len = dhd_os_get_image_block((char*)memptr, MEMBLOCK, image))) { - bcmerror = dhdsdio_membytes(bus, TRUE, offset, memptr, len); - if (bcmerror) { - DHD_ERROR(("%s: error %d on writing %d membytes at 0x%08x\n", - __FUNCTION__, bcmerror, MEMBLOCK, offset)); - goto err; - } - - offset += MEMBLOCK; - } - -err: - if (memblock) - MFREE(bus->dhd->osh, memblock, MEMBLOCK + DHD_SDALIGN); - - if (image) - dhd_os_close_image(image); - - return bcmerror; -} - -/* - * ProcessVars:Takes a buffer of "=\n" lines read from a file and ending in a NUL. - * Removes carriage returns, empty lines, comment lines, and converts newlines to NULs. - * Shortens buffer as needed and pads with NULs. End of buffer is marked by two NULs. -*/ - -static uint -process_nvram_vars(char *varbuf, uint len) -{ - char *dp; - bool findNewline; - int column; - uint buf_len, n; - - dp = varbuf; - - findNewline = FALSE; - column = 0; - - for (n = 0; n < len; n++) { - if (varbuf[n] == 0) - break; - if (varbuf[n] == '\r') - continue; - if (findNewline && varbuf[n] != '\n') - continue; - findNewline = FALSE; - if (varbuf[n] == '#') { - findNewline = TRUE; - continue; - } - if (varbuf[n] == '\n') { - if (column == 0) - continue; - *dp++ = 0; - column = 0; - continue; - } - *dp++ = varbuf[n]; - column++; - } - buf_len = dp - varbuf; - - while (dp < varbuf + n) - *dp++ = 0; - - return buf_len; -} - -/* - EXAMPLE: nvram_array - nvram_arry format: - name=value - Use carriage return at the end of each assignment, and an empty string with - carriage return at the end of array. - - For example: - unsigned char nvram_array[] = {"name1=value1\n", "name2=value2\n", "\n"}; - Hex values start with 0x, and mac addr format: xx:xx:xx:xx:xx:xx. - - Search "EXAMPLE: nvram_array" to see how the array is activated. -*/ - -void -dhd_bus_set_nvram_params(struct dhd_bus * bus, const char *nvram_params) -{ - bus->nvram_params = nvram_params; -} - -static int -dhdsdio_download_nvram(struct dhd_bus *bus) -{ - int bcmerror = -1; - uint len; - void * image = NULL; - char * memblock = NULL; - char *bufp; - char *nv_path; - bool nvram_file_exists; - - nv_path = bus->nv_path; - - nvram_file_exists = ((nv_path != NULL) && (nv_path[0] != '\0')); - if (!nvram_file_exists && (bus->nvram_params == NULL)) - return (0); - - if (nvram_file_exists) { - image = dhd_os_open_image(nv_path); - if (image == NULL) - goto err; - } - - memblock = MALLOC(bus->dhd->osh, MEMBLOCK); - if (memblock == NULL) { - DHD_ERROR(("%s: Failed to allocate memory %d bytes\n", - __FUNCTION__, MEMBLOCK)); - goto err; - } - - /* Download variables */ - if (nvram_file_exists) { - len = dhd_os_get_image_block(memblock, MEMBLOCK, image); - } - else { - len = strlen(bus->nvram_params); - ASSERT(len <= MEMBLOCK); - if (len > MEMBLOCK) - len = MEMBLOCK; - memcpy(memblock, bus->nvram_params, len); - } - - if (len > 0 && len < MEMBLOCK) { - bufp = (char *)memblock; - bufp[len] = 0; - len = process_nvram_vars(bufp, len); - bufp += len; - *bufp++ = 0; - if (len) - bcmerror = dhdsdio_downloadvars(bus, memblock, len + 1); - if (bcmerror) { - DHD_ERROR(("%s: error downloading vars: %d\n", - __FUNCTION__, bcmerror)); - } - } - else { - DHD_ERROR(("%s: error reading nvram file: %d\n", - __FUNCTION__, len)); - bcmerror = BCME_SDIO_ERROR; - } - -err: - if (memblock) - MFREE(bus->dhd->osh, memblock, MEMBLOCK); - - if (image) - dhd_os_close_image(image); - - return bcmerror; -} - -static int -_dhdsdio_download_firmware(struct dhd_bus *bus) -{ - int bcmerror = -1; - - bool embed = FALSE; /* download embedded firmware */ - bool dlok = FALSE; /* download firmware succeeded */ - - /* Out immediately if no image to download */ - if ((bus->fw_path == NULL) || (bus->fw_path[0] == '\0')) { -#ifdef BCMEMBEDIMAGE - embed = TRUE; -#else - return bcmerror; -#endif - } - - /* Keep arm in reset */ - if (dhdsdio_download_state(bus, TRUE)) { - DHD_ERROR(("%s: error placing ARM core in reset\n", __FUNCTION__)); - goto err; - } - - /* External image takes precedence if specified */ - if ((bus->fw_path != NULL) && (bus->fw_path[0] != '\0')) { - if (dhdsdio_download_code_file(bus, bus->fw_path)) { - DHD_ERROR(("%s: dongle image file download failed\n", __FUNCTION__)); -#ifdef BCMEMBEDIMAGE - embed = TRUE; -#else - goto err; -#endif - } - else { - embed = FALSE; - dlok = TRUE; - } - } -#ifdef BCMEMBEDIMAGE - if (embed) { - if (dhdsdio_download_code_array(bus)) { - DHD_ERROR(("%s: dongle image array download failed\n", __FUNCTION__)); - goto err; - } - else { - dlok = TRUE; - } - } -#endif - if (!dlok) { - DHD_ERROR(("%s: dongle image download failed\n", __FUNCTION__)); - goto err; - } - - /* EXAMPLE: nvram_array */ - /* If a valid nvram_arry is specified as above, it can be passed down to dongle */ - /* dhd_bus_set_nvram_params(bus, (char *)&nvram_array); */ - - /* External nvram takes precedence if specified */ - if (dhdsdio_download_nvram(bus)) { - DHD_ERROR(("%s: dongle nvram file download failed\n", __FUNCTION__)); - } - - /* Take arm out of reset */ - if (dhdsdio_download_state(bus, FALSE)) { - DHD_ERROR(("%s: error getting out of ARM core reset\n", __FUNCTION__)); - goto err; - } - - bcmerror = 0; - -err: - return bcmerror; -} - -static int -dhd_bcmsdh_recv_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, uint8 *buf, uint nbytes, - void *pkt, bcmsdh_cmplt_fn_t complete, void *handle) -{ - int status; - - /* 4329: GSPI check */ - status = bcmsdh_recv_buf(bus->sdh, addr, fn, flags, buf, nbytes, pkt, complete, handle); - return status; -} - -static int -dhd_bcmsdh_send_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, uint8 *buf, uint nbytes, - void *pkt, bcmsdh_cmplt_fn_t complete, void *handle) -{ - return (bcmsdh_send_buf(bus->sdh, addr, fn, flags, buf, nbytes, pkt, complete, handle)); -} - -uint -dhd_bus_chip(struct dhd_bus *bus) -{ - ASSERT(bus->sih != NULL); - return bus->sih->chip; -} - -void * -dhd_bus_pub(struct dhd_bus *bus) -{ - return bus->dhd; -} - -void * -dhd_bus_txq(struct dhd_bus *bus) -{ - return &bus->txq; -} - -uint -dhd_bus_hdrlen(struct dhd_bus *bus) -{ - return SDPCM_HDRLEN; -} - -int -dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag) -{ - int bcmerror = 0; - dhd_bus_t *bus; - - bus = dhdp->bus; - - if (flag == TRUE) { - if (!bus->dhd->dongle_reset) { - dhd_os_sdlock(dhdp); - /* Turning off watchdog */ - dhd_os_wd_timer(dhdp, 0); -#if !defined(IGNORE_ETH0_DOWN) - /* Force flow control as protection when stop come before ifconfig_down */ - dhd_txflowcontrol(bus->dhd, 0, ON); -#endif /* !defined(IGNORE_ETH0_DOWN) */ - /* Expect app to have torn down any connection before calling */ - /* Stop the bus, disable F2 */ - dhd_bus_stop(bus, FALSE); -#if defined(OOB_INTR_ONLY) - bcmsdh_set_irq(FALSE); -#endif /* defined(OOB_INTR_ONLY) */ - /* Clean tx/rx buffer pointers, detach from the dongle */ - dhdsdio_release_dongle(bus, bus->dhd->osh, TRUE); - - bus->dhd->dongle_reset = TRUE; - bus->dhd->up = FALSE; - dhd_os_sdunlock(dhdp); - - DHD_TRACE(("%s: WLAN OFF DONE\n", __FUNCTION__)); - /* App can now remove power from device */ - } else - bcmerror = BCME_SDIO_ERROR; - } else { - /* App must have restored power to device before calling */ - - DHD_TRACE(("\n\n%s: == WLAN ON ==\n", __FUNCTION__)); - - if (bus->dhd->dongle_reset) { - /* Turn on WLAN */ - dhd_os_sdlock(dhdp); - - /* Reset SD client */ - bcmsdh_reset(bus->sdh); - - /* Attempt to re-attach & download */ - if (dhdsdio_probe_attach(bus, bus->dhd->osh, bus->sdh, - (uint32 *)SI_ENUM_BASE, - bus->cl_devid)) { - /* Attempt to download binary to the dongle */ - if (dhdsdio_probe_init(bus, bus->dhd->osh, bus->sdh) && - dhdsdio_download_firmware(bus, bus->dhd->osh, bus->sdh)) { - - /* Re-init bus, enable F2 transfer */ - bcmerror = dhd_bus_init((dhd_pub_t *) bus->dhd, FALSE); - if (bcmerror == BCME_OK) { -#if defined(OOB_INTR_ONLY) - bcmsdh_set_irq(TRUE); - dhd_enable_oob_intr(bus, TRUE); -#endif /* defined(OOB_INTR_ONLY) */ - bus->dhd->dongle_reset = FALSE; - bus->dhd->up = TRUE; -#if !defined(IGNORE_ETH0_DOWN) - /* Restore flow control */ - dhd_txflowcontrol(bus->dhd, 0, OFF); -#endif - /* Turning on watchdog back */ - dhd_os_wd_timer(dhdp, dhd_watchdog_ms); - - DHD_TRACE(("%s: WLAN ON DONE\n", __FUNCTION__)); - } else { - dhd_bus_stop(bus, FALSE); - dhdsdio_release_dongle(bus, bus->dhd->osh, FALSE); - } - } else - bcmerror = BCME_SDIO_ERROR; - } else - bcmerror = BCME_SDIO_ERROR; - - dhd_os_sdunlock(dhdp); - } else { - bcmerror = BCME_NOTDOWN; - DHD_ERROR(("%s: Set DEVRESET=FALSE invoked when device is on\n", - __FUNCTION__)); - bcmerror = BCME_SDIO_ERROR; - } - } - return bcmerror; -} diff --git a/drivers/net/wireless/bcm4329/dngl_stats.h b/drivers/net/wireless/bcm4329/dngl_stats.h deleted file mode 100644 index e5db54e7edfe..000000000000 --- a/drivers/net/wireless/bcm4329/dngl_stats.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Common stats definitions for clients of dongle - * ports - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dngl_stats.h,v 1.2.140.3 2008/05/26 16:52:08 Exp $ - */ - -#ifndef _dngl_stats_h_ -#define _dngl_stats_h_ - -typedef struct { - unsigned long rx_packets; /* total packets received */ - unsigned long tx_packets; /* total packets transmitted */ - unsigned long rx_bytes; /* total bytes received */ - unsigned long tx_bytes; /* total bytes transmitted */ - unsigned long rx_errors; /* bad packets received */ - unsigned long tx_errors; /* packet transmit problems */ - unsigned long rx_dropped; /* packets dropped by dongle */ - unsigned long tx_dropped; /* packets dropped by dongle */ - unsigned long multicast; /* multicast packets received */ -} dngl_stats_t; - -#endif /* _dngl_stats_h_ */ diff --git a/drivers/net/wireless/bcm4329/hndpmu.c b/drivers/net/wireless/bcm4329/hndpmu.c deleted file mode 100644 index 307347a43bde..000000000000 --- a/drivers/net/wireless/bcm4329/hndpmu.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Misc utility routines for accessing PMU corerev specific features - * of the SiliconBackplane-based Broadcom chips. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: hndpmu.c,v 1.95.2.17.4.11.2.63 2010/07/21 13:55:09 Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* debug/trace */ -#define PMU_ERROR(args) - -#define PMU_MSG(args) - - -/* SDIO Pad drive strength to select value mappings */ -typedef struct { - uint8 strength; /* Pad Drive Strength in mA */ - uint8 sel; /* Chip-specific select value */ -} sdiod_drive_str_t; - -/* SDIO Drive Strength to sel value table for PMU Rev 1 */ -static const sdiod_drive_str_t sdiod_drive_strength_tab1[] = { - {4, 0x2}, - {2, 0x3}, - {1, 0x0}, - {0, 0x0} }; - -/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */ -static const sdiod_drive_str_t sdiod_drive_strength_tab2[] = { - {12, 0x7}, - {10, 0x6}, - {8, 0x5}, - {6, 0x4}, - {4, 0x2}, - {2, 0x1}, - {0, 0x0} }; - -#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) - -void -si_sdiod_drive_strength_init(si_t *sih, osl_t *osh, uint32 drivestrength) -{ - chipcregs_t *cc; - uint origidx, intr_val = 0; - sdiod_drive_str_t *str_tab = NULL; - uint32 str_mask = 0; - uint32 str_shift = 0; - - if (!(sih->cccaps & CC_CAP_PMU)) { - return; - } - - /* Remember original core before switch to chipc */ - cc = (chipcregs_t *) si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val); - - switch (SDIOD_DRVSTR_KEY(sih->chip, sih->pmurev)) { - case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1): - str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab1; - str_mask = 0x30000000; - str_shift = 28; - break; - case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2): - case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3): - case SDIOD_DRVSTR_KEY(BCM4315_CHIP_ID, 4): - str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab2; - str_mask = 0x00003800; - str_shift = 11; - break; - - default: - PMU_MSG(("No SDIO Drive strength init done for chip %x rev %d pmurev %d\n", - sih->chip, sih->chiprev, sih->pmurev)); - - break; - } - - if (str_tab != NULL) { - uint32 drivestrength_sel = 0; - uint32 cc_data_temp; - int i; - - for (i = 0; str_tab[i].strength != 0; i ++) { - if (drivestrength >= str_tab[i].strength) { - drivestrength_sel = str_tab[i].sel; - break; - } - } - - W_REG(osh, &cc->chipcontrol_addr, 1); - cc_data_temp = R_REG(osh, &cc->chipcontrol_data); - cc_data_temp &= ~str_mask; - drivestrength_sel <<= str_shift; - cc_data_temp |= drivestrength_sel; - W_REG(osh, &cc->chipcontrol_data, cc_data_temp); - - PMU_MSG(("SDIO: %dmA drive strength selected, set to 0x%08x\n", - drivestrength, cc_data_temp)); - } - - /* Return to original core */ - si_restore_core(sih, origidx, intr_val); -} diff --git a/drivers/net/wireless/bcm4329/include/Makefile b/drivers/net/wireless/bcm4329/include/Makefile deleted file mode 100644 index 439ead14a0e6..000000000000 --- a/drivers/net/wireless/bcm4329/include/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# -# include/Makefile -# -# Copyright 2005, Broadcom, Inc. -# -# $Id: Makefile,v 13.5 2005/02/17 19:11:31 Exp $ -# - -SRCBASE = .. - -TARGETS = epivers.h - - -all release: - bash epivers.sh - -clean: - rm -rf ${TARGETS} *.prev - - -.PHONY: all release clean diff --git a/drivers/net/wireless/bcm4329/include/aidmp.h b/drivers/net/wireless/bcm4329/include/aidmp.h deleted file mode 100644 index a927e5dae586..000000000000 --- a/drivers/net/wireless/bcm4329/include/aidmp.h +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Broadcom AMBA Interconnect definitions. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: aidmp.h,v 13.2.10.1 2008/05/07 20:32:12 Exp $ - */ - - -#ifndef _AIDMP_H -#define _AIDMP_H - - -#define MFGID_ARM 0x43b -#define MFGID_BRCM 0x4bf -#define MFGID_MIPS 0x4a7 - - -#define CC_SIM 0 -#define CC_EROM 1 -#define CC_CORESIGHT 9 -#define CC_VERIF 0xb -#define CC_OPTIMO 0xd -#define CC_GEN 0xe -#define CC_PRIMECELL 0xf - - -#define ER_EROMENTRY 0x000 -#define ER_REMAPCONTROL 0xe00 -#define ER_REMAPSELECT 0xe04 -#define ER_MASTERSELECT 0xe10 -#define ER_ITCR 0xf00 -#define ER_ITIP 0xf04 - - -#define ER_TAG 0xe -#define ER_TAG1 0x6 -#define ER_VALID 1 -#define ER_CI 0 -#define ER_MP 2 -#define ER_ADD 4 -#define ER_END 0xe -#define ER_BAD 0xffffffff - - -#define CIA_MFG_MASK 0xfff00000 -#define CIA_MFG_SHIFT 20 -#define CIA_CID_MASK 0x000fff00 -#define CIA_CID_SHIFT 8 -#define CIA_CCL_MASK 0x000000f0 -#define CIA_CCL_SHIFT 4 - - -#define CIB_REV_MASK 0xff000000 -#define CIB_REV_SHIFT 24 -#define CIB_NSW_MASK 0x00f80000 -#define CIB_NSW_SHIFT 19 -#define CIB_NMW_MASK 0x0007c000 -#define CIB_NMW_SHIFT 14 -#define CIB_NSP_MASK 0x00003e00 -#define CIB_NSP_SHIFT 9 -#define CIB_NMP_MASK 0x000001f0 -#define CIB_NMP_SHIFT 4 - - -#define MPD_MUI_MASK 0x0000ff00 -#define MPD_MUI_SHIFT 8 -#define MPD_MP_MASK 0x000000f0 -#define MPD_MP_SHIFT 4 - - -#define AD_ADDR_MASK 0xfffff000 -#define AD_SP_MASK 0x00000f00 -#define AD_SP_SHIFT 8 -#define AD_ST_MASK 0x000000c0 -#define AD_ST_SHIFT 6 -#define AD_ST_SLAVE 0x00000000 -#define AD_ST_BRIDGE 0x00000040 -#define AD_ST_SWRAP 0x00000080 -#define AD_ST_MWRAP 0x000000c0 -#define AD_SZ_MASK 0x00000030 -#define AD_SZ_SHIFT 4 -#define AD_SZ_4K 0x00000000 -#define AD_SZ_8K 0x00000010 -#define AD_SZ_16K 0x00000020 -#define AD_SZ_SZD 0x00000030 -#define AD_AG32 0x00000008 -#define AD_ADDR_ALIGN 0x00000fff -#define AD_SZ_BASE 0x00001000 - - -#define SD_SZ_MASK 0xfffff000 -#define SD_SG32 0x00000008 -#define SD_SZ_ALIGN 0x00000fff - - -#ifndef _LANGUAGE_ASSEMBLY - -typedef volatile struct _aidmp { - uint32 oobselina30; - uint32 oobselina74; - uint32 PAD[6]; - uint32 oobselinb30; - uint32 oobselinb74; - uint32 PAD[6]; - uint32 oobselinc30; - uint32 oobselinc74; - uint32 PAD[6]; - uint32 oobselind30; - uint32 oobselind74; - uint32 PAD[38]; - uint32 oobselouta30; - uint32 oobselouta74; - uint32 PAD[6]; - uint32 oobseloutb30; - uint32 oobseloutb74; - uint32 PAD[6]; - uint32 oobseloutc30; - uint32 oobseloutc74; - uint32 PAD[6]; - uint32 oobseloutd30; - uint32 oobseloutd74; - uint32 PAD[38]; - uint32 oobsynca; - uint32 oobseloutaen; - uint32 PAD[6]; - uint32 oobsyncb; - uint32 oobseloutben; - uint32 PAD[6]; - uint32 oobsyncc; - uint32 oobseloutcen; - uint32 PAD[6]; - uint32 oobsyncd; - uint32 oobseloutden; - uint32 PAD[38]; - uint32 oobaextwidth; - uint32 oobainwidth; - uint32 oobaoutwidth; - uint32 PAD[5]; - uint32 oobbextwidth; - uint32 oobbinwidth; - uint32 oobboutwidth; - uint32 PAD[5]; - uint32 oobcextwidth; - uint32 oobcinwidth; - uint32 oobcoutwidth; - uint32 PAD[5]; - uint32 oobdextwidth; - uint32 oobdinwidth; - uint32 oobdoutwidth; - uint32 PAD[37]; - uint32 ioctrlset; - uint32 ioctrlclear; - uint32 ioctrl; - uint32 PAD[61]; - uint32 iostatus; - uint32 PAD[127]; - uint32 ioctrlwidth; - uint32 iostatuswidth; - uint32 PAD[62]; - uint32 resetctrl; - uint32 resetstatus; - uint32 resetreadid; - uint32 resetwriteid; - uint32 PAD[60]; - uint32 errlogctrl; - uint32 errlogdone; - uint32 errlogstatus; - uint32 errlogaddrlo; - uint32 errlogaddrhi; - uint32 errlogid; - uint32 errloguser; - uint32 errlogflags; - uint32 PAD[56]; - uint32 intstatus; - uint32 PAD[127]; - uint32 config; - uint32 PAD[63]; - uint32 itcr; - uint32 PAD[3]; - uint32 itipooba; - uint32 itipoobb; - uint32 itipoobc; - uint32 itipoobd; - uint32 PAD[4]; - uint32 itipoobaout; - uint32 itipoobbout; - uint32 itipoobcout; - uint32 itipoobdout; - uint32 PAD[4]; - uint32 itopooba; - uint32 itopoobb; - uint32 itopoobc; - uint32 itopoobd; - uint32 PAD[4]; - uint32 itopoobain; - uint32 itopoobbin; - uint32 itopoobcin; - uint32 itopoobdin; - uint32 PAD[4]; - uint32 itopreset; - uint32 PAD[15]; - uint32 peripherialid4; - uint32 peripherialid5; - uint32 peripherialid6; - uint32 peripherialid7; - uint32 peripherialid0; - uint32 peripherialid1; - uint32 peripherialid2; - uint32 peripherialid3; - uint32 componentid0; - uint32 componentid1; - uint32 componentid2; - uint32 componentid3; -} aidmp_t; - -#endif - - -#define OOB_BUSCONFIG 0x020 -#define OOB_STATUSA 0x100 -#define OOB_STATUSB 0x104 -#define OOB_STATUSC 0x108 -#define OOB_STATUSD 0x10c -#define OOB_ENABLEA0 0x200 -#define OOB_ENABLEA1 0x204 -#define OOB_ENABLEA2 0x208 -#define OOB_ENABLEA3 0x20c -#define OOB_ENABLEB0 0x280 -#define OOB_ENABLEB1 0x284 -#define OOB_ENABLEB2 0x288 -#define OOB_ENABLEB3 0x28c -#define OOB_ENABLEC0 0x300 -#define OOB_ENABLEC1 0x304 -#define OOB_ENABLEC2 0x308 -#define OOB_ENABLEC3 0x30c -#define OOB_ENABLED0 0x380 -#define OOB_ENABLED1 0x384 -#define OOB_ENABLED2 0x388 -#define OOB_ENABLED3 0x38c -#define OOB_ITCR 0xf00 -#define OOB_ITIPOOBA 0xf10 -#define OOB_ITIPOOBB 0xf14 -#define OOB_ITIPOOBC 0xf18 -#define OOB_ITIPOOBD 0xf1c -#define OOB_ITOPOOBA 0xf30 -#define OOB_ITOPOOBB 0xf34 -#define OOB_ITOPOOBC 0xf38 -#define OOB_ITOPOOBD 0xf3c - - -#define AI_OOBSELINA30 0x000 -#define AI_OOBSELINA74 0x004 -#define AI_OOBSELINB30 0x020 -#define AI_OOBSELINB74 0x024 -#define AI_OOBSELINC30 0x040 -#define AI_OOBSELINC74 0x044 -#define AI_OOBSELIND30 0x060 -#define AI_OOBSELIND74 0x064 -#define AI_OOBSELOUTA30 0x100 -#define AI_OOBSELOUTA74 0x104 -#define AI_OOBSELOUTB30 0x120 -#define AI_OOBSELOUTB74 0x124 -#define AI_OOBSELOUTC30 0x140 -#define AI_OOBSELOUTC74 0x144 -#define AI_OOBSELOUTD30 0x160 -#define AI_OOBSELOUTD74 0x164 -#define AI_OOBSYNCA 0x200 -#define AI_OOBSELOUTAEN 0x204 -#define AI_OOBSYNCB 0x220 -#define AI_OOBSELOUTBEN 0x224 -#define AI_OOBSYNCC 0x240 -#define AI_OOBSELOUTCEN 0x244 -#define AI_OOBSYNCD 0x260 -#define AI_OOBSELOUTDEN 0x264 -#define AI_OOBAEXTWIDTH 0x300 -#define AI_OOBAINWIDTH 0x304 -#define AI_OOBAOUTWIDTH 0x308 -#define AI_OOBBEXTWIDTH 0x320 -#define AI_OOBBINWIDTH 0x324 -#define AI_OOBBOUTWIDTH 0x328 -#define AI_OOBCEXTWIDTH 0x340 -#define AI_OOBCINWIDTH 0x344 -#define AI_OOBCOUTWIDTH 0x348 -#define AI_OOBDEXTWIDTH 0x360 -#define AI_OOBDINWIDTH 0x364 -#define AI_OOBDOUTWIDTH 0x368 -#define AI_IOCTRLSET 0x400 -#define AI_IOCTRLCLEAR 0x404 -#define AI_IOCTRL 0x408 -#define AI_IOSTATUS 0x500 -#define AI_IOCTRLWIDTH 0x700 -#define AI_IOSTATUSWIDTH 0x704 -#define AI_RESETCTRL 0x800 -#define AI_RESETSTATUS 0x804 -#define AI_RESETREADID 0x808 -#define AI_RESETWRITEID 0x80c -#define AI_ERRLOGCTRL 0xa00 -#define AI_ERRLOGDONE 0xa04 -#define AI_ERRLOGSTATUS 0xa08 -#define AI_ERRLOGADDRLO 0xa0c -#define AI_ERRLOGADDRHI 0xa10 -#define AI_ERRLOGID 0xa14 -#define AI_ERRLOGUSER 0xa18 -#define AI_ERRLOGFLAGS 0xa1c -#define AI_INTSTATUS 0xa00 -#define AI_CONFIG 0xe00 -#define AI_ITCR 0xf00 -#define AI_ITIPOOBA 0xf10 -#define AI_ITIPOOBB 0xf14 -#define AI_ITIPOOBC 0xf18 -#define AI_ITIPOOBD 0xf1c -#define AI_ITIPOOBAOUT 0xf30 -#define AI_ITIPOOBBOUT 0xf34 -#define AI_ITIPOOBCOUT 0xf38 -#define AI_ITIPOOBDOUT 0xf3c -#define AI_ITOPOOBA 0xf50 -#define AI_ITOPOOBB 0xf54 -#define AI_ITOPOOBC 0xf58 -#define AI_ITOPOOBD 0xf5c -#define AI_ITOPOOBAIN 0xf70 -#define AI_ITOPOOBBIN 0xf74 -#define AI_ITOPOOBCIN 0xf78 -#define AI_ITOPOOBDIN 0xf7c -#define AI_ITOPRESET 0xf90 -#define AI_PERIPHERIALID4 0xfd0 -#define AI_PERIPHERIALID5 0xfd4 -#define AI_PERIPHERIALID6 0xfd8 -#define AI_PERIPHERIALID7 0xfdc -#define AI_PERIPHERIALID0 0xfe0 -#define AI_PERIPHERIALID1 0xfe4 -#define AI_PERIPHERIALID2 0xfe8 -#define AI_PERIPHERIALID3 0xfec -#define AI_COMPONENTID0 0xff0 -#define AI_COMPONENTID1 0xff4 -#define AI_COMPONENTID2 0xff8 -#define AI_COMPONENTID3 0xffc - - -#define AIRC_RESET 1 - - -#define AICFG_OOB 0x00000020 -#define AICFG_IOS 0x00000010 -#define AICFG_IOC 0x00000008 -#define AICFG_TO 0x00000004 -#define AICFG_ERRL 0x00000002 -#define AICFG_RST 0x00000001 - -#endif diff --git a/drivers/net/wireless/bcm4329/include/bcmcdc.h b/drivers/net/wireless/bcm4329/include/bcmcdc.h deleted file mode 100644 index c2a860beab24..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmcdc.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * CDC network driver ioctl/indication encoding - * Broadcom 802.11abg Networking Device Driver - * - * Definitions subject to change without notice. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmcdc.h,v 13.14.16.3.16.4 2009/04/12 16:58:45 Exp $ - */ -#include - -typedef struct cdc_ioctl { - uint32 cmd; /* ioctl command value */ - uint32 len; /* lower 16: output buflen; upper 16: input buflen (excludes header) */ - uint32 flags; /* flag defns given below */ - uint32 status; /* status code returned from the device */ -} cdc_ioctl_t; - -/* Max valid buffer size that can be sent to the dongle */ -#define CDC_MAX_MSG_SIZE ETHER_MAX_LEN - -/* len field is divided into input and output buffer lengths */ -#define CDCL_IOC_OUTLEN_MASK 0x0000FFFF /* maximum or expected response length, */ - /* excluding IOCTL header */ -#define CDCL_IOC_OUTLEN_SHIFT 0 -#define CDCL_IOC_INLEN_MASK 0xFFFF0000 /* input buffer length, excluding IOCTL header */ -#define CDCL_IOC_INLEN_SHIFT 16 - -/* CDC flag definitions */ -#define CDCF_IOC_ERROR 0x01 /* 0=success, 1=ioctl cmd failed */ -#define CDCF_IOC_SET 0x02 /* 0=get, 1=set cmd */ -#define CDCF_IOC_IF_MASK 0xF000 /* I/F index */ -#define CDCF_IOC_IF_SHIFT 12 -#define CDCF_IOC_ID_MASK 0xFFFF0000 /* used to uniquely id an ioctl req/resp pairing */ -#define CDCF_IOC_ID_SHIFT 16 /* # of bits of shift for ID Mask */ - -#define CDC_IOC_IF_IDX(flags) (((flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT) -#define CDC_IOC_ID(flags) (((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT) - -#define CDC_GET_IF_IDX(hdr) \ - ((int)((((hdr)->flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT)) -#define CDC_SET_IF_IDX(hdr, idx) \ - ((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | ((idx) << CDCF_IOC_IF_SHIFT))) - -/* - * BDC header - * - * The BDC header is used on data packets to convey priority across USB. - */ - -#define BDC_HEADER_LEN 4 - -#define BDC_PROTO_VER 1 /* Protocol version */ - -#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */ -#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */ - -#define BDC_FLAG__UNUSED 0x03 /* Unassigned */ -#define BDC_FLAG_SUM_GOOD 0x04 /* Dongle has verified good RX checksums */ -#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */ - -#define BDC_PRIORITY_MASK 0x7 - -#define BDC_FLAG2_FC_FLAG 0x10 /* flag to indicate if pkt contains */ - /* FLOW CONTROL info only */ -#define BDC_PRIORITY_FC_SHIFT 4 /* flow control info shift */ - -#define BDC_FLAG2_IF_MASK 0x0f /* APSTA: interface on which the packet was received */ -#define BDC_FLAG2_IF_SHIFT 0 - -#define BDC_GET_IF_IDX(hdr) \ - ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT)) -#define BDC_SET_IF_IDX(hdr, idx) \ - ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | ((idx) << BDC_FLAG2_IF_SHIFT))) - -struct bdc_header { - uint8 flags; /* Flags */ - uint8 priority; /* 802.1d Priority 0:2 bits, 4:7 flow control info for usb */ - uint8 flags2; - uint8 rssi; -}; diff --git a/drivers/net/wireless/bcm4329/include/bcmdefs.h b/drivers/net/wireless/bcm4329/include/bcmdefs.h deleted file mode 100644 index f4e99461971b..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmdefs.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Misc system wide definitions - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * $Id: bcmdefs.h,v 13.38.4.10.2.7.6.11 2010/02/01 05:51:55 Exp $ - */ - - -#ifndef _bcmdefs_h_ -#define _bcmdefs_h_ - -#define STATIC static - -#define SI_BUS 0 -#define PCI_BUS 1 -#define PCMCIA_BUS 2 -#define SDIO_BUS 3 -#define JTAG_BUS 4 -#define USB_BUS 5 -#define SPI_BUS 6 - - -#ifdef BCMBUSTYPE -#define BUSTYPE(bus) (BCMBUSTYPE) -#else -#define BUSTYPE(bus) (bus) -#endif - - -#ifdef BCMCHIPTYPE -#define CHIPTYPE(bus) (BCMCHIPTYPE) -#else -#define CHIPTYPE(bus) (bus) -#endif - - - -#if defined(BCMSPROMBUS) -#define SPROMBUS (BCMSPROMBUS) -#elif defined(SI_PCMCIA_SROM) -#define SPROMBUS (PCMCIA_BUS) -#else -#define SPROMBUS (PCI_BUS) -#endif - - -#ifdef BCMCHIPID -#define CHIPID(chip) (BCMCHIPID) -#else -#define CHIPID(chip) (chip) -#endif - - -#define DMADDR_MASK_32 0x0 -#define DMADDR_MASK_30 0xc0000000 -#define DMADDR_MASK_0 0xffffffff - -#define DMADDRWIDTH_30 30 -#define DMADDRWIDTH_32 32 -#define DMADDRWIDTH_63 63 -#define DMADDRWIDTH_64 64 - - -#define BCMEXTRAHDROOM 164 - - -#define BCMDONGLEHDRSZ 12 -#define BCMDONGLEPADSZ 16 - -#define BCMDONGLEOVERHEAD (BCMDONGLEHDRSZ + BCMDONGLEPADSZ) - - - -#define BITFIELD_MASK(width) \ - (((unsigned)1 << (width)) - 1) -#define GFIELD(val, field) \ - (((val) >> field ## _S) & field ## _M) -#define SFIELD(val, field, bits) \ - (((val) & (~(field ## _M << field ## _S))) | \ - ((unsigned)(bits) << field ## _S)) - - -#ifdef BCMSMALL -#undef BCMSPACE -#define bcmspace FALSE -#else -#define BCMSPACE -#define bcmspace TRUE -#endif - - -#define MAXSZ_NVRAM_VARS 4096 - -#define LOCATOR_EXTERN static - -#endif diff --git a/drivers/net/wireless/bcm4329/include/bcmdevs.h b/drivers/net/wireless/bcm4329/include/bcmdevs.h deleted file mode 100644 index 14853f17795c..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmdevs.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Broadcom device-specific manifest constants. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmdevs.h,v 13.172.4.5.4.10.2.36 2010/05/25 08:33:44 Exp $ - */ - - -#ifndef _BCMDEVS_H -#define _BCMDEVS_H - - -#define VENDOR_EPIGRAM 0xfeda -#define VENDOR_BROADCOM 0x14e4 -#define VENDOR_SI_IMAGE 0x1095 -#define VENDOR_TI 0x104c -#define VENDOR_RICOH 0x1180 -#define VENDOR_JMICRON 0x197b - - -#define VENDOR_BROADCOM_PCMCIA 0x02d0 - - -#define VENDOR_BROADCOM_SDIO 0x00BF - - -#define BCM_DNGL_VID 0xa5c -#define BCM_DNGL_BL_PID_4320 0xbd11 -#define BCM_DNGL_BL_PID_4328 0xbd12 -#define BCM_DNGL_BL_PID_4322 0xbd13 -#define BCM_DNGL_BL_PID_4325 0xbd14 -#define BCM_DNGL_BL_PID_4315 0xbd15 -#define BCM_DNGL_BL_PID_4319 0xbd16 -#define BCM_DNGL_BDC_PID 0xbdc - -#define BCM4325_D11DUAL_ID 0x431b -#define BCM4325_D11G_ID 0x431c -#define BCM4325_D11A_ID 0x431d -#define BCM4329_D11NDUAL_ID 0x432e -#define BCM4329_D11N2G_ID 0x432f -#define BCM4329_D11N5G_ID 0x4330 -#define BCM4336_D11N_ID 0x4343 -#define BCM4315_D11DUAL_ID 0x4334 -#define BCM4315_D11G_ID 0x4335 -#define BCM4315_D11A_ID 0x4336 -#define BCM4319_D11N_ID 0x4337 -#define BCM4319_D11N2G_ID 0x4338 -#define BCM4319_D11N5G_ID 0x4339 - - -#define SDIOH_FPGA_ID 0x43f2 -#define SPIH_FPGA_ID 0x43f5 -#define BCM4710_DEVICE_ID 0x4710 -#define BCM27XX_SDIOH_ID 0x2702 -#define PCIXX21_FLASHMEDIA0_ID 0x8033 -#define PCIXX21_SDIOH0_ID 0x8034 -#define PCIXX21_FLASHMEDIA_ID 0x803b -#define PCIXX21_SDIOH_ID 0x803c -#define R5C822_SDIOH_ID 0x0822 -#define JMICRON_SDIOH_ID 0x2381 - - -#define BCM4306_CHIP_ID 0x4306 -#define BCM4311_CHIP_ID 0x4311 -#define BCM4312_CHIP_ID 0x4312 -#define BCM4315_CHIP_ID 0x4315 -#define BCM4318_CHIP_ID 0x4318 -#define BCM4319_CHIP_ID 0x4319 -#define BCM4320_CHIP_ID 0x4320 -#define BCM4321_CHIP_ID 0x4321 -#define BCM4322_CHIP_ID 0x4322 -#define BCM4325_CHIP_ID 0x4325 -#define BCM4328_CHIP_ID 0x4328 -#define BCM4329_CHIP_ID 0x4329 -#define BCM4336_CHIP_ID 0x4336 -#define BCM4402_CHIP_ID 0x4402 -#define BCM4704_CHIP_ID 0x4704 -#define BCM4710_CHIP_ID 0x4710 -#define BCM4712_CHIP_ID 0x4712 -#define BCM4785_CHIP_ID 0x4785 -#define BCM5350_CHIP_ID 0x5350 -#define BCM5352_CHIP_ID 0x5352 -#define BCM5354_CHIP_ID 0x5354 -#define BCM5365_CHIP_ID 0x5365 - - - -#define BCM4303_PKG_ID 2 -#define BCM4309_PKG_ID 1 -#define BCM4712LARGE_PKG_ID 0 -#define BCM4712SMALL_PKG_ID 1 -#define BCM4712MID_PKG_ID 2 -#define BCM4328USBD11G_PKG_ID 2 -#define BCM4328USBDUAL_PKG_ID 3 -#define BCM4328SDIOD11G_PKG_ID 4 -#define BCM4328SDIODUAL_PKG_ID 5 -#define BCM4329_289PIN_PKG_ID 0 -#define BCM4329_182PIN_PKG_ID 1 -#define BCM5354E_PKG_ID 1 -#define HDLSIM5350_PKG_ID 1 -#define HDLSIM_PKG_ID 14 -#define HWSIM_PKG_ID 15 - - -#endif diff --git a/drivers/net/wireless/bcm4329/include/bcmendian.h b/drivers/net/wireless/bcm4329/include/bcmendian.h deleted file mode 100644 index ae468383aa74..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmendian.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Byte order utilities - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmendian.h,v 1.31.302.1.16.1 2009/02/03 18:34:31 Exp $ - * - * This file by default provides proper behavior on little-endian architectures. - * On big-endian architectures, IL_BIGENDIAN should be defined. - */ - - -#ifndef _BCMENDIAN_H_ -#define _BCMENDIAN_H_ - -#include - - -#define BCMSWAP16(val) \ - ((uint16)((((uint16)(val) & (uint16)0x00ffU) << 8) | \ - (((uint16)(val) & (uint16)0xff00U) >> 8))) - - -#define BCMSWAP32(val) \ - ((uint32)((((uint32)(val) & (uint32)0x000000ffU) << 24) | \ - (((uint32)(val) & (uint32)0x0000ff00U) << 8) | \ - (((uint32)(val) & (uint32)0x00ff0000U) >> 8) | \ - (((uint32)(val) & (uint32)0xff000000U) >> 24))) - - -#define BCMSWAP32BY16(val) \ - ((uint32)((((uint32)(val) & (uint32)0x0000ffffU) << 16) | \ - (((uint32)(val) & (uint32)0xffff0000U) >> 16))) - - -static INLINE uint16 -bcmswap16(uint16 val) -{ - return BCMSWAP16(val); -} - -static INLINE uint32 -bcmswap32(uint32 val) -{ - return BCMSWAP32(val); -} - -static INLINE uint32 -bcmswap32by16(uint32 val) -{ - return BCMSWAP32BY16(val); -} - - - - -static INLINE void -bcmswap16_buf(uint16 *buf, uint len) -{ - len = len / 2; - - while (len--) { - *buf = bcmswap16(*buf); - buf++; - } -} - -#ifndef hton16 -#ifndef IL_BIGENDIAN -#define HTON16(i) BCMSWAP16(i) -#define HTON32(i) BCMSWAP32(i) -#define hton16(i) bcmswap16(i) -#define hton32(i) bcmswap32(i) -#define ntoh16(i) bcmswap16(i) -#define ntoh32(i) bcmswap32(i) -#define HTOL16(i) (i) -#define HTOL32(i) (i) -#define ltoh16(i) (i) -#define ltoh32(i) (i) -#define htol16(i) (i) -#define htol32(i) (i) -#else -#define HTON16(i) (i) -#define HTON32(i) (i) -#define hton16(i) (i) -#define hton32(i) (i) -#define ntoh16(i) (i) -#define ntoh32(i) (i) -#define HTOL16(i) BCMSWAP16(i) -#define HTOL32(i) BCMSWAP32(i) -#define ltoh16(i) bcmswap16(i) -#define ltoh32(i) bcmswap32(i) -#define htol16(i) bcmswap16(i) -#define htol32(i) bcmswap32(i) -#endif -#endif - -#ifndef IL_BIGENDIAN -#define ltoh16_buf(buf, i) -#define htol16_buf(buf, i) -#else -#define ltoh16_buf(buf, i) bcmswap16_buf((uint16 *)buf, i) -#define htol16_buf(buf, i) bcmswap16_buf((uint16 *)buf, i) -#endif - - -static INLINE void -htol16_ua_store(uint16 val, uint8 *bytes) -{ - bytes[0] = val & 0xff; - bytes[1] = val >> 8; -} - - -static INLINE void -htol32_ua_store(uint32 val, uint8 *bytes) -{ - bytes[0] = val & 0xff; - bytes[1] = (val >> 8) & 0xff; - bytes[2] = (val >> 16) & 0xff; - bytes[3] = val >> 24; -} - - -static INLINE void -hton16_ua_store(uint16 val, uint8 *bytes) -{ - bytes[0] = val >> 8; - bytes[1] = val & 0xff; -} - - -static INLINE void -hton32_ua_store(uint32 val, uint8 *bytes) -{ - bytes[0] = val >> 24; - bytes[1] = (val >> 16) & 0xff; - bytes[2] = (val >> 8) & 0xff; - bytes[3] = val & 0xff; -} - -#define _LTOH16_UA(cp) ((cp)[0] | ((cp)[1] << 8)) -#define _LTOH32_UA(cp) ((cp)[0] | ((cp)[1] << 8) | ((cp)[2] << 16) | ((cp)[3] << 24)) -#define _NTOH16_UA(cp) (((cp)[0] << 8) | (cp)[1]) -#define _NTOH32_UA(cp) (((cp)[0] << 24) | ((cp)[1] << 16) | ((cp)[2] << 8) | (cp)[3]) - - -static INLINE uint16 -ltoh16_ua(const void *bytes) -{ - return _LTOH16_UA((const uint8 *)bytes); -} - - -static INLINE uint32 -ltoh32_ua(const void *bytes) -{ - return _LTOH32_UA((const uint8 *)bytes); -} - - -static INLINE uint16 -ntoh16_ua(const void *bytes) -{ - return _NTOH16_UA((const uint8 *)bytes); -} - - -static INLINE uint32 -ntoh32_ua(const void *bytes) -{ - return _NTOH32_UA((const uint8 *)bytes); -} - -#define ltoh_ua(ptr) \ - (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)ptr : \ - sizeof(*(ptr)) == sizeof(uint16) ? _LTOH16_UA((const uint8 *)ptr) : \ - sizeof(*(ptr)) == sizeof(uint32) ? _LTOH32_UA((const uint8 *)ptr) : \ - 0xfeedf00d) - -#define ntoh_ua(ptr) \ - (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)ptr : \ - sizeof(*(ptr)) == sizeof(uint16) ? _NTOH16_UA((const uint8 *)ptr) : \ - sizeof(*(ptr)) == sizeof(uint32) ? _NTOH32_UA((const uint8 *)ptr) : \ - 0xfeedf00d) - -#endif diff --git a/drivers/net/wireless/bcm4329/include/bcmpcispi.h b/drivers/net/wireless/bcm4329/include/bcmpcispi.h deleted file mode 100644 index 7d98fb7cbdc8..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmpcispi.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Broadcom PCI-SPI Host Controller Register Definitions - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmpcispi.h,v 13.11.8.3 2008/07/09 21:23:29 Exp $ - */ - -/* cpp contortions to concatenate w/arg prescan */ -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif /* PAD */ - -/* -+---------------------------------------------------------------------------+ -| | -| 7 6 5 4 3 2 1 0 | -| 0x0000 SPI_CTRL SPIE SPE 0 MSTR CPOL CPHA SPR1 SPR0 | -| 0x0004 SPI_STAT SPIF WCOL ST1 ST0 WFFUL WFEMP RFFUL RFEMP | -| 0x0008 SPI_DATA Bits 31:0, data to send out on MOSI | -| 0x000C SPI_EXT ICNT1 ICNT0 BSWAP *HSMODE ESPR1 ESPR0 | -| 0x0020 GPIO_OE 0=input, 1=output PWR_OE CS_OE | -| 0x0024 GPIO_DATA CARD:1=missing, 0=present CARD PWR_DAT CS_DAT | -| 0x0040 INT_EDGE 0=level, 1=edge DEV_E SPI_E | -| 0x0044 INT_POL 1=active high, 0=active low DEV_P SPI_P | -| 0x0048 INTMASK DEV SPI | -| 0x004C INTSTATUS DEV SPI | -| 0x0060 HEXDISP Reset value: 0x14e443f5. In hexdisp mode, value | -| shows on the Raggedstone1 4-digit 7-segment display. | -| 0x0064 CURRENT_MA Low 16 bits indicate card current consumption in mA | -| 0x006C DISP_SEL Display mode (0=hexdisp, 1=current) DSP | -| 0x00C0 PLL_CTL bit31=ext_clk, remainder unused. | -| 0x00C4 PLL_STAT LOCK | -| 0x00C8 CLK_FREQ | -| 0x00CC CLK_CNT | -| | -| *Notes: HSMODE is not implemented, never set this bit! | -| BSWAP is available in rev >= 8 | -| | -+---------------------------------------------------------------------------+ -*/ - -typedef volatile struct { - uint32 spih_ctrl; /* 0x00 SPI Control Register */ - uint32 spih_stat; /* 0x04 SPI Status Register */ - uint32 spih_data; /* 0x08 SPI Data Register, 32-bits wide */ - uint32 spih_ext; /* 0x0C SPI Extension Register */ - uint32 PAD[4]; /* 0x10-0x1F PADDING */ - - uint32 spih_gpio_ctrl; /* 0x20 SPI GPIO Control Register */ - uint32 spih_gpio_data; /* 0x24 SPI GPIO Data Register */ - uint32 PAD[6]; /* 0x28-0x3F PADDING */ - - uint32 spih_int_edge; /* 0x40 SPI Interrupt Edge Register (0=Level, 1=Edge) */ - uint32 spih_int_pol; /* 0x44 SPI Interrupt Polarity Register (0=Active Low, */ - /* 1=Active High) */ - uint32 spih_int_mask; /* 0x48 SPI Interrupt Mask */ - uint32 spih_int_status; /* 0x4C SPI Interrupt Status */ - uint32 PAD[4]; /* 0x50-0x5F PADDING */ - - uint32 spih_hex_disp; /* 0x60 SPI 4-digit hex display value */ - uint32 spih_current_ma; /* 0x64 SPI SD card current consumption in mA */ - uint32 PAD[1]; /* 0x68 PADDING */ - uint32 spih_disp_sel; /* 0x6c SPI 4-digit hex display mode select (1=current) */ - uint32 PAD[4]; /* 0x70-0x7F PADDING */ - uint32 PAD[8]; /* 0x80-0x9F PADDING */ - uint32 PAD[8]; /* 0xA0-0xBF PADDING */ - uint32 spih_pll_ctrl; /* 0xC0 PLL Control Register */ - uint32 spih_pll_status; /* 0xC4 PLL Status Register */ - uint32 spih_xtal_freq; /* 0xC8 External Clock Frequency in units of 10000Hz */ - uint32 spih_clk_count; /* 0xCC External Clock Count Register */ - -} spih_regs_t; - -typedef volatile struct { - uint32 cfg_space[0x40]; /* 0x000-0x0FF PCI Configuration Space (Read Only) */ - uint32 P_IMG_CTRL0; /* 0x100 PCI Image0 Control Register */ - - uint32 P_BA0; /* 0x104 32 R/W PCI Image0 Base Address register */ - uint32 P_AM0; /* 0x108 32 R/W PCI Image0 Address Mask register */ - uint32 P_TA0; /* 0x10C 32 R/W PCI Image0 Translation Address register */ - uint32 P_IMG_CTRL1; /* 0x110 32 R/W PCI Image1 Control register */ - uint32 P_BA1; /* 0x114 32 R/W PCI Image1 Base Address register */ - uint32 P_AM1; /* 0x118 32 R/W PCI Image1 Address Mask register */ - uint32 P_TA1; /* 0x11C 32 R/W PCI Image1 Translation Address register */ - uint32 P_IMG_CTRL2; /* 0x120 32 R/W PCI Image2 Control register */ - uint32 P_BA2; /* 0x124 32 R/W PCI Image2 Base Address register */ - uint32 P_AM2; /* 0x128 32 R/W PCI Image2 Address Mask register */ - uint32 P_TA2; /* 0x12C 32 R/W PCI Image2 Translation Address register */ - uint32 P_IMG_CTRL3; /* 0x130 32 R/W PCI Image3 Control register */ - uint32 P_BA3; /* 0x134 32 R/W PCI Image3 Base Address register */ - uint32 P_AM3; /* 0x138 32 R/W PCI Image3 Address Mask register */ - uint32 P_TA3; /* 0x13C 32 R/W PCI Image3 Translation Address register */ - uint32 P_IMG_CTRL4; /* 0x140 32 R/W PCI Image4 Control register */ - uint32 P_BA4; /* 0x144 32 R/W PCI Image4 Base Address register */ - uint32 P_AM4; /* 0x148 32 R/W PCI Image4 Address Mask register */ - uint32 P_TA4; /* 0x14C 32 R/W PCI Image4 Translation Address register */ - uint32 P_IMG_CTRL5; /* 0x150 32 R/W PCI Image5 Control register */ - uint32 P_BA5; /* 0x154 32 R/W PCI Image5 Base Address register */ - uint32 P_AM5; /* 0x158 32 R/W PCI Image5 Address Mask register */ - uint32 P_TA5; /* 0x15C 32 R/W PCI Image5 Translation Address register */ - uint32 P_ERR_CS; /* 0x160 32 R/W PCI Error Control and Status register */ - uint32 P_ERR_ADDR; /* 0x164 32 R PCI Erroneous Address register */ - uint32 P_ERR_DATA; /* 0x168 32 R PCI Erroneous Data register */ - - uint32 PAD[5]; /* 0x16C-0x17F PADDING */ - - uint32 WB_CONF_SPC_BAR; /* 0x180 32 R WISHBONE Configuration Space Base Address */ - uint32 W_IMG_CTRL1; /* 0x184 32 R/W WISHBONE Image1 Control register */ - uint32 W_BA1; /* 0x188 32 R/W WISHBONE Image1 Base Address register */ - uint32 W_AM1; /* 0x18C 32 R/W WISHBONE Image1 Address Mask register */ - uint32 W_TA1; /* 0x190 32 R/W WISHBONE Image1 Translation Address reg */ - uint32 W_IMG_CTRL2; /* 0x194 32 R/W WISHBONE Image2 Control register */ - uint32 W_BA2; /* 0x198 32 R/W WISHBONE Image2 Base Address register */ - uint32 W_AM2; /* 0x19C 32 R/W WISHBONE Image2 Address Mask register */ - uint32 W_TA2; /* 0x1A0 32 R/W WISHBONE Image2 Translation Address reg */ - uint32 W_IMG_CTRL3; /* 0x1A4 32 R/W WISHBONE Image3 Control register */ - uint32 W_BA3; /* 0x1A8 32 R/W WISHBONE Image3 Base Address register */ - uint32 W_AM3; /* 0x1AC 32 R/W WISHBONE Image3 Address Mask register */ - uint32 W_TA3; /* 0x1B0 32 R/W WISHBONE Image3 Translation Address reg */ - uint32 W_IMG_CTRL4; /* 0x1B4 32 R/W WISHBONE Image4 Control register */ - uint32 W_BA4; /* 0x1B8 32 R/W WISHBONE Image4 Base Address register */ - uint32 W_AM4; /* 0x1BC 32 R/W WISHBONE Image4 Address Mask register */ - uint32 W_TA4; /* 0x1C0 32 R/W WISHBONE Image4 Translation Address reg */ - uint32 W_IMG_CTRL5; /* 0x1C4 32 R/W WISHBONE Image5 Control register */ - uint32 W_BA5; /* 0x1C8 32 R/W WISHBONE Image5 Base Address register */ - uint32 W_AM5; /* 0x1CC 32 R/W WISHBONE Image5 Address Mask register */ - uint32 W_TA5; /* 0x1D0 32 R/W WISHBONE Image5 Translation Address reg */ - uint32 W_ERR_CS; /* 0x1D4 32 R/W WISHBONE Error Control and Status reg */ - uint32 W_ERR_ADDR; /* 0x1D8 32 R WISHBONE Erroneous Address register */ - uint32 W_ERR_DATA; /* 0x1DC 32 R WISHBONE Erroneous Data register */ - uint32 CNF_ADDR; /* 0x1E0 32 R/W Configuration Cycle register */ - uint32 CNF_DATA; /* 0x1E4 32 R/W Configuration Cycle Generation Data reg */ - - uint32 INT_ACK; /* 0x1E8 32 R Interrupt Acknowledge register */ - uint32 ICR; /* 0x1EC 32 R/W Interrupt Control register */ - uint32 ISR; /* 0x1F0 32 R/W Interrupt Status register */ -} spih_pciregs_t; - -/* - * PCI Core interrupt enable and status bit definitions. - */ - -/* PCI Core ICR Register bit definitions */ -#define PCI_INT_PROP_EN (1 << 0) /* Interrupt Propagation Enable */ -#define PCI_WB_ERR_INT_EN (1 << 1) /* Wishbone Error Interrupt Enable */ -#define PCI_PCI_ERR_INT_EN (1 << 2) /* PCI Error Interrupt Enable */ -#define PCI_PAR_ERR_INT_EN (1 << 3) /* Parity Error Interrupt Enable */ -#define PCI_SYS_ERR_INT_EN (1 << 4) /* System Error Interrupt Enable */ -#define PCI_SOFTWARE_RESET (1U << 31) /* Software reset of the PCI Core. */ - - -/* PCI Core ISR Register bit definitions */ -#define PCI_INT_PROP_ST (1 << 0) /* Interrupt Propagation Status */ -#define PCI_WB_ERR_INT_ST (1 << 1) /* Wishbone Error Interrupt Status */ -#define PCI_PCI_ERR_INT_ST (1 << 2) /* PCI Error Interrupt Status */ -#define PCI_PAR_ERR_INT_ST (1 << 3) /* Parity Error Interrupt Status */ -#define PCI_SYS_ERR_INT_ST (1 << 4) /* System Error Interrupt Status */ - - -/* Registers on the Wishbone bus */ -#define SPIH_CTLR_INTR (1 << 0) /* SPI Host Controller Core Interrupt */ -#define SPIH_DEV_INTR (1 << 1) /* SPI Device Interrupt */ -#define SPIH_WFIFO_INTR (1 << 2) /* SPI Tx FIFO Empty Intr (FPGA Rev >= 8) */ - -/* GPIO Bit definitions */ -#define SPIH_CS (1 << 0) /* SPI Chip Select (active low) */ -#define SPIH_SLOT_POWER (1 << 1) /* SD Card Slot Power Enable */ -#define SPIH_CARD_DETECT (1 << 2) /* SD Card Detect */ - -/* SPI Status Register Bit definitions */ -#define SPIH_STATE_MASK 0x30 /* SPI Transfer State Machine state mask */ -#define SPIH_STATE_SHIFT 4 /* SPI Transfer State Machine state shift */ -#define SPIH_WFFULL (1 << 3) /* SPI Write FIFO Full */ -#define SPIH_WFEMPTY (1 << 2) /* SPI Write FIFO Empty */ -#define SPIH_RFFULL (1 << 1) /* SPI Read FIFO Full */ -#define SPIH_RFEMPTY (1 << 0) /* SPI Read FIFO Empty */ - -#define SPIH_EXT_CLK (1U << 31) /* Use External Clock as PLL Clock source. */ - -#define SPIH_PLL_NO_CLK (1 << 1) /* Set to 1 if the PLL's input clock is lost. */ -#define SPIH_PLL_LOCKED (1 << 3) /* Set to 1 when the PLL is locked. */ - -/* Spin bit loop bound check */ -#define SPI_SPIN_BOUND 0xf4240 /* 1 million */ diff --git a/drivers/net/wireless/bcm4329/include/bcmperf.h b/drivers/net/wireless/bcm4329/include/bcmperf.h deleted file mode 100644 index 2a78784e85d3..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmperf.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Performance counters software interface. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmperf.h,v 13.5 2007/09/14 22:00:59 Exp $ - */ -/* essai */ -#ifndef _BCMPERF_H_ -#define _BCMPERF_H_ -/* get cache hits and misses */ -#define BCMPERF_ENABLE_INSTRCOUNT() -#define BCMPERF_ENABLE_ICACHE_MISS() -#define BCMPERF_ENABLE_ICACHE_HIT() -#define BCMPERF_GETICACHE_MISS(x) ((x) = 0) -#define BCMPERF_GETICACHE_HIT(x) ((x) = 0) -#define BCMPERF_GETINSTRCOUNT(x) ((x) = 0) -#endif /* _BCMPERF_H_ */ diff --git a/drivers/net/wireless/bcm4329/include/bcmsdbus.h b/drivers/net/wireless/bcm4329/include/bcmsdbus.h deleted file mode 100644 index b7b67bc66248..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmsdbus.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Definitions for API from sdio common code (bcmsdh) to individual - * host controller drivers. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdbus.h,v 13.11.14.2.6.6 2009/10/27 17:20:28 Exp $ - */ - -#ifndef _sdio_api_h_ -#define _sdio_api_h_ - - -#define SDIOH_API_RC_SUCCESS (0x00) -#define SDIOH_API_RC_FAIL (0x01) -#define SDIOH_API_SUCCESS(status) (status == 0) - -#define SDIOH_READ 0 /* Read request */ -#define SDIOH_WRITE 1 /* Write request */ - -#define SDIOH_DATA_FIX 0 /* Fixed addressing */ -#define SDIOH_DATA_INC 1 /* Incremental addressing */ - -#define SDIOH_CMD_TYPE_NORMAL 0 /* Normal command */ -#define SDIOH_CMD_TYPE_APPEND 1 /* Append command */ -#define SDIOH_CMD_TYPE_CUTTHRU 2 /* Cut-through command */ - -#define SDIOH_DATA_PIO 0 /* PIO mode */ -#define SDIOH_DATA_DMA 1 /* DMA mode */ - - -typedef int SDIOH_API_RC; - -/* SDio Host structure */ -typedef struct sdioh_info sdioh_info_t; - -/* callback function, taking one arg */ -typedef void (*sdioh_cb_fn_t)(void *); - -/* attach, return handler on success, NULL if failed. - * The handler shall be provided by all subsequent calls. No local cache - * cfghdl points to the starting address of pci device mapped memory - */ -extern sdioh_info_t * sdioh_attach(osl_t *osh, void *cfghdl, uint irq); -extern SDIOH_API_RC sdioh_detach(osl_t *osh, sdioh_info_t *si); -extern SDIOH_API_RC sdioh_interrupt_register(sdioh_info_t *si, sdioh_cb_fn_t fn, void *argh); -extern SDIOH_API_RC sdioh_interrupt_deregister(sdioh_info_t *si); - -/* query whether SD interrupt is enabled or not */ -extern SDIOH_API_RC sdioh_interrupt_query(sdioh_info_t *si, bool *onoff); - -/* enable or disable SD interrupt */ -extern SDIOH_API_RC sdioh_interrupt_set(sdioh_info_t *si, bool enable_disable); - -#if defined(DHD_DEBUG) -extern bool sdioh_interrupt_pending(sdioh_info_t *si); -#endif - -/* read or write one byte using cmd52 */ -extern SDIOH_API_RC sdioh_request_byte(sdioh_info_t *si, uint rw, uint fnc, uint addr, uint8 *byte); - -/* read or write 2/4 bytes using cmd53 */ -extern SDIOH_API_RC sdioh_request_word(sdioh_info_t *si, uint cmd_type, uint rw, uint fnc, - uint addr, uint32 *word, uint nbyte); - -/* read or write any buffer using cmd53 */ -extern SDIOH_API_RC sdioh_request_buffer(sdioh_info_t *si, uint pio_dma, uint fix_inc, - uint rw, uint fnc_num, uint32 addr, uint regwidth, uint32 buflen, uint8 *buffer, - void *pkt); - -/* get cis data */ -extern SDIOH_API_RC sdioh_cis_read(sdioh_info_t *si, uint fuc, uint8 *cis, uint32 length); - -extern SDIOH_API_RC sdioh_cfg_read(sdioh_info_t *si, uint fuc, uint32 addr, uint8 *data); -extern SDIOH_API_RC sdioh_cfg_write(sdioh_info_t *si, uint fuc, uint32 addr, uint8 *data); - -/* query number of io functions */ -extern uint sdioh_query_iofnum(sdioh_info_t *si); - -/* handle iovars */ -extern int sdioh_iovar_op(sdioh_info_t *si, const char *name, - void *params, int plen, void *arg, int len, bool set); - -/* Issue abort to the specified function and clear controller as needed */ -extern int sdioh_abort(sdioh_info_t *si, uint fnc); - -/* Start and Stop SDIO without re-enumerating the SD card. */ -extern int sdioh_start(sdioh_info_t *si, int stage); -extern int sdioh_stop(sdioh_info_t *si); - -/* Reset and re-initialize the device */ -extern int sdioh_sdio_reset(sdioh_info_t *si); - -/* Helper function */ -void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh); - - - -#endif /* _sdio_api_h_ */ diff --git a/drivers/net/wireless/bcm4329/include/bcmsdh.h b/drivers/net/wireless/bcm4329/include/bcmsdh.h deleted file mode 100644 index f5dee5c58445..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmsdh.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - * SDIO host client driver interface of Broadcom HNBU - * export functions to client drivers - * abstract OS and BUS specific details of SDIO - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdh.h,v 13.35.14.7.6.8 2009/10/14 04:22:25 Exp $ - */ - -#ifndef _bcmsdh_h_ -#define _bcmsdh_h_ - -#define BCMSDH_ERROR_VAL 0x0001 /* Error */ -#define BCMSDH_INFO_VAL 0x0002 /* Info */ -extern const uint bcmsdh_msglevel; - -#define BCMSDH_ERROR(x) -#define BCMSDH_INFO(x) - -/* forward declarations */ -typedef struct bcmsdh_info bcmsdh_info_t; -typedef void (*bcmsdh_cb_fn_t)(void *); - -/* Attach and build an interface to the underlying SD host driver. - * - Allocates resources (structs, arrays, mem, OS handles, etc) needed by bcmsdh. - * - Returns the bcmsdh handle and virtual address base for register access. - * The returned handle should be used in all subsequent calls, but the bcmsh - * implementation may maintain a single "default" handle (e.g. the first or - * most recent one) to enable single-instance implementations to pass NULL. - */ -extern bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq); - -/* Detach - freeup resources allocated in attach */ -extern int bcmsdh_detach(osl_t *osh, void *sdh); - -/* Query if SD device interrupts are enabled */ -extern bool bcmsdh_intr_query(void *sdh); - -/* Enable/disable SD interrupt */ -extern int bcmsdh_intr_enable(void *sdh); -extern int bcmsdh_intr_disable(void *sdh); - -/* Register/deregister device interrupt handler. */ -extern int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh); -extern int bcmsdh_intr_dereg(void *sdh); - -#if defined(DHD_DEBUG) -/* Query pending interrupt status from the host controller */ -extern bool bcmsdh_intr_pending(void *sdh); -#endif - -#ifdef BCMLXSDMMC -extern int bcmsdh_claim_host_and_lock(void *sdh); -extern int bcmsdh_release_host_and_unlock(void *sdh); -#endif /* BCMLXSDMMC */ - -/* Register a callback to be called if and when bcmsdh detects - * device removal. No-op in the case of non-removable/hardwired devices. - */ -extern int bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh); - -/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface). - * fn: function number - * addr: unmodified SDIO-space address - * data: data byte to write - * err: pointer to error code (or NULL) - */ -extern uint8 bcmsdh_cfg_read(void *sdh, uint func, uint32 addr, int *err); -extern void bcmsdh_cfg_write(void *sdh, uint func, uint32 addr, uint8 data, int *err); - -/* Read/Write 4bytes from/to cfg space */ -extern uint32 bcmsdh_cfg_read_word(void *sdh, uint fnc_num, uint32 addr, int *err); -extern void bcmsdh_cfg_write_word(void *sdh, uint fnc_num, uint32 addr, uint32 data, int *err); - -/* Read CIS content for specified function. - * fn: function whose CIS is being requested (0 is common CIS) - * cis: pointer to memory location to place results - * length: number of bytes to read - * Internally, this routine uses the values from the cis base regs (0x9-0xB) - * to form an SDIO-space address to read the data from. - */ -extern int bcmsdh_cis_read(void *sdh, uint func, uint8 *cis, uint length); - -/* Synchronous access to device (client) core registers via CMD53 to F1. - * addr: backplane address (i.e. >= regsva from attach) - * size: register width in bytes (2 or 4) - * data: data for register write - */ -extern uint32 bcmsdh_reg_read(void *sdh, uint32 addr, uint size); -extern uint32 bcmsdh_reg_write(void *sdh, uint32 addr, uint size, uint32 data); - -/* Indicate if last reg read/write failed */ -extern bool bcmsdh_regfail(void *sdh); - -/* Buffer transfer to/from device (client) core via cmd53. - * fn: function number - * addr: backplane address (i.e. >= regsva from attach) - * flags: backplane width, address increment, sync/async - * buf: pointer to memory data buffer - * nbytes: number of bytes to transfer to/from buf - * pkt: pointer to packet associated with buf (if any) - * complete: callback function for command completion (async only) - * handle: handle for completion callback (first arg in callback) - * Returns 0 or error code. - * NOTE: Async operation is not currently supported. - */ -typedef void (*bcmsdh_cmplt_fn_t)(void *handle, int status, bool sync_waiting); -extern int bcmsdh_send_buf(void *sdh, uint32 addr, uint fn, uint flags, - uint8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete, void *handle); -extern int bcmsdh_recv_buf(void *sdh, uint32 addr, uint fn, uint flags, - uint8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete, void *handle); - -/* Flags bits */ -#define SDIO_REQ_4BYTE 0x1 /* Four-byte target (backplane) width (vs. two-byte) */ -#define SDIO_REQ_FIXED 0x2 /* Fixed address (FIFO) (vs. incrementing address) */ -#define SDIO_REQ_ASYNC 0x4 /* Async request (vs. sync request) */ - -/* Pending (non-error) return code */ -#define BCME_PENDING 1 - -/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only). - * rw: read or write (0/1) - * addr: direct SDIO address - * buf: pointer to memory data buffer - * nbytes: number of bytes to transfer to/from buf - * Returns 0 or error code. - */ -extern int bcmsdh_rwdata(void *sdh, uint rw, uint32 addr, uint8 *buf, uint nbytes); - -/* Issue an abort to the specified function */ -extern int bcmsdh_abort(void *sdh, uint fn); - -/* Start SDIO Host Controller communication */ -extern int bcmsdh_start(void *sdh, int stage); - -/* Stop SDIO Host Controller communication */ -extern int bcmsdh_stop(void *sdh); - -/* Returns the "Device ID" of target device on the SDIO bus. */ -extern int bcmsdh_query_device(void *sdh); - -/* Returns the number of IO functions reported by the device */ -extern uint bcmsdh_query_iofnum(void *sdh); - -/* Miscellaneous knob tweaker. */ -extern int bcmsdh_iovar_op(void *sdh, const char *name, - void *params, int plen, void *arg, int len, bool set); - -/* Reset and reinitialize the device */ -extern int bcmsdh_reset(bcmsdh_info_t *sdh); - -/* helper functions */ - -extern void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh); - -/* callback functions */ -typedef struct { - /* attach to device */ - void *(*attach)(uint16 vend_id, uint16 dev_id, uint16 bus, uint16 slot, - uint16 func, uint bustype, void * regsva, osl_t * osh, - void * param); - /* detach from device */ - void (*detach)(void *ch); -} bcmsdh_driver_t; - -/* platform specific/high level functions */ -extern int bcmsdh_register(bcmsdh_driver_t *driver); -extern void bcmsdh_unregister(void); -extern bool bcmsdh_chipmatch(uint16 vendor, uint16 device); -extern void bcmsdh_device_remove(void * sdh); - -#if defined(OOB_INTR_ONLY) -extern int bcmsdh_register_oob_intr(void * dhdp); -extern void bcmsdh_unregister_oob_intr(void); -extern void bcmsdh_oob_intr_set(bool enable); -#endif /* defined(OOB_INTR_ONLY) */ -/* Function to pass device-status bits to DHD. */ -extern uint32 bcmsdh_get_dstatus(void *sdh); - -/* Function to return current window addr */ -extern uint32 bcmsdh_cur_sbwad(void *sdh); - -/* Function to pass chipid and rev to lower layers for controlling pr's */ -extern void bcmsdh_chipinfo(void *sdh, uint32 chip, uint32 chiprev); - - -#endif /* _bcmsdh_h_ */ diff --git a/drivers/net/wireless/bcm4329/include/bcmsdh_sdmmc.h b/drivers/net/wireless/bcm4329/include/bcmsdh_sdmmc.h deleted file mode 100644 index 4e6d1b5bd94f..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmsdh_sdmmc.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdh_sdmmc.h,v 13.1.2.1.8.7 2009/10/27 18:22:52 Exp $ - */ - -#ifndef __BCMSDH_SDMMC_H__ -#define __BCMSDH_SDMMC_H__ - -#define sd_err(x) -#define sd_trace(x) -#define sd_info(x) -#define sd_debug(x) -#define sd_data(x) -#define sd_ctrl(x) - -#define sd_sync_dma(sd, read, nbytes) -#define sd_init_dma(sd) -#define sd_ack_intr(sd) -#define sd_wakeup(sd); - -/* Allocate/init/free per-OS private data */ -extern int sdioh_sdmmc_osinit(sdioh_info_t *sd); -extern void sdioh_sdmmc_osfree(sdioh_info_t *sd); - -#define sd_log(x) - -#define SDIOH_ASSERT(exp) \ - do { if (!(exp)) \ - printf("!!!ASSERT fail: file %s lines %d", __FILE__, __LINE__); \ - } while (0) - -#define BLOCK_SIZE_4318 64 -#define BLOCK_SIZE_4328 512 - -/* internal return code */ -#define SUCCESS 0 -#define ERROR 1 - -/* private bus modes */ -#define SDIOH_MODE_SD4 2 -#define CLIENT_INTR 0x100 /* Get rid of this! */ - -struct sdioh_info { - osl_t *osh; /* osh handler */ - bool client_intr_enabled; /* interrupt connnected flag */ - bool intr_handler_valid; /* client driver interrupt handler valid */ - sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ - void *intr_handler_arg; /* argument to call interrupt handler */ - uint16 intmask; /* Current active interrupts */ - void *sdos_info; /* Pointer to per-OS private data */ - - uint irq; /* Client irq */ - int intrcount; /* Client interrupts */ - - bool sd_use_dma; /* DMA on CMD53 */ - bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */ - /* Must be on for sd_multiblock to be effective */ - bool use_client_ints; /* If this is false, make sure to restore */ - int sd_mode; /* SD1/SD4/SPI */ - int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */ - uint8 num_funcs; /* Supported funcs on client */ - uint32 com_cis_ptr; - uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; - uint max_dma_len; - uint max_dma_descriptors; /* DMA Descriptors supported by this controller. */ -// SDDMA_DESCRIPTOR SGList[32]; /* Scatter/Gather DMA List */ -}; - -/************************************************************ - * Internal interfaces: per-port references into bcmsdh_sdmmc.c - */ - -/* Global message bits */ -extern uint sd_msglevel; - -/* OS-independent interrupt handler */ -extern bool check_client_intr(sdioh_info_t *sd); - -/* Core interrupt enable/disable of device interrupts */ -extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd); -extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd); - - -/************************************************************** - * Internal interfaces: bcmsdh_sdmmc.c references to per-port code - */ - -/* Register mapping routines */ -extern uint32 *sdioh_sdmmc_reg_map(osl_t *osh, int32 addr, int size); -extern void sdioh_sdmmc_reg_unmap(osl_t *osh, int32 addr, int size); - -/* Interrupt (de)registration routines */ -extern int sdioh_sdmmc_register_irq(sdioh_info_t *sd, uint irq); -extern void sdioh_sdmmc_free_irq(uint irq, sdioh_info_t *sd); - -typedef struct _BCMSDH_SDMMC_INSTANCE { - sdioh_info_t *sd; - struct sdio_func *func[SDIOD_MAX_IOFUNCS]; -} BCMSDH_SDMMC_INSTANCE, *PBCMSDH_SDMMC_INSTANCE; - -#endif /* __BCMSDH_SDMMC_H__ */ diff --git a/drivers/net/wireless/bcm4329/include/bcmsdpcm.h b/drivers/net/wireless/bcm4329/include/bcmsdpcm.h deleted file mode 100644 index 77aca4500ad8..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmsdpcm.h +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Broadcom SDIO/PCMCIA - * Software-specific definitions shared between device and host side - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdpcm.h,v 1.1.2.4 2010/07/02 01:15:46 Exp $ - */ - -#ifndef _bcmsdpcm_h_ -#define _bcmsdpcm_h_ - -/* - * Software allocation of To SB Mailbox resources - */ - -/* intstatus bits */ -#define I_SMB_NAK I_SMB_SW0 /* To SB Mailbox Frame NAK */ -#define I_SMB_INT_ACK I_SMB_SW1 /* To SB Mailbox Host Interrupt ACK */ -#define I_SMB_USE_OOB I_SMB_SW2 /* To SB Mailbox Use OOB Wakeup */ -#define I_SMB_DEV_INT I_SMB_SW3 /* To SB Mailbox Miscellaneous Interrupt */ - -/* tosbmailbox bits corresponding to intstatus bits */ -#define SMB_NAK (1 << 0) /* To SB Mailbox Frame NAK */ -#define SMB_INT_ACK (1 << 1) /* To SB Mailbox Host Interrupt ACK */ -#define SMB_USE_OOB (1 << 2) /* To SB Mailbox Use OOB Wakeup */ -#define SMB_DEV_INT (1 << 3) /* To SB Mailbox Miscellaneous Interrupt */ -#define SMB_MASK 0x0000000f /* To SB Mailbox Mask */ - -/* tosbmailboxdata */ -#define SMB_DATA_VERSION_MASK 0x00ff0000 /* host protocol version (sent with F2 enable) */ -#define SMB_DATA_VERSION_SHIFT 16 /* host protocol version (sent with F2 enable) */ - -/* - * Software allocation of To Host Mailbox resources - */ - -/* intstatus bits */ -#define I_HMB_FC_STATE I_HMB_SW0 /* To Host Mailbox Flow Control State */ -#define I_HMB_FC_CHANGE I_HMB_SW1 /* To Host Mailbox Flow Control State Changed */ -#define I_HMB_FRAME_IND I_HMB_SW2 /* To Host Mailbox Frame Indication */ -#define I_HMB_HOST_INT I_HMB_SW3 /* To Host Mailbox Miscellaneous Interrupt */ - -/* tohostmailbox bits corresponding to intstatus bits */ -#define HMB_FC_ON (1 << 0) /* To Host Mailbox Flow Control State */ -#define HMB_FC_CHANGE (1 << 1) /* To Host Mailbox Flow Control State Changed */ -#define HMB_FRAME_IND (1 << 2) /* To Host Mailbox Frame Indication */ -#define HMB_HOST_INT (1 << 3) /* To Host Mailbox Miscellaneous Interrupt */ -#define HMB_MASK 0x0000000f /* To Host Mailbox Mask */ - -/* tohostmailboxdata */ -#define HMB_DATA_NAKHANDLED 1 /* we're ready to retransmit NAK'd frame to host */ -#define HMB_DATA_DEVREADY 2 /* we're ready to to talk to host after enable */ -#define HMB_DATA_FC 4 /* per prio flowcontrol update flag to host */ -#define HMB_DATA_FWREADY 8 /* firmware is ready for protocol activity */ - -#define HMB_DATA_FCDATA_MASK 0xff000000 /* per prio flowcontrol data */ -#define HMB_DATA_FCDATA_SHIFT 24 /* per prio flowcontrol data */ - -#define HMB_DATA_VERSION_MASK 0x00ff0000 /* device protocol version (with devready) */ -#define HMB_DATA_VERSION_SHIFT 16 /* device protocol version (with devready) */ - -/* - * Software-defined protocol header - */ - -/* Current protocol version */ -#define SDPCM_PROT_VERSION 4 - -/* SW frame header */ -#define SDPCM_SEQUENCE_MASK 0x000000ff /* Sequence Number Mask */ -#define SDPCM_PACKET_SEQUENCE(p) (((uint8 *)p)[0] & 0xff) /* p starts w/SW Header */ - -#define SDPCM_CHANNEL_MASK 0x00000f00 /* Channel Number Mask */ -#define SDPCM_CHANNEL_SHIFT 8 /* Channel Number Shift */ -#define SDPCM_PACKET_CHANNEL(p) (((uint8 *)p)[1] & 0x0f) /* p starts w/SW Header */ - -#define SDPCM_FLAGS_MASK 0x0000f000 /* Mask of flag bits */ -#define SDPCM_FLAGS_SHIFT 12 /* Flag bits shift */ -#define SDPCM_PACKET_FLAGS(p) ((((uint8 *)p)[1] & 0xf0) >> 4) /* p starts w/SW Header */ - -/* Next Read Len: lookahead length of next frame, in 16-byte units (rounded up) */ -#define SDPCM_NEXTLEN_MASK 0x00ff0000 /* Next Read Len Mask */ -#define SDPCM_NEXTLEN_SHIFT 16 /* Next Read Len Shift */ -#define SDPCM_NEXTLEN_VALUE(p) ((((uint8 *)p)[2] & 0xff) << 4) /* p starts w/SW Header */ -#define SDPCM_NEXTLEN_OFFSET 2 - -/* Data Offset from SOF (HW Tag, SW Tag, Pad) */ -#define SDPCM_DOFFSET_OFFSET 3 /* Data Offset */ -#define SDPCM_DOFFSET_VALUE(p) (((uint8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff) -#define SDPCM_DOFFSET_MASK 0xff000000 -#define SDPCM_DOFFSET_SHIFT 24 - -#define SDPCM_FCMASK_OFFSET 4 /* Flow control */ -#define SDPCM_FCMASK_VALUE(p) (((uint8 *)p)[SDPCM_FCMASK_OFFSET ] & 0xff) -#define SDPCM_WINDOW_OFFSET 5 /* Credit based fc */ -#define SDPCM_WINDOW_VALUE(p) (((uint8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff) -#define SDPCM_VERSION_OFFSET 6 /* Version # */ -#define SDPCM_VERSION_VALUE(p) (((uint8 *)p)[SDPCM_VERSION_OFFSET] & 0xff) -#define SDPCM_UNUSED_OFFSET 7 /* Spare */ -#define SDPCM_UNUSED_VALUE(p) (((uint8 *)p)[SDPCM_UNUSED_OFFSET] & 0xff) - -#define SDPCM_SWHEADER_LEN 8 /* SW header is 64 bits */ - -/* logical channel numbers */ -#define SDPCM_CONTROL_CHANNEL 0 /* Control Request/Response Channel Id */ -#define SDPCM_EVENT_CHANNEL 1 /* Asyc Event Indication Channel Id */ -#define SDPCM_DATA_CHANNEL 2 /* Data Xmit/Recv Channel Id */ -#define SDPCM_GLOM_CHANNEL 3 /* For coalesced packets (superframes) */ -#define SDPCM_TEST_CHANNEL 15 /* Reserved for test/debug packets */ -#define SDPCM_MAX_CHANNEL 15 - -#define SDPCM_SEQUENCE_WRAP 256 /* wrap-around val for eight-bit frame seq number */ - -#define SDPCM_FLAG_RESVD0 0x01 -#define SDPCM_FLAG_RESVD1 0x02 -#define SDPCM_FLAG_GSPI_TXENAB 0x04 -#define SDPCM_FLAG_GLOMDESC 0x08 /* Superframe descriptor mask */ - -/* For GLOM_CHANNEL frames, use a flag to indicate descriptor frame */ -#define SDPCM_GLOMDESC_FLAG (SDPCM_FLAG_GLOMDESC << SDPCM_FLAGS_SHIFT) - -#define SDPCM_GLOMDESC(p) (((uint8 *)p)[1] & 0x80) - -/* For TEST_CHANNEL packets, define another 4-byte header */ -#define SDPCM_TEST_HDRLEN 4 /* Generally: Cmd(1), Ext(1), Len(2); - * Semantics of Ext byte depend on command. - * Len is current or requested frame length, not - * including test header; sent little-endian. - */ -#define SDPCM_TEST_DISCARD 0x01 /* Receiver discards. Ext is a pattern id. */ -#define SDPCM_TEST_ECHOREQ 0x02 /* Echo request. Ext is a pattern id. */ -#define SDPCM_TEST_ECHORSP 0x03 /* Echo response. Ext is a pattern id. */ -#define SDPCM_TEST_BURST 0x04 /* Receiver to send a burst. Ext is a frame count */ -#define SDPCM_TEST_SEND 0x05 /* Receiver sets send mode. Ext is boolean on/off */ - -/* Handy macro for filling in datagen packets with a pattern */ -#define SDPCM_TEST_FILL(byteno, id) ((uint8)(id + byteno)) - -/* - * Software counters (first part matches hardware counters) - */ - -typedef volatile struct { - uint32 cmd52rd; /* Cmd52RdCount, SDIO: cmd52 reads */ - uint32 cmd52wr; /* Cmd52WrCount, SDIO: cmd52 writes */ - uint32 cmd53rd; /* Cmd53RdCount, SDIO: cmd53 reads */ - uint32 cmd53wr; /* Cmd53WrCount, SDIO: cmd53 writes */ - uint32 abort; /* AbortCount, SDIO: aborts */ - uint32 datacrcerror; /* DataCrcErrorCount, SDIO: frames w/CRC error */ - uint32 rdoutofsync; /* RdOutOfSyncCount, SDIO/PCMCIA: Rd Frm out of sync */ - uint32 wroutofsync; /* RdOutOfSyncCount, SDIO/PCMCIA: Wr Frm out of sync */ - uint32 writebusy; /* WriteBusyCount, SDIO: device asserted "busy" */ - uint32 readwait; /* ReadWaitCount, SDIO: no data ready for a read cmd */ - uint32 readterm; /* ReadTermCount, SDIO: read frame termination cmds */ - uint32 writeterm; /* WriteTermCount, SDIO: write frames termination cmds */ - uint32 rxdescuflo; /* receive descriptor underflows */ - uint32 rxfifooflo; /* receive fifo overflows */ - uint32 txfifouflo; /* transmit fifo underflows */ - uint32 runt; /* runt (too short) frames recv'd from bus */ - uint32 badlen; /* frame's rxh len does not match its hw tag len */ - uint32 badcksum; /* frame's hw tag chksum doesn't agree with len value */ - uint32 seqbreak; /* break in sequence # space from one rx frame to the next */ - uint32 rxfcrc; /* frame rx header indicates crc error */ - uint32 rxfwoos; /* frame rx header indicates write out of sync */ - uint32 rxfwft; /* frame rx header indicates write frame termination */ - uint32 rxfabort; /* frame rx header indicates frame aborted */ - uint32 woosint; /* write out of sync interrupt */ - uint32 roosint; /* read out of sync interrupt */ - uint32 rftermint; /* read frame terminate interrupt */ - uint32 wftermint; /* write frame terminate interrupt */ -} sdpcmd_cnt_t; - -/* - * Register Access Macros - */ - -#define SDIODREV_IS(var, val) ((var) == (val)) -#define SDIODREV_GE(var, val) ((var) >= (val)) -#define SDIODREV_GT(var, val) ((var) > (val)) -#define SDIODREV_LT(var, val) ((var) < (val)) -#define SDIODREV_LE(var, val) ((var) <= (val)) - -#define SDIODDMAREG32(h, dir, chnl) \ - ((dir) == DMA_TX ? \ - (void *)(uintptr)&((h)->regs->dma.sdiod32.dma32regs[chnl].xmt) : \ - (void *)(uintptr)&((h)->regs->dma.sdiod32.dma32regs[chnl].rcv)) - -#define SDIODDMAREG64(h, dir, chnl) \ - ((dir) == DMA_TX ? \ - (void *)(uintptr)&((h)->regs->dma.sdiod64.dma64regs[chnl].xmt) : \ - (void *)(uintptr)&((h)->regs->dma.sdiod64.dma64regs[chnl].rcv)) - -#define SDIODDMAREG(h, dir, chnl) \ - (SDIODREV_LT((h)->corerev, 1) ? \ - SDIODDMAREG32((h), (dir), (chnl)) : \ - SDIODDMAREG64((h), (dir), (chnl))) - -#define PCMDDMAREG(h, dir, chnl) \ - ((dir) == DMA_TX ? \ - (void *)(uintptr)&((h)->regs->dma.pcm32.dmaregs.xmt) : \ - (void *)(uintptr)&((h)->regs->dma.pcm32.dmaregs.rcv)) - -#define SDPCMDMAREG(h, dir, chnl, coreid) \ - ((coreid) == SDIOD_CORE_ID ? \ - SDIODDMAREG(h, dir, chnl) : \ - PCMDDMAREG(h, dir, chnl)) - -#define SDIODFIFOREG(h, corerev) \ - (SDIODREV_LT((corerev), 1) ? \ - ((dma32diag_t *)(uintptr)&((h)->regs->dma.sdiod32.dmafifo)) : \ - ((dma32diag_t *)(uintptr)&((h)->regs->dma.sdiod64.dmafifo))) - -#define PCMDFIFOREG(h) \ - ((dma32diag_t *)(uintptr)&((h)->regs->dma.pcm32.dmafifo)) - -#define SDPCMFIFOREG(h, coreid, corerev) \ - ((coreid) == SDIOD_CORE_ID ? \ - SDIODFIFOREG(h, corerev) : \ - PCMDFIFOREG(h)) - -/* - * Shared structure between dongle and the host - * The structure contains pointers to trap or assert information shared with the host - */ -#define SDPCM_SHARED_VERSION 0x0002 -#define SDPCM_SHARED_VERSION_MASK 0x00FF -#define SDPCM_SHARED_ASSERT_BUILT 0x0100 -#define SDPCM_SHARED_ASSERT 0x0200 -#define SDPCM_SHARED_TRAP 0x0400 - -typedef struct { - uint32 flags; - uint32 trap_addr; - uint32 assert_exp_addr; - uint32 assert_file_addr; - uint32 assert_line; - uint32 console_addr; /* Address of hndrte_cons_t */ - uint32 msgtrace_addr; - uint8 tag[32]; -} sdpcm_shared_t; - -extern sdpcm_shared_t sdpcm_shared; - -#endif /* _bcmsdpcm_h_ */ diff --git a/drivers/net/wireless/bcm4329/include/bcmsdspi.h b/drivers/net/wireless/bcm4329/include/bcmsdspi.h deleted file mode 100644 index eaae10d8bf19..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmsdspi.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * SD-SPI Protocol Conversion - BCMSDH->SPI Translation Layer - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdspi.h,v 13.8.10.2 2008/06/30 21:09:40 Exp $ - */ - -/* global msglevel for debug messages - bitvals come from sdiovar.h */ - -#define sd_err(x) -#define sd_trace(x) -#define sd_info(x) -#define sd_debug(x) -#define sd_data(x) -#define sd_ctrl(x) - -#define sd_log(x) - -#define SDIOH_ASSERT(exp) \ - do { if (!(exp)) \ - printf("!!!ASSERT fail: file %s lines %d", __FILE__, __LINE__); \ - } while (0) - -#define BLOCK_SIZE_4318 64 -#define BLOCK_SIZE_4328 512 - -/* internal return code */ -#define SUCCESS 0 -#undef ERROR -#define ERROR 1 - -/* private bus modes */ -#define SDIOH_MODE_SPI 0 - -#define USE_BLOCKMODE 0x2 /* Block mode can be single block or multi */ -#define USE_MULTIBLOCK 0x4 - -struct sdioh_info { - uint cfg_bar; /* pci cfg address for bar */ - uint32 caps; /* cached value of capabilities reg */ - uint bar0; /* BAR0 for PCI Device */ - osl_t *osh; /* osh handler */ - void *controller; /* Pointer to SPI Controller's private data struct */ - - uint lockcount; /* nest count of sdspi_lock() calls */ - bool client_intr_enabled; /* interrupt connnected flag */ - bool intr_handler_valid; /* client driver interrupt handler valid */ - sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ - void *intr_handler_arg; /* argument to call interrupt handler */ - bool initialized; /* card initialized */ - uint32 target_dev; /* Target device ID */ - uint32 intmask; /* Current active interrupts */ - void *sdos_info; /* Pointer to per-OS private data */ - - uint32 controller_type; /* Host controller type */ - uint8 version; /* Host Controller Spec Compliance Version */ - uint irq; /* Client irq */ - uint32 intrcount; /* Client interrupts */ - uint32 local_intrcount; /* Controller interrupts */ - bool host_init_done; /* Controller initted */ - bool card_init_done; /* Client SDIO interface initted */ - bool polled_mode; /* polling for command completion */ - - bool sd_use_dma; /* DMA on CMD53 */ - bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */ - /* Must be on for sd_multiblock to be effective */ - bool use_client_ints; /* If this is false, make sure to restore */ - bool got_hcint; /* Host Controller interrupt. */ - /* polling hack in wl_linux.c:wl_timer() */ - int adapter_slot; /* Maybe dealing with multiple slots/controllers */ - int sd_mode; /* SD1/SD4/SPI */ - int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */ - uint32 data_xfer_count; /* Current register transfer size */ - uint32 cmd53_wr_data; /* Used to pass CMD53 write data */ - uint32 card_response; /* Used to pass back response status byte */ - uint32 card_rsp_data; /* Used to pass back response data word */ - uint16 card_rca; /* Current Address */ - uint8 num_funcs; /* Supported funcs on client */ - uint32 com_cis_ptr; - uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; - void *dma_buf; - ulong dma_phys; - int r_cnt; /* rx count */ - int t_cnt; /* tx_count */ -}; - -/************************************************************ - * Internal interfaces: per-port references into bcmsdspi.c - */ - -/* Global message bits */ -extern uint sd_msglevel; - -/************************************************************** - * Internal interfaces: bcmsdspi.c references to per-port code - */ - -/* Register mapping routines */ -extern uint32 *spi_reg_map(osl_t *osh, uintptr addr, int size); -extern void spi_reg_unmap(osl_t *osh, uintptr addr, int size); - -/* Interrupt (de)registration routines */ -extern int spi_register_irq(sdioh_info_t *sd, uint irq); -extern void spi_free_irq(uint irq, sdioh_info_t *sd); - -/* OS-specific interrupt wrappers (atomic interrupt enable/disable) */ -extern void spi_lock(sdioh_info_t *sd); -extern void spi_unlock(sdioh_info_t *sd); - -/* Allocate/init/free per-OS private data */ -extern int spi_osinit(sdioh_info_t *sd); -extern void spi_osfree(sdioh_info_t *sd); diff --git a/drivers/net/wireless/bcm4329/include/bcmsdstd.h b/drivers/net/wireless/bcm4329/include/bcmsdstd.h deleted file mode 100644 index 974b3d41698d..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmsdstd.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - * 'Standard' SDIO HOST CONTROLLER driver - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdstd.h,v 13.16.18.1.16.3 2009/12/10 01:09:23 Exp $ - */ - -/* global msglevel for debug messages - bitvals come from sdiovar.h */ - -#define sd_err(x) do { if (sd_msglevel & SDH_ERROR_VAL) printf x; } while (0) -#define sd_trace(x) -#define sd_info(x) -#define sd_debug(x) -#define sd_data(x) -#define sd_ctrl(x) -#define sd_dma(x) - -#define sd_sync_dma(sd, read, nbytes) -#define sd_init_dma(sd) -#define sd_ack_intr(sd) -#define sd_wakeup(sd); -/* Allocate/init/free per-OS private data */ -extern int sdstd_osinit(sdioh_info_t *sd); -extern void sdstd_osfree(sdioh_info_t *sd); - -#define sd_log(x) - -#define SDIOH_ASSERT(exp) \ - do { if (!(exp)) \ - printf("!!!ASSERT fail: file %s lines %d", __FILE__, __LINE__); \ - } while (0) - -#define BLOCK_SIZE_4318 64 -#define BLOCK_SIZE_4328 512 - -/* internal return code */ -#define SUCCESS 0 -#define ERROR 1 - -/* private bus modes */ -#define SDIOH_MODE_SPI 0 -#define SDIOH_MODE_SD1 1 -#define SDIOH_MODE_SD4 2 - -#define MAX_SLOTS 6 /* For PCI: Only 6 BAR entries => 6 slots */ -#define SDIOH_REG_WINSZ 0x100 /* Number of registers in Standard Host Controller */ - -#define SDIOH_TYPE_ARASAN_HDK 1 -#define SDIOH_TYPE_BCM27XX 2 -#define SDIOH_TYPE_TI_PCIXX21 4 /* TI PCIxx21 Standard Host Controller */ -#define SDIOH_TYPE_RICOH_R5C822 5 /* Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter */ -#define SDIOH_TYPE_JMICRON 6 /* JMicron Standard SDIO Host Controller */ - -/* For linux, allow yielding for dongle */ -#define BCMSDYIELD - -/* Expected card status value for CMD7 */ -#define SDIOH_CMD7_EXP_STATUS 0x00001E00 - -#define RETRIES_LARGE 100000 -#define RETRIES_SMALL 100 - - -#define USE_BLOCKMODE 0x2 /* Block mode can be single block or multi */ -#define USE_MULTIBLOCK 0x4 - -#define USE_FIFO 0x8 /* Fifo vs non-fifo */ - -#define CLIENT_INTR 0x100 /* Get rid of this! */ - - -struct sdioh_info { - uint cfg_bar; /* pci cfg address for bar */ - uint32 caps; /* cached value of capabilities reg */ - uint32 curr_caps; /* max current capabilities reg */ - - osl_t *osh; /* osh handler */ - volatile char *mem_space; /* pci device memory va */ - uint lockcount; /* nest count of sdstd_lock() calls */ - bool client_intr_enabled; /* interrupt connnected flag */ - bool intr_handler_valid; /* client driver interrupt handler valid */ - sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ - void *intr_handler_arg; /* argument to call interrupt handler */ - bool initialized; /* card initialized */ - uint target_dev; /* Target device ID */ - uint16 intmask; /* Current active interrupts */ - void *sdos_info; /* Pointer to per-OS private data */ - - uint32 controller_type; /* Host controller type */ - uint8 version; /* Host Controller Spec Compliance Version */ - uint irq; /* Client irq */ - int intrcount; /* Client interrupts */ - int local_intrcount; /* Controller interrupts */ - bool host_init_done; /* Controller initted */ - bool card_init_done; /* Client SDIO interface initted */ - bool polled_mode; /* polling for command completion */ - - bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */ - /* Must be on for sd_multiblock to be effective */ - bool use_client_ints; /* If this is false, make sure to restore */ - /* polling hack in wl_linux.c:wl_timer() */ - int adapter_slot; /* Maybe dealing with multiple slots/controllers */ - int sd_mode; /* SD1/SD4/SPI */ - int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */ - uint32 data_xfer_count; /* Current transfer */ - uint16 card_rca; /* Current Address */ - int8 sd_dma_mode; /* DMA Mode (PIO, SDMA, ... ADMA2) on CMD53 */ - uint8 num_funcs; /* Supported funcs on client */ - uint32 com_cis_ptr; - uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; - void *dma_buf; /* DMA Buffer virtual address */ - ulong dma_phys; /* DMA Buffer physical address */ - void *adma2_dscr_buf; /* ADMA2 Descriptor Buffer virtual address */ - ulong adma2_dscr_phys; /* ADMA2 Descriptor Buffer physical address */ - - /* adjustments needed to make the dma align properly */ - void *dma_start_buf; - ulong dma_start_phys; - uint alloced_dma_size; - void *adma2_dscr_start_buf; - ulong adma2_dscr_start_phys; - uint alloced_adma2_dscr_size; - - int r_cnt; /* rx count */ - int t_cnt; /* tx_count */ - bool got_hcint; /* local interrupt flag */ - uint16 last_intrstatus; /* to cache intrstatus */ -}; - -#define DMA_MODE_NONE 0 -#define DMA_MODE_SDMA 1 -#define DMA_MODE_ADMA1 2 -#define DMA_MODE_ADMA2 3 -#define DMA_MODE_ADMA2_64 4 -#define DMA_MODE_AUTO -1 - -#define USE_DMA(sd) ((bool)((sd->sd_dma_mode > 0) ? TRUE : FALSE)) - -/* SDIO Host Control Register DMA Mode Definitions */ -#define SDIOH_SDMA_MODE 0 -#define SDIOH_ADMA1_MODE 1 -#define SDIOH_ADMA2_MODE 2 -#define SDIOH_ADMA2_64_MODE 3 - -#define ADMA2_ATTRIBUTE_VALID (1 << 0) /* ADMA Descriptor line valid */ -#define ADMA2_ATTRIBUTE_END (1 << 1) /* End of Descriptor */ -#define ADMA2_ATTRIBUTE_INT (1 << 2) /* Interrupt when line is done */ -#define ADMA2_ATTRIBUTE_ACT_NOP (0 << 4) /* Skip current line, go to next. */ -#define ADMA2_ATTRIBUTE_ACT_RSV (1 << 4) /* Same as NOP */ -#define ADMA1_ATTRIBUTE_ACT_SET (1 << 4) /* ADMA1 Only - set transfer length */ -#define ADMA2_ATTRIBUTE_ACT_TRAN (2 << 4) /* Transfer Data of one descriptor line. */ -#define ADMA2_ATTRIBUTE_ACT_LINK (3 << 4) /* Link Descriptor */ - -/* ADMA2 Descriptor Table Entry for 32-bit Address */ -typedef struct adma2_dscr_32b { - uint32 len_attr; - uint32 phys_addr; -} adma2_dscr_32b_t; - -/* ADMA1 Descriptor Table Entry */ -typedef struct adma1_dscr { - uint32 phys_addr_attr; -} adma1_dscr_t; - -/************************************************************ - * Internal interfaces: per-port references into bcmsdstd.c - */ - -/* Global message bits */ -extern uint sd_msglevel; - -/* OS-independent interrupt handler */ -extern bool check_client_intr(sdioh_info_t *sd); - -/* Core interrupt enable/disable of device interrupts */ -extern void sdstd_devintr_on(sdioh_info_t *sd); -extern void sdstd_devintr_off(sdioh_info_t *sd); - -/* Enable/disable interrupts for local controller events */ -extern void sdstd_intrs_on(sdioh_info_t *sd, uint16 norm, uint16 err); -extern void sdstd_intrs_off(sdioh_info_t *sd, uint16 norm, uint16 err); - -/* Wait for specified interrupt and error bits to be set */ -extern void sdstd_spinbits(sdioh_info_t *sd, uint16 norm, uint16 err); - - -/************************************************************** - * Internal interfaces: bcmsdstd.c references to per-port code - */ - -/* Register mapping routines */ -extern uint32 *sdstd_reg_map(osl_t *osh, int32 addr, int size); -extern void sdstd_reg_unmap(osl_t *osh, int32 addr, int size); - -/* Interrupt (de)registration routines */ -extern int sdstd_register_irq(sdioh_info_t *sd, uint irq); -extern void sdstd_free_irq(uint irq, sdioh_info_t *sd); - -/* OS-specific interrupt wrappers (atomic interrupt enable/disable) */ -extern void sdstd_lock(sdioh_info_t *sd); -extern void sdstd_unlock(sdioh_info_t *sd); - -/* OS-specific wait-for-interrupt-or-status */ -extern uint16 sdstd_waitbits(sdioh_info_t *sd, uint16 norm, uint16 err, bool yield); diff --git a/drivers/net/wireless/bcm4329/include/bcmspi.h b/drivers/net/wireless/bcm4329/include/bcmspi.h deleted file mode 100644 index 2e2bc935716f..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmspi.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Broadcom SPI Low-Level Hardware Driver API - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmspi.h,v 13.3.10.2 2008/06/30 21:09:40 Exp $ - */ - -extern void spi_devintr_off(sdioh_info_t *sd); -extern void spi_devintr_on(sdioh_info_t *sd); -extern bool spi_start_clock(sdioh_info_t *sd, uint16 new_sd_divisor); -extern bool spi_controller_highspeed_mode(sdioh_info_t *sd, bool hsmode); -extern bool spi_check_client_intr(sdioh_info_t *sd, int *is_dev_intr); -extern bool spi_hw_attach(sdioh_info_t *sd); -extern bool spi_hw_detach(sdioh_info_t *sd); -extern void spi_sendrecv(sdioh_info_t *sd, uint8 *msg_out, uint8 *msg_in, int msglen); -extern void spi_spinbits(sdioh_info_t *sd); -extern void spi_waitbits(sdioh_info_t *sd, bool yield); diff --git a/drivers/net/wireless/bcm4329/include/bcmutils.h b/drivers/net/wireless/bcm4329/include/bcmutils.h deleted file mode 100644 index f85ed351d663..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmutils.h +++ /dev/null @@ -1,637 +0,0 @@ -/* - * Misc useful os-independent macros and functions. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * $Id: bcmutils.h,v 13.184.4.6.2.1.18.25 2010/04/26 06:05:24 Exp $ - */ - - -#ifndef _bcmutils_h_ -#define _bcmutils_h_ - -#ifdef __cplusplus -extern "C" { -#endif - - -#define _BCM_U 0x01 -#define _BCM_L 0x02 -#define _BCM_D 0x04 -#define _BCM_C 0x08 -#define _BCM_P 0x10 -#define _BCM_S 0x20 -#define _BCM_X 0x40 -#define _BCM_SP 0x80 - -extern const unsigned char bcm_ctype[]; -#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)]) - -#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0) -#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0) -#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0) -#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0) -#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0) -#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0) -#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0) -#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0) -#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0) -#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0) -#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0) -#define bcm_tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c)) -#define bcm_toupper(c) (bcm_islower((c)) ? ((c) + 'A' - 'a') : (c)) - - - -struct bcmstrbuf { - char *buf; - unsigned int size; - char *origbuf; - unsigned int origsize; -}; - - -#ifdef BCMDRIVER -#include - -#define GPIO_PIN_NOTDEFINED 0x20 - - -#define SPINWAIT(exp, us) { \ - uint countdown = (us) + 9; \ - while ((exp) && (countdown >= 10)) {\ - OSL_DELAY(10); \ - countdown -= 10; \ - } \ -} - - - -#ifndef PKTQ_LEN_DEFAULT -#define PKTQ_LEN_DEFAULT 128 -#endif -#ifndef PKTQ_MAX_PREC -#define PKTQ_MAX_PREC 16 -#endif - -typedef struct pktq_prec { - void *head; - void *tail; - uint16 len; - uint16 max; -} pktq_prec_t; - - - -struct pktq { - uint16 num_prec; - uint16 hi_prec; - uint16 max; - uint16 len; - - struct pktq_prec q[PKTQ_MAX_PREC]; -}; - - -struct spktq { - uint16 num_prec; - uint16 hi_prec; - uint16 max; - uint16 len; - - struct pktq_prec q[1]; -}; - -#define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--) - - - - -struct ether_addr; - -extern int ether_isbcast(const void *ea); -extern int ether_isnulladdr(const void *ea); - - - -#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max)) -#define pktq_plen(pq, prec) ((pq)->q[prec].len) -#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len) -#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max) -#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0) - -#define pktq_ppeek(pq, prec) ((pq)->q[prec].head) -#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail) - -extern void *pktq_penq(struct pktq *pq, int prec, void *p); -extern void *pktq_penq_head(struct pktq *pq, int prec, void *p); -extern void *pktq_pdeq(struct pktq *pq, int prec); -extern void *pktq_pdeq_tail(struct pktq *pq, int prec); - -extern bool pktq_pdel(struct pktq *pq, void *p, int prec); - - -extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir); - -extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir); - - - -extern int pktq_mlen(struct pktq *pq, uint prec_bmp); -extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); - - - -#define pktq_len(pq) ((int)(pq)->len) -#define pktq_max(pq) ((int)(pq)->max) -#define pktq_avail(pq) ((int)((pq)->max - (pq)->len)) -#define pktq_full(pq) ((pq)->len >= (pq)->max) -#define pktq_empty(pq) ((pq)->len == 0) - - -#define pktenq(pq, p) pktq_penq(((struct pktq *)pq), 0, (p)) -#define pktenq_head(pq, p) pktq_penq_head(((struct pktq *)pq), 0, (p)) -#define pktdeq(pq) pktq_pdeq(((struct pktq *)pq), 0) -#define pktdeq_tail(pq) pktq_pdeq_tail(((struct pktq *)pq), 0) -#define pktqinit(pq, len) pktq_init(((struct pktq *)pq), 1, len) - -extern void pktq_init(struct pktq *pq, int num_prec, int max_len); - -extern void *pktq_deq(struct pktq *pq, int *prec_out); -extern void *pktq_deq_tail(struct pktq *pq, int *prec_out); -extern void *pktq_peek(struct pktq *pq, int *prec_out); -extern void *pktq_peek_tail(struct pktq *pq, int *prec_out); - - - -extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); -extern uint pktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf); -extern uint pkttotlen(osl_t *osh, void *p); -extern void *pktlast(osl_t *osh, void *p); -extern uint pktsegcnt(osl_t *osh, void *p); - - -extern uint pktsetprio(void *pkt, bool update_vtag); -#define PKTPRIO_VDSCP 0x100 -#define PKTPRIO_VLAN 0x200 -#define PKTPRIO_UPD 0x400 -#define PKTPRIO_DSCP 0x800 - - -extern int bcm_atoi(char *s); -extern ulong bcm_strtoul(char *cp, char **endp, uint base); -extern char *bcmstrstr(char *haystack, char *needle); -extern char *bcmstrcat(char *dest, const char *src); -extern char *bcmstrncat(char *dest, const char *src, uint size); -extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen); -char* bcmstrtok(char **string, const char *delimiters, char *tokdelim); -int bcmstricmp(const char *s1, const char *s2); -int bcmstrnicmp(const char* s1, const char* s2, int cnt); - - - -extern char *bcm_ether_ntoa(const struct ether_addr *ea, char *buf); -extern int bcm_ether_atoe(char *p, struct ether_addr *ea); - - -struct ipv4_addr; -extern char *bcm_ip_ntoa(struct ipv4_addr *ia, char *buf); - - -extern void bcm_mdelay(uint ms); - -extern char *getvar(char *vars, const char *name); -extern int getintvar(char *vars, const char *name); -extern uint getgpiopin(char *vars, char *pin_name, uint def_pin); -#define bcm_perf_enable() -#define bcmstats(fmt) -#define bcmlog(fmt, a1, a2) -#define bcmdumplog(buf, size) *buf = '\0' -#define bcmdumplogent(buf, idx) -1 - -#define bcmtslog(tstamp, fmt, a1, a2) -#define bcmprinttslogs() -#define bcmprinttstamp(us) - - - - -typedef struct bcm_iovar { - const char *name; - uint16 varid; - uint16 flags; - uint16 type; - uint16 minlen; -} bcm_iovar_t; - - - - -#define IOV_GET 0 -#define IOV_SET 1 - - -#define IOV_GVAL(id) ((id)*2) -#define IOV_SVAL(id) (((id)*2)+IOV_SET) -#define IOV_ISSET(actionid) ((actionid & IOV_SET) == IOV_SET) - - - -extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name); -extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg, int len, bool set); - -#endif - - -#define IOVT_VOID 0 -#define IOVT_BOOL 1 -#define IOVT_INT8 2 -#define IOVT_UINT8 3 -#define IOVT_INT16 4 -#define IOVT_UINT16 5 -#define IOVT_INT32 6 -#define IOVT_UINT32 7 -#define IOVT_BUFFER 8 -#define BCM_IOVT_VALID(type) (((unsigned int)(type)) <= IOVT_BUFFER) - - -#define BCM_IOV_TYPE_INIT { \ - "void", \ - "bool", \ - "int8", \ - "uint8", \ - "int16", \ - "uint16", \ - "int32", \ - "uint32", \ - "buffer", \ - "" } - -#define BCM_IOVT_IS_INT(type) (\ - (type == IOVT_BOOL) || \ - (type == IOVT_INT8) || \ - (type == IOVT_UINT8) || \ - (type == IOVT_INT16) || \ - (type == IOVT_UINT16) || \ - (type == IOVT_INT32) || \ - (type == IOVT_UINT32)) - - - -#define BCME_STRLEN 64 -#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST)) - - - - -#define BCME_OK 0 -#define BCME_ERROR -1 -#define BCME_BADARG -2 -#define BCME_BADOPTION -3 -#define BCME_NOTUP -4 -#define BCME_NOTDOWN -5 -#define BCME_NOTAP -6 -#define BCME_NOTSTA -7 -#define BCME_BADKEYIDX -8 -#define BCME_RADIOOFF -9 -#define BCME_NOTBANDLOCKED -10 -#define BCME_NOCLK -11 -#define BCME_BADRATESET -12 -#define BCME_BADBAND -13 -#define BCME_BUFTOOSHORT -14 -#define BCME_BUFTOOLONG -15 -#define BCME_BUSY -16 -#define BCME_NOTASSOCIATED -17 -#define BCME_BADSSIDLEN -18 -#define BCME_OUTOFRANGECHAN -19 -#define BCME_BADCHAN -20 -#define BCME_BADADDR -21 -#define BCME_NORESOURCE -22 -#define BCME_UNSUPPORTED -23 -#define BCME_BADLEN -24 -#define BCME_NOTREADY -25 -#define BCME_EPERM -26 -#define BCME_NOMEM -27 -#define BCME_ASSOCIATED -28 -#define BCME_RANGE -29 -#define BCME_NOTFOUND -30 -#define BCME_WME_NOT_ENABLED -31 -#define BCME_TSPEC_NOTFOUND -32 -#define BCME_ACM_NOTSUPPORTED -33 -#define BCME_NOT_WME_ASSOCIATION -34 -#define BCME_SDIO_ERROR -35 -#define BCME_DONGLE_DOWN -36 -#define BCME_VERSION -37 -#define BCME_TXFAIL -38 -#define BCME_RXFAIL -39 -#define BCME_NODEVICE -40 -#define BCME_UNFINISHED -41 -#define BCME_LAST BCME_UNFINISHED - - -#define BCMERRSTRINGTABLE { \ - "OK", \ - "Undefined error", \ - "Bad Argument", \ - "Bad Option", \ - "Not up", \ - "Not down", \ - "Not AP", \ - "Not STA", \ - "Bad Key Index", \ - "Radio Off", \ - "Not band locked", \ - "No clock", \ - "Bad Rate valueset", \ - "Bad Band", \ - "Buffer too short", \ - "Buffer too long", \ - "Busy", \ - "Not Associated", \ - "Bad SSID len", \ - "Out of Range Channel", \ - "Bad Channel", \ - "Bad Address", \ - "Not Enough Resources", \ - "Unsupported", \ - "Bad length", \ - "Not Ready", \ - "Not Permitted", \ - "No Memory", \ - "Associated", \ - "Not In Range", \ - "Not Found", \ - "WME Not Enabled", \ - "TSPEC Not Found", \ - "ACM Not Supported", \ - "Not WME Association", \ - "SDIO Bus Error", \ - "Dongle Not Accessible", \ - "Incorrect version", \ - "TX Failure", \ - "RX Failure", \ - "Device Not Present", \ - "Command not finished", \ -} - -#ifndef ABS -#define ABS(a) (((a) < 0)?-(a):(a)) -#endif - -#ifndef MIN -#define MIN(a, b) (((a) < (b))?(a):(b)) -#endif - -#ifndef MAX -#define MAX(a, b) (((a) > (b))?(a):(b)) -#endif - -#define CEIL(x, y) (((x) + ((y)-1)) / (y)) -#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) -#define ISALIGNED(a, x) (((a) & ((x)-1)) == 0) -#define ALIGN_ADDR(addr, boundary) (void *)(((uintptr)(addr) + (boundary) - 1) \ - & ~((boundary) - 1)) -#define ISPOWEROF2(x) ((((x)-1)&(x)) == 0) -#define VALID_MASK(mask) !((mask) & ((mask) + 1)) -#ifndef OFFSETOF -#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member) -#endif -#ifndef ARRAYSIZE -#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0])) -#endif - - -#ifndef setbit -#ifndef NBBY -#define NBBY 8 -#endif -#define setbit(a, i) (((uint8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY)) -#define clrbit(a, i) (((uint8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) -#define isset(a, i) (((const uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) -#define isclr(a, i) ((((const uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) -#endif - -#define NBITS(type) (sizeof(type) * 8) -#define NBITVAL(nbits) (1 << (nbits)) -#define MAXBITVAL(nbits) ((1 << (nbits)) - 1) -#define NBITMASK(nbits) MAXBITVAL(nbits) -#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8) - - -#define MUX(pred, true, false) ((pred) ? (true) : (false)) - - -#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1) -#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1) - - -#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1)) -#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1)) - - -#define MODADD(x, y, bound) \ - MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y)) -#define MODSUB(x, y, bound) \ - MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y)) - - -#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1)) -#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1)) - - -#define CRC8_INIT_VALUE 0xff -#define CRC8_GOOD_VALUE 0x9f -#define CRC16_INIT_VALUE 0xffff -#define CRC16_GOOD_VALUE 0xf0b8 -#define CRC32_INIT_VALUE 0xffffffff -#define CRC32_GOOD_VALUE 0xdebb20e3 - - -typedef struct bcm_bit_desc { - uint32 bit; - const char* name; -} bcm_bit_desc_t; - - -typedef struct bcm_tlv { - uint8 id; - uint8 len; - uint8 data[1]; -} bcm_tlv_t; - - -#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len)) - - -#define ETHER_ADDR_STR_LEN 18 - - -#ifdef IL_BIGENDIAN -static INLINE uint32 -load32_ua(uint8 *a) -{ - return ((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]); -} - -static INLINE void -store32_ua(uint8 *a, uint32 v) -{ - a[0] = (v >> 24) & 0xff; - a[1] = (v >> 16) & 0xff; - a[2] = (v >> 8) & 0xff; - a[3] = v & 0xff; -} - -static INLINE uint16 -load16_ua(uint8 *a) -{ - return ((a[0] << 8) | a[1]); -} - -static INLINE void -store16_ua(uint8 *a, uint16 v) -{ - a[0] = (v >> 8) & 0xff; - a[1] = v & 0xff; -} - -#else - -static INLINE uint32 -load32_ua(uint8 *a) -{ - return ((a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]); -} - -static INLINE void -store32_ua(uint8 *a, uint32 v) -{ - a[3] = (v >> 24) & 0xff; - a[2] = (v >> 16) & 0xff; - a[1] = (v >> 8) & 0xff; - a[0] = v & 0xff; -} - -static INLINE uint16 -load16_ua(uint8 *a) -{ - return ((a[1] << 8) | a[0]); -} - -static INLINE void -store16_ua(uint8 *a, uint16 v) -{ - a[1] = (v >> 8) & 0xff; - a[0] = v & 0xff; -} - -#endif - - - -static INLINE void -xor_128bit_block(const uint8 *src1, const uint8 *src2, uint8 *dst) -{ - if ( -#ifdef __i386__ - 1 || -#endif - (((uintptr)src1 | (uintptr)src2 | (uintptr)dst) & 3) == 0) { - - - ((uint32 *)dst)[0] = ((uint32 *)src1)[0] ^ ((uint32 *)src2)[0]; - ((uint32 *)dst)[1] = ((uint32 *)src1)[1] ^ ((uint32 *)src2)[1]; - ((uint32 *)dst)[2] = ((uint32 *)src1)[2] ^ ((uint32 *)src2)[2]; - ((uint32 *)dst)[3] = ((uint32 *)src1)[3] ^ ((uint32 *)src2)[3]; - } else { - - int k; - for (k = 0; k < 16; k++) - dst[k] = src1[k] ^ src2[k]; - } -} - - - -extern uint8 hndcrc8(uint8 *p, uint nbytes, uint8 crc); -extern uint16 hndcrc16(uint8 *p, uint nbytes, uint16 crc); -extern uint32 hndcrc32(uint8 *p, uint nbytes, uint32 crc); - -#if defined(DHD_DEBUG) || defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || \ - defined(WLMSG_ASSOC) -extern int bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len); -extern int bcm_format_hex(char *str, const void *bytes, int len); -extern void prhex(const char *msg, uchar *buf, uint len); -#endif -extern char *bcm_brev_str(uint32 brev, char *buf); -extern void printbig(char *buf); - - -extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen); -extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key); -extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key); - - -extern const char *bcmerrorstr(int bcmerror); - - -typedef uint32 mbool; -#define mboolset(mb, bit) ((mb) |= (bit)) -#define mboolclr(mb, bit) ((mb) &= ~(bit)) -#define mboolisset(mb, bit) (((mb) & (bit)) != 0) -#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val))) - - -extern uint16 bcm_qdbm_to_mw(uint8 qdbm); -extern uint8 bcm_mw_to_qdbm(uint16 mw); - - -struct fielddesc { - const char *nameandfmt; - uint32 offset; - uint32 len; -}; - -extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size); -extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...); -extern void bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount); -extern int bcm_cmp_bytes(uchar *arg1, uchar *arg2, uint8 nbytes); -extern void bcm_print_bytes(char *name, const uchar *cdata, int len); - -typedef uint32 (*bcmutl_rdreg_rtn)(void *arg0, uint arg1, uint32 offset); -extern uint bcmdumpfields(bcmutl_rdreg_rtn func_ptr, void *arg0, uint arg1, struct fielddesc *str, - char *buf, uint32 bufsize); - -extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len); -extern uint bcm_bitcount(uint8 *bitmap, uint bytelength); - -#if defined(WLTINYDUMP) || defined(WLMSG_INFORM) || defined(WLMSG_ASSOC) || \ - defined(WLMSG_PRPKT) || defined(WLMSG_WSEC) -extern int bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len); -#endif - - -#define SSID_FMT_BUF_LEN ((4 * DOT11_MAX_SSID_LEN) + 1) - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/drivers/net/wireless/bcm4329/include/bcmwifi.h b/drivers/net/wireless/bcm4329/include/bcmwifi.h deleted file mode 100644 index 038aedcdb3c8..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmwifi.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Misc utility routines for WL and Apps - * This header file housing the define and function prototype use by - * both the wl driver, tools & Apps. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * $Id: bcmwifi.h,v 1.15.30.4 2010/03/10 20:10:52 Exp $ - */ - - -#ifndef _bcmwifi_h_ -#define _bcmwifi_h_ - - - -typedef uint16 chanspec_t; - - -#define CH_UPPER_SB 0x01 -#define CH_LOWER_SB 0x02 -#define CH_EWA_VALID 0x04 -#define CH_20MHZ_APART 4 -#define CH_10MHZ_APART 2 -#define CH_5MHZ_APART 1 -#define CH_MAX_2G_CHANNEL 14 -#define WLC_MAX_2G_CHANNEL CH_MAX_2G_CHANNEL -#define MAXCHANNEL 224 - -#define WL_CHANSPEC_CHAN_MASK 0x00ff -#define WL_CHANSPEC_CHAN_SHIFT 0 - -#define WL_CHANSPEC_CTL_SB_MASK 0x0300 -#define WL_CHANSPEC_CTL_SB_SHIFT 8 -#define WL_CHANSPEC_CTL_SB_LOWER 0x0100 -#define WL_CHANSPEC_CTL_SB_UPPER 0x0200 -#define WL_CHANSPEC_CTL_SB_NONE 0x0300 - -#define WL_CHANSPEC_BW_MASK 0x0C00 -#define WL_CHANSPEC_BW_SHIFT 10 -#define WL_CHANSPEC_BW_10 0x0400 -#define WL_CHANSPEC_BW_20 0x0800 -#define WL_CHANSPEC_BW_40 0x0C00 - -#define WL_CHANSPEC_BAND_MASK 0xf000 -#define WL_CHANSPEC_BAND_SHIFT 12 -#define WL_CHANSPEC_BAND_5G 0x1000 -#define WL_CHANSPEC_BAND_2G 0x2000 -#define INVCHANSPEC 255 - - -#define WF_CHAN_FACTOR_2_4_G 4814 -#define WF_CHAN_FACTOR_5_G 10000 -#define WF_CHAN_FACTOR_4_G 8000 - - -#define LOWER_20_SB(channel) ((channel > CH_10MHZ_APART) ? (channel - CH_10MHZ_APART) : 0) -#define UPPER_20_SB(channel) ((channel < (MAXCHANNEL - CH_10MHZ_APART)) ? \ - (channel + CH_10MHZ_APART) : 0) -#define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX) -#define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \ - WL_CHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \ - WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) -#define NEXT_20MHZ_CHAN(channel) ((channel < (MAXCHANNEL - CH_20MHZ_APART)) ? \ - (channel + CH_20MHZ_APART) : 0) -#define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ - ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \ - ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \ - WL_CHANSPEC_BAND_5G)) -#define CHSPEC_CHANNEL(chspec) ((uint8)(chspec & WL_CHANSPEC_CHAN_MASK)) -#define CHSPEC_BAND(chspec) (chspec & WL_CHANSPEC_BAND_MASK) - -#ifdef WL20MHZ_ONLY - -#define CHSPEC_CTL_SB(chspec) WL_CHANSPEC_CTL_SB_NONE -#define CHSPEC_BW(chspec) WL_CHANSPEC_BW_20 -#define CHSPEC_IS10(chspec) 0 -#define CHSPEC_IS20(chspec) 1 -#ifndef CHSPEC_IS40 -#define CHSPEC_IS40(chspec) 0 -#endif - -#else - -#define CHSPEC_CTL_SB(chspec) (chspec & WL_CHANSPEC_CTL_SB_MASK) -#define CHSPEC_BW(chspec) (chspec & WL_CHANSPEC_BW_MASK) -#define CHSPEC_IS10(chspec) ((chspec & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10) -#define CHSPEC_IS20(chspec) ((chspec & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) -#ifndef CHSPEC_IS40 -#define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40) -#endif - -#endif - -#define CHSPEC_IS5G(chspec) ((chspec & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G) -#define CHSPEC_IS2G(chspec) ((chspec & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G) -#define CHSPEC_SB_NONE(chspec) ((chspec & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE) -#define CHSPEC_SB_UPPER(chspec) ((chspec & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) -#define CHSPEC_SB_LOWER(chspec) ((chspec & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) -#define CHSPEC_CTL_CHAN(chspec) ((CHSPEC_SB_LOWER(chspec)) ? \ - (LOWER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \ - (UPPER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK)))) - -#define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G((chspec))? WLC_BAND_5G: WLC_BAND_2G) - -#define CHANSPEC_STR_LEN 8 - - -#define WLC_MAXRATE 108 -#define WLC_RATE_1M 2 -#define WLC_RATE_2M 4 -#define WLC_RATE_5M5 11 -#define WLC_RATE_11M 22 -#define WLC_RATE_6M 12 -#define WLC_RATE_9M 18 -#define WLC_RATE_12M 24 -#define WLC_RATE_18M 36 -#define WLC_RATE_24M 48 -#define WLC_RATE_36M 72 -#define WLC_RATE_48M 96 -#define WLC_RATE_54M 108 - -#define WLC_2G_25MHZ_OFFSET 5 - - -extern char * wf_chspec_ntoa(chanspec_t chspec, char *buf); - - -extern chanspec_t wf_chspec_aton(char *a); - - -extern int wf_mhz2channel(uint freq, uint start_factor); - - -extern int wf_channel2mhz(uint channel, uint start_factor); - -#endif diff --git a/drivers/net/wireless/bcm4329/include/dhdioctl.h b/drivers/net/wireless/bcm4329/include/dhdioctl.h deleted file mode 100644 index 980a14301003..000000000000 --- a/drivers/net/wireless/bcm4329/include/dhdioctl.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Definitions for ioctls to access DHD iovars. - * Based on wlioctl.h (for Broadcom 802.11abg driver). - * (Moves towards generic ioctls for BCM drivers/iovars.) - * - * Definitions subject to change without notice. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhdioctl.h,v 13.7.8.1.4.1.16.5 2010/05/21 21:49:38 Exp $ - */ - -#ifndef _dhdioctl_h_ -#define _dhdioctl_h_ - -#include - - -/* require default structure packing */ -#define BWL_DEFAULT_PACKING -#include - - -/* Linux network driver ioctl encoding */ -typedef struct dhd_ioctl { - uint cmd; /* common ioctl definition */ - void *buf; /* pointer to user buffer */ - uint len; /* length of user buffer */ - bool set; /* get or set request (optional) */ - uint used; /* bytes read or written (optional) */ - uint needed; /* bytes needed (optional) */ - uint driver; /* to identify target driver */ -} dhd_ioctl_t; - -/* per-driver magic numbers */ -#define DHD_IOCTL_MAGIC 0x00444944 - -/* bump this number if you change the ioctl interface */ -#define DHD_IOCTL_VERSION 1 - -#define DHD_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */ -#define DHD_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */ - -/* common ioctl definitions */ -#define DHD_GET_MAGIC 0 -#define DHD_GET_VERSION 1 -#define DHD_GET_VAR 2 -#define DHD_SET_VAR 3 - -/* message levels */ -#define DHD_ERROR_VAL 0x0001 -#define DHD_TRACE_VAL 0x0002 -#define DHD_INFO_VAL 0x0004 -#define DHD_DATA_VAL 0x0008 -#define DHD_CTL_VAL 0x0010 -#define DHD_TIMER_VAL 0x0020 -#define DHD_HDRS_VAL 0x0040 -#define DHD_BYTES_VAL 0x0080 -#define DHD_INTR_VAL 0x0100 -#define DHD_LOG_VAL 0x0200 -#define DHD_GLOM_VAL 0x0400 -#define DHD_EVENT_VAL 0x0800 -#define DHD_BTA_VAL 0x1000 -#define DHD_ISCAN_VAL 0x2000 - -#ifdef SDTEST -/* For pktgen iovar */ -typedef struct dhd_pktgen { - uint version; /* To allow structure change tracking */ - uint freq; /* Max ticks between tx/rx attempts */ - uint count; /* Test packets to send/rcv each attempt */ - uint print; /* Print counts every attempts */ - uint total; /* Total packets (or bursts) */ - uint minlen; /* Minimum length of packets to send */ - uint maxlen; /* Maximum length of packets to send */ - uint numsent; /* Count of test packets sent */ - uint numrcvd; /* Count of test packets received */ - uint numfail; /* Count of test send failures */ - uint mode; /* Test mode (type of test packets) */ - uint stop; /* Stop after this many tx failures */ -} dhd_pktgen_t; - -/* Version in case structure changes */ -#define DHD_PKTGEN_VERSION 2 - -/* Type of test packets to use */ -#define DHD_PKTGEN_ECHO 1 /* Send echo requests */ -#define DHD_PKTGEN_SEND 2 /* Send discard packets */ -#define DHD_PKTGEN_RXBURST 3 /* Request dongle send N packets */ -#define DHD_PKTGEN_RECV 4 /* Continuous rx from continuous tx dongle */ -#endif /* SDTEST */ - -/* Enter idle immediately (no timeout) */ -#define DHD_IDLE_IMMEDIATE (-1) - -/* Values for idleclock iovar: other values are the sd_divisor to use when idle */ -#define DHD_IDLE_ACTIVE 0 /* Do not request any SD clock change when idle */ -#define DHD_IDLE_STOP (-1) /* Request SD clock be stopped (and use SD1 mode) */ - - -/* require default structure packing */ -#include - - -#endif /* _dhdioctl_h_ */ diff --git a/drivers/net/wireless/bcm4329/include/epivers.h b/drivers/net/wireless/bcm4329/include/epivers.h deleted file mode 100644 index cd66a9501cb6..000000000000 --- a/drivers/net/wireless/bcm4329/include/epivers.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: epivers.h.in,v 13.25 2005/10/28 18:35:33 Exp $ - * -*/ - - -#ifndef _epivers_h_ -#define _epivers_h_ - -#define EPI_MAJOR_VERSION 4 - -#define EPI_MINOR_VERSION 218 - -#define EPI_RC_NUMBER 248 - -#define EPI_INCREMENTAL_NUMBER 23 - -#define EPI_BUILD_NUMBER 0 - -#define EPI_VERSION 4, 218, 248, 23 - -#define EPI_VERSION_NUM 0x04daf817 - - -#define EPI_VERSION_STR "4.218.248.23" -#define EPI_ROUTER_VERSION_STR "4.219.248.23" - -#endif diff --git a/drivers/net/wireless/bcm4329/include/hndpmu.h b/drivers/net/wireless/bcm4329/include/hndpmu.h deleted file mode 100644 index e829b3df2d0b..000000000000 --- a/drivers/net/wireless/bcm4329/include/hndpmu.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * HND SiliconBackplane PMU support. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: hndpmu.h,v 13.14.4.3.4.3.8.7 2010/04/09 13:20:51 Exp $ - */ - -#ifndef _hndpmu_h_ -#define _hndpmu_h_ - - -extern void si_pmu_otp_power(si_t *sih, osl_t *osh, bool on); -extern void si_sdiod_drive_strength_init(si_t *sih, osl_t *osh, uint32 drivestrength); - -#endif /* _hndpmu_h_ */ diff --git a/drivers/net/wireless/bcm4329/include/hndrte_armtrap.h b/drivers/net/wireless/bcm4329/include/hndrte_armtrap.h deleted file mode 100644 index ca3281b6d901..000000000000 --- a/drivers/net/wireless/bcm4329/include/hndrte_armtrap.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * HNDRTE arm trap handling. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: hndrte_armtrap.h,v 13.3.196.2 2010/07/15 19:06:11 Exp $ - */ - -#ifndef _hndrte_armtrap_h -#define _hndrte_armtrap_h - - -/* ARM trap handling */ - -/* Trap types defined by ARM (see arminc.h) */ - -/* Trap locations in lo memory */ -#define TRAP_STRIDE 4 -#define FIRST_TRAP TR_RST -#define LAST_TRAP (TR_FIQ * TRAP_STRIDE) - -#if defined(__ARM_ARCH_4T__) -#define MAX_TRAP_TYPE (TR_FIQ + 1) -#elif defined(__ARM_ARCH_7M__) -#define MAX_TRAP_TYPE (TR_ISR + ARMCM3_NUMINTS) -#endif /* __ARM_ARCH_7M__ */ - -/* The trap structure is defined here as offsets for assembly */ -#define TR_TYPE 0x00 -#define TR_EPC 0x04 -#define TR_CPSR 0x08 -#define TR_SPSR 0x0c -#define TR_REGS 0x10 -#define TR_REG(n) (TR_REGS + (n) * 4) -#define TR_SP TR_REG(13) -#define TR_LR TR_REG(14) -#define TR_PC TR_REG(15) - -#define TRAP_T_SIZE 80 - -#ifndef _LANGUAGE_ASSEMBLY - -#include - -typedef struct _trap_struct { - uint32 type; - uint32 epc; - uint32 cpsr; - uint32 spsr; - uint32 r0; - uint32 r1; - uint32 r2; - uint32 r3; - uint32 r4; - uint32 r5; - uint32 r6; - uint32 r7; - uint32 r8; - uint32 r9; - uint32 r10; - uint32 r11; - uint32 r12; - uint32 r13; - uint32 r14; - uint32 pc; -} trap_t; - -#endif /* !_LANGUAGE_ASSEMBLY */ - -#endif /* _hndrte_armtrap_h */ diff --git a/drivers/net/wireless/bcm4329/include/hndrte_cons.h b/drivers/net/wireless/bcm4329/include/hndrte_cons.h deleted file mode 100644 index a42417478a16..000000000000 --- a/drivers/net/wireless/bcm4329/include/hndrte_cons.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Console support for hndrte. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: hndrte_cons.h,v 13.1.2.4 2010/07/15 19:06:11 Exp $ - */ - -#include - -#define CBUF_LEN (128) - -#define LOG_BUF_LEN 1024 - -typedef struct { - uint32 buf; /* Can't be pointer on (64-bit) hosts */ - uint buf_size; - uint idx; - char *_buf_compat; /* Redundant pointer for backward compat. */ -} hndrte_log_t; - -typedef struct { - /* Virtual UART - * When there is no UART (e.g. Quickturn), the host should write a complete - * input line directly into cbuf and then write the length into vcons_in. - * This may also be used when there is a real UART (at risk of conflicting with - * the real UART). vcons_out is currently unused. - */ - volatile uint vcons_in; - volatile uint vcons_out; - - /* Output (logging) buffer - * Console output is written to a ring buffer log_buf at index log_idx. - * The host may read the output when it sees log_idx advance. - * Output will be lost if the output wraps around faster than the host polls. - */ - hndrte_log_t log; - - /* Console input line buffer - * Characters are read one at a time into cbuf until is received, then - * the buffer is processed as a command line. Also used for virtual UART. - */ - uint cbuf_idx; - char cbuf[CBUF_LEN]; -} hndrte_cons_t; diff --git a/drivers/net/wireless/bcm4329/include/hndsoc.h b/drivers/net/wireless/bcm4329/include/hndsoc.h deleted file mode 100644 index 35424175f55e..000000000000 --- a/drivers/net/wireless/bcm4329/include/hndsoc.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Broadcom HND chip & on-chip-interconnect-related definitions. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: hndsoc.h,v 13.3.10.3 2008/08/06 03:43:25 Exp $ - */ - -#ifndef _HNDSOC_H -#define _HNDSOC_H - -/* Include the soci specific files */ -#include -#include - -/* - * SOC Interconnect Address Map. - * All regions may not exist on all chips. - */ -#define SI_SDRAM_BASE 0x00000000 /* Physical SDRAM */ -#define SI_PCI_MEM 0x08000000 /* Host Mode sb2pcitranslation0 (64 MB) */ -#define SI_PCI_MEM_SZ (64 * 1024 * 1024) -#define SI_PCI_CFG 0x0c000000 /* Host Mode sb2pcitranslation1 (64 MB) */ -#define SI_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ - -#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */ -#define SI_CORE_SIZE 0x1000 /* each core gets 4Kbytes for registers */ -#ifndef SI_MAXCORES -#define SI_MAXCORES 16 /* Max cores (this is arbitrary, for software - * convenience and could be changed if we - * make any larger chips - */ -#endif - -#define SI_FASTRAM 0x19000000 /* On-chip RAM on chips that also have DDR */ - -#define SI_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */ -#define SI_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */ -#define SI_ARMCM3_ROM 0x1e000000 /* ARM Cortex-M3 ROM */ -#define SI_FLASH1 0x1fc00000 /* MIPS Flash Region 1 */ -#define SI_FLASH1_SZ 0x00400000 /* MIPS Size of Flash Region 1 */ -#define SI_ARM7S_ROM 0x20000000 /* ARM7TDMI-S ROM */ -#define SI_ARMCM3_SRAM2 0x60000000 /* ARM Cortex-M3 SRAM Region 2 */ -#define SI_ARM7S_SRAM2 0x80000000 /* ARM7TDMI-S SRAM Region 2 */ -#define SI_ARM_FLASH1 0xffff0000 /* ARM Flash Region 1 */ -#define SI_ARM_FLASH1_SZ 0x00010000 /* ARM Size of Flash Region 1 */ - -#define SI_PCI_DMA 0x40000000 /* Client Mode sb2pcitranslation2 (1 GB) */ -#define SI_PCI_DMA2 0x80000000 /* Client Mode sb2pcitranslation2 (1 GB) */ -#define SI_PCI_DMA_SZ 0x40000000 /* Client Mode sb2pcitranslation2 size in bytes */ -#define SI_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2 - * (2 ZettaBytes), low 32 bits - */ -#define SI_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2 - * (2 ZettaBytes), high 32 bits - */ - -/* core codes */ -#define NODEV_CORE_ID 0x700 /* Invalid coreid */ -#define CC_CORE_ID 0x800 /* chipcommon core */ -#define ILINE20_CORE_ID 0x801 /* iline20 core */ -#define SRAM_CORE_ID 0x802 /* sram core */ -#define SDRAM_CORE_ID 0x803 /* sdram core */ -#define PCI_CORE_ID 0x804 /* pci core */ -#define MIPS_CORE_ID 0x805 /* mips core */ -#define ENET_CORE_ID 0x806 /* enet mac core */ -#define CODEC_CORE_ID 0x807 /* v90 codec core */ -#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */ -#define ADSL_CORE_ID 0x809 /* ADSL core */ -#define ILINE100_CORE_ID 0x80a /* iline100 core */ -#define IPSEC_CORE_ID 0x80b /* ipsec core */ -#define UTOPIA_CORE_ID 0x80c /* utopia core */ -#define PCMCIA_CORE_ID 0x80d /* pcmcia core */ -#define SOCRAM_CORE_ID 0x80e /* internal memory core */ -#define MEMC_CORE_ID 0x80f /* memc sdram core */ -#define OFDM_CORE_ID 0x810 /* OFDM phy core */ -#define EXTIF_CORE_ID 0x811 /* external interface core */ -#define D11_CORE_ID 0x812 /* 802.11 MAC core */ -#define APHY_CORE_ID 0x813 /* 802.11a phy core */ -#define BPHY_CORE_ID 0x814 /* 802.11b phy core */ -#define GPHY_CORE_ID 0x815 /* 802.11g phy core */ -#define MIPS33_CORE_ID 0x816 /* mips3302 core */ -#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */ -#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */ -#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */ -#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */ -#define SDIOH_CORE_ID 0x81b /* sdio host core */ -#define ROBO_CORE_ID 0x81c /* roboswitch core */ -#define ATA100_CORE_ID 0x81d /* parallel ATA core */ -#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */ -#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */ -#define PCIE_CORE_ID 0x820 /* pci express core */ -#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */ -#define SRAMC_CORE_ID 0x822 /* SRAM controller core */ -#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */ -#define ARM11_CORE_ID 0x824 /* ARM 1176 core */ -#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */ -#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */ -#define PMU_CORE_ID 0x827 /* PMU core */ -#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */ -#define SDIOD_CORE_ID 0x829 /* SDIO device core */ -#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */ -#define QNPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */ -#define MIPS74K_CORE_ID 0x82c /* mips 74k core */ -#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ -#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */ -#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */ -#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */ -#define SC_CORE_ID 0x831 /* shared common core */ -#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */ -#define SPIH_CORE_ID 0x833 /* SPI host core */ -#define I2S_CORE_ID 0x834 /* I2S core */ -#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ -#define DEF_AI_COMP 0xfff /* Default component, in ai chips it maps all - * unused address ranges - */ - -/* There are TWO constants on all HND chips: SI_ENUM_BASE above, - * and chipcommon being the first core: - */ -#define SI_CC_IDX 0 - -/* SOC Interconnect types (aka chip types) */ -#define SOCI_SB 0 -#define SOCI_AI 1 - -/* Common core control flags */ -#define SICF_BIST_EN 0x8000 -#define SICF_PME_EN 0x4000 -#define SICF_CORE_BITS 0x3ffc -#define SICF_FGC 0x0002 -#define SICF_CLOCK_EN 0x0001 - -/* Common core status flags */ -#define SISF_BIST_DONE 0x8000 -#define SISF_BIST_ERROR 0x4000 -#define SISF_GATED_CLK 0x2000 -#define SISF_DMA64 0x1000 -#define SISF_CORE_BITS 0x0fff - -/* A register that is common to all cores to - * communicate w/PMU regarding clock control. - */ -#define SI_CLK_CTL_ST 0x1e0 /* clock control and status */ - -/* clk_ctl_st register */ -#define CCS_FORCEALP 0x00000001 /* force ALP request */ -#define CCS_FORCEHT 0x00000002 /* force HT request */ -#define CCS_FORCEILP 0x00000004 /* force ILP request */ -#define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */ -#define CCS_HTAREQ 0x00000010 /* HT Avail Request */ -#define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */ -#define CCS_ALPAVAIL 0x00010000 /* ALP is available */ -#define CCS_HTAVAIL 0x00020000 /* HT is available */ -#define CCS0_HTAVAIL 0x00010000 /* HT avail in chipc and pcmcia on 4328a0 */ -#define CCS0_ALPAVAIL 0x00020000 /* ALP avail in chipc and pcmcia on 4328a0 */ - -/* Not really related to SOC Interconnect, but a couple of software - * conventions for the use the flash space: - */ - -/* Minumum amount of flash we support */ -#define FLASH_MIN 0x00020000 /* Minimum flash size */ - -/* A boot/binary may have an embedded block that describes its size */ -#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */ -#define BISZ_MAGIC 0x4249535a /* Marked with this value: 'BISZ' */ -#define BISZ_MAGIC_IDX 0 /* Word 0: magic */ -#define BISZ_TXTST_IDX 1 /* 1: text start */ -#define BISZ_TXTEND_IDX 2 /* 2: text end */ -#define BISZ_DATAST_IDX 3 /* 3: data start */ -#define BISZ_DATAEND_IDX 4 /* 4: data end */ -#define BISZ_BSSST_IDX 5 /* 5: bss start */ -#define BISZ_BSSEND_IDX 6 /* 6: bss end */ -#define BISZ_SIZE 7 /* descriptor size in 32-bit intergers */ - -#endif /* _HNDSOC_H */ diff --git a/drivers/net/wireless/bcm4329/include/linux_osl.h b/drivers/net/wireless/bcm4329/include/linux_osl.h deleted file mode 100644 index b059c2adb17d..000000000000 --- a/drivers/net/wireless/bcm4329/include/linux_osl.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Linux OS Independent Layer - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: linux_osl.h,v 13.131.30.8 2010/04/26 05:42:18 Exp $ - */ - - -#ifndef _linux_osl_h_ -#define _linux_osl_h_ - -#include - - -#include - - -#ifdef __GNUC__ -#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#if GCC_VERSION > 30100 -#define ASSERT(exp) do {} while (0) -#else - -#define ASSERT(exp) -#endif -#endif - - -#define OSL_DELAY(usec) osl_delay(usec) -extern void osl_delay(uint usec); - - - -#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \ - osl_pcmcia_read_attr((osh), (offset), (buf), (size)) -#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \ - osl_pcmcia_write_attr((osh), (offset), (buf), (size)) -extern void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size); -extern void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size); - - -#define OSL_PCI_READ_CONFIG(osh, offset, size) \ - osl_pci_read_config((osh), (offset), (size)) -#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \ - osl_pci_write_config((osh), (offset), (size), (val)) -extern uint32 osl_pci_read_config(osl_t *osh, uint offset, uint size); -extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val); - - -#define OSL_PCI_BUS(osh) osl_pci_bus(osh) -#define OSL_PCI_SLOT(osh) osl_pci_slot(osh) -extern uint osl_pci_bus(osl_t *osh); -extern uint osl_pci_slot(osl_t *osh); - - -typedef struct { - bool pkttag; - uint pktalloced; - bool mmbus; - pktfree_cb_fn_t tx_fn; - void *tx_ctx; -} osl_pubinfo_t; - - -extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag); -extern void osl_detach(osl_t *osh); - -#define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \ - do { \ - ((osl_pubinfo_t*)osh)->tx_fn = _tx_fn; \ - ((osl_pubinfo_t*)osh)->tx_ctx = _tx_ctx; \ - } while (0) - - -#define BUS_SWAP32(v) (v) - - -#define MALLOC(osh, size) osl_malloc((osh), (size)) -#define MFREE(osh, addr, size) osl_mfree((osh), (addr), (size)) -#define MALLOCED(osh) osl_malloced((osh)) - - -#define MALLOC_FAILED(osh) osl_malloc_failed((osh)) - -extern void *osl_malloc(osl_t *osh, uint size); -extern void osl_mfree(osl_t *osh, void *addr, uint size); -extern uint osl_malloced(osl_t *osh); -extern uint osl_malloc_failed(osl_t *osh); - - -#define DMA_CONSISTENT_ALIGN PAGE_SIZE -#define DMA_ALLOC_CONSISTENT(osh, size, pap, dmah, alignbits) \ - osl_dma_alloc_consistent((osh), (size), (pap)) -#define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \ - osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) -extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap); -extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa); - - -#define DMA_TX 1 -#define DMA_RX 2 - - -#define DMA_MAP(osh, va, size, direction, p, dmah) \ - osl_dma_map((osh), (va), (size), (direction)) -#define DMA_UNMAP(osh, pa, size, direction, p, dmah) \ - osl_dma_unmap((osh), (pa), (size), (direction)) -extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction); -extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); - - -#define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0) - - -#include -#define OSL_WRITE_REG(osh, r, v) (bcmsdh_reg_write(NULL, (uintptr)(r), sizeof(*(r)), (v))) -#define OSL_READ_REG(osh, r) (bcmsdh_reg_read(NULL, (uintptr)(r), sizeof(*(r)))) - -#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) if (((osl_pubinfo_t*)(osh))->mmbus) \ - mmap_op else bus_op -#define SELECT_BUS_READ(osh, mmap_op, bus_op) (((osl_pubinfo_t*)(osh))->mmbus) ? \ - mmap_op : bus_op - - - - -#ifndef printf -#define printf(fmt, args...) printk(fmt, ## args) -#endif -#include -#include - - -#ifndef IL_BIGENDIAN -#define R_REG(osh, r) (\ - SELECT_BUS_READ(osh, sizeof(*(r)) == sizeof(uint8) ? readb((volatile uint8*)(r)) : \ - sizeof(*(r)) == sizeof(uint16) ? readw((volatile uint16*)(r)) : \ - readl((volatile uint32*)(r)), OSL_READ_REG(osh, r)) \ -) -#define W_REG(osh, r, v) do { \ - SELECT_BUS_WRITE(osh, \ - switch (sizeof(*(r))) { \ - case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ - case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ - case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ - }, \ - (OSL_WRITE_REG(osh, r, v))); \ - } while (0) -#else -#define R_REG(osh, r) (\ - SELECT_BUS_READ(osh, \ - ({ \ - __typeof(*(r)) __osl_v; \ - switch (sizeof(*(r))) { \ - case sizeof(uint8): __osl_v = \ - readb((volatile uint8*)((uintptr)(r)^3)); break; \ - case sizeof(uint16): __osl_v = \ - readw((volatile uint16*)((uintptr)(r)^2)); break; \ - case sizeof(uint32): __osl_v = \ - readl((volatile uint32*)(r)); break; \ - } \ - __osl_v; \ - }), \ - OSL_READ_REG(osh, r)) \ -) -#define W_REG(osh, r, v) do { \ - SELECT_BUS_WRITE(osh, \ - switch (sizeof(*(r))) { \ - case sizeof(uint8): writeb((uint8)(v), \ - (volatile uint8*)((uintptr)(r)^3)); break; \ - case sizeof(uint16): writew((uint16)(v), \ - (volatile uint16*)((uintptr)(r)^2)); break; \ - case sizeof(uint32): writel((uint32)(v), \ - (volatile uint32*)(r)); break; \ - }, \ - (OSL_WRITE_REG(osh, r, v))); \ - } while (0) -#endif - -#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) -#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) - - -#define bcopy(src, dst, len) memcpy((dst), (src), (len)) -#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) -#define bzero(b, len) memset((b), '\0', (len)) - - -#define OSL_UNCACHED(va) ((void*)va) - - -#if defined(__i386__) -#define OSL_GETCYCLES(x) rdtscl((x)) -#else -#define OSL_GETCYCLES(x) ((x) = 0) -#endif - - -#define BUSPROBE(val, addr) ({ (val) = R_REG(NULL, (addr)); 0; }) - - -#if !defined(CONFIG_MMC_MSM7X00A) -#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) -#else -#define REG_MAP(pa, size) (void *)(0) -#endif -#define REG_UNMAP(va) iounmap((va)) - - -#define R_SM(r) *(r) -#define W_SM(r, v) (*(r) = (v)) -#define BZERO_SM(r, len) memset((r), '\0', (len)) - - -#define PKTGET(osh, len, send) osl_pktget((osh), (len)) -#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) -#ifdef DHD_USE_STATIC_BUF -#define PKTGET_STATIC(osh, len, send) osl_pktget_static((osh), (len)) -#define PKTFREE_STATIC(osh, skb, send) osl_pktfree_static((osh), (skb), (send)) -#endif -#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data) -#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len) -#define PKTHEADROOM(osh, skb) (PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head)) -#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail)) -#define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next) -#define PKTSETNEXT(osh, skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x)) -#define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len)) -#define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes)) -#define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes)) -#define PKTDUP(osh, skb) osl_pktdup((osh), (skb)) -#define PKTTAG(skb) ((void*)(((struct sk_buff*)(skb))->cb)) -#define PKTALLOCED(osh) ((osl_pubinfo_t *)(osh))->pktalloced -#define PKTSETPOOL(osh, skb, x, y) do {} while (0) -#define PKTPOOL(osh, skb) FALSE -#define PKTPOOLLEN(osh, pktp) (0) -#define PKTPOOLAVAIL(osh, pktp) (0) -#define PKTPOOLADD(osh, pktp, p) BCME_ERROR -#define PKTPOOLGET(osh, pktp) NULL -#define PKTLIST_DUMP(osh, buf) - -extern void *osl_pktget(osl_t *osh, uint len); -extern void osl_pktfree(osl_t *osh, void *skb, bool send); -extern void *osl_pktget_static(osl_t *osh, uint len); -extern void osl_pktfree_static(osl_t *osh, void *skb, bool send); -extern void *osl_pktdup(osl_t *osh, void *skb); - - - -static INLINE void * -osl_pkt_frmnative(osl_pubinfo_t *osh, struct sk_buff *skb) -{ - struct sk_buff *nskb; - - if (osh->pkttag) - bzero((void*)skb->cb, OSL_PKTTAG_SZ); - - - for (nskb = skb; nskb; nskb = nskb->next) { - osh->pktalloced++; - } - - return (void *)skb; -} -#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_pubinfo_t *)osh), (struct sk_buff*)(skb)) - - -static INLINE struct sk_buff * -osl_pkt_tonative(osl_pubinfo_t *osh, void *pkt) -{ - struct sk_buff *nskb; - - if (osh->pkttag) - bzero(((struct sk_buff*)pkt)->cb, OSL_PKTTAG_SZ); - - - for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { - osh->pktalloced--; - } - - return (struct sk_buff *)pkt; -} -#define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osl_pubinfo_t *)(osh), (pkt)) - -#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev) -#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x)) -#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority) -#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x)) -#define PKTSUMNEEDED(skb) (((struct sk_buff*)(skb))->ip_summed == CHECKSUM_HW) -#define PKTSETSUMGOOD(skb, x) (((struct sk_buff*)(skb))->ip_summed = \ - ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE)) - -#define PKTSHARED(skb) (((struct sk_buff*)(skb))->cloned) - - -#define OSL_ERROR(bcmerror) osl_error(bcmerror) -extern int osl_error(int bcmerror); - - -#define PKTBUFSZ 2048 - - -#define OSL_SYSUPTIME() ((uint32)jiffies * (1000 / HZ)) -#endif diff --git a/drivers/net/wireless/bcm4329/include/linuxver.h b/drivers/net/wireless/bcm4329/include/linuxver.h deleted file mode 100644 index 6ed22658a72b..000000000000 --- a/drivers/net/wireless/bcm4329/include/linuxver.h +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Linux-specific abstractions to gain some independence from linux kernel versions. - * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: linuxver.h,v 13.38.8.1.8.6 2010/04/29 05:00:46 Exp $ - */ - - -#ifndef _linuxver_h_ -#define _linuxver_h_ - -#include -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) -#include -#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)) -#include -#endif -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)) - -#ifdef __UNDEF_NO_VERSION__ -#undef __NO_VERSION__ -#else -#define __NO_VERSION__ -#endif -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#define module_param(_name_, _type_, _perm_) MODULE_PARM(_name_, "i") -#define module_param_string(_name_, _string_, _size_, _perm_) \ - MODULE_PARM(_string_, "c" __MODULE_STRING(_size_)) -#endif - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 9)) -#include -#else -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) -#undef IP_TOS -#endif -#include - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41)) -#include -#else -#include -#ifndef work_struct -#define work_struct tq_struct -#endif -#ifndef INIT_WORK -#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data)) -#endif -#ifndef schedule_work -#define schedule_work(_work) schedule_task((_work)) -#endif -#ifndef flush_scheduled_work -#define flush_scheduled_work() flush_scheduled_tasks() -#endif -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) -#define MY_INIT_WORK(_work, _func, _data) INIT_WORK(_work, _func) -#else -#define MY_INIT_WORK(_work, _func, _data) INIT_WORK(_work, _func, _data) -typedef void (*work_func_t)(void *work); -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) - -#ifndef IRQ_NONE -typedef void irqreturn_t; -#define IRQ_NONE -#define IRQ_HANDLED -#define IRQ_RETVAL(x) -#endif -#else -typedef irqreturn_t(*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs); -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) -#define IRQF_SHARED SA_SHIRQ -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17) -#ifdef CONFIG_NET_RADIO -#define CONFIG_WIRELESS_EXT -#endif -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 67) -#ifndef SANDGATE2G -#define MOD_INC_USE_COUNT -#endif -#endif - - -#ifndef __exit -#define __exit -#endif -#ifndef __devexit -#define __devexit -#endif -#ifndef __devinit -#define __devinit __init -#endif -#ifndef __devinitdata -#define __devinitdata -#endif -#ifndef __devexit_p -#define __devexit_p(x) x -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)) - -#define pci_get_drvdata(dev) (dev)->sysdata -#define pci_set_drvdata(dev, value) (dev)->sysdata = (value) - - - -struct pci_device_id { - unsigned int vendor, device; - unsigned int subvendor, subdevice; - unsigned int class, class_mask; - unsigned long driver_data; -}; - -struct pci_driver { - struct list_head node; - char *name; - const struct pci_device_id *id_table; - int (*probe)(struct pci_dev *dev, - const struct pci_device_id *id); - void (*remove)(struct pci_dev *dev); - void (*suspend)(struct pci_dev *dev); - void (*resume)(struct pci_dev *dev); -}; - -#define MODULE_DEVICE_TABLE(type, name) -#define PCI_ANY_ID (~0) - - -#define pci_module_init pci_register_driver -extern int pci_register_driver(struct pci_driver *drv); -extern void pci_unregister_driver(struct pci_driver *drv); - -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)) -#define pci_module_init pci_register_driver -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)) -#ifdef MODULE -#define module_init(x) int init_module(void) { return x(); } -#define module_exit(x) void cleanup_module(void) { x(); } -#else -#define module_init(x) __initcall(x); -#define module_exit(x) __exitcall(x); -#endif -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 48)) -#define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 13)) -#define pci_resource_start(dev, bar) ((dev)->base_address[(bar)]) -#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 44)) -#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start) -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 23)) -#define pci_enable_device(dev) do { } while (0) -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 14)) -#define net_device device -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 42)) - - - -#ifndef PCI_DMA_TODEVICE -#define PCI_DMA_TODEVICE 1 -#define PCI_DMA_FROMDEVICE 2 -#endif - -typedef u32 dma_addr_t; - - -static inline int get_order(unsigned long size) -{ - int order; - - size = (size-1) >> (PAGE_SHIFT-1); - order = -1; - do { - size >>= 1; - order++; - } while (size); - return order; -} - -static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, - dma_addr_t *dma_handle) -{ - void *ret; - int gfp = GFP_ATOMIC | GFP_DMA; - - ret = (void *)__get_free_pages(gfp, get_order(size)); - - if (ret != NULL) { - memset(ret, 0, size); - *dma_handle = virt_to_bus(ret); - } - return ret; -} -static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - free_pages((unsigned long)vaddr, get_order(size)); -} -#define pci_map_single(cookie, address, size, dir) virt_to_bus(address) -#define pci_unmap_single(cookie, address, size, dir) - -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43)) - -#define dev_kfree_skb_any(a) dev_kfree_skb(a) -#define netif_down(dev) do { (dev)->start = 0; } while (0) - - -#ifndef _COMPAT_NETDEVICE_H - - - -#define dev_kfree_skb_irq(a) dev_kfree_skb(a) -#define netif_wake_queue(dev) \ - do { clear_bit(0, &(dev)->tbusy); mark_bh(NET_BH); } while (0) -#define netif_stop_queue(dev) set_bit(0, &(dev)->tbusy) - -static inline void netif_start_queue(struct net_device *dev) -{ - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; -} - -#define netif_queue_stopped(dev) (dev)->tbusy -#define netif_running(dev) (dev)->start - -#endif - -#define netif_device_attach(dev) netif_start_queue(dev) -#define netif_device_detach(dev) netif_stop_queue(dev) - - -#define tasklet_struct tq_struct -static inline void tasklet_schedule(struct tasklet_struct *tasklet) -{ - queue_task(tasklet, &tq_immediate); - mark_bh(IMMEDIATE_BH); -} - -static inline void tasklet_init(struct tasklet_struct *tasklet, - void (*func)(unsigned long), - unsigned long data) -{ - tasklet->next = NULL; - tasklet->sync = 0; - tasklet->routine = (void (*)(void *))func; - tasklet->data = (void *)data; -} -#define tasklet_kill(tasklet) { do {} while (0); } - - -#define del_timer_sync(timer) del_timer(timer) - -#else - -#define netif_down(dev) - -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3)) - - -#define PREPARE_TQUEUE(_tq, _routine, _data) \ - do { \ - (_tq)->routine = _routine; \ - (_tq)->data = _data; \ - } while (0) - - -#define INIT_TQUEUE(_tq, _routine, _data) \ - do { \ - INIT_LIST_HEAD(&(_tq)->list); \ - (_tq)->sync = 0; \ - PREPARE_TQUEUE((_tq), (_routine), (_data)); \ - } while (0) - -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 6)) - - - -static inline int -pci_save_state(struct pci_dev *dev, u32 *buffer) -{ - int i; - if (buffer) { - for (i = 0; i < 16; i++) - pci_read_config_dword(dev, i * 4, &buffer[i]); - } - return 0; -} - -static inline int -pci_restore_state(struct pci_dev *dev, u32 *buffer) -{ - int i; - - if (buffer) { - for (i = 0; i < 16; i++) - pci_write_config_dword(dev, i * 4, buffer[i]); - } - - else { - for (i = 0; i < 6; i ++) - pci_write_config_dword(dev, - PCI_BASE_ADDRESS_0 + (i * 4), - pci_resource_start(dev, i)); - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - } - return 0; -} - -#endif - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 19)) -#define read_c0_count() read_32bit_cp0_register(CP0_COUNT) -#endif - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)) -#ifndef SET_MODULE_OWNER -#define SET_MODULE_OWNER(dev) do {} while (0) -#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT -#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT -#else -#define OLD_MOD_INC_USE_COUNT do {} while (0) -#define OLD_MOD_DEC_USE_COUNT do {} while (0) -#endif -#else -#ifndef SET_MODULE_OWNER -#define SET_MODULE_OWNER(dev) do {} while (0) -#endif -#ifndef MOD_INC_USE_COUNT -#define MOD_INC_USE_COUNT do {} while (0) -#endif -#ifndef MOD_DEC_USE_COUNT -#define MOD_DEC_USE_COUNT do {} while (0) -#endif -#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT -#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT -#endif - -#ifndef SET_NETDEV_DEV -#define SET_NETDEV_DEV(net, pdev) do {} while (0) -#endif - -#ifndef HAVE_FREE_NETDEV -#define free_netdev(dev) kfree(dev) -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) - -#define af_packet_priv data -#endif - - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) -#define DRV_SUSPEND_STATE_TYPE pm_message_t -#else -#define DRV_SUSPEND_STATE_TYPE uint32 -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) -#define CHECKSUM_HW CHECKSUM_PARTIAL -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -#define KILL_PROC(pid, sig) \ -{ \ - struct task_struct *tsk; \ - tsk = pid_task(find_vpid(pid), PIDTYPE_PID); \ - if (tsk) send_sig(sig, tsk, 1); \ -} -#else -#define KILL_PROC(pid, sig) \ -{ \ - kill_proc(pid, sig, 1); \ -} -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) -#define netdev_priv(dev) dev->priv -#endif - -#endif diff --git a/drivers/net/wireless/bcm4329/include/miniopt.h b/drivers/net/wireless/bcm4329/include/miniopt.h deleted file mode 100644 index 3667fb1e215b..000000000000 --- a/drivers/net/wireless/bcm4329/include/miniopt.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Command line options parser. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * $Id: miniopt.h,v 1.1.6.2 2009/01/14 23:52:48 Exp $ - */ - - -#ifndef MINI_OPT_H -#define MINI_OPT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* ---- Include Files ---------------------------------------------------- */ -/* ---- Constants and Types ---------------------------------------------- */ - -#define MINIOPT_MAXKEY 128 /* Max options */ -typedef struct miniopt { - - /* These are persistent after miniopt_init() */ - const char* name; /* name for prompt in error strings */ - const char* flags; /* option chars that take no args */ - bool longflags; /* long options may be flags */ - bool opt_end; /* at end of options (passed a "--") */ - - /* These are per-call to miniopt() */ - - int consumed; /* number of argv entries cosumed in - * the most recent call to miniopt() - */ - bool positional; - bool good_int; /* 'val' member is the result of a sucessful - * strtol conversion of the option value - */ - char opt; - char key[MINIOPT_MAXKEY]; - char* valstr; /* positional param, or value for the option, - * or null if the option had - * no accompanying value - */ - uint uval; /* strtol translation of valstr */ - int val; /* strtol translation of valstr */ -} miniopt_t; - -void miniopt_init(miniopt_t *t, const char* name, const char* flags, bool longflags); -int miniopt(miniopt_t *t, char **argv); - - -/* ---- Variable Externs ------------------------------------------------- */ -/* ---- Function Prototypes ---------------------------------------------- */ - - -#ifdef __cplusplus - } -#endif - -#endif /* MINI_OPT_H */ diff --git a/drivers/net/wireless/bcm4329/include/msgtrace.h b/drivers/net/wireless/bcm4329/include/msgtrace.h deleted file mode 100644 index 1479086dba3e..000000000000 --- a/drivers/net/wireless/bcm4329/include/msgtrace.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Trace messages sent over HBUS - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: msgtrace.h,v 1.1.2.4 2009/01/27 04:09:40 Exp $ - */ - -#ifndef _MSGTRACE_H -#define _MSGTRACE_H - -#ifndef _TYPEDEFS_H_ -#include -#endif - - -/* This marks the start of a packed structure section. */ -#include - -#define MSGTRACE_VERSION 1 - -/* Message trace header */ -typedef BWL_PRE_PACKED_STRUCT struct msgtrace_hdr { - uint8 version; - uint8 spare; - uint16 len; /* Len of the trace */ - uint32 seqnum; /* Sequence number of message. Useful if the messsage has been lost - * because of DMA error or a bus reset (ex: SDIO Func2) - */ - uint32 discarded_bytes; /* Number of discarded bytes because of trace overflow */ - uint32 discarded_printf; /* Number of discarded printf because of trace overflow */ -} BWL_POST_PACKED_STRUCT msgtrace_hdr_t; - -#define MSGTRACE_HDRLEN sizeof(msgtrace_hdr_t) - -/* The hbus driver generates traces when sending a trace message. This causes endless traces. - * This flag must be set to TRUE in any hbus traces. The flag is reset in the function msgtrace_put. - * This prevents endless traces but generates hasardous lost of traces only in bus device code. - * It is recommendat to set this flag in macro SD_TRACE but not in SD_ERROR for avoiding missing - * hbus error traces. hbus error trace should not generates endless traces. - */ -extern bool msgtrace_hbus_trace; - -typedef void (*msgtrace_func_send_t)(void *hdl1, void *hdl2, uint8 *hdr, - uint16 hdrlen, uint8 *buf, uint16 buflen); - -extern void msgtrace_sent(void); -extern void msgtrace_put(char *buf, int count); -extern void msgtrace_init(void *hdl1, void *hdl2, msgtrace_func_send_t func_send); - -/* This marks the end of a packed structure section. */ -#include - -#endif /* _MSGTRACE_H */ diff --git a/drivers/net/wireless/bcm4329/include/osl.h b/drivers/net/wireless/bcm4329/include/osl.h deleted file mode 100644 index 5599e536eeea..000000000000 --- a/drivers/net/wireless/bcm4329/include/osl.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * OS Abstraction Layer - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * $Id: osl.h,v 13.37.32.1 2008/11/20 00:51:15 Exp $ - */ - - -#ifndef _osl_h_ -#define _osl_h_ - - -typedef struct osl_info osl_t; -typedef struct osl_dmainfo osldma_t; - -#define OSL_PKTTAG_SZ 32 - - -typedef void (*pktfree_cb_fn_t)(void *ctx, void *pkt, unsigned int status); - -#include - - - - -#define SET_REG(osh, r, mask, val) W_REG((osh), (r), ((R_REG((osh), r) & ~(mask)) | (val))) - -#ifndef AND_REG -#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) -#endif - -#ifndef OR_REG -#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) -#endif - - -#endif diff --git a/drivers/net/wireless/bcm4329/include/packed_section_end.h b/drivers/net/wireless/bcm4329/include/packed_section_end.h deleted file mode 100644 index 5b61c18fcd08..000000000000 --- a/drivers/net/wireless/bcm4329/include/packed_section_end.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Declare directives for structure packing. No padding will be provided - * between the members of packed structures, and therefore, there is no - * guarantee that structure members will be aligned. - * - * Declaring packed structures is compiler specific. In order to handle all - * cases, packed structures should be delared as: - * - * #include - * - * typedef BWL_PRE_PACKED_STRUCT struct foobar_t { - * some_struct_members; - * } BWL_POST_PACKED_STRUCT foobar_t; - * - * #include - * - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * $Id: packed_section_end.h,v 1.1.6.3 2008/12/10 00:27:54 Exp $ - */ - - - - -#ifdef BWL_PACKED_SECTION - #undef BWL_PACKED_SECTION -#else - #error "BWL_PACKED_SECTION is NOT defined!" -#endif - - - - - -#undef BWL_PRE_PACKED_STRUCT -#undef BWL_POST_PACKED_STRUCT diff --git a/drivers/net/wireless/bcm4329/include/packed_section_start.h b/drivers/net/wireless/bcm4329/include/packed_section_start.h deleted file mode 100644 index cb93aa64079a..000000000000 --- a/drivers/net/wireless/bcm4329/include/packed_section_start.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Declare directives for structure packing. No padding will be provided - * between the members of packed structures, and therefore, there is no - * guarantee that structure members will be aligned. - * - * Declaring packed structures is compiler specific. In order to handle all - * cases, packed structures should be delared as: - * - * #include - * - * typedef BWL_PRE_PACKED_STRUCT struct foobar_t { - * some_struct_members; - * } BWL_POST_PACKED_STRUCT foobar_t; - * - * #include - * - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * $Id: packed_section_start.h,v 1.1.6.3 2008/12/10 00:27:54 Exp $ - */ - - - - -#ifdef BWL_PACKED_SECTION - #error "BWL_PACKED_SECTION is already defined!" -#else - #define BWL_PACKED_SECTION -#endif - - - - - -#if defined(__GNUC__) - #define BWL_PRE_PACKED_STRUCT - #define BWL_POST_PACKED_STRUCT __attribute__((packed)) -#elif defined(__CC_ARM) - #define BWL_PRE_PACKED_STRUCT __packed - #define BWL_POST_PACKED_STRUCT -#else - #error "Unknown compiler!" -#endif diff --git a/drivers/net/wireless/bcm4329/include/pcicfg.h b/drivers/net/wireless/bcm4329/include/pcicfg.h deleted file mode 100644 index 898962c942a8..000000000000 --- a/drivers/net/wireless/bcm4329/include/pcicfg.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * pcicfg.h: PCI configuration constants and structures. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: pcicfg.h,v 1.41.12.3 2008/06/26 22:49:41 Exp $ - */ - - -#ifndef _h_pcicfg_ -#define _h_pcicfg_ - - -#define PCI_CFG_VID 0 -#define PCI_CFG_CMD 4 -#define PCI_CFG_REV 8 -#define PCI_CFG_BAR0 0x10 -#define PCI_CFG_BAR1 0x14 -#define PCI_BAR0_WIN 0x80 -#define PCI_INT_STATUS 0x90 -#define PCI_INT_MASK 0x94 - -#define PCIE_EXTCFG_OFFSET 0x100 -#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) -#define PCI_BAR0_PCISBR_OFFSET (4 * 1024) - -#define PCI_BAR0_WINSZ (16 * 1024) - - -#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) -#define PCI_16KB0_CCREGS_OFFSET (12 * 1024) -#define PCI_16KBB0_WINSZ (16 * 1024) - -#endif diff --git a/drivers/net/wireless/bcm4329/include/proto/802.11.h b/drivers/net/wireless/bcm4329/include/proto/802.11.h deleted file mode 100644 index fd26317361da..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/802.11.h +++ /dev/null @@ -1,1433 +0,0 @@ -/* - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * Fundamental types and constants relating to 802.11 - * - * $Id: 802.11.h,v 9.219.4.1.4.5.6.11 2010/02/09 13:23:26 Exp $ - */ - - -#ifndef _802_11_H_ -#define _802_11_H_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - -#ifndef _NET_ETHERNET_H_ -#include -#endif - -#include - - -#include - - -#define DOT11_TU_TO_US 1024 - - -#define DOT11_A3_HDR_LEN 24 -#define DOT11_A4_HDR_LEN 30 -#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN -#define DOT11_FCS_LEN 4 -#define DOT11_ICV_LEN 4 -#define DOT11_ICV_AES_LEN 8 -#define DOT11_QOS_LEN 2 -#define DOT11_HTC_LEN 4 - -#define DOT11_KEY_INDEX_SHIFT 6 -#define DOT11_IV_LEN 4 -#define DOT11_IV_TKIP_LEN 8 -#define DOT11_IV_AES_OCB_LEN 4 -#define DOT11_IV_AES_CCM_LEN 8 -#define DOT11_IV_MAX_LEN 8 - - -#define DOT11_MAX_MPDU_BODY_LEN 2304 - -#define DOT11_MAX_MPDU_LEN (DOT11_A4_HDR_LEN + \ - DOT11_QOS_LEN + \ - DOT11_IV_AES_CCM_LEN + \ - DOT11_MAX_MPDU_BODY_LEN + \ - DOT11_ICV_LEN + \ - DOT11_FCS_LEN) - -#define DOT11_MAX_SSID_LEN 32 - - -#define DOT11_DEFAULT_RTS_LEN 2347 -#define DOT11_MAX_RTS_LEN 2347 - - -#define DOT11_MIN_FRAG_LEN 256 -#define DOT11_MAX_FRAG_LEN 2346 -#define DOT11_DEFAULT_FRAG_LEN 2346 - - -#define DOT11_MIN_BEACON_PERIOD 1 -#define DOT11_MAX_BEACON_PERIOD 0xFFFF - - -#define DOT11_MIN_DTIM_PERIOD 1 -#define DOT11_MAX_DTIM_PERIOD 0xFF - - -#define DOT11_LLC_SNAP_HDR_LEN 8 -#define DOT11_OUI_LEN 3 -BWL_PRE_PACKED_STRUCT struct dot11_llc_snap_header { - uint8 dsap; - uint8 ssap; - uint8 ctl; - uint8 oui[DOT11_OUI_LEN]; - uint16 type; -} BWL_POST_PACKED_STRUCT; - - -#define RFC1042_HDR_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN) - - - -BWL_PRE_PACKED_STRUCT struct dot11_header { - uint16 fc; - uint16 durid; - struct ether_addr a1; - struct ether_addr a2; - struct ether_addr a3; - uint16 seq; - struct ether_addr a4; -} BWL_POST_PACKED_STRUCT; - - - -BWL_PRE_PACKED_STRUCT struct dot11_rts_frame { - uint16 fc; - uint16 durid; - struct ether_addr ra; - struct ether_addr ta; -} BWL_POST_PACKED_STRUCT; -#define DOT11_RTS_LEN 16 - -BWL_PRE_PACKED_STRUCT struct dot11_cts_frame { - uint16 fc; - uint16 durid; - struct ether_addr ra; -} BWL_POST_PACKED_STRUCT; -#define DOT11_CTS_LEN 10 - -BWL_PRE_PACKED_STRUCT struct dot11_ack_frame { - uint16 fc; - uint16 durid; - struct ether_addr ra; -} BWL_POST_PACKED_STRUCT; -#define DOT11_ACK_LEN 10 - -BWL_PRE_PACKED_STRUCT struct dot11_ps_poll_frame { - uint16 fc; - uint16 durid; - struct ether_addr bssid; - struct ether_addr ta; -} BWL_POST_PACKED_STRUCT; -#define DOT11_PS_POLL_LEN 16 - -BWL_PRE_PACKED_STRUCT struct dot11_cf_end_frame { - uint16 fc; - uint16 durid; - struct ether_addr ra; - struct ether_addr bssid; -} BWL_POST_PACKED_STRUCT; -#define DOT11_CS_END_LEN 16 - -BWL_PRE_PACKED_STRUCT struct dot11_action_wifi_vendor_specific { - uint8 category; - uint8 OUI[3]; - uint8 type; - uint8 subtype; - uint8 data[1040]; - struct dot11_action_wifi_vendor_specific* next_node; -} BWL_POST_PACKED_STRUCT; - -typedef struct dot11_action_wifi_vendor_specific dot11_action_wifi_vendor_specific_t; - -#define DOT11_BA_CTL_POLICY_NORMAL 0x0000 -#define DOT11_BA_CTL_POLICY_NOACK 0x0001 -#define DOT11_BA_CTL_POLICY_MASK 0x0001 - -#define DOT11_BA_CTL_MTID 0x0002 -#define DOT11_BA_CTL_COMPRESSED 0x0004 - -#define DOT11_BA_CTL_NUMMSDU_MASK 0x0FC0 -#define DOT11_BA_CTL_NUMMSDU_SHIFT 6 - -#define DOT11_BA_CTL_TID_MASK 0xF000 -#define DOT11_BA_CTL_TID_SHIFT 12 - - -BWL_PRE_PACKED_STRUCT struct dot11_ctl_header { - uint16 fc; - uint16 durid; - struct ether_addr ra; - struct ether_addr ta; -} BWL_POST_PACKED_STRUCT; -#define DOT11_CTL_HDR_LEN 16 - - -BWL_PRE_PACKED_STRUCT struct dot11_bar { - uint16 bar_control; - uint16 seqnum; -} BWL_POST_PACKED_STRUCT; -#define DOT11_BAR_LEN 4 - -#define DOT11_BA_BITMAP_LEN 128 -#define DOT11_BA_CMP_BITMAP_LEN 8 - -BWL_PRE_PACKED_STRUCT struct dot11_ba { - uint16 ba_control; - uint16 seqnum; - uint8 bitmap[DOT11_BA_BITMAP_LEN]; -} BWL_POST_PACKED_STRUCT; -#define DOT11_BA_LEN 4 - - -BWL_PRE_PACKED_STRUCT struct dot11_management_header { - uint16 fc; - uint16 durid; - struct ether_addr da; - struct ether_addr sa; - struct ether_addr bssid; - uint16 seq; -} BWL_POST_PACKED_STRUCT; -#define DOT11_MGMT_HDR_LEN 24 - - - -BWL_PRE_PACKED_STRUCT struct dot11_bcn_prb { - uint32 timestamp[2]; - uint16 beacon_interval; - uint16 capability; -} BWL_POST_PACKED_STRUCT; -#define DOT11_BCN_PRB_LEN 12 - -BWL_PRE_PACKED_STRUCT struct dot11_auth { - uint16 alg; - uint16 seq; - uint16 status; -} BWL_POST_PACKED_STRUCT; -#define DOT11_AUTH_FIXED_LEN 6 - -BWL_PRE_PACKED_STRUCT struct dot11_assoc_req { - uint16 capability; - uint16 listen; -} BWL_POST_PACKED_STRUCT; -#define DOT11_ASSOC_REQ_FIXED_LEN 4 - -BWL_PRE_PACKED_STRUCT struct dot11_reassoc_req { - uint16 capability; - uint16 listen; - struct ether_addr ap; -} BWL_POST_PACKED_STRUCT; -#define DOT11_REASSOC_REQ_FIXED_LEN 10 - -BWL_PRE_PACKED_STRUCT struct dot11_assoc_resp { - uint16 capability; - uint16 status; - uint16 aid; -} BWL_POST_PACKED_STRUCT; -#define DOT11_ASSOC_RESP_FIXED_LEN 6 - -BWL_PRE_PACKED_STRUCT struct dot11_action_measure { - uint8 category; - uint8 action; - uint8 token; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT; -#define DOT11_ACTION_MEASURE_LEN 3 - -BWL_PRE_PACKED_STRUCT struct dot11_action_ht_ch_width { - uint8 category; - uint8 action; - uint8 ch_width; -} BWL_POST_PACKED_STRUCT; - -BWL_PRE_PACKED_STRUCT struct dot11_action_ht_mimops { - uint8 category; - uint8 action; - uint8 control; -} BWL_POST_PACKED_STRUCT; - -#define SM_PWRSAVE_ENABLE 1 -#define SM_PWRSAVE_MODE 2 - - -BWL_PRE_PACKED_STRUCT struct dot11_power_cnst { - uint8 id; - uint8 len; - uint8 power; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_power_cnst dot11_power_cnst_t; - -BWL_PRE_PACKED_STRUCT struct dot11_power_cap { - uint8 min; - uint8 max; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_power_cap dot11_power_cap_t; - -BWL_PRE_PACKED_STRUCT struct dot11_tpc_rep { - uint8 id; - uint8 len; - uint8 tx_pwr; - uint8 margin; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_tpc_rep dot11_tpc_rep_t; -#define DOT11_MNG_IE_TPC_REPORT_LEN 2 - -BWL_PRE_PACKED_STRUCT struct dot11_supp_channels { - uint8 id; - uint8 len; - uint8 first_channel; - uint8 num_channels; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_supp_channels dot11_supp_channels_t; - - -BWL_PRE_PACKED_STRUCT struct dot11_extch { - uint8 id; - uint8 len; - uint8 extch; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_extch dot11_extch_ie_t; - -BWL_PRE_PACKED_STRUCT struct dot11_brcm_extch { - uint8 id; - uint8 len; - uint8 oui[3]; - uint8 type; - uint8 extch; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_brcm_extch dot11_brcm_extch_ie_t; - -#define BRCM_EXTCH_IE_LEN 5 -#define BRCM_EXTCH_IE_TYPE 53 -#define DOT11_EXTCH_IE_LEN 1 -#define DOT11_EXT_CH_MASK 0x03 -#define DOT11_EXT_CH_UPPER 0x01 -#define DOT11_EXT_CH_LOWER 0x03 -#define DOT11_EXT_CH_NONE 0x00 - -BWL_PRE_PACKED_STRUCT struct dot11_action_frmhdr { - uint8 category; - uint8 action; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT; -#define DOT11_ACTION_FRMHDR_LEN 2 - - -BWL_PRE_PACKED_STRUCT struct dot11_channel_switch { - uint8 id; - uint8 len; - uint8 mode; - uint8 channel; - uint8 count; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_channel_switch dot11_chan_switch_ie_t; - -#define DOT11_SWITCH_IE_LEN 3 - -#define DOT11_CSA_MODE_ADVISORY 0 -#define DOT11_CSA_MODE_NO_TX 1 - -BWL_PRE_PACKED_STRUCT struct dot11_action_switch_channel { - uint8 category; - uint8 action; - dot11_chan_switch_ie_t chan_switch_ie; - dot11_brcm_extch_ie_t extch_ie; -} BWL_POST_PACKED_STRUCT; - -BWL_PRE_PACKED_STRUCT struct dot11_csa_body { - uint8 mode; - uint8 reg; - uint8 channel; - uint8 count; -} BWL_POST_PACKED_STRUCT; - - -BWL_PRE_PACKED_STRUCT struct dot11_ext_csa { - uint8 id; - uint8 len; - struct dot11_csa_body b; -} BWL_POST_PACKED_STRUCT; - -BWL_PRE_PACKED_STRUCT struct dot11y_action_ext_csa { - uint8 category; - uint8 action; - struct dot11_csa_body b; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_ext_csa dot11_ext_csa_ie_t; -#define DOT11_EXT_CSA_IE_LEN 4 - -BWL_PRE_PACKED_STRUCT struct dot11_action_ext_csa { - uint8 category; - uint8 action; - dot11_ext_csa_ie_t chan_switch_ie; -} BWL_POST_PACKED_STRUCT; - -BWL_PRE_PACKED_STRUCT struct dot11_obss_coex { - uint8 id; - uint8 len; - uint8 info; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_obss_coex dot11_obss_coex_t; -#define DOT11_OBSS_COEXINFO_LEN 1 - -#define DOT11_OBSS_COEX_INFO_REQ 0x01 -#define DOT11_OBSS_COEX_40MHZ_INTOLERANT 0x02 -#define DOT11_OBSS_COEX_20MHZ_WIDTH_REQ 0x04 - -BWL_PRE_PACKED_STRUCT struct dot11_obss_chanlist { - uint8 id; - uint8 len; - uint8 regclass; - uint8 chanlist[1]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_obss_chanlist dot11_obss_chanlist_t; -#define DOT11_OBSS_CHANLIST_FIXED_LEN 1 - -BWL_PRE_PACKED_STRUCT struct dot11_extcap_ie { - uint8 id; - uint8 len; - uint8 cap; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_extcap_ie dot11_extcap_ie_t; -#define DOT11_EXTCAP_LEN 1 - - - -#define DOT11_MEASURE_TYPE_BASIC 0 -#define DOT11_MEASURE_TYPE_CCA 1 -#define DOT11_MEASURE_TYPE_RPI 2 - - -#define DOT11_MEASURE_MODE_ENABLE (1<<1) -#define DOT11_MEASURE_MODE_REQUEST (1<<2) -#define DOT11_MEASURE_MODE_REPORT (1<<3) - -#define DOT11_MEASURE_MODE_LATE (1<<0) -#define DOT11_MEASURE_MODE_INCAPABLE (1<<1) -#define DOT11_MEASURE_MODE_REFUSED (1<<2) - -#define DOT11_MEASURE_BASIC_MAP_BSS ((uint8)(1<<0)) -#define DOT11_MEASURE_BASIC_MAP_OFDM ((uint8)(1<<1)) -#define DOT11_MEASURE_BASIC_MAP_UKNOWN ((uint8)(1<<2)) -#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3)) -#define DOT11_MEASURE_BASIC_MAP_UNMEAS ((uint8)(1<<4)) - -BWL_PRE_PACKED_STRUCT struct dot11_meas_req { - uint8 id; - uint8 len; - uint8 token; - uint8 mode; - uint8 type; - uint8 channel; - uint8 start_time[8]; - uint16 duration; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_meas_req dot11_meas_req_t; -#define DOT11_MNG_IE_MREQ_LEN 14 - -#define DOT11_MNG_IE_MREQ_FIXED_LEN 3 - -BWL_PRE_PACKED_STRUCT struct dot11_meas_rep { - uint8 id; - uint8 len; - uint8 token; - uint8 mode; - uint8 type; - BWL_PRE_PACKED_STRUCT union - { - BWL_PRE_PACKED_STRUCT struct { - uint8 channel; - uint8 start_time[8]; - uint16 duration; - uint8 map; - } BWL_POST_PACKED_STRUCT basic; - uint8 data[1]; - } BWL_POST_PACKED_STRUCT rep; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_meas_rep dot11_meas_rep_t; - - -#define DOT11_MNG_IE_MREP_FIXED_LEN 3 - -BWL_PRE_PACKED_STRUCT struct dot11_meas_rep_basic { - uint8 channel; - uint8 start_time[8]; - uint16 duration; - uint8 map; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_meas_rep_basic dot11_meas_rep_basic_t; -#define DOT11_MEASURE_BASIC_REP_LEN 12 - -BWL_PRE_PACKED_STRUCT struct dot11_quiet { - uint8 id; - uint8 len; - uint8 count; - uint8 period; - uint16 duration; - uint16 offset; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_quiet dot11_quiet_t; - -BWL_PRE_PACKED_STRUCT struct chan_map_tuple { - uint8 channel; - uint8 map; -} BWL_POST_PACKED_STRUCT; -typedef struct chan_map_tuple chan_map_tuple_t; - -BWL_PRE_PACKED_STRUCT struct dot11_ibss_dfs { - uint8 id; - uint8 len; - uint8 eaddr[ETHER_ADDR_LEN]; - uint8 interval; - chan_map_tuple_t map[1]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_ibss_dfs dot11_ibss_dfs_t; - - -#define WME_OUI "\x00\x50\xf2" -#define WME_VER 1 -#define WME_TYPE 2 -#define WME_SUBTYPE_IE 0 -#define WME_SUBTYPE_PARAM_IE 1 -#define WME_SUBTYPE_TSPEC 2 - - -#define AC_BE 0 -#define AC_BK 1 -#define AC_VI 2 -#define AC_VO 3 -#define AC_COUNT 4 - -typedef uint8 ac_bitmap_t; - -#define AC_BITMAP_NONE 0x0 -#define AC_BITMAP_ALL 0xf -#define AC_BITMAP_TST(ab, ac) (((ab) & (1 << (ac))) != 0) -#define AC_BITMAP_SET(ab, ac) (((ab) |= (1 << (ac)))) -#define AC_BITMAP_RESET(ab, ac) (((ab) &= ~(1 << (ac)))) - - -BWL_PRE_PACKED_STRUCT struct wme_ie { - uint8 oui[3]; - uint8 type; - uint8 subtype; - uint8 version; - uint8 qosinfo; -} BWL_POST_PACKED_STRUCT; -typedef struct wme_ie wme_ie_t; -#define WME_IE_LEN 7 - -BWL_PRE_PACKED_STRUCT struct edcf_acparam { - uint8 ACI; - uint8 ECW; - uint16 TXOP; -} BWL_POST_PACKED_STRUCT; -typedef struct edcf_acparam edcf_acparam_t; - - -BWL_PRE_PACKED_STRUCT struct wme_param_ie { - uint8 oui[3]; - uint8 type; - uint8 subtype; - uint8 version; - uint8 qosinfo; - uint8 rsvd; - edcf_acparam_t acparam[AC_COUNT]; -} BWL_POST_PACKED_STRUCT; -typedef struct wme_param_ie wme_param_ie_t; -#define WME_PARAM_IE_LEN 24 - - -#define WME_QI_AP_APSD_MASK 0x80 -#define WME_QI_AP_APSD_SHIFT 7 -#define WME_QI_AP_COUNT_MASK 0x0f -#define WME_QI_AP_COUNT_SHIFT 0 - - -#define WME_QI_STA_MAXSPLEN_MASK 0x60 -#define WME_QI_STA_MAXSPLEN_SHIFT 5 -#define WME_QI_STA_APSD_ALL_MASK 0xf -#define WME_QI_STA_APSD_ALL_SHIFT 0 -#define WME_QI_STA_APSD_BE_MASK 0x8 -#define WME_QI_STA_APSD_BE_SHIFT 3 -#define WME_QI_STA_APSD_BK_MASK 0x4 -#define WME_QI_STA_APSD_BK_SHIFT 2 -#define WME_QI_STA_APSD_VI_MASK 0x2 -#define WME_QI_STA_APSD_VI_SHIFT 1 -#define WME_QI_STA_APSD_VO_MASK 0x1 -#define WME_QI_STA_APSD_VO_SHIFT 0 - - -#define EDCF_AIFSN_MIN 1 -#define EDCF_AIFSN_MAX 15 -#define EDCF_AIFSN_MASK 0x0f -#define EDCF_ACM_MASK 0x10 -#define EDCF_ACI_MASK 0x60 -#define EDCF_ACI_SHIFT 5 -#define EDCF_AIFSN_SHIFT 12 - - -#define EDCF_ECW_MIN 0 -#define EDCF_ECW_MAX 15 -#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) -#define EDCF_ECWMIN_MASK 0x0f -#define EDCF_ECWMAX_MASK 0xf0 -#define EDCF_ECWMAX_SHIFT 4 - - -#define EDCF_TXOP_MIN 0 -#define EDCF_TXOP_MAX 65535 -#define EDCF_TXOP2USEC(txop) ((txop) << 5) - - -#define NON_EDCF_AC_BE_ACI_STA 0x02 - - -#define EDCF_AC_BE_ACI_STA 0x03 -#define EDCF_AC_BE_ECW_STA 0xA4 -#define EDCF_AC_BE_TXOP_STA 0x0000 -#define EDCF_AC_BK_ACI_STA 0x27 -#define EDCF_AC_BK_ECW_STA 0xA4 -#define EDCF_AC_BK_TXOP_STA 0x0000 -#define EDCF_AC_VI_ACI_STA 0x42 -#define EDCF_AC_VI_ECW_STA 0x43 -#define EDCF_AC_VI_TXOP_STA 0x005e -#define EDCF_AC_VO_ACI_STA 0x62 -#define EDCF_AC_VO_ECW_STA 0x32 -#define EDCF_AC_VO_TXOP_STA 0x002f - - -#define EDCF_AC_BE_ACI_AP 0x03 -#define EDCF_AC_BE_ECW_AP 0x64 -#define EDCF_AC_BE_TXOP_AP 0x0000 -#define EDCF_AC_BK_ACI_AP 0x27 -#define EDCF_AC_BK_ECW_AP 0xA4 -#define EDCF_AC_BK_TXOP_AP 0x0000 -#define EDCF_AC_VI_ACI_AP 0x41 -#define EDCF_AC_VI_ECW_AP 0x43 -#define EDCF_AC_VI_TXOP_AP 0x005e -#define EDCF_AC_VO_ACI_AP 0x61 -#define EDCF_AC_VO_ECW_AP 0x32 -#define EDCF_AC_VO_TXOP_AP 0x002f - - -BWL_PRE_PACKED_STRUCT struct edca_param_ie { - uint8 qosinfo; - uint8 rsvd; - edcf_acparam_t acparam[AC_COUNT]; -} BWL_POST_PACKED_STRUCT; -typedef struct edca_param_ie edca_param_ie_t; -#define EDCA_PARAM_IE_LEN 18 - - -BWL_PRE_PACKED_STRUCT struct qos_cap_ie { - uint8 qosinfo; -} BWL_POST_PACKED_STRUCT; -typedef struct qos_cap_ie qos_cap_ie_t; - -BWL_PRE_PACKED_STRUCT struct dot11_qbss_load_ie { - uint8 id; - uint8 length; - uint16 station_count; - uint8 channel_utilization; - uint16 aac; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_qbss_load_ie dot11_qbss_load_ie_t; - - -#define FIXED_MSDU_SIZE 0x8000 -#define MSDU_SIZE_MASK 0x7fff - - - -#define INTEGER_SHIFT 13 -#define FRACTION_MASK 0x1FFF - - -BWL_PRE_PACKED_STRUCT struct dot11_management_notification { - uint8 category; - uint8 action; - uint8 token; - uint8 status; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT; -#define DOT11_MGMT_NOTIFICATION_LEN 4 - - -#define WME_ADDTS_REQUEST 0 -#define WME_ADDTS_RESPONSE 1 -#define WME_DELTS_REQUEST 2 - - -#define WME_ADMISSION_ACCEPTED 0 -#define WME_INVALID_PARAMETERS 1 -#define WME_ADMISSION_REFUSED 3 - - -#define BCN_PRB_SSID(body) ((char*)(body) + DOT11_BCN_PRB_LEN) - - -#define DOT11_OPEN_SYSTEM 0 -#define DOT11_SHARED_KEY 1 - -#define DOT11_OPEN_SHARED 2 -#define DOT11_CHALLENGE_LEN 128 - - -#define FC_PVER_MASK 0x3 -#define FC_PVER_SHIFT 0 -#define FC_TYPE_MASK 0xC -#define FC_TYPE_SHIFT 2 -#define FC_SUBTYPE_MASK 0xF0 -#define FC_SUBTYPE_SHIFT 4 -#define FC_TODS 0x100 -#define FC_TODS_SHIFT 8 -#define FC_FROMDS 0x200 -#define FC_FROMDS_SHIFT 9 -#define FC_MOREFRAG 0x400 -#define FC_MOREFRAG_SHIFT 10 -#define FC_RETRY 0x800 -#define FC_RETRY_SHIFT 11 -#define FC_PM 0x1000 -#define FC_PM_SHIFT 12 -#define FC_MOREDATA 0x2000 -#define FC_MOREDATA_SHIFT 13 -#define FC_WEP 0x4000 -#define FC_WEP_SHIFT 14 -#define FC_ORDER 0x8000 -#define FC_ORDER_SHIFT 15 - - -#define SEQNUM_SHIFT 4 -#define SEQNUM_MAX 0x1000 -#define FRAGNUM_MASK 0xF - - - - -#define FC_TYPE_MNG 0 -#define FC_TYPE_CTL 1 -#define FC_TYPE_DATA 2 - - -#define FC_SUBTYPE_ASSOC_REQ 0 -#define FC_SUBTYPE_ASSOC_RESP 1 -#define FC_SUBTYPE_REASSOC_REQ 2 -#define FC_SUBTYPE_REASSOC_RESP 3 -#define FC_SUBTYPE_PROBE_REQ 4 -#define FC_SUBTYPE_PROBE_RESP 5 -#define FC_SUBTYPE_BEACON 8 -#define FC_SUBTYPE_ATIM 9 -#define FC_SUBTYPE_DISASSOC 10 -#define FC_SUBTYPE_AUTH 11 -#define FC_SUBTYPE_DEAUTH 12 -#define FC_SUBTYPE_ACTION 13 -#define FC_SUBTYPE_ACTION_NOACK 14 - - -#define FC_SUBTYPE_CTL_WRAPPER 7 -#define FC_SUBTYPE_BLOCKACK_REQ 8 -#define FC_SUBTYPE_BLOCKACK 9 -#define FC_SUBTYPE_PS_POLL 10 -#define FC_SUBTYPE_RTS 11 -#define FC_SUBTYPE_CTS 12 -#define FC_SUBTYPE_ACK 13 -#define FC_SUBTYPE_CF_END 14 -#define FC_SUBTYPE_CF_END_ACK 15 - - -#define FC_SUBTYPE_DATA 0 -#define FC_SUBTYPE_DATA_CF_ACK 1 -#define FC_SUBTYPE_DATA_CF_POLL 2 -#define FC_SUBTYPE_DATA_CF_ACK_POLL 3 -#define FC_SUBTYPE_NULL 4 -#define FC_SUBTYPE_CF_ACK 5 -#define FC_SUBTYPE_CF_POLL 6 -#define FC_SUBTYPE_CF_ACK_POLL 7 -#define FC_SUBTYPE_QOS_DATA 8 -#define FC_SUBTYPE_QOS_DATA_CF_ACK 9 -#define FC_SUBTYPE_QOS_DATA_CF_POLL 10 -#define FC_SUBTYPE_QOS_DATA_CF_ACK_POLL 11 -#define FC_SUBTYPE_QOS_NULL 12 -#define FC_SUBTYPE_QOS_CF_POLL 14 -#define FC_SUBTYPE_QOS_CF_ACK_POLL 15 - - -#define FC_SUBTYPE_ANY_QOS(s) (((s) & 8) != 0) -#define FC_SUBTYPE_ANY_NULL(s) (((s) & 4) != 0) -#define FC_SUBTYPE_ANY_CF_POLL(s) (((s) & 2) != 0) -#define FC_SUBTYPE_ANY_CF_ACK(s) (((s) & 1) != 0) - - -#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK) - -#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT)) - -#define FC_SUBTYPE(fc) (((fc) & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT) -#define FC_TYPE(fc) (((fc) & FC_TYPE_MASK) >> FC_TYPE_SHIFT) - -#define FC_ASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ) -#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP) -#define FC_REASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ) -#define FC_REASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP) -#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ) -#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP) -#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON) -#define FC_DISASSOC FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC) -#define FC_AUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH) -#define FC_DEAUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH) -#define FC_ACTION FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION) -#define FC_ACTION_NOACK FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION_NOACK) - -#define FC_CTL_WRAPPER FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTL_WRAPPER) -#define FC_BLOCKACK_REQ FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK_REQ) -#define FC_BLOCKACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK) -#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL) -#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS) -#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS) -#define FC_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK) -#define FC_CF_END FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END) -#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK) - -#define FC_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA) -#define FC_NULL_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL) -#define FC_DATA_CF_ACK FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK) -#define FC_QOS_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_DATA) -#define FC_QOS_NULL FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_NULL) - - - - -#define QOS_PRIO_SHIFT 0 -#define QOS_PRIO_MASK 0x0007 -#define QOS_PRIO(qos) (((qos) & QOS_PRIO_MASK) >> QOS_PRIO_SHIFT) - - -#define QOS_TID_SHIFT 0 -#define QOS_TID_MASK 0x000f -#define QOS_TID(qos) (((qos) & QOS_TID_MASK) >> QOS_TID_SHIFT) - - -#define QOS_EOSP_SHIFT 4 -#define QOS_EOSP_MASK 0x0010 -#define QOS_EOSP(qos) (((qos) & QOS_EOSP_MASK) >> QOS_EOSP_SHIFT) - - -#define QOS_ACK_NORMAL_ACK 0 -#define QOS_ACK_NO_ACK 1 -#define QOS_ACK_NO_EXP_ACK 2 -#define QOS_ACK_BLOCK_ACK 3 -#define QOS_ACK_SHIFT 5 -#define QOS_ACK_MASK 0x0060 -#define QOS_ACK(qos) (((qos) & QOS_ACK_MASK) >> QOS_ACK_SHIFT) - - -#define QOS_AMSDU_SHIFT 7 -#define QOS_AMSDU_MASK 0x0080 - - - - - - -#define DOT11_MNG_AUTH_ALGO_LEN 2 -#define DOT11_MNG_AUTH_SEQ_LEN 2 -#define DOT11_MNG_BEACON_INT_LEN 2 -#define DOT11_MNG_CAP_LEN 2 -#define DOT11_MNG_AP_ADDR_LEN 6 -#define DOT11_MNG_LISTEN_INT_LEN 2 -#define DOT11_MNG_REASON_LEN 2 -#define DOT11_MNG_AID_LEN 2 -#define DOT11_MNG_STATUS_LEN 2 -#define DOT11_MNG_TIMESTAMP_LEN 8 - - -#define DOT11_AID_MASK 0x3fff - - -#define DOT11_RC_RESERVED 0 -#define DOT11_RC_UNSPECIFIED 1 -#define DOT11_RC_AUTH_INVAL 2 -#define DOT11_RC_DEAUTH_LEAVING 3 -#define DOT11_RC_INACTIVITY 4 -#define DOT11_RC_BUSY 5 -#define DOT11_RC_INVAL_CLASS_2 6 -#define DOT11_RC_INVAL_CLASS_3 7 -#define DOT11_RC_DISASSOC_LEAVING 8 -#define DOT11_RC_NOT_AUTH 9 -#define DOT11_RC_BAD_PC 10 -#define DOT11_RC_BAD_CHANNELS 11 - - - -#define DOT11_RC_UNSPECIFIED_QOS 32 -#define DOT11_RC_INSUFFCIENT_BW 33 -#define DOT11_RC_EXCESSIVE_FRAMES 34 -#define DOT11_RC_TX_OUTSIDE_TXOP 35 -#define DOT11_RC_LEAVING_QBSS 36 -#define DOT11_RC_BAD_MECHANISM 37 -#define DOT11_RC_SETUP_NEEDED 38 -#define DOT11_RC_TIMEOUT 39 - -#define DOT11_RC_MAX 23 - - -#define DOT11_SC_SUCCESS 0 -#define DOT11_SC_FAILURE 1 -#define DOT11_SC_CAP_MISMATCH 10 -#define DOT11_SC_REASSOC_FAIL 11 -#define DOT11_SC_ASSOC_FAIL 12 -#define DOT11_SC_AUTH_MISMATCH 13 -#define DOT11_SC_AUTH_SEQ 14 -#define DOT11_SC_AUTH_CHALLENGE_FAIL 15 -#define DOT11_SC_AUTH_TIMEOUT 16 -#define DOT11_SC_ASSOC_BUSY_FAIL 17 -#define DOT11_SC_ASSOC_RATE_MISMATCH 18 -#define DOT11_SC_ASSOC_SHORT_REQUIRED 19 -#define DOT11_SC_ASSOC_PBCC_REQUIRED 20 -#define DOT11_SC_ASSOC_AGILITY_REQUIRED 21 -#define DOT11_SC_ASSOC_SPECTRUM_REQUIRED 22 -#define DOT11_SC_ASSOC_BAD_POWER_CAP 23 -#define DOT11_SC_ASSOC_BAD_SUP_CHANNELS 24 -#define DOT11_SC_ASSOC_SHORTSLOT_REQUIRED 25 -#define DOT11_SC_ASSOC_ERPBCC_REQUIRED 26 -#define DOT11_SC_ASSOC_DSSOFDM_REQUIRED 27 - -#define DOT11_SC_DECLINED 37 -#define DOT11_SC_INVALID_PARAMS 38 - - -#define DOT11_MNG_DS_PARAM_LEN 1 -#define DOT11_MNG_IBSS_PARAM_LEN 2 - - -#define DOT11_MNG_TIM_FIXED_LEN 3 -#define DOT11_MNG_TIM_DTIM_COUNT 0 -#define DOT11_MNG_TIM_DTIM_PERIOD 1 -#define DOT11_MNG_TIM_BITMAP_CTL 2 -#define DOT11_MNG_TIM_PVB 3 - - -#define TLV_TAG_OFF 0 -#define TLV_LEN_OFF 1 -#define TLV_HDR_LEN 2 -#define TLV_BODY_OFF 2 - - -#define DOT11_MNG_SSID_ID 0 -#define DOT11_MNG_RATES_ID 1 -#define DOT11_MNG_FH_PARMS_ID 2 -#define DOT11_MNG_DS_PARMS_ID 3 -#define DOT11_MNG_CF_PARMS_ID 4 -#define DOT11_MNG_TIM_ID 5 -#define DOT11_MNG_IBSS_PARMS_ID 6 -#define DOT11_MNG_COUNTRY_ID 7 -#define DOT11_MNG_HOPPING_PARMS_ID 8 -#define DOT11_MNG_HOPPING_TABLE_ID 9 -#define DOT11_MNG_REQUEST_ID 10 -#define DOT11_MNG_QBSS_LOAD_ID 11 -#define DOT11_MNG_EDCA_PARAM_ID 12 -#define DOT11_MNG_CHALLENGE_ID 16 -#define DOT11_MNG_PWR_CONSTRAINT_ID 32 -#define DOT11_MNG_PWR_CAP_ID 33 -#define DOT11_MNG_TPC_REQUEST_ID 34 -#define DOT11_MNG_TPC_REPORT_ID 35 -#define DOT11_MNG_SUPP_CHANNELS_ID 36 -#define DOT11_MNG_CHANNEL_SWITCH_ID 37 -#define DOT11_MNG_MEASURE_REQUEST_ID 38 -#define DOT11_MNG_MEASURE_REPORT_ID 39 -#define DOT11_MNG_QUIET_ID 40 -#define DOT11_MNG_IBSS_DFS_ID 41 -#define DOT11_MNG_ERP_ID 42 -#define DOT11_MNG_TS_DELAY_ID 43 -#define DOT11_MNG_HT_CAP 45 -#define DOT11_MNG_QOS_CAP_ID 46 -#define DOT11_MNG_NONERP_ID 47 -#define DOT11_MNG_RSN_ID 48 -#define DOT11_MNG_EXT_RATES_ID 50 -#define DOT11_MNG_REGCLASS_ID 59 -#define DOT11_MNG_EXT_CSA_ID 60 -#define DOT11_MNG_HT_ADD 61 -#define DOT11_MNG_EXT_CHANNEL_OFFSET 62 -#define DOT11_MNG_WAPI_ID 68 -#define DOT11_MNG_HT_BSS_COEXINFO_ID 72 -#define DOT11_MNG_HT_BSS_CHANNEL_REPORT_ID 73 -#define DOT11_MNG_HT_OBSS_ID 74 -#define DOT11_MNG_EXT_CAP 127 -#define DOT11_MNG_WPA_ID 221 -#define DOT11_MNG_PROPR_ID 221 - - -#define DOT11_RATE_BASIC 0x80 -#define DOT11_RATE_MASK 0x7F - - -#define DOT11_MNG_ERP_LEN 1 -#define DOT11_MNG_NONERP_PRESENT 0x01 -#define DOT11_MNG_USE_PROTECTION 0x02 -#define DOT11_MNG_BARKER_PREAMBLE 0x04 - -#define DOT11_MGN_TS_DELAY_LEN 4 -#define TS_DELAY_FIELD_SIZE 4 - - -#define DOT11_CAP_ESS 0x0001 -#define DOT11_CAP_IBSS 0x0002 -#define DOT11_CAP_POLLABLE 0x0004 -#define DOT11_CAP_POLL_RQ 0x0008 -#define DOT11_CAP_PRIVACY 0x0010 -#define DOT11_CAP_SHORT 0x0020 -#define DOT11_CAP_PBCC 0x0040 -#define DOT11_CAP_AGILITY 0x0080 -#define DOT11_CAP_SPECTRUM 0x0100 -#define DOT11_CAP_SHORTSLOT 0x0400 -#define DOT11_CAP_CCK_OFDM 0x2000 - - -#define DOT11_OBSS_COEX_MNG_SUPPORT 0x01 - - -#define DOT11_ACTION_HDR_LEN 2 -#define DOT11_ACTION_CAT_ERR_MASK 0x80 -#define DOT11_ACTION_CAT_MASK 0x7F -#define DOT11_ACTION_CAT_SPECT_MNG 0 -#define DOT11_ACTION_CAT_BLOCKACK 3 -#define DOT11_ACTION_CAT_PUBLIC 4 -#define DOT11_ACTION_CAT_HT 7 -#define DOT11_ACTION_CAT_VS 127 -#define DOT11_ACTION_NOTIFICATION 0x11 - -#define DOT11_ACTION_ID_M_REQ 0 -#define DOT11_ACTION_ID_M_REP 1 -#define DOT11_ACTION_ID_TPC_REQ 2 -#define DOT11_ACTION_ID_TPC_REP 3 -#define DOT11_ACTION_ID_CHANNEL_SWITCH 4 -#define DOT11_ACTION_ID_EXT_CSA 5 - - -#define DOT11_ACTION_ID_HT_CH_WIDTH 0 -#define DOT11_ACTION_ID_HT_MIMO_PS 1 - - -#define DOT11_PUB_ACTION_BSS_COEX_MNG 0 -#define DOT11_PUB_ACTION_CHANNEL_SWITCH 4 - - -#define DOT11_BA_ACTION_ADDBA_REQ 0 -#define DOT11_BA_ACTION_ADDBA_RESP 1 -#define DOT11_BA_ACTION_DELBA 2 - - -#define DOT11_ADDBA_PARAM_AMSDU_SUP 0x0001 -#define DOT11_ADDBA_PARAM_POLICY_MASK 0x0002 -#define DOT11_ADDBA_PARAM_POLICY_SHIFT 1 -#define DOT11_ADDBA_PARAM_TID_MASK 0x003c -#define DOT11_ADDBA_PARAM_TID_SHIFT 2 -#define DOT11_ADDBA_PARAM_BSIZE_MASK 0xffc0 -#define DOT11_ADDBA_PARAM_BSIZE_SHIFT 6 - -#define DOT11_ADDBA_POLICY_DELAYED 0 -#define DOT11_ADDBA_POLICY_IMMEDIATE 1 - -BWL_PRE_PACKED_STRUCT struct dot11_addba_req { - uint8 category; - uint8 action; - uint8 token; - uint16 addba_param_set; - uint16 timeout; - uint16 start_seqnum; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_addba_req dot11_addba_req_t; -#define DOT11_ADDBA_REQ_LEN 9 - -BWL_PRE_PACKED_STRUCT struct dot11_addba_resp { - uint8 category; - uint8 action; - uint8 token; - uint16 status; - uint16 addba_param_set; - uint16 timeout; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_addba_resp dot11_addba_resp_t; -#define DOT11_ADDBA_RESP_LEN 9 - - -#define DOT11_DELBA_PARAM_INIT_MASK 0x0800 -#define DOT11_DELBA_PARAM_INIT_SHIFT 11 -#define DOT11_DELBA_PARAM_TID_MASK 0xf000 -#define DOT11_DELBA_PARAM_TID_SHIFT 12 - -BWL_PRE_PACKED_STRUCT struct dot11_delba { - uint8 category; - uint8 action; - uint16 delba_param_set; - uint16 reason; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_delba dot11_delba_t; -#define DOT11_DELBA_LEN 6 - - -#define DOT11_BSSTYPE_INFRASTRUCTURE 0 -#define DOT11_BSSTYPE_INDEPENDENT 1 -#define DOT11_BSSTYPE_ANY 2 -#define DOT11_SCANTYPE_ACTIVE 0 -#define DOT11_SCANTYPE_PASSIVE 1 - - -#define PREN_PREAMBLE 24 -#define PREN_MM_EXT 8 -#define PREN_PREAMBLE_EXT 4 - - -#define NPHY_RIFS_TIME 2 - - -#define APHY_SLOT_TIME 9 -#define APHY_SIFS_TIME 16 -#define APHY_DIFS_TIME (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME)) -#define APHY_PREAMBLE_TIME 16 -#define APHY_SIGNAL_TIME 4 -#define APHY_SYMBOL_TIME 4 -#define APHY_SERVICE_NBITS 16 -#define APHY_TAIL_NBITS 6 -#define APHY_CWMIN 15 - - -#define BPHY_SLOT_TIME 20 -#define BPHY_SIFS_TIME 10 -#define BPHY_DIFS_TIME 50 -#define BPHY_PLCP_TIME 192 -#define BPHY_PLCP_SHORT_TIME 96 -#define BPHY_CWMIN 31 - - -#define DOT11_OFDM_SIGNAL_EXTENSION 6 - -#define PHY_CWMAX 1023 - -#define DOT11_MAXNUMFRAGS 16 - - -typedef struct d11cnt { - uint32 txfrag; - uint32 txmulti; - uint32 txfail; - uint32 txretry; - uint32 txretrie; - uint32 rxdup; - uint32 txrts; - uint32 txnocts; - uint32 txnoack; - uint32 rxfrag; - uint32 rxmulti; - uint32 rxcrc; - uint32 txfrmsnt; - uint32 rxundec; -} d11cnt_t; - - -#define BRCM_PROP_OUI "\x00\x90\x4C" - - - - -BWL_PRE_PACKED_STRUCT struct brcm_prop_ie_s { - uint8 id; - uint8 len; - uint8 oui[3]; - uint8 type; - uint16 cap; -} BWL_POST_PACKED_STRUCT; -typedef struct brcm_prop_ie_s brcm_prop_ie_t; - -#define BRCM_PROP_IE_LEN 6 - -#define DPT_IE_TYPE 2 - - -#define BRCM_OUI "\x00\x10\x18" - - -BWL_PRE_PACKED_STRUCT struct brcm_ie { - uint8 id; - uint8 len; - uint8 oui[3]; - uint8 ver; - uint8 assoc; - uint8 flags; - uint8 flags1; - uint16 amsdu_mtu_pref; -} BWL_POST_PACKED_STRUCT; -typedef struct brcm_ie brcm_ie_t; -#define BRCM_IE_LEN 11 -#define BRCM_IE_VER 2 -#define BRCM_IE_LEGACY_AES_VER 1 - - -#ifdef WLAFTERBURNER -#define BRF_ABCAP 0x1 -#define BRF_ABRQRD 0x2 -#define BRF_ABCOUNTER_MASK 0xf0 -#define BRF_ABCOUNTER_SHIFT 4 -#endif -#define BRF_LZWDS 0x4 -#define BRF_BLOCKACK 0x8 - - -#define BRF1_AMSDU 0x1 -#define BRF1_WMEPS 0x4 -#define BRF1_PSOFIX 0x8 - -#ifdef WLAFTERBURNER -#define AB_WDS_TIMEOUT_MAX 15 -#define AB_WDS_TIMEOUT_MIN 1 -#endif - -#define AB_GUARDCOUNT 10 - -#define MCSSET_LEN 16 -#define MAX_MCS_NUM (128) - -BWL_PRE_PACKED_STRUCT struct ht_cap_ie { - uint16 cap; - uint8 params; - uint8 supp_mcs[MCSSET_LEN]; - uint16 ext_htcap; - uint32 txbf_cap; - uint8 as_cap; -} BWL_POST_PACKED_STRUCT; -typedef struct ht_cap_ie ht_cap_ie_t; - - - -BWL_PRE_PACKED_STRUCT struct ht_prop_cap_ie { - uint8 id; - uint8 len; - uint8 oui[3]; - uint8 type; - ht_cap_ie_t cap_ie; -} BWL_POST_PACKED_STRUCT; -typedef struct ht_prop_cap_ie ht_prop_cap_ie_t; -#define HT_PROP_IE_OVERHEAD 4 -#define HT_CAP_IE_LEN 26 -#define HT_CAP_IE_TYPE 51 - -#define HT_CAP_LDPC_CODING 0x0001 -#define HT_CAP_40MHZ 0x0002 -#define HT_CAP_MIMO_PS_MASK 0x000C -#define HT_CAP_MIMO_PS_SHIFT 0x0002 -#define HT_CAP_MIMO_PS_OFF 0x0003 -#define HT_CAP_MIMO_PS_RTS 0x0001 -#define HT_CAP_MIMO_PS_ON 0x0000 -#define HT_CAP_GF 0x0010 -#define HT_CAP_SHORT_GI_20 0x0020 -#define HT_CAP_SHORT_GI_40 0x0040 -#define HT_CAP_TX_STBC 0x0080 -#define HT_CAP_RX_STBC_MASK 0x0300 -#define HT_CAP_RX_STBC_SHIFT 8 -#define HT_CAP_DELAYED_BA 0x0400 -#define HT_CAP_MAX_AMSDU 0x0800 -#define HT_CAP_DSSS_CCK 0x1000 -#define HT_CAP_PSMP 0x2000 -#define HT_CAP_40MHZ_INTOLERANT 0x4000 -#define HT_CAP_LSIG_TXOP 0x8000 - -#define HT_CAP_RX_STBC_NO 0x0 -#define HT_CAP_RX_STBC_ONE_STREAM 0x1 -#define HT_CAP_RX_STBC_TWO_STREAM 0x2 -#define HT_CAP_RX_STBC_THREE_STREAM 0x3 - -#define HT_MAX_AMSDU 7935 -#define HT_MIN_AMSDU 3835 - -#define HT_PARAMS_RX_FACTOR_MASK 0x03 -#define HT_PARAMS_DENSITY_MASK 0x1C -#define HT_PARAMS_DENSITY_SHIFT 2 - - -#define AMPDU_MAX_MPDU_DENSITY 7 -#define AMPDU_RX_FACTOR_64K 3 -#define AMPDU_RX_FACTOR_BASE 8*1024 -#define AMPDU_DELIMITER_LEN 4 - -#define HT_CAP_EXT_PCO 0x0001 -#define HT_CAP_EXT_PCO_TTIME_MASK 0x0006 -#define HT_CAP_EXT_PCO_TTIME_SHIFT 1 -#define HT_CAP_EXT_MCS_FEEDBACK_MASK 0x0300 -#define HT_CAP_EXT_MCS_FEEDBACK_SHIFT 8 -#define HT_CAP_EXT_HTC 0x0400 -#define HT_CAP_EXT_RD_RESP 0x0800 - -BWL_PRE_PACKED_STRUCT struct ht_add_ie { - uint8 ctl_ch; - uint8 byte1; - uint16 opmode; - uint16 misc_bits; - uint8 basic_mcs[MCSSET_LEN]; -} BWL_POST_PACKED_STRUCT; -typedef struct ht_add_ie ht_add_ie_t; - - - -BWL_PRE_PACKED_STRUCT struct ht_prop_add_ie { - uint8 id; - uint8 len; - uint8 oui[3]; - uint8 type; - ht_add_ie_t add_ie; -} BWL_POST_PACKED_STRUCT; -typedef struct ht_prop_add_ie ht_prop_add_ie_t; - -#define HT_ADD_IE_LEN 22 -#define HT_ADD_IE_TYPE 52 - - -#define HT_BW_ANY 0x04 -#define HT_RIFS_PERMITTED 0x08 - - -#define HT_OPMODE_MASK 0x0003 -#define HT_OPMODE_SHIFT 0 -#define HT_OPMODE_PURE 0x0000 -#define HT_OPMODE_OPTIONAL 0x0001 -#define HT_OPMODE_HT20IN40 0x0002 -#define HT_OPMODE_MIXED 0x0003 -#define HT_OPMODE_NONGF 0x0004 -#define DOT11N_TXBURST 0x0008 -#define DOT11N_OBSS_NONHT 0x0010 - - -#define HT_BASIC_STBC_MCS 0x007f -#define HT_DUAL_STBC_PROT 0x0080 -#define HT_SECOND_BCN 0x0100 -#define HT_LSIG_TXOP 0x0200 -#define HT_PCO_ACTIVE 0x0400 -#define HT_PCO_PHASE 0x0800 -#define HT_DUALCTS_PROTECTION 0x0080 - - -#define DOT11N_2G_TXBURST_LIMIT 6160 -#define DOT11N_5G_TXBURST_LIMIT 3080 - - -#define GET_HT_OPMODE(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ - >> HT_OPMODE_SHIFT) -#define HT_MIXEDMODE_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ - == HT_OPMODE_MIXED) -#define HT_HT20_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ - == HT_OPMODE_HT20IN40) -#define HT_OPTIONAL_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ - == HT_OPMODE_OPTIONAL) -#define HT_USE_PROTECTION(add_ie) (HT_HT20_PRESENT((add_ie)) || \ - HT_MIXEDMODE_PRESENT((add_ie))) -#define HT_NONGF_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_NONGF) \ - == HT_OPMODE_NONGF) -#define DOT11N_TXBURST_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_TXBURST) \ - == DOT11N_TXBURST) -#define DOT11N_OBSS_NONHT_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_OBSS_NONHT) \ - == DOT11N_OBSS_NONHT) - -BWL_PRE_PACKED_STRUCT struct obss_params { - uint16 passive_dwell; - uint16 active_dwell; - uint16 bss_widthscan_interval; - uint16 passive_total; - uint16 active_total; - uint16 chanwidth_transition_dly; - uint16 activity_threshold; -} BWL_POST_PACKED_STRUCT; -typedef struct obss_params obss_params_t; - -BWL_PRE_PACKED_STRUCT struct dot11_obss_ie { - uint8 id; - uint8 len; - obss_params_t obss_params; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_obss_ie dot11_obss_ie_t; -#define DOT11_OBSS_SCAN_IE_LEN sizeof(obss_params_t) - - -BWL_PRE_PACKED_STRUCT struct vndr_ie { - uchar id; - uchar len; - uchar oui [3]; - uchar data [1]; -} BWL_POST_PACKED_STRUCT; -typedef struct vndr_ie vndr_ie_t; - -#define VNDR_IE_HDR_LEN 2 -#define VNDR_IE_MIN_LEN 3 -#define VNDR_IE_MAX_LEN 256 - - -#define WPA_VERSION 1 -#define WPA_OUI "\x00\x50\xF2" - -#define WPA2_VERSION 1 -#define WPA2_VERSION_LEN 2 -#define WPA2_OUI "\x00\x0F\xAC" - -#define WPA_OUI_LEN 3 - - -#define RSN_AKM_NONE 0 -#define RSN_AKM_UNSPECIFIED 1 -#define RSN_AKM_PSK 2 - - -#define DOT11_MAX_DEFAULT_KEYS 4 -#define DOT11_MAX_KEY_SIZE 32 -#define DOT11_MAX_IV_SIZE 16 -#define DOT11_EXT_IV_FLAG (1<<5) -#define DOT11_WPA_KEY_RSC_LEN 8 - -#define WEP1_KEY_SIZE 5 -#define WEP1_KEY_HEX_SIZE 10 -#define WEP128_KEY_SIZE 13 -#define WEP128_KEY_HEX_SIZE 26 -#define TKIP_MIC_SIZE 8 -#define TKIP_EOM_SIZE 7 -#define TKIP_EOM_FLAG 0x5a -#define TKIP_KEY_SIZE 32 -#define TKIP_MIC_AUTH_TX 16 -#define TKIP_MIC_AUTH_RX 24 -#define TKIP_MIC_SUP_RX TKIP_MIC_AUTH_TX -#define TKIP_MIC_SUP_TX TKIP_MIC_AUTH_RX -#define AES_KEY_SIZE 16 -#define AES_MIC_SIZE 8 - -#define SMS4_KEY_LEN 16 -#define SMS4_WPI_CBC_MAC_LEN 16 - - -#include - - -#endif diff --git a/drivers/net/wireless/bcm4329/include/proto/802.11e.h b/drivers/net/wireless/bcm4329/include/proto/802.11e.h deleted file mode 100644 index 1dd6f45b1ed8..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/802.11e.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 802.11e protocol header file - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: 802.11e.h,v 1.5.56.1 2008/11/20 00:51:18 Exp $ - */ - -#ifndef _802_11e_H_ -#define _802_11e_H_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - -/* This marks the start of a packed structure section. */ -#include - - -/* WME Traffic Specification (TSPEC) element */ -#define WME_TSPEC_HDR_LEN 2 /* WME TSPEC header length */ -#define WME_TSPEC_BODY_OFF 2 /* WME TSPEC body offset */ - -#define WME_CATEGORY_CODE_OFFSET 0 /* WME Category code offset */ -#define WME_ACTION_CODE_OFFSET 1 /* WME Action code offset */ -#define WME_TOKEN_CODE_OFFSET 2 /* WME Token code offset */ -#define WME_STATUS_CODE_OFFSET 3 /* WME Status code offset */ - -BWL_PRE_PACKED_STRUCT struct tsinfo { - uint8 octets[3]; -} BWL_POST_PACKED_STRUCT; - -typedef struct tsinfo tsinfo_t; - -/* 802.11e TSPEC IE */ -typedef BWL_PRE_PACKED_STRUCT struct tspec { - uint8 oui[DOT11_OUI_LEN]; /* WME_OUI */ - uint8 type; /* WME_TYPE */ - uint8 subtype; /* WME_SUBTYPE_TSPEC */ - uint8 version; /* WME_VERSION */ - tsinfo_t tsinfo; /* TS Info bit field */ - uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */ - uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */ - uint32 min_srv_interval; /* Minimum Service Interval (us) */ - uint32 max_srv_interval; /* Maximum Service Interval (us) */ - uint32 inactivity_interval; /* Inactivity Interval (us) */ - uint32 suspension_interval; /* Suspension Interval (us) */ - uint32 srv_start_time; /* Service Start Time (us) */ - uint32 min_data_rate; /* Minimum Data Rate (bps) */ - uint32 mean_data_rate; /* Mean Data Rate (bps) */ - uint32 peak_data_rate; /* Peak Data Rate (bps) */ - uint32 max_burst_size; /* Maximum Burst Size (bytes) */ - uint32 delay_bound; /* Delay Bound (us) */ - uint32 min_phy_rate; /* Minimum PHY Rate (bps) */ - uint16 surplus_bw; /* Surplus Bandwidth Allowance (range 1.0-8.0) */ - uint16 medium_time; /* Medium Time (32 us/s periods) */ -} BWL_POST_PACKED_STRUCT tspec_t; - -#define WME_TSPEC_LEN (sizeof(tspec_t)) /* not including 2-bytes of header */ - -/* ts_info */ -/* 802.1D priority is duplicated - bits 13-11 AND bits 3-1 */ -#define TS_INFO_TID_SHIFT 1 /* TS info. TID shift */ -#define TS_INFO_TID_MASK (0xf << TS_INFO_TID_SHIFT) /* TS info. TID mask */ -#define TS_INFO_CONTENTION_SHIFT 7 /* TS info. contention shift */ -#define TS_INFO_CONTENTION_MASK (0x1 << TS_INFO_CONTENTION_SHIFT) /* TS info. contention mask */ -#define TS_INFO_DIRECTION_SHIFT 5 /* TS info. direction shift */ -#define TS_INFO_DIRECTION_MASK (0x3 << TS_INFO_DIRECTION_SHIFT) /* TS info. direction mask */ -#define TS_INFO_PSB_SHIFT 2 /* TS info. PSB bit Shift */ -#define TS_INFO_PSB_MASK (1 << TS_INFO_PSB_SHIFT) /* TS info. PSB mask */ -#define TS_INFO_UPLINK (0 << TS_INFO_DIRECTION_SHIFT) /* TS info. uplink */ -#define TS_INFO_DOWNLINK (1 << TS_INFO_DIRECTION_SHIFT) /* TS info. downlink */ -#define TS_INFO_BIDIRECTIONAL (3 << TS_INFO_DIRECTION_SHIFT) /* TS info. bidirectional */ -#define TS_INFO_USER_PRIO_SHIFT 3 /* TS info. user priority shift */ -/* TS info. user priority mask */ -#define TS_INFO_USER_PRIO_MASK (0x7 << TS_INFO_USER_PRIO_SHIFT) - -/* Macro to get/set bit(s) field in TSINFO */ -#define WLC_CAC_GET_TID(pt) ((((pt).octets[0]) & TS_INFO_TID_MASK) >> TS_INFO_TID_SHIFT) -#define WLC_CAC_GET_DIR(pt) ((((pt).octets[0]) & \ - TS_INFO_DIRECTION_MASK) >> TS_INFO_DIRECTION_SHIFT) -#define WLC_CAC_GET_PSB(pt) ((((pt).octets[1]) & TS_INFO_PSB_MASK) >> TS_INFO_PSB_SHIFT) -#define WLC_CAC_GET_USER_PRIO(pt) ((((pt).octets[1]) & \ - TS_INFO_USER_PRIO_MASK) >> TS_INFO_USER_PRIO_SHIFT) - -#define WLC_CAC_SET_TID(pt, id) ((((pt).octets[0]) & (~TS_INFO_TID_MASK)) | \ - ((id) << TS_INFO_TID_SHIFT)) -#define WLC_CAC_SET_USER_PRIO(pt, prio) ((((pt).octets[0]) & (~TS_INFO_USER_PRIO_MASK)) | \ - ((prio) << TS_INFO_USER_PRIO_SHIFT)) - -/* 802.11e QBSS Load IE */ -#define QBSS_LOAD_IE_LEN 5 /* QBSS Load IE length */ -#define QBSS_LOAD_AAC_OFF 3 /* AAC offset in IE */ - -#define CAC_ADDTS_RESP_TIMEOUT 300 /* default ADDTS response timeout in ms */ - -/* 802.11e ADDTS status code */ -#define DOT11E_STATUS_ADMISSION_ACCEPTED 0 /* TSPEC Admission accepted status */ -#define DOT11E_STATUS_ADDTS_INVALID_PARAM 1 /* TSPEC invalid parameter status */ -#define DOT11E_STATUS_ADDTS_REFUSED_NSBW 3 /* ADDTS refused (non-sufficient BW) */ -#define DOT11E_STATUS_ADDTS_REFUSED_AWHILE 47 /* ADDTS refused but could retry later */ - -/* 802.11e DELTS status code */ -#define DOT11E_STATUS_QSTA_LEAVE_QBSS 36 /* STA leave QBSS */ -#define DOT11E_STATUS_END_TS 37 /* END TS */ -#define DOT11E_STATUS_UNKNOWN_TS 38 /* UNKNOWN TS */ -#define DOT11E_STATUS_QSTA_REQ_TIMEOUT 39 /* STA ADDTS request timeout */ - - -/* This marks the end of a packed structure section. */ -#include - -#endif /* _802_11e_CAC_H_ */ diff --git a/drivers/net/wireless/bcm4329/include/proto/802.1d.h b/drivers/net/wireless/bcm4329/include/proto/802.1d.h deleted file mode 100644 index 45c728bc2976..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/802.1d.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * Fundamental types and constants relating to 802.1D - * - * $Id: 802.1d.h,v 9.3 2007/04/10 21:33:06 Exp $ - */ - - -#ifndef _802_1_D_ -#define _802_1_D_ - - -#define PRIO_8021D_NONE 2 -#define PRIO_8021D_BK 1 -#define PRIO_8021D_BE 0 -#define PRIO_8021D_EE 3 -#define PRIO_8021D_CL 4 -#define PRIO_8021D_VI 5 -#define PRIO_8021D_VO 6 -#define PRIO_8021D_NC 7 -#define MAXPRIO 7 -#define NUMPRIO (MAXPRIO + 1) - -#define ALLPRIO -1 - - -#define PRIO2PREC(prio) \ - (((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? ((prio^2)) : (prio)) - -#endif diff --git a/drivers/net/wireless/bcm4329/include/proto/bcmeth.h b/drivers/net/wireless/bcm4329/include/proto/bcmeth.h deleted file mode 100644 index fdb5a2a5648f..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/bcmeth.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Broadcom Ethernettype protocol definitions - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmeth.h,v 9.9.46.1 2008/11/20 00:51:20 Exp $ - */ - - - - -#ifndef _BCMETH_H_ -#define _BCMETH_H_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - - -#include - - - - - - - -#define BCMILCP_SUBTYPE_RATE 1 -#define BCMILCP_SUBTYPE_LINK 2 -#define BCMILCP_SUBTYPE_CSA 3 -#define BCMILCP_SUBTYPE_LARQ 4 -#define BCMILCP_SUBTYPE_VENDOR 5 -#define BCMILCP_SUBTYPE_FLH 17 - -#define BCMILCP_SUBTYPE_VENDOR_LONG 32769 -#define BCMILCP_SUBTYPE_CERT 32770 -#define BCMILCP_SUBTYPE_SES 32771 - - -#define BCMILCP_BCM_SUBTYPE_RESERVED 0 -#define BCMILCP_BCM_SUBTYPE_EVENT 1 -#define BCMILCP_BCM_SUBTYPE_SES 2 - - -#define BCMILCP_BCM_SUBTYPE_DPT 4 - -#define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH 8 -#define BCMILCP_BCM_SUBTYPEHDR_VERSION 0 - - -typedef BWL_PRE_PACKED_STRUCT struct bcmeth_hdr -{ - uint16 subtype; - uint16 length; - uint8 version; - uint8 oui[3]; - - uint16 usr_subtype; -} BWL_POST_PACKED_STRUCT bcmeth_hdr_t; - - - -#include - -#endif diff --git a/drivers/net/wireless/bcm4329/include/proto/bcmevent.h b/drivers/net/wireless/bcm4329/include/proto/bcmevent.h deleted file mode 100644 index 1f8ecb14d97a..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/bcmevent.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Broadcom Event protocol definitions - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * - * Dependencies: proto/bcmeth.h - * - * $Id: bcmevent.h,v 9.34.4.1.20.16.64.1 2010/11/08 21:57:03 Exp $ - * - */ - - - - -#ifndef _BCMEVENT_H_ -#define _BCMEVENT_H_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - - -#include - -#define BCM_EVENT_MSG_VERSION 1 -#define BCM_MSG_IFNAME_MAX 16 - - -#define WLC_EVENT_MSG_LINK 0x01 -#define WLC_EVENT_MSG_FLUSHTXQ 0x02 -#define WLC_EVENT_MSG_GROUP 0x04 - - -typedef BWL_PRE_PACKED_STRUCT struct -{ - uint16 version; - uint16 flags; - uint32 event_type; - uint32 status; - uint32 reason; - uint32 auth_type; - uint32 datalen; - struct ether_addr addr; - char ifname[BCM_MSG_IFNAME_MAX]; -} BWL_POST_PACKED_STRUCT wl_event_msg_t; - - -typedef BWL_PRE_PACKED_STRUCT struct bcm_event { - struct ether_header eth; - bcmeth_hdr_t bcm_hdr; - wl_event_msg_t event; - -} BWL_POST_PACKED_STRUCT bcm_event_t; - -#define BCM_MSG_LEN (sizeof(bcm_event_t) - sizeof(bcmeth_hdr_t) - sizeof(struct ether_header)) - - -#define WLC_E_SET_SSID 0 -#define WLC_E_JOIN 1 -#define WLC_E_START 2 -#define WLC_E_AUTH 3 -#define WLC_E_AUTH_IND 4 -#define WLC_E_DEAUTH 5 -#define WLC_E_DEAUTH_IND 6 -#define WLC_E_ASSOC 7 -#define WLC_E_ASSOC_IND 8 -#define WLC_E_REASSOC 9 -#define WLC_E_REASSOC_IND 10 -#define WLC_E_DISASSOC 11 -#define WLC_E_DISASSOC_IND 12 -#define WLC_E_QUIET_START 13 -#define WLC_E_QUIET_END 14 -#define WLC_E_BEACON_RX 15 -#define WLC_E_LINK 16 -#define WLC_E_MIC_ERROR 17 -#define WLC_E_NDIS_LINK 18 -#define WLC_E_ROAM 19 -#define WLC_E_TXFAIL 20 -#define WLC_E_PMKID_CACHE 21 -#define WLC_E_RETROGRADE_TSF 22 -#define WLC_E_PRUNE 23 -#define WLC_E_AUTOAUTH 24 -#define WLC_E_EAPOL_MSG 25 -#define WLC_E_SCAN_COMPLETE 26 -#define WLC_E_ADDTS_IND 27 -#define WLC_E_DELTS_IND 28 -#define WLC_E_BCNSENT_IND 29 -#define WLC_E_BCNRX_MSG 30 -#define WLC_E_BCNLOST_MSG 31 -#define WLC_E_ROAM_PREP 32 -#define WLC_E_PFN_NET_FOUND 33 -#define WLC_E_PFN_NET_LOST 34 -#define WLC_E_RESET_COMPLETE 35 -#define WLC_E_JOIN_START 36 -#define WLC_E_ROAM_START 37 -#define WLC_E_ASSOC_START 38 -#define WLC_E_IBSS_ASSOC 39 -#define WLC_E_RADIO 40 -#define WLC_E_PSM_WATCHDOG 41 -#define WLC_E_PROBREQ_MSG 44 -#define WLC_E_SCAN_CONFIRM_IND 45 -#define WLC_E_PSK_SUP 46 -#define WLC_E_COUNTRY_CODE_CHANGED 47 -#define WLC_E_EXCEEDED_MEDIUM_TIME 48 -#define WLC_E_ICV_ERROR 49 -#define WLC_E_UNICAST_DECODE_ERROR 50 -#define WLC_E_MULTICAST_DECODE_ERROR 51 -#define WLC_E_TRACE 52 -#define WLC_E_IF 54 -#define WLC_E_RSSI 56 -#define WLC_E_PFN_SCAN_COMPLETE 57 -#define WLC_E_ACTION_FRAME 58 -#define WLC_E_ACTION_FRAME_COMPLETE 59 - -#define WLC_E_ESCAN_RESULT 69 -#define WLC_E_WAKE_EVENT 70 -#define WLC_E_RELOAD 71 -#define WLC_E_LAST 72 - - - -#define WLC_E_STATUS_SUCCESS 0 -#define WLC_E_STATUS_FAIL 1 -#define WLC_E_STATUS_TIMEOUT 2 -#define WLC_E_STATUS_NO_NETWORKS 3 -#define WLC_E_STATUS_ABORT 4 -#define WLC_E_STATUS_NO_ACK 5 -#define WLC_E_STATUS_UNSOLICITED 6 -#define WLC_E_STATUS_ATTEMPT 7 -#define WLC_E_STATUS_PARTIAL 8 -#define WLC_E_STATUS_NEWSCAN 9 -#define WLC_E_STATUS_NEWASSOC 10 -#define WLC_E_STATUS_11HQUIET 11 -#define WLC_E_STATUS_SUPPRESS 12 -#define WLC_E_STATUS_NOCHANS 13 -#define WLC_E_STATUS_CCXFASTRM 14 -#define WLC_E_STATUS_CS_ABORT 15 - - -#define WLC_E_REASON_INITIAL_ASSOC 0 -#define WLC_E_REASON_LOW_RSSI 1 -#define WLC_E_REASON_DEAUTH 2 -#define WLC_E_REASON_DISASSOC 3 -#define WLC_E_REASON_BCNS_LOST 4 -#define WLC_E_REASON_FAST_ROAM_FAILED 5 -#define WLC_E_REASON_DIRECTED_ROAM 6 -#define WLC_E_REASON_TSPEC_REJECTED 7 -#define WLC_E_REASON_BETTER_AP 8 - - -#define WLC_E_PRUNE_ENCR_MISMATCH 1 -#define WLC_E_PRUNE_BCAST_BSSID 2 -#define WLC_E_PRUNE_MAC_DENY 3 -#define WLC_E_PRUNE_MAC_NA 4 -#define WLC_E_PRUNE_REG_PASSV 5 -#define WLC_E_PRUNE_SPCT_MGMT 6 -#define WLC_E_PRUNE_RADAR 7 -#define WLC_E_RSN_MISMATCH 8 -#define WLC_E_PRUNE_NO_COMMON_RATES 9 -#define WLC_E_PRUNE_BASIC_RATES 10 -#define WLC_E_PRUNE_CIPHER_NA 12 -#define WLC_E_PRUNE_KNOWN_STA 13 -#define WLC_E_PRUNE_WDS_PEER 15 -#define WLC_E_PRUNE_QBSS_LOAD 16 -#define WLC_E_PRUNE_HOME_AP 17 - - -#define WLC_E_SUP_OTHER 0 -#define WLC_E_SUP_DECRYPT_KEY_DATA 1 -#define WLC_E_SUP_BAD_UCAST_WEP128 2 -#define WLC_E_SUP_BAD_UCAST_WEP40 3 -#define WLC_E_SUP_UNSUP_KEY_LEN 4 -#define WLC_E_SUP_PW_KEY_CIPHER 5 -#define WLC_E_SUP_MSG3_TOO_MANY_IE 6 -#define WLC_E_SUP_MSG3_IE_MISMATCH 7 -#define WLC_E_SUP_NO_INSTALL_FLAG 8 -#define WLC_E_SUP_MSG3_NO_GTK 9 -#define WLC_E_SUP_GRP_KEY_CIPHER 10 -#define WLC_E_SUP_GRP_MSG1_NO_GTK 11 -#define WLC_E_SUP_GTK_DECRYPT_FAIL 12 -#define WLC_E_SUP_SEND_FAIL 13 -#define WLC_E_SUP_DEAUTH 14 -#define WLC_E_SUP_WPA_PSK_TMO 15 - - -#define WLC_E_IF_ADD 1 -#define WLC_E_IF_DEL 2 - -#define WLC_E_RELOAD_STATUS1 1 - -#include - -#endif diff --git a/drivers/net/wireless/bcm4329/include/proto/bcmip.h b/drivers/net/wireless/bcm4329/include/proto/bcmip.h deleted file mode 100644 index 9d2fd6fba484..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/bcmip.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * Fundamental constants relating to IP Protocol - * - * $Id: bcmip.h,v 9.16.186.4 2009/01/27 04:25:25 Exp $ - */ - - -#ifndef _bcmip_h_ -#define _bcmip_h_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - - -#include - - - -#define IP_VER_OFFSET 0x0 -#define IP_VER_MASK 0xf0 -#define IP_VER_SHIFT 4 -#define IP_VER_4 4 -#define IP_VER_6 6 - -#define IP_VER(ip_body) \ - ((((uint8 *)(ip_body))[IP_VER_OFFSET] & IP_VER_MASK) >> IP_VER_SHIFT) - -#define IP_PROT_ICMP 0x1 -#define IP_PROT_TCP 0x6 -#define IP_PROT_UDP 0x11 - - -#define IPV4_VER_HL_OFFSET 0 -#define IPV4_TOS_OFFSET 1 -#define IPV4_PKTLEN_OFFSET 2 -#define IPV4_PKTFLAG_OFFSET 6 -#define IPV4_PROT_OFFSET 9 -#define IPV4_CHKSUM_OFFSET 10 -#define IPV4_SRC_IP_OFFSET 12 -#define IPV4_DEST_IP_OFFSET 16 -#define IPV4_OPTIONS_OFFSET 20 - - -#define IPV4_VER_MASK 0xf0 -#define IPV4_VER_SHIFT 4 - -#define IPV4_HLEN_MASK 0x0f -#define IPV4_HLEN(ipv4_body) (4 * (((uint8 *)(ipv4_body))[IPV4_VER_HL_OFFSET] & IPV4_HLEN_MASK)) - -#define IPV4_ADDR_LEN 4 - -#define IPV4_ADDR_NULL(a) ((((uint8 *)(a))[0] | ((uint8 *)(a))[1] | \ - ((uint8 *)(a))[2] | ((uint8 *)(a))[3]) == 0) - -#define IPV4_ADDR_BCAST(a) ((((uint8 *)(a))[0] & ((uint8 *)(a))[1] & \ - ((uint8 *)(a))[2] & ((uint8 *)(a))[3]) == 0xff) - -#define IPV4_TOS_DSCP_MASK 0xfc -#define IPV4_TOS_DSCP_SHIFT 2 - -#define IPV4_TOS(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_TOS_OFFSET]) - -#define IPV4_TOS_PREC_MASK 0xe0 -#define IPV4_TOS_PREC_SHIFT 5 - -#define IPV4_TOS_LOWDELAY 0x10 -#define IPV4_TOS_THROUGHPUT 0x8 -#define IPV4_TOS_RELIABILITY 0x4 - -#define IPV4_PROT(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_PROT_OFFSET]) - -#define IPV4_FRAG_RESV 0x8000 -#define IPV4_FRAG_DONT 0x4000 -#define IPV4_FRAG_MORE 0x2000 -#define IPV4_FRAG_OFFSET_MASK 0x1fff - -#define IPV4_ADDR_STR_LEN 16 - - -BWL_PRE_PACKED_STRUCT struct ipv4_addr { - uint8 addr[IPV4_ADDR_LEN]; -} BWL_POST_PACKED_STRUCT; - -BWL_PRE_PACKED_STRUCT struct ipv4_hdr { - uint8 version_ihl; - uint8 tos; - uint16 tot_len; - uint16 id; - uint16 frag; - uint8 ttl; - uint8 prot; - uint16 hdr_chksum; - uint8 src_ip[IPV4_ADDR_LEN]; - uint8 dst_ip[IPV4_ADDR_LEN]; -} BWL_POST_PACKED_STRUCT; - - -#define IPV6_PAYLOAD_LEN_OFFSET 4 -#define IPV6_NEXT_HDR_OFFSET 6 -#define IPV6_HOP_LIMIT_OFFSET 7 -#define IPV6_SRC_IP_OFFSET 8 -#define IPV6_DEST_IP_OFFSET 24 - - -#define IPV6_TRAFFIC_CLASS(ipv6_body) \ - (((((uint8 *)(ipv6_body))[0] & 0x0f) << 4) | \ - ((((uint8 *)(ipv6_body))[1] & 0xf0) >> 4)) - -#define IPV6_FLOW_LABEL(ipv6_body) \ - (((((uint8 *)(ipv6_body))[1] & 0x0f) << 16) | \ - (((uint8 *)(ipv6_body))[2] << 8) | \ - (((uint8 *)(ipv6_body))[3])) - -#define IPV6_PAYLOAD_LEN(ipv6_body) \ - ((((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 0] << 8) | \ - ((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 1]) - -#define IPV6_NEXT_HDR(ipv6_body) \ - (((uint8 *)(ipv6_body))[IPV6_NEXT_HDR_OFFSET]) - -#define IPV6_PROT(ipv6_body) IPV6_NEXT_HDR(ipv6_body) - -#define IPV6_ADDR_LEN 16 - - -#ifndef IP_TOS -#define IP_TOS(ip_body) \ - (IP_VER(ip_body) == IP_VER_4 ? IPV4_TOS(ip_body) : \ - IP_VER(ip_body) == IP_VER_6 ? IPV6_TRAFFIC_CLASS(ip_body) : 0) -#endif - - - -#include - -#endif diff --git a/drivers/net/wireless/bcm4329/include/proto/eapol.h b/drivers/net/wireless/bcm4329/include/proto/eapol.h deleted file mode 100644 index 95e76ff18c6b..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/eapol.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 802.1x EAPOL definitions - * - * See - * IEEE Std 802.1X-2001 - * IEEE 802.1X RADIUS Usage Guidelines - * - * Copyright (C) 2002 Broadcom Corporation - * - * $Id: eapol.h,v 9.18.260.1.2.1.6.6 2009/04/08 05:00:08 Exp $ - */ - -#ifndef _eapol_h_ -#define _eapol_h_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - -/* This marks the start of a packed structure section. */ -#include - -#define AKW_BLOCK_LEN 8 /* The only def we need here */ - -/* EAPOL for 802.3/Ethernet */ -typedef struct { - struct ether_header eth; /* 802.3/Ethernet header */ - unsigned char version; /* EAPOL protocol version */ - unsigned char type; /* EAPOL type */ - unsigned short length; /* Length of body */ - unsigned char body[1]; /* Body (optional) */ -} eapol_header_t; - -#define EAPOL_HEADER_LEN 18 - -/* EAPOL version */ -#define WPA2_EAPOL_VERSION 2 -#define WPA_EAPOL_VERSION 1 -#define LEAP_EAPOL_VERSION 1 -#define SES_EAPOL_VERSION 1 - -/* EAPOL types */ -#define EAP_PACKET 0 -#define EAPOL_START 1 -#define EAPOL_LOGOFF 2 -#define EAPOL_KEY 3 -#define EAPOL_ASF 4 - -/* EAPOL-Key types */ -#define EAPOL_RC4_KEY 1 -#define EAPOL_WPA2_KEY 2 /* 802.11i/WPA2 */ -#define EAPOL_WPA_KEY 254 /* WPA */ - -/* RC4 EAPOL-Key header field sizes */ -#define EAPOL_KEY_REPLAY_LEN 8 -#define EAPOL_KEY_IV_LEN 16 -#define EAPOL_KEY_SIG_LEN 16 - -/* RC4 EAPOL-Key */ -typedef BWL_PRE_PACKED_STRUCT struct { - unsigned char type; /* Key Descriptor Type */ - unsigned short length; /* Key Length (unaligned) */ - unsigned char replay[EAPOL_KEY_REPLAY_LEN]; /* Replay Counter */ - unsigned char iv[EAPOL_KEY_IV_LEN]; /* Key IV */ - unsigned char index; /* Key Flags & Index */ - unsigned char signature[EAPOL_KEY_SIG_LEN]; /* Key Signature */ - unsigned char key[1]; /* Key (optional) */ -} BWL_POST_PACKED_STRUCT eapol_key_header_t; - -#define EAPOL_KEY_HEADER_LEN 44 - -/* RC4 EAPOL-Key flags */ -#define EAPOL_KEY_FLAGS_MASK 0x80 -#define EAPOL_KEY_BROADCAST 0 -#define EAPOL_KEY_UNICAST 0x80 - -/* RC4 EAPOL-Key index */ -#define EAPOL_KEY_INDEX_MASK 0x7f - -/* WPA/802.11i/WPA2 EAPOL-Key header field sizes */ -#define EAPOL_WPA_KEY_REPLAY_LEN 8 -#define EAPOL_WPA_KEY_NONCE_LEN 32 -#define EAPOL_WPA_KEY_IV_LEN 16 -#define EAPOL_WPA_KEY_ID_LEN 8 -#define EAPOL_WPA_KEY_RSC_LEN 8 -#define EAPOL_WPA_KEY_MIC_LEN 16 -#define EAPOL_WPA_KEY_DATA_LEN (EAPOL_WPA_MAX_KEY_SIZE + AKW_BLOCK_LEN) -#define EAPOL_WPA_MAX_KEY_SIZE 32 - -/* WPA EAPOL-Key */ -typedef BWL_PRE_PACKED_STRUCT struct { - unsigned char type; /* Key Descriptor Type */ - unsigned short key_info; /* Key Information (unaligned) */ - unsigned short key_len; /* Key Length (unaligned) */ - unsigned char replay[EAPOL_WPA_KEY_REPLAY_LEN]; /* Replay Counter */ - unsigned char nonce[EAPOL_WPA_KEY_NONCE_LEN]; /* Nonce */ - unsigned char iv[EAPOL_WPA_KEY_IV_LEN]; /* Key IV */ - unsigned char rsc[EAPOL_WPA_KEY_RSC_LEN]; /* Key RSC */ - unsigned char id[EAPOL_WPA_KEY_ID_LEN]; /* WPA:Key ID, 802.11i/WPA2: Reserved */ - unsigned char mic[EAPOL_WPA_KEY_MIC_LEN]; /* Key MIC */ - unsigned short data_len; /* Key Data Length */ - unsigned char data[EAPOL_WPA_KEY_DATA_LEN]; /* Key data */ -} BWL_POST_PACKED_STRUCT eapol_wpa_key_header_t; - -#define EAPOL_WPA_KEY_LEN 95 - -/* WPA/802.11i/WPA2 KEY KEY_INFO bits */ -#define WPA_KEY_DESC_V1 0x01 -#define WPA_KEY_DESC_V2 0x02 -#define WPA_KEY_PAIRWISE 0x08 -#define WPA_KEY_INSTALL 0x40 -#define WPA_KEY_ACK 0x80 -#define WPA_KEY_MIC 0x100 -#define WPA_KEY_SECURE 0x200 -#define WPA_KEY_ERROR 0x400 -#define WPA_KEY_REQ 0x800 - -/* WPA-only KEY KEY_INFO bits */ -#define WPA_KEY_INDEX_0 0x00 -#define WPA_KEY_INDEX_1 0x10 -#define WPA_KEY_INDEX_2 0x20 -#define WPA_KEY_INDEX_3 0x30 -#define WPA_KEY_INDEX_MASK 0x30 -#define WPA_KEY_INDEX_SHIFT 0x04 - -/* 802.11i/WPA2-only KEY KEY_INFO bits */ -#define WPA_KEY_ENCRYPTED_DATA 0x1000 - -/* Key Data encapsulation */ -typedef BWL_PRE_PACKED_STRUCT struct { - uint8 type; - uint8 length; - uint8 oui[3]; - uint8 subtype; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT eapol_wpa2_encap_data_t; - -#define EAPOL_WPA2_ENCAP_DATA_HDR_LEN 6 - -#define WPA2_KEY_DATA_SUBTYPE_GTK 1 -#define WPA2_KEY_DATA_SUBTYPE_STAKEY 2 -#define WPA2_KEY_DATA_SUBTYPE_MAC 3 -#define WPA2_KEY_DATA_SUBTYPE_PMKID 4 - -/* GTK encapsulation */ -typedef BWL_PRE_PACKED_STRUCT struct { - uint8 flags; - uint8 reserved; - uint8 gtk[EAPOL_WPA_MAX_KEY_SIZE]; -} BWL_POST_PACKED_STRUCT eapol_wpa2_key_gtk_encap_t; - -#define EAPOL_WPA2_KEY_GTK_ENCAP_HDR_LEN 2 - -#define WPA2_GTK_INDEX_MASK 0x03 -#define WPA2_GTK_INDEX_SHIFT 0x00 - -#define WPA2_GTK_TRANSMIT 0x04 - -/* STAKey encapsulation */ -typedef BWL_PRE_PACKED_STRUCT struct { - uint8 reserved[2]; - uint8 mac[ETHER_ADDR_LEN]; - uint8 stakey[EAPOL_WPA_MAX_KEY_SIZE]; -} BWL_POST_PACKED_STRUCT eapol_wpa2_key_stakey_encap_t; - -#define WPA2_KEY_DATA_PAD 0xdd - - -/* This marks the end of a packed structure section. */ -#include - -#endif /* _eapol_h_ */ diff --git a/drivers/net/wireless/bcm4329/include/proto/ethernet.h b/drivers/net/wireless/bcm4329/include/proto/ethernet.h deleted file mode 100644 index 9ad2ea0c70fd..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/ethernet.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * From FreeBSD 2.2.7: Fundamental constants relating to ethernet. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: ethernet.h,v 9.45.56.5 2010/02/22 22:04:36 Exp $ - */ - - -#ifndef _NET_ETHERNET_H_ -#define _NET_ETHERNET_H_ - -#ifndef _TYPEDEFS_H_ -#include "typedefs.h" -#endif - - -#include - - - -#define ETHER_ADDR_LEN 6 - - -#define ETHER_TYPE_LEN 2 - - -#define ETHER_CRC_LEN 4 - - -#define ETHER_HDR_LEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN) - - -#define ETHER_MIN_LEN 64 - - -#define ETHER_MIN_DATA 46 - - -#define ETHER_MAX_LEN 1518 - - -#define ETHER_MAX_DATA 1500 - - -#define ETHER_TYPE_MIN 0x0600 -#define ETHER_TYPE_IP 0x0800 -#define ETHER_TYPE_ARP 0x0806 -#define ETHER_TYPE_8021Q 0x8100 -#define ETHER_TYPE_BRCM 0x886c -#define ETHER_TYPE_802_1X 0x888e -#define ETHER_TYPE_WAI 0x88b4 -#ifdef BCMWPA2 -#define ETHER_TYPE_802_1X_PREAUTH 0x88c7 -#endif - - -#define ETHER_BRCM_SUBTYPE_LEN 4 -#define ETHER_BRCM_CRAM 1 - - -#define ETHER_DEST_OFFSET (0 * ETHER_ADDR_LEN) -#define ETHER_SRC_OFFSET (1 * ETHER_ADDR_LEN) -#define ETHER_TYPE_OFFSET (2 * ETHER_ADDR_LEN) - - -#define ETHER_IS_VALID_LEN(foo) \ - ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN) - - -#ifndef __INCif_etherh - -BWL_PRE_PACKED_STRUCT struct ether_header { - uint8 ether_dhost[ETHER_ADDR_LEN]; - uint8 ether_shost[ETHER_ADDR_LEN]; - uint16 ether_type; -} BWL_POST_PACKED_STRUCT; - - -BWL_PRE_PACKED_STRUCT struct ether_addr { - uint8 octet[ETHER_ADDR_LEN]; -} BWL_POST_PACKED_STRUCT; -#endif - - -#define ETHER_SET_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] | 2)) -#define ETHER_IS_LOCALADDR(ea) (((uint8 *)(ea))[0] & 2) -#define ETHER_CLR_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & 0xd)) -#define ETHER_TOGGLE_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] ^ 2)) - - -#define ETHER_SET_UNICAST(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & ~1)) - - -#define ETHER_ISMULTI(ea) (((const uint8 *)(ea))[0] & 1) - - - -#define ether_cmp(a, b) (!(((short*)a)[0] == ((short*)b)[0]) | \ - !(((short*)a)[1] == ((short*)b)[1]) | \ - !(((short*)a)[2] == ((short*)b)[2])) - - -#define ether_copy(s, d) { \ - ((short*)d)[0] = ((short*)s)[0]; \ - ((short*)d)[1] = ((short*)s)[1]; \ - ((short*)d)[2] = ((short*)s)[2]; } - - -static const struct ether_addr ether_bcast = {{255, 255, 255, 255, 255, 255}}; -static const struct ether_addr ether_null = {{0, 0, 0, 0, 0, 0}}; - -#define ETHER_ISBCAST(ea) ((((uint8 *)(ea))[0] & \ - ((uint8 *)(ea))[1] & \ - ((uint8 *)(ea))[2] & \ - ((uint8 *)(ea))[3] & \ - ((uint8 *)(ea))[4] & \ - ((uint8 *)(ea))[5]) == 0xff) -#define ETHER_ISNULLADDR(ea) ((((uint8 *)(ea))[0] | \ - ((uint8 *)(ea))[1] | \ - ((uint8 *)(ea))[2] | \ - ((uint8 *)(ea))[3] | \ - ((uint8 *)(ea))[4] | \ - ((uint8 *)(ea))[5]) == 0) - - - -#include - -#endif diff --git a/drivers/net/wireless/bcm4329/include/proto/sdspi.h b/drivers/net/wireless/bcm4329/include/proto/sdspi.h deleted file mode 100644 index 7739e68a2440..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/sdspi.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * SD-SPI Protocol Standard - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sdspi.h,v 9.1.20.1 2008/05/06 22:59:19 Exp $ - */ - -#define SPI_START_M BITFIELD_MASK(1) /* Bit [31] - Start Bit */ -#define SPI_START_S 31 -#define SPI_DIR_M BITFIELD_MASK(1) /* Bit [30] - Direction */ -#define SPI_DIR_S 30 -#define SPI_CMD_INDEX_M BITFIELD_MASK(6) /* Bits [29:24] - Command number */ -#define SPI_CMD_INDEX_S 24 -#define SPI_RW_M BITFIELD_MASK(1) /* Bit [23] - Read=0, Write=1 */ -#define SPI_RW_S 23 -#define SPI_FUNC_M BITFIELD_MASK(3) /* Bits [22:20] - Function Number */ -#define SPI_FUNC_S 20 -#define SPI_RAW_M BITFIELD_MASK(1) /* Bit [19] - Read After Wr */ -#define SPI_RAW_S 19 -#define SPI_STUFF_M BITFIELD_MASK(1) /* Bit [18] - Stuff bit */ -#define SPI_STUFF_S 18 -#define SPI_BLKMODE_M BITFIELD_MASK(1) /* Bit [19] - Blockmode 1=blk */ -#define SPI_BLKMODE_S 19 -#define SPI_OPCODE_M BITFIELD_MASK(1) /* Bit [18] - OP Code */ -#define SPI_OPCODE_S 18 -#define SPI_ADDR_M BITFIELD_MASK(17) /* Bits [17:1] - Address */ -#define SPI_ADDR_S 1 -#define SPI_STUFF0_M BITFIELD_MASK(1) /* Bit [0] - Stuff bit */ -#define SPI_STUFF0_S 0 - -#define SPI_RSP_START_M BITFIELD_MASK(1) /* Bit [7] - Start Bit (always 0) */ -#define SPI_RSP_START_S 7 -#define SPI_RSP_PARAM_ERR_M BITFIELD_MASK(1) /* Bit [6] - Parameter Error */ -#define SPI_RSP_PARAM_ERR_S 6 -#define SPI_RSP_RFU5_M BITFIELD_MASK(1) /* Bit [5] - RFU (Always 0) */ -#define SPI_RSP_RFU5_S 5 -#define SPI_RSP_FUNC_ERR_M BITFIELD_MASK(1) /* Bit [4] - Function number error */ -#define SPI_RSP_FUNC_ERR_S 4 -#define SPI_RSP_CRC_ERR_M BITFIELD_MASK(1) /* Bit [3] - COM CRC Error */ -#define SPI_RSP_CRC_ERR_S 3 -#define SPI_RSP_ILL_CMD_M BITFIELD_MASK(1) /* Bit [2] - Illegal Command error */ -#define SPI_RSP_ILL_CMD_S 2 -#define SPI_RSP_RFU1_M BITFIELD_MASK(1) /* Bit [1] - RFU (Always 0) */ -#define SPI_RSP_RFU1_S 1 -#define SPI_RSP_IDLE_M BITFIELD_MASK(1) /* Bit [0] - In idle state */ -#define SPI_RSP_IDLE_S 0 - -/* SD-SPI Protocol Definitions */ -#define SDSPI_COMMAND_LEN 6 /* Number of bytes in an SD command */ -#define SDSPI_START_BLOCK 0xFE /* SD Start Block Token */ -#define SDSPI_IDLE_PAD 0xFF /* SD-SPI idle value for MOSI */ -#define SDSPI_START_BIT_MASK 0x80 diff --git a/drivers/net/wireless/bcm4329/include/proto/vlan.h b/drivers/net/wireless/bcm4329/include/proto/vlan.h deleted file mode 100644 index 670bc44c6bd6..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/vlan.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 802.1Q VLAN protocol definitions - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: vlan.h,v 9.4.196.2 2008/12/07 21:19:20 Exp $ - */ - - -#ifndef _vlan_h_ -#define _vlan_h_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - - -#include - -#define VLAN_VID_MASK 0xfff -#define VLAN_CFI_SHIFT 12 -#define VLAN_PRI_SHIFT 13 - -#define VLAN_PRI_MASK 7 - -#define VLAN_TAG_LEN 4 -#define VLAN_TAG_OFFSET (2 * ETHER_ADDR_LEN) - -#define VLAN_TPID 0x8100 - -struct ethervlan_header { - uint8 ether_dhost[ETHER_ADDR_LEN]; - uint8 ether_shost[ETHER_ADDR_LEN]; - uint16 vlan_type; - uint16 vlan_tag; - uint16 ether_type; -}; - -#define ETHERVLAN_HDR_LEN (ETHER_HDR_LEN + VLAN_TAG_LEN) - - - -#include - -#endif diff --git a/drivers/net/wireless/bcm4329/include/proto/wpa.h b/drivers/net/wireless/bcm4329/include/proto/wpa.h deleted file mode 100644 index f5d0cd539777..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/wpa.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Fundamental types and constants relating to WPA - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wpa.h,v 1.16.166.1.20.1 2008/11/20 00:51:31 Exp $ - */ - - -#ifndef _proto_wpa_h_ -#define _proto_wpa_h_ - -#include -#include - - - -#include - - - - -#define DOT11_RC_INVALID_WPA_IE 13 -#define DOT11_RC_MIC_FAILURE 14 -#define DOT11_RC_4WH_TIMEOUT 15 -#define DOT11_RC_GTK_UPDATE_TIMEOUT 16 -#define DOT11_RC_WPA_IE_MISMATCH 17 -#define DOT11_RC_INVALID_MC_CIPHER 18 -#define DOT11_RC_INVALID_UC_CIPHER 19 -#define DOT11_RC_INVALID_AKMP 20 -#define DOT11_RC_BAD_WPA_VERSION 21 -#define DOT11_RC_INVALID_WPA_CAP 22 -#define DOT11_RC_8021X_AUTH_FAIL 23 - -#define WPA2_PMKID_LEN 16 - - -typedef BWL_PRE_PACKED_STRUCT struct -{ - uint8 tag; - uint8 length; - uint8 oui[3]; - uint8 oui_type; - BWL_PRE_PACKED_STRUCT struct { - uint8 low; - uint8 high; - } BWL_POST_PACKED_STRUCT version; -} BWL_POST_PACKED_STRUCT wpa_ie_fixed_t; -#define WPA_IE_OUITYPE_LEN 4 -#define WPA_IE_FIXED_LEN 8 -#define WPA_IE_TAG_FIXED_LEN 6 - -typedef BWL_PRE_PACKED_STRUCT struct { - uint8 tag; - uint8 length; - BWL_PRE_PACKED_STRUCT struct { - uint8 low; - uint8 high; - } BWL_POST_PACKED_STRUCT version; -} BWL_POST_PACKED_STRUCT wpa_rsn_ie_fixed_t; -#define WPA_RSN_IE_FIXED_LEN 4 -#define WPA_RSN_IE_TAG_FIXED_LEN 2 -typedef uint8 wpa_pmkid_t[WPA2_PMKID_LEN]; - - -typedef BWL_PRE_PACKED_STRUCT struct -{ - uint8 oui[3]; - uint8 type; -} BWL_POST_PACKED_STRUCT wpa_suite_t, wpa_suite_mcast_t; -#define WPA_SUITE_LEN 4 - - -typedef BWL_PRE_PACKED_STRUCT struct -{ - BWL_PRE_PACKED_STRUCT struct { - uint8 low; - uint8 high; - } BWL_POST_PACKED_STRUCT count; - wpa_suite_t list[1]; -} BWL_POST_PACKED_STRUCT wpa_suite_ucast_t, wpa_suite_auth_key_mgmt_t; -#define WPA_IE_SUITE_COUNT_LEN 2 -typedef BWL_PRE_PACKED_STRUCT struct -{ - BWL_PRE_PACKED_STRUCT struct { - uint8 low; - uint8 high; - } BWL_POST_PACKED_STRUCT count; - wpa_pmkid_t list[1]; -} BWL_POST_PACKED_STRUCT wpa_pmkid_list_t; - - -#define WPA_CIPHER_NONE 0 -#define WPA_CIPHER_WEP_40 1 -#define WPA_CIPHER_TKIP 2 -#define WPA_CIPHER_AES_OCB 3 -#define WPA_CIPHER_AES_CCM 4 -#define WPA_CIPHER_WEP_104 5 - -#define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \ - (cipher) == WPA_CIPHER_WEP_40 || \ - (cipher) == WPA_CIPHER_WEP_104 || \ - (cipher) == WPA_CIPHER_TKIP || \ - (cipher) == WPA_CIPHER_AES_OCB || \ - (cipher) == WPA_CIPHER_AES_CCM) - - -#define WPA_TKIP_CM_DETECT 60 -#define WPA_TKIP_CM_BLOCK 60 - - -#define RSN_CAP_LEN 2 - - -#define RSN_CAP_PREAUTH 0x0001 -#define RSN_CAP_NOPAIRWISE 0x0002 -#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C -#define RSN_CAP_PTK_REPLAY_CNTR_SHIFT 2 -#define RSN_CAP_GTK_REPLAY_CNTR_MASK 0x0030 -#define RSN_CAP_GTK_REPLAY_CNTR_SHIFT 4 -#define RSN_CAP_1_REPLAY_CNTR 0 -#define RSN_CAP_2_REPLAY_CNTRS 1 -#define RSN_CAP_4_REPLAY_CNTRS 2 -#define RSN_CAP_16_REPLAY_CNTRS 3 - - -#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS -#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS -#define WPA_CAP_REPLAY_CNTR_SHIFT RSN_CAP_PTK_REPLAY_CNTR_SHIFT -#define WPA_CAP_REPLAY_CNTR_MASK RSN_CAP_PTK_REPLAY_CNTR_MASK - - -#define WPA_CAP_LEN RSN_CAP_LEN - -#define WPA_CAP_WPA2_PREAUTH RSN_CAP_PREAUTH - - - -#include - -#endif diff --git a/drivers/net/wireless/bcm4329/include/sbchipc.h b/drivers/net/wireless/bcm4329/include/sbchipc.h deleted file mode 100644 index 39e5c8d6aed0..000000000000 --- a/drivers/net/wireless/bcm4329/include/sbchipc.h +++ /dev/null @@ -1,1026 +0,0 @@ -/* - * SiliconBackplane Chipcommon core hardware definitions. - * - * The chipcommon core provides chip identification, SB control, - * jtag, 0/1/2 uarts, clock frequency control, a watchdog interrupt timer, - * gpio interface, extbus, and support for serial and parallel flashes. - * - * $Id: sbchipc.h,v 13.103.2.5.4.5.2.9 2009/07/03 14:23:21 Exp $ - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - */ - - -#ifndef _SBCHIPC_H -#define _SBCHIPC_H - -#ifndef _LANGUAGE_ASSEMBLY - - -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif - -typedef volatile struct { - uint32 chipid; - uint32 capabilities; - uint32 corecontrol; - uint32 bist; - - - uint32 otpstatus; - uint32 otpcontrol; - uint32 otpprog; - uint32 PAD; - - - uint32 intstatus; - uint32 intmask; - uint32 chipcontrol; - uint32 chipstatus; - - - uint32 jtagcmd; - uint32 jtagir; - uint32 jtagdr; - uint32 jtagctrl; - - - uint32 flashcontrol; - uint32 flashaddress; - uint32 flashdata; - uint32 PAD[1]; - - - uint32 broadcastaddress; - uint32 broadcastdata; - - - uint32 gpiopullup; - uint32 gpiopulldown; - uint32 gpioin; - uint32 gpioout; - uint32 gpioouten; - uint32 gpiocontrol; - uint32 gpiointpolarity; - uint32 gpiointmask; - - - uint32 gpioevent; - uint32 gpioeventintmask; - - - uint32 watchdog; - - - uint32 gpioeventintpolarity; - - - uint32 gpiotimerval; - uint32 gpiotimeroutmask; - - - uint32 clockcontrol_n; - uint32 clockcontrol_sb; - uint32 clockcontrol_pci; - uint32 clockcontrol_m2; - uint32 clockcontrol_m3; - uint32 clkdiv; - uint32 PAD[2]; - - - uint32 pll_on_delay; - uint32 fref_sel_delay; - uint32 slow_clk_ctl; - uint32 PAD[1]; - - - uint32 system_clk_ctl; - uint32 clkstatestretch; - uint32 PAD[13]; - - - uint32 eromptr; - - - uint32 pcmcia_config; - uint32 pcmcia_memwait; - uint32 pcmcia_attrwait; - uint32 pcmcia_iowait; - uint32 ide_config; - uint32 ide_memwait; - uint32 ide_attrwait; - uint32 ide_iowait; - uint32 prog_config; - uint32 prog_waitcount; - uint32 flash_config; - uint32 flash_waitcount; - uint32 PAD[4]; - uint32 PAD[40]; - - - - uint32 clk_ctl_st; - uint32 hw_war; - uint32 PAD[70]; - - - uint8 uart0data; - uint8 uart0imr; - uint8 uart0fcr; - uint8 uart0lcr; - uint8 uart0mcr; - uint8 uart0lsr; - uint8 uart0msr; - uint8 uart0scratch; - uint8 PAD[248]; - - uint8 uart1data; - uint8 uart1imr; - uint8 uart1fcr; - uint8 uart1lcr; - uint8 uart1mcr; - uint8 uart1lsr; - uint8 uart1msr; - uint8 uart1scratch; - uint32 PAD[126]; - - - uint32 pmucontrol; - uint32 pmucapabilities; - uint32 pmustatus; - uint32 res_state; - uint32 res_pending; - uint32 pmutimer; - uint32 min_res_mask; - uint32 max_res_mask; - uint32 res_table_sel; - uint32 res_dep_mask; - uint32 res_updn_timer; - uint32 res_timer; - uint32 clkstretch; - uint32 pmuwatchdog; - uint32 gpiosel; - uint32 gpioenable; - uint32 res_req_timer_sel; - uint32 res_req_timer; - uint32 res_req_mask; - uint32 PAD; - uint32 chipcontrol_addr; - uint32 chipcontrol_data; - uint32 regcontrol_addr; - uint32 regcontrol_data; - uint32 pllcontrol_addr; - uint32 pllcontrol_data; - uint32 PAD[102]; - uint16 otp[768]; -} chipcregs_t; - -#endif - -#define CC_CHIPID 0 -#define CC_CAPABILITIES 4 -#define CC_OTPST 0x10 -#define CC_CHIPST 0x2c -#define CC_JTAGCMD 0x30 -#define CC_JTAGIR 0x34 -#define CC_JTAGDR 0x38 -#define CC_JTAGCTRL 0x3c -#define CC_WATCHDOG 0x80 -#define CC_CLKC_N 0x90 -#define CC_CLKC_M0 0x94 -#define CC_CLKC_M1 0x98 -#define CC_CLKC_M2 0x9c -#define CC_CLKC_M3 0xa0 -#define CC_CLKDIV 0xa4 -#define CC_SYS_CLK_CTL 0xc0 -#define CC_CLK_CTL_ST SI_CLK_CTL_ST -#define CC_EROMPTR 0xfc -#define PMU_CTL 0x600 -#define PMU_CAP 0x604 -#define PMU_ST 0x608 -#define PMU_RES_STATE 0x60c -#define PMU_TIMER 0x614 -#define PMU_MIN_RES_MASK 0x618 -#define PMU_MAX_RES_MASK 0x61c -#define PMU_REG_CONTROL_ADDR 0x658 -#define PMU_REG_CONTROL_DATA 0x65C -#define PMU_PLL_CONTROL_ADDR 0x660 -#define PMU_PLL_CONTROL_DATA 0x664 -#define CC_OTP 0x800 - - -#define CID_ID_MASK 0x0000ffff -#define CID_REV_MASK 0x000f0000 -#define CID_REV_SHIFT 16 -#define CID_PKG_MASK 0x00f00000 -#define CID_PKG_SHIFT 20 -#define CID_CC_MASK 0x0f000000 -#define CID_CC_SHIFT 24 -#define CID_TYPE_MASK 0xf0000000 -#define CID_TYPE_SHIFT 28 - - -#define CC_CAP_UARTS_MASK 0x00000003 -#define CC_CAP_MIPSEB 0x00000004 -#define CC_CAP_UCLKSEL 0x00000018 -#define CC_CAP_UINTCLK 0x00000008 -#define CC_CAP_UARTGPIO 0x00000020 -#define CC_CAP_EXTBUS_MASK 0x000000c0 -#define CC_CAP_EXTBUS_NONE 0x00000000 -#define CC_CAP_EXTBUS_FULL 0x00000040 -#define CC_CAP_EXTBUS_PROG 0x00000080 -#define CC_CAP_FLASH_MASK 0x00000700 -#define CC_CAP_PLL_MASK 0x00038000 -#define CC_CAP_PWR_CTL 0x00040000 -#define CC_CAP_OTPSIZE 0x00380000 -#define CC_CAP_OTPSIZE_SHIFT 19 -#define CC_CAP_OTPSIZE_BASE 5 -#define CC_CAP_JTAGP 0x00400000 -#define CC_CAP_ROM 0x00800000 -#define CC_CAP_BKPLN64 0x08000000 -#define CC_CAP_PMU 0x10000000 -#define CC_CAP_ECI 0x20000000 - - -#define PLL_NONE 0x00000000 -#define PLL_TYPE1 0x00010000 -#define PLL_TYPE2 0x00020000 -#define PLL_TYPE3 0x00030000 -#define PLL_TYPE4 0x00008000 -#define PLL_TYPE5 0x00018000 -#define PLL_TYPE6 0x00028000 -#define PLL_TYPE7 0x00038000 - - -#define ILP_CLOCK 32000 - - -#define ALP_CLOCK 20000000 - - -#define HT_CLOCK 80000000 - - -#define CC_UARTCLKO 0x00000001 -#define CC_SE 0x00000002 -#define CC_UARTCLKEN 0x00000008 - - -#define CHIPCTRL_4321A0_DEFAULT 0x3a4 -#define CHIPCTRL_4321A1_DEFAULT 0x0a4 -#define CHIPCTRL_4321_PLL_DOWN 0x800000 - - -#define OTPS_OL_MASK 0x000000ff -#define OTPS_OL_MFG 0x00000001 -#define OTPS_OL_OR1 0x00000002 -#define OTPS_OL_OR2 0x00000004 -#define OTPS_OL_GU 0x00000008 -#define OTPS_GUP_MASK 0x00000f00 -#define OTPS_GUP_SHIFT 8 -#define OTPS_GUP_HW 0x00000100 -#define OTPS_GUP_SW 0x00000200 -#define OTPS_GUP_CI 0x00000400 -#define OTPS_GUP_FUSE 0x00000800 -#define OTPS_READY 0x00001000 -#define OTPS_RV(x) (1 << (16 + (x))) -#define OTPS_RV_MASK 0x0fff0000 - - -#define OTPC_PROGSEL 0x00000001 -#define OTPC_PCOUNT_MASK 0x0000000e -#define OTPC_PCOUNT_SHIFT 1 -#define OTPC_VSEL_MASK 0x000000f0 -#define OTPC_VSEL_SHIFT 4 -#define OTPC_TMM_MASK 0x00000700 -#define OTPC_TMM_SHIFT 8 -#define OTPC_ODM 0x00000800 -#define OTPC_PROGEN 0x80000000 - - -#define OTPP_COL_MASK 0x000000ff -#define OTPP_COL_SHIFT 0 -#define OTPP_ROW_MASK 0x0000ff00 -#define OTPP_ROW_SHIFT 8 -#define OTPP_OC_MASK 0x0f000000 -#define OTPP_OC_SHIFT 24 -#define OTPP_READERR 0x10000000 -#define OTPP_VALUE_MASK 0x20000000 -#define OTPP_VALUE_SHIFT 29 -#define OTPP_START_BUSY 0x80000000 - - -#define OTPPOC_READ 0 -#define OTPPOC_BIT_PROG 1 -#define OTPPOC_VERIFY 3 -#define OTPPOC_INIT 4 -#define OTPPOC_SET 5 -#define OTPPOC_RESET 6 -#define OTPPOC_OCST 7 -#define OTPPOC_ROW_LOCK 8 -#define OTPPOC_PRESCN_TEST 9 - - -#define JCMD_START 0x80000000 -#define JCMD_BUSY 0x80000000 -#define JCMD_STATE_MASK 0x60000000 -#define JCMD_STATE_TLR 0x00000000 -#define JCMD_STATE_PIR 0x20000000 -#define JCMD_STATE_PDR 0x40000000 -#define JCMD_STATE_RTI 0x60000000 -#define JCMD0_ACC_MASK 0x0000f000 -#define JCMD0_ACC_IRDR 0x00000000 -#define JCMD0_ACC_DR 0x00001000 -#define JCMD0_ACC_IR 0x00002000 -#define JCMD0_ACC_RESET 0x00003000 -#define JCMD0_ACC_IRPDR 0x00004000 -#define JCMD0_ACC_PDR 0x00005000 -#define JCMD0_IRW_MASK 0x00000f00 -#define JCMD_ACC_MASK 0x000f0000 -#define JCMD_ACC_IRDR 0x00000000 -#define JCMD_ACC_DR 0x00010000 -#define JCMD_ACC_IR 0x00020000 -#define JCMD_ACC_RESET 0x00030000 -#define JCMD_ACC_IRPDR 0x00040000 -#define JCMD_ACC_PDR 0x00050000 -#define JCMD_ACC_PIR 0x00060000 -#define JCMD_ACC_IRDR_I 0x00070000 -#define JCMD_ACC_DR_I 0x00080000 -#define JCMD_IRW_MASK 0x00001f00 -#define JCMD_IRW_SHIFT 8 -#define JCMD_DRW_MASK 0x0000003f - - -#define JCTRL_FORCE_CLK 4 -#define JCTRL_EXT_EN 2 -#define JCTRL_EN 1 - - -#define CLKD_SFLASH 0x0f000000 -#define CLKD_SFLASH_SHIFT 24 -#define CLKD_OTP 0x000f0000 -#define CLKD_OTP_SHIFT 16 -#define CLKD_JTAG 0x00000f00 -#define CLKD_JTAG_SHIFT 8 -#define CLKD_UART 0x000000ff - - -#define CI_GPIO 0x00000001 -#define CI_EI 0x00000002 -#define CI_TEMP 0x00000004 -#define CI_SIRQ 0x00000008 -#define CI_ECI 0x00000010 -#define CI_PMU 0x00000020 -#define CI_UART 0x00000040 -#define CI_WDRESET 0x80000000 - - -#define SCC_SS_MASK 0x00000007 -#define SCC_SS_LPO 0x00000000 -#define SCC_SS_XTAL 0x00000001 -#define SCC_SS_PCI 0x00000002 -#define SCC_LF 0x00000200 -#define SCC_LP 0x00000400 -#define SCC_FS 0x00000800 -#define SCC_IP 0x00001000 -#define SCC_XC 0x00002000 -#define SCC_XP 0x00004000 -#define SCC_CD_MASK 0xffff0000 -#define SCC_CD_SHIFT 16 - - -#define SYCC_IE 0x00000001 -#define SYCC_AE 0x00000002 -#define SYCC_FP 0x00000004 -#define SYCC_AR 0x00000008 -#define SYCC_HR 0x00000010 -#define SYCC_CD_MASK 0xffff0000 -#define SYCC_CD_SHIFT 16 - - -#define CF_EN 0x00000001 -#define CF_EM_MASK 0x0000000e -#define CF_EM_SHIFT 1 -#define CF_EM_FLASH 0 -#define CF_EM_SYNC 2 -#define CF_EM_PCMCIA 4 -#define CF_DS 0x00000010 -#define CF_BS 0x00000020 -#define CF_CD_MASK 0x000000c0 -#define CF_CD_SHIFT 6 -#define CF_CD_DIV2 0x00000000 -#define CF_CD_DIV3 0x00000040 -#define CF_CD_DIV4 0x00000080 -#define CF_CE 0x00000100 -#define CF_SB 0x00000200 - - -#define PM_W0_MASK 0x0000003f -#define PM_W1_MASK 0x00001f00 -#define PM_W1_SHIFT 8 -#define PM_W2_MASK 0x001f0000 -#define PM_W2_SHIFT 16 -#define PM_W3_MASK 0x1f000000 -#define PM_W3_SHIFT 24 - - -#define PA_W0_MASK 0x0000003f -#define PA_W1_MASK 0x00001f00 -#define PA_W1_SHIFT 8 -#define PA_W2_MASK 0x001f0000 -#define PA_W2_SHIFT 16 -#define PA_W3_MASK 0x1f000000 -#define PA_W3_SHIFT 24 - - -#define PI_W0_MASK 0x0000003f -#define PI_W1_MASK 0x00001f00 -#define PI_W1_SHIFT 8 -#define PI_W2_MASK 0x001f0000 -#define PI_W2_SHIFT 16 -#define PI_W3_MASK 0x1f000000 -#define PI_W3_SHIFT 24 - - -#define PW_W0_MASK 0x0000001f -#define PW_W1_MASK 0x00001f00 -#define PW_W1_SHIFT 8 -#define PW_W2_MASK 0x001f0000 -#define PW_W2_SHIFT 16 -#define PW_W3_MASK 0x1f000000 -#define PW_W3_SHIFT 24 - -#define PW_W0 0x0000000c -#define PW_W1 0x00000a00 -#define PW_W2 0x00020000 -#define PW_W3 0x01000000 - - -#define FW_W0_MASK 0x0000003f -#define FW_W1_MASK 0x00001f00 -#define FW_W1_SHIFT 8 -#define FW_W2_MASK 0x001f0000 -#define FW_W2_SHIFT 16 -#define FW_W3_MASK 0x1f000000 -#define FW_W3_SHIFT 24 - - -#define WATCHDOG_CLOCK 48000000 -#define WATCHDOG_CLOCK_5354 32000 - - -#define PCTL_ILP_DIV_MASK 0xffff0000 -#define PCTL_ILP_DIV_SHIFT 16 -#define PCTL_PLL_PLLCTL_UPD 0x00000400 -#define PCTL_NOILP_ON_WAIT 0x00000200 -#define PCTL_HT_REQ_EN 0x00000100 -#define PCTL_ALP_REQ_EN 0x00000080 -#define PCTL_XTALFREQ_MASK 0x0000007c -#define PCTL_XTALFREQ_SHIFT 2 -#define PCTL_ILP_DIV_EN 0x00000002 -#define PCTL_LPO_SEL 0x00000001 - - -#define CSTRETCH_HT 0xffff0000 -#define CSTRETCH_ALP 0x0000ffff - - -#define GPIO_ONTIME_SHIFT 16 - - -#define CN_N1_MASK 0x3f -#define CN_N2_MASK 0x3f00 -#define CN_N2_SHIFT 8 -#define CN_PLLC_MASK 0xf0000 -#define CN_PLLC_SHIFT 16 - - -#define CC_M1_MASK 0x3f -#define CC_M2_MASK 0x3f00 -#define CC_M2_SHIFT 8 -#define CC_M3_MASK 0x3f0000 -#define CC_M3_SHIFT 16 -#define CC_MC_MASK 0x1f000000 -#define CC_MC_SHIFT 24 - - -#define CC_F6_2 0x02 -#define CC_F6_3 0x03 -#define CC_F6_4 0x05 -#define CC_F6_5 0x09 -#define CC_F6_6 0x11 -#define CC_F6_7 0x21 - -#define CC_F5_BIAS 5 - -#define CC_MC_BYPASS 0x08 -#define CC_MC_M1 0x04 -#define CC_MC_M1M2 0x02 -#define CC_MC_M1M2M3 0x01 -#define CC_MC_M1M3 0x11 - - -#define CC_T2_BIAS 2 -#define CC_T2M2_BIAS 3 - -#define CC_T2MC_M1BYP 1 -#define CC_T2MC_M2BYP 2 -#define CC_T2MC_M3BYP 4 - - -#define CC_T6_MMASK 1 -#define CC_T6_M0 120000000 -#define CC_T6_M1 100000000 -#define SB2MIPS_T6(sb) (2 * (sb)) - - -#define CC_CLOCK_BASE1 24000000 -#define CC_CLOCK_BASE2 12500000 - - -#define CLKC_5350_N 0x0311 -#define CLKC_5350_M 0x04020009 - - -#define FLASH_NONE 0x000 -#define SFLASH_ST 0x100 -#define SFLASH_AT 0x200 -#define PFLASH 0x700 - - -#define CC_CFG_EN 0x0001 -#define CC_CFG_EM_MASK 0x000e -#define CC_CFG_EM_ASYNC 0x0000 -#define CC_CFG_EM_SYNC 0x0002 -#define CC_CFG_EM_PCMCIA 0x0004 -#define CC_CFG_EM_IDE 0x0006 -#define CC_CFG_DS 0x0010 -#define CC_CFG_CD_MASK 0x00e0 -#define CC_CFG_CE 0x0100 -#define CC_CFG_SB 0x0200 -#define CC_CFG_IS 0x0400 - - -#define CC_EB_BASE 0x1a000000 -#define CC_EB_PCMCIA_MEM 0x1a000000 -#define CC_EB_PCMCIA_IO 0x1a200000 -#define CC_EB_PCMCIA_CFG 0x1a400000 -#define CC_EB_IDE 0x1a800000 -#define CC_EB_PCMCIA1_MEM 0x1a800000 -#define CC_EB_PCMCIA1_IO 0x1aa00000 -#define CC_EB_PCMCIA1_CFG 0x1ac00000 -#define CC_EB_PROGIF 0x1b000000 - - - -#define SFLASH_OPCODE 0x000000ff -#define SFLASH_ACTION 0x00000700 -#define SFLASH_CS_ACTIVE 0x00001000 -#define SFLASH_START 0x80000000 -#define SFLASH_BUSY SFLASH_START - - -#define SFLASH_ACT_OPONLY 0x0000 -#define SFLASH_ACT_OP1D 0x0100 -#define SFLASH_ACT_OP3A 0x0200 -#define SFLASH_ACT_OP3A1D 0x0300 -#define SFLASH_ACT_OP3A4D 0x0400 -#define SFLASH_ACT_OP3A4X4D 0x0500 -#define SFLASH_ACT_OP3A1X4D 0x0700 - - -#define SFLASH_ST_WREN 0x0006 -#define SFLASH_ST_WRDIS 0x0004 -#define SFLASH_ST_RDSR 0x0105 -#define SFLASH_ST_WRSR 0x0101 -#define SFLASH_ST_READ 0x0303 -#define SFLASH_ST_PP 0x0302 -#define SFLASH_ST_SE 0x02d8 -#define SFLASH_ST_BE 0x00c7 -#define SFLASH_ST_DP 0x00b9 -#define SFLASH_ST_RES 0x03ab -#define SFLASH_ST_CSA 0x1000 - - -#define SFLASH_ST_WIP 0x01 -#define SFLASH_ST_WEL 0x02 -#define SFLASH_ST_BP_MASK 0x1c -#define SFLASH_ST_BP_SHIFT 2 -#define SFLASH_ST_SRWD 0x80 - - -#define SFLASH_AT_READ 0x07e8 -#define SFLASH_AT_PAGE_READ 0x07d2 -#define SFLASH_AT_BUF1_READ -#define SFLASH_AT_BUF2_READ -#define SFLASH_AT_STATUS 0x01d7 -#define SFLASH_AT_BUF1_WRITE 0x0384 -#define SFLASH_AT_BUF2_WRITE 0x0387 -#define SFLASH_AT_BUF1_ERASE_PROGRAM 0x0283 -#define SFLASH_AT_BUF2_ERASE_PROGRAM 0x0286 -#define SFLASH_AT_BUF1_PROGRAM 0x0288 -#define SFLASH_AT_BUF2_PROGRAM 0x0289 -#define SFLASH_AT_PAGE_ERASE 0x0281 -#define SFLASH_AT_BLOCK_ERASE 0x0250 -#define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382 -#define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385 -#define SFLASH_AT_BUF1_LOAD 0x0253 -#define SFLASH_AT_BUF2_LOAD 0x0255 -#define SFLASH_AT_BUF1_COMPARE 0x0260 -#define SFLASH_AT_BUF2_COMPARE 0x0261 -#define SFLASH_AT_BUF1_REPROGRAM 0x0258 -#define SFLASH_AT_BUF2_REPROGRAM 0x0259 - - -#define SFLASH_AT_READY 0x80 -#define SFLASH_AT_MISMATCH 0x40 -#define SFLASH_AT_ID_MASK 0x38 -#define SFLASH_AT_ID_SHIFT 3 - - - -#define UART_RX 0 -#define UART_TX 0 -#define UART_DLL 0 -#define UART_IER 1 -#define UART_DLM 1 -#define UART_IIR 2 -#define UART_FCR 2 -#define UART_LCR 3 -#define UART_MCR 4 -#define UART_LSR 5 -#define UART_MSR 6 -#define UART_SCR 7 -#define UART_LCR_DLAB 0x80 -#define UART_LCR_WLEN8 0x03 -#define UART_MCR_OUT2 0x08 -#define UART_MCR_LOOP 0x10 -#define UART_LSR_RX_FIFO 0x80 -#define UART_LSR_TDHR 0x40 -#define UART_LSR_THRE 0x20 -#define UART_LSR_BREAK 0x10 -#define UART_LSR_FRAMING 0x08 -#define UART_LSR_PARITY 0x04 -#define UART_LSR_OVERRUN 0x02 -#define UART_LSR_RXRDY 0x01 -#define UART_FCR_FIFO_ENABLE 1 - - -#define UART_IIR_FIFO_MASK 0xc0 -#define UART_IIR_INT_MASK 0xf -#define UART_IIR_MDM_CHG 0x0 -#define UART_IIR_NOINT 0x1 -#define UART_IIR_THRE 0x2 -#define UART_IIR_RCVD_DATA 0x4 -#define UART_IIR_RCVR_STATUS 0x6 -#define UART_IIR_CHAR_TIME 0xc - - -#define UART_IER_EDSSI 8 -#define UART_IER_ELSI 4 -#define UART_IER_ETBEI 2 -#define UART_IER_ERBFI 1 - - -#define PST_INTPEND 0x0040 -#define PST_SBCLKST 0x0030 -#define PST_SBCLKST_ILP 0x0010 -#define PST_SBCLKST_ALP 0x0020 -#define PST_SBCLKST_HT 0x0030 -#define PST_ALPAVAIL 0x0008 -#define PST_HTAVAIL 0x0004 -#define PST_RESINIT 0x0003 - - -#define PCAP_REV_MASK 0x000000ff -#define PCAP_RC_MASK 0x00001f00 -#define PCAP_RC_SHIFT 8 -#define PCAP_TC_MASK 0x0001e000 -#define PCAP_TC_SHIFT 13 -#define PCAP_PC_MASK 0x001e0000 -#define PCAP_PC_SHIFT 17 -#define PCAP_VC_MASK 0x01e00000 -#define PCAP_VC_SHIFT 21 -#define PCAP_CC_MASK 0x1e000000 -#define PCAP_CC_SHIFT 25 -#define PCAP5_PC_MASK 0x003e0000 -#define PCAP5_PC_SHIFT 17 -#define PCAP5_VC_MASK 0x07c00000 -#define PCAP5_VC_SHIFT 22 -#define PCAP5_CC_MASK 0xf8000000 -#define PCAP5_CC_SHIFT 27 - - - -#define PRRT_TIME_MASK 0x03ff -#define PRRT_INTEN 0x0400 -#define PRRT_REQ_ACTIVE 0x0800 -#define PRRT_ALP_REQ 0x1000 -#define PRRT_HT_REQ 0x2000 - - -#define PMURES_BIT(bit) (1 << (bit)) - - -#define PMURES_MAX_RESNUM 30 - - - - -#define PMU0_PLL0_PLLCTL0 0 -#define PMU0_PLL0_PC0_PDIV_MASK 1 -#define PMU0_PLL0_PC0_PDIV_FREQ 25000 -#define PMU0_PLL0_PC0_DIV_ARM_MASK 0x00000038 -#define PMU0_PLL0_PC0_DIV_ARM_SHIFT 3 -#define PMU0_PLL0_PC0_DIV_ARM_BASE 8 - - -#define PMU0_PLL0_PC0_DIV_ARM_110MHZ 0 -#define PMU0_PLL0_PC0_DIV_ARM_97_7MHZ 1 -#define PMU0_PLL0_PC0_DIV_ARM_88MHZ 2 -#define PMU0_PLL0_PC0_DIV_ARM_80MHZ 3 -#define PMU0_PLL0_PC0_DIV_ARM_73_3MHZ 4 -#define PMU0_PLL0_PC0_DIV_ARM_67_7MHZ 5 -#define PMU0_PLL0_PC0_DIV_ARM_62_9MHZ 6 -#define PMU0_PLL0_PC0_DIV_ARM_58_6MHZ 7 - - -#define PMU0_PLL0_PLLCTL1 1 -#define PMU0_PLL0_PC1_WILD_INT_MASK 0xf0000000 -#define PMU0_PLL0_PC1_WILD_INT_SHIFT 28 -#define PMU0_PLL0_PC1_WILD_FRAC_MASK 0x0fffff00 -#define PMU0_PLL0_PC1_WILD_FRAC_SHIFT 8 -#define PMU0_PLL0_PC1_STOP_MOD 0x00000040 - - -#define PMU0_PLL0_PLLCTL2 2 -#define PMU0_PLL0_PC2_WILD_INT_MASK 0xf -#define PMU0_PLL0_PC2_WILD_INT_SHIFT 4 - - -#define RES4328_EXT_SWITCHER_PWM 0 -#define RES4328_BB_SWITCHER_PWM 1 -#define RES4328_BB_SWITCHER_BURST 2 -#define RES4328_BB_EXT_SWITCHER_BURST 3 -#define RES4328_ILP_REQUEST 4 -#define RES4328_RADIO_SWITCHER_PWM 5 -#define RES4328_RADIO_SWITCHER_BURST 6 -#define RES4328_ROM_SWITCH 7 -#define RES4328_PA_REF_LDO 8 -#define RES4328_RADIO_LDO 9 -#define RES4328_AFE_LDO 10 -#define RES4328_PLL_LDO 11 -#define RES4328_BG_FILTBYP 12 -#define RES4328_TX_FILTBYP 13 -#define RES4328_RX_FILTBYP 14 -#define RES4328_XTAL_PU 15 -#define RES4328_XTAL_EN 16 -#define RES4328_BB_PLL_FILTBYP 17 -#define RES4328_RF_PLL_FILTBYP 18 -#define RES4328_BB_PLL_PU 19 - -#define RES5354_EXT_SWITCHER_PWM 0 -#define RES5354_BB_SWITCHER_PWM 1 -#define RES5354_BB_SWITCHER_BURST 2 -#define RES5354_BB_EXT_SWITCHER_BURST 3 -#define RES5354_ILP_REQUEST 4 -#define RES5354_RADIO_SWITCHER_PWM 5 -#define RES5354_RADIO_SWITCHER_BURST 6 -#define RES5354_ROM_SWITCH 7 -#define RES5354_PA_REF_LDO 8 -#define RES5354_RADIO_LDO 9 -#define RES5354_AFE_LDO 10 -#define RES5354_PLL_LDO 11 -#define RES5354_BG_FILTBYP 12 -#define RES5354_TX_FILTBYP 13 -#define RES5354_RX_FILTBYP 14 -#define RES5354_XTAL_PU 15 -#define RES5354_XTAL_EN 16 -#define RES5354_BB_PLL_FILTBYP 17 -#define RES5354_RF_PLL_FILTBYP 18 -#define RES5354_BB_PLL_PU 19 - - - -#define DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT 8 -#define DOT11MAC_880MHZ_CLK_DIVISOR_MASK (0xFF << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT) -#define DOT11MAC_880MHZ_CLK_DIVISOR_VAL (0xE << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT) - - -#define PMU2_PHY_PLL_PLLCTL 4 -#define PMU2_SI_PLL_PLLCTL 10 - - -#define RES4325_BUCK_BOOST_BURST 0 -#define RES4325_CBUCK_BURST 1 -#define RES4325_CBUCK_PWM 2 -#define RES4325_CLDO_CBUCK_BURST 3 -#define RES4325_CLDO_CBUCK_PWM 4 -#define RES4325_BUCK_BOOST_PWM 5 -#define RES4325_ILP_REQUEST 6 -#define RES4325_ABUCK_BURST 7 -#define RES4325_ABUCK_PWM 8 -#define RES4325_LNLDO1_PU 9 -#define RES4325_OTP_PU 10 -#define RES4325_LNLDO3_PU 11 -#define RES4325_LNLDO4_PU 12 -#define RES4325_XTAL_PU 13 -#define RES4325_ALP_AVAIL 14 -#define RES4325_RX_PWRSW_PU 15 -#define RES4325_TX_PWRSW_PU 16 -#define RES4325_RFPLL_PWRSW_PU 17 -#define RES4325_LOGEN_PWRSW_PU 18 -#define RES4325_AFE_PWRSW_PU 19 -#define RES4325_BBPLL_PWRSW_PU 20 -#define RES4325_HT_AVAIL 21 - - -#define RES4325B0_CBUCK_LPOM 1 -#define RES4325B0_CBUCK_BURST 2 -#define RES4325B0_CBUCK_PWM 3 -#define RES4325B0_CLDO_PU 4 - - -#define RES4325C1_OTP_PWRSW_PU 10 -#define RES4325C1_LNLDO2_PU 12 - - -#define CST4325_SPROM_OTP_SEL_MASK 0x00000003 -#define CST4325_DEFCIS_SEL 0 -#define CST4325_SPROM_SEL 1 -#define CST4325_OTP_SEL 2 -#define CST4325_OTP_PWRDN 3 -#define CST4325_SDIO_USB_MODE_MASK 0x00000004 -#define CST4325_SDIO_USB_MODE_SHIFT 2 -#define CST4325_RCAL_VALID_MASK 0x00000008 -#define CST4325_RCAL_VALID_SHIFT 3 -#define CST4325_RCAL_VALUE_MASK 0x000001f0 -#define CST4325_RCAL_VALUE_SHIFT 4 -#define CST4325_PMUTOP_2B_MASK 0x00000200 -#define CST4325_PMUTOP_2B_SHIFT 9 - -#define RES4329_RESERVED0 0 -#define RES4329_CBUCK_LPOM 1 -#define RES4329_CBUCK_BURST 2 -#define RES4329_CBUCK_PWM 3 -#define RES4329_CLDO_PU 4 -#define RES4329_PALDO_PU 5 -#define RES4329_ILP_REQUEST 6 -#define RES4329_RESERVED7 7 -#define RES4329_RESERVED8 8 -#define RES4329_LNLDO1_PU 9 -#define RES4329_OTP_PU 10 -#define RES4329_RESERVED11 11 -#define RES4329_LNLDO2_PU 12 -#define RES4329_XTAL_PU 13 -#define RES4329_ALP_AVAIL 14 -#define RES4329_RX_PWRSW_PU 15 -#define RES4329_TX_PWRSW_PU 16 -#define RES4329_RFPLL_PWRSW_PU 17 -#define RES4329_LOGEN_PWRSW_PU 18 -#define RES4329_AFE_PWRSW_PU 19 -#define RES4329_BBPLL_PWRSW_PU 20 -#define RES4329_HT_AVAIL 21 - -#define CST4329_SPROM_OTP_SEL_MASK 0x00000003 -#define CST4329_DEFCIS_SEL 0 -#define CST4329_SPROM_SEL 1 -#define CST4329_OTP_SEL 2 -#define CST4329_OTP_PWRDN 3 -#define CST4329_SPI_SDIO_MODE_MASK 0x00000004 -#define CST4329_SPI_SDIO_MODE_SHIFT 2 - - -#define RES4312_SWITCHER_BURST 0 -#define RES4312_SWITCHER_PWM 1 -#define RES4312_PA_REF_LDO 2 -#define RES4312_CORE_LDO_BURST 3 -#define RES4312_CORE_LDO_PWM 4 -#define RES4312_RADIO_LDO 5 -#define RES4312_ILP_REQUEST 6 -#define RES4312_BG_FILTBYP 7 -#define RES4312_TX_FILTBYP 8 -#define RES4312_RX_FILTBYP 9 -#define RES4312_XTAL_PU 10 -#define RES4312_ALP_AVAIL 11 -#define RES4312_BB_PLL_FILTBYP 12 -#define RES4312_RF_PLL_FILTBYP 13 -#define RES4312_HT_AVAIL 14 - -#define RES4322_RF_LDO 0 -#define RES4322_ILP_REQUEST 1 -#define RES4322_XTAL_PU 2 -#define RES4322_ALP_AVAIL 3 -#define RES4322_SI_PLL_ON 4 -#define RES4322_HT_SI_AVAIL 5 -#define RES4322_PHY_PLL_ON 6 -#define RES4322_HT_PHY_AVAIL 7 -#define RES4322_OTP_PU 8 - - -#define CST4322_XTAL_FREQ_20_40MHZ 0x00000020 -#define CST4322_SPROM_OTP_SEL_MASK 0x000000c0 -#define CST4322_SPROM_OTP_SEL_SHIFT 6 -#define CST4322_NO_SPROM_OTP 0 -#define CST4322_SPROM_PRESENT 1 -#define CST4322_OTP_PRESENT 2 -#define CST4322_PCI_OR_USB 0x00000100 -#define CST4322_BOOT_MASK 0x00000600 -#define CST4322_BOOT_SHIFT 9 -#define CST4322_BOOT_FROM_SRAM 0 -#define CST4322_BOOT_FROM_ROM 1 -#define CST4322_BOOT_FROM_FLASH 2 -#define CST4322_BOOT_FROM_INVALID 3 -#define CST4322_ILP_DIV_EN 0x00000800 -#define CST4322_FLASH_TYPE_MASK 0x00001000 -#define CST4322_FLASH_TYPE_SHIFT 12 -#define CST4322_FLASH_TYPE_SHIFT_ST 0 -#define CST4322_FLASH_TYPE_SHIFT_ATMEL 1 -#define CST4322_ARM_TAP_SEL 0x00002000 -#define CST4322_RES_INIT_MODE_MASK 0x0000c000 -#define CST4322_RES_INIT_MODE_SHIFT 14 -#define CST4322_RES_INIT_MODE_ILPAVAIL 0 -#define CST4322_RES_INIT_MODE_ILPREQ 1 -#define CST4322_RES_INIT_MODE_ALPAVAIL 2 -#define CST4322_RES_INIT_MODE_HTAVAIL 3 -#define CST4322_PCIPLLCLK_GATING 0x00010000 -#define CST4322_CLK_SWITCH_PCI_TO_ALP 0x00020000 -#define CST4322_PCI_CARDBUS_MODE 0x00040000 - -#define RES4315_CBUCK_LPOM 1 -#define RES4315_CBUCK_BURST 2 -#define RES4315_CBUCK_PWM 3 -#define RES4315_CLDO_PU 4 -#define RES4315_PALDO_PU 5 -#define RES4315_ILP_REQUEST 6 -#define RES4315_LNLDO1_PU 9 -#define RES4315_OTP_PU 10 -#define RES4315_LNLDO2_PU 12 -#define RES4315_XTAL_PU 13 -#define RES4315_ALP_AVAIL 14 -#define RES4315_RX_PWRSW_PU 15 -#define RES4315_TX_PWRSW_PU 16 -#define RES4315_RFPLL_PWRSW_PU 17 -#define RES4315_LOGEN_PWRSW_PU 18 -#define RES4315_AFE_PWRSW_PU 19 -#define RES4315_BBPLL_PWRSW_PU 20 -#define RES4315_HT_AVAIL 21 - -#define CST4315_SPROM_OTP_SEL_MASK 0x00000003 -#define CST4315_DEFCIS_SEL 0x00000000 -#define CST4315_SPROM_SEL 0x00000001 -#define CST4315_OTP_SEL 0x00000002 -#define CST4315_OTP_PWRDN 0x00000003 -#define CST4315_SDIO_MODE 0x00000004 -#define CST4315_RCAL_VALID 0x00000008 -#define CST4315_RCAL_VALUE_MASK 0x000001f0 -#define CST4315_RCAL_VALUE_SHIFT 4 -#define CST4315_PALDO_EXTPNP 0x00000200 -#define CST4315_CBUCK_MODE_MASK 0x00000c00 -#define CST4315_CBUCK_MODE_BURST 0x00000400 -#define CST4315_CBUCK_MODE_LPBURST 0x00000c00 - -#define PMU_MAX_TRANSITION_DLY 15000 - - -#define PMURES_UP_TRANSITION 2 - - - - - -#define ECI_BW_20 0x0 -#define ECI_BW_25 0x1 -#define ECI_BW_30 0x2 -#define ECI_BW_35 0x3 -#define ECI_BW_40 0x4 -#define ECI_BW_45 0x5 -#define ECI_BW_50 0x6 -#define ECI_BW_ALL 0x7 - - -#define WLAN_NUM_ANT1 TXANT_0 -#define WLAN_NUM_ANT2 TXANT_1 - -#endif diff --git a/drivers/net/wireless/bcm4329/include/sbconfig.h b/drivers/net/wireless/bcm4329/include/sbconfig.h deleted file mode 100644 index da18ccbe9ab8..000000000000 --- a/drivers/net/wireless/bcm4329/include/sbconfig.h +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Broadcom SiliconBackplane hardware register definitions. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sbconfig.h,v 13.67.30.1 2008/05/07 20:17:27 Exp $ - */ - - -#ifndef _SBCONFIG_H -#define _SBCONFIG_H - - -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif - - -#define SB_BUS_SIZE 0x10000 -#define SB_BUS_BASE(b) (SI_ENUM_BASE + (b) * SB_BUS_SIZE) -#define SB_BUS_MAXCORES (SB_BUS_SIZE / SI_CORE_SIZE) - - -#define SBCONFIGOFF 0xf00 -#define SBCONFIGSIZE 256 - -#define SBIPSFLAG 0x08 -#define SBTPSFLAG 0x18 -#define SBTMERRLOGA 0x48 -#define SBTMERRLOG 0x50 -#define SBADMATCH3 0x60 -#define SBADMATCH2 0x68 -#define SBADMATCH1 0x70 -#define SBIMSTATE 0x90 -#define SBINTVEC 0x94 -#define SBTMSTATELOW 0x98 -#define SBTMSTATEHIGH 0x9c -#define SBBWA0 0xa0 -#define SBIMCONFIGLOW 0xa8 -#define SBIMCONFIGHIGH 0xac -#define SBADMATCH0 0xb0 -#define SBTMCONFIGLOW 0xb8 -#define SBTMCONFIGHIGH 0xbc -#define SBBCONFIG 0xc0 -#define SBBSTATE 0xc8 -#define SBACTCNFG 0xd8 -#define SBFLAGST 0xe8 -#define SBIDLOW 0xf8 -#define SBIDHIGH 0xfc - - - -#define SBIMERRLOGA 0xea8 -#define SBIMERRLOG 0xeb0 -#define SBTMPORTCONNID0 0xed8 -#define SBTMPORTLOCK0 0xef8 - -#ifndef _LANGUAGE_ASSEMBLY - -typedef volatile struct _sbconfig { - uint32 PAD[2]; - uint32 sbipsflag; - uint32 PAD[3]; - uint32 sbtpsflag; - uint32 PAD[11]; - uint32 sbtmerrloga; - uint32 PAD; - uint32 sbtmerrlog; - uint32 PAD[3]; - uint32 sbadmatch3; - uint32 PAD; - uint32 sbadmatch2; - uint32 PAD; - uint32 sbadmatch1; - uint32 PAD[7]; - uint32 sbimstate; - uint32 sbintvec; - uint32 sbtmstatelow; - uint32 sbtmstatehigh; - uint32 sbbwa0; - uint32 PAD; - uint32 sbimconfiglow; - uint32 sbimconfighigh; - uint32 sbadmatch0; - uint32 PAD; - uint32 sbtmconfiglow; - uint32 sbtmconfighigh; - uint32 sbbconfig; - uint32 PAD; - uint32 sbbstate; - uint32 PAD[3]; - uint32 sbactcnfg; - uint32 PAD[3]; - uint32 sbflagst; - uint32 PAD[3]; - uint32 sbidlow; - uint32 sbidhigh; -} sbconfig_t; - -#endif - - -#define SBIPS_INT1_MASK 0x3f -#define SBIPS_INT1_SHIFT 0 -#define SBIPS_INT2_MASK 0x3f00 -#define SBIPS_INT2_SHIFT 8 -#define SBIPS_INT3_MASK 0x3f0000 -#define SBIPS_INT3_SHIFT 16 -#define SBIPS_INT4_MASK 0x3f000000 -#define SBIPS_INT4_SHIFT 24 - - -#define SBTPS_NUM0_MASK 0x3f -#define SBTPS_F0EN0 0x40 - - -#define SBTMEL_CM 0x00000007 -#define SBTMEL_CI 0x0000ff00 -#define SBTMEL_EC 0x0f000000 -#define SBTMEL_ME 0x80000000 - - -#define SBIM_PC 0xf -#define SBIM_AP_MASK 0x30 -#define SBIM_AP_BOTH 0x00 -#define SBIM_AP_TS 0x10 -#define SBIM_AP_TK 0x20 -#define SBIM_AP_RSV 0x30 -#define SBIM_IBE 0x20000 -#define SBIM_TO 0x40000 -#define SBIM_BY 0x01800000 -#define SBIM_RJ 0x02000000 - - -#define SBTML_RESET 0x0001 -#define SBTML_REJ_MASK 0x0006 -#define SBTML_REJ 0x0002 -#define SBTML_TMPREJ 0x0004 - -#define SBTML_SICF_SHIFT 16 - - -#define SBTMH_SERR 0x0001 -#define SBTMH_INT 0x0002 -#define SBTMH_BUSY 0x0004 -#define SBTMH_TO 0x0020 - -#define SBTMH_SISF_SHIFT 16 - - -#define SBBWA_TAB0_MASK 0xffff -#define SBBWA_TAB1_MASK 0xffff -#define SBBWA_TAB1_SHIFT 16 - - -#define SBIMCL_STO_MASK 0x7 -#define SBIMCL_RTO_MASK 0x70 -#define SBIMCL_RTO_SHIFT 4 -#define SBIMCL_CID_MASK 0xff0000 -#define SBIMCL_CID_SHIFT 16 - - -#define SBIMCH_IEM_MASK 0xc -#define SBIMCH_TEM_MASK 0x30 -#define SBIMCH_TEM_SHIFT 4 -#define SBIMCH_BEM_MASK 0xc0 -#define SBIMCH_BEM_SHIFT 6 - - -#define SBAM_TYPE_MASK 0x3 -#define SBAM_AD64 0x4 -#define SBAM_ADINT0_MASK 0xf8 -#define SBAM_ADINT0_SHIFT 3 -#define SBAM_ADINT1_MASK 0x1f8 -#define SBAM_ADINT1_SHIFT 3 -#define SBAM_ADINT2_MASK 0x1f8 -#define SBAM_ADINT2_SHIFT 3 -#define SBAM_ADEN 0x400 -#define SBAM_ADNEG 0x800 -#define SBAM_BASE0_MASK 0xffffff00 -#define SBAM_BASE0_SHIFT 8 -#define SBAM_BASE1_MASK 0xfffff000 -#define SBAM_BASE1_SHIFT 12 -#define SBAM_BASE2_MASK 0xffff0000 -#define SBAM_BASE2_SHIFT 16 - - -#define SBTMCL_CD_MASK 0xff -#define SBTMCL_CO_MASK 0xf800 -#define SBTMCL_CO_SHIFT 11 -#define SBTMCL_IF_MASK 0xfc0000 -#define SBTMCL_IF_SHIFT 18 -#define SBTMCL_IM_MASK 0x3000000 -#define SBTMCL_IM_SHIFT 24 - - -#define SBTMCH_BM_MASK 0x3 -#define SBTMCH_RM_MASK 0x3 -#define SBTMCH_RM_SHIFT 2 -#define SBTMCH_SM_MASK 0x30 -#define SBTMCH_SM_SHIFT 4 -#define SBTMCH_EM_MASK 0x300 -#define SBTMCH_EM_SHIFT 8 -#define SBTMCH_IM_MASK 0xc00 -#define SBTMCH_IM_SHIFT 10 - - -#define SBBC_LAT_MASK 0x3 -#define SBBC_MAX0_MASK 0xf0000 -#define SBBC_MAX0_SHIFT 16 -#define SBBC_MAX1_MASK 0xf00000 -#define SBBC_MAX1_SHIFT 20 - - -#define SBBS_SRD 0x1 -#define SBBS_HRD 0x2 - - -#define SBIDL_CS_MASK 0x3 -#define SBIDL_AR_MASK 0x38 -#define SBIDL_AR_SHIFT 3 -#define SBIDL_SYNCH 0x40 -#define SBIDL_INIT 0x80 -#define SBIDL_MINLAT_MASK 0xf00 -#define SBIDL_MINLAT_SHIFT 8 -#define SBIDL_MAXLAT 0xf000 -#define SBIDL_MAXLAT_SHIFT 12 -#define SBIDL_FIRST 0x10000 -#define SBIDL_CW_MASK 0xc0000 -#define SBIDL_CW_SHIFT 18 -#define SBIDL_TP_MASK 0xf00000 -#define SBIDL_TP_SHIFT 20 -#define SBIDL_IP_MASK 0xf000000 -#define SBIDL_IP_SHIFT 24 -#define SBIDL_RV_MASK 0xf0000000 -#define SBIDL_RV_SHIFT 28 -#define SBIDL_RV_2_2 0x00000000 -#define SBIDL_RV_2_3 0x10000000 - - -#define SBIDH_RC_MASK 0x000f -#define SBIDH_RCE_MASK 0x7000 -#define SBIDH_RCE_SHIFT 8 -#define SBCOREREV(sbidh) \ - ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK)) -#define SBIDH_CC_MASK 0x8ff0 -#define SBIDH_CC_SHIFT 4 -#define SBIDH_VC_MASK 0xffff0000 -#define SBIDH_VC_SHIFT 16 - -#define SB_COMMIT 0xfd8 - - -#define SB_VEND_BCM 0x4243 - -#endif diff --git a/drivers/net/wireless/bcm4329/include/sbhnddma.h b/drivers/net/wireless/bcm4329/include/sbhnddma.h deleted file mode 100644 index 7681395f5b3b..000000000000 --- a/drivers/net/wireless/bcm4329/include/sbhnddma.h +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Generic Broadcom Home Networking Division (HND) DMA engine HW interface - * This supports the following chips: BCM42xx, 44xx, 47xx . - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sbhnddma.h,v 13.11.250.5.16.1 2009/07/21 14:04:51 Exp $ - */ - - -#ifndef _sbhnddma_h_ -#define _sbhnddma_h_ - - - - - - - -typedef volatile struct { - uint32 control; - uint32 addr; - uint32 ptr; - uint32 status; -} dma32regs_t; - -typedef volatile struct { - dma32regs_t xmt; - dma32regs_t rcv; -} dma32regp_t; - -typedef volatile struct { - uint32 fifoaddr; - uint32 fifodatalow; - uint32 fifodatahigh; - uint32 pad; -} dma32diag_t; - - -typedef volatile struct { - uint32 ctrl; - uint32 addr; -} dma32dd_t; - - -#define D32RINGALIGN_BITS 12 -#define D32MAXRINGSZ (1 << D32RINGALIGN_BITS) -#define D32RINGALIGN (1 << D32RINGALIGN_BITS) -#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t)) - - -#define XC_XE ((uint32)1 << 0) -#define XC_SE ((uint32)1 << 1) -#define XC_LE ((uint32)1 << 2) -#define XC_FL ((uint32)1 << 4) -#define XC_PD ((uint32)1 << 11) -#define XC_AE ((uint32)3 << 16) -#define XC_AE_SHIFT 16 - - -#define XP_LD_MASK 0xfff - - -#define XS_CD_MASK 0x0fff -#define XS_XS_MASK 0xf000 -#define XS_XS_SHIFT 12 -#define XS_XS_DISABLED 0x0000 -#define XS_XS_ACTIVE 0x1000 -#define XS_XS_IDLE 0x2000 -#define XS_XS_STOPPED 0x3000 -#define XS_XS_SUSP 0x4000 -#define XS_XE_MASK 0xf0000 -#define XS_XE_SHIFT 16 -#define XS_XE_NOERR 0x00000 -#define XS_XE_DPE 0x10000 -#define XS_XE_DFU 0x20000 -#define XS_XE_BEBR 0x30000 -#define XS_XE_BEDA 0x40000 -#define XS_AD_MASK 0xfff00000 -#define XS_AD_SHIFT 20 - - -#define RC_RE ((uint32)1 << 0) -#define RC_RO_MASK 0xfe -#define RC_RO_SHIFT 1 -#define RC_FM ((uint32)1 << 8) -#define RC_SH ((uint32)1 << 9) -#define RC_OC ((uint32)1 << 10) -#define RC_PD ((uint32)1 << 11) -#define RC_AE ((uint32)3 << 16) -#define RC_AE_SHIFT 16 - - -#define RP_LD_MASK 0xfff - - -#define RS_CD_MASK 0x0fff -#define RS_RS_MASK 0xf000 -#define RS_RS_SHIFT 12 -#define RS_RS_DISABLED 0x0000 -#define RS_RS_ACTIVE 0x1000 -#define RS_RS_IDLE 0x2000 -#define RS_RS_STOPPED 0x3000 -#define RS_RE_MASK 0xf0000 -#define RS_RE_SHIFT 16 -#define RS_RE_NOERR 0x00000 -#define RS_RE_DPE 0x10000 -#define RS_RE_DFO 0x20000 -#define RS_RE_BEBW 0x30000 -#define RS_RE_BEDA 0x40000 -#define RS_AD_MASK 0xfff00000 -#define RS_AD_SHIFT 20 - - -#define FA_OFF_MASK 0xffff -#define FA_SEL_MASK 0xf0000 -#define FA_SEL_SHIFT 16 -#define FA_SEL_XDD 0x00000 -#define FA_SEL_XDP 0x10000 -#define FA_SEL_RDD 0x40000 -#define FA_SEL_RDP 0x50000 -#define FA_SEL_XFD 0x80000 -#define FA_SEL_XFP 0x90000 -#define FA_SEL_RFD 0xc0000 -#define FA_SEL_RFP 0xd0000 -#define FA_SEL_RSD 0xe0000 -#define FA_SEL_RSP 0xf0000 - - -#define CTRL_BC_MASK 0x1fff -#define CTRL_AE ((uint32)3 << 16) -#define CTRL_AE_SHIFT 16 -#define CTRL_EOT ((uint32)1 << 28) -#define CTRL_IOC ((uint32)1 << 29) -#define CTRL_EOF ((uint32)1 << 30) -#define CTRL_SOF ((uint32)1 << 31) - - -#define CTRL_CORE_MASK 0x0ff00000 - - - - -typedef volatile struct { - uint32 control; - uint32 ptr; - uint32 addrlow; - uint32 addrhigh; - uint32 status0; - uint32 status1; -} dma64regs_t; - -typedef volatile struct { - dma64regs_t tx; - dma64regs_t rx; -} dma64regp_t; - -typedef volatile struct { - uint32 fifoaddr; - uint32 fifodatalow; - uint32 fifodatahigh; - uint32 pad; -} dma64diag_t; - - -typedef volatile struct { - uint32 ctrl1; - uint32 ctrl2; - uint32 addrlow; - uint32 addrhigh; -} dma64dd_t; - - -#define D64RINGALIGN_BITS 13 -#define D64MAXRINGSZ (1 << D64RINGALIGN_BITS) -#define D64RINGALIGN (1 << D64RINGALIGN_BITS) -#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) - - -#define D64_XC_XE 0x00000001 -#define D64_XC_SE 0x00000002 -#define D64_XC_LE 0x00000004 -#define D64_XC_FL 0x00000010 -#define D64_XC_PD 0x00000800 -#define D64_XC_AE 0x00030000 -#define D64_XC_AE_SHIFT 16 - - -#define D64_XP_LD_MASK 0x00000fff - - -#define D64_XS0_CD_MASK 0x00001fff -#define D64_XS0_XS_MASK 0xf0000000 -#define D64_XS0_XS_SHIFT 28 -#define D64_XS0_XS_DISABLED 0x00000000 -#define D64_XS0_XS_ACTIVE 0x10000000 -#define D64_XS0_XS_IDLE 0x20000000 -#define D64_XS0_XS_STOPPED 0x30000000 -#define D64_XS0_XS_SUSP 0x40000000 - -#define D64_XS1_AD_MASK 0x0001ffff -#define D64_XS1_XE_MASK 0xf0000000 -#define D64_XS1_XE_SHIFT 28 -#define D64_XS1_XE_NOERR 0x00000000 -#define D64_XS1_XE_DPE 0x10000000 -#define D64_XS1_XE_DFU 0x20000000 -#define D64_XS1_XE_DTE 0x30000000 -#define D64_XS1_XE_DESRE 0x40000000 -#define D64_XS1_XE_COREE 0x50000000 - - -#define D64_RC_RE 0x00000001 -#define D64_RC_RO_MASK 0x000000fe -#define D64_RC_RO_SHIFT 1 -#define D64_RC_FM 0x00000100 -#define D64_RC_SH 0x00000200 -#define D64_RC_OC 0x00000400 -#define D64_RC_PD 0x00000800 -#define D64_RC_AE 0x00030000 -#define D64_RC_AE_SHIFT 16 - - -#define D64_RP_LD_MASK 0x00000fff - - -#define D64_RS0_CD_MASK 0x00001fff -#define D64_RS0_RS_MASK 0xf0000000 -#define D64_RS0_RS_SHIFT 28 -#define D64_RS0_RS_DISABLED 0x00000000 -#define D64_RS0_RS_ACTIVE 0x10000000 -#define D64_RS0_RS_IDLE 0x20000000 -#define D64_RS0_RS_STOPPED 0x30000000 -#define D64_RS0_RS_SUSP 0x40000000 - -#define D64_RS1_AD_MASK 0x0001ffff -#define D64_RS1_RE_MASK 0xf0000000 -#define D64_RS1_RE_SHIFT 28 -#define D64_RS1_RE_NOERR 0x00000000 -#define D64_RS1_RE_DPO 0x10000000 -#define D64_RS1_RE_DFU 0x20000000 -#define D64_RS1_RE_DTE 0x30000000 -#define D64_RS1_RE_DESRE 0x40000000 -#define D64_RS1_RE_COREE 0x50000000 - - -#define D64_FA_OFF_MASK 0xffff -#define D64_FA_SEL_MASK 0xf0000 -#define D64_FA_SEL_SHIFT 16 -#define D64_FA_SEL_XDD 0x00000 -#define D64_FA_SEL_XDP 0x10000 -#define D64_FA_SEL_RDD 0x40000 -#define D64_FA_SEL_RDP 0x50000 -#define D64_FA_SEL_XFD 0x80000 -#define D64_FA_SEL_XFP 0x90000 -#define D64_FA_SEL_RFD 0xc0000 -#define D64_FA_SEL_RFP 0xd0000 -#define D64_FA_SEL_RSD 0xe0000 -#define D64_FA_SEL_RSP 0xf0000 - - -#define D64_CTRL1_EOT ((uint32)1 << 28) -#define D64_CTRL1_IOC ((uint32)1 << 29) -#define D64_CTRL1_EOF ((uint32)1 << 30) -#define D64_CTRL1_SOF ((uint32)1 << 31) - - -#define D64_CTRL2_BC_MASK 0x00007fff -#define D64_CTRL2_AE 0x00030000 -#define D64_CTRL2_AE_SHIFT 16 -#define D64_CTRL2_PARITY 0x00040000 - - -#define D64_CTRL_CORE_MASK 0x0ff00000 - - -#endif diff --git a/drivers/net/wireless/bcm4329/include/sbpcmcia.h b/drivers/net/wireless/bcm4329/include/sbpcmcia.h deleted file mode 100644 index d6d80334258a..000000000000 --- a/drivers/net/wireless/bcm4329/include/sbpcmcia.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sbpcmcia.h,v 13.31.4.1.2.3.8.7 2009/06/22 05:14:24 Exp $ - */ - - -#ifndef _SBPCMCIA_H -#define _SBPCMCIA_H - - - - -#define PCMCIA_FCR (0x700 / 2) - -#define FCR0_OFF 0 -#define FCR1_OFF (0x40 / 2) -#define FCR2_OFF (0x80 / 2) -#define FCR3_OFF (0xc0 / 2) - -#define PCMCIA_FCR0 (0x700 / 2) -#define PCMCIA_FCR1 (0x740 / 2) -#define PCMCIA_FCR2 (0x780 / 2) -#define PCMCIA_FCR3 (0x7c0 / 2) - - - -#define PCMCIA_COR 0 - -#define COR_RST 0x80 -#define COR_LEV 0x40 -#define COR_IRQEN 0x04 -#define COR_BLREN 0x01 -#define COR_FUNEN 0x01 - - -#define PCICIA_FCSR (2 / 2) -#define PCICIA_PRR (4 / 2) -#define PCICIA_SCR (6 / 2) -#define PCICIA_ESR (8 / 2) - - -#define PCM_MEMOFF 0x0000 -#define F0_MEMOFF 0x1000 -#define F1_MEMOFF 0x2000 -#define F2_MEMOFF 0x3000 -#define F3_MEMOFF 0x4000 - - -#define MEM_ADDR0 (0x728 / 2) -#define MEM_ADDR1 (0x72a / 2) -#define MEM_ADDR2 (0x72c / 2) - - -#define PCMCIA_ADDR0 (0x072e / 2) -#define PCMCIA_ADDR1 (0x0730 / 2) -#define PCMCIA_ADDR2 (0x0732 / 2) - -#define MEM_SEG (0x0734 / 2) -#define SROM_CS (0x0736 / 2) -#define SROM_DATAL (0x0738 / 2) -#define SROM_DATAH (0x073a / 2) -#define SROM_ADDRL (0x073c / 2) -#define SROM_ADDRH (0x073e / 2) -#define SROM_INFO2 (0x0772 / 2) -#define SROM_INFO (0x07be / 2) - - -#define SROM_IDLE 0 -#define SROM_WRITE 1 -#define SROM_READ 2 -#define SROM_WEN 4 -#define SROM_WDS 7 -#define SROM_DONE 8 - - -#define SRI_SZ_MASK 0x03 -#define SRI_BLANK 0x04 -#define SRI_OTP 0x80 - - - -#define SBTML_INT_ACK 0x40000 -#define SBTML_INT_EN 0x20000 - - -#define SBTMH_INT_STATUS 0x40000 - -#endif diff --git a/drivers/net/wireless/bcm4329/include/sbsdio.h b/drivers/net/wireless/bcm4329/include/sbsdio.h deleted file mode 100644 index 75aaf4d88f7d..000000000000 --- a/drivers/net/wireless/bcm4329/include/sbsdio.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * SDIO device core hardware definitions. - * sdio is a portion of the pcmcia core in core rev 3 - rev 8 - * - * SDIO core support 1bit, 4 bit SDIO mode as well as SPI mode. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sbsdio.h,v 13.29.4.1.22.3 2009/03/11 20:26:57 Exp $ - */ - -#ifndef _SBSDIO_H -#define _SBSDIO_H - -#define SBSDIO_NUM_FUNCTION 3 /* as of sdiod rev 0, supports 3 functions */ - -/* function 1 miscellaneous registers */ -#define SBSDIO_SPROM_CS 0x10000 /* sprom command and status */ -#define SBSDIO_SPROM_INFO 0x10001 /* sprom info register */ -#define SBSDIO_SPROM_DATA_LOW 0x10002 /* sprom indirect access data byte 0 */ -#define SBSDIO_SPROM_DATA_HIGH 0x10003 /* sprom indirect access data byte 1 */ -#define SBSDIO_SPROM_ADDR_LOW 0x10004 /* sprom indirect access addr byte 0 */ -#define SBSDIO_SPROM_ADDR_HIGH 0x10005 /* sprom indirect access addr byte 0 */ -#define SBSDIO_CHIP_CTRL_DATA 0x10006 /* xtal_pu (gpio) output */ -#define SBSDIO_CHIP_CTRL_EN 0x10007 /* xtal_pu (gpio) enable */ -#define SBSDIO_WATERMARK 0x10008 /* rev < 7, watermark for sdio device */ -#define SBSDIO_DEVICE_CTL 0x10009 /* control busy signal generation */ - -/* registers introduced in rev 8, some content (mask/bits) defs in sbsdpcmdev.h */ -#define SBSDIO_FUNC1_SBADDRLOW 0x1000A /* SB Address Window Low (b15) */ -#define SBSDIO_FUNC1_SBADDRMID 0x1000B /* SB Address Window Mid (b23:b16) */ -#define SBSDIO_FUNC1_SBADDRHIGH 0x1000C /* SB Address Window High (b31:b24) */ -#define SBSDIO_FUNC1_FRAMECTRL 0x1000D /* Frame Control (frame term/abort) */ -#define SBSDIO_FUNC1_CHIPCLKCSR 0x1000E /* ChipClockCSR (ALP/HT ctl/status) */ -#define SBSDIO_FUNC1_SDIOPULLUP 0x1000F /* SdioPullUp (on cmd, d0-d2) */ -#define SBSDIO_FUNC1_WFRAMEBCLO 0x10019 /* Write Frame Byte Count Low */ -#define SBSDIO_FUNC1_WFRAMEBCHI 0x1001A /* Write Frame Byte Count High */ -#define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B /* Read Frame Byte Count Low */ -#define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C /* Read Frame Byte Count High */ - -#define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */ -#define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001C /* f1 misc register end */ - -/* SBSDIO_SPROM_CS */ -#define SBSDIO_SPROM_IDLE 0 -#define SBSDIO_SPROM_WRITE 1 -#define SBSDIO_SPROM_READ 2 -#define SBSDIO_SPROM_WEN 4 -#define SBSDIO_SPROM_WDS 7 -#define SBSDIO_SPROM_DONE 8 - -/* SBSDIO_SPROM_INFO */ -#define SROM_SZ_MASK 0x03 /* SROM size, 1: 4k, 2: 16k */ -#define SROM_BLANK 0x04 /* depreciated in corerev 6 */ -#define SROM_OTP 0x80 /* OTP present */ - -/* SBSDIO_CHIP_CTRL */ -#define SBSDIO_CHIP_CTRL_XTAL 0x01 /* or'd with onchip xtal_pu, - * 1: power on oscillator - * (for 4318 only) - */ -/* SBSDIO_WATERMARK */ -#define SBSDIO_WATERMARK_MASK 0x7f /* number of words - 1 for sd device - * to wait before sending data to host - */ - -/* SBSDIO_DEVICE_CTL */ -#define SBSDIO_DEVCTL_SETBUSY 0x01 /* 1: device will assert busy signal when - * receiving CMD53 - */ -#define SBSDIO_DEVCTL_SPI_INTR_SYNC 0x02 /* 1: assertion of sdio interrupt is - * synchronous to the sdio clock - */ -#define SBSDIO_DEVCTL_CA_INT_ONLY 0x04 /* 1: mask all interrupts to host - * except the chipActive (rev 8) - */ -#define SBSDIO_DEVCTL_PADS_ISO 0x08 /* 1: isolate internal sdio signals, put - * external pads in tri-state; requires - * sdio bus power cycle to clear (rev 9) - */ -#define SBSDIO_DEVCTL_SB_RST_CTL 0x30 /* Force SD->SB reset mapping (rev 11) */ -#define SBSDIO_DEVCTL_RST_CORECTL 0x00 /* Determined by CoreControl bit */ -#define SBSDIO_DEVCTL_RST_BPRESET 0x10 /* Force backplane reset */ -#define SBSDIO_DEVCTL_RST_NOBPRESET 0x20 /* Force no backplane reset */ - - -/* SBSDIO_FUNC1_CHIPCLKCSR */ -#define SBSDIO_FORCE_ALP 0x01 /* Force ALP request to backplane */ -#define SBSDIO_FORCE_HT 0x02 /* Force HT request to backplane */ -#define SBSDIO_FORCE_ILP 0x04 /* Force ILP request to backplane */ -#define SBSDIO_ALP_AVAIL_REQ 0x08 /* Make ALP ready (power up xtal) */ -#define SBSDIO_HT_AVAIL_REQ 0x10 /* Make HT ready (power up PLL) */ -#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20 /* Squelch clock requests from HW */ -#define SBSDIO_ALP_AVAIL 0x40 /* Status: ALP is ready */ -#define SBSDIO_HT_AVAIL 0x80 /* Status: HT is ready */ -/* In rev8, actual avail bits followed original docs */ -#define SBSDIO_Rev8_HT_AVAIL 0x40 -#define SBSDIO_Rev8_ALP_AVAIL 0x80 - -#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL) -#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS) -#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS) -#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval)) -#define SBSDIO_CLKAV(regval, alponly) (SBSDIO_ALPAV(regval) && \ - (alponly ? 1 : SBSDIO_HTAV(regval))) - -/* SBSDIO_FUNC1_SDIOPULLUP */ -#define SBSDIO_PULLUP_D0 0x01 /* Enable D0/MISO pullup */ -#define SBSDIO_PULLUP_D1 0x02 /* Enable D1/INT# pullup */ -#define SBSDIO_PULLUP_D2 0x04 /* Enable D2 pullup */ -#define SBSDIO_PULLUP_CMD 0x08 /* Enable CMD/MOSI pullup */ -#define SBSDIO_PULLUP_ALL 0x0f /* All valid bits */ - -/* function 1 OCP space */ -#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF /* sb offset addr is <= 15 bits, 32k */ -#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000 -#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 /* with b15, maps to 32-bit SB access */ - -/* some duplication with sbsdpcmdev.h here */ -/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */ -#define SBSDIO_SBADDRLOW_MASK 0x80 /* Valid bits in SBADDRLOW */ -#define SBSDIO_SBADDRMID_MASK 0xff /* Valid bits in SBADDRMID */ -#define SBSDIO_SBADDRHIGH_MASK 0xffU /* Valid bits in SBADDRHIGH */ -#define SBSDIO_SBWINDOW_MASK 0xffff8000 /* Address bits from SBADDR regs */ - -/* direct(mapped) cis space */ -#define SBSDIO_CIS_BASE_COMMON 0x1000 /* MAPPED common CIS address */ -#define SBSDIO_CIS_SIZE_LIMIT 0x200 /* maximum bytes in one CIS */ -#define SBSDIO_OTP_CIS_SIZE_LIMIT 0x078 /* maximum bytes OTP CIS */ - -#define SBSDIO_CIS_OFT_ADDR_MASK 0x1FFFF /* cis offset addr is < 17 bits */ - -#define SBSDIO_CIS_MANFID_TUPLE_LEN 6 /* manfid tuple length, include tuple, - * link bytes - */ - -/* indirect cis access (in sprom) */ -#define SBSDIO_SPROM_CIS_OFFSET 0x8 /* 8 control bytes first, CIS starts from - * 8th byte - */ - -#define SBSDIO_BYTEMODE_DATALEN_MAX 64 /* sdio byte mode: maximum length of one - * data comamnd - */ - -#define SBSDIO_CORE_ADDR_MASK 0x1FFFF /* sdio core function one address mask */ - -#endif /* _SBSDIO_H */ diff --git a/drivers/net/wireless/bcm4329/include/sbsdpcmdev.h b/drivers/net/wireless/bcm4329/include/sbsdpcmdev.h deleted file mode 100644 index 7c7c7e4de0f6..000000000000 --- a/drivers/net/wireless/bcm4329/include/sbsdpcmdev.h +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Broadcom SiliconBackplane SDIO/PCMCIA hardware-specific device core support - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sbsdpcmdev.h,v 13.29.4.1.4.6.6.2 2008/12/31 21:16:51 Exp $ - */ - -#ifndef _sbsdpcmdev_h_ -#define _sbsdpcmdev_h_ - -/* cpp contortions to concatenate w/arg prescan */ -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif /* PAD */ - - -typedef volatile struct { - dma64regs_t xmt; /* dma tx */ - uint32 PAD[2]; - dma64regs_t rcv; /* dma rx */ - uint32 PAD[2]; -} dma64p_t; - -/* dma64 sdiod corerev >= 1 */ -typedef volatile struct { - dma64p_t dma64regs[2]; - dma64diag_t dmafifo; /* DMA Diagnostic Regs, 0x280-0x28c */ - uint32 PAD[92]; -} sdiodma64_t; - -/* dma32 sdiod corerev == 0 */ -typedef volatile struct { - dma32regp_t dma32regs[2]; /* dma tx & rx, 0x200-0x23c */ - dma32diag_t dmafifo; /* DMA Diagnostic Regs, 0x240-0x24c */ - uint32 PAD[108]; -} sdiodma32_t; - -/* dma32 regs for pcmcia core */ -typedef volatile struct { - dma32regp_t dmaregs; /* DMA Regs, 0x200-0x21c, rev8 */ - dma32diag_t dmafifo; /* DMA Diagnostic Regs, 0x220-0x22c */ - uint32 PAD[116]; -} pcmdma32_t; - -/* core registers */ -typedef volatile struct { - uint32 corecontrol; /* CoreControl, 0x000, rev8 */ - uint32 corestatus; /* CoreStatus, 0x004, rev8 */ - uint32 PAD[1]; - uint32 biststatus; /* BistStatus, 0x00c, rev8 */ - - /* PCMCIA access */ - uint16 pcmciamesportaladdr; /* PcmciaMesPortalAddr, 0x010, rev8 */ - uint16 PAD[1]; - uint16 pcmciamesportalmask; /* PcmciaMesPortalMask, 0x014, rev8 */ - uint16 PAD[1]; - uint16 pcmciawrframebc; /* PcmciaWrFrameBC, 0x018, rev8 */ - uint16 PAD[1]; - uint16 pcmciaunderflowtimer; /* PcmciaUnderflowTimer, 0x01c, rev8 */ - uint16 PAD[1]; - - /* interrupt */ - uint32 intstatus; /* IntStatus, 0x020, rev8 */ - uint32 hostintmask; /* IntHostMask, 0x024, rev8 */ - uint32 intmask; /* IntSbMask, 0x028, rev8 */ - uint32 sbintstatus; /* SBIntStatus, 0x02c, rev8 */ - uint32 sbintmask; /* SBIntMask, 0x030, rev8 */ - uint32 PAD[3]; - uint32 tosbmailbox; /* ToSBMailbox, 0x040, rev8 */ - uint32 tohostmailbox; /* ToHostMailbox, 0x044, rev8 */ - uint32 tosbmailboxdata; /* ToSbMailboxData, 0x048, rev8 */ - uint32 tohostmailboxdata; /* ToHostMailboxData, 0x04c, rev8 */ - - /* synchronized access to registers in SDIO clock domain */ - uint32 sdioaccess; /* SdioAccess, 0x050, rev8 */ - uint32 PAD[3]; - - /* PCMCIA frame control */ - uint8 pcmciaframectrl; /* pcmciaFrameCtrl, 0x060, rev8 */ - uint8 PAD[3]; - uint8 pcmciawatermark; /* pcmciaWaterMark, 0x064, rev8 */ - uint8 PAD[155]; - - /* interrupt batching control */ - uint32 intrcvlazy; /* IntRcvLazy, 0x100, rev8 */ - uint32 PAD[3]; - - /* counters */ - uint32 cmd52rd; /* Cmd52RdCount, 0x110, rev8, SDIO: cmd52 reads */ - uint32 cmd52wr; /* Cmd52WrCount, 0x114, rev8, SDIO: cmd52 writes */ - uint32 cmd53rd; /* Cmd53RdCount, 0x118, rev8, SDIO: cmd53 reads */ - uint32 cmd53wr; /* Cmd53WrCount, 0x11c, rev8, SDIO: cmd53 writes */ - uint32 abort; /* AbortCount, 0x120, rev8, SDIO: aborts */ - uint32 datacrcerror; /* DataCrcErrorCount, 0x124, rev8, SDIO: frames w/bad CRC */ - uint32 rdoutofsync; /* RdOutOfSyncCount, 0x128, rev8, SDIO/PCMCIA: Rd Frm OOS */ - uint32 wroutofsync; /* RdOutOfSyncCount, 0x12c, rev8, SDIO/PCMCIA: Wr Frm OOS */ - uint32 writebusy; /* WriteBusyCount, 0x130, rev8, SDIO: dev asserted "busy" */ - uint32 readwait; /* ReadWaitCount, 0x134, rev8, SDIO: read: no data avail */ - uint32 readterm; /* ReadTermCount, 0x138, rev8, SDIO: rd frm terminates */ - uint32 writeterm; /* WriteTermCount, 0x13c, rev8, SDIO: wr frm terminates */ - uint32 PAD[40]; - uint32 clockctlstatus; /* ClockCtlStatus, 0x1e0, rev8 */ - uint32 PAD[7]; - - /* DMA engines */ - volatile union { - pcmdma32_t pcm32; - sdiodma32_t sdiod32; - sdiodma64_t sdiod64; - } dma; - - /* SDIO/PCMCIA CIS region */ - char cis[512]; /* 512 byte CIS, 0x400-0x5ff, rev6 */ - - /* PCMCIA function control registers */ - char pcmciafcr[256]; /* PCMCIA FCR, 0x600-6ff, rev6 */ - uint16 PAD[55]; - - /* PCMCIA backplane access */ - uint16 backplanecsr; /* BackplaneCSR, 0x76E, rev6 */ - uint16 backplaneaddr0; /* BackplaneAddr0, 0x770, rev6 */ - uint16 backplaneaddr1; /* BackplaneAddr1, 0x772, rev6 */ - uint16 backplaneaddr2; /* BackplaneAddr2, 0x774, rev6 */ - uint16 backplaneaddr3; /* BackplaneAddr3, 0x776, rev6 */ - uint16 backplanedata0; /* BackplaneData0, 0x778, rev6 */ - uint16 backplanedata1; /* BackplaneData1, 0x77a, rev6 */ - uint16 backplanedata2; /* BackplaneData2, 0x77c, rev6 */ - uint16 backplanedata3; /* BackplaneData3, 0x77e, rev6 */ - uint16 PAD[31]; - - /* sprom "size" & "blank" info */ - uint16 spromstatus; /* SPROMStatus, 0x7BE, rev2 */ - uint32 PAD[464]; - - /* Sonics SiliconBackplane registers */ - sbconfig_t sbconfig; /* SbConfig Regs, 0xf00-0xfff, rev8 */ -} sdpcmd_regs_t; - -/* corecontrol */ -#define CC_CISRDY (1 << 0) /* CIS Ready */ -#define CC_BPRESEN (1 << 1) /* CCCR RES signal causes backplane reset */ -#define CC_F2RDY (1 << 2) /* set CCCR IOR2 bit */ -#define CC_CLRPADSISO (1 << 3) /* clear SDIO pads isolation bit (rev 11) */ - -/* corestatus */ -#define CS_PCMCIAMODE (1 << 0) /* Device Mode; 0=SDIO, 1=PCMCIA */ -#define CS_SMARTDEV (1 << 1) /* 1=smartDev enabled */ -#define CS_F2ENABLED (1 << 2) /* 1=host has enabled the device */ - -#define PCMCIA_MES_PA_MASK 0x7fff /* PCMCIA Message Portal Address Mask */ -#define PCMCIA_MES_PM_MASK 0x7fff /* PCMCIA Message Portal Mask Mask */ -#define PCMCIA_WFBC_MASK 0xffff /* PCMCIA Write Frame Byte Count Mask */ -#define PCMCIA_UT_MASK 0x07ff /* PCMCIA Underflow Timer Mask */ - -/* intstatus */ -#define I_SMB_SW0 (1 << 0) /* To SB Mail S/W interrupt 0 */ -#define I_SMB_SW1 (1 << 1) /* To SB Mail S/W interrupt 1 */ -#define I_SMB_SW2 (1 << 2) /* To SB Mail S/W interrupt 2 */ -#define I_SMB_SW3 (1 << 3) /* To SB Mail S/W interrupt 3 */ -#define I_SMB_SW_MASK 0x0000000f /* To SB Mail S/W interrupts mask */ -#define I_SMB_SW_SHIFT 0 /* To SB Mail S/W interrupts shift */ -#define I_HMB_SW0 (1 << 4) /* To Host Mail S/W interrupt 0 */ -#define I_HMB_SW1 (1 << 5) /* To Host Mail S/W interrupt 1 */ -#define I_HMB_SW2 (1 << 6) /* To Host Mail S/W interrupt 2 */ -#define I_HMB_SW3 (1 << 7) /* To Host Mail S/W interrupt 3 */ -#define I_HMB_SW_MASK 0x000000f0 /* To Host Mail S/W interrupts mask */ -#define I_HMB_SW_SHIFT 4 /* To Host Mail S/W interrupts shift */ -#define I_WR_OOSYNC (1 << 8) /* Write Frame Out Of Sync */ -#define I_RD_OOSYNC (1 << 9) /* Read Frame Out Of Sync */ -#define I_PC (1 << 10) /* descriptor error */ -#define I_PD (1 << 11) /* data error */ -#define I_DE (1 << 12) /* Descriptor protocol Error */ -#define I_RU (1 << 13) /* Receive descriptor Underflow */ -#define I_RO (1 << 14) /* Receive fifo Overflow */ -#define I_XU (1 << 15) /* Transmit fifo Underflow */ -#define I_RI (1 << 16) /* Receive Interrupt */ -#define I_BUSPWR (1 << 17) /* SDIO Bus Power Change (rev 9) */ -#define I_XI (1 << 24) /* Transmit Interrupt */ -#define I_RF_TERM (1 << 25) /* Read Frame Terminate */ -#define I_WF_TERM (1 << 26) /* Write Frame Terminate */ -#define I_PCMCIA_XU (1 << 27) /* PCMCIA Transmit FIFO Underflow */ -#define I_SBINT (1 << 28) /* sbintstatus Interrupt */ -#define I_CHIPACTIVE (1 << 29) /* chip transitioned from doze to active state */ -#define I_SRESET (1 << 30) /* CCCR RES interrupt */ -#define I_IOE2 (1U << 31) /* CCCR IOE2 Bit Changed */ -#define I_ERRORS (I_PC | I_PD | I_DE | I_RU | I_RO | I_XU) /* DMA Errors */ -#define I_DMA (I_RI | I_XI | I_ERRORS) - -/* sbintstatus */ -#define I_SB_SERR (1 << 8) /* Backplane SError (write) */ -#define I_SB_RESPERR (1 << 9) /* Backplane Response Error (read) */ -#define I_SB_SPROMERR (1 << 10) /* Error accessing the sprom */ - -/* sdioaccess */ -#define SDA_DATA_MASK 0x000000ff /* Read/Write Data Mask */ -#define SDA_ADDR_MASK 0x000fff00 /* Read/Write Address Mask */ -#define SDA_ADDR_SHIFT 8 /* Read/Write Address Shift */ -#define SDA_WRITE 0x01000000 /* Write bit */ -#define SDA_READ 0x00000000 /* Write bit cleared for Read */ -#define SDA_BUSY 0x80000000 /* Busy bit */ - -/* sdioaccess-accessible register address spaces */ -#define SDA_CCCR_SPACE 0x000 /* sdioAccess CCCR register space */ -#define SDA_F1_FBR_SPACE 0x100 /* sdioAccess F1 FBR register space */ -#define SDA_F2_FBR_SPACE 0x200 /* sdioAccess F2 FBR register space */ -#define SDA_F1_REG_SPACE 0x300 /* sdioAccess F1 core-specific register space */ - -/* SDA_F1_REG_SPACE sdioaccess-accessible F1 reg space register offsets */ -#define SDA_CHIPCONTROLDATA 0x006 /* ChipControlData */ -#define SDA_CHIPCONTROLENAB 0x007 /* ChipControlEnable */ -#define SDA_F2WATERMARK 0x008 /* Function 2 Watermark */ -#define SDA_DEVICECONTROL 0x009 /* DeviceControl */ -#define SDA_SBADDRLOW 0x00a /* SbAddrLow */ -#define SDA_SBADDRMID 0x00b /* SbAddrMid */ -#define SDA_SBADDRHIGH 0x00c /* SbAddrHigh */ -#define SDA_FRAMECTRL 0x00d /* FrameCtrl */ -#define SDA_CHIPCLOCKCSR 0x00e /* ChipClockCSR */ -#define SDA_SDIOPULLUP 0x00f /* SdioPullUp */ -#define SDA_SDIOWRFRAMEBCLOW 0x019 /* SdioWrFrameBCLow */ -#define SDA_SDIOWRFRAMEBCHIGH 0x01a /* SdioWrFrameBCHigh */ -#define SDA_SDIORDFRAMEBCLOW 0x01b /* SdioRdFrameBCLow */ -#define SDA_SDIORDFRAMEBCHIGH 0x01c /* SdioRdFrameBCHigh */ - -/* SDA_F2WATERMARK */ -#define SDA_F2WATERMARK_MASK 0x7f /* F2Watermark Mask */ - -/* SDA_SBADDRLOW */ -#define SDA_SBADDRLOW_MASK 0x80 /* SbAddrLow Mask */ - -/* SDA_SBADDRMID */ -#define SDA_SBADDRMID_MASK 0xff /* SbAddrMid Mask */ - -/* SDA_SBADDRHIGH */ -#define SDA_SBADDRHIGH_MASK 0xff /* SbAddrHigh Mask */ - -/* SDA_FRAMECTRL */ -#define SFC_RF_TERM (1 << 0) /* Read Frame Terminate */ -#define SFC_WF_TERM (1 << 1) /* Write Frame Terminate */ -#define SFC_CRC4WOOS (1 << 2) /* HW reports CRC error for write out of sync */ -#define SFC_ABORTALL (1 << 3) /* Abort cancels all in-progress frames */ - -/* pcmciaframectrl */ -#define PFC_RF_TERM (1 << 0) /* Read Frame Terminate */ -#define PFC_WF_TERM (1 << 1) /* Write Frame Terminate */ - -/* intrcvlazy */ -#define IRL_TO_MASK 0x00ffffff /* timeout */ -#define IRL_FC_MASK 0xff000000 /* frame count */ -#define IRL_FC_SHIFT 24 /* frame count */ - -/* rx header */ -typedef volatile struct { - uint16 len; - uint16 flags; -} sdpcmd_rxh_t; - -/* rx header flags */ -#define RXF_CRC 0x0001 /* CRC error detected */ -#define RXF_WOOS 0x0002 /* write frame out of sync */ -#define RXF_WF_TERM 0x0004 /* write frame terminated */ -#define RXF_ABORT 0x0008 /* write frame aborted */ -#define RXF_DISCARD (RXF_CRC | RXF_WOOS | RXF_WF_TERM | RXF_ABORT) /* bad frame */ - -/* HW frame tag */ -#define SDPCM_FRAMETAG_LEN 4 /* HW frametag: 2 bytes len, 2 bytes check val */ - -#endif /* _sbsdpcmdev_h_ */ diff --git a/drivers/net/wireless/bcm4329/include/sbsocram.h b/drivers/net/wireless/bcm4329/include/sbsocram.h deleted file mode 100644 index 5ede0b66d97f..000000000000 --- a/drivers/net/wireless/bcm4329/include/sbsocram.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * BCM47XX Sonics SiliconBackplane embedded ram core - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sbsocram.h,v 13.9.162.2 2008/12/12 14:13:27 Exp $ - */ - - -#ifndef _SBSOCRAM_H -#define _SBSOCRAM_H - -#ifndef _LANGUAGE_ASSEMBLY - - -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif - - -typedef volatile struct sbsocramregs { - uint32 coreinfo; - uint32 bwalloc; - uint32 extracoreinfo; - uint32 biststat; - uint32 bankidx; - uint32 standbyctrl; - - uint32 errlogstatus; - uint32 errlogaddr; - - uint32 cambankidx; - uint32 cambankstandbyctrl; - uint32 cambankpatchctrl; - uint32 cambankpatchtblbaseaddr; - uint32 cambankcmdreg; - uint32 cambankdatareg; - uint32 cambankmaskreg; - uint32 PAD[17]; - uint32 extmemconfig; - uint32 extmemparitycsr; - uint32 extmemparityerrdata; - uint32 extmemparityerrcnt; - uint32 extmemwrctrlandsize; - uint32 PAD[84]; - uint32 workaround; - uint32 pwrctl; -} sbsocramregs_t; - -#endif - - -#define SR_COREINFO 0x00 -#define SR_BWALLOC 0x04 -#define SR_BISTSTAT 0x0c -#define SR_BANKINDEX 0x10 -#define SR_BANKSTBYCTL 0x14 -#define SR_PWRCTL 0x1e8 - - -#define SRCI_PT_MASK 0x00070000 -#define SRCI_PT_SHIFT 16 - -#define SRCI_PT_OCP_OCP 0 -#define SRCI_PT_AXI_OCP 1 -#define SRCI_PT_ARM7AHB_OCP 2 -#define SRCI_PT_CM3AHB_OCP 3 -#define SRCI_PT_AXI_AXI 4 -#define SRCI_PT_AHB_AXI 5 - -#define SRCI_LSS_MASK 0x00f00000 -#define SRCI_LSS_SHIFT 20 -#define SRCI_LRS_MASK 0x0f000000 -#define SRCI_LRS_SHIFT 24 - - -#define SRCI_MS0_MASK 0xf -#define SR_MS0_BASE 16 - - -#define SRCI_ROMNB_MASK 0xf000 -#define SRCI_ROMNB_SHIFT 12 -#define SRCI_ROMBSZ_MASK 0xf00 -#define SRCI_ROMBSZ_SHIFT 8 -#define SRCI_SRNB_MASK 0xf0 -#define SRCI_SRNB_SHIFT 4 -#define SRCI_SRBSZ_MASK 0xf -#define SRCI_SRBSZ_SHIFT 0 - -#define SR_BSZ_BASE 14 - - -#define SRSC_SBYOVR_MASK 0x80000000 -#define SRSC_SBYOVR_SHIFT 31 -#define SRSC_SBYOVRVAL_MASK 0x60000000 -#define SRSC_SBYOVRVAL_SHIFT 29 -#define SRSC_SBYEN_MASK 0x01000000 -#define SRSC_SBYEN_SHIFT 24 - - -#define SRPC_PMU_STBYDIS_MASK 0x00000010 -#define SRPC_PMU_STBYDIS_SHIFT 4 -#define SRPC_STBYOVRVAL_MASK 0x00000008 -#define SRPC_STBYOVRVAL_SHIFT 3 -#define SRPC_STBYOVR_MASK 0x00000007 -#define SRPC_STBYOVR_SHIFT 0 - - -#define SRECC_NUM_BANKS_MASK 0x000000F0 -#define SRECC_NUM_BANKS_SHIFT 4 -#define SRECC_BANKSIZE_MASK 0x0000000F -#define SRECC_BANKSIZE_SHIFT 0 - -#define SRECC_BANKSIZE(value) (1 << (value)) - - -#define SRCBPC_PATCHENABLE 0x80000000 - -#define SRP_ADDRESS 0x0001FFFC -#define SRP_VALID 0x8000 - - -#define SRCMD_WRITE 0x00020000 -#define SRCMD_READ 0x00010000 -#define SRCMD_DONE 0x80000000 - -#define SRCMD_DONE_DLY 1000 - - -#endif diff --git a/drivers/net/wireless/bcm4329/include/sdio.h b/drivers/net/wireless/bcm4329/include/sdio.h deleted file mode 100644 index 280cb845fb04..000000000000 --- a/drivers/net/wireless/bcm4329/include/sdio.h +++ /dev/null @@ -1,566 +0,0 @@ -/* - * SDIO spec header file - * Protocol and standard (common) device definitions - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sdio.h,v 13.24.4.1.4.1.16.1 2009/08/12 01:08:02 Exp $ - */ - -#ifndef _SDIO_H -#define _SDIO_H - - -/* CCCR structure for function 0 */ -typedef volatile struct { - uint8 cccr_sdio_rev; /* RO, cccr and sdio revision */ - uint8 sd_rev; /* RO, sd spec revision */ - uint8 io_en; /* I/O enable */ - uint8 io_rdy; /* I/O ready reg */ - uint8 intr_ctl; /* Master and per function interrupt enable control */ - uint8 intr_status; /* RO, interrupt pending status */ - uint8 io_abort; /* read/write abort or reset all functions */ - uint8 bus_inter; /* bus interface control */ - uint8 capability; /* RO, card capability */ - - uint8 cis_base_low; /* 0x9 RO, common CIS base address, LSB */ - uint8 cis_base_mid; - uint8 cis_base_high; /* 0xB RO, common CIS base address, MSB */ - - /* suspend/resume registers */ - uint8 bus_suspend; /* 0xC */ - uint8 func_select; /* 0xD */ - uint8 exec_flag; /* 0xE */ - uint8 ready_flag; /* 0xF */ - - uint8 fn0_blk_size[2]; /* 0x10(LSB), 0x11(MSB) */ - - uint8 power_control; /* 0x12 (SDIO version 1.10) */ - - uint8 speed_control; /* 0x13 */ -} sdio_regs_t; - -/* SDIO Device CCCR offsets */ -#define SDIOD_CCCR_REV 0x00 -#define SDIOD_CCCR_SDREV 0x01 -#define SDIOD_CCCR_IOEN 0x02 -#define SDIOD_CCCR_IORDY 0x03 -#define SDIOD_CCCR_INTEN 0x04 -#define SDIOD_CCCR_INTPEND 0x05 -#define SDIOD_CCCR_IOABORT 0x06 -#define SDIOD_CCCR_BICTRL 0x07 -#define SDIOD_CCCR_CAPABLITIES 0x08 -#define SDIOD_CCCR_CISPTR_0 0x09 -#define SDIOD_CCCR_CISPTR_1 0x0A -#define SDIOD_CCCR_CISPTR_2 0x0B -#define SDIOD_CCCR_BUSSUSP 0x0C -#define SDIOD_CCCR_FUNCSEL 0x0D -#define SDIOD_CCCR_EXECFLAGS 0x0E -#define SDIOD_CCCR_RDYFLAGS 0x0F -#define SDIOD_CCCR_BLKSIZE_0 0x10 -#define SDIOD_CCCR_BLKSIZE_1 0x11 -#define SDIOD_CCCR_POWER_CONTROL 0x12 -#define SDIOD_CCCR_SPEED_CONTROL 0x13 - -/* Broadcom extensions (corerev >= 1) */ -#define SDIOD_CCCR_BRCM_SEPINT 0xf2 - -/* cccr_sdio_rev */ -#define SDIO_REV_SDIOID_MASK 0xf0 /* SDIO spec revision number */ -#define SDIO_REV_CCCRID_MASK 0x0f /* CCCR format version number */ - -/* sd_rev */ -#define SD_REV_PHY_MASK 0x0f /* SD format version number */ - -/* io_en */ -#define SDIO_FUNC_ENABLE_1 0x02 /* function 1 I/O enable */ -#define SDIO_FUNC_ENABLE_2 0x04 /* function 2 I/O enable */ - -/* io_rdys */ -#define SDIO_FUNC_READY_1 0x02 /* function 1 I/O ready */ -#define SDIO_FUNC_READY_2 0x04 /* function 2 I/O ready */ - -/* intr_ctl */ -#define INTR_CTL_MASTER_EN 0x1 /* interrupt enable master */ -#define INTR_CTL_FUNC1_EN 0x2 /* interrupt enable for function 1 */ -#define INTR_CTL_FUNC2_EN 0x4 /* interrupt enable for function 2 */ - -/* intr_status */ -#define INTR_STATUS_FUNC1 0x2 /* interrupt pending for function 1 */ -#define INTR_STATUS_FUNC2 0x4 /* interrupt pending for function 2 */ - -/* io_abort */ -#define IO_ABORT_RESET_ALL 0x08 /* I/O card reset */ -#define IO_ABORT_FUNC_MASK 0x07 /* abort selction: function x */ - -/* bus_inter */ -#define BUS_CARD_DETECT_DIS 0x80 /* Card Detect disable */ -#define BUS_SPI_CONT_INTR_CAP 0x40 /* support continuous SPI interrupt */ -#define BUS_SPI_CONT_INTR_EN 0x20 /* continuous SPI interrupt enable */ -#define BUS_SD_DATA_WIDTH_MASK 0x03 /* bus width mask */ -#define BUS_SD_DATA_WIDTH_4BIT 0x02 /* bus width 4-bit mode */ -#define BUS_SD_DATA_WIDTH_1BIT 0x00 /* bus width 1-bit mode */ - -/* capability */ -#define SDIO_CAP_4BLS 0x80 /* 4-bit support for low speed card */ -#define SDIO_CAP_LSC 0x40 /* low speed card */ -#define SDIO_CAP_E4MI 0x20 /* enable interrupt between block of data in 4-bit mode */ -#define SDIO_CAP_S4MI 0x10 /* support interrupt between block of data in 4-bit mode */ -#define SDIO_CAP_SBS 0x08 /* support suspend/resume */ -#define SDIO_CAP_SRW 0x04 /* support read wait */ -#define SDIO_CAP_SMB 0x02 /* support multi-block transfer */ -#define SDIO_CAP_SDC 0x01 /* Support Direct commands during multi-byte transfer */ - -/* power_control */ -#define SDIO_POWER_SMPC 0x01 /* supports master power control (RO) */ -#define SDIO_POWER_EMPC 0x02 /* enable master power control (allow > 200mA) (RW) */ - -/* speed_control (control device entry into high-speed clocking mode) */ -#define SDIO_SPEED_SHS 0x01 /* supports high-speed [clocking] mode (RO) */ -#define SDIO_SPEED_EHS 0x02 /* enable high-speed [clocking] mode (RW) */ - -/* brcm sepint */ -#define SDIO_SEPINT_MASK 0x01 /* route sdpcmdev intr onto separate pad (chip-specific) */ -#define SDIO_SEPINT_OE 0x02 /* 1 asserts output enable for above pad */ -#define SDIO_SEPINT_ACT_HI 0x04 /* use active high interrupt level instead of active low */ - -/* FBR structure for function 1-7, FBR addresses and register offsets */ -typedef volatile struct { - uint8 devctr; /* device interface, CSA control */ - uint8 ext_dev; /* extended standard I/O device type code */ - uint8 pwr_sel; /* power selection support */ - uint8 PAD[6]; /* reserved */ - - uint8 cis_low; /* CIS LSB */ - uint8 cis_mid; - uint8 cis_high; /* CIS MSB */ - uint8 csa_low; /* code storage area, LSB */ - uint8 csa_mid; - uint8 csa_high; /* code storage area, MSB */ - uint8 csa_dat_win; /* data access window to function */ - - uint8 fnx_blk_size[2]; /* block size, little endian */ -} sdio_fbr_t; - -/* Maximum number of I/O funcs */ -#define SDIOD_MAX_IOFUNCS 7 - -/* SDIO Device FBR Start Address */ -#define SDIOD_FBR_STARTADDR 0x100 - -/* SDIO Device FBR Size */ -#define SDIOD_FBR_SIZE 0x100 - -/* Macro to calculate FBR register base */ -#define SDIOD_FBR_BASE(n) ((n) * 0x100) - -/* Function register offsets */ -#define SDIOD_FBR_DEVCTR 0x00 /* basic info for function */ -#define SDIOD_FBR_EXT_DEV 0x01 /* extended I/O device code */ -#define SDIOD_FBR_PWR_SEL 0x02 /* power selection bits */ - -/* SDIO Function CIS ptr offset */ -#define SDIOD_FBR_CISPTR_0 0x09 -#define SDIOD_FBR_CISPTR_1 0x0A -#define SDIOD_FBR_CISPTR_2 0x0B - -/* Code Storage Area pointer */ -#define SDIOD_FBR_CSA_ADDR_0 0x0C -#define SDIOD_FBR_CSA_ADDR_1 0x0D -#define SDIOD_FBR_CSA_ADDR_2 0x0E -#define SDIOD_FBR_CSA_DATA 0x0F - -/* SDIO Function I/O Block Size */ -#define SDIOD_FBR_BLKSIZE_0 0x10 -#define SDIOD_FBR_BLKSIZE_1 0x11 - -/* devctr */ -#define SDIOD_FBR_DEVCTR_DIC 0x0f /* device interface code */ -#define SDIOD_FBR_DECVTR_CSA 0x40 /* CSA support flag */ -#define SDIOD_FBR_DEVCTR_CSA_EN 0x80 /* CSA enabled */ -/* interface codes */ -#define SDIOD_DIC_NONE 0 /* SDIO standard interface is not supported */ -#define SDIOD_DIC_UART 1 -#define SDIOD_DIC_BLUETOOTH_A 2 -#define SDIOD_DIC_BLUETOOTH_B 3 -#define SDIOD_DIC_GPS 4 -#define SDIOD_DIC_CAMERA 5 -#define SDIOD_DIC_PHS 6 -#define SDIOD_DIC_WLAN 7 -#define SDIOD_DIC_EXT 0xf /* extended device interface, read ext_dev register */ - -/* pwr_sel */ -#define SDIOD_PWR_SEL_SPS 0x01 /* supports power selection */ -#define SDIOD_PWR_SEL_EPS 0x02 /* enable power selection (low-current mode) */ - -/* misc defines */ -#define SDIO_FUNC_0 0 -#define SDIO_FUNC_1 1 -#define SDIO_FUNC_2 2 -#define SDIO_FUNC_3 3 -#define SDIO_FUNC_4 4 -#define SDIO_FUNC_5 5 -#define SDIO_FUNC_6 6 -#define SDIO_FUNC_7 7 - -#define SD_CARD_TYPE_UNKNOWN 0 /* bad type or unrecognized */ -#define SD_CARD_TYPE_IO 1 /* IO only card */ -#define SD_CARD_TYPE_MEMORY 2 /* memory only card */ -#define SD_CARD_TYPE_COMBO 3 /* IO and memory combo card */ - -#define SDIO_MAX_BLOCK_SIZE 2048 /* maximum block size for block mode operation */ -#define SDIO_MIN_BLOCK_SIZE 1 /* minimum block size for block mode operation */ - -/* Card registers: status bit position */ -#define CARDREG_STATUS_BIT_OUTOFRANGE 31 -#define CARDREG_STATUS_BIT_COMCRCERROR 23 -#define CARDREG_STATUS_BIT_ILLEGALCOMMAND 22 -#define CARDREG_STATUS_BIT_ERROR 19 -#define CARDREG_STATUS_BIT_IOCURRENTSTATE3 12 -#define CARDREG_STATUS_BIT_IOCURRENTSTATE2 11 -#define CARDREG_STATUS_BIT_IOCURRENTSTATE1 10 -#define CARDREG_STATUS_BIT_IOCURRENTSTATE0 9 -#define CARDREG_STATUS_BIT_FUN_NUM_ERROR 4 - - - -#define SD_CMD_GO_IDLE_STATE 0 /* mandatory for SDIO */ -#define SD_CMD_SEND_OPCOND 1 -#define SD_CMD_MMC_SET_RCA 3 -#define SD_CMD_IO_SEND_OP_COND 5 /* mandatory for SDIO */ -#define SD_CMD_SELECT_DESELECT_CARD 7 -#define SD_CMD_SEND_CSD 9 -#define SD_CMD_SEND_CID 10 -#define SD_CMD_STOP_TRANSMISSION 12 -#define SD_CMD_SEND_STATUS 13 -#define SD_CMD_GO_INACTIVE_STATE 15 -#define SD_CMD_SET_BLOCKLEN 16 -#define SD_CMD_READ_SINGLE_BLOCK 17 -#define SD_CMD_READ_MULTIPLE_BLOCK 18 -#define SD_CMD_WRITE_BLOCK 24 -#define SD_CMD_WRITE_MULTIPLE_BLOCK 25 -#define SD_CMD_PROGRAM_CSD 27 -#define SD_CMD_SET_WRITE_PROT 28 -#define SD_CMD_CLR_WRITE_PROT 29 -#define SD_CMD_SEND_WRITE_PROT 30 -#define SD_CMD_ERASE_WR_BLK_START 32 -#define SD_CMD_ERASE_WR_BLK_END 33 -#define SD_CMD_ERASE 38 -#define SD_CMD_LOCK_UNLOCK 42 -#define SD_CMD_IO_RW_DIRECT 52 /* mandatory for SDIO */ -#define SD_CMD_IO_RW_EXTENDED 53 /* mandatory for SDIO */ -#define SD_CMD_APP_CMD 55 -#define SD_CMD_GEN_CMD 56 -#define SD_CMD_READ_OCR 58 -#define SD_CMD_CRC_ON_OFF 59 /* mandatory for SDIO */ -#define SD_ACMD_SD_STATUS 13 -#define SD_ACMD_SEND_NUM_WR_BLOCKS 22 -#define SD_ACMD_SET_WR_BLOCK_ERASE_CNT 23 -#define SD_ACMD_SD_SEND_OP_COND 41 -#define SD_ACMD_SET_CLR_CARD_DETECT 42 -#define SD_ACMD_SEND_SCR 51 - -/* argument for SD_CMD_IO_RW_DIRECT and SD_CMD_IO_RW_EXTENDED */ -#define SD_IO_OP_READ 0 /* Read_Write: Read */ -#define SD_IO_OP_WRITE 1 /* Read_Write: Write */ -#define SD_IO_RW_NORMAL 0 /* no RAW */ -#define SD_IO_RW_RAW 1 /* RAW */ -#define SD_IO_BYTE_MODE 0 /* Byte Mode */ -#define SD_IO_BLOCK_MODE 1 /* BlockMode */ -#define SD_IO_FIXED_ADDRESS 0 /* fix Address */ -#define SD_IO_INCREMENT_ADDRESS 1 /* IncrementAddress */ - -/* build SD_CMD_IO_RW_DIRECT Argument */ -#define SDIO_IO_RW_DIRECT_ARG(rw, raw, func, addr, data) \ - ((((rw) & 1) << 31) | (((func) & 0x7) << 28) | (((raw) & 1) << 27) | \ - (((addr) & 0x1FFFF) << 9) | ((data) & 0xFF)) - -/* build SD_CMD_IO_RW_EXTENDED Argument */ -#define SDIO_IO_RW_EXTENDED_ARG(rw, blk, func, addr, inc_addr, count) \ - ((((rw) & 1) << 31) | (((func) & 0x7) << 28) | (((blk) & 1) << 27) | \ - (((inc_addr) & 1) << 26) | (((addr) & 0x1FFFF) << 9) | ((count) & 0x1FF)) - -/* SDIO response parameters */ -#define SD_RSP_NO_NONE 0 -#define SD_RSP_NO_1 1 -#define SD_RSP_NO_2 2 -#define SD_RSP_NO_3 3 -#define SD_RSP_NO_4 4 -#define SD_RSP_NO_5 5 -#define SD_RSP_NO_6 6 - - /* Modified R6 response (to CMD3) */ -#define SD_RSP_MR6_COM_CRC_ERROR 0x8000 -#define SD_RSP_MR6_ILLEGAL_COMMAND 0x4000 -#define SD_RSP_MR6_ERROR 0x2000 - - /* Modified R1 in R4 Response (to CMD5) */ -#define SD_RSP_MR1_SBIT 0x80 -#define SD_RSP_MR1_PARAMETER_ERROR 0x40 -#define SD_RSP_MR1_RFU5 0x20 -#define SD_RSP_MR1_FUNC_NUM_ERROR 0x10 -#define SD_RSP_MR1_COM_CRC_ERROR 0x08 -#define SD_RSP_MR1_ILLEGAL_COMMAND 0x04 -#define SD_RSP_MR1_RFU1 0x02 -#define SD_RSP_MR1_IDLE_STATE 0x01 - - /* R5 response (to CMD52 and CMD53) */ -#define SD_RSP_R5_COM_CRC_ERROR 0x80 -#define SD_RSP_R5_ILLEGAL_COMMAND 0x40 -#define SD_RSP_R5_IO_CURRENTSTATE1 0x20 -#define SD_RSP_R5_IO_CURRENTSTATE0 0x10 -#define SD_RSP_R5_ERROR 0x08 -#define SD_RSP_R5_RFU 0x04 -#define SD_RSP_R5_FUNC_NUM_ERROR 0x02 -#define SD_RSP_R5_OUT_OF_RANGE 0x01 - -#define SD_RSP_R5_ERRBITS 0xCB - - -/* ------------------------------------------------ - * SDIO Commands and responses - * - * I/O only commands are: - * CMD0, CMD3, CMD5, CMD7, CMD15, CMD52, CMD53 - * ------------------------------------------------ - */ - -/* SDIO Commands */ -#define SDIOH_CMD_0 0 -#define SDIOH_CMD_3 3 -#define SDIOH_CMD_5 5 -#define SDIOH_CMD_7 7 -#define SDIOH_CMD_15 15 -#define SDIOH_CMD_52 52 -#define SDIOH_CMD_53 53 -#define SDIOH_CMD_59 59 - -/* SDIO Command Responses */ -#define SDIOH_RSP_NONE 0 -#define SDIOH_RSP_R1 1 -#define SDIOH_RSP_R2 2 -#define SDIOH_RSP_R3 3 -#define SDIOH_RSP_R4 4 -#define SDIOH_RSP_R5 5 -#define SDIOH_RSP_R6 6 - -/* - * SDIO Response Error flags - */ -#define SDIOH_RSP5_ERROR_FLAGS 0xCB - -/* ------------------------------------------------ - * SDIO Command structures. I/O only commands are: - * - * CMD0, CMD3, CMD5, CMD7, CMD15, CMD52, CMD53 - * ------------------------------------------------ - */ - -#define CMD5_OCR_M BITFIELD_MASK(24) -#define CMD5_OCR_S 0 - -#define CMD7_RCA_M BITFIELD_MASK(16) -#define CMD7_RCA_S 16 - -#define CMD_15_RCA_M BITFIELD_MASK(16) -#define CMD_15_RCA_S 16 - -#define CMD52_DATA_M BITFIELD_MASK(8) /* Bits [7:0] - Write Data/Stuff bits of CMD52 - */ -#define CMD52_DATA_S 0 -#define CMD52_REG_ADDR_M BITFIELD_MASK(17) /* Bits [25:9] - register address */ -#define CMD52_REG_ADDR_S 9 -#define CMD52_RAW_M BITFIELD_MASK(1) /* Bit 27 - Read after Write flag */ -#define CMD52_RAW_S 27 -#define CMD52_FUNCTION_M BITFIELD_MASK(3) /* Bits [30:28] - Function number */ -#define CMD52_FUNCTION_S 28 -#define CMD52_RW_FLAG_M BITFIELD_MASK(1) /* Bit 31 - R/W flag */ -#define CMD52_RW_FLAG_S 31 - - -#define CMD53_BYTE_BLK_CNT_M BITFIELD_MASK(9) /* Bits [8:0] - Byte/Block Count of CMD53 */ -#define CMD53_BYTE_BLK_CNT_S 0 -#define CMD53_REG_ADDR_M BITFIELD_MASK(17) /* Bits [25:9] - register address */ -#define CMD53_REG_ADDR_S 9 -#define CMD53_OP_CODE_M BITFIELD_MASK(1) /* Bit 26 - R/W Operation Code */ -#define CMD53_OP_CODE_S 26 -#define CMD53_BLK_MODE_M BITFIELD_MASK(1) /* Bit 27 - Block Mode */ -#define CMD53_BLK_MODE_S 27 -#define CMD53_FUNCTION_M BITFIELD_MASK(3) /* Bits [30:28] - Function number */ -#define CMD53_FUNCTION_S 28 -#define CMD53_RW_FLAG_M BITFIELD_MASK(1) /* Bit 31 - R/W flag */ -#define CMD53_RW_FLAG_S 31 - -/* ------------------------------------------------------ - * SDIO Command Response structures for SD1 and SD4 modes - * ----------------------------------------------------- - */ -#define RSP4_IO_OCR_M BITFIELD_MASK(24) /* Bits [23:0] - Card's OCR Bits [23:0] */ -#define RSP4_IO_OCR_S 0 -#define RSP4_STUFF_M BITFIELD_MASK(3) /* Bits [26:24] - Stuff bits */ -#define RSP4_STUFF_S 24 -#define RSP4_MEM_PRESENT_M BITFIELD_MASK(1) /* Bit 27 - Memory present */ -#define RSP4_MEM_PRESENT_S 27 -#define RSP4_NUM_FUNCS_M BITFIELD_MASK(3) /* Bits [30:28] - Number of I/O funcs */ -#define RSP4_NUM_FUNCS_S 28 -#define RSP4_CARD_READY_M BITFIELD_MASK(1) /* Bit 31 - SDIO card ready */ -#define RSP4_CARD_READY_S 31 - -#define RSP6_STATUS_M BITFIELD_MASK(16) /* Bits [15:0] - Card status bits [19,22,23,12:0] - */ -#define RSP6_STATUS_S 0 -#define RSP6_IO_RCA_M BITFIELD_MASK(16) /* Bits [31:16] - RCA bits[31-16] */ -#define RSP6_IO_RCA_S 16 - -#define RSP1_AKE_SEQ_ERROR_M BITFIELD_MASK(1) /* Bit 3 - Authentication seq error */ -#define RSP1_AKE_SEQ_ERROR_S 3 -#define RSP1_APP_CMD_M BITFIELD_MASK(1) /* Bit 5 - Card expects ACMD */ -#define RSP1_APP_CMD_S 5 -#define RSP1_READY_FOR_DATA_M BITFIELD_MASK(1) /* Bit 8 - Ready for data (buff empty) */ -#define RSP1_READY_FOR_DATA_S 8 -#define RSP1_CURR_STATE_M BITFIELD_MASK(4) /* Bits [12:9] - State of card - * when Cmd was received - */ -#define RSP1_CURR_STATE_S 9 -#define RSP1_EARSE_RESET_M BITFIELD_MASK(1) /* Bit 13 - Erase seq cleared */ -#define RSP1_EARSE_RESET_S 13 -#define RSP1_CARD_ECC_DISABLE_M BITFIELD_MASK(1) /* Bit 14 - Card ECC disabled */ -#define RSP1_CARD_ECC_DISABLE_S 14 -#define RSP1_WP_ERASE_SKIP_M BITFIELD_MASK(1) /* Bit 15 - Partial blocks erased due to W/P */ -#define RSP1_WP_ERASE_SKIP_S 15 -#define RSP1_CID_CSD_OVERW_M BITFIELD_MASK(1) /* Bit 16 - Illegal write to CID or R/O bits - * of CSD - */ -#define RSP1_CID_CSD_OVERW_S 16 -#define RSP1_ERROR_M BITFIELD_MASK(1) /* Bit 19 - General/Unknown error */ -#define RSP1_ERROR_S 19 -#define RSP1_CC_ERROR_M BITFIELD_MASK(1) /* Bit 20 - Internal Card Control error */ -#define RSP1_CC_ERROR_S 20 -#define RSP1_CARD_ECC_FAILED_M BITFIELD_MASK(1) /* Bit 21 - Card internal ECC failed - * to correct data - */ -#define RSP1_CARD_ECC_FAILED_S 21 -#define RSP1_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 22 - Cmd not legal for the card state */ -#define RSP1_ILLEGAL_CMD_S 22 -#define RSP1_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 23 - CRC check of previous command failed - */ -#define RSP1_COM_CRC_ERROR_S 23 -#define RSP1_LOCK_UNLOCK_FAIL_M BITFIELD_MASK(1) /* Bit 24 - Card lock-unlock Cmd Seq error */ -#define RSP1_LOCK_UNLOCK_FAIL_S 24 -#define RSP1_CARD_LOCKED_M BITFIELD_MASK(1) /* Bit 25 - Card locked by the host */ -#define RSP1_CARD_LOCKED_S 25 -#define RSP1_WP_VIOLATION_M BITFIELD_MASK(1) /* Bit 26 - Attempt to program - * write-protected blocks - */ -#define RSP1_WP_VIOLATION_S 26 -#define RSP1_ERASE_PARAM_M BITFIELD_MASK(1) /* Bit 27 - Invalid erase blocks */ -#define RSP1_ERASE_PARAM_S 27 -#define RSP1_ERASE_SEQ_ERR_M BITFIELD_MASK(1) /* Bit 28 - Erase Cmd seq error */ -#define RSP1_ERASE_SEQ_ERR_S 28 -#define RSP1_BLK_LEN_ERR_M BITFIELD_MASK(1) /* Bit 29 - Block length error */ -#define RSP1_BLK_LEN_ERR_S 29 -#define RSP1_ADDR_ERR_M BITFIELD_MASK(1) /* Bit 30 - Misaligned address */ -#define RSP1_ADDR_ERR_S 30 -#define RSP1_OUT_OF_RANGE_M BITFIELD_MASK(1) /* Bit 31 - Cmd arg was out of range */ -#define RSP1_OUT_OF_RANGE_S 31 - - -#define RSP5_DATA_M BITFIELD_MASK(8) /* Bits [0:7] - data */ -#define RSP5_DATA_S 0 -#define RSP5_FLAGS_M BITFIELD_MASK(8) /* Bit [15:8] - Rsp flags */ -#define RSP5_FLAGS_S 8 -#define RSP5_STUFF_M BITFIELD_MASK(16) /* Bits [31:16] - Stuff bits */ -#define RSP5_STUFF_S 16 - -/* ---------------------------------------------- - * SDIO Command Response structures for SPI mode - * ---------------------------------------------- - */ -#define SPIRSP4_IO_OCR_M BITFIELD_MASK(16) /* Bits [15:0] - Card's OCR Bits [23:8] */ -#define SPIRSP4_IO_OCR_S 0 -#define SPIRSP4_STUFF_M BITFIELD_MASK(3) /* Bits [18:16] - Stuff bits */ -#define SPIRSP4_STUFF_S 16 -#define SPIRSP4_MEM_PRESENT_M BITFIELD_MASK(1) /* Bit 19 - Memory present */ -#define SPIRSP4_MEM_PRESENT_S 19 -#define SPIRSP4_NUM_FUNCS_M BITFIELD_MASK(3) /* Bits [22:20] - Number of I/O funcs */ -#define SPIRSP4_NUM_FUNCS_S 20 -#define SPIRSP4_CARD_READY_M BITFIELD_MASK(1) /* Bit 23 - SDIO card ready */ -#define SPIRSP4_CARD_READY_S 23 -#define SPIRSP4_IDLE_STATE_M BITFIELD_MASK(1) /* Bit 24 - idle state */ -#define SPIRSP4_IDLE_STATE_S 24 -#define SPIRSP4_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 26 - Illegal Cmd error */ -#define SPIRSP4_ILLEGAL_CMD_S 26 -#define SPIRSP4_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 27 - COM CRC error */ -#define SPIRSP4_COM_CRC_ERROR_S 27 -#define SPIRSP4_FUNC_NUM_ERROR_M BITFIELD_MASK(1) /* Bit 28 - Function number error - */ -#define SPIRSP4_FUNC_NUM_ERROR_S 28 -#define SPIRSP4_PARAM_ERROR_M BITFIELD_MASK(1) /* Bit 30 - Parameter Error Bit */ -#define SPIRSP4_PARAM_ERROR_S 30 -#define SPIRSP4_START_BIT_M BITFIELD_MASK(1) /* Bit 31 - Start Bit */ -#define SPIRSP4_START_BIT_S 31 - -#define SPIRSP5_DATA_M BITFIELD_MASK(8) /* Bits [23:16] - R/W Data */ -#define SPIRSP5_DATA_S 16 -#define SPIRSP5_IDLE_STATE_M BITFIELD_MASK(1) /* Bit 24 - Idle state */ -#define SPIRSP5_IDLE_STATE_S 24 -#define SPIRSP5_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 26 - Illegal Cmd error */ -#define SPIRSP5_ILLEGAL_CMD_S 26 -#define SPIRSP5_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 27 - COM CRC error */ -#define SPIRSP5_COM_CRC_ERROR_S 27 -#define SPIRSP5_FUNC_NUM_ERROR_M BITFIELD_MASK(1) /* Bit 28 - Function number error - */ -#define SPIRSP5_FUNC_NUM_ERROR_S 28 -#define SPIRSP5_PARAM_ERROR_M BITFIELD_MASK(1) /* Bit 30 - Parameter Error Bit */ -#define SPIRSP5_PARAM_ERROR_S 30 -#define SPIRSP5_START_BIT_M BITFIELD_MASK(1) /* Bit 31 - Start Bit */ -#define SPIRSP5_START_BIT_S 31 - -/* RSP6 card status format; Pg 68 Physical Layer spec v 1.10 */ -#define RSP6STAT_AKE_SEQ_ERROR_M BITFIELD_MASK(1) /* Bit 3 - Authentication seq error - */ -#define RSP6STAT_AKE_SEQ_ERROR_S 3 -#define RSP6STAT_APP_CMD_M BITFIELD_MASK(1) /* Bit 5 - Card expects ACMD */ -#define RSP6STAT_APP_CMD_S 5 -#define RSP6STAT_READY_FOR_DATA_M BITFIELD_MASK(1) /* Bit 8 - Ready for data - * (buff empty) - */ -#define RSP6STAT_READY_FOR_DATA_S 8 -#define RSP6STAT_CURR_STATE_M BITFIELD_MASK(4) /* Bits [12:9] - Card state at - * Cmd reception - */ -#define RSP6STAT_CURR_STATE_S 9 -#define RSP6STAT_ERROR_M BITFIELD_MASK(1) /* Bit 13 - General/Unknown error Bit 19 - */ -#define RSP6STAT_ERROR_S 13 -#define RSP6STAT_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 14 - Illegal cmd for - * card state Bit 22 - */ -#define RSP6STAT_ILLEGAL_CMD_S 14 -#define RSP6STAT_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 15 - CRC previous command - * failed Bit 23 - */ -#define RSP6STAT_COM_CRC_ERROR_S 15 - -#define SDIOH_XFER_TYPE_READ SD_IO_OP_READ -#define SDIOH_XFER_TYPE_WRITE SD_IO_OP_WRITE - -#endif /* _SDIO_H */ diff --git a/drivers/net/wireless/bcm4329/include/sdioh.h b/drivers/net/wireless/bcm4329/include/sdioh.h deleted file mode 100644 index 8123452eac2b..000000000000 --- a/drivers/net/wireless/bcm4329/include/sdioh.h +++ /dev/null @@ -1,299 +0,0 @@ -/* - * SDIO Host Controller Spec header file - * Register map and definitions for the Standard Host Controller - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sdioh.h,v 13.13.18.1.16.3 2009/12/08 22:34:21 Exp $ - */ - -#ifndef _SDIOH_H -#define _SDIOH_H - -#define SD_SysAddr 0x000 -#define SD_BlockSize 0x004 -#define SD_BlockCount 0x006 -#define SD_Arg0 0x008 -#define SD_Arg1 0x00A -#define SD_TransferMode 0x00C -#define SD_Command 0x00E -#define SD_Response0 0x010 -#define SD_Response1 0x012 -#define SD_Response2 0x014 -#define SD_Response3 0x016 -#define SD_Response4 0x018 -#define SD_Response5 0x01A -#define SD_Response6 0x01C -#define SD_Response7 0x01E -#define SD_BufferDataPort0 0x020 -#define SD_BufferDataPort1 0x022 -#define SD_PresentState 0x024 -#define SD_HostCntrl 0x028 -#define SD_PwrCntrl 0x029 -#define SD_BlockGapCntrl 0x02A -#define SD_WakeupCntrl 0x02B -#define SD_ClockCntrl 0x02C -#define SD_TimeoutCntrl 0x02E -#define SD_SoftwareReset 0x02F -#define SD_IntrStatus 0x030 -#define SD_ErrorIntrStatus 0x032 -#define SD_IntrStatusEnable 0x034 -#define SD_ErrorIntrStatusEnable 0x036 -#define SD_IntrSignalEnable 0x038 -#define SD_ErrorIntrSignalEnable 0x03A -#define SD_CMD12ErrorStatus 0x03C -#define SD_Capabilities 0x040 -#define SD_Capabilities_Reserved 0x044 -#define SD_MaxCurCap 0x048 -#define SD_MaxCurCap_Reserved 0x04C -#define SD_ADMA_SysAddr 0x58 -#define SD_SlotInterruptStatus 0x0FC -#define SD_HostControllerVersion 0x0FE - -/* SD specific registers in PCI config space */ -#define SD_SlotInfo 0x40 - -/* SD_Capabilities reg (0x040) */ -#define CAP_TO_CLKFREQ_M BITFIELD_MASK(6) -#define CAP_TO_CLKFREQ_S 0 -#define CAP_TO_CLKUNIT_M BITFIELD_MASK(1) -#define CAP_TO_CLKUNIT_S 7 -#define CAP_BASECLK_M BITFIELD_MASK(6) -#define CAP_BASECLK_S 8 -#define CAP_MAXBLOCK_M BITFIELD_MASK(2) -#define CAP_MAXBLOCK_S 16 -#define CAP_ADMA2_M BITFIELD_MASK(1) -#define CAP_ADMA2_S 19 -#define CAP_ADMA1_M BITFIELD_MASK(1) -#define CAP_ADMA1_S 20 -#define CAP_HIGHSPEED_M BITFIELD_MASK(1) -#define CAP_HIGHSPEED_S 21 -#define CAP_DMA_M BITFIELD_MASK(1) -#define CAP_DMA_S 22 -#define CAP_SUSPEND_M BITFIELD_MASK(1) -#define CAP_SUSPEND_S 23 -#define CAP_VOLT_3_3_M BITFIELD_MASK(1) -#define CAP_VOLT_3_3_S 24 -#define CAP_VOLT_3_0_M BITFIELD_MASK(1) -#define CAP_VOLT_3_0_S 25 -#define CAP_VOLT_1_8_M BITFIELD_MASK(1) -#define CAP_VOLT_1_8_S 26 -#define CAP_64BIT_HOST_M BITFIELD_MASK(1) -#define CAP_64BIT_HOST_S 28 - -/* SD_MaxCurCap reg (0x048) */ -#define CAP_CURR_3_3_M BITFIELD_MASK(8) -#define CAP_CURR_3_3_S 0 -#define CAP_CURR_3_0_M BITFIELD_MASK(8) -#define CAP_CURR_3_0_S 8 -#define CAP_CURR_1_8_M BITFIELD_MASK(8) -#define CAP_CURR_1_8_S 16 - -/* SD_SysAddr: Offset 0x0000, Size 4 bytes */ - -/* SD_BlockSize: Offset 0x004, Size 2 bytes */ -#define BLKSZ_BLKSZ_M BITFIELD_MASK(12) -#define BLKSZ_BLKSZ_S 0 -#define BLKSZ_BNDRY_M BITFIELD_MASK(3) -#define BLKSZ_BNDRY_S 12 - -/* SD_BlockCount: Offset 0x006, size 2 bytes */ - -/* SD_Arg0: Offset 0x008, size = 4 bytes */ -/* SD_TransferMode Offset 0x00C, size = 2 bytes */ -#define XFER_DMA_ENABLE_M BITFIELD_MASK(1) -#define XFER_DMA_ENABLE_S 0 -#define XFER_BLK_COUNT_EN_M BITFIELD_MASK(1) -#define XFER_BLK_COUNT_EN_S 1 -#define XFER_CMD_12_EN_M BITFIELD_MASK(1) -#define XFER_CMD_12_EN_S 2 -#define XFER_DATA_DIRECTION_M BITFIELD_MASK(1) -#define XFER_DATA_DIRECTION_S 4 -#define XFER_MULTI_BLOCK_M BITFIELD_MASK(1) -#define XFER_MULTI_BLOCK_S 5 - -/* SD_Command: Offset 0x00E, size = 2 bytes */ -/* resp_type field */ -#define RESP_TYPE_NONE 0 -#define RESP_TYPE_136 1 -#define RESP_TYPE_48 2 -#define RESP_TYPE_48_BUSY 3 -/* type field */ -#define CMD_TYPE_NORMAL 0 -#define CMD_TYPE_SUSPEND 1 -#define CMD_TYPE_RESUME 2 -#define CMD_TYPE_ABORT 3 - -#define CMD_RESP_TYPE_M BITFIELD_MASK(2) /* Bits [0-1] - Response type */ -#define CMD_RESP_TYPE_S 0 -#define CMD_CRC_EN_M BITFIELD_MASK(1) /* Bit 3 - CRC enable */ -#define CMD_CRC_EN_S 3 -#define CMD_INDEX_EN_M BITFIELD_MASK(1) /* Bit 4 - Enable index checking */ -#define CMD_INDEX_EN_S 4 -#define CMD_DATA_EN_M BITFIELD_MASK(1) /* Bit 5 - Using DAT line */ -#define CMD_DATA_EN_S 5 -#define CMD_TYPE_M BITFIELD_MASK(2) /* Bit [6-7] - Normal, abort, resume, etc - */ -#define CMD_TYPE_S 6 -#define CMD_INDEX_M BITFIELD_MASK(6) /* Bits [8-13] - Command number */ -#define CMD_INDEX_S 8 - -/* SD_BufferDataPort0 : Offset 0x020, size = 2 or 4 bytes */ -/* SD_BufferDataPort1 : Offset 0x022, size = 2 bytes */ -/* SD_PresentState : Offset 0x024, size = 4 bytes */ -#define PRES_CMD_INHIBIT_M BITFIELD_MASK(1) /* Bit 0 May use CMD */ -#define PRES_CMD_INHIBIT_S 0 -#define PRES_DAT_INHIBIT_M BITFIELD_MASK(1) /* Bit 1 May use DAT */ -#define PRES_DAT_INHIBIT_S 1 -#define PRES_DAT_BUSY_M BITFIELD_MASK(1) /* Bit 2 DAT is busy */ -#define PRES_DAT_BUSY_S 2 -#define PRES_PRESENT_RSVD_M BITFIELD_MASK(5) /* Bit [3-7] rsvd */ -#define PRES_PRESENT_RSVD_S 3 -#define PRES_WRITE_ACTIVE_M BITFIELD_MASK(1) /* Bit 8 Write is active */ -#define PRES_WRITE_ACTIVE_S 8 -#define PRES_READ_ACTIVE_M BITFIELD_MASK(1) /* Bit 9 Read is active */ -#define PRES_READ_ACTIVE_S 9 -#define PRES_WRITE_DATA_RDY_M BITFIELD_MASK(1) /* Bit 10 Write buf is avail */ -#define PRES_WRITE_DATA_RDY_S 10 -#define PRES_READ_DATA_RDY_M BITFIELD_MASK(1) /* Bit 11 Read buf data avail */ -#define PRES_READ_DATA_RDY_S 11 -#define PRES_CARD_PRESENT_M BITFIELD_MASK(1) /* Bit 16 Card present - debounced */ -#define PRES_CARD_PRESENT_S 16 -#define PRES_CARD_STABLE_M BITFIELD_MASK(1) /* Bit 17 Debugging */ -#define PRES_CARD_STABLE_S 17 -#define PRES_CARD_PRESENT_RAW_M BITFIELD_MASK(1) /* Bit 18 Not debounced */ -#define PRES_CARD_PRESENT_RAW_S 18 -#define PRES_WRITE_ENABLED_M BITFIELD_MASK(1) /* Bit 19 Write protected? */ -#define PRES_WRITE_ENABLED_S 19 -#define PRES_DAT_SIGNAL_M BITFIELD_MASK(4) /* Bit [20-23] Debugging */ -#define PRES_DAT_SIGNAL_S 20 -#define PRES_CMD_SIGNAL_M BITFIELD_MASK(1) /* Bit 24 Debugging */ -#define PRES_CMD_SIGNAL_S 24 - -/* SD_HostCntrl: Offset 0x028, size = 1 bytes */ -#define HOST_LED_M BITFIELD_MASK(1) /* Bit 0 LED On/Off */ -#define HOST_LED_S 0 -#define HOST_DATA_WIDTH_M BITFIELD_MASK(1) /* Bit 1 4 bit enable */ -#define HOST_DATA_WIDTH_S 1 -#define HOST_HI_SPEED_EN_M BITFIELD_MASK(1) /* Bit 2 High speed vs low speed */ -#define HOST_DMA_SEL_S 3 -#define HOST_DMA_SEL_M BITFIELD_MASK(2) /* Bit 4:3 DMA Select */ -#define HOST_HI_SPEED_EN_S 2 - -/* misc defines */ -#define SD1_MODE 0x1 /* SD Host Cntrlr Spec */ -#define SD4_MODE 0x2 /* SD Host Cntrlr Spec */ - -/* SD_PwrCntrl: Offset 0x029, size = 1 bytes */ -#define PWR_BUS_EN_M BITFIELD_MASK(1) /* Bit 0 Power the bus */ -#define PWR_BUS_EN_S 0 -#define PWR_VOLTS_M BITFIELD_MASK(3) /* Bit [1-3] Voltage Select */ -#define PWR_VOLTS_S 1 - -/* SD_SoftwareReset: Offset 0x02F, size = 1 byte */ -#define SW_RESET_ALL_M BITFIELD_MASK(1) /* Bit 0 Reset All */ -#define SW_RESET_ALL_S 0 -#define SW_RESET_CMD_M BITFIELD_MASK(1) /* Bit 1 CMD Line Reset */ -#define SW_RESET_CMD_S 1 -#define SW_RESET_DAT_M BITFIELD_MASK(1) /* Bit 2 DAT Line Reset */ -#define SW_RESET_DAT_S 2 - -/* SD_IntrStatus: Offset 0x030, size = 2 bytes */ -/* Defs also serve SD_IntrStatusEnable and SD_IntrSignalEnable */ -#define INTSTAT_CMD_COMPLETE_M BITFIELD_MASK(1) /* Bit 0 */ -#define INTSTAT_CMD_COMPLETE_S 0 -#define INTSTAT_XFER_COMPLETE_M BITFIELD_MASK(1) -#define INTSTAT_XFER_COMPLETE_S 1 -#define INTSTAT_BLOCK_GAP_EVENT_M BITFIELD_MASK(1) -#define INTSTAT_BLOCK_GAP_EVENT_S 2 -#define INTSTAT_DMA_INT_M BITFIELD_MASK(1) -#define INTSTAT_DMA_INT_S 3 -#define INTSTAT_BUF_WRITE_READY_M BITFIELD_MASK(1) -#define INTSTAT_BUF_WRITE_READY_S 4 -#define INTSTAT_BUF_READ_READY_M BITFIELD_MASK(1) -#define INTSTAT_BUF_READ_READY_S 5 -#define INTSTAT_CARD_INSERTION_M BITFIELD_MASK(1) -#define INTSTAT_CARD_INSERTION_S 6 -#define INTSTAT_CARD_REMOVAL_M BITFIELD_MASK(1) -#define INTSTAT_CARD_REMOVAL_S 7 -#define INTSTAT_CARD_INT_M BITFIELD_MASK(1) -#define INTSTAT_CARD_INT_S 8 -#define INTSTAT_ERROR_INT_M BITFIELD_MASK(1) /* Bit 15 */ -#define INTSTAT_ERROR_INT_S 15 - -/* SD_ErrorIntrStatus: Offset 0x032, size = 2 bytes */ -/* Defs also serve SD_ErrorIntrStatusEnable and SD_ErrorIntrSignalEnable */ -#define ERRINT_CMD_TIMEOUT_M BITFIELD_MASK(1) -#define ERRINT_CMD_TIMEOUT_S 0 -#define ERRINT_CMD_CRC_M BITFIELD_MASK(1) -#define ERRINT_CMD_CRC_S 1 -#define ERRINT_CMD_ENDBIT_M BITFIELD_MASK(1) -#define ERRINT_CMD_ENDBIT_S 2 -#define ERRINT_CMD_INDEX_M BITFIELD_MASK(1) -#define ERRINT_CMD_INDEX_S 3 -#define ERRINT_DATA_TIMEOUT_M BITFIELD_MASK(1) -#define ERRINT_DATA_TIMEOUT_S 4 -#define ERRINT_DATA_CRC_M BITFIELD_MASK(1) -#define ERRINT_DATA_CRC_S 5 -#define ERRINT_DATA_ENDBIT_M BITFIELD_MASK(1) -#define ERRINT_DATA_ENDBIT_S 6 -#define ERRINT_CURRENT_LIMIT_M BITFIELD_MASK(1) -#define ERRINT_CURRENT_LIMIT_S 7 -#define ERRINT_AUTO_CMD12_M BITFIELD_MASK(1) -#define ERRINT_AUTO_CMD12_S 8 -#define ERRINT_VENDOR_M BITFIELD_MASK(4) -#define ERRINT_VENDOR_S 12 - -/* Also provide definitions in "normal" form to allow combined masks */ -#define ERRINT_CMD_TIMEOUT_BIT 0x0001 -#define ERRINT_CMD_CRC_BIT 0x0002 -#define ERRINT_CMD_ENDBIT_BIT 0x0004 -#define ERRINT_CMD_INDEX_BIT 0x0008 -#define ERRINT_DATA_TIMEOUT_BIT 0x0010 -#define ERRINT_DATA_CRC_BIT 0x0020 -#define ERRINT_DATA_ENDBIT_BIT 0x0040 -#define ERRINT_CURRENT_LIMIT_BIT 0x0080 -#define ERRINT_AUTO_CMD12_BIT 0x0100 - -/* Masks to select CMD vs. DATA errors */ -#define ERRINT_CMD_ERRS (ERRINT_CMD_TIMEOUT_BIT | ERRINT_CMD_CRC_BIT |\ - ERRINT_CMD_ENDBIT_BIT | ERRINT_CMD_INDEX_BIT) -#define ERRINT_DATA_ERRS (ERRINT_DATA_TIMEOUT_BIT | ERRINT_DATA_CRC_BIT |\ - ERRINT_DATA_ENDBIT_BIT) -#define ERRINT_TRANSFER_ERRS (ERRINT_CMD_ERRS | ERRINT_DATA_ERRS) - -/* SD_WakeupCntr_BlockGapCntrl : Offset 0x02A , size = bytes */ -/* SD_ClockCntrl : Offset 0x02C , size = bytes */ -/* SD_SoftwareReset_TimeoutCntrl : Offset 0x02E , size = bytes */ -/* SD_IntrStatus : Offset 0x030 , size = bytes */ -/* SD_ErrorIntrStatus : Offset 0x032 , size = bytes */ -/* SD_IntrStatusEnable : Offset 0x034 , size = bytes */ -/* SD_ErrorIntrStatusEnable : Offset 0x036 , size = bytes */ -/* SD_IntrSignalEnable : Offset 0x038 , size = bytes */ -/* SD_ErrorIntrSignalEnable : Offset 0x03A , size = bytes */ -/* SD_CMD12ErrorStatus : Offset 0x03C , size = bytes */ -/* SD_Capabilities : Offset 0x040 , size = bytes */ -/* SD_MaxCurCap : Offset 0x048 , size = bytes */ -/* SD_MaxCurCap_Reserved: Offset 0x04C , size = bytes */ -/* SD_SlotInterruptStatus: Offset 0x0FC , size = bytes */ -/* SD_HostControllerVersion : Offset 0x0FE , size = bytes */ - -#endif /* _SDIOH_H */ diff --git a/drivers/net/wireless/bcm4329/include/sdiovar.h b/drivers/net/wireless/bcm4329/include/sdiovar.h deleted file mode 100644 index 0179d4cb96db..000000000000 --- a/drivers/net/wireless/bcm4329/include/sdiovar.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Structure used by apps whose drivers access SDIO drivers. - * Pulled out separately so dhdu and wlu can both use it. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sdiovar.h,v 13.5.14.2.16.2 2009/12/08 22:34:21 Exp $ - */ - -#ifndef _sdiovar_h_ -#define _sdiovar_h_ - -#include - -/* require default structure packing */ -#define BWL_DEFAULT_PACKING -#include - -typedef struct sdreg { - int func; - int offset; - int value; -} sdreg_t; - -/* Common msglevel constants */ -#define SDH_ERROR_VAL 0x0001 /* Error */ -#define SDH_TRACE_VAL 0x0002 /* Trace */ -#define SDH_INFO_VAL 0x0004 /* Info */ -#define SDH_DEBUG_VAL 0x0008 /* Debug */ -#define SDH_DATA_VAL 0x0010 /* Data */ -#define SDH_CTRL_VAL 0x0020 /* Control Regs */ -#define SDH_LOG_VAL 0x0040 /* Enable bcmlog */ -#define SDH_DMA_VAL 0x0080 /* DMA */ - -#define NUM_PREV_TRANSACTIONS 16 - - -#include - -#endif /* _sdiovar_h_ */ diff --git a/drivers/net/wireless/bcm4329/include/siutils.h b/drivers/net/wireless/bcm4329/include/siutils.h deleted file mode 100644 index cb9f1407b73b..000000000000 --- a/drivers/net/wireless/bcm4329/include/siutils.h +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Misc utility routines for accessing the SOC Interconnects - * of Broadcom HNBU chips. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: siutils.h,v 13.197.4.2.4.3.8.16 2010/06/23 21:36:05 Exp $ - */ - - -#ifndef _siutils_h_ -#define _siutils_h_ - - -struct si_pub { - uint socitype; - - uint bustype; - uint buscoretype; - uint buscorerev; - uint buscoreidx; - int ccrev; - uint32 cccaps; - int pmurev; - uint32 pmucaps; - uint boardtype; - uint boardvendor; - uint boardflags; - uint chip; - uint chiprev; - uint chippkg; - uint32 chipst; - bool issim; - uint socirev; - bool pci_pr32414; -}; - -#if defined(WLC_HIGH) && !defined(WLC_LOW) -typedef struct si_pub si_t; -#else -typedef const struct si_pub si_t; -#endif - - -#define SI_OSH NULL - - -#define XTAL 0x1 -#define PLL 0x2 - - -#define CLK_FAST 0 -#define CLK_DYNAMIC 2 - - -#define GPIO_DRV_PRIORITY 0 -#define GPIO_APP_PRIORITY 1 -#define GPIO_HI_PRIORITY 2 - - -#define GPIO_PULLUP 0 -#define GPIO_PULLDN 1 - - -#define GPIO_REGEVT 0 -#define GPIO_REGEVT_INTMSK 1 -#define GPIO_REGEVT_INTPOL 2 - - -#define SI_DEVPATH_BUFSZ 16 - - -#define SI_DOATTACH 1 -#define SI_PCIDOWN 2 -#define SI_PCIUP 3 - -#define ISSIM_ENAB(sih) 0 - - -#if defined(BCMPMUCTL) -#define PMUCTL_ENAB(sih) (BCMPMUCTL) -#else -#define PMUCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PMU) -#endif - - -#if defined(BCMPMUCTL) && BCMPMUCTL -#define CCCTL_ENAB(sih) (0) -#define CCPLL_ENAB(sih) (0) -#else -#define CCCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PWR_CTL) -#define CCPLL_ENAB(sih) ((sih)->cccaps & CC_CAP_PLL_MASK) -#endif - -typedef void (*gpio_handler_t)(uint32 stat, void *arg); - - - -extern si_t *si_attach(uint pcidev, osl_t *osh, void *regs, uint bustype, - void *sdh, char **vars, uint *varsz); -extern si_t *si_kattach(osl_t *osh); -extern void si_detach(si_t *sih); -extern bool si_pci_war16165(si_t *sih); - -extern uint si_corelist(si_t *sih, uint coreid[]); -extern uint si_coreid(si_t *sih); -extern uint si_flag(si_t *sih); -extern uint si_intflag(si_t *sih); -extern uint si_coreidx(si_t *sih); -extern uint si_coreunit(si_t *sih); -extern uint si_corevendor(si_t *sih); -extern uint si_corerev(si_t *sih); -extern void *si_osh(si_t *sih); -extern void si_setosh(si_t *sih, osl_t *osh); -extern uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); -extern void *si_coreregs(si_t *sih); -extern void si_write_wrapperreg(si_t *sih, uint32 offset, uint32 val); -extern uint32 si_core_cflags(si_t *sih, uint32 mask, uint32 val); -extern void si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val); -extern uint32 si_core_sflags(si_t *sih, uint32 mask, uint32 val); -extern bool si_iscoreup(si_t *sih); -extern uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit); -extern void *si_setcoreidx(si_t *sih, uint coreidx); -extern void *si_setcore(si_t *sih, uint coreid, uint coreunit); -extern void *si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val); -extern void si_restore_core(si_t *sih, uint coreid, uint intr_val); -extern int si_numaddrspaces(si_t *sih); -extern uint32 si_addrspace(si_t *sih, uint asidx); -extern uint32 si_addrspacesize(si_t *sih, uint asidx); -extern int si_corebist(si_t *sih); -extern void si_core_reset(si_t *sih, uint32 bits, uint32 resetbits); -extern void si_core_tofixup(si_t *sih); -extern void si_core_disable(si_t *sih, uint32 bits); -extern uint32 si_clock_rate(uint32 pll_type, uint32 n, uint32 m); -extern uint32 si_clock(si_t *sih); -extern void si_clock_pmu_spuravoid(si_t *sih, bool spuravoid); -extern uint32 si_alp_clock(si_t *sih); -extern uint32 si_ilp_clock(si_t *sih); -extern void si_pci_setup(si_t *sih, uint coremask); -extern void si_pcmcia_init(si_t *sih); -extern void si_setint(si_t *sih, int siflag); -extern bool si_backplane64(si_t *sih); -extern void si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn, - void *intrsenabled_fn, void *intr_arg); -extern void si_deregister_intr_callback(si_t *sih); -extern void si_clkctl_init(si_t *sih); -extern uint16 si_clkctl_fast_pwrup_delay(si_t *sih); -extern bool si_clkctl_cc(si_t *sih, uint mode); -extern int si_clkctl_xtal(si_t *sih, uint what, bool on); -extern uint32 si_gpiotimerval(si_t *sih, uint32 mask, uint32 val); -extern bool si_backplane64(si_t *sih); -extern void si_btcgpiowar(si_t *sih); -extern bool si_deviceremoved(si_t *sih); -extern uint32 si_socram_size(si_t *sih); - -extern void si_watchdog(si_t *sih, uint ticks); -extern void si_watchdog_ms(si_t *sih, uint32 ms); -extern void *si_gpiosetcore(si_t *sih); -extern uint32 si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority); -extern uint32 si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority); -extern uint32 si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority); -extern uint32 si_gpioin(si_t *sih); -extern uint32 si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority); -extern uint32 si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority); -extern uint32 si_gpioled(si_t *sih, uint32 mask, uint32 val); -extern uint32 si_gpioreserve(si_t *sih, uint32 gpio_num, uint8 priority); -extern uint32 si_gpiorelease(si_t *sih, uint32 gpio_num, uint8 priority); -extern uint32 si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val); -extern uint32 si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val); -extern uint32 si_gpio_int_enable(si_t *sih, bool enable); - - -extern void *si_gpio_handler_register(si_t *sih, uint32 e, bool lev, gpio_handler_t cb, void *arg); -extern void si_gpio_handler_unregister(si_t *sih, void* gpioh); -extern void si_gpio_handler_process(si_t *sih); - - -extern bool si_pci_pmecap(si_t *sih); -struct osl_info; -extern bool si_pci_fastpmecap(struct osl_info *osh); -extern bool si_pci_pmeclr(si_t *sih); -extern void si_pci_pmeen(si_t *sih); -extern uint si_pcie_readreg(void *sih, uint addrtype, uint offset); - -extern void si_sdio_init(si_t *sih); - -extern uint16 si_d11_devid(si_t *sih); -extern int si_corepciid(si_t *sih, uint func, uint16 *pcivendor, uint16 *pcidevice, - uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif, uint8 *pciheader); - -#define si_eci_init(sih) (0) -#define si_eci_notify_bt(sih, type, val, interrupt) (0) - - - -extern int si_devpath(si_t *sih, char *path, int size); - -extern char *si_getdevpathvar(si_t *sih, const char *name); -extern int si_getdevpathintvar(si_t *sih, const char *name); - - -extern uint8 si_pcieclkreq(si_t *sih, uint32 mask, uint32 val); -extern void si_war42780_clkreq(si_t *sih, bool clkreq); -extern void si_pci_sleep(si_t *sih); -extern void si_pci_down(si_t *sih); -extern void si_pci_up(si_t *sih); -extern void si_pcie_war_ovr_disable(si_t *sih); -extern void si_pcie_extendL1timer(si_t *sih, bool extend); -extern int si_pci_fixcfg(si_t *sih); - - - - - - - -#endif diff --git a/drivers/net/wireless/bcm4329/include/trxhdr.h b/drivers/net/wireless/bcm4329/include/trxhdr.h deleted file mode 100644 index 8f5eed9410eb..000000000000 --- a/drivers/net/wireless/bcm4329/include/trxhdr.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * TRX image file header format. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: trxhdr.h,v 13.11.310.1 2008/08/17 12:58:58 Exp $ - */ - -#include - -#define TRX_MAGIC 0x30524448 /* "HDR0" */ -#define TRX_VERSION 1 /* Version 1 */ -#define TRX_MAX_LEN 0x3A0000 /* Max length */ -#define TRX_NO_HEADER 1 /* Do not write TRX header */ -#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */ -#define TRX_MAX_OFFSET 3 /* Max number of individual files */ -#define TRX_UNCOMP_IMAGE 0x20 /* Trx contains uncompressed rtecdc.bin image */ - -struct trx_header { - uint32 magic; /* "HDR0" */ - uint32 len; /* Length of file including header */ - uint32 crc32; /* 32-bit CRC from flag_version to end of file */ - uint32 flag_version; /* 0:15 flags, 16:31 version */ - uint32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ -}; - -/* Compatibility */ -typedef struct trx_header TRXHDR, *PTRXHDR; diff --git a/drivers/net/wireless/bcm4329/include/typedefs.h b/drivers/net/wireless/bcm4329/include/typedefs.h deleted file mode 100644 index 4d9dd761ed64..000000000000 --- a/drivers/net/wireless/bcm4329/include/typedefs.h +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * $Id: typedefs.h,v 1.85.34.1.2.5 2009/01/27 04:09:40 Exp $ - */ - - -#ifndef _TYPEDEFS_H_ -#define _TYPEDEFS_H_ - -#ifdef SITE_TYPEDEFS - - - -#include "site_typedefs.h" - -#else - - - -#ifdef __cplusplus - -#define TYPEDEF_BOOL -#ifndef FALSE -#define FALSE false -#endif -#ifndef TRUE -#define TRUE true -#endif - -#else - - -#endif - -#if defined(__x86_64__) -#define TYPEDEF_UINTPTR -typedef unsigned long long int uintptr; -#endif - - - - -#if defined(TARGETOS_nucleus) - -#include - - -#define TYPEDEF_FLOAT_T -#endif - -#if defined(_NEED_SIZE_T_) -typedef long unsigned int size_t; -#endif - -#ifdef __DJGPP__ -typedef long unsigned int size_t; -#endif - - - - - -#define TYPEDEF_UINT -#ifndef TARGETENV_android -#define TYPEDEF_USHORT -#define TYPEDEF_ULONG -#endif -#ifdef __KERNEL__ -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)) -#define TYPEDEF_BOOL -#endif -#endif - - - - - -#if defined(__GNUC__) && defined(__STRICT_ANSI__) -#define TYPEDEF_INT64 -#define TYPEDEF_UINT64 -#endif - - -#if defined(__ICL) - -#define TYPEDEF_INT64 - -#if defined(__STDC__) -#define TYPEDEF_UINT64 -#endif - -#endif - -#if !defined(__DJGPP__) && !defined(TARGETOS_nucleus) - - -#if defined(__KERNEL__) - -#include - -#else - - -#include - -#endif - -#endif - - - - -#define USE_TYPEDEF_DEFAULTS - -#endif - - - - -#ifdef USE_TYPEDEF_DEFAULTS -#undef USE_TYPEDEF_DEFAULTS - -#ifndef TYPEDEF_BOOL -typedef unsigned char bool; -#endif - - - -#ifndef TYPEDEF_UCHAR -typedef unsigned char uchar; -#endif - -#ifndef TYPEDEF_USHORT -typedef unsigned short ushort; -#endif - -#ifndef TYPEDEF_UINT -typedef unsigned int uint; -#endif - -#ifndef TYPEDEF_ULONG -typedef unsigned long ulong; -#endif - - - -#ifndef TYPEDEF_UINT8 -typedef unsigned char uint8; -#endif - -#ifndef TYPEDEF_UINT16 -typedef unsigned short uint16; -#endif - -#ifndef TYPEDEF_UINT32 -typedef unsigned int uint32; -#endif - -#ifndef TYPEDEF_UINT64 -typedef unsigned long long uint64; -#endif - -#ifndef TYPEDEF_UINTPTR -typedef unsigned int uintptr; -#endif - -#ifndef TYPEDEF_INT8 -typedef signed char int8; -#endif - -#ifndef TYPEDEF_INT16 -typedef signed short int16; -#endif - -#ifndef TYPEDEF_INT32 -typedef signed int int32; -#endif - -#ifndef TYPEDEF_INT64 -typedef signed long long int64; -#endif - - - -#ifndef TYPEDEF_FLOAT32 -typedef float float32; -#endif - -#ifndef TYPEDEF_FLOAT64 -typedef double float64; -#endif - - - -#ifndef TYPEDEF_FLOAT_T - -#if defined(FLOAT32) -typedef float32 float_t; -#else -typedef float64 float_t; -#endif - -#endif - - - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef OFF -#define OFF 0 -#endif - -#ifndef ON -#define ON 1 -#endif - -#define AUTO (-1) - - - -#ifndef PTRSZ -#define PTRSZ sizeof(char*) -#endif - - - -#if defined(__GNUC__) - #define BWL_COMPILER_GNU -#elif defined(__CC_ARM) - #define BWL_COMPILER_ARMCC -#else - #error "Unknown compiler!" -#endif - - -#ifndef INLINE - #if defined(BWL_COMPILER_MICROSOFT) - #define INLINE __inline - #elif defined(BWL_COMPILER_GNU) - #define INLINE __inline__ - #elif defined(BWL_COMPILER_ARMCC) - #define INLINE __inline - #else - #define INLINE - #endif -#endif - -#undef TYPEDEF_BOOL -#undef TYPEDEF_UCHAR -#undef TYPEDEF_USHORT -#undef TYPEDEF_UINT -#undef TYPEDEF_ULONG -#undef TYPEDEF_UINT8 -#undef TYPEDEF_UINT16 -#undef TYPEDEF_UINT32 -#undef TYPEDEF_UINT64 -#undef TYPEDEF_UINTPTR -#undef TYPEDEF_INT8 -#undef TYPEDEF_INT16 -#undef TYPEDEF_INT32 -#undef TYPEDEF_INT64 -#undef TYPEDEF_FLOAT32 -#undef TYPEDEF_FLOAT64 -#undef TYPEDEF_FLOAT_T - -#endif - - -#define UNUSED_PARAMETER(x) (void)(x) - - -#include - -#endif diff --git a/drivers/net/wireless/bcm4329/include/wlioctl.h b/drivers/net/wireless/bcm4329/include/wlioctl.h deleted file mode 100644 index 00c61f10782f..000000000000 --- a/drivers/net/wireless/bcm4329/include/wlioctl.h +++ /dev/null @@ -1,1673 +0,0 @@ -/* - * Custom OID/ioctl definitions for - * Broadcom 802.11abg Networking Device Driver - * - * Definitions subject to change without notice. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wlioctl.h,v 1.601.4.15.2.14.2.62.4.3 2011/02/09 23:31:02 Exp $ - */ - - -#ifndef _wlioctl_h_ -#define _wlioctl_h_ - -#include -#include -#include -#include -#include -#include - - - -#define ACTION_FRAME_SIZE 1040 - -typedef struct wl_action_frame { - struct ether_addr da; - uint16 len; - uint32 packetId; - uint8 data[ACTION_FRAME_SIZE]; -} wl_action_frame_t; - -#define WL_WIFI_ACTION_FRAME_SIZE sizeof(struct wl_action_frame) - - -#define BWL_DEFAULT_PACKING -#include - -#define RWL_ACTION_WIFI_CATEGORY 127 -#define RWL_WIFI_OUI_BYTE1 0x90 -#define RWL_WIFI_OUI_BYTE2 0x4C -#define RWL_WIFI_OUI_BYTE3 0x0F -#define RWL_WIFI_ACTION_FRAME_SIZE sizeof(struct dot11_action_wifi_vendor_specific) -#define RWL_WIFI_DEFAULT 0x00 -#define RWL_WIFI_FIND_MY_PEER 0x09 -#define RWL_WIFI_FOUND_PEER 0x0A -#define RWL_ACTION_WIFI_FRAG_TYPE 0x55 - -typedef struct ssid_info -{ - uint8 ssid_len; - uint8 ssid[32]; -} ssid_info_t; - -typedef struct cnt_rx -{ - uint32 cnt_rxundec; - uint32 cnt_rxframe; -} cnt_rx_t; - - - -#define RWL_REF_MAC_ADDRESS_OFFSET 17 -#define RWL_DUT_MAC_ADDRESS_OFFSET 23 -#define RWL_WIFI_CLIENT_CHANNEL_OFFSET 50 -#define RWL_WIFI_SERVER_CHANNEL_OFFSET 51 - - - - - -#define WL_BSS_INFO_VERSION 108 - - -typedef struct wl_bss_info { - uint32 version; - uint32 length; - struct ether_addr BSSID; - uint16 beacon_period; - uint16 capability; - uint8 SSID_len; - uint8 SSID[32]; - struct { - uint count; - uint8 rates[16]; - } rateset; - chanspec_t chanspec; - uint16 atim_window; - uint8 dtim_period; - int16 RSSI; - int8 phy_noise; - - uint8 n_cap; - uint32 nbss_cap; - uint8 ctl_ch; - uint32 reserved32[1]; - uint8 flags; - uint8 reserved[3]; - uint8 basic_mcs[MCSSET_LEN]; - - uint16 ie_offset; - uint32 ie_length; - - -} wl_bss_info_t; - -typedef struct wlc_ssid { - uint32 SSID_len; - uchar SSID[32]; -} wlc_ssid_t; - - -#define WL_BSSTYPE_INFRA 1 -#define WL_BSSTYPE_INDEP 0 -#define WL_BSSTYPE_ANY 2 - - -#define WL_SCANFLAGS_PASSIVE 0x01 -#define WL_SCANFLAGS_PROHIBITED 0x04 - -typedef struct wl_scan_params { - wlc_ssid_t ssid; - struct ether_addr bssid; - int8 bss_type; - int8 scan_type; - int32 nprobes; - int32 active_time; - int32 passive_time; - int32 home_time; - int32 channel_num; - uint16 channel_list[1]; -} wl_scan_params_t; - -#define WL_SCAN_PARAMS_FIXED_SIZE 64 - - -#define WL_SCAN_PARAMS_COUNT_MASK 0x0000ffff -#define WL_SCAN_PARAMS_NSSID_SHIFT 16 - -#define WL_SCAN_ACTION_START 1 -#define WL_SCAN_ACTION_CONTINUE 2 -#define WL_SCAN_ACTION_ABORT 3 - -#define ISCAN_REQ_VERSION 1 - - -typedef struct wl_iscan_params { - uint32 version; - uint16 action; - uint16 scan_duration; - wl_scan_params_t params; -} wl_iscan_params_t; - -#define WL_ISCAN_PARAMS_FIXED_SIZE (OFFSETOF(wl_iscan_params_t, params) + sizeof(wlc_ssid_t)) - -typedef struct wl_scan_results { - uint32 buflen; - uint32 version; - uint32 count; - wl_bss_info_t bss_info[1]; -} wl_scan_results_t; - -#define WL_SCAN_RESULTS_FIXED_SIZE 12 - - -#define WL_SCAN_RESULTS_SUCCESS 0 -#define WL_SCAN_RESULTS_PARTIAL 1 -#define WL_SCAN_RESULTS_PENDING 2 -#define WL_SCAN_RESULTS_ABORTED 3 -#define WL_SCAN_RESULTS_NO_MEM 4 - -#define ESCAN_REQ_VERSION 1 - -typedef struct wl_escan_params { - uint32 version; - uint16 action; - uint16 sync_id; - wl_scan_params_t params; -} wl_escan_params_t; - -#define WL_ESCAN_PARAMS_FIXED_SIZE (OFFSETOF(wl_escan_params_t, params) + sizeof(wlc_ssid_t)) - -typedef struct wl_escan_result { - uint32 buflen; - uint32 version; - uint16 sync_id; - uint16 bss_count; - wl_bss_info_t bss_info[1]; -} wl_escan_result_t; - -#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(wl_escan_result_t) - sizeof(wl_bss_info_t)) - - -typedef struct wl_iscan_results { - uint32 status; - wl_scan_results_t results; -} wl_iscan_results_t; - -#define WL_ISCAN_RESULTS_FIXED_SIZE \ - (WL_SCAN_RESULTS_FIXED_SIZE + OFFSETOF(wl_iscan_results_t, results)) - -#define WL_NUMRATES 16 -typedef struct wl_rateset { - uint32 count; - uint8 rates[WL_NUMRATES]; -} wl_rateset_t; - - -typedef struct wl_uint32_list { - - uint32 count; - - uint32 element[1]; -} wl_uint32_list_t; - - -typedef struct wl_assoc_params { - struct ether_addr bssid; - uint16 bssid_cnt; - int32 chanspec_num; - chanspec_t chanspec_list[1]; -} wl_assoc_params_t; -#define WL_ASSOC_PARAMS_FIXED_SIZE (sizeof(wl_assoc_params_t) - sizeof(chanspec_t)) - - -typedef wl_assoc_params_t wl_reassoc_params_t; -#define WL_REASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE - - -typedef struct wl_join_params { - wlc_ssid_t ssid; - wl_assoc_params_t params; -} wl_join_params_t; -#define WL_JOIN_PARAMS_FIXED_SIZE (sizeof(wl_join_params_t) - sizeof(chanspec_t)) - -#define WLC_CNTRY_BUF_SZ 4 - -typedef struct wl_country { - char country_abbrev[WLC_CNTRY_BUF_SZ]; - int32 rev; - char ccode[WLC_CNTRY_BUF_SZ]; -} wl_country_t; - -typedef enum sup_auth_status { - - WLC_SUP_DISCONNECTED = 0, - WLC_SUP_CONNECTING, - WLC_SUP_IDREQUIRED, - WLC_SUP_AUTHENTICATING, - WLC_SUP_AUTHENTICATED, - WLC_SUP_KEYXCHANGE, - WLC_SUP_KEYED, - WLC_SUP_TIMEOUT, - WLC_SUP_LAST_BASIC_STATE, - - - WLC_SUP_KEYXCHANGE_WAIT_M1 = WLC_SUP_AUTHENTICATED, - - WLC_SUP_KEYXCHANGE_PREP_M2 = WLC_SUP_KEYXCHANGE, - - WLC_SUP_KEYXCHANGE_WAIT_M3 = WLC_SUP_LAST_BASIC_STATE, - - WLC_SUP_KEYXCHANGE_PREP_M4, - WLC_SUP_KEYXCHANGE_WAIT_G1, - WLC_SUP_KEYXCHANGE_PREP_G2 -} sup_auth_status_t; - - -#define CRYPTO_ALGO_OFF 0 -#define CRYPTO_ALGO_WEP1 1 -#define CRYPTO_ALGO_TKIP 2 -#define CRYPTO_ALGO_WEP128 3 -#define CRYPTO_ALGO_AES_CCM 4 -#define CRYPTO_ALGO_AES_OCB_MSDU 5 -#define CRYPTO_ALGO_AES_OCB_MPDU 6 -#define CRYPTO_ALGO_NALG 7 -#define CRYPTO_ALGO_SMS4 11 - -#define WSEC_GEN_MIC_ERROR 0x0001 -#define WSEC_GEN_REPLAY 0x0002 -#define WSEC_GEN_ICV_ERROR 0x0004 - -#define WL_SOFT_KEY (1 << 0) -#define WL_PRIMARY_KEY (1 << 1) -#define WL_KF_RES_4 (1 << 4) -#define WL_KF_RES_5 (1 << 5) -#define WL_IBSS_PEER_GROUP_KEY (1 << 6) - -typedef struct wl_wsec_key { - uint32 index; - uint32 len; - uint8 data[DOT11_MAX_KEY_SIZE]; - uint32 pad_1[18]; - uint32 algo; - uint32 flags; - uint32 pad_2[2]; - int pad_3; - int iv_initialized; - int pad_4; - - struct { - uint32 hi; - uint16 lo; - } rxiv; - uint32 pad_5[2]; - struct ether_addr ea; -} wl_wsec_key_t; - -#define WSEC_MIN_PSK_LEN 8 -#define WSEC_MAX_PSK_LEN 64 - - -#define WSEC_PASSPHRASE (1<<0) - - -typedef struct { - ushort key_len; - ushort flags; - uint8 key[WSEC_MAX_PSK_LEN]; -} wsec_pmk_t; - - -#define WEP_ENABLED 0x0001 -#define TKIP_ENABLED 0x0002 -#define AES_ENABLED 0x0004 -#define WSEC_SWFLAG 0x0008 -#define SES_OW_ENABLED 0x0040 -#define SMS4_ENABLED 0x0100 - - -#define WPA_AUTH_DISABLED 0x0000 -#define WPA_AUTH_NONE 0x0001 -#define WPA_AUTH_UNSPECIFIED 0x0002 -#define WPA_AUTH_PSK 0x0004 - -#define WPA2_AUTH_UNSPECIFIED 0x0040 -#define WPA2_AUTH_PSK 0x0080 -#define BRCM_AUTH_PSK 0x0100 -#define BRCM_AUTH_DPT 0x0200 -#define WPA_AUTH_WAPI 0x0400 - -#define WPA_AUTH_PFN_ANY 0xffffffff - - -#define MAXPMKID 16 - -typedef struct _pmkid { - struct ether_addr BSSID; - uint8 PMKID[WPA2_PMKID_LEN]; -} pmkid_t; - -typedef struct _pmkid_list { - uint32 npmkid; - pmkid_t pmkid[1]; -} pmkid_list_t; - -typedef struct _pmkid_cand { - struct ether_addr BSSID; - uint8 preauth; -} pmkid_cand_t; - -typedef struct _pmkid_cand_list { - uint32 npmkid_cand; - pmkid_cand_t pmkid_cand[1]; -} pmkid_cand_list_t; - - - - -typedef struct { - uint32 val; - struct ether_addr ea; -} scb_val_t; - - - -typedef struct channel_info { - int hw_channel; - int target_channel; - int scan_channel; -} channel_info_t; - - -struct maclist { - uint count; - struct ether_addr ea[1]; -}; - - -typedef struct get_pktcnt { - uint rx_good_pkt; - uint rx_bad_pkt; - uint tx_good_pkt; - uint tx_bad_pkt; - uint rx_ocast_good_pkt; -} get_pktcnt_t; - - -typedef struct wl_ioctl { - uint cmd; - void *buf; - uint len; - uint8 set; - uint used; - uint needed; -} wl_ioctl_t; - - - -#define WLC_IOCTL_MAGIC 0x14e46c77 - - -#define WLC_IOCTL_VERSION 1 - -#define WLC_IOCTL_MAXLEN 8192 -#define WLC_IOCTL_SMLEN 256 -#define WLC_IOCTL_MEDLEN 1536 - - - -#define WLC_GET_MAGIC 0 -#define WLC_GET_VERSION 1 -#define WLC_UP 2 -#define WLC_DOWN 3 -#define WLC_GET_LOOP 4 -#define WLC_SET_LOOP 5 -#define WLC_DUMP 6 -#define WLC_GET_MSGLEVEL 7 -#define WLC_SET_MSGLEVEL 8 -#define WLC_GET_PROMISC 9 -#define WLC_SET_PROMISC 10 - -#define WLC_GET_RATE 12 - -#define WLC_GET_INSTANCE 14 - - - - -#define WLC_GET_INFRA 19 -#define WLC_SET_INFRA 20 -#define WLC_GET_AUTH 21 -#define WLC_SET_AUTH 22 -#define WLC_GET_BSSID 23 -#define WLC_SET_BSSID 24 -#define WLC_GET_SSID 25 -#define WLC_SET_SSID 26 -#define WLC_RESTART 27 - -#define WLC_GET_CHANNEL 29 -#define WLC_SET_CHANNEL 30 -#define WLC_GET_SRL 31 -#define WLC_SET_SRL 32 -#define WLC_GET_LRL 33 -#define WLC_SET_LRL 34 -#define WLC_GET_PLCPHDR 35 -#define WLC_SET_PLCPHDR 36 -#define WLC_GET_RADIO 37 -#define WLC_SET_RADIO 38 -#define WLC_GET_PHYTYPE 39 -#define WLC_DUMP_RATE 40 -#define WLC_SET_RATE_PARAMS 41 - - -#define WLC_GET_KEY 44 -#define WLC_SET_KEY 45 -#define WLC_GET_REGULATORY 46 -#define WLC_SET_REGULATORY 47 -#define WLC_GET_PASSIVE_SCAN 48 -#define WLC_SET_PASSIVE_SCAN 49 -#define WLC_SCAN 50 -#define WLC_SCAN_RESULTS 51 -#define WLC_DISASSOC 52 -#define WLC_REASSOC 53 -#define WLC_GET_ROAM_TRIGGER 54 -#define WLC_SET_ROAM_TRIGGER 55 -#define WLC_GET_ROAM_DELTA 56 -#define WLC_SET_ROAM_DELTA 57 -#define WLC_GET_ROAM_SCAN_PERIOD 58 -#define WLC_SET_ROAM_SCAN_PERIOD 59 -#define WLC_EVM 60 -#define WLC_GET_TXANT 61 -#define WLC_SET_TXANT 62 -#define WLC_GET_ANTDIV 63 -#define WLC_SET_ANTDIV 64 - - -#define WLC_GET_CLOSED 67 -#define WLC_SET_CLOSED 68 -#define WLC_GET_MACLIST 69 -#define WLC_SET_MACLIST 70 -#define WLC_GET_RATESET 71 -#define WLC_SET_RATESET 72 - -#define WLC_LONGTRAIN 74 -#define WLC_GET_BCNPRD 75 -#define WLC_SET_BCNPRD 76 -#define WLC_GET_DTIMPRD 77 -#define WLC_SET_DTIMPRD 78 -#define WLC_GET_SROM 79 -#define WLC_SET_SROM 80 -#define WLC_GET_WEP_RESTRICT 81 -#define WLC_SET_WEP_RESTRICT 82 -#define WLC_GET_COUNTRY 83 -#define WLC_SET_COUNTRY 84 -#define WLC_GET_PM 85 -#define WLC_SET_PM 86 -#define WLC_GET_WAKE 87 -#define WLC_SET_WAKE 88 - -#define WLC_GET_FORCELINK 90 -#define WLC_SET_FORCELINK 91 -#define WLC_FREQ_ACCURACY 92 -#define WLC_CARRIER_SUPPRESS 93 -#define WLC_GET_PHYREG 94 -#define WLC_SET_PHYREG 95 -#define WLC_GET_RADIOREG 96 -#define WLC_SET_RADIOREG 97 -#define WLC_GET_REVINFO 98 -#define WLC_GET_UCANTDIV 99 -#define WLC_SET_UCANTDIV 100 -#define WLC_R_REG 101 -#define WLC_W_REG 102 - - -#define WLC_GET_MACMODE 105 -#define WLC_SET_MACMODE 106 -#define WLC_GET_MONITOR 107 -#define WLC_SET_MONITOR 108 -#define WLC_GET_GMODE 109 -#define WLC_SET_GMODE 110 -#define WLC_GET_LEGACY_ERP 111 -#define WLC_SET_LEGACY_ERP 112 -#define WLC_GET_RX_ANT 113 -#define WLC_GET_CURR_RATESET 114 -#define WLC_GET_SCANSUPPRESS 115 -#define WLC_SET_SCANSUPPRESS 116 -#define WLC_GET_AP 117 -#define WLC_SET_AP 118 -#define WLC_GET_EAP_RESTRICT 119 -#define WLC_SET_EAP_RESTRICT 120 -#define WLC_SCB_AUTHORIZE 121 -#define WLC_SCB_DEAUTHORIZE 122 -#define WLC_GET_WDSLIST 123 -#define WLC_SET_WDSLIST 124 -#define WLC_GET_ATIM 125 -#define WLC_SET_ATIM 126 -#define WLC_GET_RSSI 127 -#define WLC_GET_PHYANTDIV 128 -#define WLC_SET_PHYANTDIV 129 -#define WLC_AP_RX_ONLY 130 -#define WLC_GET_TX_PATH_PWR 131 -#define WLC_SET_TX_PATH_PWR 132 -#define WLC_GET_WSEC 133 -#define WLC_SET_WSEC 134 -#define WLC_GET_PHY_NOISE 135 -#define WLC_GET_BSS_INFO 136 -#define WLC_GET_PKTCNTS 137 -#define WLC_GET_LAZYWDS 138 -#define WLC_SET_LAZYWDS 139 -#define WLC_GET_BANDLIST 140 -#define WLC_GET_BAND 141 -#define WLC_SET_BAND 142 -#define WLC_SCB_DEAUTHENTICATE 143 -#define WLC_GET_SHORTSLOT 144 -#define WLC_GET_SHORTSLOT_OVERRIDE 145 -#define WLC_SET_SHORTSLOT_OVERRIDE 146 -#define WLC_GET_SHORTSLOT_RESTRICT 147 -#define WLC_SET_SHORTSLOT_RESTRICT 148 -#define WLC_GET_GMODE_PROTECTION 149 -#define WLC_GET_GMODE_PROTECTION_OVERRIDE 150 -#define WLC_SET_GMODE_PROTECTION_OVERRIDE 151 -#define WLC_UPGRADE 152 - - -#define WLC_GET_IGNORE_BCNS 155 -#define WLC_SET_IGNORE_BCNS 156 -#define WLC_GET_SCB_TIMEOUT 157 -#define WLC_SET_SCB_TIMEOUT 158 -#define WLC_GET_ASSOCLIST 159 -#define WLC_GET_CLK 160 -#define WLC_SET_CLK 161 -#define WLC_GET_UP 162 -#define WLC_OUT 163 -#define WLC_GET_WPA_AUTH 164 -#define WLC_SET_WPA_AUTH 165 -#define WLC_GET_UCFLAGS 166 -#define WLC_SET_UCFLAGS 167 -#define WLC_GET_PWRIDX 168 -#define WLC_SET_PWRIDX 169 -#define WLC_GET_TSSI 170 -#define WLC_GET_SUP_RATESET_OVERRIDE 171 -#define WLC_SET_SUP_RATESET_OVERRIDE 172 - - - - - -#define WLC_GET_PROTECTION_CONTROL 178 -#define WLC_SET_PROTECTION_CONTROL 179 -#define WLC_GET_PHYLIST 180 -#define WLC_ENCRYPT_STRENGTH 181 -#define WLC_DECRYPT_STATUS 182 -#define WLC_GET_KEY_SEQ 183 -#define WLC_GET_SCAN_CHANNEL_TIME 184 -#define WLC_SET_SCAN_CHANNEL_TIME 185 -#define WLC_GET_SCAN_UNASSOC_TIME 186 -#define WLC_SET_SCAN_UNASSOC_TIME 187 -#define WLC_GET_SCAN_HOME_TIME 188 -#define WLC_SET_SCAN_HOME_TIME 189 -#define WLC_GET_SCAN_NPROBES 190 -#define WLC_SET_SCAN_NPROBES 191 -#define WLC_GET_PRB_RESP_TIMEOUT 192 -#define WLC_SET_PRB_RESP_TIMEOUT 193 -#define WLC_GET_ATTEN 194 -#define WLC_SET_ATTEN 195 -#define WLC_GET_SHMEM 196 -#define WLC_SET_SHMEM 197 - - -#define WLC_SET_WSEC_TEST 200 -#define WLC_SCB_DEAUTHENTICATE_FOR_REASON 201 -#define WLC_TKIP_COUNTERMEASURES 202 -#define WLC_GET_PIOMODE 203 -#define WLC_SET_PIOMODE 204 -#define WLC_SET_ASSOC_PREFER 205 -#define WLC_GET_ASSOC_PREFER 206 -#define WLC_SET_ROAM_PREFER 207 -#define WLC_GET_ROAM_PREFER 208 -#define WLC_SET_LED 209 -#define WLC_GET_LED 210 -#define WLC_GET_INTERFERENCE_MODE 211 -#define WLC_SET_INTERFERENCE_MODE 212 -#define WLC_GET_CHANNEL_QA 213 -#define WLC_START_CHANNEL_QA 214 -#define WLC_GET_CHANNEL_SEL 215 -#define WLC_START_CHANNEL_SEL 216 -#define WLC_GET_VALID_CHANNELS 217 -#define WLC_GET_FAKEFRAG 218 -#define WLC_SET_FAKEFRAG 219 -#define WLC_GET_PWROUT_PERCENTAGE 220 -#define WLC_SET_PWROUT_PERCENTAGE 221 -#define WLC_SET_BAD_FRAME_PREEMPT 222 -#define WLC_GET_BAD_FRAME_PREEMPT 223 -#define WLC_SET_LEAP_LIST 224 -#define WLC_GET_LEAP_LIST 225 -#define WLC_GET_CWMIN 226 -#define WLC_SET_CWMIN 227 -#define WLC_GET_CWMAX 228 -#define WLC_SET_CWMAX 229 -#define WLC_GET_WET 230 -#define WLC_SET_WET 231 -#define WLC_GET_PUB 232 - - -#define WLC_GET_KEY_PRIMARY 235 -#define WLC_SET_KEY_PRIMARY 236 - -#define WLC_GET_ACI_ARGS 238 -#define WLC_SET_ACI_ARGS 239 -#define WLC_UNSET_CALLBACK 240 -#define WLC_SET_CALLBACK 241 -#define WLC_GET_RADAR 242 -#define WLC_SET_RADAR 243 -#define WLC_SET_SPECT_MANAGMENT 244 -#define WLC_GET_SPECT_MANAGMENT 245 -#define WLC_WDS_GET_REMOTE_HWADDR 246 -#define WLC_WDS_GET_WPA_SUP 247 -#define WLC_SET_CS_SCAN_TIMER 248 -#define WLC_GET_CS_SCAN_TIMER 249 -#define WLC_MEASURE_REQUEST 250 -#define WLC_INIT 251 -#define WLC_SEND_QUIET 252 -#define WLC_KEEPALIVE 253 -#define WLC_SEND_PWR_CONSTRAINT 254 -#define WLC_UPGRADE_STATUS 255 -#define WLC_CURRENT_PWR 256 -#define WLC_GET_SCAN_PASSIVE_TIME 257 -#define WLC_SET_SCAN_PASSIVE_TIME 258 -#define WLC_LEGACY_LINK_BEHAVIOR 259 -#define WLC_GET_CHANNELS_IN_COUNTRY 260 -#define WLC_GET_COUNTRY_LIST 261 -#define WLC_GET_VAR 262 -#define WLC_SET_VAR 263 -#define WLC_NVRAM_GET 264 -#define WLC_NVRAM_SET 265 -#define WLC_NVRAM_DUMP 266 -#define WLC_REBOOT 267 -#define WLC_SET_WSEC_PMK 268 -#define WLC_GET_AUTH_MODE 269 -#define WLC_SET_AUTH_MODE 270 -#define WLC_GET_WAKEENTRY 271 -#define WLC_SET_WAKEENTRY 272 -#define WLC_NDCONFIG_ITEM 273 -#define WLC_NVOTPW 274 -#define WLC_OTPW 275 -#define WLC_IOV_BLOCK_GET 276 -#define WLC_IOV_MODULES_GET 277 -#define WLC_SOFT_RESET 278 -#define WLC_GET_ALLOW_MODE 279 -#define WLC_SET_ALLOW_MODE 280 -#define WLC_GET_DESIRED_BSSID 281 -#define WLC_SET_DESIRED_BSSID 282 -#define WLC_DISASSOC_MYAP 283 -#define WLC_GET_NBANDS 284 -#define WLC_GET_BANDSTATES 285 -#define WLC_GET_WLC_BSS_INFO 286 -#define WLC_GET_ASSOC_INFO 287 -#define WLC_GET_OID_PHY 288 -#define WLC_SET_OID_PHY 289 -#define WLC_SET_ASSOC_TIME 290 -#define WLC_GET_DESIRED_SSID 291 -#define WLC_GET_CHANSPEC 292 -#define WLC_GET_ASSOC_STATE 293 -#define WLC_SET_PHY_STATE 294 -#define WLC_GET_SCAN_PENDING 295 -#define WLC_GET_SCANREQ_PENDING 296 -#define WLC_GET_PREV_ROAM_REASON 297 -#define WLC_SET_PREV_ROAM_REASON 298 -#define WLC_GET_BANDSTATES_PI 299 -#define WLC_GET_PHY_STATE 300 -#define WLC_GET_BSS_WPA_RSN 301 -#define WLC_GET_BSS_WPA2_RSN 302 -#define WLC_GET_BSS_BCN_TS 303 -#define WLC_GET_INT_DISASSOC 304 -#define WLC_SET_NUM_PEERS 305 -#define WLC_GET_NUM_BSS 306 -#define WLC_LAST 307 - - - -#define WL_RADIO_SW_DISABLE (1<<0) -#define WL_RADIO_HW_DISABLE (1<<1) -#define WL_RADIO_MPC_DISABLE (1<<2) -#define WL_RADIO_COUNTRY_DISABLE (1<<3) - - -#define WL_TXPWR_OVERRIDE (1U<<31) - -#define WL_PHY_PAVARS_LEN 6 - - -#define WL_DIAG_INTERRUPT 1 -#define WL_DIAG_LOOPBACK 2 -#define WL_DIAG_MEMORY 3 -#define WL_DIAG_LED 4 -#define WL_DIAG_REG 5 -#define WL_DIAG_SROM 6 -#define WL_DIAG_DMA 7 - -#define WL_DIAGERR_SUCCESS 0 -#define WL_DIAGERR_FAIL_TO_RUN 1 -#define WL_DIAGERR_NOT_SUPPORTED 2 -#define WL_DIAGERR_INTERRUPT_FAIL 3 -#define WL_DIAGERR_LOOPBACK_FAIL 4 -#define WL_DIAGERR_SROM_FAIL 5 -#define WL_DIAGERR_SROM_BADCRC 6 -#define WL_DIAGERR_REG_FAIL 7 -#define WL_DIAGERR_MEMORY_FAIL 8 -#define WL_DIAGERR_NOMEM 9 -#define WL_DIAGERR_DMA_FAIL 10 - -#define WL_DIAGERR_MEMORY_TIMEOUT 11 -#define WL_DIAGERR_MEMORY_BADPATTERN 12 - - -#define WLC_BAND_AUTO 0 -#define WLC_BAND_5G 1 -#define WLC_BAND_2G 2 -#define WLC_BAND_ALL 3 - - -#define WL_CHAN_FREQ_RANGE_2G 0 -#define WL_CHAN_FREQ_RANGE_5GL 1 -#define WL_CHAN_FREQ_RANGE_5GM 2 -#define WL_CHAN_FREQ_RANGE_5GH 3 - - -#define WLC_PHY_TYPE_A 0 -#define WLC_PHY_TYPE_B 1 -#define WLC_PHY_TYPE_G 2 -#define WLC_PHY_TYPE_N 4 -#define WLC_PHY_TYPE_LP 5 -#define WLC_PHY_TYPE_SSN 6 -#define WLC_PHY_TYPE_NULL 0xf - - -#define WLC_MACMODE_DISABLED 0 -#define WLC_MACMODE_DENY 1 -#define WLC_MACMODE_ALLOW 2 - - -#define GMODE_LEGACY_B 0 -#define GMODE_AUTO 1 -#define GMODE_ONLY 2 -#define GMODE_B_DEFERRED 3 -#define GMODE_PERFORMANCE 4 -#define GMODE_LRS 5 -#define GMODE_MAX 6 - - -#define WLC_PLCP_AUTO -1 -#define WLC_PLCP_SHORT 0 -#define WLC_PLCP_LONG 1 - - -#define WLC_PROTECTION_AUTO -1 -#define WLC_PROTECTION_OFF 0 -#define WLC_PROTECTION_ON 1 -#define WLC_PROTECTION_MMHDR_ONLY 2 -#define WLC_PROTECTION_CTS_ONLY 3 - - -#define WLC_PROTECTION_CTL_OFF 0 -#define WLC_PROTECTION_CTL_LOCAL 1 -#define WLC_PROTECTION_CTL_OVERLAP 2 - - -#define WLC_N_PROTECTION_OFF 0 -#define WLC_N_PROTECTION_OPTIONAL 1 -#define WLC_N_PROTECTION_20IN40 2 -#define WLC_N_PROTECTION_MIXEDMODE 3 - - -#define WLC_N_PREAMBLE_MIXEDMODE 0 -#define WLC_N_PREAMBLE_GF 1 - - -#define WLC_N_BW_20ALL 0 -#define WLC_N_BW_40ALL 1 -#define WLC_N_BW_20IN2G_40IN5G 2 - - -#define WLC_N_TXRX_CHAIN0 0 -#define WLC_N_TXRX_CHAIN1 1 - - -#define WLC_N_SGI_20 0x01 -#define WLC_N_SGI_40 0x02 - - -#define PM_OFF 0 -#define PM_MAX 1 -#define PM_FAST 2 - -#define LISTEN_INTERVAL 10 - -#define INTERFERE_NONE 0 -#define NON_WLAN 1 -#define WLAN_MANUAL 2 -#define WLAN_AUTO 3 -#define AUTO_ACTIVE (1 << 7) - -typedef struct wl_aci_args { - int enter_aci_thresh; - int exit_aci_thresh; - int usec_spin; - int glitch_delay; - uint16 nphy_adcpwr_enter_thresh; - uint16 nphy_adcpwr_exit_thresh; - uint16 nphy_repeat_ctr; - uint16 nphy_num_samples; - uint16 nphy_undetect_window_sz; - uint16 nphy_b_energy_lo_aci; - uint16 nphy_b_energy_md_aci; - uint16 nphy_b_energy_hi_aci; -} wl_aci_args_t; - -#define WL_ACI_ARGS_LEGACY_LENGTH 16 - - - -#define WL_ERROR_VAL 0x00000001 -#define WL_TRACE_VAL 0x00000002 -#define WL_PRHDRS_VAL 0x00000004 -#define WL_PRPKT_VAL 0x00000008 -#define WL_INFORM_VAL 0x00000010 -#define WL_TMP_VAL 0x00000020 -#define WL_OID_VAL 0x00000040 -#define WL_RATE_VAL 0x00000080 -#define WL_ASSOC_VAL 0x00000100 -#define WL_PRUSR_VAL 0x00000200 -#define WL_PS_VAL 0x00000400 -#define WL_TXPWR_VAL 0x00000800 -#define WL_PORT_VAL 0x00001000 -#define WL_DUAL_VAL 0x00002000 -#define WL_WSEC_VAL 0x00004000 -#define WL_WSEC_DUMP_VAL 0x00008000 -#define WL_LOG_VAL 0x00010000 -#define WL_NRSSI_VAL 0x00020000 -#define WL_LOFT_VAL 0x00040000 -#define WL_REGULATORY_VAL 0x00080000 -#define WL_PHYCAL_VAL 0x00100000 -#define WL_RADAR_VAL 0x00200000 -#define WL_MPC_VAL 0x00400000 -#define WL_APSTA_VAL 0x00800000 -#define WL_DFS_VAL 0x01000000 -#define WL_BA_VAL 0x02000000 -#define WL_MBSS_VAL 0x04000000 -#define WL_CAC_VAL 0x08000000 -#define WL_AMSDU_VAL 0x10000000 -#define WL_AMPDU_VAL 0x20000000 -#define WL_FFPLD_VAL 0x40000000 - - -#define WL_DPT_VAL 0x00000001 -#define WL_SCAN_VAL 0x00000002 -#define WL_WOWL_VAL 0x00000004 -#define WL_COEX_VAL 0x00000008 -#define WL_RTDC_VAL 0x00000010 -#define WL_BTA_VAL 0x00000040 - - -#define WL_LED_NUMGPIO 16 - - -#define WL_LED_OFF 0 -#define WL_LED_ON 1 -#define WL_LED_ACTIVITY 2 -#define WL_LED_RADIO 3 -#define WL_LED_ARADIO 4 -#define WL_LED_BRADIO 5 -#define WL_LED_BGMODE 6 -#define WL_LED_WI1 7 -#define WL_LED_WI2 8 -#define WL_LED_WI3 9 -#define WL_LED_ASSOC 10 -#define WL_LED_INACTIVE 11 -#define WL_LED_ASSOCACT 12 -#define WL_LED_NUMBEHAVIOR 13 - - -#define WL_LED_BEH_MASK 0x7f -#define WL_LED_AL_MASK 0x80 - - -#define WL_NUMCHANNELS 64 -#define WL_NUMCHANSPECS 100 - - -#define WL_WDS_WPA_ROLE_AUTH 0 -#define WL_WDS_WPA_ROLE_SUP 1 -#define WL_WDS_WPA_ROLE_AUTO 255 - - -#define WL_EVENTING_MASK_LEN 16 - - -#define VNDR_IE_CMD_LEN 4 - - -#define VNDR_IE_BEACON_FLAG 0x1 -#define VNDR_IE_PRBRSP_FLAG 0x2 -#define VNDR_IE_ASSOCRSP_FLAG 0x4 -#define VNDR_IE_AUTHRSP_FLAG 0x8 -#define VNDR_IE_PRBREQ_FLAG 0x10 -#define VNDR_IE_ASSOCREQ_FLAG 0x20 -#define VNDR_IE_CUSTOM_FLAG 0x100 - -#define VNDR_IE_INFO_HDR_LEN (sizeof(uint32)) - -typedef struct { - uint32 pktflag; - vndr_ie_t vndr_ie_data; -} vndr_ie_info_t; - -typedef struct { - int iecount; - vndr_ie_info_t vndr_ie_list[1]; -} vndr_ie_buf_t; - -typedef struct { - char cmd[VNDR_IE_CMD_LEN]; - vndr_ie_buf_t vndr_ie_buffer; -} vndr_ie_setbuf_t; - - - - -#define WL_JOIN_PREF_RSSI 1 -#define WL_JOIN_PREF_WPA 2 -#define WL_JOIN_PREF_BAND 3 - - -#define WLJP_BAND_ASSOC_PREF 255 - - -#define WL_WPA_ACP_MCS_ANY "\x00\x00\x00\x00" - -struct tsinfo_arg { - uint8 octets[3]; -}; - - -#define NFIFO 6 - -#define WL_CNT_T_VERSION 5 -#define WL_CNT_EXT_T_VERSION 1 - -typedef struct { - uint16 version; - uint16 length; - - - uint32 txframe; - uint32 txbyte; - uint32 txretrans; - uint32 txerror; - uint32 txctl; - uint32 txprshort; - uint32 txserr; - uint32 txnobuf; - uint32 txnoassoc; - uint32 txrunt; - uint32 txchit; - uint32 txcmiss; - - - uint32 txuflo; - uint32 txphyerr; - uint32 txphycrs; - - - uint32 rxframe; - uint32 rxbyte; - uint32 rxerror; - uint32 rxctl; - uint32 rxnobuf; - uint32 rxnondata; - uint32 rxbadds; - uint32 rxbadcm; - uint32 rxfragerr; - uint32 rxrunt; - uint32 rxgiant; - uint32 rxnoscb; - uint32 rxbadproto; - uint32 rxbadsrcmac; - uint32 rxbadda; - uint32 rxfilter; - - - uint32 rxoflo; - uint32 rxuflo[NFIFO]; - - uint32 d11cnt_txrts_off; - uint32 d11cnt_rxcrc_off; - uint32 d11cnt_txnocts_off; - - - uint32 dmade; - uint32 dmada; - uint32 dmape; - uint32 reset; - uint32 tbtt; - uint32 txdmawar; - uint32 pkt_callback_reg_fail; - - - uint32 txallfrm; - uint32 txrtsfrm; - uint32 txctsfrm; - uint32 txackfrm; - uint32 txdnlfrm; - uint32 txbcnfrm; - uint32 txfunfl[8]; - uint32 txtplunfl; - uint32 txphyerror; - uint32 rxfrmtoolong; - uint32 rxfrmtooshrt; - uint32 rxinvmachdr; - uint32 rxbadfcs; - uint32 rxbadplcp; - uint32 rxcrsglitch; - uint32 rxstrt; - uint32 rxdfrmucastmbss; - uint32 rxmfrmucastmbss; - uint32 rxcfrmucast; - uint32 rxrtsucast; - uint32 rxctsucast; - uint32 rxackucast; - uint32 rxdfrmocast; - uint32 rxmfrmocast; - uint32 rxcfrmocast; - uint32 rxrtsocast; - uint32 rxctsocast; - uint32 rxdfrmmcast; - uint32 rxmfrmmcast; - uint32 rxcfrmmcast; - uint32 rxbeaconmbss; - uint32 rxdfrmucastobss; - uint32 rxbeaconobss; - uint32 rxrsptmout; - uint32 bcntxcancl; - uint32 rxf0ovfl; - uint32 rxf1ovfl; - uint32 rxf2ovfl; - uint32 txsfovfl; - uint32 pmqovfl; - uint32 rxcgprqfrm; - uint32 rxcgprsqovfl; - uint32 txcgprsfail; - uint32 txcgprssuc; - uint32 prs_timeout; - uint32 rxnack; - uint32 frmscons; - uint32 txnack; - uint32 txglitch_nack; - uint32 txburst; - - - uint32 txfrag; - uint32 txmulti; - uint32 txfail; - uint32 txretry; - uint32 txretrie; - uint32 rxdup; - uint32 txrts; - uint32 txnocts; - uint32 txnoack; - uint32 rxfrag; - uint32 rxmulti; - uint32 rxcrc; - uint32 txfrmsnt; - uint32 rxundec; - - - uint32 tkipmicfaill; - uint32 tkipcntrmsr; - uint32 tkipreplay; - uint32 ccmpfmterr; - uint32 ccmpreplay; - uint32 ccmpundec; - uint32 fourwayfail; - uint32 wepundec; - uint32 wepicverr; - uint32 decsuccess; - uint32 tkipicverr; - uint32 wepexcluded; - - uint32 txchanrej; - uint32 psmwds; - uint32 phywatchdog; - - - uint32 prq_entries_handled; - uint32 prq_undirected_entries; - uint32 prq_bad_entries; - uint32 atim_suppress_count; - uint32 bcn_template_not_ready; - uint32 bcn_template_not_ready_done; - uint32 late_tbtt_dpc; - - - uint32 rx1mbps; - uint32 rx2mbps; - uint32 rx5mbps5; - uint32 rx6mbps; - uint32 rx9mbps; - uint32 rx11mbps; - uint32 rx12mbps; - uint32 rx18mbps; - uint32 rx24mbps; - uint32 rx36mbps; - uint32 rx48mbps; - uint32 rx54mbps; - uint32 rx108mbps; - uint32 rx162mbps; - uint32 rx216mbps; - uint32 rx270mbps; - uint32 rx324mbps; - uint32 rx378mbps; - uint32 rx432mbps; - uint32 rx486mbps; - uint32 rx540mbps; - - uint32 pktengrxducast; - uint32 pktengrxdmcast; -} wl_cnt_t; - -typedef struct { - uint16 version; - uint16 length; - - uint32 rxampdu_sgi; - uint32 rxampdu_stbc; - uint32 rxmpdu_sgi; - uint32 rxmpdu_stbc; - uint32 rxmcs0_40M; - uint32 rxmcs1_40M; - uint32 rxmcs2_40M; - uint32 rxmcs3_40M; - uint32 rxmcs4_40M; - uint32 rxmcs5_40M; - uint32 rxmcs6_40M; - uint32 rxmcs7_40M; - uint32 rxmcs32_40M; - - uint32 txfrmsnt_20Mlo; - uint32 txfrmsnt_20Mup; - uint32 txfrmsnt_40M; - - uint32 rx_20ul; -} wl_cnt_ext_t; - -#define WL_RXDIV_STATS_T_VERSION 1 -typedef struct { - uint16 version; - uint16 length; - - uint32 rxant[4]; -} wl_rxdiv_stats_t; - -#define WL_DELTA_STATS_T_VERSION 1 - -typedef struct { - uint16 version; - uint16 length; - - - uint32 txframe; - uint32 txbyte; - uint32 txretrans; - uint32 txfail; - - - uint32 rxframe; - uint32 rxbyte; - - - uint32 rx1mbps; - uint32 rx2mbps; - uint32 rx5mbps5; - uint32 rx6mbps; - uint32 rx9mbps; - uint32 rx11mbps; - uint32 rx12mbps; - uint32 rx18mbps; - uint32 rx24mbps; - uint32 rx36mbps; - uint32 rx48mbps; - uint32 rx54mbps; - uint32 rx108mbps; - uint32 rx162mbps; - uint32 rx216mbps; - uint32 rx270mbps; - uint32 rx324mbps; - uint32 rx378mbps; - uint32 rx432mbps; - uint32 rx486mbps; - uint32 rx540mbps; -} wl_delta_stats_t; - -#define WL_WME_CNT_VERSION 1 - -typedef struct { - uint32 packets; - uint32 bytes; -} wl_traffic_stats_t; - -typedef struct { - uint16 version; - uint16 length; - - wl_traffic_stats_t tx[AC_COUNT]; - wl_traffic_stats_t tx_failed[AC_COUNT]; - wl_traffic_stats_t rx[AC_COUNT]; - wl_traffic_stats_t rx_failed[AC_COUNT]; - - wl_traffic_stats_t forward[AC_COUNT]; - - wl_traffic_stats_t tx_expired[AC_COUNT]; - -} wl_wme_cnt_t; - - - -#define WLC_ROAM_TRIGGER_DEFAULT 0 -#define WLC_ROAM_TRIGGER_BANDWIDTH 1 -#define WLC_ROAM_TRIGGER_DISTANCE 2 -#define WLC_ROAM_TRIGGER_MAX_VALUE 2 - - -enum { - PFN_LIST_ORDER, - PFN_RSSI -}; - -enum { - DISABLE, - ENABLE -}; - -#define SORT_CRITERIA_BIT 0 -#define AUTO_NET_SWITCH_BIT 1 -#define ENABLE_BKGRD_SCAN_BIT 2 -#define IMMEDIATE_SCAN_BIT 3 -#define AUTO_CONNECT_BIT 4 -#define ENABLE_BD_SCAN_BIT 5 -#define ENABLE_ADAPTSCAN_BIT 6 - -#define SORT_CRITERIA_MASK 0x01 -#define AUTO_NET_SWITCH_MASK 0x02 -#define ENABLE_BKGRD_SCAN_MASK 0x04 -#define IMMEDIATE_SCAN_MASK 0x08 -#define AUTO_CONNECT_MASK 0x10 -#define ENABLE_BD_SCAN_MASK 0x20 -#define ENABLE_ADAPTSCAN_MASK 0x40 - -#define PFN_VERSION 1 - -#define MAX_PFN_LIST_COUNT 16 - - -typedef struct wl_pfn_param { - int32 version; - int32 scan_freq; - int32 lost_network_timeout; - int16 flags; - int16 rssi_margin; - int32 repeat_scan; - int32 max_freq_adjust; -} wl_pfn_param_t; - -typedef struct wl_pfn { - wlc_ssid_t ssid; - int32 bss_type; - int32 infra; - int32 auth; - uint32 wpa_auth; - int32 wsec; -} wl_pfn_t; - -#define PNO_SCAN_MAX_FW 508*1000 -#define PNO_SCAN_MAX_FW_SEC PNO_SCAN_MAX_FW/1000 -#define PNO_SCAN_MIN_FW_SEC 10 - - -#define TOE_TX_CSUM_OL 0x00000001 -#define TOE_RX_CSUM_OL 0x00000002 - - -#define TOE_ERRTEST_TX_CSUM 0x00000001 -#define TOE_ERRTEST_RX_CSUM 0x00000002 -#define TOE_ERRTEST_RX_CSUM2 0x00000004 - -struct toe_ol_stats_t { - - uint32 tx_summed; - - - uint32 tx_iph_fill; - uint32 tx_tcp_fill; - uint32 tx_udp_fill; - uint32 tx_icmp_fill; - - - uint32 rx_iph_good; - uint32 rx_iph_bad; - uint32 rx_tcp_good; - uint32 rx_tcp_bad; - uint32 rx_udp_good; - uint32 rx_udp_bad; - uint32 rx_icmp_good; - uint32 rx_icmp_bad; - - - uint32 tx_tcp_errinj; - uint32 tx_udp_errinj; - uint32 tx_icmp_errinj; - - - uint32 rx_tcp_errinj; - uint32 rx_udp_errinj; - uint32 rx_icmp_errinj; -}; - - -#define ARP_OL_AGENT 0x00000001 -#define ARP_OL_SNOOP 0x00000002 -#define ARP_OL_HOST_AUTO_REPLY 0x00000004 -#define ARP_OL_PEER_AUTO_REPLY 0x00000008 - - -#define ARP_ERRTEST_REPLY_PEER 0x1 -#define ARP_ERRTEST_REPLY_HOST 0x2 - -#define ARP_MULTIHOMING_MAX 8 - - -struct arp_ol_stats_t { - uint32 host_ip_entries; - uint32 host_ip_overflow; - - uint32 arp_table_entries; - uint32 arp_table_overflow; - - uint32 host_request; - uint32 host_reply; - uint32 host_service; - - uint32 peer_request; - uint32 peer_request_drop; - uint32 peer_reply; - uint32 peer_reply_drop; - uint32 peer_service; -}; - - - - - -typedef struct wl_keep_alive_pkt { - uint32 period_msec; - uint16 len_bytes; - uint8 data[1]; -} wl_keep_alive_pkt_t; - -#define WL_KEEP_ALIVE_FIXED_LEN OFFSETOF(wl_keep_alive_pkt_t, data) - - - - - -typedef enum wl_pkt_filter_type { - WL_PKT_FILTER_TYPE_PATTERN_MATCH -} wl_pkt_filter_type_t; - -#define WL_PKT_FILTER_TYPE wl_pkt_filter_type_t - - -typedef struct wl_pkt_filter_pattern { - uint32 offset; - uint32 size_bytes; - uint8 mask_and_pattern[1]; -} wl_pkt_filter_pattern_t; - - -typedef struct wl_pkt_filter { - uint32 id; - uint32 type; - uint32 negate_match; - union { - wl_pkt_filter_pattern_t pattern; - } u; -} wl_pkt_filter_t; - -#define WL_PKT_FILTER_FIXED_LEN OFFSETOF(wl_pkt_filter_t, u) -#define WL_PKT_FILTER_PATTERN_FIXED_LEN OFFSETOF(wl_pkt_filter_pattern_t, mask_and_pattern) - - -typedef struct wl_pkt_filter_enable { - uint32 id; - uint32 enable; -} wl_pkt_filter_enable_t; - - -typedef struct wl_pkt_filter_list { - uint32 num; - wl_pkt_filter_t filter[1]; -} wl_pkt_filter_list_t; - -#define WL_PKT_FILTER_LIST_FIXED_LEN OFFSETOF(wl_pkt_filter_list_t, filter) - - -typedef struct wl_pkt_filter_stats { - uint32 num_pkts_matched; - uint32 num_pkts_forwarded; - uint32 num_pkts_discarded; -} wl_pkt_filter_stats_t; - - -typedef struct wl_seq_cmd_ioctl { - uint32 cmd; - uint32 len; -} wl_seq_cmd_ioctl_t; - -#define WL_SEQ_CMD_ALIGN_BYTES 4 - - -#define WL_SEQ_CMDS_GET_IOCTL_FILTER(cmd) \ - (((cmd) == WLC_GET_MAGIC) || \ - ((cmd) == WLC_GET_VERSION) || \ - ((cmd) == WLC_GET_AP) || \ - ((cmd) == WLC_GET_INSTANCE)) - - - -#define WL_PKTENG_PER_TX_START 0x01 -#define WL_PKTENG_PER_TX_STOP 0x02 -#define WL_PKTENG_PER_RX_START 0x04 -#define WL_PKTENG_PER_RX_WITH_ACK_START 0x05 -#define WL_PKTENG_PER_TX_WITH_ACK_START 0x06 -#define WL_PKTENG_PER_RX_STOP 0x08 -#define WL_PKTENG_PER_MASK 0xff - -#define WL_PKTENG_SYNCHRONOUS 0x100 - -typedef struct wl_pkteng { - uint32 flags; - uint32 delay; - uint32 nframes; - uint32 length; - uint8 seqno; - struct ether_addr dest; - struct ether_addr src; -} wl_pkteng_t; - -#define NUM_80211b_RATES 4 -#define NUM_80211ag_RATES 8 -#define NUM_80211n_RATES 32 -#define NUM_80211_RATES (NUM_80211b_RATES+NUM_80211ag_RATES+NUM_80211n_RATES) -typedef struct wl_pkteng_stats { - uint32 lostfrmcnt; - int32 rssi; - int32 snr; - uint16 rxpktcnt[NUM_80211_RATES+1]; -} wl_pkteng_stats_t; - -#define WL_WOWL_MAGIC (1 << 0) -#define WL_WOWL_NET (1 << 1) -#define WL_WOWL_DIS (1 << 2) -#define WL_WOWL_RETR (1 << 3) -#define WL_WOWL_BCN (1 << 4) -#define WL_WOWL_TST (1 << 5) -#define WL_WOWL_BCAST (1 << 15) - -#define MAGIC_PKT_MINLEN 102 - -typedef struct { - uint masksize; - uint offset; - uint patternoffset; - uint patternsize; - - -} wl_wowl_pattern_t; - -typedef struct { - uint count; - wl_wowl_pattern_t pattern[1]; -} wl_wowl_pattern_list_t; - -typedef struct { - uint8 pci_wakeind; - uint16 ucode_wakeind; -} wl_wowl_wakeind_t; - - -typedef struct wl_txrate_class { - uint8 init_rate; - uint8 min_rate; - uint8 max_rate; -} wl_txrate_class_t; - - - - -#define WLC_OBSS_SCAN_PASSIVE_DWELL_DEFAULT 100 -#define WLC_OBSS_SCAN_PASSIVE_DWELL_MIN 5 -#define WLC_OBSS_SCAN_PASSIVE_DWELL_MAX 1000 -#define WLC_OBSS_SCAN_ACTIVE_DWELL_DEFAULT 20 -#define WLC_OBSS_SCAN_ACTIVE_DWELL_MIN 10 -#define WLC_OBSS_SCAN_ACTIVE_DWELL_MAX 1000 -#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_DEFAULT 300 -#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MIN 10 -#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MAX 900 -#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_DEFAULT 5 -#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MIN 5 -#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MAX 100 -#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_DEFAULT 200 -#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MIN 200 -#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MAX 10000 -#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_DEFAULT 20 -#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MIN 20 -#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MAX 10000 -#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_DEFAULT 25 -#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MIN 0 -#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MAX 100 - - -typedef struct wl_obss_scan_arg { - int16 passive_dwell; - int16 active_dwell; - int16 bss_widthscan_interval; - int16 passive_total; - int16 active_total; - int16 chanwidth_transition_delay; - int16 activity_threshold; -} wl_obss_scan_arg_t; -#define WL_OBSS_SCAN_PARAM_LEN sizeof(wl_obss_scan_arg_t) -#define WL_MIN_NUM_OBSS_SCAN_ARG 7 - -#define WL_COEX_INFO_MASK 0x07 -#define WL_COEX_INFO_REQ 0x01 -#define WL_COEX_40MHZ_INTOLERANT 0x02 -#define WL_COEX_WIDTH20 0x04 - -typedef struct wl_action_obss_coex_req { - uint8 info; - uint8 num; - uint8 ch_list[1]; -} wl_action_obss_coex_req_t; - - -#define MAX_RSSI_LEVELS 8 - - -typedef struct wl_rssi_event { - - uint32 rate_limit_msec; - - uint8 num_rssi_levels; - - int8 rssi_levels[MAX_RSSI_LEVELS]; -} wl_rssi_event_t; - - - -#define WLFEATURE_DISABLE_11N 0x00000001 -#define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002 -#define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004 -#define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008 -#define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010 -#define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020 -#define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040 -#define WLFEATURE_DISABLE_11N_GF 0x00000080 - - - -#include - - -#include - - -typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_hdr { - struct ether_addr staAddr; - uint16 ieLen; -} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_hdr_t; - -typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_data { - sta_prbreq_wps_ie_hdr_t hdr; - uint8 ieData[1]; -} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_data_t; - -typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_list { - uint32 totLen; - uint8 ieDataList[1]; -} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_list_t; - - -#include - -#endif diff --git a/drivers/net/wireless/bcm4329/linux_osl.c b/drivers/net/wireless/bcm4329/linux_osl.c deleted file mode 100644 index cf72a077bd90..000000000000 --- a/drivers/net/wireless/bcm4329/linux_osl.c +++ /dev/null @@ -1,625 +0,0 @@ -/* - * Linux OS Independent Layer - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: linux_osl.c,v 1.125.12.3.8.7 2010/05/04 21:10:04 Exp $ - */ - - -#define LINUX_OSL - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PCI_CFG_RETRY 10 - -#define OS_HANDLE_MAGIC 0x1234abcd -#define BCM_MEM_FILENAME_LEN 24 - -#ifdef DHD_USE_STATIC_BUF -#define MAX_STATIC_BUF_NUM 16 -#define STATIC_BUF_SIZE (PAGE_SIZE*2) -#define STATIC_BUF_TOTAL_LEN (MAX_STATIC_BUF_NUM*STATIC_BUF_SIZE) -typedef struct bcm_static_buf { - struct mutex static_sem; - unsigned char *buf_ptr; - unsigned char buf_use[MAX_STATIC_BUF_NUM]; -} bcm_static_buf_t; - -static bcm_static_buf_t *bcm_static_buf = 0; - -#define MAX_STATIC_PKT_NUM 8 -typedef struct bcm_static_pkt { - struct sk_buff *skb_4k[MAX_STATIC_PKT_NUM]; - struct sk_buff *skb_8k[MAX_STATIC_PKT_NUM]; - struct mutex osl_pkt_sem; - unsigned char pkt_use[MAX_STATIC_PKT_NUM*2]; -} bcm_static_pkt_t; -static bcm_static_pkt_t *bcm_static_skb = 0; - -#endif -typedef struct bcm_mem_link { - struct bcm_mem_link *prev; - struct bcm_mem_link *next; - uint size; - int line; - char file[BCM_MEM_FILENAME_LEN]; -} bcm_mem_link_t; - -struct osl_info { - osl_pubinfo_t pub; - uint magic; - void *pdev; - uint malloced; - uint failed; - uint bustype; - bcm_mem_link_t *dbgmem_list; -}; - -static int16 linuxbcmerrormap[] = -{ 0, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -E2BIG, - -E2BIG, - -EBUSY, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EFAULT, - -ENOMEM, - -EOPNOTSUPP, - -EMSGSIZE, - -EINVAL, - -EPERM, - -ENOMEM, - -EINVAL, - -ERANGE, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EIO, - -ENODEV, - -EINVAL, - -EIO, - -EIO, - -EINVAL, - -EINVAL, - - - -#if BCME_LAST != -41 -#error "You need to add a OS error translation in the linuxbcmerrormap \ - for new error code defined in bcmutils.h" -#endif -}; - - -int -osl_error(int bcmerror) -{ - if (bcmerror > 0) - bcmerror = 0; - else if (bcmerror < BCME_LAST) - bcmerror = BCME_ERROR; - - - return linuxbcmerrormap[-bcmerror]; -} - -void * dhd_os_prealloc(int section, unsigned long size); -osl_t * -osl_attach(void *pdev, uint bustype, bool pkttag) -{ - osl_t *osh; - gfp_t flags; - - flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; - osh = kmalloc(sizeof(osl_t), flags); - ASSERT(osh); - - bzero(osh, sizeof(osl_t)); - - - ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1)); - - osh->magic = OS_HANDLE_MAGIC; - osh->malloced = 0; - osh->failed = 0; - osh->dbgmem_list = NULL; - osh->pdev = pdev; - osh->pub.pkttag = pkttag; - osh->bustype = bustype; - - switch (bustype) { - case PCI_BUS: - case SI_BUS: - case PCMCIA_BUS: - osh->pub.mmbus = TRUE; - break; - case JTAG_BUS: - case SDIO_BUS: - case USB_BUS: - case SPI_BUS: - osh->pub.mmbus = FALSE; - break; - default: - ASSERT(FALSE); - break; - } - -#ifdef DHD_USE_STATIC_BUF - - - if (!bcm_static_buf) { - if (!(bcm_static_buf = (bcm_static_buf_t *)dhd_os_prealloc(3, STATIC_BUF_SIZE+ - STATIC_BUF_TOTAL_LEN))) { - printk("can not alloc static buf!\n"); - } - else { - /* printk("alloc static buf at %x!\n", (unsigned int)bcm_static_buf); */ - } - - mutex_init(&bcm_static_buf->static_sem); - - - bcm_static_buf->buf_ptr = (unsigned char *)bcm_static_buf + STATIC_BUF_SIZE; - - } - - if (!bcm_static_skb) - { - int i; - void *skb_buff_ptr = 0; - bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048); - skb_buff_ptr = dhd_os_prealloc(4, 0); - - bcopy(skb_buff_ptr, bcm_static_skb, sizeof(struct sk_buff *)*16); - for (i = 0; i < MAX_STATIC_PKT_NUM*2; i++) - bcm_static_skb->pkt_use[i] = 0; - - mutex_init(&bcm_static_skb->osl_pkt_sem); - } -#endif - return osh; -} - -void -osl_detach(osl_t *osh) -{ - if (osh == NULL) - return; - -#ifdef DHD_USE_STATIC_BUF - if (bcm_static_buf) { - bcm_static_buf = 0; - } - if (bcm_static_skb) { - bcm_static_skb = 0; - } -#endif - ASSERT(osh->magic == OS_HANDLE_MAGIC); - kfree(osh); -} - - -void* -osl_pktget(osl_t *osh, uint len) -{ - struct sk_buff *skb; - gfp_t flags; - - flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; - if ((skb = __dev_alloc_skb(len, flags))) { - skb_put(skb, len); - skb->priority = 0; - - - osh->pub.pktalloced++; - } - - return ((void*) skb); -} - - -void -osl_pktfree(osl_t *osh, void *p, bool send) -{ - struct sk_buff *skb, *nskb; - - skb = (struct sk_buff*) p; - - if (send && osh->pub.tx_fn) - osh->pub.tx_fn(osh->pub.tx_ctx, p, 0); - - - while (skb) { - nskb = skb->next; - skb->next = NULL; - - - if (skb->destructor) { - - dev_kfree_skb_any(skb); - } else { - - dev_kfree_skb(skb); - } - - osh->pub.pktalloced--; - - skb = nskb; - } -} - -#ifdef DHD_USE_STATIC_BUF -void* -osl_pktget_static(osl_t *osh, uint len) -{ - int i = 0; - struct sk_buff *skb; - - - if (len > (PAGE_SIZE*2)) - { - printk("Do we really need this big skb??\n"); - return osl_pktget(osh, len); - } - - - mutex_lock(&bcm_static_skb->osl_pkt_sem); - if (len <= PAGE_SIZE) - { - - for (i = 0; i < MAX_STATIC_PKT_NUM; i++) - { - if (bcm_static_skb->pkt_use[i] == 0) - break; - } - - if (i != MAX_STATIC_PKT_NUM) - { - bcm_static_skb->pkt_use[i] = 1; - mutex_unlock(&bcm_static_skb->osl_pkt_sem); - - skb = bcm_static_skb->skb_4k[i]; - skb->tail = skb->data + len; - skb->len = len; - - return skb; - } - } - - - for (i = 0; i < MAX_STATIC_PKT_NUM; i++) - { - if (bcm_static_skb->pkt_use[i+MAX_STATIC_PKT_NUM] == 0) - break; - } - - if (i != MAX_STATIC_PKT_NUM) - { - bcm_static_skb->pkt_use[i+MAX_STATIC_PKT_NUM] = 1; - mutex_unlock(&bcm_static_skb->osl_pkt_sem); - skb = bcm_static_skb->skb_8k[i]; - skb->tail = skb->data + len; - skb->len = len; - - return skb; - } - - - - mutex_unlock(&bcm_static_skb->osl_pkt_sem); - printk("all static pkt in use!\n"); - return osl_pktget(osh, len); -} - - -void -osl_pktfree_static(osl_t *osh, void *p, bool send) -{ - int i; - - for (i = 0; i < MAX_STATIC_PKT_NUM*2; i++) - { - if (p == bcm_static_skb->skb_4k[i]) - { - mutex_lock(&bcm_static_skb->osl_pkt_sem); - bcm_static_skb->pkt_use[i] = 0; - mutex_unlock(&bcm_static_skb->osl_pkt_sem); - - - return; - } - } - return osl_pktfree(osh, p, send); -} -#endif -uint32 -osl_pci_read_config(osl_t *osh, uint offset, uint size) -{ - uint val = 0; - uint retry = PCI_CFG_RETRY; - - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - - - ASSERT(size == 4); - - do { - pci_read_config_dword(osh->pdev, offset, &val); - if (val != 0xffffffff) - break; - } while (retry--); - - - return (val); -} - -void -osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) -{ - uint retry = PCI_CFG_RETRY; - - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - - - ASSERT(size == 4); - - do { - pci_write_config_dword(osh->pdev, offset, val); - if (offset != PCI_BAR0_WIN) - break; - if (osl_pci_read_config(osh, offset, size) == val) - break; - } while (retry--); - -} - - -uint -osl_pci_bus(osl_t *osh) -{ - ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); - - return ((struct pci_dev *)osh->pdev)->bus->number; -} - - -uint -osl_pci_slot(osl_t *osh) -{ - ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); - - return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); -} - -static void -osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write) -{ -} - -void -osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size) -{ - osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE); -} - -void -osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size) -{ - osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE); -} - - - -void* -osl_malloc(osl_t *osh, uint size) -{ - void *addr; - gfp_t flags; - - if (osh) - ASSERT(osh->magic == OS_HANDLE_MAGIC); - -#ifdef DHD_USE_STATIC_BUF - if (bcm_static_buf) - { - int i = 0; - if ((size >= PAGE_SIZE)&&(size <= STATIC_BUF_SIZE)) - { - mutex_lock(&bcm_static_buf->static_sem); - - for (i = 0; i < MAX_STATIC_BUF_NUM; i++) - { - if (bcm_static_buf->buf_use[i] == 0) - break; - } - - if (i == MAX_STATIC_BUF_NUM) - { - mutex_unlock(&bcm_static_buf->static_sem); - printk("all static buff in use!\n"); - goto original; - } - - bcm_static_buf->buf_use[i] = 1; - mutex_unlock(&bcm_static_buf->static_sem); - - bzero(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i, size); - if (osh) - osh->malloced += size; - - return ((void *)(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i)); - } - } -original: -#endif - flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; - if ((addr = kmalloc(size, flags)) == NULL) { - if (osh) - osh->failed++; - return (NULL); - } - if (osh) - osh->malloced += size; - - return (addr); -} - -void -osl_mfree(osl_t *osh, void *addr, uint size) -{ -#ifdef DHD_USE_STATIC_BUF - if (bcm_static_buf) - { - if ((addr > (void *)bcm_static_buf) && ((unsigned char *)addr - <= ((unsigned char *)bcm_static_buf + STATIC_BUF_TOTAL_LEN))) - { - int buf_idx = 0; - - buf_idx = ((unsigned char *)addr - bcm_static_buf->buf_ptr)/STATIC_BUF_SIZE; - - mutex_lock(&bcm_static_buf->static_sem); - bcm_static_buf->buf_use[buf_idx] = 0; - mutex_unlock(&bcm_static_buf->static_sem); - - if (osh) { - ASSERT(osh->magic == OS_HANDLE_MAGIC); - osh->malloced -= size; - } - return; - } - } -#endif - if (osh) { - ASSERT(osh->magic == OS_HANDLE_MAGIC); - osh->malloced -= size; - } - kfree(addr); -} - -uint -osl_malloced(osl_t *osh) -{ - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - return (osh->malloced); -} - -uint -osl_malloc_failed(osl_t *osh) -{ - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - return (osh->failed); -} - -void* -osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap) -{ - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - - return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap)); -} - -void -osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa) -{ - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - - pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa); -} - -uint -osl_dma_map(osl_t *osh, void *va, uint size, int direction) -{ - int dir; - - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; - return (pci_map_single(osh->pdev, va, size, dir)); -} - -void -osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction) -{ - int dir; - - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; - pci_unmap_single(osh->pdev, (uint32)pa, size, dir); -} - - -void -osl_delay(uint usec) -{ - uint d; - - while (usec > 0) { - d = MIN(usec, 1000); - udelay(d); - usec -= d; - } -} - - - -void * -osl_pktdup(osl_t *osh, void *skb) -{ - void * p; - gfp_t flags; - - flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; - if ((p = skb_clone((struct sk_buff*)skb, flags)) == NULL) - return NULL; - - - if (osh->pub.pkttag) - bzero((void*)((struct sk_buff *)p)->cb, OSL_PKTTAG_SZ); - - - osh->pub.pktalloced++; - return (p); -} diff --git a/drivers/net/wireless/bcm4329/miniopt.c b/drivers/net/wireless/bcm4329/miniopt.c deleted file mode 100644 index 6a184a75f06b..000000000000 --- a/drivers/net/wireless/bcm4329/miniopt.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Description. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * $Id: miniopt.c,v 1.1.6.4 2009/09/25 00:32:01 Exp $ - */ - -/* ---- Include Files ---------------------------------------------------- */ - -#include -#include -#include -#include -#include "miniopt.h" - - -/* ---- Public Variables ------------------------------------------------- */ -/* ---- Private Constants and Types -------------------------------------- */ - - - -/* ---- Private Variables ------------------------------------------------ */ -/* ---- Private Function Prototypes -------------------------------------- */ -/* ---- Functions -------------------------------------------------------- */ - -/* ----------------------------------------------------------------------- */ -void -miniopt_init(miniopt_t *t, const char* name, const char* flags, bool longflags) -{ - static const char *null_flags = ""; - - memset(t, 0, sizeof(miniopt_t)); - t->name = name; - if (flags == NULL) - t->flags = null_flags; - else - t->flags = flags; - t->longflags = longflags; -} - - -/* ----------------------------------------------------------------------- */ -int -miniopt(miniopt_t *t, char **argv) -{ - int keylen; - char *p, *eq, *valstr, *endptr = NULL; - int err = 0; - - t->consumed = 0; - t->positional = FALSE; - memset(t->key, 0, MINIOPT_MAXKEY); - t->opt = '\0'; - t->valstr = NULL; - t->good_int = FALSE; - valstr = NULL; - - if (*argv == NULL) { - err = -1; - goto exit; - } - - p = *argv++; - t->consumed++; - - if (!t->opt_end && !strcmp(p, "--")) { - t->opt_end = TRUE; - if (*argv == NULL) { - err = -1; - goto exit; - } - p = *argv++; - t->consumed++; - } - - if (t->opt_end) { - t->positional = TRUE; - valstr = p; - } - else if (!strncmp(p, "--", 2)) { - eq = strchr(p, '='); - if (eq == NULL && !t->longflags) { - fprintf(stderr, - "%s: missing \" = \" in long param \"%s\"\n", t->name, p); - err = 1; - goto exit; - } - keylen = eq ? (eq - (p + 2)) : (int)strlen(p) - 2; - if (keylen > 63) keylen = 63; - memcpy(t->key, p + 2, keylen); - - if (eq) { - valstr = eq + 1; - if (*valstr == '\0') { - fprintf(stderr, - "%s: missing value after \" = \" in long param \"%s\"\n", - t->name, p); - err = 1; - goto exit; - } - } - } - else if (!strncmp(p, "-", 1)) { - t->opt = p[1]; - if (strlen(p) > 2) { - fprintf(stderr, - "%s: only single char options, error on param \"%s\"\n", - t->name, p); - err = 1; - goto exit; - } - if (strchr(t->flags, t->opt)) { - /* this is a flag option, no value expected */ - valstr = NULL; - } else { - if (*argv == NULL) { - fprintf(stderr, - "%s: missing value parameter after \"%s\"\n", t->name, p); - err = 1; - goto exit; - } - valstr = *argv; - argv++; - t->consumed++; - } - } else { - t->positional = TRUE; - valstr = p; - } - - /* parse valstr as int just in case */ - if (valstr) { - t->uval = (uint)strtoul(valstr, &endptr, 0); - t->val = (int)t->uval; - t->good_int = (*endptr == '\0'); - } - - t->valstr = valstr; - -exit: - if (err == 1) - t->opt = '?'; - - return err; -} diff --git a/drivers/net/wireless/bcm4329/sbutils.c b/drivers/net/wireless/bcm4329/sbutils.c deleted file mode 100644 index 46cd51010b78..000000000000 --- a/drivers/net/wireless/bcm4329/sbutils.c +++ /dev/null @@ -1,1004 +0,0 @@ -/* - * Misc utility routines for accessing chip-specific features - * of the SiliconBackplane-based Broadcom chips. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sbutils.c,v 1.662.4.10.2.7.4.2 2010/04/19 05:48:48 Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "siutils_priv.h" - -/* local prototypes */ -static uint _sb_coreidx(si_info_t *sii, uint32 sba); -static uint _sb_scan(si_info_t *sii, uint32 sba, void *regs, uint bus, uint32 sbba, - uint ncores); -static uint32 _sb_coresba(si_info_t *sii); -static void *_sb_setcoreidx(si_info_t *sii, uint coreidx); - -#define SET_SBREG(sii, r, mask, val) \ - W_SBREG((sii), (r), ((R_SBREG((sii), (r)) & ~(mask)) | (val))) -#define REGS2SB(va) (sbconfig_t*) ((int8*)(va) + SBCONFIGOFF) - -/* sonicsrev */ -#define SONICS_2_2 (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT) -#define SONICS_2_3 (SBIDL_RV_2_3 >> SBIDL_RV_SHIFT) - -#define R_SBREG(sii, sbr) sb_read_sbreg((sii), (sbr)) -#define W_SBREG(sii, sbr, v) sb_write_sbreg((sii), (sbr), (v)) -#define AND_SBREG(sii, sbr, v) W_SBREG((sii), (sbr), (R_SBREG((sii), (sbr)) & (v))) -#define OR_SBREG(sii, sbr, v) W_SBREG((sii), (sbr), (R_SBREG((sii), (sbr)) | (v))) - -static uint32 -sb_read_sbreg(si_info_t *sii, volatile uint32 *sbr) -{ - uint8 tmp; - uint32 val, intr_val = 0; - - - /* - * compact flash only has 11 bits address, while we needs 12 bits address. - * MEM_SEG will be OR'd with other 11 bits address in hardware, - * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). - * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special - */ - if (PCMCIA(sii)) { - INTR_OFF(sii, intr_val); - tmp = 1; - OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1); - sbr = (volatile uint32 *)((uintptr)sbr & ~(1 << 11)); /* mask out bit 11 */ - } - - val = R_REG(sii->osh, sbr); - - if (PCMCIA(sii)) { - tmp = 0; - OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1); - INTR_RESTORE(sii, intr_val); - } - - return (val); -} - -static void -sb_write_sbreg(si_info_t *sii, volatile uint32 *sbr, uint32 v) -{ - uint8 tmp; - volatile uint32 dummy; - uint32 intr_val = 0; - - - /* - * compact flash only has 11 bits address, while we needs 12 bits address. - * MEM_SEG will be OR'd with other 11 bits address in hardware, - * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). - * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special - */ - if (PCMCIA(sii)) { - INTR_OFF(sii, intr_val); - tmp = 1; - OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1); - sbr = (volatile uint32 *)((uintptr)sbr & ~(1 << 11)); /* mask out bit 11 */ - } - - if (BUSTYPE(sii->pub.bustype) == PCMCIA_BUS) { -#ifdef IL_BIGENDIAN - dummy = R_REG(sii->osh, sbr); - W_REG(sii->osh, ((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); - dummy = R_REG(sii->osh, sbr); - W_REG(sii->osh, (volatile uint16 *)sbr, (uint16)(v & 0xffff)); -#else - dummy = R_REG(sii->osh, sbr); - W_REG(sii->osh, (volatile uint16 *)sbr, (uint16)(v & 0xffff)); - dummy = R_REG(sii->osh, sbr); - W_REG(sii->osh, ((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); -#endif /* IL_BIGENDIAN */ - } else - W_REG(sii->osh, sbr, v); - - if (PCMCIA(sii)) { - tmp = 0; - OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1); - INTR_RESTORE(sii, intr_val); - } -} - -uint -sb_coreid(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - return ((R_SBREG(sii, &sb->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT); -} - -uint -sb_flag(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - return R_SBREG(sii, &sb->sbtpsflag) & SBTPS_NUM0_MASK; -} - -void -sb_setint(si_t *sih, int siflag) -{ - si_info_t *sii; - sbconfig_t *sb; - uint32 vec; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - if (siflag == -1) - vec = 0; - else - vec = 1 << siflag; - W_SBREG(sii, &sb->sbintvec, vec); -} - -/* return core index of the core with address 'sba' */ -static uint -_sb_coreidx(si_info_t *sii, uint32 sba) -{ - uint i; - - for (i = 0; i < sii->numcores; i ++) - if (sba == sii->common_info->coresba[i]) - return i; - return BADIDX; -} - -/* return core address of the current core */ -static uint32 -_sb_coresba(si_info_t *sii) -{ - uint32 sbaddr; - - - switch (BUSTYPE(sii->pub.bustype)) { - case SI_BUS: { - sbconfig_t *sb = REGS2SB(sii->curmap); - sbaddr = sb_base(R_SBREG(sii, &sb->sbadmatch0)); - break; - } - - case PCI_BUS: - sbaddr = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32)); - break; - - case PCMCIA_BUS: { - uint8 tmp = 0; - OSL_PCMCIA_READ_ATTR(sii->osh, PCMCIA_ADDR0, &tmp, 1); - sbaddr = (uint32)tmp << 12; - OSL_PCMCIA_READ_ATTR(sii->osh, PCMCIA_ADDR1, &tmp, 1); - sbaddr |= (uint32)tmp << 16; - OSL_PCMCIA_READ_ATTR(sii->osh, PCMCIA_ADDR2, &tmp, 1); - sbaddr |= (uint32)tmp << 24; - break; - } - - case SPI_BUS: - case SDIO_BUS: - sbaddr = (uint32)(uintptr)sii->curmap; - break; - - - default: - sbaddr = BADCOREADDR; - break; - } - - return sbaddr; -} - -uint -sb_corevendor(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - return ((R_SBREG(sii, &sb->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT); -} - -uint -sb_corerev(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - uint sbidh; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - sbidh = R_SBREG(sii, &sb->sbidhigh); - - return (SBCOREREV(sbidh)); -} - -/* set core-specific control flags */ -void -sb_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - sbconfig_t *sb; - uint32 w; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - ASSERT((val & ~mask) == 0); - - /* mask and set */ - w = (R_SBREG(sii, &sb->sbtmstatelow) & ~(mask << SBTML_SICF_SHIFT)) | - (val << SBTML_SICF_SHIFT); - W_SBREG(sii, &sb->sbtmstatelow, w); -} - -/* set/clear core-specific control flags */ -uint32 -sb_core_cflags(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - sbconfig_t *sb; - uint32 w; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - ASSERT((val & ~mask) == 0); - - /* mask and set */ - if (mask || val) { - w = (R_SBREG(sii, &sb->sbtmstatelow) & ~(mask << SBTML_SICF_SHIFT)) | - (val << SBTML_SICF_SHIFT); - W_SBREG(sii, &sb->sbtmstatelow, w); - } - - /* return the new value - * for write operation, the following readback ensures the completion of write opration. - */ - return (R_SBREG(sii, &sb->sbtmstatelow) >> SBTML_SICF_SHIFT); -} - -/* set/clear core-specific status flags */ -uint32 -sb_core_sflags(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - sbconfig_t *sb; - uint32 w; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - ASSERT((val & ~mask) == 0); - ASSERT((mask & ~SISF_CORE_BITS) == 0); - - /* mask and set */ - if (mask || val) { - w = (R_SBREG(sii, &sb->sbtmstatehigh) & ~(mask << SBTMH_SISF_SHIFT)) | - (val << SBTMH_SISF_SHIFT); - W_SBREG(sii, &sb->sbtmstatehigh, w); - } - - /* return the new value */ - return (R_SBREG(sii, &sb->sbtmstatehigh) >> SBTMH_SISF_SHIFT); -} - -bool -sb_iscoreup(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - return ((R_SBREG(sii, &sb->sbtmstatelow) & - (SBTML_RESET | SBTML_REJ_MASK | (SICF_CLOCK_EN << SBTML_SICF_SHIFT))) == - (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); -} - -/* - * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, - * switch back to the original core, and return the new value. - * - * When using the silicon backplane, no fidleing with interrupts or core switches are needed. - * - * Also, when using pci/pcie, we can optimize away the core switching for pci registers - * and (on newer pci cores) chipcommon registers. - */ -uint -sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) -{ - uint origidx = 0; - uint32 *r = NULL; - uint w; - uint intr_val = 0; - bool fast = FALSE; - si_info_t *sii; - - sii = SI_INFO(sih); - - ASSERT(GOODIDX(coreidx)); - ASSERT(regoff < SI_CORE_SIZE); - ASSERT((val & ~mask) == 0); - - if (coreidx >= SI_MAXCORES) - return 0; - - if (BUSTYPE(sii->pub.bustype) == SI_BUS) { - /* If internal bus, we can always get at everything */ - fast = TRUE; - /* map if does not exist */ - if (!sii->common_info->regs[coreidx]) { - sii->common_info->regs[coreidx] = - REG_MAP(sii->common_info->coresba[coreidx], SI_CORE_SIZE); - ASSERT(GOODREGS(sii->common_info->regs[coreidx])); - } - r = (uint32 *)((uchar *)sii->common_info->regs[coreidx] + regoff); - } else if (BUSTYPE(sii->pub.bustype) == PCI_BUS) { - /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */ - - if ((sii->common_info->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) { - /* Chipc registers are mapped at 12KB */ - - fast = TRUE; - r = (uint32 *)((char *)sii->curmap + PCI_16KB0_CCREGS_OFFSET + regoff); - } else if (sii->pub.buscoreidx == coreidx) { - /* pci registers are at either in the last 2KB of an 8KB window - * or, in pcie and pci rev 13 at 8KB - */ - fast = TRUE; - if (SI_FAST(sii)) - r = (uint32 *)((char *)sii->curmap + - PCI_16KB0_PCIREGS_OFFSET + regoff); - else - r = (uint32 *)((char *)sii->curmap + - ((regoff >= SBCONFIGOFF) ? - PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) + - regoff); - } - } - - if (!fast) { - INTR_OFF(sii, intr_val); - - /* save current core index */ - origidx = si_coreidx(&sii->pub); - - /* switch core */ - r = (uint32*) ((uchar*)sb_setcoreidx(&sii->pub, coreidx) + regoff); - } - ASSERT(r != NULL); - - /* mask and set */ - if (mask || val) { - if (regoff >= SBCONFIGOFF) { - w = (R_SBREG(sii, r) & ~mask) | val; - W_SBREG(sii, r, w); - } else { - w = (R_REG(sii->osh, r) & ~mask) | val; - W_REG(sii->osh, r, w); - } - } - - /* readback */ - if (regoff >= SBCONFIGOFF) - w = R_SBREG(sii, r); - else { - if ((CHIPID(sii->pub.chip) == BCM5354_CHIP_ID) && - (coreidx == SI_CC_IDX) && - (regoff == OFFSETOF(chipcregs_t, watchdog))) { - w = val; - } else - w = R_REG(sii->osh, r); - } - - if (!fast) { - /* restore core index */ - if (origidx != coreidx) - sb_setcoreidx(&sii->pub, origidx); - - INTR_RESTORE(sii, intr_val); - } - - return (w); -} - -/* Scan the enumeration space to find all cores starting from the given - * bus 'sbba'. Append coreid and other info to the lists in 'si'. 'sba' - * is the default core address at chip POR time and 'regs' is the virtual - * address that the default core is mapped at. 'ncores' is the number of - * cores expected on bus 'sbba'. It returns the total number of cores - * starting from bus 'sbba', inclusive. - */ -#define SB_MAXBUSES 2 -static uint -_sb_scan(si_info_t *sii, uint32 sba, void *regs, uint bus, uint32 sbba, uint numcores) -{ - uint next; - uint ncc = 0; - uint i; - - if (bus >= SB_MAXBUSES) { - SI_ERROR(("_sb_scan: bus 0x%08x at level %d is too deep to scan\n", sbba, bus)); - return 0; - } - SI_MSG(("_sb_scan: scan bus 0x%08x assume %u cores\n", sbba, numcores)); - - /* Scan all cores on the bus starting from core 0. - * Core addresses must be contiguous on each bus. - */ - for (i = 0, next = sii->numcores; i < numcores && next < SB_BUS_MAXCORES; i++, next++) { - sii->common_info->coresba[next] = sbba + (i * SI_CORE_SIZE); - - /* keep and reuse the initial register mapping */ - if ((BUSTYPE(sii->pub.bustype) == SI_BUS) && - (sii->common_info->coresba[next] == sba)) { - SI_MSG(("_sb_scan: reuse mapped regs %p for core %u\n", regs, next)); - sii->common_info->regs[next] = regs; - } - - /* change core to 'next' and read its coreid */ - sii->curmap = _sb_setcoreidx(sii, next); - sii->curidx = next; - - sii->common_info->coreid[next] = sb_coreid(&sii->pub); - - /* core specific processing... */ - /* chipc provides # cores */ - if (sii->common_info->coreid[next] == CC_CORE_ID) { - chipcregs_t *cc = (chipcregs_t *)sii->curmap; - uint32 ccrev = sb_corerev(&sii->pub); - - /* determine numcores - this is the total # cores in the chip */ - if (((ccrev == 4) || (ccrev >= 6))) - numcores = (R_REG(sii->osh, &cc->chipid) & CID_CC_MASK) >> - CID_CC_SHIFT; - else { - /* Older chips */ - uint chip = sii->pub.chip; - - if (chip == BCM4306_CHIP_ID) /* < 4306c0 */ - numcores = 6; - else if (chip == BCM4704_CHIP_ID) - numcores = 9; - else if (chip == BCM5365_CHIP_ID) - numcores = 7; - else { - SI_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", - chip)); - ASSERT(0); - numcores = 1; - } - } - SI_MSG(("_sb_scan: there are %u cores in the chip %s\n", numcores, - sii->pub.issim ? "QT" : "")); - } - /* scan bridged SB(s) and add results to the end of the list */ - else if (sii->common_info->coreid[next] == OCP_CORE_ID) { - sbconfig_t *sb = REGS2SB(sii->curmap); - uint32 nsbba = R_SBREG(sii, &sb->sbadmatch1); - uint nsbcc; - - sii->numcores = next + 1; - - if ((nsbba & 0xfff00000) != SI_ENUM_BASE) - continue; - nsbba &= 0xfffff000; - if (_sb_coreidx(sii, nsbba) != BADIDX) - continue; - - nsbcc = (R_SBREG(sii, &sb->sbtmstatehigh) & 0x000f0000) >> 16; - nsbcc = _sb_scan(sii, sba, regs, bus + 1, nsbba, nsbcc); - if (sbba == SI_ENUM_BASE) - numcores -= nsbcc; - ncc += nsbcc; - } - } - - SI_MSG(("_sb_scan: found %u cores on bus 0x%08x\n", i, sbba)); - - sii->numcores = i + ncc; - return sii->numcores; -} - -/* scan the sb enumerated space to identify all cores */ -void -sb_scan(si_t *sih, void *regs, uint devid) -{ - si_info_t *sii; - uint32 origsba; - - sii = SI_INFO(sih); - - /* Save the current core info and validate it later till we know - * for sure what is good and what is bad. - */ - origsba = _sb_coresba(sii); - - /* scan all SB(s) starting from SI_ENUM_BASE */ - sii->numcores = _sb_scan(sii, origsba, regs, 0, SI_ENUM_BASE, 1); -} - -/* - * This function changes logical "focus" to the indicated core; - * must be called with interrupts off. - * Moreover, callers should keep interrupts off during switching out of and back to d11 core - */ -void * -sb_setcoreidx(si_t *sih, uint coreidx) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - if (coreidx >= sii->numcores) - return (NULL); - - /* - * If the user has provided an interrupt mask enabled function, - * then assert interrupts are disabled before switching the core. - */ - ASSERT((sii->intrsenabled_fn == NULL) || !(*(sii)->intrsenabled_fn)((sii)->intr_arg)); - - sii->curmap = _sb_setcoreidx(sii, coreidx); - sii->curidx = coreidx; - - return (sii->curmap); -} - -/* This function changes the logical "focus" to the indicated core. - * Return the current core's virtual address. - */ -static void * -_sb_setcoreidx(si_info_t *sii, uint coreidx) -{ - uint32 sbaddr = sii->common_info->coresba[coreidx]; - void *regs; - - switch (BUSTYPE(sii->pub.bustype)) { - case SI_BUS: - /* map new one */ - if (!sii->common_info->regs[coreidx]) { - sii->common_info->regs[coreidx] = REG_MAP(sbaddr, SI_CORE_SIZE); - ASSERT(GOODREGS(sii->common_info->regs[coreidx])); - } - regs = sii->common_info->regs[coreidx]; - break; - - case PCI_BUS: - /* point bar0 window */ - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, sbaddr); - regs = sii->curmap; - break; - - case PCMCIA_BUS: { - uint8 tmp = (sbaddr >> 12) & 0x0f; - OSL_PCMCIA_WRITE_ATTR(sii->osh, PCMCIA_ADDR0, &tmp, 1); - tmp = (sbaddr >> 16) & 0xff; - OSL_PCMCIA_WRITE_ATTR(sii->osh, PCMCIA_ADDR1, &tmp, 1); - tmp = (sbaddr >> 24) & 0xff; - OSL_PCMCIA_WRITE_ATTR(sii->osh, PCMCIA_ADDR2, &tmp, 1); - regs = sii->curmap; - break; - } - case SPI_BUS: - case SDIO_BUS: - /* map new one */ - if (!sii->common_info->regs[coreidx]) { - sii->common_info->regs[coreidx] = (void *)(uintptr)sbaddr; - ASSERT(GOODREGS(sii->common_info->regs[coreidx])); - } - regs = sii->common_info->regs[coreidx]; - break; - - - default: - ASSERT(0); - regs = NULL; - break; - } - - return regs; -} - -/* Return the address of sbadmatch0/1/2/3 register */ -static volatile uint32 * -sb_admatch(si_info_t *sii, uint asidx) -{ - sbconfig_t *sb; - volatile uint32 *addrm; - - sb = REGS2SB(sii->curmap); - - switch (asidx) { - case 0: - addrm = &sb->sbadmatch0; - break; - - case 1: - addrm = &sb->sbadmatch1; - break; - - case 2: - addrm = &sb->sbadmatch2; - break; - - case 3: - addrm = &sb->sbadmatch3; - break; - - default: - SI_ERROR(("%s: Address space index (%d) out of range\n", __FUNCTION__, asidx)); - return 0; - } - - return (addrm); -} - -/* Return the number of address spaces in current core */ -int -sb_numaddrspaces(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - /* + 1 because of enumeration space */ - return ((R_SBREG(sii, &sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT) + 1; -} - -/* Return the address of the nth address space in the current core */ -uint32 -sb_addrspace(si_t *sih, uint asidx) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - return (sb_base(R_SBREG(sii, sb_admatch(sii, asidx)))); -} - -/* Return the size of the nth address space in the current core */ -uint32 -sb_addrspacesize(si_t *sih, uint asidx) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - return (sb_size(R_SBREG(sii, sb_admatch(sii, asidx)))); -} - - -/* do buffered registers update */ -void -sb_commit(si_t *sih) -{ - si_info_t *sii; - uint origidx; - uint intr_val = 0; - - sii = SI_INFO(sih); - - origidx = sii->curidx; - ASSERT(GOODIDX(origidx)); - - INTR_OFF(sii, intr_val); - - /* switch over to chipcommon core if there is one, else use pci */ - if (sii->pub.ccrev != NOREV) { - chipcregs_t *ccregs = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); - - /* do the buffer registers update */ - W_REG(sii->osh, &ccregs->broadcastaddress, SB_COMMIT); - W_REG(sii->osh, &ccregs->broadcastdata, 0x0); - } else - ASSERT(0); - - /* restore core index */ - sb_setcoreidx(sih, origidx); - INTR_RESTORE(sii, intr_val); -} - -void -sb_core_disable(si_t *sih, uint32 bits) -{ - si_info_t *sii; - volatile uint32 dummy; - sbconfig_t *sb; - - sii = SI_INFO(sih); - - ASSERT(GOODREGS(sii->curmap)); - sb = REGS2SB(sii->curmap); - - /* if core is already in reset, just return */ - if (R_SBREG(sii, &sb->sbtmstatelow) & SBTML_RESET) - return; - - /* if clocks are not enabled, put into reset and return */ - if ((R_SBREG(sii, &sb->sbtmstatelow) & (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) == 0) - goto disable; - - /* set target reject and spin until busy is clear (preserve core-specific bits) */ - OR_SBREG(sii, &sb->sbtmstatelow, SBTML_REJ); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - OSL_DELAY(1); - SPINWAIT((R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000); - if (R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_BUSY) - SI_ERROR(("%s: target state still busy\n", __FUNCTION__)); - - if (R_SBREG(sii, &sb->sbidlow) & SBIDL_INIT) { - OR_SBREG(sii, &sb->sbimstate, SBIM_RJ); - dummy = R_SBREG(sii, &sb->sbimstate); - OSL_DELAY(1); - SPINWAIT((R_SBREG(sii, &sb->sbimstate) & SBIM_BY), 100000); - } - - /* set reset and reject while enabling the clocks */ - W_SBREG(sii, &sb->sbtmstatelow, - (((bits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | - SBTML_REJ | SBTML_RESET)); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - OSL_DELAY(10); - - /* don't forget to clear the initiator reject bit */ - if (R_SBREG(sii, &sb->sbidlow) & SBIDL_INIT) - AND_SBREG(sii, &sb->sbimstate, ~SBIM_RJ); - -disable: - /* leave reset and reject asserted */ - W_SBREG(sii, &sb->sbtmstatelow, ((bits << SBTML_SICF_SHIFT) | SBTML_REJ | SBTML_RESET)); - OSL_DELAY(1); -} - -/* reset and re-enable a core - * inputs: - * bits - core specific bits that are set during and after reset sequence - * resetbits - core specific bits that are set only during reset sequence - */ -void -sb_core_reset(si_t *sih, uint32 bits, uint32 resetbits) -{ - si_info_t *sii; - sbconfig_t *sb; - volatile uint32 dummy; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curmap)); - sb = REGS2SB(sii->curmap); - - /* - * Must do the disable sequence first to work for arbitrary current core state. - */ - sb_core_disable(sih, (bits | resetbits)); - - /* - * Now do the initialization sequence. - */ - - /* set reset while enabling the clock and forcing them on throughout the core */ - W_SBREG(sii, &sb->sbtmstatelow, - (((bits | resetbits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | - SBTML_RESET)); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - OSL_DELAY(1); - - if (R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_SERR) { - W_SBREG(sii, &sb->sbtmstatehigh, 0); - } - if ((dummy = R_SBREG(sii, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) { - AND_SBREG(sii, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO)); - } - - /* clear reset and allow it to propagate throughout the core */ - W_SBREG(sii, &sb->sbtmstatelow, - ((bits | resetbits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT)); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - OSL_DELAY(1); - - /* leave clock enabled */ - W_SBREG(sii, &sb->sbtmstatelow, ((bits | SICF_CLOCK_EN) << SBTML_SICF_SHIFT)); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - OSL_DELAY(1); -} - -void -sb_core_tofixup(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - - if ((BUSTYPE(sii->pub.bustype) != PCI_BUS) || PCIE(sii) || - (PCI(sii) && (sii->pub.buscorerev >= 5))) - return; - - ASSERT(GOODREGS(sii->curmap)); - sb = REGS2SB(sii->curmap); - - if (BUSTYPE(sii->pub.bustype) == SI_BUS) { - SET_SBREG(sii, &sb->sbimconfiglow, - SBIMCL_RTO_MASK | SBIMCL_STO_MASK, - (0x5 << SBIMCL_RTO_SHIFT) | 0x3); - } else { - if (sb_coreid(sih) == PCI_CORE_ID) { - SET_SBREG(sii, &sb->sbimconfiglow, - SBIMCL_RTO_MASK | SBIMCL_STO_MASK, - (0x3 << SBIMCL_RTO_SHIFT) | 0x2); - } else { - SET_SBREG(sii, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0); - } - } - - sb_commit(sih); -} - -/* - * Set the initiator timeout for the "master core". - * The master core is defined to be the core in control - * of the chip and so it issues accesses to non-memory - * locations (Because of dma *any* core can access memeory). - * - * The routine uses the bus to decide who is the master: - * SI_BUS => mips - * JTAG_BUS => chipc - * PCI_BUS => pci or pcie - * PCMCIA_BUS => pcmcia - * SDIO_BUS => pcmcia - * - * This routine exists so callers can disable initiator - * timeouts so accesses to very slow devices like otp - * won't cause an abort. The routine allows arbitrary - * settings of the service and request timeouts, though. - * - * Returns the timeout state before changing it or -1 - * on error. - */ - -#define TO_MASK (SBIMCL_RTO_MASK | SBIMCL_STO_MASK) - -uint32 -sb_set_initiator_to(si_t *sih, uint32 to, uint idx) -{ - si_info_t *sii; - uint origidx; - uint intr_val = 0; - uint32 tmp, ret = 0xffffffff; - sbconfig_t *sb; - - sii = SI_INFO(sih); - - if ((to & ~TO_MASK) != 0) - return ret; - - /* Figure out the master core */ - if (idx == BADIDX) { - switch (BUSTYPE(sii->pub.bustype)) { - case PCI_BUS: - idx = sii->pub.buscoreidx; - break; - case JTAG_BUS: - idx = SI_CC_IDX; - break; - case PCMCIA_BUS: - case SDIO_BUS: - idx = si_findcoreidx(sih, PCMCIA_CORE_ID, 0); - break; - case SI_BUS: - idx = si_findcoreidx(sih, MIPS33_CORE_ID, 0); - break; - default: - ASSERT(0); - } - if (idx == BADIDX) - return ret; - } - - INTR_OFF(sii, intr_val); - origidx = si_coreidx(sih); - - sb = REGS2SB(sb_setcoreidx(sih, idx)); - - tmp = R_SBREG(sii, &sb->sbimconfiglow); - ret = tmp & TO_MASK; - W_SBREG(sii, &sb->sbimconfiglow, (tmp & ~TO_MASK) | to); - - sb_commit(sih); - sb_setcoreidx(sih, origidx); - INTR_RESTORE(sii, intr_val); - return ret; -} - -uint32 -sb_base(uint32 admatch) -{ - uint32 base; - uint type; - - type = admatch & SBAM_TYPE_MASK; - ASSERT(type < 3); - - base = 0; - - if (type == 0) { - base = admatch & SBAM_BASE0_MASK; - } else if (type == 1) { - ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ - base = admatch & SBAM_BASE1_MASK; - } else if (type == 2) { - ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ - base = admatch & SBAM_BASE2_MASK; - } - - return (base); -} - -uint32 -sb_size(uint32 admatch) -{ - uint32 size; - uint type; - - type = admatch & SBAM_TYPE_MASK; - ASSERT(type < 3); - - size = 0; - - if (type == 0) { - size = 1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) + 1); - } else if (type == 1) { - ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ - size = 1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) + 1); - } else if (type == 2) { - ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ - size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1); - } - - return (size); -} diff --git a/drivers/net/wireless/bcm4329/siutils.c b/drivers/net/wireless/bcm4329/siutils.c deleted file mode 100644 index 1814db0f9dd6..000000000000 --- a/drivers/net/wireless/bcm4329/siutils.c +++ /dev/null @@ -1,1527 +0,0 @@ -/* - * Misc utility routines for accessing chip-specific features - * of the SiliconBackplane-based Broadcom chips. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: siutils.c,v 1.662.4.4.4.16.4.28 2010/06/23 21:37:54 Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "siutils_priv.h" - -/* local prototypes */ -static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs, - uint bustype, void *sdh, char **vars, uint *varsz); -static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh); -static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin, - uint *origidx, void *regs); - - -/* global variable to indicate reservation/release of gpio's */ -static uint32 si_gpioreservation = 0; -static void *common_info_alloced = NULL; - -/* global flag to prevent shared resources from being initialized multiple times in si_attach() */ - -/* - * Allocate a si handle. - * devid - pci device id (used to determine chip#) - * osh - opaque OS handle - * regs - virtual address of initial core registers - * bustype - pci/pcmcia/sb/sdio/etc - * vars - pointer to a pointer area for "environment" variables - * varsz - pointer to int to return the size of the vars - */ -si_t * -si_attach(uint devid, osl_t *osh, void *regs, - uint bustype, void *sdh, char **vars, uint *varsz) -{ - si_info_t *sii; - - /* alloc si_info_t */ - if ((sii = MALLOC(osh, sizeof (si_info_t))) == NULL) { - SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh))); - return (NULL); - } - - if (si_doattach(sii, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) { - if (NULL != sii->common_info) - MFREE(osh, sii->common_info, sizeof(si_common_info_t)); - MFREE(osh, sii, sizeof(si_info_t)); - return (NULL); - } - sii->vars = vars ? *vars : NULL; - sii->varsz = varsz ? *varsz : 0; - - return (si_t *)sii; -} - -/* global kernel resource */ -static si_info_t ksii; - -static uint32 wd_msticks; /* watchdog timer ticks normalized to ms */ - -/* generic kernel variant of si_attach() */ -si_t * -si_kattach(osl_t *osh) -{ - static bool ksii_attached = FALSE; - - if (!ksii_attached) { - void *regs = REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE); - - if (si_doattach(&ksii, BCM4710_DEVICE_ID, osh, regs, - SI_BUS, NULL, - osh != SI_OSH ? &ksii.vars : NULL, - osh != SI_OSH ? &ksii.varsz : NULL) == NULL) { - if (NULL != ksii.common_info) - MFREE(osh, ksii.common_info, sizeof(si_common_info_t)); - SI_ERROR(("si_kattach: si_doattach failed\n")); - REG_UNMAP(regs); - return NULL; - } - REG_UNMAP(regs); - - /* save ticks normalized to ms for si_watchdog_ms() */ - if (PMUCTL_ENAB(&ksii.pub)) { - /* based on 32KHz ILP clock */ - wd_msticks = 32; - } else { - wd_msticks = ALP_CLOCK / 1000; - } - - ksii_attached = TRUE; - SI_MSG(("si_kattach done. ccrev = %d, wd_msticks = %d\n", - ksii.pub.ccrev, wd_msticks)); - } - - return &ksii.pub; -} - - -static bool -si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh) -{ - /* need to set memseg flag for CF card first before any sb registers access */ - if (BUSTYPE(bustype) == PCMCIA_BUS) - sii->memseg = TRUE; - - - if (BUSTYPE(bustype) == SDIO_BUS) { - int err; - uint8 clkset; - - /* Try forcing SDIO core to do ALPAvail request only */ - clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); - if (!err) { - uint8 clkval; - - /* If register supported, wait for ALPAvail and then force ALP */ - clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, NULL); - if ((clkval & ~SBSDIO_AVBITS) == clkset) { - SPINWAIT(((clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_CHIPCLKCSR, NULL)), !SBSDIO_ALPAV(clkval)), - PMU_MAX_TRANSITION_DLY); - if (!SBSDIO_ALPAV(clkval)) { - SI_ERROR(("timeout on ALPAV wait, clkval 0x%02x\n", - clkval)); - return FALSE; - } - clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - clkset, &err); - OSL_DELAY(65); - } - } - - /* Also, disable the extra SDIO pull-ups */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); - } - - - return TRUE; -} - -static bool -si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin, - uint *origidx, void *regs) -{ - bool pci, pcie; - uint i; - uint pciidx, pcieidx, pcirev, pcierev; - - cc = si_setcoreidx(&sii->pub, SI_CC_IDX); - ASSERT((uintptr)cc); - - /* get chipcommon rev */ - sii->pub.ccrev = (int)si_corerev(&sii->pub); - - /* get chipcommon chipstatus */ - if (sii->pub.ccrev >= 11) - sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus); - - /* get chipcommon capabilites */ - sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities); - - /* get pmu rev and caps */ - if (sii->pub.cccaps & CC_CAP_PMU) { - sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities); - sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK; - } - - SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n", - sii->pub.ccrev, sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev, - sii->pub.pmucaps)); - - /* figure out bus/orignal core idx */ - sii->pub.buscoretype = NODEV_CORE_ID; - sii->pub.buscorerev = NOREV; - sii->pub.buscoreidx = BADIDX; - - pci = pcie = FALSE; - pcirev = pcierev = NOREV; - pciidx = pcieidx = BADIDX; - - for (i = 0; i < sii->numcores; i++) { - uint cid, crev; - - si_setcoreidx(&sii->pub, i); - cid = si_coreid(&sii->pub); - crev = si_corerev(&sii->pub); - - /* Display cores found */ - SI_MSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n", - i, cid, crev, sii->common_info->coresba[i], sii->common_info->regs[i])); - - if (BUSTYPE(bustype) == PCI_BUS) { - if (cid == PCI_CORE_ID) { - pciidx = i; - pcirev = crev; - pci = TRUE; - } else if (cid == PCIE_CORE_ID) { - pcieidx = i; - pcierev = crev; - pcie = TRUE; - } - } else if ((BUSTYPE(bustype) == PCMCIA_BUS) && - (cid == PCMCIA_CORE_ID)) { - sii->pub.buscorerev = crev; - sii->pub.buscoretype = cid; - sii->pub.buscoreidx = i; - } - else if (((BUSTYPE(bustype) == SDIO_BUS) || - (BUSTYPE(bustype) == SPI_BUS)) && - ((cid == PCMCIA_CORE_ID) || - (cid == SDIOD_CORE_ID))) { - sii->pub.buscorerev = crev; - sii->pub.buscoretype = cid; - sii->pub.buscoreidx = i; - } - - /* find the core idx before entering this func. */ - if ((savewin && (savewin == sii->common_info->coresba[i])) || - (regs == sii->common_info->regs[i])) - *origidx = i; - } - - - SI_MSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, sii->pub.buscoretype, - sii->pub.buscorerev)); - - if (BUSTYPE(sii->pub.bustype) == SI_BUS && (CHIPID(sii->pub.chip) == BCM4712_CHIP_ID) && - (sii->pub.chippkg != BCM4712LARGE_PKG_ID) && (sii->pub.chiprev <= 3)) - OR_REG(sii->osh, &cc->slow_clk_ctl, SCC_SS_XTAL); - - - /* Make sure any on-chip ARM is off (in case strapping is wrong), or downloaded code was - * already running. - */ - if ((BUSTYPE(bustype) == SDIO_BUS) || (BUSTYPE(bustype) == SPI_BUS)) { - if (si_setcore(&sii->pub, ARM7S_CORE_ID, 0) || - si_setcore(&sii->pub, ARMCM3_CORE_ID, 0)) - si_core_disable(&sii->pub, 0); - } - - /* return to the original core */ - si_setcoreidx(&sii->pub, *origidx); - - return TRUE; -} - - - -static si_info_t * -si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs, - uint bustype, void *sdh, char **vars, uint *varsz) -{ - struct si_pub *sih = &sii->pub; - uint32 w, savewin; - chipcregs_t *cc; - char *pvars = NULL; - uint origidx; - - ASSERT(GOODREGS(regs)); - - bzero((uchar*)sii, sizeof(si_info_t)); - - - { - if (NULL == (common_info_alloced = (void *)MALLOC(osh, sizeof(si_common_info_t)))) { - SI_ERROR(("si_doattach: malloc failed! malloced %dbytes\n", MALLOCED(osh))); - return (NULL); - } - bzero((uchar*)(common_info_alloced), sizeof(si_common_info_t)); - } - sii->common_info = (si_common_info_t *)common_info_alloced; - sii->common_info->attach_count++; - - savewin = 0; - - sih->buscoreidx = BADIDX; - - sii->curmap = regs; - sii->sdh = sdh; - sii->osh = osh; - - - /* find Chipcommon address */ - if (bustype == PCI_BUS) { - savewin = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32)); - if (!GOODCOREADDR(savewin, SI_ENUM_BASE)) - savewin = SI_ENUM_BASE; - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE); - cc = (chipcregs_t *)regs; - } else - if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) { - cc = (chipcregs_t *)sii->curmap; - } else { - cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE); - } - - sih->bustype = bustype; - if (bustype != BUSTYPE(bustype)) { - SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n", - bustype, BUSTYPE(bustype))); - return NULL; - } - - /* bus/core/clk setup for register access */ - if (!si_buscore_prep(sii, bustype, devid, sdh)) { - SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", bustype)); - return NULL; - } - - /* ChipID recognition. - * We assume we can read chipid at offset 0 from the regs arg. - * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon), - * some way of recognizing them needs to be added here. - */ - w = R_REG(osh, &cc->chipid); - sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT; - /* Might as wll fill in chip id rev & pkg */ - sih->chip = w & CID_ID_MASK; - sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT; - sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT; - if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chippkg != BCM4329_289PIN_PKG_ID)) - sih->chippkg = BCM4329_182PIN_PKG_ID; - sih->issim = IS_SIM(sih->chippkg); - - /* scan for cores */ - if (CHIPTYPE(sii->pub.socitype) == SOCI_SB) { - SI_MSG(("Found chip type SB (0x%08x)\n", w)); - sb_scan(&sii->pub, regs, devid); - } else if (CHIPTYPE(sii->pub.socitype) == SOCI_AI) { - SI_MSG(("Found chip type AI (0x%08x)\n", w)); - /* pass chipc address instead of original core base */ - ai_scan(&sii->pub, (void *)cc, devid); - } else { - SI_ERROR(("Found chip of unkown type (0x%08x)\n", w)); - return NULL; - } - /* no cores found, bail out */ - if (sii->numcores == 0) { - SI_ERROR(("si_doattach: could not find any cores\n")); - return NULL; - } - /* bus/core/clk setup */ - origidx = SI_CC_IDX; - if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) { - SI_ERROR(("si_doattach: si_buscore_setup failed\n")); - return NULL; - } - - pvars = NULL; - - - - if (sii->pub.ccrev >= 20) { - cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); - W_REG(osh, &cc->gpiopullup, 0); - W_REG(osh, &cc->gpiopulldown, 0); - si_setcoreidx(sih, origidx); - } - - /* Skip PMU initialization from the Dongle Host. - * Firmware will take care of it when it comes up. - */ - - - - return (sii); -} - -/* may be called with core in reset */ -void -si_detach(si_t *sih) -{ - si_info_t *sii; - uint idx; - - sii = SI_INFO(sih); - - if (sii == NULL) - return; - - if (BUSTYPE(sih->bustype) == SI_BUS) - for (idx = 0; idx < SI_MAXCORES; idx++) - if (sii->common_info->regs[idx]) { - REG_UNMAP(sii->common_info->regs[idx]); - sii->common_info->regs[idx] = NULL; - } - - - if (1 == sii->common_info->attach_count--) { - MFREE(sii->osh, sii->common_info, sizeof(si_common_info_t)); - common_info_alloced = NULL; - } - -#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS) - if (sii != &ksii) -#endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */ - MFREE(sii->osh, sii, sizeof(si_info_t)); -} - -void * -si_osh(si_t *sih) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - return sii->osh; -} - -void -si_setosh(si_t *sih, osl_t *osh) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - if (sii->osh != NULL) { - SI_ERROR(("osh is already set....\n")); - ASSERT(!sii->osh); - } - sii->osh = osh; -} - -/* register driver interrupt disabling and restoring callback functions */ -void -si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn, - void *intrsenabled_fn, void *intr_arg) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - sii->intr_arg = intr_arg; - sii->intrsoff_fn = (si_intrsoff_t)intrsoff_fn; - sii->intrsrestore_fn = (si_intrsrestore_t)intrsrestore_fn; - sii->intrsenabled_fn = (si_intrsenabled_t)intrsenabled_fn; - /* save current core id. when this function called, the current core - * must be the core which provides driver functions(il, et, wl, etc.) - */ - sii->dev_coreid = sii->common_info->coreid[sii->curidx]; -} - -void -si_deregister_intr_callback(si_t *sih) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - sii->intrsoff_fn = NULL; -} - -uint -si_intflag(si_t *sih) -{ - si_info_t *sii = SI_INFO(sih); - if (CHIPTYPE(sih->socitype) == SOCI_SB) { - sbconfig_t *ccsbr = (sbconfig_t *)((uintptr)((ulong) - (sii->common_info->coresba[SI_CC_IDX]) + SBCONFIGOFF)); - return R_REG(sii->osh, &ccsbr->sbflagst); - } else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return R_REG(sii->osh, ((uint32 *)(uintptr) - (sii->common_info->oob_router + OOB_STATUSA))); - else { - ASSERT(0); - return 0; - } -} - -uint -si_flag(si_t *sih) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_flag(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_flag(sih); - else { - ASSERT(0); - return 0; - } -} - -void -si_setint(si_t *sih, int siflag) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - sb_setint(sih, siflag); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - ai_setint(sih, siflag); - else - ASSERT(0); -} - -uint -si_coreid(si_t *sih) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - return sii->common_info->coreid[sii->curidx]; -} - -uint -si_coreidx(si_t *sih) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - return sii->curidx; -} - -/* return the core-type instantiation # of the current core */ -uint -si_coreunit(si_t *sih) -{ - si_info_t *sii; - uint idx; - uint coreid; - uint coreunit; - uint i; - - sii = SI_INFO(sih); - coreunit = 0; - - idx = sii->curidx; - - ASSERT(GOODREGS(sii->curmap)); - coreid = si_coreid(sih); - - /* count the cores of our type */ - for (i = 0; i < idx; i++) - if (sii->common_info->coreid[i] == coreid) - coreunit++; - - return (coreunit); -} - -uint -si_corevendor(si_t *sih) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_corevendor(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_corevendor(sih); - else { - ASSERT(0); - return 0; - } -} - -bool -si_backplane64(si_t *sih) -{ - return ((sih->cccaps & CC_CAP_BKPLN64) != 0); -} - -uint -si_corerev(si_t *sih) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_corerev(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_corerev(sih); - else { - ASSERT(0); - return 0; - } -} - -/* return index of coreid or BADIDX if not found */ -uint -si_findcoreidx(si_t *sih, uint coreid, uint coreunit) -{ - si_info_t *sii; - uint found; - uint i; - - sii = SI_INFO(sih); - - found = 0; - - for (i = 0; i < sii->numcores; i++) - if (sii->common_info->coreid[i] == coreid) { - if (found == coreunit) - return (i); - found++; - } - - return (BADIDX); -} - -/* return list of found cores */ -uint -si_corelist(si_t *sih, uint coreid[]) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - bcopy((uchar*)sii->common_info->coreid, (uchar*)coreid, (sii->numcores * sizeof(uint))); - return (sii->numcores); -} - -/* return current register mapping */ -void * -si_coreregs(si_t *sih) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curmap)); - - return (sii->curmap); -} - -/* - * This function changes logical "focus" to the indicated core; - * must be called with interrupts off. - * Moreover, callers should keep interrupts off during switching out of and back to d11 core - */ -void * -si_setcore(si_t *sih, uint coreid, uint coreunit) -{ - uint idx; - - idx = si_findcoreidx(sih, coreid, coreunit); - if (!GOODIDX(idx)) - return (NULL); - - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_setcoreidx(sih, idx); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_setcoreidx(sih, idx); - else { - ASSERT(0); - return NULL; - } -} - -void * -si_setcoreidx(si_t *sih, uint coreidx) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_setcoreidx(sih, coreidx); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_setcoreidx(sih, coreidx); - else { - ASSERT(0); - return NULL; - } -} - -/* Turn off interrupt as required by sb_setcore, before switch core */ -void *si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val) -{ - void *cc; - si_info_t *sii; - - sii = SI_INFO(sih); - - INTR_OFF(sii, *intr_val); - *origidx = sii->curidx; - cc = si_setcore(sih, coreid, 0); - ASSERT(cc != NULL); - - return cc; -} - -/* restore coreidx and restore interrupt */ -void si_restore_core(si_t *sih, uint coreid, uint intr_val) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - si_setcoreidx(sih, coreid); - INTR_RESTORE(sii, intr_val); -} - -int -si_numaddrspaces(si_t *sih) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_numaddrspaces(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_numaddrspaces(sih); - else { - ASSERT(0); - return 0; - } -} - -uint32 -si_addrspace(si_t *sih, uint asidx) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_addrspace(sih, asidx); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_addrspace(sih, asidx); - else { - ASSERT(0); - return 0; - } -} - -uint32 -si_addrspacesize(si_t *sih, uint asidx) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_addrspacesize(sih, asidx); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_addrspacesize(sih, asidx); - else { - ASSERT(0); - return 0; - } -} - -uint32 -si_core_cflags(si_t *sih, uint32 mask, uint32 val) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_core_cflags(sih, mask, val); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_core_cflags(sih, mask, val); - else { - ASSERT(0); - return 0; - } -} - -void -si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - sb_core_cflags_wo(sih, mask, val); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - ai_core_cflags_wo(sih, mask, val); - else - ASSERT(0); -} - -uint32 -si_core_sflags(si_t *sih, uint32 mask, uint32 val) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_core_sflags(sih, mask, val); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_core_sflags(sih, mask, val); - else { - ASSERT(0); - return 0; - } -} - -bool -si_iscoreup(si_t *sih) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_iscoreup(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_iscoreup(sih); - else { - ASSERT(0); - return FALSE; - } -} - -void -si_write_wrapperreg(si_t *sih, uint32 offset, uint32 val) -{ - /* only for 4319, no requirement for SOCI_SB */ - if (CHIPTYPE(sih->socitype) == SOCI_AI) { - ai_write_wrap_reg(sih, offset, val); - } - else - return; - - return; -} - -uint -si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_corereg(sih, coreidx, regoff, mask, val); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_corereg(sih, coreidx, regoff, mask, val); - else { - ASSERT(0); - return 0; - } -} - -void -si_core_disable(si_t *sih, uint32 bits) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - sb_core_disable(sih, bits); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - ai_core_disable(sih, bits); -} - -void -si_core_reset(si_t *sih, uint32 bits, uint32 resetbits) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - sb_core_reset(sih, bits, resetbits); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - ai_core_reset(sih, bits, resetbits); -} - -void -si_core_tofixup(si_t *sih) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - sb_core_tofixup(sih); -} - -/* Run bist on current core. Caller needs to take care of core-specific bist hazards */ -int -si_corebist(si_t *sih) -{ - uint32 cflags; - int result = 0; - - /* Read core control flags */ - cflags = si_core_cflags(sih, 0, 0); - - /* Set bist & fgc */ - si_core_cflags(sih, 0, (SICF_BIST_EN | SICF_FGC)); - - /* Wait for bist done */ - SPINWAIT(((si_core_sflags(sih, 0, 0) & SISF_BIST_DONE) == 0), 100000); - - if (si_core_sflags(sih, 0, 0) & SISF_BIST_ERROR) - result = BCME_ERROR; - - /* Reset core control flags */ - si_core_cflags(sih, 0xffff, cflags); - - return result; -} - -static uint32 -factor6(uint32 x) -{ - switch (x) { - case CC_F6_2: return 2; - case CC_F6_3: return 3; - case CC_F6_4: return 4; - case CC_F6_5: return 5; - case CC_F6_6: return 6; - case CC_F6_7: return 7; - default: return 0; - } -} - -/* calculate the speed the SI would run at given a set of clockcontrol values */ -uint32 -si_clock_rate(uint32 pll_type, uint32 n, uint32 m) -{ - uint32 n1, n2, clock, m1, m2, m3, mc; - - n1 = n & CN_N1_MASK; - n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT; - - if (pll_type == PLL_TYPE6) { - if (m & CC_T6_MMASK) - return CC_T6_M1; - else - return CC_T6_M0; - } else if ((pll_type == PLL_TYPE1) || - (pll_type == PLL_TYPE3) || - (pll_type == PLL_TYPE4) || - (pll_type == PLL_TYPE7)) { - n1 = factor6(n1); - n2 += CC_F5_BIAS; - } else if (pll_type == PLL_TYPE2) { - n1 += CC_T2_BIAS; - n2 += CC_T2_BIAS; - ASSERT((n1 >= 2) && (n1 <= 7)); - ASSERT((n2 >= 5) && (n2 <= 23)); - } else if (pll_type == PLL_TYPE5) { - return (100000000); - } else - ASSERT(0); - /* PLL types 3 and 7 use BASE2 (25Mhz) */ - if ((pll_type == PLL_TYPE3) || - (pll_type == PLL_TYPE7)) { - clock = CC_CLOCK_BASE2 * n1 * n2; - } else - clock = CC_CLOCK_BASE1 * n1 * n2; - - if (clock == 0) - return 0; - - m1 = m & CC_M1_MASK; - m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT; - m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT; - mc = (m & CC_MC_MASK) >> CC_MC_SHIFT; - - if ((pll_type == PLL_TYPE1) || - (pll_type == PLL_TYPE3) || - (pll_type == PLL_TYPE4) || - (pll_type == PLL_TYPE7)) { - m1 = factor6(m1); - if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3)) - m2 += CC_F5_BIAS; - else - m2 = factor6(m2); - m3 = factor6(m3); - - switch (mc) { - case CC_MC_BYPASS: return (clock); - case CC_MC_M1: return (clock / m1); - case CC_MC_M1M2: return (clock / (m1 * m2)); - case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3)); - case CC_MC_M1M3: return (clock / (m1 * m3)); - default: return (0); - } - } else { - ASSERT(pll_type == PLL_TYPE2); - - m1 += CC_T2_BIAS; - m2 += CC_T2M2_BIAS; - m3 += CC_T2_BIAS; - ASSERT((m1 >= 2) && (m1 <= 7)); - ASSERT((m2 >= 3) && (m2 <= 10)); - ASSERT((m3 >= 2) && (m3 <= 7)); - - if ((mc & CC_T2MC_M1BYP) == 0) - clock /= m1; - if ((mc & CC_T2MC_M2BYP) == 0) - clock /= m2; - if ((mc & CC_T2MC_M3BYP) == 0) - clock /= m3; - - return (clock); - } -} - - -/* set chip watchdog reset timer to fire in 'ticks' */ -void -si_watchdog(si_t *sih, uint ticks) -{ - if (PMUCTL_ENAB(sih)) { - - if ((sih->chip == BCM4319_CHIP_ID) && (sih->chiprev == 0) && (ticks != 0)) { - si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), ~0, 0x2); - si_setcore(sih, USB20D_CORE_ID, 0); - si_core_disable(sih, 1); - si_setcore(sih, CC_CORE_ID, 0); - } - - if (ticks == 1) - ticks = 2; - si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pmuwatchdog), ~0, ticks); - } else { - /* instant NMI */ - si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0, ticks); - } -} - -#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS) -/* trigger watchdog reset after ms milliseconds */ -void -si_watchdog_ms(si_t *sih, uint32 ms) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - si_watchdog(sih, wd_msticks * ms); -} -#endif - - - -/* initialize the sdio core */ -void -si_sdio_init(si_t *sih) -{ - si_info_t *sii = SI_INFO(sih); - - if (((sih->buscoretype == PCMCIA_CORE_ID) && (sih->buscorerev >= 8)) || - (sih->buscoretype == SDIOD_CORE_ID)) { - uint idx; - sdpcmd_regs_t *sdpregs; - - /* get the current core index */ - idx = sii->curidx; - ASSERT(idx == si_findcoreidx(sih, D11_CORE_ID, 0)); - - /* switch to sdio core */ - if (!(sdpregs = (sdpcmd_regs_t *)si_setcore(sih, PCMCIA_CORE_ID, 0))) - sdpregs = (sdpcmd_regs_t *)si_setcore(sih, SDIOD_CORE_ID, 0); - ASSERT(sdpregs); - - SI_MSG(("si_sdio_init: For PCMCIA/SDIO Corerev %d, enable ints from core %d " - "through SD core %d (%p)\n", - sih->buscorerev, idx, sii->curidx, sdpregs)); - - /* enable backplane error and core interrupts */ - W_REG(sii->osh, &sdpregs->hostintmask, I_SBINT); - W_REG(sii->osh, &sdpregs->sbintmask, (I_SB_SERR | I_SB_RESPERR | (1 << idx))); - - /* switch back to previous core */ - si_setcoreidx(sih, idx); - } - - /* enable interrupts */ - bcmsdh_intr_enable(sii->sdh); - -} - - -/* change logical "focus" to the gpio core for optimized access */ -void * -si_gpiosetcore(si_t *sih) -{ - return (si_setcoreidx(sih, SI_CC_IDX)); -} - -/* mask&set gpiocontrol bits */ -uint32 -si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority) -{ - uint regoff; - - regoff = 0; - - /* gpios could be shared on router platforms - * ignore reservation if it's high priority (e.g., test apps) - */ - if ((priority != GPIO_HI_PRIORITY) && - (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { - mask = priority ? (si_gpioreservation & mask) : - ((si_gpioreservation | mask) & ~(si_gpioreservation)); - val &= mask; - } - - regoff = OFFSETOF(chipcregs_t, gpiocontrol); - return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -} - -/* mask&set gpio output enable bits */ -uint32 -si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority) -{ - uint regoff; - - regoff = 0; - - /* gpios could be shared on router platforms - * ignore reservation if it's high priority (e.g., test apps) - */ - if ((priority != GPIO_HI_PRIORITY) && - (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { - mask = priority ? (si_gpioreservation & mask) : - ((si_gpioreservation | mask) & ~(si_gpioreservation)); - val &= mask; - } - - regoff = OFFSETOF(chipcregs_t, gpioouten); - return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -} - -/* mask&set gpio output bits */ -uint32 -si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority) -{ - uint regoff; - - regoff = 0; - - /* gpios could be shared on router platforms - * ignore reservation if it's high priority (e.g., test apps) - */ - if ((priority != GPIO_HI_PRIORITY) && - (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { - mask = priority ? (si_gpioreservation & mask) : - ((si_gpioreservation | mask) & ~(si_gpioreservation)); - val &= mask; - } - - regoff = OFFSETOF(chipcregs_t, gpioout); - return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -} - -/* reserve one gpio */ -uint32 -si_gpioreserve(si_t *sih, uint32 gpio_bitmask, uint8 priority) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - /* only cores on SI_BUS share GPIO's and only applcation users need to - * reserve/release GPIO - */ - if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) { - ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority)); - return -1; - } - /* make sure only one bit is set */ - if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { - ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); - return -1; - } - - /* already reserved */ - if (si_gpioreservation & gpio_bitmask) - return -1; - /* set reservation */ - si_gpioreservation |= gpio_bitmask; - - return si_gpioreservation; -} - -/* release one gpio */ -/* - * releasing the gpio doesn't change the current value on the GPIO last write value - * persists till some one overwrites it - */ - -uint32 -si_gpiorelease(si_t *sih, uint32 gpio_bitmask, uint8 priority) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - /* only cores on SI_BUS share GPIO's and only applcation users need to - * reserve/release GPIO - */ - if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) { - ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority)); - return -1; - } - /* make sure only one bit is set */ - if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { - ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); - return -1; - } - - /* already released */ - if (!(si_gpioreservation & gpio_bitmask)) - return -1; - - /* clear reservation */ - si_gpioreservation &= ~gpio_bitmask; - - return si_gpioreservation; -} - -/* return the current gpioin register value */ -uint32 -si_gpioin(si_t *sih) -{ - si_info_t *sii; - uint regoff; - - sii = SI_INFO(sih); - regoff = 0; - - regoff = OFFSETOF(chipcregs_t, gpioin); - return (si_corereg(sih, SI_CC_IDX, regoff, 0, 0)); -} - -/* mask&set gpio interrupt polarity bits */ -uint32 -si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority) -{ - si_info_t *sii; - uint regoff; - - sii = SI_INFO(sih); - regoff = 0; - - /* gpios could be shared on router platforms */ - if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { - mask = priority ? (si_gpioreservation & mask) : - ((si_gpioreservation | mask) & ~(si_gpioreservation)); - val &= mask; - } - - regoff = OFFSETOF(chipcregs_t, gpiointpolarity); - return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -} - -/* mask&set gpio interrupt mask bits */ -uint32 -si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority) -{ - si_info_t *sii; - uint regoff; - - sii = SI_INFO(sih); - regoff = 0; - - /* gpios could be shared on router platforms */ - if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { - mask = priority ? (si_gpioreservation & mask) : - ((si_gpioreservation | mask) & ~(si_gpioreservation)); - val &= mask; - } - - regoff = OFFSETOF(chipcregs_t, gpiointmask); - return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -} - -/* assign the gpio to an led */ -uint32 -si_gpioled(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - if (sih->ccrev < 16) - return -1; - - /* gpio led powersave reg */ - return (si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val)); -} - -/* mask&set gpio timer val */ -uint32 -si_gpiotimerval(si_t *sih, uint32 mask, uint32 gpiotimerval) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - if (sih->ccrev < 16) - return -1; - - return (si_corereg(sih, SI_CC_IDX, - OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval)); -} - -uint32 -si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val) -{ - si_info_t *sii; - uint offs; - - sii = SI_INFO(sih); - if (sih->ccrev < 20) - return -1; - - offs = (updown ? OFFSETOF(chipcregs_t, gpiopulldown) : OFFSETOF(chipcregs_t, gpiopullup)); - return (si_corereg(sih, SI_CC_IDX, offs, mask, val)); -} - -uint32 -si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val) -{ - si_info_t *sii; - uint offs; - - sii = SI_INFO(sih); - if (sih->ccrev < 11) - return -1; - - if (regtype == GPIO_REGEVT) - offs = OFFSETOF(chipcregs_t, gpioevent); - else if (regtype == GPIO_REGEVT_INTMSK) - offs = OFFSETOF(chipcregs_t, gpioeventintmask); - else if (regtype == GPIO_REGEVT_INTPOL) - offs = OFFSETOF(chipcregs_t, gpioeventintpolarity); - else - return -1; - - return (si_corereg(sih, SI_CC_IDX, offs, mask, val)); -} - -void * -si_gpio_handler_register(si_t *sih, uint32 event, - bool level, gpio_handler_t cb, void *arg) -{ - si_info_t *sii; - gpioh_item_t *gi; - - ASSERT(event); - ASSERT(cb != NULL); - - sii = SI_INFO(sih); - if (sih->ccrev < 11) - return NULL; - - if ((gi = MALLOC(sii->osh, sizeof(gpioh_item_t))) == NULL) - return NULL; - - bzero(gi, sizeof(gpioh_item_t)); - gi->event = event; - gi->handler = cb; - gi->arg = arg; - gi->level = level; - - gi->next = sii->gpioh_head; - sii->gpioh_head = gi; - - return (void *)(gi); -} - -void -si_gpio_handler_unregister(si_t *sih, void *gpioh) -{ - si_info_t *sii; - gpioh_item_t *p, *n; - - sii = SI_INFO(sih); - if (sih->ccrev < 11) - return; - - ASSERT(sii->gpioh_head != NULL); - if ((void*)sii->gpioh_head == gpioh) { - sii->gpioh_head = sii->gpioh_head->next; - MFREE(sii->osh, gpioh, sizeof(gpioh_item_t)); - return; - } else { - p = sii->gpioh_head; - n = p->next; - while (n) { - if ((void*)n == gpioh) { - p->next = n->next; - MFREE(sii->osh, gpioh, sizeof(gpioh_item_t)); - return; - } - p = n; - n = n->next; - } - } - - ASSERT(0); /* Not found in list */ -} - -void -si_gpio_handler_process(si_t *sih) -{ - si_info_t *sii; - gpioh_item_t *h; - uint32 status; - uint32 level = si_gpioin(sih); - uint32 edge = si_gpioevent(sih, GPIO_REGEVT, 0, 0); - - sii = SI_INFO(sih); - for (h = sii->gpioh_head; h != NULL; h = h->next) { - if (h->handler) { - status = (h->level ? level : edge); - - if (status & h->event) - h->handler(status, h->arg); - } - } - - si_gpioevent(sih, GPIO_REGEVT, edge, edge); /* clear edge-trigger status */ -} - -uint32 -si_gpio_int_enable(si_t *sih, bool enable) -{ - si_info_t *sii; - uint offs; - - sii = SI_INFO(sih); - if (sih->ccrev < 11) - return -1; - - offs = OFFSETOF(chipcregs_t, intmask); - return (si_corereg(sih, SI_CC_IDX, offs, CI_GPIO, (enable ? CI_GPIO : 0))); -} - - -/* Return the RAM size of the SOCRAM core */ -uint32 -si_socram_size(si_t *sih) -{ - si_info_t *sii; - uint origidx; - uint intr_val = 0; - - sbsocramregs_t *regs; - bool wasup; - uint corerev; - uint32 coreinfo; - uint memsize = 0; - - sii = SI_INFO(sih); - - /* Block ints and save current core */ - INTR_OFF(sii, intr_val); - origidx = si_coreidx(sih); - - /* Switch to SOCRAM core */ - if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) - goto done; - - /* Get info for determining size */ - if (!(wasup = si_iscoreup(sih))) - si_core_reset(sih, 0, 0); - corerev = si_corerev(sih); - coreinfo = R_REG(sii->osh, ®s->coreinfo); - - /* Calculate size from coreinfo based on rev */ - if (corerev == 0) - memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK)); - else if (corerev < 3) { - memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK)); - memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; - } else { - uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; - uint bsz = (coreinfo & SRCI_SRBSZ_MASK); - uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT; - if (lss != 0) - nb --; - memsize = nb * (1 << (bsz + SR_BSZ_BASE)); - if (lss != 0) - memsize += (1 << ((lss - 1) + SR_BSZ_BASE)); - } - - /* Return to previous state and core */ - if (!wasup) - si_core_disable(sih, 0); - si_setcoreidx(sih, origidx); - -done: - INTR_RESTORE(sii, intr_val); - - return memsize; -} - - -void -si_btcgpiowar(si_t *sih) -{ - si_info_t *sii; - uint origidx; - uint intr_val = 0; - chipcregs_t *cc; - - sii = SI_INFO(sih); - - /* Make sure that there is ChipCommon core present && - * UART_TX is strapped to 1 - */ - if (!(sih->cccaps & CC_CAP_UARTGPIO)) - return; - - /* si_corereg cannot be used as we have to guarantee 8-bit read/writes */ - INTR_OFF(sii, intr_val); - - origidx = si_coreidx(sih); - - cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); - ASSERT(cc != NULL); - - W_REG(sii->osh, &cc->uart0mcr, R_REG(sii->osh, &cc->uart0mcr) | 0x04); - - /* restore the original index */ - si_setcoreidx(sih, origidx); - - INTR_RESTORE(sii, intr_val); -} - -/* check if the device is removed */ -bool -si_deviceremoved(si_t *sih) -{ - uint32 w; - si_info_t *sii; - - sii = SI_INFO(sih); - - switch (BUSTYPE(sih->bustype)) { - case PCI_BUS: - ASSERT(sii->osh != NULL); - w = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_VID, sizeof(uint32)); - if ((w & 0xFFFF) != VENDOR_BROADCOM) - return TRUE; - else - return FALSE; - default: - return FALSE; - } - return FALSE; -} diff --git a/drivers/net/wireless/bcm4329/siutils_priv.h b/drivers/net/wireless/bcm4329/siutils_priv.h deleted file mode 100644 index e8ad7e50958a..000000000000 --- a/drivers/net/wireless/bcm4329/siutils_priv.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Include file private to the SOC Interconnect support files. - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: siutils_priv.h,v 1.3.10.5.4.2 2009/09/22 13:28:16 Exp $ - */ - -#ifndef _siutils_priv_h_ -#define _siutils_priv_h_ - -/* debug/trace */ -#define SI_ERROR(args) - -#define SI_MSG(args) - -#define IS_SIM(chippkg) ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID)) - -typedef uint32 (*si_intrsoff_t)(void *intr_arg); -typedef void (*si_intrsrestore_t)(void *intr_arg, uint32 arg); -typedef bool (*si_intrsenabled_t)(void *intr_arg); - -typedef struct gpioh_item { - void *arg; - bool level; - gpio_handler_t handler; - uint32 event; - struct gpioh_item *next; -} gpioh_item_t; - -/* misc si info needed by some of the routines */ -typedef struct si_common_info { - void *regs[SI_MAXCORES]; /* other regs va */ - void *regs2[SI_MAXCORES]; /* va of each core second register set (usbh20) */ - uint coreid[SI_MAXCORES]; /* id of each core */ - uint32 cia[SI_MAXCORES]; /* erom cia entry for each core */ - uint32 cib[SI_MAXCORES]; /* erom cia entry for each core */ - uint32 coresba_size[SI_MAXCORES]; /* backplane address space size */ - uint32 coresba2_size[SI_MAXCORES]; /* second address space size */ - uint32 coresba[SI_MAXCORES]; /* backplane address of each core */ - uint32 coresba2[SI_MAXCORES]; /* address of each core second register set (usbh20) */ - void *wrappers[SI_MAXCORES]; /* other cores wrapper va */ - uint32 wrapba[SI_MAXCORES]; /* address of controlling wrapper */ - uint32 oob_router; /* oob router registers for axi */ - uint8 attach_count; -} si_common_info_t; - -typedef struct si_info { - struct si_pub pub; /* back plane public state (must be first field) */ - - void *osh; /* osl os handle */ - void *sdh; /* bcmsdh handle */ - void *pch; /* PCI/E core handle */ - uint dev_coreid; /* the core provides driver functions */ - void *intr_arg; /* interrupt callback function arg */ - si_intrsoff_t intrsoff_fn; /* turns chip interrupts off */ - si_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */ - si_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */ - - - gpioh_item_t *gpioh_head; /* GPIO event handlers list */ - - bool memseg; /* flag to toggle MEM_SEG register */ - - char *vars; - uint varsz; - - void *curmap; /* current regs va */ - - uint curidx; /* current core index */ - uint numcores; /* # discovered cores */ - void *curwrap; /* current wrapper va */ - si_common_info_t *common_info; /* Common information for all the cores in a chip */ -} si_info_t; - -#define SI_INFO(sih) (si_info_t *)(uintptr)sih - -#define GOODCOREADDR(x, b) (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ - ISALIGNED((x), SI_CORE_SIZE)) -#define GOODREGS(regs) ((regs) != NULL && ISALIGNED((uintptr)(regs), SI_CORE_SIZE)) -#define BADCOREADDR 0 -#define GOODIDX(idx) (((uint)idx) < SI_MAXCORES) -#define BADIDX (SI_MAXCORES + 1) -#define NOREV -1 /* Invalid rev */ - -#define PCI(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ - ((si)->pub.buscoretype == PCI_CORE_ID)) -#define PCIE(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ - ((si)->pub.buscoretype == PCIE_CORE_ID)) -#define PCMCIA(si) ((BUSTYPE((si)->pub.bustype) == PCMCIA_BUS) && ((si)->memseg == TRUE)) - -/* Newer chips can access PCI/PCIE and CC core without requiring to change - * PCI BAR0 WIN - */ -#define SI_FAST(si) (((si)->pub.buscoretype == PCIE_CORE_ID) || \ - (((si)->pub.buscoretype == PCI_CORE_ID) && (si)->pub.buscorerev >= 13)) - -#define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET)) -#define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET)) - -/* - * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/ - * after core switching to avoid invalid register accesss inside ISR. - */ -#define INTR_OFF(si, intr_val) \ - if ((si)->intrsoff_fn && (si)->common_info->coreid[(si)->curidx] == (si)->dev_coreid) { \ - intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); } -#define INTR_RESTORE(si, intr_val) \ - if ((si)->intrsrestore_fn && (si)->common_info->coreid[(si)->curidx] == (si)->dev_coreid) {\ - (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } - -/* dynamic clock control defines */ -#define LPOMINFREQ 25000 /* low power oscillator min */ -#define LPOMAXFREQ 43000 /* low power oscillator max */ -#define XTALMINFREQ 19800000 /* 20 MHz - 1% */ -#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */ -#define PCIMINFREQ 25000000 /* 25 MHz */ -#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */ - -#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ -#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ - -#define PCI_FORCEHT(si) \ - (((PCIE(si)) && (si->pub.chip == BCM4311_CHIP_ID) && ((si->pub.chiprev <= 1))) || \ - ((PCI(si) || PCIE(si)) && (si->pub.chip == BCM4321_CHIP_ID))) - -/* GPIO Based LED powersave defines */ -#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */ -#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */ - -#ifndef DEFAULT_GPIOTIMERVAL -#define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) -#endif - -/* Silicon Backplane externs */ -extern void sb_scan(si_t *sih, void *regs, uint devid); -extern uint sb_coreid(si_t *sih); -extern uint sb_flag(si_t *sih); -extern void sb_setint(si_t *sih, int siflag); -extern uint sb_corevendor(si_t *sih); -extern uint sb_corerev(si_t *sih); -extern uint sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); -extern bool sb_iscoreup(si_t *sih); -extern void *sb_setcoreidx(si_t *sih, uint coreidx); -extern uint32 sb_core_cflags(si_t *sih, uint32 mask, uint32 val); -extern void sb_core_cflags_wo(si_t *sih, uint32 mask, uint32 val); -extern uint32 sb_core_sflags(si_t *sih, uint32 mask, uint32 val); -extern void sb_commit(si_t *sih); -extern uint32 sb_base(uint32 admatch); -extern uint32 sb_size(uint32 admatch); -extern void sb_core_reset(si_t *sih, uint32 bits, uint32 resetbits); -extern void sb_core_tofixup(si_t *sih); -extern void sb_core_disable(si_t *sih, uint32 bits); -extern uint32 sb_addrspace(si_t *sih, uint asidx); -extern uint32 sb_addrspacesize(si_t *sih, uint asidx); -extern int sb_numaddrspaces(si_t *sih); - -extern uint32 sb_set_initiator_to(si_t *sih, uint32 to, uint idx); - - - -/* Wake-on-wireless-LAN (WOWL) */ -extern bool sb_pci_pmecap(si_t *sih); -struct osl_info; -extern bool sb_pci_fastpmecap(struct osl_info *osh); -extern bool sb_pci_pmeclr(si_t *sih); -extern void sb_pci_pmeen(si_t *sih); -extern uint sb_pcie_readreg(void *sih, uint addrtype, uint offset); - -/* AMBA Interconnect exported externs */ -extern si_t *ai_attach(uint pcidev, osl_t *osh, void *regs, uint bustype, - void *sdh, char **vars, uint *varsz); -extern si_t *ai_kattach(osl_t *osh); -extern void ai_scan(si_t *sih, void *regs, uint devid); - -extern uint ai_flag(si_t *sih); -extern void ai_setint(si_t *sih, int siflag); -extern uint ai_coreidx(si_t *sih); -extern uint ai_corevendor(si_t *sih); -extern uint ai_corerev(si_t *sih); -extern bool ai_iscoreup(si_t *sih); -extern void *ai_setcoreidx(si_t *sih, uint coreidx); -extern uint32 ai_core_cflags(si_t *sih, uint32 mask, uint32 val); -extern void ai_core_cflags_wo(si_t *sih, uint32 mask, uint32 val); -extern uint32 ai_core_sflags(si_t *sih, uint32 mask, uint32 val); -extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); -extern void ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits); -extern void ai_core_disable(si_t *sih, uint32 bits); -extern int ai_numaddrspaces(si_t *sih); -extern uint32 ai_addrspace(si_t *sih, uint asidx); -extern uint32 ai_addrspacesize(si_t *sih, uint asidx); -extern void ai_write_wrap_reg(si_t *sih, uint32 offset, uint32 val); - - -#endif /* _siutils_priv_h_ */ diff --git a/drivers/net/wireless/bcm4329/wl_iw.c b/drivers/net/wireless/bcm4329/wl_iw.c deleted file mode 100644 index 434e584f830c..000000000000 --- a/drivers/net/wireless/bcm4329/wl_iw.c +++ /dev/null @@ -1,8455 +0,0 @@ -/* - * Linux Wireless Extensions support - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wl_iw.c,v 1.51.4.9.2.6.4.142.4.78 2011/02/11 21:27:52 Exp $ - */ - - -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include - -typedef void wlc_info_t; -typedef void wl_info_t; -typedef const struct si_pub si_t; -#include - -#include -#include -#include -#define WL_ERROR(x) printf x -#define WL_TRACE(x) -#define WL_ASSOC(x) -#define WL_INFORM(x) -#define WL_WSEC(x) -#define WL_SCAN(x) -#define WL_PNO(x) -#define WL_TRACE_COEX(x) - -#include - - - -#ifndef IW_ENCODE_ALG_SM4 -#define IW_ENCODE_ALG_SM4 0x20 -#endif - -#ifndef IW_AUTH_WAPI_ENABLED -#define IW_AUTH_WAPI_ENABLED 0x20 -#endif - -#ifndef IW_AUTH_WAPI_VERSION_1 -#define IW_AUTH_WAPI_VERSION_1 0x00000008 -#endif - -#ifndef IW_AUTH_CIPHER_SMS4 -#define IW_AUTH_CIPHER_SMS4 0x00000020 -#endif - -#ifndef IW_AUTH_KEY_MGMT_WAPI_PSK -#define IW_AUTH_KEY_MGMT_WAPI_PSK 4 -#endif - -#ifndef IW_AUTH_KEY_MGMT_WAPI_CERT -#define IW_AUTH_KEY_MGMT_WAPI_CERT 8 -#endif - - -#define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED | SMS4_ENABLED)) - -#include -#include - -#define WL_IW_USE_ISCAN 1 -#define ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS 1 - -#if defined(SOFTAP) -#define WL_SOFTAP(x) printk x -static struct net_device *priv_dev; -static bool ap_cfg_running = FALSE; -bool ap_fw_loaded = FALSE; -static long ap_cfg_pid = -1; -struct net_device *ap_net_dev = NULL; -struct semaphore ap_eth_sema; -static struct completion ap_cfg_exited; -static int wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap); -static int wl_iw_softap_deassoc_stations(struct net_device *dev, u8 *mac); -#endif - -#define WL_IW_IOCTL_CALL(func_call) \ - do { \ - func_call; \ - } while (0) - -static int g_onoff = G_WLAN_SET_ON; -wl_iw_extra_params_t g_wl_iw_params; -static struct mutex wl_cache_lock; - -extern bool wl_iw_conn_status_str(uint32 event_type, uint32 status, - uint32 reason, char* stringBuf, uint buflen); -#include -extern void dhd_customer_gpio_wlan_ctrl(int onoff); -extern uint dhd_dev_reset(struct net_device *dev, uint8 flag); -extern void dhd_dev_init_ioctl(struct net_device *dev); -int dev_iw_write_cfg1_bss_var(struct net_device *dev, int val); - -uint wl_msg_level = WL_ERROR_VAL; - -#define MAX_WLIW_IOCTL_LEN 1024 - - -#if defined(IL_BIGENDIAN) -#include -#define htod32(i) (bcmswap32(i)) -#define htod16(i) (bcmswap16(i)) -#define dtoh32(i) (bcmswap32(i)) -#define dtoh16(i) (bcmswap16(i)) -#define htodchanspec(i) htod16(i) -#define dtohchanspec(i) dtoh16(i) -#else -#define htod32(i) i -#define htod16(i) i -#define dtoh32(i) i -#define dtoh16(i) i -#define htodchanspec(i) i -#define dtohchanspec(i) i -#endif - -#ifdef CONFIG_WIRELESS_EXT - -extern struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev); -extern int dhd_wait_pend8021x(struct net_device *dev); -#endif - -#if WIRELESS_EXT < 19 -#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST) -#define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST) -#endif - -static void *g_scan = NULL; -static volatile uint g_scan_specified_ssid; -static wlc_ssid_t g_specific_ssid; - -static wlc_ssid_t g_ssid; - -bool btcoex_is_sco_active(struct net_device *dev); -static wl_iw_ss_cache_ctrl_t g_ss_cache_ctrl; -#if defined(CONFIG_FIRST_SCAN) -static volatile uint g_first_broadcast_scan; -static volatile uint g_first_counter_scans; -#define MAX_ALLOWED_BLOCK_SCAN_FROM_FIRST_SCAN 3 -#endif - - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define DAEMONIZE(a) daemonize(a); \ - allow_signal(SIGKILL); \ - allow_signal(SIGTERM); -#else -#define RAISE_RX_SOFTIRQ() \ - cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ) -#define DAEMONIZE(a) daemonize(); \ - do { if (a) \ - strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a) + 1))); \ - } while (0); -#endif - -#if defined(WL_IW_USE_ISCAN) -#if !defined(CSCAN) -static void wl_iw_free_ss_cache(void); -static int wl_iw_run_ss_cache_timer(int kick_off); -#endif -#if defined(CONFIG_FIRST_SCAN) -int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag); -#endif -static int dev_wlc_bufvar_set(struct net_device *dev, char *name, char *buf, int len); -#define ISCAN_STATE_IDLE 0 -#define ISCAN_STATE_SCANING 1 - -#define WLC_IW_ISCAN_MAXLEN 2048 -typedef struct iscan_buf { - struct iscan_buf * next; - char iscan_buf[WLC_IW_ISCAN_MAXLEN]; -} iscan_buf_t; - -typedef struct iscan_info { - struct net_device *dev; - struct timer_list timer; - uint32 timer_ms; - uint32 timer_on; - int iscan_state; - iscan_buf_t * list_hdr; - iscan_buf_t * list_cur; - - - long sysioc_pid; - struct semaphore sysioc_sem; - struct completion sysioc_exited; - - uint32 scan_flag; -#if defined CSCAN - char ioctlbuf[WLC_IOCTL_MEDLEN]; -#else - char ioctlbuf[WLC_IOCTL_SMLEN]; -#endif - wl_iscan_params_t *iscan_ex_params_p; - int iscan_ex_param_size; -} iscan_info_t; -#define COEX_DHCP 1 - -#define BT_DHCP_eSCO_FIX -#define BT_DHCP_USE_FLAGS -#define BT_DHCP_OPPORTUNITY_WINDOW_TIME 2500 -#define BT_DHCP_FLAG_FORCE_TIME 5500 -static void wl_iw_bt_flag_set(struct net_device *dev, bool set); -static void wl_iw_bt_release(void); - -typedef enum bt_coex_status { - BT_DHCP_IDLE = 0, - BT_DHCP_START, - BT_DHCP_OPPORTUNITY_WINDOW, - BT_DHCP_FLAG_FORCE_TIMEOUT -} coex_status_t; - -typedef struct bt_info { - struct net_device *dev; - struct timer_list timer; - uint32 timer_ms; - uint32 timer_on; - bool dhcp_done; - int bt_state; - - long bt_pid; - struct semaphore bt_sem; - struct completion bt_exited; -} bt_info_t; - -bt_info_t *g_bt = NULL; -static void wl_iw_bt_timerfunc(ulong data); -iscan_info_t *g_iscan = NULL; -static void wl_iw_timerfunc(ulong data); -static void wl_iw_set_event_mask(struct net_device *dev); -static int -wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action); -#endif -static int -wl_iw_set_scan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -); - -#ifndef CSCAN -static int -wl_iw_get_scan( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -); - -static uint -wl_iw_get_scan_prep( - wl_scan_results_t *list, - struct iw_request_info *info, - char *extra, - short max_size -); -#endif - -static void swap_key_from_BE( - wl_wsec_key_t *key -) -{ - key->index = htod32(key->index); - key->len = htod32(key->len); - key->algo = htod32(key->algo); - key->flags = htod32(key->flags); - key->rxiv.hi = htod32(key->rxiv.hi); - key->rxiv.lo = htod16(key->rxiv.lo); - key->iv_initialized = htod32(key->iv_initialized); -} - -static void swap_key_to_BE( - wl_wsec_key_t *key -) -{ - key->index = dtoh32(key->index); - key->len = dtoh32(key->len); - key->algo = dtoh32(key->algo); - key->flags = dtoh32(key->flags); - key->rxiv.hi = dtoh32(key->rxiv.hi); - key->rxiv.lo = dtoh16(key->rxiv.lo); - key->iv_initialized = dtoh32(key->iv_initialized); -} - -static int -dev_wlc_ioctl( - struct net_device *dev, - int cmd, - void *arg, - int len -) -{ - struct ifreq ifr; - wl_ioctl_t ioc; - mm_segment_t fs; - int ret = -EINVAL; - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return ret; - } - - net_os_wake_lock(dev); - - WL_INFORM(("\n%s, PID:%x: send Local IOCTL -> dhd: cmd:0x%x, buf:%p, len:%d ,\n", - __FUNCTION__, current->pid, cmd, arg, len)); - - if (g_onoff == G_WLAN_SET_ON) { - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = cmd; - ioc.buf = arg; - ioc.len = len; - - strcpy(ifr.ifr_name, dev->name); - ifr.ifr_data = (caddr_t) &ioc; - - ret = dev_open(dev); - if (ret) { - WL_ERROR(("%s: Error dev_open: %d\n", __func__, ret)); - net_os_wake_unlock(dev); - return ret; - } - - fs = get_fs(); - set_fs(get_ds()); -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31)) - ret = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE); -#else - ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE); -#endif - set_fs(fs); - } - else { - WL_TRACE(("%s: call after driver stop : ignored\n", __FUNCTION__)); - } - - net_os_wake_unlock(dev); - - return ret; -} - - -static int -dev_wlc_intvar_get_reg( - struct net_device *dev, - char *name, - uint reg, - int *retval) -{ - union { - char buf[WLC_IOCTL_SMLEN]; - int val; - } var; - int error; - - uint len; - len = bcm_mkiovar(name, (char *)(®), sizeof(reg), (char *)(&var), sizeof(var.buf)); - ASSERT(len); - error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)&var, len); - - *retval = dtoh32(var.val); - return (error); -} - - -static int -dev_wlc_intvar_set_reg( - struct net_device *dev, - char *name, - char *addr, - char * val) -{ - char reg_addr[8]; - - memset(reg_addr, 0, sizeof(reg_addr)); - memcpy((char *)®_addr[0], (char *)addr, 4); - memcpy((char *)®_addr[4], (char *)val, 4); - - return (dev_wlc_bufvar_set(dev, name, (char *)®_addr[0], sizeof(reg_addr))); -} - - -static int -dev_wlc_intvar_set( - struct net_device *dev, - char *name, - int val) -{ - char buf[WLC_IOCTL_SMLEN]; - uint len; - - val = htod32(val); - len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf)); - ASSERT(len); - - return (dev_wlc_ioctl(dev, WLC_SET_VAR, buf, len)); -} - -#if defined(WL_IW_USE_ISCAN) -static int -dev_iw_iovar_setbuf( - struct net_device *dev, - char *iovar, - void *param, - int paramlen, - void *bufptr, - int buflen) -{ - int iolen; - - iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen); - ASSERT(iolen); - - if (iolen == 0) - return 0; - - return (dev_wlc_ioctl(dev, WLC_SET_VAR, bufptr, iolen)); -} - -static int -dev_iw_iovar_getbuf( - struct net_device *dev, - char *iovar, - void *param, - int paramlen, - void *bufptr, - int buflen) -{ - int iolen; - - iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen); - ASSERT(iolen); - - return (dev_wlc_ioctl(dev, WLC_GET_VAR, bufptr, buflen)); -} -#endif - - -#if WIRELESS_EXT > 17 -static int -dev_wlc_bufvar_set( - struct net_device *dev, - char *name, - char *buf, int len) -{ - static char ioctlbuf[MAX_WLIW_IOCTL_LEN]; - uint buflen; - - buflen = bcm_mkiovar(name, buf, len, ioctlbuf, sizeof(ioctlbuf)); - ASSERT(buflen); - - return (dev_wlc_ioctl(dev, WLC_SET_VAR, ioctlbuf, buflen)); -} -#endif - - -static int -dev_wlc_bufvar_get( - struct net_device *dev, - char *name, - char *buf, int buflen) -{ - static char ioctlbuf[MAX_WLIW_IOCTL_LEN]; - int error; - uint len; - - len = bcm_mkiovar(name, NULL, 0, ioctlbuf, sizeof(ioctlbuf)); - ASSERT(len); - error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)ioctlbuf, MAX_WLIW_IOCTL_LEN); - if (!error) - bcopy(ioctlbuf, buf, buflen); - - return (error); -} - - - -static int -dev_wlc_intvar_get( - struct net_device *dev, - char *name, - int *retval) -{ - union { - char buf[WLC_IOCTL_SMLEN]; - int val; - } var; - int error; - - uint len; - uint data_null; - - len = bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), sizeof(var.buf)); - ASSERT(len); - error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)&var, len); - - *retval = dtoh32(var.val); - - return (error); -} - - -#if WIRELESS_EXT > 12 -static int -wl_iw_set_active_scan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int as = 0; - int error = 0; - char *p = extra; - -#if defined(WL_IW_USE_ISCAN) - if (g_iscan->iscan_state == ISCAN_STATE_IDLE) -#endif - error = dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &as, sizeof(as)); -#if defined(WL_IW_USE_ISCAN) - else - g_iscan->scan_flag = as; -#endif - p += snprintf(p, MAX_WX_STRING, "OK"); - - wrqu->data.length = p - extra + 1; - return error; -} - -static int -wl_iw_set_passive_scan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int ps = 1; - int error = 0; - char *p = extra; - -#if defined(WL_IW_USE_ISCAN) - if (g_iscan->iscan_state == ISCAN_STATE_IDLE) { -#endif - - - if (g_scan_specified_ssid == 0) { - error = dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &ps, sizeof(ps)); - } -#if defined(WL_IW_USE_ISCAN) - } - else - g_iscan->scan_flag = ps; -#endif - - p += snprintf(p, MAX_WX_STRING, "OK"); - - wrqu->data.length = p - extra + 1; - return error; -} - - -static int -wl_iw_set_txpower( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = 0; - char *p = extra; - int txpower = -1; - - txpower = bcm_atoi(extra + strlen(TXPOWER_SET_CMD) + 1); - if ((txpower >= 0) && (txpower <= 127)) { - txpower |= WL_TXPWR_OVERRIDE; - txpower = htod32(txpower); - - error = dev_wlc_intvar_set(dev, "qtxpower", txpower); - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_TRACE(("%s: set TXpower 0x%X is OK\n", __FUNCTION__, txpower)); - } else { - WL_ERROR(("%s: set tx power failed\n", __FUNCTION__)); - p += snprintf(p, MAX_WX_STRING, "FAIL"); - } - - wrqu->data.length = p - extra + 1; - return error; -} - -static int -wl_iw_get_macaddr( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error; - char buf[128]; - struct ether_addr *id; - char *p = extra; - - - strcpy(buf, "cur_etheraddr"); - error = dev_wlc_ioctl(dev, WLC_GET_VAR, buf, sizeof(buf)); - id = (struct ether_addr *) buf; - p += snprintf(p, MAX_WX_STRING, "Macaddr = %02X:%02X:%02X:%02X:%02X:%02X\n", - id->octet[0], id->octet[1], id->octet[2], - id->octet[3], id->octet[4], id->octet[5]); - wrqu->data.length = p - extra + 1; - - return error; -} - - -static int -wl_iw_set_country( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - char country_code[WLC_CNTRY_BUF_SZ]; - int error = 0; - char *p = extra; - int country_offset; - int country_code_size; - wl_country_t cspec = {{0}, 0, {0}}; - char smbuf[WLC_IOCTL_SMLEN]; - - cspec.rev = -1; - memset(country_code, 0, sizeof(country_code)); - memset(smbuf, 0, sizeof(smbuf)); - - country_offset = strcspn(extra, " "); - country_code_size = strlen(extra) - country_offset; - - if (country_offset != 0) { - strncpy(country_code, extra + country_offset +1, - MIN(country_code_size, sizeof(country_code))); - - - memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ); - memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ); - - get_customized_country_code((char *)&cspec.country_abbrev, &cspec); - - if ((error = dev_iw_iovar_setbuf(dev, "country", &cspec, \ - sizeof(cspec), smbuf, sizeof(smbuf))) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_ERROR(("%s: set country for %s as %s rev %d is OK\n", \ - __FUNCTION__, country_code, cspec.ccode, cspec.rev)); - dhd_bus_country_set(dev, &cspec); - goto exit; - } - } - - WL_ERROR(("%s: set country for %s as %s rev %d failed\n", \ - __FUNCTION__, country_code, cspec.ccode, cspec.rev)); - - p += snprintf(p, MAX_WX_STRING, "FAIL"); - -exit: - wrqu->data.length = p - extra + 1; - return error; -} - -#ifdef CUSTOMER_HW2 -static int -wl_iw_set_power_mode( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = 0; - char *p = extra; - static int pm = PM_FAST; - int pm_local = PM_OFF; - char powermode_val = 0; - - WL_TRACE_COEX(("%s: DHCP session cmd:%s\n", __FUNCTION__, extra)); - - strncpy((char *)&powermode_val, extra + strlen("POWERMODE") + 1, 1); - - if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) { - - dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm)); - dev_wlc_ioctl(dev, WLC_SET_PM, &pm_local, sizeof(pm_local)); - - /* Disable packet filtering if necessary */ - net_os_set_packet_filter(dev, 0); - - g_bt->dhcp_done = false; - WL_TRACE_COEX(("%s: DHCP start, pm:%d changed to pm:%d\n", - __FUNCTION__, pm, pm_local)); - - } else if (strnicmp((char *)&powermode_val, "0", strlen("0")) == 0) { - - dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)); - - /* Enable packet filtering if was turned off */ - net_os_set_packet_filter(dev, 1); - - g_bt->dhcp_done = true; - - } else { - WL_ERROR(("%s Unkwown yet power setting, ignored\n", - __FUNCTION__)); - } - - p += snprintf(p, MAX_WX_STRING, "OK"); - - wrqu->data.length = p - extra + 1; - - return error; -} -#endif - - -bool btcoex_is_sco_active(struct net_device *dev) -{ - int ioc_res = 0; - bool res = false; - int sco_id_cnt = 0; - int param27; - int i; - - for (i = 0; i < 12; i++) { - - ioc_res = dev_wlc_intvar_get_reg(dev, "btc_params", 27, ¶m27); - - WL_TRACE_COEX(("%s, sample[%d], btc params: 27:%x\n", - __FUNCTION__, i, param27)); - - if (ioc_res < 0) { - WL_ERROR(("%s ioc read btc params error\n", __FUNCTION__)); - break; - } - - if ((param27 & 0x6) == 2) { - sco_id_cnt++; - } - - if (sco_id_cnt > 2) { - WL_TRACE_COEX(("%s, sco/esco detected, pkt id_cnt:%d samples:%d\n", - __FUNCTION__, sco_id_cnt, i)); - res = true; - break; - } - - msleep(5); - } - - return res; -} - -#if defined(BT_DHCP_eSCO_FIX) - -static int set_btc_esco_params(struct net_device *dev, bool trump_sco) -{ - static bool saved_status = false; - - char buf_reg50va_dhcp_on[8] = { 50, 00, 00, 00, 0x22, 0x80, 0x00, 0x00 }; - char buf_reg51va_dhcp_on[8] = { 51, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - char buf_reg64va_dhcp_on[8] = { 64, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - char buf_reg65va_dhcp_on[8] = { 65, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - char buf_reg71va_dhcp_on[8] = { 71, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - - uint32 regaddr; - static uint32 saved_reg50; - static uint32 saved_reg51; - static uint32 saved_reg64; - static uint32 saved_reg65; - static uint32 saved_reg71; - - if (trump_sco) { - - WL_TRACE_COEX(("Do new SCO/eSCO coex algo {save & override} \n")); - - if ((!dev_wlc_intvar_get_reg(dev, "btc_params", 50, &saved_reg50)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 51, &saved_reg51)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 64, &saved_reg64)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 65, &saved_reg65)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 71, &saved_reg71))) { - - saved_status = TRUE; - WL_TRACE_COEX(("%s saved bt_params[50,51,64,65,71]:" - " 0x%x 0x%x 0x%x 0x%x 0x%x\n", - __FUNCTION__, saved_reg50, saved_reg51, - saved_reg64, saved_reg65, saved_reg71)); - - } else { - WL_ERROR((":%s: save btc_params failed\n", - __FUNCTION__)); - saved_status = false; - return -1; - } - - WL_TRACE_COEX(("override with [50,51,64,65,71]:" - " 0x%x 0x%x 0x%x 0x%x 0x%x\n", - *(u32 *)(buf_reg50va_dhcp_on+4), - *(u32 *)(buf_reg51va_dhcp_on+4), - *(u32 *)(buf_reg64va_dhcp_on+4), - *(u32 *)(buf_reg65va_dhcp_on+4), - *(u32 *)(buf_reg71va_dhcp_on+4))); - - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg50va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg51va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg64va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg65va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg71va_dhcp_on[0], 8); - - saved_status = true; - - } else if (saved_status) { - - WL_TRACE_COEX(("Do new SCO/eSCO coex algo {save & override} \n")); - - regaddr = 50; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg50); - regaddr = 51; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg51); - regaddr = 64; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg64); - regaddr = 65; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg65); - regaddr = 71; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg71); - - WL_TRACE_COEX(("restore bt_params[50,51,64,65,71]: 0x%x 0x%x 0x%x 0x%x 0x%x\n", - saved_reg50, saved_reg51, saved_reg64, - saved_reg65, saved_reg71)); - - saved_status = false; - } else { - WL_ERROR((":%s att to restore not saved BTCOEX params\n", - __FUNCTION__)); - return -1; - } - return 0; -} -#endif - -static int -wl_iw_get_power_mode( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error; - char *p = extra; - int pm_local = PM_FAST; - - error = dev_wlc_ioctl(dev, WLC_GET_PM, &pm_local, sizeof(pm_local)); - if (!error) { - WL_TRACE(("%s: Powermode = %d\n", __func__, pm_local)); - if (pm_local == PM_OFF) - pm_local = 1; /* Active */ - else - pm_local = 0; /* Auto */ - p += snprintf(p, MAX_WX_STRING, "powermode = %d", pm_local); - } - else { - WL_TRACE(("%s: Error = %d\n", __func__, error)); - p += snprintf(p, MAX_WX_STRING, "FAIL"); - } - wrqu->data.length = p - extra + 1; - return error; -} - -static int -wl_iw_set_btcoex_dhcp( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = 0; - char *p = extra; -#ifndef CUSTOMER_HW2 - static int pm = PM_FAST; - int pm_local = PM_OFF; -#endif - char powermode_val = 0; - char buf_reg66va_dhcp_on[8] = { 66, 00, 00, 00, 0x10, 0x27, 0x00, 0x00 }; - char buf_reg41va_dhcp_on[8] = { 41, 00, 00, 00, 0x33, 0x00, 0x00, 0x00 }; - char buf_reg68va_dhcp_on[8] = { 68, 00, 00, 00, 0x90, 0x01, 0x00, 0x00 }; - - uint32 regaddr; - static uint32 saved_reg66; - static uint32 saved_reg41; - static uint32 saved_reg68; - static bool saved_status = FALSE; - - char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00}; - -#ifdef CUSTOMER_HW2 - strncpy((char *)&powermode_val, extra + strlen("BTCOEXMODE") + 1, 1); -#else - strncpy((char *)&powermode_val, extra + strlen("POWERMODE") + 1, 1); -#endif - - if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) { - - WL_TRACE_COEX(("%s: DHCP session start, cmd:%s\n", __FUNCTION__, extra)); - - if ((saved_status == FALSE) && -#ifndef CUSTOMER_HW2 - (!dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm))) && -#endif - (!dev_wlc_intvar_get_reg(dev, "btc_params", 66, &saved_reg66)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 41, &saved_reg41)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 68, &saved_reg68))) { - WL_TRACE_COEX(("save regs {66,41,68} ->: 0x%x 0x%x 0x%x\n", \ - saved_reg66, saved_reg41, saved_reg68)); - -#ifndef CUSTOMER_HW2 - dev_wlc_ioctl(dev, WLC_SET_PM, &pm_local, sizeof(pm_local)); -#endif - - if (btcoex_is_sco_active(dev)) { - - dev_wlc_bufvar_set(dev, "btc_params", \ - (char *)&buf_reg66va_dhcp_on[0], \ - sizeof(buf_reg66va_dhcp_on)); - - dev_wlc_bufvar_set(dev, "btc_params", \ - (char *)&buf_reg41va_dhcp_on[0], \ - sizeof(buf_reg41va_dhcp_on)); - - dev_wlc_bufvar_set(dev, "btc_params", \ - (char *)&buf_reg68va_dhcp_on[0], \ - sizeof(buf_reg68va_dhcp_on)); - saved_status = TRUE; - - g_bt->bt_state = BT_DHCP_START; - g_bt->timer_on = 1; - mod_timer(&g_bt->timer, g_bt->timer.expires); - WL_TRACE_COEX(("%s enable BT DHCP Timer\n", \ - __FUNCTION__)); - } - } - else if (saved_status == TRUE) { - WL_ERROR(("%s was called w/o DHCP OFF. Continue\n", __FUNCTION__)); - } - } -#ifdef CUSTOMER_HW2 - else if (strnicmp((char *)&powermode_val, "2", strlen("2")) == 0) { -#else - else if (strnicmp((char *)&powermode_val, "0", strlen("0")) == 0) { -#endif - -#ifndef CUSTOMER_HW2 - dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)); -#endif - - WL_TRACE_COEX(("%s disable BT DHCP Timer\n", __FUNCTION__)); - if (g_bt->timer_on) { - g_bt->timer_on = 0; - del_timer_sync(&g_bt->timer); - - if (g_bt->bt_state != BT_DHCP_IDLE) { - WL_TRACE_COEX(("%s bt->bt_state:%d\n", - __FUNCTION__, g_bt->bt_state)); - - up(&g_bt->bt_sem); - } - } - - if (saved_status == TRUE) { - dev_wlc_bufvar_set(dev, "btc_flags", \ - (char *)&buf_flag7_default[0], sizeof(buf_flag7_default)); - - regaddr = 66; - dev_wlc_intvar_set_reg(dev, "btc_params", \ - (char *)®addr, (char *)&saved_reg66); - regaddr = 41; - dev_wlc_intvar_set_reg(dev, "btc_params", \ - (char *)®addr, (char *)&saved_reg41); - regaddr = 68; - dev_wlc_intvar_set_reg(dev, "btc_params", \ - (char *)®addr, (char *)&saved_reg68); - - WL_TRACE_COEX(("restore regs {66,41,68} <- 0x%x 0x%x 0x%x\n", \ - saved_reg66, saved_reg41, saved_reg68)); - } - saved_status = FALSE; - } - else { - WL_ERROR(("%s Unkwown yet power setting, ignored\n", - __FUNCTION__)); - } - - p += snprintf(p, MAX_WX_STRING, "OK"); - - wrqu->data.length = p - extra + 1; - - return error; -} - -static int -wl_iw_set_suspend( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int suspend_flag; - int ret_now; - int ret = 0; - - suspend_flag = *(extra + strlen(SETSUSPEND_CMD) + 1) - '0'; - - if (suspend_flag != 0) - suspend_flag = 1; - - ret_now = net_os_set_suspend_disable(dev, suspend_flag); - - if (ret_now != suspend_flag) { - if (!(ret = net_os_set_suspend(dev, ret_now))) - WL_ERROR(("%s: Suspend Flag %d -> %d\n", \ - __FUNCTION__, ret_now, suspend_flag)); - else - WL_ERROR(("%s: failed %d\n", __FUNCTION__, ret)); - } - - return ret; -} - - -int -wl_format_ssid(char* ssid_buf, uint8* ssid, int ssid_len) -{ - int i, c; - char *p = ssid_buf; - - if (ssid_len > 32) ssid_len = 32; - - for (i = 0; i < ssid_len; i++) { - c = (int)ssid[i]; - if (c == '\\') { - *p++ = '\\'; - *p++ = '\\'; - } else if (isprint((uchar)c)) { - *p++ = (char)c; - } else { - p += sprintf(p, "\\x%02X", c); - } - } - *p = '\0'; - - return p - ssid_buf; -} - -static int -wl_iw_get_link_speed( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = 0; - char *p = extra; - static int link_speed; - - net_os_wake_lock(dev); - if (g_onoff == G_WLAN_SET_ON) { - error = dev_wlc_ioctl(dev, WLC_GET_RATE, &link_speed, sizeof(link_speed)); - link_speed *= 500000; - } - - p += snprintf(p, MAX_WX_STRING, "LinkSpeed %d", link_speed/1000000); - - wrqu->data.length = p - extra + 1; - - net_os_wake_unlock(dev); - return error; -} - - -static int -wl_iw_get_dtim_skip( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - char iovbuf[32]; - - net_os_wake_lock(dev); - if (g_onoff == G_WLAN_SET_ON) { - - memset(iovbuf, 0, sizeof(iovbuf)); - strcpy(iovbuf, "bcn_li_dtim"); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_VAR, - &iovbuf, sizeof(iovbuf))) >= 0) { - - p += snprintf(p, MAX_WX_STRING, "Dtim_skip %d", iovbuf[0]); - WL_TRACE(("%s: get dtim_skip = %d\n", __FUNCTION__, iovbuf[0])); - wrqu->data.length = p - extra + 1; - } - else - WL_ERROR(("%s: get dtim_skip failed code %d\n", \ - __FUNCTION__, error)); - } - net_os_wake_unlock(dev); - return error; -} - - -static int -wl_iw_set_dtim_skip( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - int bcn_li_dtim; - char iovbuf[32]; - - net_os_wake_lock(dev); - if (g_onoff == G_WLAN_SET_ON) { - - bcn_li_dtim = htod32((uint)*(extra + strlen(DTIM_SKIP_SET_CMD) + 1) - '0'); - - if ((bcn_li_dtim >= 0) || ((bcn_li_dtim <= 5))) { - - memset(iovbuf, 0, sizeof(iovbuf)); - bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim, - 4, iovbuf, sizeof(iovbuf)); - - if ((error = dev_wlc_ioctl(dev, WLC_SET_VAR, - &iovbuf, sizeof(iovbuf))) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - - net_os_set_dtim_skip(dev, bcn_li_dtim); - - WL_TRACE(("%s: set dtim_skip %d OK\n", __FUNCTION__, \ - bcn_li_dtim)); - goto exit; - } - else WL_ERROR(("%s: set dtim_skip %d failed code %d\n", \ - __FUNCTION__, bcn_li_dtim, error)); - } - else WL_ERROR(("%s Incorrect dtim_skip setting %d, ignored\n", \ - __FUNCTION__, bcn_li_dtim)); - } - - p += snprintf(p, MAX_WX_STRING, "FAIL"); - -exit: - wrqu->data.length = p - extra + 1; - net_os_wake_unlock(dev); - return error; -} - - -static int -wl_iw_get_band( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - static int band; - - net_os_wake_lock(dev); - - if (g_onoff == G_WLAN_SET_ON) { - error = dev_wlc_ioctl(dev, WLC_GET_BAND, &band, sizeof(band)); - - p += snprintf(p, MAX_WX_STRING, "Band %d", band); - - wrqu->data.length = p - extra + 1; - } - - net_os_wake_unlock(dev); - return error; -} - - -static int -wl_iw_set_band( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - uint band; - - net_os_wake_lock(dev); - - if (g_onoff == G_WLAN_SET_ON) { - - band = htod32((uint)*(extra + strlen(BAND_SET_CMD) + 1) - '0'); - - if ((band == WLC_BAND_AUTO) || (band == WLC_BAND_5G) || (band == WLC_BAND_2G)) { - - if ((error = dev_wlc_ioctl(dev, WLC_SET_BAND, - &band, sizeof(band))) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_TRACE(("%s: set band %d OK\n", __FUNCTION__, band)); - goto exit; - } - else WL_ERROR(("%s: set band %d failed code %d\n", __FUNCTION__, \ - band, error)); - } - else WL_ERROR(("%s Incorrect band setting %d, ignored\n", __FUNCTION__, band)); - } - - p += snprintf(p, MAX_WX_STRING, "FAIL"); - -exit: - wrqu->data.length = p - extra + 1; - net_os_wake_unlock(dev); - return error; -} - -#ifdef PNO_SUPPORT - -static int -wl_iw_set_pno_reset( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - - net_os_wake_lock(dev); - if ((g_onoff == G_WLAN_SET_ON) && (dev != NULL)) { - - if ((error = dhd_dev_pno_reset(dev)) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_TRACE(("%s: set OK\n", __FUNCTION__)); - goto exit; - } - else WL_ERROR(("%s: failed code %d\n", __FUNCTION__, error)); - } - - p += snprintf(p, MAX_WX_STRING, "FAIL"); - -exit: - wrqu->data.length = p - extra + 1; - net_os_wake_unlock(dev); - return error; -} - - - -static int -wl_iw_set_pno_enable( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - int pfn_enabled; - - net_os_wake_lock(dev); - pfn_enabled = htod32((uint)*(extra + strlen(PNOENABLE_SET_CMD) + 1) - '0'); - - if ((g_onoff == G_WLAN_SET_ON) && (dev != NULL)) { - - if ((error = dhd_dev_pno_enable(dev, pfn_enabled)) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_TRACE(("%s: set OK\n", __FUNCTION__)); - goto exit; - } - else WL_ERROR(("%s: failed code %d\n", __FUNCTION__, error)); - } - - p += snprintf(p, MAX_WX_STRING, "FAIL"); - -exit: - wrqu->data.length = p - extra + 1; - net_os_wake_unlock(dev); - return error; -} - - - -static int -wl_iw_set_pno_set( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int res = -1; - wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT]; - int nssid = 0; - cmd_tlv_t *cmd_tlv_temp; - char *str_ptr; - int tlv_size_left; - int pno_time; - int pno_repeat; - int pno_freq_expo_max; - -#ifdef PNO_SET_DEBUG - int i; - char pno_in_example[] = {'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ', \ - 'S', '1', '2', '0', - 'S', - 0x04, - 'B', 'R', 'C', 'M', - 'S', - 0x04, - 'G', 'O', 'O', 'G', - 'T', - '1','E', - 'R', - '2', - 'M', - '2', - 0x00 - }; -#endif - - net_os_wake_lock(dev); - WL_ERROR(("\n### %s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); - goto exit_proc; - } - - if (wrqu->data.length < (strlen(PNOSETUP_SET_CMD) + sizeof(cmd_tlv_t))) { - WL_ERROR(("%s aggument=%d less %d\n", __FUNCTION__, \ - wrqu->data.length, strlen(PNOSETUP_SET_CMD) + sizeof(cmd_tlv_t))); - goto exit_proc; - } - -#ifdef PNO_SET_DEBUG - if (!(extra = kmalloc(sizeof(pno_in_example) +100, GFP_KERNEL))) { - res = -ENOMEM; - goto exit_proc; - } - memcpy(extra, pno_in_example, sizeof(pno_in_example)); - wrqu->data.length = sizeof(pno_in_example); - for (i = 0; i < wrqu->data.length; i++) - printf("%02X ", extra[i]); - printf("\n"); -#endif - - str_ptr = extra; -#ifdef PNO_SET_DEBUG - str_ptr += strlen("PNOSETUP "); - tlv_size_left = wrqu->data.length - strlen("PNOSETUP "); -#else - str_ptr += strlen(PNOSETUP_SET_CMD); - tlv_size_left = wrqu->data.length - strlen(PNOSETUP_SET_CMD); -#endif - - cmd_tlv_temp = (cmd_tlv_t *)str_ptr; - memset(ssids_local, 0, sizeof(ssids_local)); - pno_repeat = pno_freq_expo_max = 0; - - if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) && \ - (cmd_tlv_temp->version == PNO_TLV_VERSION) && \ - (cmd_tlv_temp->subver == PNO_TLV_SUBVERSION)) - { - str_ptr += sizeof(cmd_tlv_t); - tlv_size_left -= sizeof(cmd_tlv_t); - - if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local, \ - MAX_PFN_LIST_COUNT, &tlv_size_left)) <= 0) { - WL_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid)); - goto exit_proc; - } - else { - if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) { - WL_ERROR(("%s scan duration corrupted field size %d\n", \ - __FUNCTION__, tlv_size_left)); - goto exit_proc; - } - str_ptr++; - pno_time = simple_strtoul(str_ptr, &str_ptr, 16); - WL_PNO(("%s: pno_time=%d\n", __FUNCTION__, pno_time)); - - if (str_ptr[0] != 0) { - if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) { - WL_ERROR(("%s pno repeat : corrupted field\n", \ - __FUNCTION__)); - goto exit_proc; - } - str_ptr++; - pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16); - WL_PNO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat)); - if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) { - WL_ERROR(("%s FREQ_EXPO_MAX corrupted field size\n", \ - __FUNCTION__)); - goto exit_proc; - } - str_ptr++; - pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16); - WL_PNO(("%s: pno_freq_expo_max=%d\n", \ - __FUNCTION__, pno_freq_expo_max)); - } - } - } - else { - WL_ERROR(("%s get wrong TLV command\n", __FUNCTION__)); - goto exit_proc; - } - - res = dhd_dev_pno_set(dev, ssids_local, nssid, pno_time, pno_repeat, pno_freq_expo_max); - -exit_proc: - net_os_wake_unlock(dev); - return res; -} -#endif - -static int -wl_iw_get_rssi( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - static int rssi = 0; - static wlc_ssid_t ssid = {0}; - int error = 0; - char *p = extra; - static char ssidbuf[SSID_FMT_BUF_LEN]; - scb_val_t scb_val; - - net_os_wake_lock(dev); - - bzero(&scb_val, sizeof(scb_val_t)); - - if (g_onoff == G_WLAN_SET_ON) { - error = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)); - if (error) { - WL_ERROR(("%s: Fails %d\n", __FUNCTION__, error)); - } else { - rssi = dtoh32(scb_val.val); - - error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)); - if (!error) { - ssid.SSID_len = dtoh32(ssid.SSID_len); - wl_format_ssid(ssidbuf, ssid.SSID, dtoh32(ssid.SSID_len)); - } - } - } - - WL_ASSOC(("%s ssid_len:%d, rssi:%d\n", __FUNCTION__, ssid.SSID_len, rssi)); - - if (error || (ssid.SSID_len == 0)) { - p += snprintf(p, MAX_WX_STRING, "FAIL"); - } else { - p += snprintf(p, MAX_WX_STRING, "%s rssi %d ", ssidbuf, rssi); - } - wrqu->data.length = p - extra + 1; - - net_os_wake_unlock(dev); - return error; -} - -int -wl_iw_send_priv_event( - struct net_device *dev, - char *flag -) -{ - union iwreq_data wrqu; - char extra[IW_CUSTOM_MAX + 1]; - int cmd; - - cmd = IWEVCUSTOM; - memset(&wrqu, 0, sizeof(wrqu)); - if (strlen(flag) > sizeof(extra)) - return -1; - - strcpy(extra, flag); - wrqu.data.length = strlen(extra); - wireless_send_event(dev, cmd, &wrqu, extra); - net_os_wake_lock_timeout_enable(dev); - WL_TRACE(("Send IWEVCUSTOM Event as %s\n", extra)); - - return 0; -} - - -int -wl_control_wl_start(struct net_device *dev) -{ - int ret = 0; - wl_iw_t *iw; - - WL_TRACE(("Enter %s \n", __FUNCTION__)); - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -1; - } - - iw = *(wl_iw_t **)netdev_priv(dev); - - if (!iw) { - WL_ERROR(("%s: wl is null\n", __FUNCTION__)); - return -1; - } - dhd_os_start_lock(iw->pub); - - if (g_onoff == G_WLAN_SET_OFF) { - dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON); - -#if defined(BCMLXSDMMC) - sdioh_start(NULL, 0); -#endif - - ret = dhd_dev_reset(dev, 0); - - if (ret == BCME_OK) { -#if defined(BCMLXSDMMC) - sdioh_start(NULL, 1); -#endif - dhd_dev_init_ioctl(dev); - g_onoff = G_WLAN_SET_ON; - } - } - WL_TRACE(("Exited %s \n", __FUNCTION__)); - - dhd_os_start_unlock(iw->pub); - return ret; -} - - -static int -wl_iw_control_wl_off( - struct net_device *dev, - struct iw_request_info *info -) -{ - int ret = 0; - wl_iw_t *iw; - - WL_TRACE(("Enter %s\n", __FUNCTION__)); - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -1; - } - - iw = *(wl_iw_t **)netdev_priv(dev); - if (!iw) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -1; - } - dhd_os_start_lock(iw->pub); - -#ifdef SOFTAP - ap_cfg_running = FALSE; -#endif - - if (g_onoff == G_WLAN_SET_ON) { - g_onoff = G_WLAN_SET_OFF; -#if defined(WL_IW_USE_ISCAN) - g_iscan->iscan_state = ISCAN_STATE_IDLE; -#endif - - dhd_dev_reset(dev, 1); - -#if defined(WL_IW_USE_ISCAN) -#if !defined(CSCAN) - wl_iw_free_ss_cache(); - wl_iw_run_ss_cache_timer(0); - - g_ss_cache_ctrl.m_link_down = 1; -#endif - memset(g_scan, 0, G_SCAN_RESULTS); - g_scan_specified_ssid = 0; -#if defined(CONFIG_FIRST_SCAN) - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_IDLE; - g_first_counter_scans = 0; -#endif -#endif - -#if defined(BCMLXSDMMC) - sdioh_stop(NULL); -#endif - - net_os_set_dtim_skip(dev, 0); - - dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); - - wl_iw_send_priv_event(dev, "STOP"); - } - - dhd_os_start_unlock(iw->pub); - - WL_TRACE(("Exited %s\n", __FUNCTION__)); - - return ret; -} - -static int -wl_iw_control_wl_on( - struct net_device *dev, - struct iw_request_info *info -) -{ - int ret = 0; - - WL_TRACE(("Enter %s \n", __FUNCTION__)); - - if ((ret = wl_control_wl_start(dev)) != BCME_OK) { - WL_ERROR(("%s failed first attemp\n", __FUNCTION__)); - dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); - if ((ret = wl_control_wl_start(dev)) != BCME_OK) { - WL_ERROR(("%s failed second attemp\n", __FUNCTION__)); - net_os_send_hang_message(dev); - return ret; - } - } - - wl_iw_send_priv_event(dev, "START"); - -#ifdef SOFTAP - if (!ap_fw_loaded) { - wl_iw_iscan_set_scan_broadcast_prep(dev, 0); - } -#else - wl_iw_iscan_set_scan_broadcast_prep(dev, 0); -#endif - - WL_TRACE(("Exited %s \n", __FUNCTION__)); - - return ret; -} - -#ifdef SOFTAP -static struct ap_profile my_ap; -static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap); -static int get_assoc_sta_list(struct net_device *dev, char *buf, int len); -static int set_ap_mac_list(struct net_device *dev, void *buf); - -#define PTYPE_STRING 0 -#define PTYPE_INTDEC 1 -#define PTYPE_INTHEX 2 -#define PTYPE_STR_HEX 3 -int get_parmeter_from_string( - char **str_ptr, const char *token, int param_type, void *dst, int param_max_len); - -#endif - -int hex2num(char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - return -1; -} - -int hex2byte(const char *hex) -{ - int a, b; - a = hex2num(*hex++); - if (a < 0) - return -1; - b = hex2num(*hex++); - if (b < 0) - return -1; - return (a << 4) | b; -} - - - -int hstr_2_buf(const char *txt, u8 *buf, int len) -{ - int i; - - for (i = 0; i < len; i++) { - int a, b; - - a = hex2num(*txt++); - if (a < 0) - return -1; - b = hex2num(*txt++); - if (b < 0) - return -1; - *buf++ = (a << 4) | b; - } - - return 0; -} - -#if defined(SOFTAP) && defined(SOFTAP_TLV_CFG) - -static int wl_iw_softap_cfg_tlv( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int res = -1; - char *str_ptr; - int tlv_size_left; - - -#define SOFTAP_TLV_DEBUG 1 -#ifdef SOFTAP_TLV_DEBUG -char softap_cmd_example[] = { - - 'S', 'O', 'F', 'T', 'A', 'P', 'S', 'E', 'T', ' ', - - SOFTAP_TLV_PREFIX, SOFTAP_TLV_VERSION, - SOFTAP_TLV_SUBVERSION, SOFTAP_TLV_RESERVED, - - TLV_TYPE_SSID, 9, 'B', 'R', 'C', 'M', ',', 'G', 'O', 'O', 'G', - - TLV_TYPE_SECUR, 4, 'O', 'P', 'E', 'N', - - TLV_TYPE_KEY, 4, 0x31, 0x32, 0x33, 0x34, - - TLV_TYPE_CHANNEL, 4, 0x06, 0x00, 0x00, 0x00 -}; -#endif - - -#ifdef SOFTAP_TLV_DEBUG - { - int i; - if (!(extra = kmalloc(sizeof(softap_cmd_example) +10, GFP_KERNEL))) - return -ENOMEM; - memcpy(extra, softap_cmd_example, sizeof(softap_cmd_example)); - wrqu->data.length = sizeof(softap_cmd_example); - print_buf(extra, wrqu->data.length, 16); - for (i = 0; i < wrqu->data.length; i++) - printf("%c ", extra[i]); - printf("\n"); - } -#endif - - WL_ERROR(("\n### %s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); - return -1; - } - - if (wrqu->data.length < (strlen(SOFTAP_SET_CMD) + sizeof(cmd_tlv_t))) { - WL_ERROR(("%s argument=%d less %d\n", __FUNCTION__, - wrqu->data.length, strlen(SOFTAP_SET_CMD) + sizeof(cmd_tlv_t))); - return -1; - } - - str_ptr = extra + strlen(SOFTAP_SET_CMD)+1; - tlv_size_left = wrqu->data.length - (strlen(SOFTAP_SET_CMD)+1); - - memset(&my_ap, 0, sizeof(my_ap)); - - return res; -} -#endif - - -#ifdef SOFTAP -int init_ap_profile_from_string(char *param_str, struct ap_profile *ap_cfg) -{ - char *str_ptr = param_str; - char sub_cmd[16]; - int ret = 0; - - memset(sub_cmd, 0, sizeof(sub_cmd)); - memset(ap_cfg, 0, sizeof(struct ap_profile)); - - if (get_parmeter_from_string(&str_ptr, "ASCII_CMD=", - PTYPE_STRING, sub_cmd, SSID_LEN) != 0) { - return -1; - } - if (strncmp(sub_cmd, "AP_CFG", 6)) { - WL_ERROR(("ERROR: sub_cmd:%s != 'AP_CFG'!\n", sub_cmd)); - return -1; - } - - ret = get_parmeter_from_string(&str_ptr, "SSID=", PTYPE_STRING, ap_cfg->ssid, SSID_LEN); - - ret |= get_parmeter_from_string(&str_ptr, "SEC=", PTYPE_STRING, ap_cfg->sec, SEC_LEN); - - ret |= get_parmeter_from_string(&str_ptr, "KEY=", PTYPE_STRING, ap_cfg->key, KEY_LEN); - - ret |= get_parmeter_from_string(&str_ptr, "CHANNEL=", PTYPE_INTDEC, &ap_cfg->channel, 5); - - get_parmeter_from_string(&str_ptr, "PREAMBLE=", PTYPE_INTDEC, &ap_cfg->preamble, 5); - - get_parmeter_from_string(&str_ptr, "MAX_SCB=", PTYPE_INTDEC, &ap_cfg->max_scb, 5); - - get_parmeter_from_string(&str_ptr, "HIDDEN=", PTYPE_INTDEC, &ap_cfg->closednet, 5); - - get_parmeter_from_string(&str_ptr, "COUNTRY=", PTYPE_STRING, &ap_cfg->country_code, 3); - - return ret; -} -#endif - - -#ifdef SOFTAP -static int iwpriv_set_ap_config(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int res = 0; - char *extra = NULL; - struct ap_profile *ap_cfg = &my_ap; - - WL_TRACE(("%s: info->cmd:%x, info->flags:%x, u.data:%p, u.len:%d\n", - __FUNCTION__, - info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (wrqu->data.length != 0) { - - char *str_ptr; - - if (!(extra = kmalloc(wrqu->data.length+1, GFP_KERNEL))) - return -ENOMEM; - - if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) { - kfree(extra); - return -EFAULT; - } - - extra[wrqu->data.length] = 0; - WL_SOFTAP((" Got str param in iw_point:\n %s\n", extra)); - - memset(ap_cfg, 0, sizeof(struct ap_profile)); - - str_ptr = extra; - - if ((res = init_ap_profile_from_string(extra, ap_cfg)) < 0) { - WL_ERROR(("%s failed to parse %d\n", __FUNCTION__, res)); - kfree(extra); - return -1; - } - - } else { - WL_ERROR(("IWPRIV argument len = 0 \n")); - return -1; - } - - if ((res = set_ap_cfg(dev, ap_cfg)) < 0) - WL_ERROR(("%s failed to set_ap_cfg %d\n", __FUNCTION__, res)); - - kfree(extra); - - return res; -} -#endif - - -#ifdef SOFTAP -static int iwpriv_get_assoc_list(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *p_iwrq, - char *extra) -{ - int i, ret = 0; - char mac_buf[256]; - struct maclist *sta_maclist = (struct maclist *)mac_buf; - - char mac_lst[384]; - char *p_mac_str; - char *p_mac_str_end; - - if ((!dev) || (!extra)) { - return -EINVAL; - } - - net_os_wake_lock(dev); - - WL_TRACE(("\n %s: IWPRIV IOCTL: cmd:%hx, flags:%hx, extra:%p, iwp.len:%d, \ - iwp.len:%p, iwp.flags:%x \n", __FUNCTION__, info->cmd, info->flags, \ - extra, p_iwrq->data.length, p_iwrq->data.pointer, p_iwrq->data.flags)); - - memset(sta_maclist, 0, sizeof(mac_buf)); - - sta_maclist->count = 8; - - WL_SOFTAP(("%s: net device:%s, buf_sz:%d\n", - __FUNCTION__, dev->name, sizeof(mac_buf))); - - if ((ret = get_assoc_sta_list(dev, mac_buf, sizeof(mac_buf))) < 0) { - WL_ERROR(("%s: sta list ioctl error:%d\n", - __FUNCTION__, ret)); - goto func_exit; - } - - WL_SOFTAP(("%s: got %d stations\n", __FUNCTION__, - sta_maclist->count)); - - memset(mac_lst, 0, sizeof(mac_lst)); - p_mac_str = mac_lst; - p_mac_str_end = &mac_lst[sizeof(mac_lst)-1]; - - for (i = 0; i < 8; i++) { - struct ether_addr *id = &sta_maclist->ea[i]; - if (!ETHER_ISNULLADDR(id->octet)) { - scb_val_t scb_val; - int rssi = 0; - - bzero(&scb_val, sizeof(scb_val_t)); - - if ((p_mac_str_end - p_mac_str) <= 36) { - WL_ERROR(("%s: mac list buf is < 36 for item[%i] item\n", - __FUNCTION__, i)); - break; - } - - p_mac_str += snprintf(p_mac_str, MAX_WX_STRING, - "\nMac[%d]=%02X:%02X:%02X:%02X:%02X:%02X,", i, - id->octet[0], id->octet[1], id->octet[2], - id->octet[3], id->octet[4], id->octet[5]); - - bcopy(id->octet, &scb_val.ea, 6); - ret = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)); - if (ret < 0) { - snprintf(p_mac_str, MAX_WX_STRING, "RSSI:ERR"); - WL_ERROR(("%s: RSSI ioctl error:%d\n", - __FUNCTION__, ret)); - break; - } - - rssi = dtoh32(scb_val.val); - p_mac_str += snprintf(p_mac_str, MAX_WX_STRING, - "RSSI:%d", rssi); - } - } - - p_iwrq->data.length = strlen(mac_lst) + 1; - - WL_SOFTAP(("%s: data to user:\n%s\n usr_ptr:%p\n", __FUNCTION__, - mac_lst, p_iwrq->data.pointer)); - - if (p_iwrq->data.length) { - bcopy(mac_lst, extra, p_iwrq->data.length); - } - -func_exit: - net_os_wake_unlock(dev); - - WL_TRACE(("Exited %s \n", __FUNCTION__)); - return ret; -} -#endif - - -#ifdef SOFTAP -#define MAC_FILT_MAX 8 -static int iwpriv_set_mac_filters(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int i, ret = -1; - char * extra = NULL; - int mac_cnt = 0; - int mac_mode = 0; - struct ether_addr *p_ea; - struct mac_list_set mflist_set; - - WL_SOFTAP((">>> Got IWPRIV SET_MAC_FILTER IOCTL: info->cmd:%x, \ - info->flags:%x, u.data:%p, u.len:%d\n", - info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (wrqu->data.length != 0) { - - char *str_ptr; - - if (!(extra = kmalloc(wrqu->data.length+1, GFP_KERNEL))) - return -ENOMEM; - - if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) { - kfree(extra); - return -EFAULT; - } - - extra[wrqu->data.length] = 0; - WL_SOFTAP((" Got parameter string in iw_point:\n %s \n", extra)); - - memset(&mflist_set, 0, sizeof(mflist_set)); - - str_ptr = extra; - - if (get_parmeter_from_string(&str_ptr, "MAC_MODE=", - PTYPE_INTDEC, &mac_mode, 4) != 0) { - WL_ERROR(("ERROR: 'MAC_MODE=' token is missing\n")); - goto exit_proc; - } - - p_ea = &mflist_set.mac_list.ea[0]; - - if (get_parmeter_from_string(&str_ptr, "MAC_CNT=", - PTYPE_INTDEC, &mac_cnt, 4) != 0) { - WL_ERROR(("ERROR: 'MAC_CNT=' token param is missing \n")); - goto exit_proc; - } - - if (mac_cnt > MAC_FILT_MAX) { - WL_ERROR(("ERROR: number of MAC filters > MAX\n")); - goto exit_proc; - } - - for (i=0; i < mac_cnt; i++) - if (get_parmeter_from_string(&str_ptr, "MAC=", - PTYPE_STR_HEX, &p_ea[i], 12) != 0) { - WL_ERROR(("ERROR: MAC_filter[%d] is missing !\n", i)); - goto exit_proc; - } - - WL_SOFTAP(("MAC_MODE=:%d, MAC_CNT=%d, MACs:..\n", mac_mode, mac_cnt)); - for (i = 0; i < mac_cnt; i++) { - WL_SOFTAP(("mac_filt[%d]:", i)); - print_buf(&p_ea[i], 6, 0); - } - - mflist_set.mode = mac_mode; - mflist_set.mac_list.count = mac_cnt; - set_ap_mac_list(dev, &mflist_set); - - wrqu->data.pointer = NULL; - wrqu->data.length = 0; - ret = 0; - - } else { - WL_ERROR(("IWPRIV argument len is 0\n")); - return -1; - } - - exit_proc: - kfree(extra); - return ret; -} -#endif - - -#ifdef SOFTAP -static int iwpriv_set_ap_sta_disassoc(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int res = 0; - char sta_mac[6] = {0, 0, 0, 0, 0, 0}; - char cmd_buf[256]; - char *str_ptr = cmd_buf; - - WL_SOFTAP((">>%s called\n args: info->cmd:%x," - " info->flags:%x, u.data.p:%p, u.data.len:%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (wrqu->data.length != 0) { - - if (copy_from_user(cmd_buf, wrqu->data.pointer, wrqu->data.length)) { - return -EFAULT; - } - - if (get_parmeter_from_string(&str_ptr, - "MAC=", PTYPE_STR_HEX, sta_mac, 12) == 0) { - res = wl_iw_softap_deassoc_stations(dev, sta_mac); - } else { - WL_ERROR(("ERROR: STA_MAC= token not found\n")); - } - } - - return res; -} -#endif - -#endif - - -#if WIRELESS_EXT < 13 -struct iw_request_info -{ - __u16 cmd; - __u16 flags; -}; - -typedef int (*iw_handler)(struct net_device *dev, - struct iw_request_info *info, - void *wrqu, - char *extra); -#endif - -static int -wl_iw_config_commit( - struct net_device *dev, - struct iw_request_info *info, - void *zwrq, - char *extra -) -{ - wlc_ssid_t ssid; - int error; - struct sockaddr bssid; - - WL_TRACE(("%s: SIOCSIWCOMMIT\n", dev->name)); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)))) - return error; - - ssid.SSID_len = dtoh32(ssid.SSID_len); - - if (!ssid.SSID_len) - return 0; - - bzero(&bssid, sizeof(struct sockaddr)); - if ((error = dev_wlc_ioctl(dev, WLC_REASSOC, &bssid, ETHER_ADDR_LEN))) { - WL_ERROR(("%s: WLC_REASSOC to %s failed \n", __FUNCTION__, ssid.SSID)); - return error; - } - - return 0; -} - -static int -wl_iw_get_name( - struct net_device *dev, - struct iw_request_info *info, - char *cwrq, - char *extra -) -{ - WL_TRACE(("%s: SIOCGIWNAME\n", dev->name)); - - strcpy(cwrq, "IEEE 802.11-DS"); - - return 0; -} - -static int -wl_iw_set_freq( - struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *fwrq, - char *extra -) -{ - int error, chan; - uint sf = 0; - - WL_TRACE(("%s %s: SIOCSIWFREQ\n", __FUNCTION__, dev->name)); - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_TRACE(("%s:>> not executed, 'SOFT_AP is active' \n", __FUNCTION__)); - return 0; - } -#endif - - - if (fwrq->e == 0 && fwrq->m < MAXCHANNEL) { - chan = fwrq->m; - } - - - else { - - if (fwrq->e >= 6) { - fwrq->e -= 6; - while (fwrq->e--) - fwrq->m *= 10; - } else if (fwrq->e < 6) { - while (fwrq->e++ < 6) - fwrq->m /= 10; - } - - if (fwrq->m > 4000 && fwrq->m < 5000) - sf = WF_CHAN_FACTOR_4_G; - - chan = wf_mhz2channel(fwrq->m, sf); - } - chan = htod32(chan); - if ((error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan)))) - return error; - - g_wl_iw_params.target_channel = chan; - - return -EINPROGRESS; -} - -static int -wl_iw_get_freq( - struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *fwrq, - char *extra -) -{ - channel_info_t ci; - int error; - - WL_TRACE(("%s: SIOCGIWFREQ\n", dev->name)); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)))) - return error; - - fwrq->m = dtoh32(ci.hw_channel); - fwrq->e = dtoh32(0); - return 0; -} - -static int -wl_iw_set_mode( - struct net_device *dev, - struct iw_request_info *info, - __u32 *uwrq, - char *extra -) -{ - int infra = 0, ap = 0, error = 0; - - WL_TRACE(("%s: SIOCSIWMODE\n", dev->name)); - - switch (*uwrq) { - case IW_MODE_MASTER: - infra = ap = 1; - break; - case IW_MODE_ADHOC: - case IW_MODE_AUTO: - break; - case IW_MODE_INFRA: - infra = 1; - break; - default: - return -EINVAL; - } - infra = htod32(infra); - ap = htod32(ap); - - if ((error = dev_wlc_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(infra))) || - (error = dev_wlc_ioctl(dev, WLC_SET_AP, &ap, sizeof(ap)))) - return error; - - - return -EINPROGRESS; -} - -static int -wl_iw_get_mode( - struct net_device *dev, - struct iw_request_info *info, - __u32 *uwrq, - char *extra -) -{ - int error, infra = 0, ap = 0; - - WL_TRACE(("%s: SIOCGIWMODE\n", dev->name)); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra))) || - (error = dev_wlc_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap)))) - return error; - - infra = dtoh32(infra); - ap = dtoh32(ap); - *uwrq = infra ? ap ? IW_MODE_MASTER : IW_MODE_INFRA : IW_MODE_ADHOC; - - return 0; -} - -static int -wl_iw_get_range( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - struct iw_range *range = (struct iw_range *) extra; - wl_uint32_list_t *list; - wl_rateset_t rateset; - int8 *channels; - int error, i, k; - uint sf, ch; - - int phytype; - int bw_cap = 0, sgi_tx = 0, nmode = 0; - channel_info_t ci; - uint8 nrate_list2copy = 0; - uint16 nrate_list[4][8] = { {13, 26, 39, 52, 78, 104, 117, 130}, - {14, 29, 43, 58, 87, 116, 130, 144}, - {27, 54, 81, 108, 162, 216, 243, 270}, - {30, 60, 90, 120, 180, 240, 270, 300}}; - - WL_TRACE(("%s: SIOCGIWRANGE\n", dev->name)); - - if (!extra) - return -EINVAL; - - channels = kmalloc((MAXCHANNEL+1)*4, GFP_KERNEL); - if (!channels) { - WL_ERROR(("Could not alloc channels\n")); - return -ENOMEM; - } - list = (wl_uint32_list_t *)channels; - - dwrq->length = sizeof(struct iw_range); - memset(range, 0, sizeof(range)); - - range->min_nwid = range->max_nwid = 0; - - list->count = htod32(MAXCHANNEL); - if ((error = dev_wlc_ioctl(dev, WLC_GET_VALID_CHANNELS, channels, (MAXCHANNEL+1)*4))) { - kfree(channels); - return error; - } - for (i = 0; i < dtoh32(list->count) && i < IW_MAX_FREQUENCIES; i++) { - range->freq[i].i = dtoh32(list->element[i]); - - ch = dtoh32(list->element[i]); - if (ch <= CH_MAX_2G_CHANNEL) - sf = WF_CHAN_FACTOR_2_4_G; - else - sf = WF_CHAN_FACTOR_5_G; - - range->freq[i].m = wf_channel2mhz(ch, sf); - range->freq[i].e = 6; - } - range->num_frequency = range->num_channels = i; - - range->max_qual.qual = 5; - - range->max_qual.level = 0x100 - 200; - - range->max_qual.noise = 0x100 - 200; - - range->sensitivity = 65535; - -#if WIRELESS_EXT > 11 - - range->avg_qual.qual = 3; - - range->avg_qual.level = 0x100 + WL_IW_RSSI_GOOD; - - range->avg_qual.noise = 0x100 - 75; -#endif - - if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset)))) { - kfree(channels); - return error; - } - rateset.count = dtoh32(rateset.count); - range->num_bitrates = rateset.count; - for (i = 0; i < rateset.count && i < IW_MAX_BITRATES; i++) - range->bitrate[i] = (rateset.rates[i]& 0x7f) * 500000; - dev_wlc_intvar_get(dev, "nmode", &nmode); - dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &phytype, sizeof(phytype)); - - if (nmode == 1 && phytype == WLC_PHY_TYPE_SSN) { - dev_wlc_intvar_get(dev, "mimo_bw_cap", &bw_cap); - dev_wlc_intvar_get(dev, "sgi_tx", &sgi_tx); - dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t)); - ci.hw_channel = dtoh32(ci.hw_channel); - - if (bw_cap == 0 || - (bw_cap == 2 && ci.hw_channel <= 14)) { - if (sgi_tx == 0) - nrate_list2copy = 0; - else - nrate_list2copy = 1; - } - if (bw_cap == 1 || - (bw_cap == 2 && ci.hw_channel >= 36)) { - if (sgi_tx == 0) - nrate_list2copy = 2; - else - nrate_list2copy = 3; - } - range->num_bitrates += 8; - for (k = 0; i < range->num_bitrates; k++, i++) { - - range->bitrate[i] = (nrate_list[nrate_list2copy][k]) * 500000; - } - } - - if ((error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &i, sizeof(i)))) { - kfree(channels); - return error; - } - i = dtoh32(i); - if (i == WLC_PHY_TYPE_A) - range->throughput = 24000000; - else - range->throughput = 1500000; - - range->min_rts = 0; - range->max_rts = 2347; - range->min_frag = 256; - range->max_frag = 2346; - - range->max_encoding_tokens = DOT11_MAX_DEFAULT_KEYS; - range->num_encoding_sizes = 4; - range->encoding_size[0] = WEP1_KEY_SIZE; - range->encoding_size[1] = WEP128_KEY_SIZE; -#if WIRELESS_EXT > 17 - range->encoding_size[2] = TKIP_KEY_SIZE; -#else - range->encoding_size[2] = 0; -#endif - range->encoding_size[3] = AES_KEY_SIZE; - - range->min_pmp = 0; - range->max_pmp = 0; - range->min_pmt = 0; - range->max_pmt = 0; - range->pmp_flags = 0; - range->pm_capa = 0; - - range->num_txpower = 2; - range->txpower[0] = 1; - range->txpower[1] = 255; - range->txpower_capa = IW_TXPOW_MWATT; - -#if WIRELESS_EXT > 10 - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 19; - - range->retry_capa = IW_RETRY_LIMIT; - range->retry_flags = IW_RETRY_LIMIT; - range->r_time_flags = 0; - - range->min_retry = 1; - range->max_retry = 255; - - range->min_r_time = 0; - range->max_r_time = 0; -#endif - -#if WIRELESS_EXT > 17 - range->enc_capa = IW_ENC_CAPA_WPA; - range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP; - range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP; -#ifdef BCMWPA2 - range->enc_capa |= IW_ENC_CAPA_WPA2; -#endif - - IW_EVENT_CAPA_SET_KERNEL(range->event_capa); - - IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP); - IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN); - IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP); - IW_EVENT_CAPA_SET(range->event_capa, IWEVMICHAELMICFAILURE); -#ifdef BCMWPA2 - IW_EVENT_CAPA_SET(range->event_capa, IWEVPMKIDCAND); -#endif -#endif - - kfree(channels); - - return 0; -} - -static int -rssi_to_qual(int rssi) -{ - if (rssi <= WL_IW_RSSI_NO_SIGNAL) - return 0; - else if (rssi <= WL_IW_RSSI_VERY_LOW) - return 1; - else if (rssi <= WL_IW_RSSI_LOW) - return 2; - else if (rssi <= WL_IW_RSSI_GOOD) - return 3; - else if (rssi <= WL_IW_RSSI_VERY_GOOD) - return 4; - else - return 5; -} - -static int -wl_iw_set_spy( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_iw_t *iw = *(wl_iw_t **)netdev_priv(dev); - struct sockaddr *addr = (struct sockaddr *) extra; - int i; - - WL_TRACE(("%s: SIOCSIWSPY\n", dev->name)); - - if (!extra) - return -EINVAL; - - iw->spy_num = MIN(ARRAYSIZE(iw->spy_addr), dwrq->length); - for (i = 0; i < iw->spy_num; i++) - memcpy(&iw->spy_addr[i], addr[i].sa_data, ETHER_ADDR_LEN); - memset(iw->spy_qual, 0, sizeof(iw->spy_qual)); - - return 0; -} - -static int -wl_iw_get_spy( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_iw_t *iw = *(wl_iw_t **)netdev_priv(dev); - struct sockaddr *addr = (struct sockaddr *) extra; - struct iw_quality *qual = (struct iw_quality *) &addr[iw->spy_num]; - int i; - - WL_TRACE(("%s: SIOCGIWSPY\n", dev->name)); - - if (!extra) - return -EINVAL; - - dwrq->length = iw->spy_num; - for (i = 0; i < iw->spy_num; i++) { - memcpy(addr[i].sa_data, &iw->spy_addr[i], ETHER_ADDR_LEN); - addr[i].sa_family = AF_UNIX; - memcpy(&qual[i], &iw->spy_qual[i], sizeof(struct iw_quality)); - iw->spy_qual[i].updated = 0; - } - - return 0; -} - - -static int -wl_iw_ch_to_chanspec(int ch, wl_join_params_t *join_params, int *join_params_size) -{ - chanspec_t chanspec = 0; - - if (ch != 0) { - - join_params->params.chanspec_num = 1; - join_params->params.chanspec_list[0] = ch; - - if (join_params->params.chanspec_list[0]) - chanspec |= WL_CHANSPEC_BAND_2G; - else - chanspec |= WL_CHANSPEC_BAND_5G; - - chanspec |= WL_CHANSPEC_BW_20; - chanspec |= WL_CHANSPEC_CTL_SB_NONE; - - *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE + - join_params->params.chanspec_num * sizeof(chanspec_t); - - join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK; - join_params->params.chanspec_list[0] |= chanspec; - join_params->params.chanspec_list[0] = - htodchanspec(join_params->params.chanspec_list[0]); - - join_params->params.chanspec_num = htod32(join_params->params.chanspec_num); - - WL_TRACE(("%s join_params->params.chanspec_list[0]= %X\n", \ - __FUNCTION__, join_params->params.chanspec_list[0])); - } - return 1; -} - -static int -wl_iw_set_wap( - struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *awrq, - char *extra -) -{ - int error = -EINVAL; - wl_join_params_t join_params; - int join_params_size; - - WL_TRACE(("%s: SIOCSIWAP\n", dev->name)); - - if (awrq->sa_family != ARPHRD_ETHER) { - WL_ERROR(("Invalid Header...sa_family\n")); - return -EINVAL; - } - - - if (ETHER_ISBCAST(awrq->sa_data) || ETHER_ISNULLADDR(awrq->sa_data)) { - scb_val_t scbval; - - bzero(&scbval, sizeof(scb_val_t)); - - (void) dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)); - return 0; - } - - - - memset(&join_params, 0, sizeof(join_params)); - join_params_size = sizeof(join_params.ssid); - - memcpy(join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); - join_params.ssid.SSID_len = htod32(g_ssid.SSID_len); - memcpy(&join_params.params.bssid, awrq->sa_data, ETHER_ADDR_LEN); - - WL_ASSOC(("%s target_channel=%d\n", __FUNCTION__, g_wl_iw_params.target_channel)); - wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params, &join_params_size); - - if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size))) { - WL_ERROR(("%s Invalid ioctl data=%d\n", __FUNCTION__, error)); - return error; - } - - if (g_ssid.SSID_len) { - WL_ASSOC(("%s: join SSID=%s BSSID="MACSTR" ch=%d\n", __FUNCTION__, \ - g_ssid.SSID, MAC2STR((u8 *)awrq->sa_data), \ - g_wl_iw_params.target_channel)); - } - - - memset(&g_ssid, 0, sizeof(g_ssid)); - return 0; -} - -static int -wl_iw_get_wap( - struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *awrq, - char *extra -) -{ - WL_TRACE(("%s: SIOCGIWAP\n", dev->name)); - - awrq->sa_family = ARPHRD_ETHER; - memset(awrq->sa_data, 0, ETHER_ADDR_LEN); - - - (void) dev_wlc_ioctl(dev, WLC_GET_BSSID, awrq->sa_data, ETHER_ADDR_LEN); - - return 0; -} - -#if WIRELESS_EXT > 17 -static int -wl_iw_mlme( - struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *awrq, - char *extra -) -{ - struct iw_mlme *mlme; - scb_val_t scbval; - int error = -EINVAL; - - WL_TRACE(("%s: SIOCSIWMLME DISASSOC/DEAUTH\n", dev->name)); - - mlme = (struct iw_mlme *)extra; - if (mlme == NULL) { - WL_ERROR(("Invalid ioctl data.\n")); - return error; - } - - scbval.val = mlme->reason_code; - bcopy(&mlme->addr.sa_data, &scbval.ea, ETHER_ADDR_LEN); - - if (mlme->cmd == IW_MLME_DISASSOC) { - scbval.val = htod32(scbval.val); - error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)); - } - else if (mlme->cmd == IW_MLME_DEAUTH) { - scbval.val = htod32(scbval.val); - error = dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval, - sizeof(scb_val_t)); - } - else { - WL_ERROR(("Invalid ioctl data.\n")); - return error; - } - - return error; -} -#endif - -#ifndef WL_IW_USE_ISCAN -static int -wl_iw_get_aplist( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_scan_results_t *list; - struct sockaddr *addr = (struct sockaddr *) extra; - struct iw_quality qual[IW_MAX_AP]; - wl_bss_info_t *bi = NULL; - int error, i; - uint buflen = dwrq->length; - - WL_TRACE(("%s: SIOCGIWAPLIST\n", dev->name)); - - if (!extra) - return -EINVAL; - - list = kmalloc(buflen, GFP_KERNEL); - if (!list) - return -ENOMEM; - memset(list, 0, buflen); - list->buflen = htod32(buflen); - if ((error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen))) { - WL_ERROR(("%d: Scan results error %d\n", __LINE__, error)); - kfree(list); - return error; - } - list->buflen = dtoh32(list->buflen); - list->version = dtoh32(list->version); - list->count = dtoh32(list->count); - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s: list->version %d != WL_BSS_INFO_VERSION\n", \ - __FUNCTION__, list->version)); - kfree(list); - return -EINVAL; - } - - for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) { - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; - - if ((dtoh32(bi->length) > buflen) || - (((uintptr)bi + dtoh32(bi->length)) > ((uintptr)list + buflen))) { - WL_ERROR(("%s: Scan results out of bounds: %u\n",__FUNCTION__,dtoh32(bi->length))); - kfree(list); - return -E2BIG; - } - - if (!(dtoh16(bi->capability) & DOT11_CAP_ESS)) - continue; - - memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN); - addr[dwrq->length].sa_family = ARPHRD_ETHER; - qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI)); - qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI); - qual[dwrq->length].noise = 0x100 + bi->phy_noise; - -#if WIRELESS_EXT > 18 - qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; -#else - qual[dwrq->length].updated = 7; -#endif - - dwrq->length++; - } - - kfree(list); - - if (dwrq->length) { - memcpy(&addr[dwrq->length], qual, sizeof(struct iw_quality) * dwrq->length); - - dwrq->flags = 1; - } - return 0; -} -#endif - -#ifdef WL_IW_USE_ISCAN -static int -wl_iw_iscan_get_aplist( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_scan_results_t *list; - iscan_buf_t * buf; - iscan_info_t *iscan = g_iscan; - - struct sockaddr *addr = (struct sockaddr *) extra; - struct iw_quality qual[IW_MAX_AP]; - wl_bss_info_t *bi = NULL; - int i; - - WL_TRACE(("%s: SIOCGIWAPLIST\n", dev->name)); - - if (!extra) - return -EINVAL; - - if ((!iscan) || (iscan->sysioc_pid < 0)) { - WL_ERROR(("%s error\n", __FUNCTION__)); - return 0; - } - - buf = iscan->list_hdr; - - while (buf) { - list = &((wl_iscan_results_t*)buf->iscan_buf)->results; - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", \ - __FUNCTION__, list->version)); - return -EINVAL; - } - - bi = NULL; - for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) { - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) - : list->bss_info; - - if ((dtoh32(bi->length) > WLC_IW_ISCAN_MAXLEN) || - (((uintptr)bi + dtoh32(bi->length)) > ((uintptr)list + WLC_IW_ISCAN_MAXLEN))) { - WL_ERROR(("%s: Scan results out of bounds: %u\n",__FUNCTION__,dtoh32(bi->length))); - return -E2BIG; - } - - if (!(dtoh16(bi->capability) & DOT11_CAP_ESS)) - continue; - - memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN); - addr[dwrq->length].sa_family = ARPHRD_ETHER; - qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI)); - qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI); - qual[dwrq->length].noise = 0x100 + bi->phy_noise; - -#if WIRELESS_EXT > 18 - qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; -#else - qual[dwrq->length].updated = 7; -#endif - - dwrq->length++; - } - buf = buf->next; - } - if (dwrq->length) { - memcpy(&addr[dwrq->length], qual, sizeof(struct iw_quality) * dwrq->length); - - dwrq->flags = 1; - } - return 0; -} - -static int -wl_iw_iscan_prep(wl_scan_params_t *params, wlc_ssid_t *ssid) -{ - int err = 0; - - memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN); - params->bss_type = DOT11_BSSTYPE_ANY; - params->scan_type = 0; - params->nprobes = -1; - params->active_time = -1; - params->passive_time = -1; - params->home_time = -1; - params->channel_num = 0; -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_STARTED) - params->passive_time = 30; -#endif - params->nprobes = htod32(params->nprobes); - params->active_time = htod32(params->active_time); - params->passive_time = htod32(params->passive_time); - params->home_time = htod32(params->home_time); - if (ssid && ssid->SSID_len) - memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t)); - - return err; -} - -static int -wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action) -{ - int err = 0; - - iscan->iscan_ex_params_p->version = htod32(ISCAN_REQ_VERSION); - iscan->iscan_ex_params_p->action = htod16(action); - iscan->iscan_ex_params_p->scan_duration = htod16(0); - - WL_SCAN(("%s : nprobes=%d\n", __FUNCTION__, iscan->iscan_ex_params_p->params.nprobes)); - WL_SCAN(("active_time=%d\n", iscan->iscan_ex_params_p->params.active_time)); - WL_SCAN(("passive_time=%d\n", iscan->iscan_ex_params_p->params.passive_time)); - WL_SCAN(("home_time=%d\n", iscan->iscan_ex_params_p->params.home_time)); - WL_SCAN(("scan_type=%d\n", iscan->iscan_ex_params_p->params.scan_type)); - WL_SCAN(("bss_type=%d\n", iscan->iscan_ex_params_p->params.bss_type)); - - if ((err = dev_iw_iovar_setbuf(iscan->dev, "iscan", iscan->iscan_ex_params_p, \ - iscan->iscan_ex_param_size, iscan->ioctlbuf, sizeof(iscan->ioctlbuf)))) { - WL_ERROR(("Set ISCAN for %s failed with %d\n", __FUNCTION__, err)); - err = -1; - } - - return err; -} - -static void -wl_iw_timerfunc(ulong data) -{ - iscan_info_t *iscan = (iscan_info_t *)data; - if (iscan) { - iscan->timer_on = 0; - if (iscan->iscan_state != ISCAN_STATE_IDLE) { - WL_SCAN(("timer trigger\n")); - up(&iscan->sysioc_sem); - } - } -} -static void wl_iw_set_event_mask(struct net_device *dev) -{ - char eventmask[WL_EVENTING_MASK_LEN]; - char iovbuf[WL_EVENTING_MASK_LEN + 12]; - - dev_iw_iovar_getbuf(dev, "event_msgs", "", 0, iovbuf, sizeof(iovbuf)); - bcopy(iovbuf, eventmask, WL_EVENTING_MASK_LEN); - setbit(eventmask, WLC_E_SCAN_COMPLETE); - dev_iw_iovar_setbuf(dev, "event_msgs", eventmask, WL_EVENTING_MASK_LEN, - iovbuf, sizeof(iovbuf)); -} - -static uint32 -wl_iw_iscan_get(iscan_info_t *iscan) -{ - iscan_buf_t * buf; - iscan_buf_t * ptr; - wl_iscan_results_t * list_buf; - wl_iscan_results_t list; - wl_scan_results_t *results; - uint32 status; - int res; - - mutex_lock(&wl_cache_lock); - if (iscan->list_cur) { - buf = iscan->list_cur; - iscan->list_cur = buf->next; - } - else { - buf = kmalloc(sizeof(iscan_buf_t), GFP_KERNEL); - if (!buf) { - WL_ERROR(("%s can't alloc iscan_buf_t : going to abort currect iscan\n", \ - __FUNCTION__)); - mutex_unlock(&wl_cache_lock); - return WL_SCAN_RESULTS_NO_MEM; - } - buf->next = NULL; - if (!iscan->list_hdr) - iscan->list_hdr = buf; - else { - ptr = iscan->list_hdr; - while (ptr->next) { - ptr = ptr->next; - } - ptr->next = buf; - } - } - memset(buf->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN); - list_buf = (wl_iscan_results_t*)buf->iscan_buf; - results = &list_buf->results; - results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE; - results->version = 0; - results->count = 0; - - memset(&list, 0, sizeof(list)); - list.results.buflen = htod32(WLC_IW_ISCAN_MAXLEN); - res = dev_iw_iovar_getbuf( - iscan->dev, - "iscanresults", - &list, - WL_ISCAN_RESULTS_FIXED_SIZE, - buf->iscan_buf, - WLC_IW_ISCAN_MAXLEN); - if (res == 0) { - results->buflen = dtoh32(results->buflen); - results->version = dtoh32(results->version); - results->count = dtoh32(results->count); - WL_SCAN(("results->count = %d\n", results->count)); - - WL_SCAN(("results->buflen = %d\n", results->buflen)); - status = dtoh32(list_buf->status); - } else { - WL_ERROR(("%s returns error %d\n", __FUNCTION__, res)); - status = WL_SCAN_RESULTS_NO_MEM; - } - mutex_unlock(&wl_cache_lock); - return status; -} - -static void wl_iw_force_specific_scan(iscan_info_t *iscan) -{ - WL_SCAN(("%s force Specific SCAN for %s\n", __FUNCTION__, g_specific_ssid.SSID)); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_lock(); -#endif - (void) dev_wlc_ioctl(iscan->dev, WLC_SCAN, &g_specific_ssid, sizeof(g_specific_ssid)); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_unlock(); -#endif -} - -static void wl_iw_send_scan_complete(iscan_info_t *iscan) -{ -#ifndef SANDGATE2G - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - - wireless_send_event(iscan->dev, SIOCGIWSCAN, &wrqu, NULL); -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_STARTED) - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_READY; -#endif - WL_SCAN(("Send Event ISCAN complete\n")); -#endif -} - -static int -_iscan_sysioc_thread(void *data) -{ - uint32 status; - iscan_info_t *iscan = (iscan_info_t *)data; - static bool iscan_pass_abort = FALSE; - - DAEMONIZE("iscan_sysioc"); - - status = WL_SCAN_RESULTS_PARTIAL; - while (down_interruptible(&iscan->sysioc_sem) == 0) { - - net_os_wake_lock(iscan->dev); - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_SCAN(("%s skipping SCAN ops in AP mode !!!\n", __FUNCTION__)); - net_os_wake_unlock(iscan->dev); - continue; - } -#endif - - if (iscan->timer_on) { - iscan->timer_on = 0; - del_timer_sync(&iscan->timer); - } - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_lock(); -#endif - status = wl_iw_iscan_get(iscan); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_unlock(); -#endif - - if (g_scan_specified_ssid && (iscan_pass_abort == TRUE)) { - WL_SCAN(("%s Get results from specific scan status=%d\n", __FUNCTION__, status)); - wl_iw_send_scan_complete(iscan); - iscan_pass_abort = FALSE; - status = -1; - } - - switch (status) { - case WL_SCAN_RESULTS_PARTIAL: - WL_SCAN(("iscanresults incomplete\n")); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_lock(); -#endif - - wl_iw_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_unlock(); -#endif - - mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000); - iscan->timer_on = 1; - break; - case WL_SCAN_RESULTS_SUCCESS: - WL_SCAN(("iscanresults complete\n")); - iscan->iscan_state = ISCAN_STATE_IDLE; - wl_iw_send_scan_complete(iscan); - break; - case WL_SCAN_RESULTS_PENDING: - WL_SCAN(("iscanresults pending\n")); - - mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000); - iscan->timer_on = 1; - break; - case WL_SCAN_RESULTS_ABORTED: - WL_SCAN(("iscanresults aborted\n")); - iscan->iscan_state = ISCAN_STATE_IDLE; - if (g_scan_specified_ssid == 0) - wl_iw_send_scan_complete(iscan); - else { - iscan_pass_abort = TRUE; - wl_iw_force_specific_scan(iscan); - } - break; - case WL_SCAN_RESULTS_NO_MEM: - WL_SCAN(("iscanresults can't alloc memory: skip\n")); - iscan->iscan_state = ISCAN_STATE_IDLE; - break; - default: - WL_SCAN(("iscanresults returned unknown status %d\n", status)); - break; - } - - net_os_wake_unlock(iscan->dev); - } - - if (iscan->timer_on) { - iscan->timer_on = 0; - del_timer_sync(&iscan->timer); - } - - complete_and_exit(&iscan->sysioc_exited, 0); -} -#endif - -#if !defined(CSCAN) - -static void -wl_iw_set_ss_cache_timer_flag(void) -{ - g_ss_cache_ctrl.m_timer_expired = 1; - WL_TRACE(("%s called\n", __FUNCTION__)); -} - -static int -wl_iw_init_ss_cache_ctrl(void) -{ - WL_TRACE(("%s :\n", __FUNCTION__)); - g_ss_cache_ctrl.m_prev_scan_mode = 0; - g_ss_cache_ctrl.m_cons_br_scan_cnt = 0; - g_ss_cache_ctrl.m_cache_head = NULL; - g_ss_cache_ctrl.m_link_down = 0; - g_ss_cache_ctrl.m_timer_expired = 0; - memset(g_ss_cache_ctrl.m_active_bssid, 0, ETHER_ADDR_LEN); - - g_ss_cache_ctrl.m_timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL); - if (!g_ss_cache_ctrl.m_timer) { - return -ENOMEM; - } - g_ss_cache_ctrl.m_timer->function = (void *)wl_iw_set_ss_cache_timer_flag; - init_timer(g_ss_cache_ctrl.m_timer); - - return 0; -} - - - -static void -wl_iw_free_ss_cache(void) -{ - wl_iw_ss_cache_t *node, *cur; - wl_iw_ss_cache_t **spec_scan_head; - - WL_TRACE(("%s called\n", __FUNCTION__)); - - mutex_lock(&wl_cache_lock); - spec_scan_head = &g_ss_cache_ctrl.m_cache_head; - node = *spec_scan_head; - - for (;node;) { - WL_TRACE(("%s : SSID - %s\n", __FUNCTION__, node->bss_info->SSID)); - cur = node; - node = cur->next; - kfree(cur); - } - *spec_scan_head = NULL; - mutex_unlock(&wl_cache_lock); -} - - - -static int -wl_iw_run_ss_cache_timer(int kick_off) -{ - struct timer_list **timer; - - timer = &g_ss_cache_ctrl.m_timer; - - if (*timer) { - if (kick_off) { - (*timer)->expires = jiffies + 30000 * HZ / 1000; - add_timer(*timer); - WL_TRACE(("%s : timer starts \n", __FUNCTION__)); - } else { - del_timer_sync(*timer); - WL_TRACE(("%s : timer stops \n", __FUNCTION__)); - } - } - - return 0; -} - - -void -wl_iw_release_ss_cache_ctrl(void) -{ - WL_TRACE(("%s :\n", __FUNCTION__)); - wl_iw_free_ss_cache(); - wl_iw_run_ss_cache_timer(0); - if (g_ss_cache_ctrl.m_timer) { - kfree(g_ss_cache_ctrl.m_timer); - } -} - - - -static void -wl_iw_reset_ss_cache(void) -{ - wl_iw_ss_cache_t *node, *prev, *cur; - wl_iw_ss_cache_t **spec_scan_head; - - mutex_lock(&wl_cache_lock); - spec_scan_head = &g_ss_cache_ctrl.m_cache_head; - node = *spec_scan_head; - prev = node; - - for (;node;) { - WL_TRACE(("%s : node SSID %s \n", __FUNCTION__, node->bss_info->SSID)); - if (!node->dirty) { - cur = node; - if (cur == *spec_scan_head) { - *spec_scan_head = cur->next; - prev = *spec_scan_head; - } - else { - prev->next = cur->next; - } - node = cur->next; - - WL_TRACE(("%s : Del node : SSID %s\n", __FUNCTION__, cur->bss_info->SSID)); - kfree(cur); - continue; - } - - node->dirty = 0; - prev = node; - node = node->next; - } - mutex_unlock(&wl_cache_lock); -} - - -static int -wl_iw_add_bss_to_ss_cache(wl_scan_results_t *ss_list) -{ - - wl_iw_ss_cache_t *node, *prev, *leaf; - wl_iw_ss_cache_t **spec_scan_head; - wl_bss_info_t *bi = NULL; - int i; - - if (!ss_list->count) { - return 0; - } - - mutex_lock(&wl_cache_lock); - spec_scan_head = &g_ss_cache_ctrl.m_cache_head; - - for (i = 0; i < ss_list->count; i++) { - - node = *spec_scan_head; - prev = node; - - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info; - - WL_TRACE(("%s : find %d with specific SSID %s\n", __FUNCTION__, i, bi->SSID)); - for (;node;) { - if (!memcmp(&node->bss_info->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) { - - WL_TRACE(("dirty marked : SSID %s\n", bi->SSID)); - node->dirty = 1; - break; - } - prev = node; - node = node->next; - } - - if (node) { - continue; - } - leaf = kmalloc(bi->length + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN, GFP_KERNEL); - if (!leaf) { - WL_ERROR(("Memory alloc failure %d\n", \ - bi->length + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN)); - mutex_unlock(&wl_cache_lock); - return -ENOMEM; - } - - memcpy(leaf->bss_info, bi, bi->length); - leaf->next = NULL; - leaf->dirty = 1; - leaf->count = 1; - leaf->version = ss_list->version; - - if (!prev) { - *spec_scan_head = leaf; - } - else { - prev->next = leaf; - } - } - mutex_unlock(&wl_cache_lock); - return 0; -} - - -static int -wl_iw_merge_scan_cache(struct iw_request_info *info, char *extra, uint buflen_from_user, -__u16 *merged_len) -{ - wl_iw_ss_cache_t *node; - wl_scan_results_t *list_merge; - - mutex_lock(&wl_cache_lock); - node = g_ss_cache_ctrl.m_cache_head; - for (;node;) { - list_merge = (wl_scan_results_t *)&node->buflen; - WL_TRACE(("%s: Cached Specific APs list=%d\n", __FUNCTION__, list_merge->count)); - if (buflen_from_user - *merged_len > 0) { - *merged_len += (__u16) wl_iw_get_scan_prep(list_merge, info, - extra + *merged_len, buflen_from_user - *merged_len); - } - else { - WL_TRACE(("%s: exit with break\n", __FUNCTION__)); - break; - } - node = node->next; - } - mutex_unlock(&wl_cache_lock); - return 0; -} - - -static int -wl_iw_delete_bss_from_ss_cache(void *addr) -{ - - wl_iw_ss_cache_t *node, *prev; - wl_iw_ss_cache_t **spec_scan_head; - - mutex_lock(&wl_cache_lock); - spec_scan_head = &g_ss_cache_ctrl.m_cache_head; - node = *spec_scan_head; - prev = node; - for (;node;) { - if (!memcmp(&node->bss_info->BSSID, addr, ETHER_ADDR_LEN)) { - if (node == *spec_scan_head) { - *spec_scan_head = node->next; - } - else { - prev->next = node->next; - } - - WL_TRACE(("%s : Del node : %s\n", __FUNCTION__, node->bss_info->SSID)); - kfree(node); - break; - } - - prev = node; - node = node->next; - } - - memset(addr, 0, ETHER_ADDR_LEN); - mutex_unlock(&wl_cache_lock); - return 0; -} - -#endif - - -static int -wl_iw_set_scan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error; - WL_TRACE(("%s dev:%s: SIOCSIWSCAN : SCAN\n", __FUNCTION__, dev->name)); - -#if defined(CSCAN) - WL_ERROR(("%s: Scan from SIOCGIWSCAN not supported\n", __FUNCTION__)); - return -EINVAL; -#endif - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_TRACE(("\n>%s: Not executed, reason -'SOFTAP is active'\n", __FUNCTION__)); - return 0; - } -#endif - - if (g_onoff == G_WLAN_SET_OFF) - return 0; - - memset(&g_specific_ssid, 0, sizeof(g_specific_ssid)); -#ifndef WL_IW_USE_ISCAN - g_scan_specified_ssid = 0; -#endif - -#if WIRELESS_EXT > 17 - - if (wrqu->data.length == sizeof(struct iw_scan_req)) { - if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - struct iw_scan_req *req = (struct iw_scan_req *)extra; -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan != BROADCAST_SCAN_FIRST_RESULT_CONSUMED) { - WL_ERROR(("%s Ignoring SC %s first BC is not done = %d\n", \ - __FUNCTION__, req->essid, \ - g_first_broadcast_scan)); - return -EBUSY; - } -#endif - if (g_scan_specified_ssid) { - WL_SCAN(("%s Specific SCAN is not done ignore scan for = %s \n", \ - __FUNCTION__, req->essid)); - return -EBUSY; - } - else { - g_specific_ssid.SSID_len = MIN(sizeof(g_specific_ssid.SSID), \ - req->essid_len); - memcpy(g_specific_ssid.SSID, req->essid, g_specific_ssid.SSID_len); - g_specific_ssid.SSID_len = htod32(g_specific_ssid.SSID_len); - g_scan_specified_ssid = 1; - WL_TRACE(("### Specific scan ssid=%s len=%d\n", \ - g_specific_ssid.SSID, g_specific_ssid.SSID_len)); - } - } - } -#endif - - if ((error = dev_wlc_ioctl(dev, WLC_SCAN, &g_specific_ssid, sizeof(g_specific_ssid)))) { - WL_SCAN(("Set SCAN for %s failed with %d\n", g_specific_ssid.SSID, error)); - g_scan_specified_ssid = 0; - return -EBUSY; - } - - return 0; -} - -#ifdef WL_IW_USE_ISCAN -int -wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag) -{ - wlc_ssid_t ssid; - iscan_info_t *iscan = g_iscan; - -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_IDLE) { - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_STARTED; - WL_SCAN(("%s: First Brodcast scan was forced\n", __FUNCTION__)); - } - else if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_STARTED) { - WL_SCAN(("%s: ignore ISCAN request first BS is not done yet\n", __FUNCTION__)); - return 0; - } -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - if (flag) - rtnl_lock(); -#endif - - dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &iscan->scan_flag, sizeof(iscan->scan_flag)); - wl_iw_set_event_mask(dev); - - WL_SCAN(("+++: Set Broadcast ISCAN\n")); - - memset(&ssid, 0, sizeof(ssid)); - - iscan->list_cur = iscan->list_hdr; - iscan->iscan_state = ISCAN_STATE_SCANING; - - memset(&iscan->iscan_ex_params_p->params, 0, iscan->iscan_ex_param_size); - wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, &ssid); - wl_iw_iscan(iscan, &ssid, WL_SCAN_ACTION_START); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - if (flag) - rtnl_unlock(); -#endif - - mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000); - - iscan->timer_on = 1; - - return 0; -} - -static int -wl_iw_iscan_set_scan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - wlc_ssid_t ssid; - iscan_info_t *iscan = g_iscan; - int ret = 0; - - WL_SCAN(("%s: SIOCSIWSCAN : ISCAN\n", dev->name)); - -#if defined(CSCAN) - WL_ERROR(("%s: Scan from SIOCGIWSCAN not supported\n", __FUNCTION__)); - return -EINVAL; -#endif - - net_os_wake_lock(dev); - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_SCAN(("\n>%s: Not executed, reason -'SOFTAP is active'\n", __FUNCTION__)); - goto set_scan_end; - } -#endif - - if (g_onoff == G_WLAN_SET_OFF) { - WL_SCAN(("%s: driver is not up yet after START\n", __FUNCTION__)); - goto set_scan_end; - } - -#ifdef PNO_SUPPORT - if (dhd_dev_get_pno_status(dev)) { - WL_SCAN(("%s: Scan called when PNO is active\n", __FUNCTION__)); - } -#endif - - if ((!iscan) || (iscan->sysioc_pid < 0)) { - WL_ERROR(("%s error\n", __FUNCTION__)); - goto set_scan_end; - } - - if (g_scan_specified_ssid) { - WL_SCAN(("%s Specific SCAN already running ignoring BC scan\n", \ - __FUNCTION__)); - ret = EBUSY; - goto set_scan_end; - } - - memset(&ssid, 0, sizeof(ssid)); - -#if WIRELESS_EXT > 17 - - if (wrqu->data.length == sizeof(struct iw_scan_req)) { - if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - int as = 0; - struct iw_scan_req *req = (struct iw_scan_req *)extra; - ssid.SSID_len = MIN(sizeof(ssid.SSID), req->essid_len); - memcpy(ssid.SSID, req->essid, ssid.SSID_len); - ssid.SSID_len = htod32(ssid.SSID_len); - dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &as, sizeof(as)); - wl_iw_set_event_mask(dev); - ret = wl_iw_set_scan(dev, info, wrqu, extra); - goto set_scan_end; - } - else { - g_scan_specified_ssid = 0; - - if (iscan->iscan_state == ISCAN_STATE_SCANING) { - WL_SCAN(("%s ISCAN already in progress \n", __FUNCTION__)); - goto set_scan_end; - } - } - } -#endif - -#if defined(CONFIG_FIRST_SCAN) && !defined(CSCAN) - if (g_first_broadcast_scan < BROADCAST_SCAN_FIRST_RESULT_CONSUMED) { - if (++g_first_counter_scans == MAX_ALLOWED_BLOCK_SCAN_FROM_FIRST_SCAN) { - - WL_ERROR(("%s Clean up First scan flag which is %d\n", \ - __FUNCTION__, g_first_broadcast_scan)); - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_CONSUMED; - } - else { - WL_ERROR(("%s Ignoring Broadcast Scan:First Scan is not done yet %d\n", \ - __FUNCTION__, g_first_counter_scans)); - ret = -EBUSY; - goto set_scan_end; - } - } -#endif - - wl_iw_iscan_set_scan_broadcast_prep(dev, 0); - -set_scan_end: - net_os_wake_unlock(dev); - return ret; -} -#endif - -#if WIRELESS_EXT > 17 -static bool -ie_is_wpa_ie(uint8 **wpaie, uint8 **tlvs, int *tlvs_len) -{ - uint8 *ie = *wpaie; - - if ((ie[1] >= 6) && - !bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x01"), 4)) { - return TRUE; - } - - ie += ie[1] + 2; - - *tlvs_len -= (int)(ie - *tlvs); - - *tlvs = ie; - return FALSE; -} - -static bool -ie_is_wps_ie(uint8 **wpsie, uint8 **tlvs, int *tlvs_len) -{ - uint8 *ie = *wpsie; - - if ((ie[1] >= 4) && - !bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x04"), 4)) { - return TRUE; - } - - ie += ie[1] + 2; - - *tlvs_len -= (int)(ie - *tlvs); - - *tlvs = ie; - return FALSE; -} -#endif - -static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, - size_t len, int uppercase) -{ - size_t i; - char *pos = buf, *end = buf + buf_size; - int ret; - if (buf_size == 0) - return 0; - for (i = 0; i < len; i++) { - ret = snprintf(pos, end - pos, uppercase ? "%02X" : "%02x", - data[i]); - if (ret < 0 || ret >= end - pos) { - end[-1] = '\0'; - return pos - buf; - } - pos += ret; - } - end[-1] = '\0'; - return pos - buf; -} - - -int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len) -{ - return _wpa_snprintf_hex(buf, buf_size, data, len, 0); -} - -static int -wl_iw_handle_scanresults_ies(char **event_p, char *end, - struct iw_request_info *info, wl_bss_info_t *bi) -{ -#if WIRELESS_EXT > 17 - struct iw_event iwe; - char *event; - char *buf; - int custom_event_len; - - event = *event_p; - if (bi->ie_length) { - - bcm_tlv_t *ie; - uint8 *ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); - int ptr_len = bi->ie_length; - -#ifdef BCMWPA2 - if ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_RSN_ID))) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); - } - ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); -#endif - - while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) { - - if (ie_is_wps_ie(((uint8 **)&ie), &ptr, &ptr_len)) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); - break; - } - } - - ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); - ptr_len = bi->ie_length; - while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) { - if (ie_is_wpa_ie(((uint8 **)&ie), &ptr, &ptr_len)) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); - break; - } - } - - ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); - ptr_len = bi->ie_length; - - while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WAPI_ID))) { - WL_TRACE(("%s: found a WAPI IE...\n", __FUNCTION__)); -#ifdef WAPI_IE_USE_GENIE - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); -#else - iwe.cmd = IWEVCUSTOM; - custom_event_len = strlen("wapi_ie=") + 2*(ie->len + 2); - iwe.u.data.length = custom_event_len; - - buf = kmalloc(custom_event_len+1, GFP_KERNEL); - if (buf == NULL) - { - WL_ERROR(("malloc(%d) returned NULL...\n", custom_event_len)); - break; - } - - memcpy(buf, "wapi_ie=", 8); - wpa_snprintf_hex(buf + 8, 2+1, &(ie->id), 1); - wpa_snprintf_hex(buf + 10, 2+1, &(ie->len), 1); - wpa_snprintf_hex(buf + 12, 2*ie->len+1, ie->data, ie->len); - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, buf); - kfree(buf); -#endif - break; - } - *event_p = event; - } -#endif - - return 0; -} - -#ifndef CSCAN -static uint -wl_iw_get_scan_prep( - wl_scan_results_t *list, - struct iw_request_info *info, - char *extra, - short max_size) -{ - int i, j; - struct iw_event iwe; - wl_bss_info_t *bi = NULL; - char *event = extra, *end = extra + max_size - WE_ADD_EVENT_FIX, *value; - int ret = 0; - int channel; - - if (!list) { - WL_ERROR(("%s: Null list pointer",__FUNCTION__)); - return ret; - } - - for (i = 0; i < list->count && i < IW_MAX_AP; i++) - { - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", \ - __FUNCTION__, list->version)); - return ret; - } - - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; - - WL_TRACE(("%s : %s\n", __FUNCTION__, bi->SSID)); - - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN); - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN); - - iwe.u.data.length = dtoh32(bi->SSID_len); - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID); - - if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) { - iwe.cmd = SIOCGIWMODE; - if (dtoh16(bi->capability) & DOT11_CAP_ESS) - iwe.u.mode = IW_MODE_INFRA; - else - iwe.u.mode = IW_MODE_ADHOC; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_UINT_LEN); - } - - iwe.cmd = SIOCGIWFREQ; - channel = (bi->ctl_ch == 0) ? CHSPEC_CHANNEL(bi->chanspec) : bi->ctl_ch; - iwe.u.freq.m = wf_channel2mhz(channel, - channel <= CH_MAX_2G_CHANNEL ? - WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G); - iwe.u.freq.e = 6; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN); - - iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI)); - iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI); - iwe.u.qual.noise = 0x100 + bi->phy_noise; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN); - - wl_iw_handle_scanresults_ies(&event, end, info, bi); - - iwe.cmd = SIOCGIWENCODE; - if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event); - - if (bi->rateset.count) { - if (((event -extra) + IW_EV_LCP_LEN) <= (uintptr)end) { - value = event + IW_EV_LCP_LEN; - iwe.cmd = SIOCGIWRATE; - - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; - for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) { - iwe.u.bitrate.value = (bi->rateset.rates[j] & 0x7f) * 500000; - value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe, - IW_EV_PARAM_LEN); - } - event = value; - } - } - } - - if ((ret = (event - extra)) < 0) { - WL_ERROR(("==> Wrong size\n")); - ret = 0; - } - WL_TRACE(("%s: size=%d bytes prepared \n", __FUNCTION__, (unsigned int)(event - extra))); - return (uint)ret; -} - -static int -wl_iw_get_scan( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - channel_info_t ci; - wl_scan_results_t *list_merge; - wl_scan_results_t *list = (wl_scan_results_t *) g_scan; - int error; - uint buflen_from_user = dwrq->length; - uint len = G_SCAN_RESULTS; - __u16 len_ret = 0; -#if !defined(CSCAN) - __u16 merged_len = 0; -#endif -#if defined(WL_IW_USE_ISCAN) - iscan_info_t *iscan = g_iscan; - iscan_buf_t * p_buf; -#if !defined(CSCAN) - uint32 counter = 0; -#endif -#endif - WL_TRACE(("%s: buflen_from_user %d: \n", dev->name, buflen_from_user)); - - if (!extra) { - WL_TRACE(("%s: wl_iw_get_scan return -EINVAL\n", dev->name)); - return -EINVAL; - } - - if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)))) - return error; - ci.scan_channel = dtoh32(ci.scan_channel); - if (ci.scan_channel) - return -EAGAIN; - -#if !defined(CSCAN) - if (g_ss_cache_ctrl.m_timer_expired) { - wl_iw_free_ss_cache(); - g_ss_cache_ctrl.m_timer_expired ^= 1; - } - if ((!g_scan_specified_ssid && g_ss_cache_ctrl.m_prev_scan_mode) || - g_ss_cache_ctrl.m_cons_br_scan_cnt > 4) { - g_ss_cache_ctrl.m_cons_br_scan_cnt = 0; - - wl_iw_reset_ss_cache(); - } - g_ss_cache_ctrl.m_prev_scan_mode = g_scan_specified_ssid; - if (g_scan_specified_ssid) { - g_ss_cache_ctrl.m_cons_br_scan_cnt = 0; - } - else { - g_ss_cache_ctrl.m_cons_br_scan_cnt++; - } -#endif - - if (g_scan_specified_ssid) { - - list = kmalloc(len, GFP_KERNEL); - if (!list) { - WL_TRACE(("%s: wl_iw_get_scan return -ENOMEM\n", dev->name)); - g_scan_specified_ssid = 0; - return -ENOMEM; - } - } - - memset(list, 0, len); - list->buflen = htod32(len); - if ((error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, len))) { - WL_ERROR(("%s: %s : Scan_results ERROR %d\n", dev->name, __FUNCTION__, error)); - dwrq->length = len; - if (g_scan_specified_ssid) { - g_scan_specified_ssid = 0; - kfree(list); - } - return 0; - } - list->buflen = dtoh32(list->buflen); - list->version = dtoh32(list->version); - list->count = dtoh32(list->count); - - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, list->version)); - if (g_scan_specified_ssid) { - g_scan_specified_ssid = 0; - kfree(list); - } - return -EINVAL; - } - -#if !defined(CSCAN) - if (g_scan_specified_ssid) { - - wl_iw_add_bss_to_ss_cache(list); - kfree(list); - } - - mutex_lock(&wl_cache_lock); -#if defined(WL_IW_USE_ISCAN) - if (g_scan_specified_ssid) - WL_TRACE(("%s: Specified scan APs from scan=%d\n", __FUNCTION__, list->count)); - p_buf = iscan->list_hdr; - - while (p_buf != iscan->list_cur) { - list_merge = &((wl_iscan_results_t*)p_buf->iscan_buf)->results; - WL_TRACE(("%s: Bcast APs list=%d\n", __FUNCTION__, list_merge->count)); - counter += list_merge->count; - if (list_merge->count > 0) - len_ret += (__u16) wl_iw_get_scan_prep(list_merge, info, - extra+len_ret, buflen_from_user -len_ret); - p_buf = p_buf->next; - } - WL_TRACE(("%s merged with total Bcast APs=%d\n", __FUNCTION__, counter)); -#else - list_merge = (wl_scan_results_t *) g_scan; - len_ret = (__u16) wl_iw_get_scan_prep(list_merge, info, extra, buflen_from_user); -#endif - mutex_unlock(&wl_cache_lock); - if (g_ss_cache_ctrl.m_link_down) { - wl_iw_delete_bss_from_ss_cache(g_ss_cache_ctrl.m_active_bssid); - } - - wl_iw_merge_scan_cache(info, extra+len_ret, buflen_from_user-len_ret, &merged_len); - len_ret += merged_len; - wl_iw_run_ss_cache_timer(0); - wl_iw_run_ss_cache_timer(1); -#else - - if (g_scan_specified_ssid) { - WL_TRACE(("%s: Specified scan APs in the list =%d\n", __FUNCTION__, list->count)); - len_ret = (__u16) wl_iw_get_scan_prep(list, info, extra, buflen_from_user); - kfree(list); - -#if defined(WL_IW_USE_ISCAN) - p_buf = iscan->list_hdr; - - while (p_buf != iscan->list_cur) { - list_merge = &((wl_iscan_results_t*)p_buf->iscan_buf)->results; - WL_TRACE(("%s: Bcast APs list=%d\n", __FUNCTION__, list_merge->count)); - if (list_merge->count > 0) - len_ret += (__u16) wl_iw_get_scan_prep(list_merge, info, - extra+len_ret, buflen_from_user -len_ret); - p_buf = p_buf->next; - } -#else - list_merge = (wl_scan_results_t *) g_scan; - WL_TRACE(("%s: Bcast APs list=%d\n", __FUNCTION__, list_merge->count)); - if (list_merge->count > 0) - len_ret += (__u16) wl_iw_get_scan_prep(list_merge, info, extra+len_ret, - buflen_from_user -len_ret); -#endif - } - else { - list = (wl_scan_results_t *) g_scan; - len_ret = (__u16) wl_iw_get_scan_prep(list, info, extra, buflen_from_user); - } -#endif - -#if defined(WL_IW_USE_ISCAN) - - g_scan_specified_ssid = 0; -#endif - - if ((len_ret + WE_ADD_EVENT_FIX) < buflen_from_user) - len = len_ret; - - dwrq->length = len; - dwrq->flags = 0; - - WL_TRACE(("%s return to WE %d bytes APs=%d\n", __FUNCTION__, dwrq->length, list->count)); - return 0; -} -#endif - -#if defined(WL_IW_USE_ISCAN) -static int -wl_iw_iscan_get_scan( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_scan_results_t *list; - struct iw_event iwe; - wl_bss_info_t *bi = NULL; - int ii, j; - int apcnt; - char *event = extra, *end = extra + dwrq->length, *value; - iscan_info_t *iscan = g_iscan; - iscan_buf_t * p_buf; - uint32 counter = 0; - uint8 channel; -#if !defined(CSCAN) - __u16 merged_len = 0; - uint buflen_from_user = dwrq->length; -#endif - - WL_SCAN(("%s %s buflen_from_user %d:\n", dev->name, __FUNCTION__, dwrq->length)); - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_TRACE(("%s: Not executed, reason -'SOFTAP is active'\n", __FUNCTION__)); - return -EINVAL; - } -#endif - - if (!extra) { - WL_TRACE(("%s: INVALID SIOCGIWSCAN GET bad parameter\n", dev->name)); - return -EINVAL; - } - -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan < BROADCAST_SCAN_FIRST_RESULT_READY) { - WL_TRACE(("%s %s: first ISCAN results are NOT ready yet \n", \ - dev->name, __FUNCTION__)); - return -EAGAIN; - } -#endif - - if ((!iscan) || (iscan->sysioc_pid < 0)) { - WL_ERROR(("%ssysioc_pid\n", __FUNCTION__)); - return -EAGAIN; - } - -#if !defined(CSCAN) - if (g_ss_cache_ctrl.m_timer_expired) { - wl_iw_free_ss_cache(); - g_ss_cache_ctrl.m_timer_expired ^= 1; - } - if (g_scan_specified_ssid) { - return wl_iw_get_scan(dev, info, dwrq, extra); - } - else { - if (g_ss_cache_ctrl.m_link_down) { - wl_iw_delete_bss_from_ss_cache(g_ss_cache_ctrl.m_active_bssid); - } - if (g_ss_cache_ctrl.m_prev_scan_mode || g_ss_cache_ctrl.m_cons_br_scan_cnt > 4) { - g_ss_cache_ctrl.m_cons_br_scan_cnt = 0; - - wl_iw_reset_ss_cache(); - } - g_ss_cache_ctrl.m_prev_scan_mode = g_scan_specified_ssid; - g_ss_cache_ctrl.m_cons_br_scan_cnt++; - } -#endif - - WL_TRACE(("%s: SIOCGIWSCAN GET broadcast results\n", dev->name)); - apcnt = 0; - p_buf = iscan->list_hdr; - - while (p_buf != iscan->list_cur) { - list = &((wl_iscan_results_t*)p_buf->iscan_buf)->results; - - counter += list->count; - - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, list->version)); - return -EINVAL; - } - - bi = NULL; - for (ii = 0; ii < list->count && apcnt < IW_MAX_AP; apcnt++, ii++) { - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; - - if ((dtoh32(bi->length) > WLC_IW_ISCAN_MAXLEN) || - (((uintptr)bi + dtoh32(bi->length)) > ((uintptr)list + WLC_IW_ISCAN_MAXLEN))) { - WL_ERROR(("%s: Scan results out of bounds: %u\n",__FUNCTION__,dtoh32(bi->length))); - return -E2BIG; - } - - if (event + ETHER_ADDR_LEN + bi->SSID_len + IW_EV_UINT_LEN + IW_EV_FREQ_LEN + - IW_EV_QUAL_LEN >= end) - return -E2BIG; - - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN); - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN); - - iwe.u.data.length = dtoh32(bi->SSID_len); - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID); - - if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) { - iwe.cmd = SIOCGIWMODE; - if (dtoh16(bi->capability) & DOT11_CAP_ESS) - iwe.u.mode = IW_MODE_INFRA; - else - iwe.u.mode = IW_MODE_ADHOC; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_UINT_LEN); - } - - iwe.cmd = SIOCGIWFREQ; - channel = (bi->ctl_ch == 0) ? CHSPEC_CHANNEL(bi->chanspec) : bi->ctl_ch; - iwe.u.freq.m = wf_channel2mhz(channel, - channel <= CH_MAX_2G_CHANNEL ? - WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G); - iwe.u.freq.e = 6; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN); - - iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI)); - iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI); - iwe.u.qual.noise = 0x100 + bi->phy_noise; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN); - - wl_iw_handle_scanresults_ies(&event, end, info, bi); - - iwe.cmd = SIOCGIWENCODE; - if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event); - - if (bi->rateset.count) { - if (event + IW_MAX_BITRATES*IW_EV_PARAM_LEN >= end) - return -E2BIG; - - value = event + IW_EV_LCP_LEN; - iwe.cmd = SIOCGIWRATE; - - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; - for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) { - iwe.u.bitrate.value = (bi->rateset.rates[j] & 0x7f) * 500000; - value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe, - IW_EV_PARAM_LEN); - } - event = value; - } - } - p_buf = p_buf->next; - } - - dwrq->length = event - extra; - dwrq->flags = 0; - -#if !defined(CSCAN) - wl_iw_merge_scan_cache(info, event, buflen_from_user - dwrq->length, &merged_len); - dwrq->length += merged_len; - wl_iw_run_ss_cache_timer(0); - wl_iw_run_ss_cache_timer(1); -#endif /* CSCAN */ -#if defined(CONFIG_FIRST_SCAN) - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_CONSUMED; -#endif - - WL_TRACE(("%s return to WE %d bytes APs=%d\n", __FUNCTION__, dwrq->length, counter)); - - return 0; -} -#endif - -static int -wl_iw_set_essid( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - int error; - wl_join_params_t join_params; - int join_params_size; - - WL_TRACE(("%s: SIOCSIWESSID\n", dev->name)); - - - memset(&g_ssid, 0, sizeof(g_ssid)); - - CHECK_EXTRA_FOR_NULL(extra); - - if (dwrq->length && extra) { -#if WIRELESS_EXT > 20 - g_ssid.SSID_len = MIN(sizeof(g_ssid.SSID), dwrq->length); -#else - g_ssid.SSID_len = MIN(sizeof(g_ssid.SSID), dwrq->length-1); -#endif - memcpy(g_ssid.SSID, extra, g_ssid.SSID_len); - } else { - - g_ssid.SSID_len = 0; - } - g_ssid.SSID_len = htod32(g_ssid.SSID_len); - - memset(&join_params, 0, sizeof(join_params)); - join_params_size = sizeof(join_params.ssid); - - memcpy(&join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); - join_params.ssid.SSID_len = htod32(g_ssid.SSID_len); - memcpy(&join_params.params.bssid, ðer_bcast, ETHER_ADDR_LEN); - - wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params, &join_params_size); - - if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size))) { - WL_ERROR(("Invalid ioctl data=%d\n", error)); - return error; - } - - if (g_ssid.SSID_len) { - WL_TRACE(("%s: join SSID=%s ch=%d\n", __FUNCTION__, \ - g_ssid.SSID, g_wl_iw_params.target_channel)); - } - return 0; -} - -static int -wl_iw_get_essid( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wlc_ssid_t ssid; - int error; - - WL_TRACE(("%s: SIOCGIWESSID\n", dev->name)); - - if (!extra) - return -EINVAL; - - if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)))) { - WL_ERROR(("Error getting the SSID\n")); - return error; - } - - ssid.SSID_len = dtoh32(ssid.SSID_len); - - memcpy(extra, ssid.SSID, ssid.SSID_len); - - dwrq->length = ssid.SSID_len; - - dwrq->flags = 1; - - return 0; -} - -static int -wl_iw_set_nick( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_iw_t *iw = *(wl_iw_t **)netdev_priv(dev); - - WL_TRACE(("%s: SIOCSIWNICKN\n", dev->name)); - - if (!extra) - return -EINVAL; - - if (dwrq->length > sizeof(iw->nickname)) - return -E2BIG; - - memcpy(iw->nickname, extra, dwrq->length); - iw->nickname[dwrq->length - 1] = '\0'; - - return 0; -} - -static int -wl_iw_get_nick( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_iw_t *iw = *(wl_iw_t **)netdev_priv(dev); - - WL_TRACE(("%s: SIOCGIWNICKN\n", dev->name)); - - if (!extra) - return -EINVAL; - - strcpy(extra, iw->nickname); - dwrq->length = strlen(extra) + 1; - - return 0; -} - -static int wl_iw_set_rate( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - wl_rateset_t rateset; - int error, rate, i, error_bg, error_a; - - WL_TRACE(("%s: SIOCSIWRATE\n", dev->name)); - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset)))) - return error; - - rateset.count = dtoh32(rateset.count); - - if (vwrq->value < 0) { - - rate = rateset.rates[rateset.count - 1] & 0x7f; - } else if (vwrq->value < rateset.count) { - - rate = rateset.rates[vwrq->value] & 0x7f; - } else { - - rate = vwrq->value / 500000; - } - - if (vwrq->fixed) { - - error_bg = dev_wlc_intvar_set(dev, "bg_rate", rate); - error_a = dev_wlc_intvar_set(dev, "a_rate", rate); - - if (error_bg && error_a) - return (error_bg | error_a); - } else { - - - error_bg = dev_wlc_intvar_set(dev, "bg_rate", 0); - - error_a = dev_wlc_intvar_set(dev, "a_rate", 0); - - if (error_bg && error_a) - return (error_bg | error_a); - - - for (i = 0; i < rateset.count; i++) - if ((rateset.rates[i] & 0x7f) > rate) - break; - rateset.count = htod32(i); - - - if ((error = dev_wlc_ioctl(dev, WLC_SET_RATESET, &rateset, sizeof(rateset)))) - return error; - } - - return 0; -} - -static int wl_iw_get_rate( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, rate; - - WL_TRACE(("%s: SIOCGIWRATE\n", dev->name)); - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate)))) - return error; - rate = dtoh32(rate); - vwrq->value = rate * 500000; - - return 0; -} - -static int -wl_iw_set_rts( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, rts; - - WL_TRACE(("%s: SIOCSIWRTS\n", dev->name)); - - if (vwrq->disabled) - rts = DOT11_DEFAULT_RTS_LEN; - else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_RTS_LEN) - return -EINVAL; - else - rts = vwrq->value; - - if ((error = dev_wlc_intvar_set(dev, "rtsthresh", rts))) - return error; - - return 0; -} - -static int -wl_iw_get_rts( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, rts; - - WL_TRACE(("%s: SIOCGIWRTS\n", dev->name)); - - if ((error = dev_wlc_intvar_get(dev, "rtsthresh", &rts))) - return error; - - vwrq->value = rts; - vwrq->disabled = (rts >= DOT11_DEFAULT_RTS_LEN); - vwrq->fixed = 1; - - return 0; -} - -static int -wl_iw_set_frag( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, frag; - - WL_TRACE(("%s: SIOCSIWFRAG\n", dev->name)); - - if (vwrq->disabled) - frag = DOT11_DEFAULT_FRAG_LEN; - else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_FRAG_LEN) - return -EINVAL; - else - frag = vwrq->value; - - if ((error = dev_wlc_intvar_set(dev, "fragthresh", frag))) - return error; - - return 0; -} - -static int -wl_iw_get_frag( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, fragthreshold; - - WL_TRACE(("%s: SIOCGIWFRAG\n", dev->name)); - - if ((error = dev_wlc_intvar_get(dev, "fragthresh", &fragthreshold))) - return error; - - vwrq->value = fragthreshold; - vwrq->disabled = (fragthreshold >= DOT11_DEFAULT_FRAG_LEN); - vwrq->fixed = 1; - - return 0; -} - -static int -wl_iw_set_txpow( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, disable; - uint16 txpwrmw; - WL_TRACE(("%s: SIOCSIWTXPOW\n", dev->name)); - - - disable = vwrq->disabled ? WL_RADIO_SW_DISABLE : 0; - disable += WL_RADIO_SW_DISABLE << 16; - - disable = htod32(disable); - if ((error = dev_wlc_ioctl(dev, WLC_SET_RADIO, &disable, sizeof(disable)))) - return error; - - - if (disable & WL_RADIO_SW_DISABLE) - return 0; - - - if (!(vwrq->flags & IW_TXPOW_MWATT)) - return -EINVAL; - - - if (vwrq->value < 0) - return 0; - - if (vwrq->value > 0xffff) txpwrmw = 0xffff; - else txpwrmw = (uint16)vwrq->value; - - - error = dev_wlc_intvar_set(dev, "qtxpower", (int)(bcm_mw_to_qdbm(txpwrmw))); - return error; -} - -static int -wl_iw_get_txpow( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, disable, txpwrdbm; - uint8 result; - - WL_TRACE(("%s: SIOCGIWTXPOW\n", dev->name)); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_RADIO, &disable, sizeof(disable))) || - (error = dev_wlc_intvar_get(dev, "qtxpower", &txpwrdbm))) - return error; - - disable = dtoh32(disable); - result = (uint8)(txpwrdbm & ~WL_TXPWR_OVERRIDE); - vwrq->value = (int32)bcm_qdbm_to_mw(result); - vwrq->fixed = 0; - vwrq->disabled = (disable & (WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE)) ? 1 : 0; - vwrq->flags = IW_TXPOW_MWATT; - - return 0; -} - -#if WIRELESS_EXT > 10 -static int -wl_iw_set_retry( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, lrl, srl; - - WL_TRACE(("%s: SIOCSIWRETRY\n", dev->name)); - - - if (vwrq->disabled || (vwrq->flags & IW_RETRY_LIFETIME)) - return -EINVAL; - - - if (vwrq->flags & IW_RETRY_LIMIT) { - - -#if WIRELESS_EXT > 20 - if ((vwrq->flags & IW_RETRY_LONG) ||(vwrq->flags & IW_RETRY_MAX) || - !((vwrq->flags & IW_RETRY_SHORT) || (vwrq->flags & IW_RETRY_MIN))) { -#else - if ((vwrq->flags & IW_RETRY_MAX) || !(vwrq->flags & IW_RETRY_MIN)) { -#endif - lrl = htod32(vwrq->value); - if ((error = dev_wlc_ioctl(dev, WLC_SET_LRL, &lrl, sizeof(lrl)))) - return error; - } - - -#if WIRELESS_EXT > 20 - if ((vwrq->flags & IW_RETRY_SHORT) ||(vwrq->flags & IW_RETRY_MIN) || - !((vwrq->flags & IW_RETRY_LONG) || (vwrq->flags & IW_RETRY_MAX))) { -#else - if ((vwrq->flags & IW_RETRY_MIN) || !(vwrq->flags & IW_RETRY_MAX)) { -#endif - srl = htod32(vwrq->value); - if ((error = dev_wlc_ioctl(dev, WLC_SET_SRL, &srl, sizeof(srl)))) - return error; - } - } - return 0; -} - -static int -wl_iw_get_retry( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, lrl, srl; - - WL_TRACE(("%s: SIOCGIWRETRY\n", dev->name)); - - vwrq->disabled = 0; - - - if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) - return -EINVAL; - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_LRL, &lrl, sizeof(lrl))) || - (error = dev_wlc_ioctl(dev, WLC_GET_SRL, &srl, sizeof(srl)))) - return error; - - lrl = dtoh32(lrl); - srl = dtoh32(srl); - - - if (vwrq->flags & IW_RETRY_MAX) { - vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; - vwrq->value = lrl; - } else { - vwrq->flags = IW_RETRY_LIMIT; - vwrq->value = srl; - if (srl != lrl) - vwrq->flags |= IW_RETRY_MIN; - } - - return 0; -} -#endif - -static int -wl_iw_set_encode( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_wsec_key_t key; - int error, val, wsec; - - WL_TRACE(("%s: SIOCSIWENCODE\n", dev->name)); - - memset(&key, 0, sizeof(key)); - - if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { - - for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) { - val = htod32(key.index); - if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val)))) - return error; - val = dtoh32(val); - if (val) - break; - } - - if (key.index == DOT11_MAX_DEFAULT_KEYS) - key.index = 0; - } else { - key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - if (key.index >= DOT11_MAX_DEFAULT_KEYS) - return -EINVAL; - } - - - if (!extra || !dwrq->length || (dwrq->flags & IW_ENCODE_NOKEY)) { - - val = htod32(key.index); - if ((error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, &val, sizeof(val)))) - return error; - } else { - key.len = dwrq->length; - - if (dwrq->length > sizeof(key.data)) - return -EINVAL; - - memcpy(key.data, extra, dwrq->length); - - key.flags = WL_PRIMARY_KEY; - switch (key.len) { - case WEP1_KEY_SIZE: - key.algo = CRYPTO_ALGO_WEP1; - break; - case WEP128_KEY_SIZE: - key.algo = CRYPTO_ALGO_WEP128; - break; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) - case TKIP_KEY_SIZE: - key.algo = CRYPTO_ALGO_TKIP; - break; -#endif - case AES_KEY_SIZE: - key.algo = CRYPTO_ALGO_AES_CCM; - break; - default: - return -EINVAL; - } - - - swap_key_from_BE(&key); - if ((error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)))) - return error; - } - - - val = (dwrq->flags & IW_ENCODE_DISABLED) ? 0 : WEP_ENABLED; - - if ((error = dev_wlc_intvar_get(dev, "wsec", &wsec))) - return error; - - wsec &= ~(WEP_ENABLED); - wsec |= val; - - if ((error = dev_wlc_intvar_set(dev, "wsec", wsec))) - return error; - - - val = (dwrq->flags & IW_ENCODE_RESTRICTED) ? 1 : 0; - val = htod32(val); - if ((error = dev_wlc_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val)))) - return error; - - return 0; -} - -static int -wl_iw_get_encode( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_wsec_key_t key; - int error, val, wsec, auth; - - WL_TRACE(("%s: SIOCGIWENCODE\n", dev->name)); - - - bzero(&key, sizeof(wl_wsec_key_t)); - - if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { - - for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) { - val = key.index; - if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val)))) - return error; - val = dtoh32(val); - if (val) - break; - } - } else - key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - - if (key.index >= DOT11_MAX_DEFAULT_KEYS) - key.index = 0; - - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec))) || - (error = dev_wlc_ioctl(dev, WLC_GET_AUTH, &auth, sizeof(auth)))) - return error; - - swap_key_to_BE(&key); - - wsec = dtoh32(wsec); - auth = dtoh32(auth); - - dwrq->length = MIN(DOT11_MAX_KEY_SIZE, key.len); - - - dwrq->flags = key.index + 1; - if (!(wsec & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))) { - - dwrq->flags |= IW_ENCODE_DISABLED; - } - if (auth) { - - dwrq->flags |= IW_ENCODE_RESTRICTED; - } - - - if (dwrq->length && extra) - memcpy(extra, key.data, dwrq->length); - - return 0; -} - -static int -wl_iw_set_power( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, pm; - - WL_TRACE(("%s: SIOCSIWPOWER\n", dev->name)); - - pm = vwrq->disabled ? PM_OFF : PM_MAX; - - pm = htod32(pm); - if ((error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)))) - return error; - - return 0; -} - -static int -wl_iw_get_power( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, pm; - - WL_TRACE(("%s: SIOCGIWPOWER\n", dev->name)); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm)))) - return error; - - pm = dtoh32(pm); - vwrq->disabled = pm ? 0 : 1; - vwrq->flags = IW_POWER_ALL_R; - - return 0; -} - -#if WIRELESS_EXT > 17 -static int -wl_iw_set_wpaie( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *iwp, - char *extra -) -{ - uchar buf[WLC_IOCTL_SMLEN] = {0}; - uchar *p = buf; - int wapi_ie_size; - - WL_TRACE(("%s: SIOCSIWGENIE\n", dev->name)); - - CHECK_EXTRA_FOR_NULL(extra); - - if (extra[0] == DOT11_MNG_WAPI_ID) - { - wapi_ie_size = iwp->length; - memcpy(p, extra, iwp->length); - dev_wlc_bufvar_set(dev, "wapiie", buf, wapi_ie_size); - } - else - dev_wlc_bufvar_set(dev, "wpaie", extra, iwp->length); - - return 0; -} - -static int -wl_iw_get_wpaie( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *iwp, - char *extra -) -{ - WL_TRACE(("%s: SIOCGIWGENIE\n", dev->name)); - iwp->length = 64; - dev_wlc_bufvar_get(dev, "wpaie", extra, iwp->length); - return 0; -} - -static int -wl_iw_set_encodeext( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_wsec_key_t key; - int error; - struct iw_encode_ext *iwe; - - WL_WSEC(("%s: SIOCSIWENCODEEXT\n", dev->name)); - - CHECK_EXTRA_FOR_NULL(extra); - - memset(&key, 0, sizeof(key)); - iwe = (struct iw_encode_ext *)extra; - - - if (dwrq->flags & IW_ENCODE_DISABLED) { - - } - - - key.index = 0; - if (dwrq->flags & IW_ENCODE_INDEX) - key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - - key.len = iwe->key_len; - - - if (!ETHER_ISMULTI(iwe->addr.sa_data)) - bcopy((void *)&iwe->addr.sa_data, (char *)&key.ea, ETHER_ADDR_LEN); - - - if (key.len == 0) { - if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - WL_WSEC(("Changing the the primary Key to %d\n", key.index)); - - key.index = htod32(key.index); - error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, - &key.index, sizeof(key.index)); - if (error) - return error; - } - - else { - swap_key_from_BE(&key); - dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - } - } - else { - if (iwe->key_len > sizeof(key.data)) - return -EINVAL; - - WL_WSEC(("Setting the key index %d\n", key.index)); - if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - WL_WSEC(("key is a Primary Key\n")); - key.flags = WL_PRIMARY_KEY; - } - - bcopy((void *)iwe->key, key.data, iwe->key_len); - - if (iwe->alg == IW_ENCODE_ALG_TKIP) { - uint8 keybuf[8]; - bcopy(&key.data[24], keybuf, sizeof(keybuf)); - bcopy(&key.data[16], &key.data[24], sizeof(keybuf)); - bcopy(keybuf, &key.data[16], sizeof(keybuf)); - } - - - if (iwe->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { - uchar *ivptr; - ivptr = (uchar *)iwe->rx_seq; - key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) | - (ivptr[3] << 8) | ivptr[2]; - key.rxiv.lo = (ivptr[1] << 8) | ivptr[0]; - key.iv_initialized = TRUE; - } - - switch (iwe->alg) { - case IW_ENCODE_ALG_NONE: - key.algo = CRYPTO_ALGO_OFF; - break; - case IW_ENCODE_ALG_WEP: - if (iwe->key_len == WEP1_KEY_SIZE) - key.algo = CRYPTO_ALGO_WEP1; - else - key.algo = CRYPTO_ALGO_WEP128; - break; - case IW_ENCODE_ALG_TKIP: - key.algo = CRYPTO_ALGO_TKIP; - break; - case IW_ENCODE_ALG_CCMP: - key.algo = CRYPTO_ALGO_AES_CCM; - break; - case IW_ENCODE_ALG_SM4: - key.algo = CRYPTO_ALGO_SMS4; - if (iwe->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { - key.flags &= ~WL_PRIMARY_KEY; - } - break; - default: - break; - } - swap_key_from_BE(&key); - - dhd_wait_pend8021x(dev); - - error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - if (error) - return error; - } - return 0; -} - -#if WIRELESS_EXT > 17 -#ifdef BCMWPA2 -struct { - pmkid_list_t pmkids; - pmkid_t foo[MAXPMKID-1]; -} pmkid_list; - -static int -wl_iw_set_pmksa( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - struct iw_pmksa *iwpmksa; - uint i; - int ret = 0; - char eabuf[ETHER_ADDR_STR_LEN]; - - WL_WSEC(("%s: SIOCSIWPMKSA\n", dev->name)); - CHECK_EXTRA_FOR_NULL(extra); - - iwpmksa = (struct iw_pmksa *)extra; - bzero((char *)eabuf, ETHER_ADDR_STR_LEN); - - if (iwpmksa->cmd == IW_PMKSA_FLUSH) { - WL_WSEC(("wl_iw_set_pmksa - IW_PMKSA_FLUSH\n")); - bzero((char *)&pmkid_list, sizeof(pmkid_list)); - } - - else if (iwpmksa->cmd == IW_PMKSA_REMOVE) { - { - pmkid_list_t pmkid, *pmkidptr; - uint j; - pmkidptr = &pmkid; - - bcopy(&iwpmksa->bssid.sa_data[0], &pmkidptr->pmkid[0].BSSID, ETHER_ADDR_LEN); - bcopy(&iwpmksa->pmkid[0], &pmkidptr->pmkid[0].PMKID, WPA2_PMKID_LEN); - - WL_WSEC(("wl_iw_set_pmksa,IW_PMKSA_REMOVE - PMKID: %s = ", - bcm_ether_ntoa(&pmkidptr->pmkid[0].BSSID, - eabuf))); - for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", pmkidptr->pmkid[0].PMKID[j])); - WL_WSEC(("\n")); - } - - for (i = 0; i < pmkid_list.pmkids.npmkid; i++) - if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_list.pmkids.pmkid[i].BSSID, - ETHER_ADDR_LEN)) - break; - - if ((pmkid_list.pmkids.npmkid > 0) && (i < pmkid_list.pmkids.npmkid)) { - bzero(&pmkid_list.pmkids.pmkid[i], sizeof(pmkid_t)); - for (; i < (pmkid_list.pmkids.npmkid - 1); i++) { - bcopy(&pmkid_list.pmkids.pmkid[i+1].BSSID, - &pmkid_list.pmkids.pmkid[i].BSSID, - ETHER_ADDR_LEN); - bcopy(&pmkid_list.pmkids.pmkid[i+1].PMKID, - &pmkid_list.pmkids.pmkid[i].PMKID, - WPA2_PMKID_LEN); - } - pmkid_list.pmkids.npmkid--; - } - else - ret = -EINVAL; - } - - else if (iwpmksa->cmd == IW_PMKSA_ADD) { - for (i = 0; i < pmkid_list.pmkids.npmkid; i++) - if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_list.pmkids.pmkid[i].BSSID, - ETHER_ADDR_LEN)) - break; - if (i < MAXPMKID) { - bcopy(&iwpmksa->bssid.sa_data[0], - &pmkid_list.pmkids.pmkid[i].BSSID, - ETHER_ADDR_LEN); - bcopy(&iwpmksa->pmkid[0], &pmkid_list.pmkids.pmkid[i].PMKID, - WPA2_PMKID_LEN); - if (i == pmkid_list.pmkids.npmkid) - pmkid_list.pmkids.npmkid++; - } - else - ret = -EINVAL; - - { - uint j; - uint k; - k = pmkid_list.pmkids.npmkid; - WL_WSEC(("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %s = ", - bcm_ether_ntoa(&pmkid_list.pmkids.pmkid[k].BSSID, - eabuf))); - for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", pmkid_list.pmkids.pmkid[k].PMKID[j])); - WL_WSEC(("\n")); - } - } - WL_WSEC(("PRINTING pmkid LIST - No of elements %d, ret = %d\n", pmkid_list.pmkids.npmkid, ret)); - for (i = 0; i < pmkid_list.pmkids.npmkid; i++) { - uint j; - WL_WSEC(("PMKID[%d]: %s = ", i, - bcm_ether_ntoa(&pmkid_list.pmkids.pmkid[i].BSSID, - eabuf))); - for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", pmkid_list.pmkids.pmkid[i].PMKID[j])); - WL_WSEC(("\n")); - } - WL_WSEC(("\n")); - - if (!ret) - ret = dev_wlc_bufvar_set(dev, "pmkid_info", (char *)&pmkid_list, sizeof(pmkid_list)); - return ret; -} -#endif -#endif - -static int -wl_iw_get_encodeext( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - WL_WSEC(("%s: SIOCGIWENCODEEXT\n", dev->name)); - return 0; -} - -static int -wl_iw_set_wpaauth( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error = 0; - int paramid; - int paramval; - int val = 0; - wl_iw_t *iw = *(wl_iw_t **)netdev_priv(dev); - - WL_WSEC(("%s: SIOCSIWAUTH\n", dev->name)); - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_TRACE(("%s: Not executed, reason -'SOFTAP is active'\n", __FUNCTION__)); - return 0; - } -#endif - - paramid = vwrq->flags & IW_AUTH_INDEX; - paramval = vwrq->value; - - WL_WSEC(("%s: SIOCSIWAUTH, paramid = 0x%0x, paramval = 0x%0x\n", - dev->name, paramid, paramval)); - - switch (paramid) { - case IW_AUTH_WPA_VERSION: - - if (paramval & IW_AUTH_WPA_VERSION_DISABLED) - val = WPA_AUTH_DISABLED; - else if (paramval & (IW_AUTH_WPA_VERSION_WPA)) - val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED; -#ifdef BCMWPA2 - else if (paramval & IW_AUTH_WPA_VERSION_WPA2) - val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED; -#endif - else if (paramval & IW_AUTH_WAPI_VERSION_1) - val = WPA_AUTH_WAPI; - WL_WSEC(("%s: %d: setting wpa_auth to 0x%0x\n", __FUNCTION__, __LINE__, val)); - if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val))) - return error; - break; - case IW_AUTH_CIPHER_PAIRWISE: - case IW_AUTH_CIPHER_GROUP: - - - if (paramval & (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) - val = WEP_ENABLED; - if (paramval & IW_AUTH_CIPHER_TKIP) - val = TKIP_ENABLED; - if (paramval & IW_AUTH_CIPHER_CCMP) - val = AES_ENABLED; - if (paramval & IW_AUTH_CIPHER_SMS4) - val = SMS4_ENABLED; - - if (paramid == IW_AUTH_CIPHER_PAIRWISE) { - iw->pwsec = val; - val |= iw->gwsec; - } - else { - iw->gwsec = val; - val |= iw->pwsec; - } - - if (iw->privacy_invoked && !val) { - WL_WSEC(("%s: %s: 'Privacy invoked' TRUE but clearing wsec, assuming " - "we're a WPS enrollee\n", dev->name, __FUNCTION__)); - if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", TRUE))) { - WL_ERROR(("Failed to set iovar is_WPS_enrollee\n")); - return error; - } - } else if (val) { - if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) { - WL_ERROR(("Failed to clear iovar is_WPS_enrollee\n")); - return error; - } - } - - if ((error = dev_wlc_intvar_set(dev, "wsec", val))) { - WL_ERROR(("Failed to set 'wsec'iovar\n")); - return error; - } - - break; - - case IW_AUTH_KEY_MGMT: - if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) { - WL_ERROR(("Failed to get 'wpa_auth'iovar\n")); - return error; - } - - if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) { - if (paramval & IW_AUTH_KEY_MGMT_PSK) - val = WPA_AUTH_PSK; - else - val = WPA_AUTH_UNSPECIFIED; - } -#ifdef BCMWPA2 - else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) { - if (paramval & IW_AUTH_KEY_MGMT_PSK) - val = WPA2_AUTH_PSK; - else - val = WPA2_AUTH_UNSPECIFIED; - } -#endif - if (paramval & (IW_AUTH_KEY_MGMT_WAPI_PSK | IW_AUTH_KEY_MGMT_WAPI_CERT)) - val = WPA_AUTH_WAPI; - WL_WSEC(("%s: %d: setting wpa_auth to %d\n", __FUNCTION__, __LINE__, val)); - if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val))) { - WL_ERROR(("Failed to set 'wpa_auth'iovar\n")); - return error; - } - - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - if ((error = dev_wlc_bufvar_set(dev, "tkip_countermeasures", \ - (char *)¶mval, sizeof(paramval)))) - WL_WSEC(("%s: tkip_countermeasures failed %d\n", __FUNCTION__, error)); - break; - - case IW_AUTH_80211_AUTH_ALG: - - WL_WSEC(("Setting the D11auth %d\n", paramval)); - if (paramval == IW_AUTH_ALG_OPEN_SYSTEM) - val = 0; - else if (paramval == IW_AUTH_ALG_SHARED_KEY) - val = 1; - else if (paramval == (IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY)) - val = 2; - else - error = 1; - if (!error && (error = dev_wlc_intvar_set(dev, "auth", val))) - return error; - break; - - case IW_AUTH_WPA_ENABLED: - if (paramval == 0) { - iw->pwsec = 0; - iw->gwsec = 0; - if ((error = dev_wlc_intvar_get(dev, "wsec", &val))) { - WL_ERROR(("Failed to get 'wsec'iovar\n")); - return error; - } - if (val & (TKIP_ENABLED | AES_ENABLED)) { - val &= ~(TKIP_ENABLED | AES_ENABLED); - dev_wlc_intvar_set(dev, "wsec", val); - } - val = 0; - - WL_INFORM(("%s: %d: setting wpa_auth to %d\n", - __FUNCTION__, __LINE__, val)); - error = dev_wlc_intvar_set(dev, "wpa_auth", 0); - if (error) - WL_ERROR(("Failed to set 'wpa_auth'iovar\n")); - return error; - } - - - break; - - case IW_AUTH_DROP_UNENCRYPTED: - error = dev_wlc_bufvar_set(dev, "wsec_restrict", \ - (char *)¶mval, sizeof(paramval)); - if (error) - WL_ERROR(("%s: wsec_restrict %d\n", __FUNCTION__, error)); - break; - - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - error = dev_wlc_bufvar_set(dev, "rx_unencrypted_eapol", \ - (char *)¶mval, sizeof(paramval)); - if (error) - WL_WSEC(("%s: rx_unencrypted_eapol %d\n", __FUNCTION__, error)); - break; - -#if WIRELESS_EXT > 17 - case IW_AUTH_ROAMING_CONTROL: - WL_INFORM(("%s: IW_AUTH_ROAMING_CONTROL\n", __FUNCTION__)); - - break; - case IW_AUTH_PRIVACY_INVOKED: { - int wsec; - - if (paramval == 0) { - iw->privacy_invoked = FALSE; - if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) { - WL_WSEC(("Failed to clear iovar is_WPS_enrollee\n")); - return error; - } - } else { - iw->privacy_invoked = TRUE; - if ((error = dev_wlc_intvar_get(dev, "wsec", &wsec))) - return error; - - if (!(IW_WSEC_ENABLED(wsec))) { - - if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", TRUE))) { - WL_WSEC(("Failed to set iovar is_WPS_enrollee\n")); - return error; - } - } else { - if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) { - WL_WSEC(("Failed to clear iovar is_WPS_enrollee\n")); - return error; - } - } - } - break; - } -#endif - case IW_AUTH_WAPI_ENABLED: - if ((error = dev_wlc_intvar_get(dev, "wsec", &val))) - return error; - if (paramval) { - val |= SMS4_ENABLED; - if ((error = dev_wlc_intvar_set(dev, "wsec", val))) { - WL_ERROR(("%s: setting wsec to 0x%0x returned error %d\n", - __FUNCTION__, val, error)); - return error; - } - if ((error = dev_wlc_intvar_set(dev, "wpa_auth", WPA_AUTH_WAPI))) { - WL_ERROR(("%s: setting wpa_auth(WPA_AUTH_WAPI) returned %d\n", - __FUNCTION__, error)); - return error; - } - } - - break; - default: - break; - } - return 0; -} -#ifdef BCMWPA2 -#define VAL_PSK(_val) (((_val) & WPA_AUTH_PSK) || ((_val) & WPA2_AUTH_PSK)) -#else -#define VAL_PSK(_val) (((_val) & WPA_AUTH_PSK)) -#endif - -static int -wl_iw_get_wpaauth( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error; - int paramid; - int paramval = 0; - int val; - wl_iw_t *iw = *(wl_iw_t **)netdev_priv(dev); - - WL_TRACE(("%s: SIOCGIWAUTH\n", dev->name)); - - paramid = vwrq->flags & IW_AUTH_INDEX; - - switch (paramid) { - case IW_AUTH_WPA_VERSION: - - if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) - return error; - if (val & (WPA_AUTH_NONE | WPA_AUTH_DISABLED)) - paramval = IW_AUTH_WPA_VERSION_DISABLED; - else if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) - paramval = IW_AUTH_WPA_VERSION_WPA; -#ifdef BCMWPA2 - else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) - paramval = IW_AUTH_WPA_VERSION_WPA2; -#endif - break; - case IW_AUTH_CIPHER_PAIRWISE: - case IW_AUTH_CIPHER_GROUP: - if (paramid == IW_AUTH_CIPHER_PAIRWISE) - val = iw->pwsec; - else - val = iw->gwsec; - - paramval = 0; - if (val) { - if (val & WEP_ENABLED) - paramval |= (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104); - if (val & TKIP_ENABLED) - paramval |= (IW_AUTH_CIPHER_TKIP); - if (val & AES_ENABLED) - paramval |= (IW_AUTH_CIPHER_CCMP); - } - else - paramval = IW_AUTH_CIPHER_NONE; - break; - case IW_AUTH_KEY_MGMT: - - if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) - return error; - if (VAL_PSK(val)) - paramval = IW_AUTH_KEY_MGMT_PSK; - else - paramval = IW_AUTH_KEY_MGMT_802_1X; - - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - error = dev_wlc_bufvar_get(dev, "tkip_countermeasures", \ - (char *)¶mval, sizeof(paramval)); - if (error) - WL_ERROR(("%s get tkip_countermeasures %d\n", __FUNCTION__, error)); - break; - - case IW_AUTH_DROP_UNENCRYPTED: - error = dev_wlc_bufvar_get(dev, "wsec_restrict", \ - (char *)¶mval, sizeof(paramval)); - if (error) - WL_ERROR(("%s get wsec_restrict %d\n", __FUNCTION__, error)); - break; - - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - error = dev_wlc_bufvar_get(dev, "rx_unencrypted_eapol", \ - (char *)¶mval, sizeof(paramval)); - if (error) - WL_ERROR(("%s get rx_unencrypted_eapol %d\n", __FUNCTION__, error)); - break; - - case IW_AUTH_80211_AUTH_ALG: - - if ((error = dev_wlc_intvar_get(dev, "auth", &val))) - return error; - if (!val) - paramval = IW_AUTH_ALG_OPEN_SYSTEM; - else - paramval = IW_AUTH_ALG_SHARED_KEY; - break; - case IW_AUTH_WPA_ENABLED: - if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) - return error; - if (val) - paramval = TRUE; - else - paramval = FALSE; - break; -#if WIRELESS_EXT > 17 - case IW_AUTH_ROAMING_CONTROL: - WL_ERROR(("%s: IW_AUTH_ROAMING_CONTROL\n", __FUNCTION__)); - - break; - case IW_AUTH_PRIVACY_INVOKED: - paramval = iw->privacy_invoked; - break; -#endif - } - vwrq->value = paramval; - return 0; -} -#endif - - -#ifdef SOFTAP - -static int ap_macmode = MACLIST_MODE_DISABLED; -static struct mflist ap_black_list; -static int -wl_iw_parse_wep(char *keystr, wl_wsec_key_t *key) -{ - char hex[] = "XX"; - unsigned char *data = key->data; - - switch (strlen(keystr)) { - case 5: - case 13: - case 16: - key->len = strlen(keystr); - memcpy(data, keystr, key->len + 1); - break; - case 12: - case 28: - case 34: - case 66: - if (!strnicmp(keystr, "0x", 2)) - keystr += 2; - else - return -1; - case 10: - case 26: - case 32: - case 64: - key->len = strlen(keystr) / 2; - while (*keystr) { - strncpy(hex, keystr, 2); - *data++ = (char) bcm_strtoul(hex, NULL, 16); - keystr += 2; - } - break; - default: - return -1; - } - - switch (key->len) { - case 5: - key->algo = CRYPTO_ALGO_WEP1; - break; - case 13: - key->algo = CRYPTO_ALGO_WEP128; - break; - case 16: - key->algo = CRYPTO_ALGO_AES_CCM; - break; - case 32: - key->algo = CRYPTO_ALGO_TKIP; - break; - default: - return -1; - } - - key->flags |= WL_PRIMARY_KEY; - - return 0; -} - -#ifdef EXT_WPA_CRYPTO -#define SHA1HashSize 20 -extern void pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len, - int iterations, u8 *buf, size_t buflen); - -#else - -#define SHA1HashSize 20 -int pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len, - int iterations, u8 *buf, size_t buflen) -{ - WL_ERROR(("WARNING: %s is not implemented !!!\n", __FUNCTION__)); - return -1; -} - -#endif - - -int dev_iw_write_cfg1_bss_var(struct net_device *dev, int val) -{ - struct { - int cfg; - int val; - } bss_setbuf; - - int bss_set_res; - char smbuf[WLC_IOCTL_SMLEN]; - memset(smbuf, 0, sizeof(smbuf)); - - bss_setbuf.cfg = 1; - bss_setbuf.val = val; - - bss_set_res = dev_iw_iovar_setbuf(dev, "bss", - &bss_setbuf, sizeof(bss_setbuf), smbuf, sizeof(smbuf)); - WL_TRACE(("%s: bss_set_result:%d set with %d\n", __FUNCTION__, bss_set_res, val)); - - return bss_set_res; -} - - -int dev_iw_read_cfg1_bss_var(struct net_device *dev, int *val) -{ - int bsscfg_idx = 1; - int bss_set_res; - char smbuf[WLC_IOCTL_SMLEN]; - memset(smbuf, 0, sizeof(smbuf)); - - bss_set_res = dev_iw_iovar_getbuf(dev, "bss", \ - &bsscfg_idx, sizeof(bsscfg_idx), smbuf, sizeof(smbuf)); - *val = *(int*)smbuf; - *val = dtoh32(*val); - WL_TRACE(("%s: status=%d bss_get_result=%d\n", __FUNCTION__, bss_set_res, *val)); - return bss_set_res; -} - - -#ifndef AP_ONLY -static int wl_bssiovar_mkbuf( - const char *iovar, - int bssidx, - void *param, - int paramlen, - void *bufptr, - int buflen, - int *perr) -{ - const char *prefix = "bsscfg:"; - int8 *p; - uint prefixlen; - uint namelen; - uint iolen; - - prefixlen = strlen(prefix); - namelen = strlen(iovar) + 1; - iolen = prefixlen + namelen + sizeof(int) + paramlen; - - if (buflen < 0 || iolen > (uint)buflen) { - *perr = BCME_BUFTOOSHORT; - return 0; - } - - p = (int8 *)bufptr; - - memcpy(p, prefix, prefixlen); - p += prefixlen; - - memcpy(p, iovar, namelen); - p += namelen; - - bssidx = htod32(bssidx); - memcpy(p, &bssidx, sizeof(int32)); - p += sizeof(int32); - - if (paramlen) - memcpy(p, param, paramlen); - - *perr = 0; - return iolen; -} -#endif - - -int get_user_params(char *user_params, struct iw_point *dwrq) -{ - int ret = 0; - - if (copy_from_user(user_params, dwrq->pointer, dwrq->length)) { - WL_ERROR(("\n%s: no user params: uptr:%p, ulen:%d\n", - __FUNCTION__, dwrq->pointer, dwrq->length)); - return -EFAULT; - } - - WL_TRACE(("\n%s: iwpriv user params:%s\n", __FUNCTION__, user_params)); - - return ret; -} - - -#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) - -#if defined(CSCAN) - -static int -wl_iw_combined_scan_set(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid, int nchan) -{ - int params_size = WL_SCAN_PARAMS_FIXED_SIZE + WL_NUMCHANNELS * sizeof(uint16); - int err = 0; - char *p; - int i; - iscan_info_t *iscan = g_iscan; - - WL_SCAN(("%s nssid=%d nchan=%d\n", __FUNCTION__, nssid, nchan)); - - if ((!dev) && (!g_iscan) && (!iscan->iscan_ex_params_p)) { - WL_ERROR(("%s error exit\n", __FUNCTION__)); - err = -1; - goto exit; - } - -#ifdef PNO_SUPPORT - if (dhd_dev_get_pno_status(dev)) { - WL_ERROR(("%s: Scan called when PNO is active\n", __FUNCTION__)); - } -#endif - - params_size += WL_SCAN_PARAMS_SSID_MAX * sizeof(wlc_ssid_t); - - if (nssid > 0) { - i = OFFSETOF(wl_scan_params_t, channel_list) + nchan * sizeof(uint16); - i = ROUNDUP(i, sizeof(uint32)); - if (i + nssid * sizeof(wlc_ssid_t) > params_size) { - printf("additional ssids exceed params_size\n"); - err = -1; - goto exit; - } - - p = ((char*)&iscan->iscan_ex_params_p->params) + i; - memcpy(p, ssids_local, nssid * sizeof(wlc_ssid_t)); - p += nssid * sizeof(wlc_ssid_t); - } else { - p = (char*)iscan->iscan_ex_params_p->params.channel_list + nchan * sizeof(uint16); - } - - iscan->iscan_ex_params_p->params.channel_num = \ - htod32((nssid << WL_SCAN_PARAMS_NSSID_SHIFT) | \ - (nchan & WL_SCAN_PARAMS_COUNT_MASK)); - - nssid = \ - (uint)((iscan->iscan_ex_params_p->params.channel_num >> WL_SCAN_PARAMS_NSSID_SHIFT) & \ - WL_SCAN_PARAMS_COUNT_MASK); - - params_size = (int) (p - (char*)iscan->iscan_ex_params_p + nssid * sizeof(wlc_ssid_t)); - iscan->iscan_ex_param_size = params_size; - - iscan->list_cur = iscan->list_hdr; - iscan->iscan_state = ISCAN_STATE_SCANING; - wl_iw_set_event_mask(dev); - mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000); - - iscan->timer_on = 1; - -#ifdef SCAN_DUMP - { - int i; - WL_SCAN(("\n### List of SSIDs to scan ###\n")); - for (i = 0; i < nssid; i++) { - if (!ssids_local[i].SSID_len) - WL_SCAN(("%d: Broadcast scan\n", i)); - else - WL_SCAN(("%d: scan for %s size =%d\n", i, \ - ssids_local[i].SSID, ssids_local[i].SSID_len)); - } - WL_SCAN(("### List of channels to scan ###\n")); - for (i = 0; i < nchan; i++) - { - WL_SCAN(("%d ", iscan->iscan_ex_params_p->params.channel_list[i])); - } - WL_SCAN(("\nnprobes=%d\n", iscan->iscan_ex_params_p->params.nprobes)); - WL_SCAN(("active_time=%d\n", iscan->iscan_ex_params_p->params.active_time)); - WL_SCAN(("passive_time=%d\n", iscan->iscan_ex_params_p->params.passive_time)); - WL_SCAN(("home_time=%d\n", iscan->iscan_ex_params_p->params.home_time)); - WL_SCAN(("scan_type=%d\n", iscan->iscan_ex_params_p->params.scan_type)); - WL_SCAN(("\n###################\n")); - } -#endif - - if (params_size > WLC_IOCTL_MEDLEN) { - WL_ERROR(("Set ISCAN for %s due to params_size=%d \n", \ - __FUNCTION__, params_size)); - err = -1; - } - - if ((err = dev_iw_iovar_setbuf(dev, "iscan", iscan->iscan_ex_params_p, \ - iscan->iscan_ex_param_size, \ - iscan->ioctlbuf, sizeof(iscan->ioctlbuf)))) { - WL_ERROR(("Set ISCAN for %s failed with %d\n", __FUNCTION__, err)); - err = -1; - } - -exit: - - return err; -} - - -static int iwpriv_set_cscan(struct net_device *dev, struct iw_request_info *info, \ - union iwreq_data *wrqu, char *ext) -{ - int res = 0; - char *extra = NULL; - iscan_info_t *iscan = g_iscan; - wlc_ssid_t ssids_local[WL_SCAN_PARAMS_SSID_MAX]; - int nssid = 0; - int nchan = 0; - - WL_TRACE(("\%s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); - return -1; - } - -#ifdef PNO_SET_DEBUG - wl_iw_set_pno_set(dev, info, wrqu, extra); - return 0; -#endif - - if (wrqu->data.length != 0) { - - char *str_ptr; - - if (!iscan->iscan_ex_params_p) { - return -EFAULT; - } - - if (!(extra = kmalloc(wrqu->data.length+1, GFP_KERNEL))) - return -ENOMEM; - - if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) { - kfree(extra); - return -EFAULT; - } - - extra[wrqu->data.length] = 0; - WL_ERROR(("Got str param in iw_point:\n %s\n", extra)); - - str_ptr = extra; - - if (strncmp(str_ptr, GET_SSID, strlen(GET_SSID))) { - WL_ERROR(("%s Error: extracting SSID='' string\n", __FUNCTION__)); - goto exit_proc; - } - str_ptr += strlen(GET_SSID); - nssid = wl_iw_parse_ssid_list(&str_ptr, ssids_local, nssid, \ - WL_SCAN_PARAMS_SSID_MAX); - if (nssid == -1) { - WL_ERROR(("%s wrong ssid list", __FUNCTION__)); - return -1; - } - - if (iscan->iscan_ex_param_size > WLC_IOCTL_MAXLEN) { - WL_ERROR(("%s wrong ex_param_size %d", \ - __FUNCTION__, iscan->iscan_ex_param_size)); - return -1; - } - memset(iscan->iscan_ex_params_p, 0, iscan->iscan_ex_param_size); - - - wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, NULL); - iscan->iscan_ex_params_p->version = htod32(ISCAN_REQ_VERSION); - iscan->iscan_ex_params_p->action = htod16(WL_SCAN_ACTION_START); - iscan->iscan_ex_params_p->scan_duration = htod16(0); - - - if ((nchan = wl_iw_parse_channel_list(&str_ptr, \ - &iscan->iscan_ex_params_p->params.channel_list[0], \ - WL_NUMCHANNELS)) == -1) { - WL_ERROR(("%s missing channel list\n", __FUNCTION__)); - return -1; - } - - - get_parmeter_from_string(&str_ptr, \ - GET_NPROBE, PTYPE_INTDEC, \ - &iscan->iscan_ex_params_p->params.nprobes, 2); - - get_parmeter_from_string(&str_ptr, GET_ACTIVE_ASSOC_DWELL, PTYPE_INTDEC, \ - &iscan->iscan_ex_params_p->params.active_time, 4); - - get_parmeter_from_string(&str_ptr, GET_PASSIVE_ASSOC_DWELL, PTYPE_INTDEC, \ - &iscan->iscan_ex_params_p->params.passive_time, 4); - - get_parmeter_from_string(&str_ptr, GET_HOME_DWELL, PTYPE_INTDEC, \ - &iscan->iscan_ex_params_p->params.home_time, 4); - - get_parmeter_from_string(&str_ptr, GET_SCAN_TYPE, PTYPE_INTDEC, \ - &iscan->iscan_ex_params_p->params.scan_type, 1); - - res = wl_iw_combined_scan_set(dev, ssids_local, nssid, nchan); - - } else { - WL_ERROR(("IWPRIV argument len = 0 \n")); - return -1; - } - -exit_proc: - - kfree(extra); - - return res; -} - - -static int -wl_iw_set_cscan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int res = -1; - iscan_info_t *iscan = g_iscan; - wlc_ssid_t ssids_local[WL_SCAN_PARAMS_SSID_MAX]; - int nssid = 0; - int nchan = 0; - cscan_tlv_t *cscan_tlv_temp; - char type; - char *str_ptr; - int tlv_size_left; -#ifdef TLV_DEBUG - int i; - char tlv_in_example[] = { 'C', 'S', 'C', 'A', 'N', ' ', \ - 0x53, 0x01, 0x00, 0x00, - 'S', - 0x00, - 'S', - 0x04, - 'B', 'R', 'C', 'M', - 'C', - 0x06, - 'P', - 0x94, - 0x11, - 'T', - 0x01 - }; -#endif - - WL_TRACE(("\n### %s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - net_os_wake_lock(dev); - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); - goto exit_proc; - } - - - if (wrqu->data.length < (strlen(CSCAN_COMMAND) + sizeof(cscan_tlv_t))) { - WL_ERROR(("%s aggument=%d less %d\n", __FUNCTION__, \ - wrqu->data.length, strlen(CSCAN_COMMAND) + sizeof(cscan_tlv_t))); - goto exit_proc; - } - -#ifdef TLV_DEBUG - memcpy(extra, tlv_in_example, sizeof(tlv_in_example)); - wrqu->data.length = sizeof(tlv_in_example); - for (i = 0; i < wrqu->data.length; i++) - printf("%02X ", extra[i]); - printf("\n"); -#endif - - str_ptr = extra; - str_ptr += strlen(CSCAN_COMMAND); - tlv_size_left = wrqu->data.length - strlen(CSCAN_COMMAND); - - cscan_tlv_temp = (cscan_tlv_t *)str_ptr; - memset(ssids_local, 0, sizeof(ssids_local)); - - if ((cscan_tlv_temp->prefix == CSCAN_TLV_PREFIX) && \ - (cscan_tlv_temp->version == CSCAN_TLV_VERSION) && \ - (cscan_tlv_temp->subver == CSCAN_TLV_SUBVERSION)) - { - str_ptr += sizeof(cscan_tlv_t); - tlv_size_left -= sizeof(cscan_tlv_t); - - - if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local, \ - WL_SCAN_PARAMS_SSID_MAX, &tlv_size_left)) <= 0) { - WL_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid)); - goto exit_proc; - } - else { - - memset(iscan->iscan_ex_params_p, 0, iscan->iscan_ex_param_size); - - - wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, NULL); - iscan->iscan_ex_params_p->version = htod32(ISCAN_REQ_VERSION); - iscan->iscan_ex_params_p->action = htod16(WL_SCAN_ACTION_START); - iscan->iscan_ex_params_p->scan_duration = htod16(0); - - - while (tlv_size_left > 0) - { - type = str_ptr[0]; - switch (type) { - case CSCAN_TLV_TYPE_CHANNEL_IE: - - if ((nchan = wl_iw_parse_channel_list_tlv(&str_ptr, \ - &iscan->iscan_ex_params_p->params.channel_list[0], \ - WL_NUMCHANNELS, &tlv_size_left)) == -1) { - WL_ERROR(("%s missing channel list\n", \ - __FUNCTION__)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_NPROBE_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, \ - &iscan->iscan_ex_params_p->params.nprobes, \ - sizeof(iscan->iscan_ex_params_p->params.nprobes), \ - type, sizeof(char), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", \ - __FUNCTION__, res)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_ACTIVE_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, \ - &iscan->iscan_ex_params_p->params.active_time, \ - sizeof(iscan->iscan_ex_params_p->params.active_time), \ - type, sizeof(short), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", \ - __FUNCTION__, res)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_PASSIVE_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, \ - &iscan->iscan_ex_params_p->params.passive_time, \ - sizeof(iscan->iscan_ex_params_p->params.passive_time), \ - type, sizeof(short), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", \ - __FUNCTION__, res)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_HOME_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, \ - &iscan->iscan_ex_params_p->params.home_time, \ - sizeof(iscan->iscan_ex_params_p->params.home_time), \ - type, sizeof(short), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", \ - __FUNCTION__, res)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_STYPE_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, \ - &iscan->iscan_ex_params_p->params.scan_type, \ - sizeof(iscan->iscan_ex_params_p->params.scan_type), \ - type, sizeof(char), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", \ - __FUNCTION__, res)); - goto exit_proc; - } - break; - - default : - WL_ERROR(("%s get unkwown type %X\n", \ - __FUNCTION__, type)); - goto exit_proc; - break; - } - } - } - } - else { - WL_ERROR(("%s get wrong TLV command\n", __FUNCTION__)); - goto exit_proc; - } - -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan < BROADCAST_SCAN_FIRST_RESULT_CONSUMED) { - if (++g_first_counter_scans == MAX_ALLOWED_BLOCK_SCAN_FROM_FIRST_SCAN) { - - WL_ERROR(("%s Clean up First scan flag which is %d\n", \ - __FUNCTION__, g_first_broadcast_scan)); - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_CONSUMED; - } - else { - WL_ERROR(("%s Ignoring CSCAN : First Scan is not done yet %d\n", \ - __FUNCTION__, g_first_counter_scans)); - res = -EBUSY; - goto exit_proc; - } - } -#endif - - res = wl_iw_combined_scan_set(dev, ssids_local, nssid, nchan); - -exit_proc: - net_os_wake_unlock(dev); - return res; -} - -#endif - -#ifdef SOFTAP -#ifndef AP_ONLY - -static int thr_wait_for_2nd_eth_dev(void *data) -{ - struct net_device *dev = (struct net_device *)data; - wl_iw_t *iw; - int ret = 0; - unsigned long flags; - - net_os_wake_lock(dev); - - DAEMONIZE("wl0_eth_wthread"); - - WL_TRACE(("\n>%s thread started:, PID:%x\n", __FUNCTION__, current->pid)); - iw = *(wl_iw_t **)netdev_priv(dev); - if (!iw) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - ret = -1; - goto fail; - } - -#ifndef BCMSDIOH_STD - if (down_timeout(&ap_eth_sema, msecs_to_jiffies(5000)) != 0) { - WL_ERROR(("\n%s: sap_eth_sema timeout \n", __FUNCTION__)); - ret = -1; - goto fail; - } -#endif - - flags = dhd_os_spin_lock(iw->pub); - if (!ap_net_dev) { - WL_ERROR((" ap_net_dev is null !!!")); - ret = -1; - dhd_os_spin_unlock(iw->pub, flags); - goto fail; - } - - WL_TRACE(("\n>%s: Thread:'softap ethdev IF:%s is detected !!!'\n\n", - __FUNCTION__, ap_net_dev->name)); - - ap_cfg_running = TRUE; - - dhd_os_spin_unlock(iw->pub, flags); - - bcm_mdelay(500); - - wl_iw_send_priv_event(priv_dev, "AP_SET_CFG_OK"); - -fail: - WL_TRACE(("\n>%s, thread completed\n", __FUNCTION__)); - - net_os_wake_unlock(dev); - - complete_and_exit(&ap_cfg_exited, 0); - return ret; -} -#endif -#ifndef AP_ONLY -static int last_auto_channel = 6; -#endif -static int get_softap_auto_channel(struct net_device *dev, struct ap_profile *ap) -{ - int chosen = 0; - wl_uint32_list_t request; - int rescan = 0; - int retry = 0; - int updown = 0; - int ret = 0; - wlc_ssid_t null_ssid; - int res = 0; -#ifndef AP_ONLY - int iolen = 0; - int mkvar_err = 0; - int bsscfg_index = 1; - char buf[WLC_IOCTL_SMLEN]; -#endif - WL_SOFTAP(("Enter %s\n", __FUNCTION__)); - -#ifndef AP_ONLY - if (ap_cfg_running) { - ap->channel = last_auto_channel; - return res; - } -#endif - memset(&null_ssid, 0, sizeof(wlc_ssid_t)); - res |= dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown)); -#ifdef AP_ONLY - res |= dev_wlc_ioctl(dev, WLC_SET_SSID, &null_ssid, sizeof(null_ssid)); -#else - iolen = wl_bssiovar_mkbuf("ssid", bsscfg_index, (char *)(&null_ssid), \ - null_ssid.SSID_len+4, buf, sizeof(buf), &mkvar_err); - ASSERT(iolen); - res |= dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen); -#endif - auto_channel_retry: - request.count = htod32(0); - ret = dev_wlc_ioctl(dev, WLC_START_CHANNEL_SEL, &request, sizeof(request)); - if (ret < 0) { - WL_ERROR(("can't start auto channel scan\n")); - goto fail; - } - - get_channel_retry: - bcm_mdelay(500); - - ret = dev_wlc_ioctl(dev, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen)); - if (ret < 0 || dtoh32(chosen) == 0) { - if (retry++ < 3) - goto get_channel_retry; - else { - WL_ERROR(("can't get auto channel sel, err = %d, \ - chosen = %d\n", ret, chosen)); - goto fail; - } - } - if ((chosen == 1) && (!rescan++)) - goto auto_channel_retry; - WL_SOFTAP(("Set auto channel = %d\n", chosen)); - ap->channel = chosen; - if ((res = dev_wlc_ioctl(dev, WLC_DOWN, &updown, sizeof(updown))) < 0) { - WL_ERROR(("%s fail to set up err =%d\n", __FUNCTION__, res)); - goto fail; - } -#ifndef AP_ONLY - if (!res) - last_auto_channel = ap->channel; -#endif - -fail : - return res; -} - - -static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap) -{ - int updown = 0; - int channel = 0; - - wlc_ssid_t ap_ssid; - int max_assoc = 8; - - int res = 0; - int apsta_var = 0; -#ifndef AP_ONLY - int mpc = 0; - int iolen = 0; - int mkvar_err = 0; - int bsscfg_index = 1; - char buf[WLC_IOCTL_SMLEN]; -#endif - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -1; - } - - net_os_wake_lock(dev); - - WL_SOFTAP(("wl_iw: set ap profile:\n")); - WL_SOFTAP((" ssid = '%s'\n", ap->ssid)); - WL_SOFTAP((" security = '%s'\n", ap->sec)); - if (ap->key[0] != '\0') - WL_SOFTAP((" key = '%s'\n", ap->key)); - WL_SOFTAP((" channel = %d\n", ap->channel)); - WL_SOFTAP((" max scb = %d\n", ap->max_scb)); - -#ifdef AP_ONLY - if (ap_cfg_running) { - wl_iw_softap_deassoc_stations(dev, NULL); - ap_cfg_running = FALSE; - } -#endif - - if (ap_cfg_running == FALSE) { - -#ifndef AP_ONLY - sema_init(&ap_eth_sema, 0); - - mpc = 0; - if ((res = dev_wlc_intvar_set(dev, "mpc", mpc))) { - WL_ERROR(("%s fail to set mpc\n", __FUNCTION__)); - goto fail; - } -#endif - - updown = 0; - if ((res = dev_wlc_ioctl(dev, WLC_DOWN, &updown, sizeof(updown)))) { - WL_ERROR(("%s fail to set updown\n", __FUNCTION__)); - goto fail; - } - -#ifdef AP_ONLY - apsta_var = 0; - if ((res = dev_wlc_ioctl(dev, WLC_SET_AP, &apsta_var, sizeof(apsta_var)))) { - WL_ERROR(("%s fail to set apsta_var 0\n", __FUNCTION__)); - goto fail; - } - apsta_var = 1; - if ((res = dev_wlc_ioctl(dev, WLC_SET_AP, &apsta_var, sizeof(apsta_var)))) { - WL_ERROR(("%s fail to set apsta_var 1\n", __FUNCTION__)); - goto fail; - } - res = dev_wlc_ioctl(dev, WLC_GET_AP, &apsta_var, sizeof(apsta_var)); -#else - apsta_var = 1; - iolen = wl_bssiovar_mkbuf("apsta", - bsscfg_index, &apsta_var, sizeof(apsta_var)+4, - buf, sizeof(buf), &mkvar_err); - - if (iolen <= 0) - goto fail; - - if ((res = dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen)) < 0) { - WL_ERROR(("%s fail to set apsta \n", __FUNCTION__)); - goto fail; - } - WL_TRACE(("\n>in %s: apsta set result: %d \n", __FUNCTION__, res)); -#endif - - updown = 1; - if ((res = dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown))) < 0) { - WL_ERROR(("%s fail to set apsta \n", __FUNCTION__)); - goto fail; - } - - } else { - - if (!ap_net_dev) { - WL_ERROR(("%s: ap_net_dev is null\n", __FUNCTION__)); - goto fail; - } - - res = wl_iw_softap_deassoc_stations(ap_net_dev, NULL); - - - if ((res = dev_iw_write_cfg1_bss_var(dev, 0)) < 0) { - WL_ERROR(("%s fail to set bss down\n", __FUNCTION__)); - goto fail; - } - } - - if (strlen(ap->country_code)) { - WL_ERROR(("%s: Igonored: Country MUST be specified \ - COUNTRY command with \n", __FUNCTION__)); - } else { - WL_SOFTAP(("%s: Country code is not specified," - " will use Radio's default\n", - __FUNCTION__)); - } - - iolen = wl_bssiovar_mkbuf("closednet", - bsscfg_index, &ap->closednet, sizeof(ap->closednet)+4, - buf, sizeof(buf), &mkvar_err); - ASSERT(iolen); - if ((res = dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen)) < 0) { - WL_ERROR(("%s failed to set 'closednet'for apsta \n", __FUNCTION__)); - goto fail; - } - - - if ((ap->channel == 0) && (get_softap_auto_channel(dev, ap) < 0)) { - ap->channel = 1; - WL_ERROR(("%s auto channel failed, pick up channel=%d\n", \ - __FUNCTION__, ap->channel)); - } - - channel = ap->channel; - if ((res = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &channel, sizeof(channel)))) { - WL_ERROR(("%s fail to set channel\n", __FUNCTION__)); - goto fail; - } - - if (ap_cfg_running == FALSE) { - updown = 0; - if ((res = dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown)))) { - WL_ERROR(("%s fail to set up\n", __FUNCTION__)); - goto fail; - } - } - - max_assoc = ap->max_scb; - if ((res = dev_wlc_intvar_set(dev, "maxassoc", max_assoc))) { - WL_ERROR(("%s fail to set maxassoc\n", __FUNCTION__)); - goto fail; - } - - ap_ssid.SSID_len = strlen(ap->ssid); - strncpy(ap_ssid.SSID, ap->ssid, ap_ssid.SSID_len); - -#ifdef AP_ONLY - if ((res = wl_iw_set_ap_security(dev, &my_ap)) != 0) { - WL_ERROR(("ERROR:%d in:%s, wl_iw_set_ap_security is skipped\n", \ - res, __FUNCTION__)); - goto fail; - } - wl_iw_send_priv_event(dev, "ASCII_CMD=AP_BSS_START"); - ap_cfg_running = TRUE; -#else - iolen = wl_bssiovar_mkbuf("ssid", bsscfg_index, (char *)(&ap_ssid), - ap_ssid.SSID_len+4, buf, sizeof(buf), &mkvar_err); - ASSERT(iolen); - if ((res = dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen)) != 0) { - WL_ERROR(("ERROR:%d in:%s, Security & BSS reconfiguration is skipped\n", \ - res, __FUNCTION__)); - goto fail; - } - if (ap_cfg_running == FALSE) { - init_completion(&ap_cfg_exited); - ap_cfg_pid = kernel_thread(thr_wait_for_2nd_eth_dev, dev, 0); - } else { - ap_cfg_pid = -1; - if (ap_net_dev == NULL) { - WL_ERROR(("%s ERROR: ap_net_dev is NULL !!!\n", __FUNCTION__)); - goto fail; - } - - WL_ERROR(("%s: %s Configure security & restart AP bss \n", \ - __FUNCTION__, ap_net_dev->name)); - - if ((res = wl_iw_set_ap_security(ap_net_dev, &my_ap)) < 0) { - WL_ERROR(("%s fail to set security : %d\n", __FUNCTION__, res)); - goto fail; - } - - if ((res = dev_iw_write_cfg1_bss_var(dev, 1)) < 0) { - WL_ERROR(("%s fail to set bss up\n", __FUNCTION__)); - goto fail; - } - } -#endif -fail: - WL_SOFTAP(("%s exit with %d\n", __FUNCTION__, res)); - - net_os_wake_unlock(dev); - - return res; -} - - -static int wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap) -{ - int wsec = 0; - int wpa_auth = 0; - int res = 0; - int i; - char *ptr; -#ifdef AP_ONLY - int mpc = 0; - wlc_ssid_t ap_ssid; -#endif - wl_wsec_key_t key; - - WL_SOFTAP(("\nsetting SOFTAP security mode:\n")); - WL_SOFTAP(("wl_iw: set ap profile:\n")); - WL_SOFTAP((" ssid = '%s'\n", ap->ssid)); - WL_SOFTAP((" security = '%s'\n", ap->sec)); - if (ap->key[0] != '\0') { - WL_SOFTAP((" key = '%s'\n", ap->key)); - } - WL_SOFTAP((" channel = %d\n", ap->channel)); - WL_SOFTAP((" max scb = %d\n", ap->max_scb)); - - if (strnicmp(ap->sec, "open", strlen("open")) == 0) { - wsec = 0; - res = dev_wlc_intvar_set(dev, "wsec", wsec); - wpa_auth = WPA_AUTH_DISABLED; - res |= dev_wlc_intvar_set(dev, "wpa_auth", wpa_auth); - - WL_SOFTAP(("=====================\n")); - WL_SOFTAP((" wsec & wpa_auth set 'OPEN', result:&d %d\n", res)); - WL_SOFTAP(("=====================\n")); - - } else if (strnicmp(ap->sec, "wep", strlen("wep")) == 0) { - - memset(&key, 0, sizeof(key)); - - wsec = WEP_ENABLED; - res = dev_wlc_intvar_set(dev, "wsec", wsec); - - key.index = 0; - if (wl_iw_parse_wep(ap->key, &key)) { - WL_SOFTAP(("wep key parse err!\n")); - return -1; - } - - key.index = htod32(key.index); - key.len = htod32(key.len); - key.algo = htod32(key.algo); - key.flags = htod32(key.flags); - - res |= dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - - wpa_auth = WPA_AUTH_DISABLED; - res |= dev_wlc_intvar_set(dev, "wpa_auth", wpa_auth); - - WL_SOFTAP(("=====================\n")); - WL_SOFTAP((" wsec & auth set 'WEP', result:&d %d\n", res)); - WL_SOFTAP(("=====================\n")); - - } else if (strnicmp(ap->sec, "wpa2-psk", strlen("wpa2-psk")) == 0) { - wsec_pmk_t psk; - size_t key_len; - - wsec = AES_ENABLED; - dev_wlc_intvar_set(dev, "wsec", wsec); - - key_len = strlen(ap->key); - if (key_len < WSEC_MIN_PSK_LEN || key_len > WSEC_MAX_PSK_LEN) { - WL_SOFTAP(("passphrase must be between %d and %d characters long\n", - WSEC_MIN_PSK_LEN, WSEC_MAX_PSK_LEN)); - return -1; - } - - if (key_len < WSEC_MAX_PSK_LEN) { - unsigned char output[2*SHA1HashSize]; - char key_str_buf[WSEC_MAX_PSK_LEN+1]; - - memset(output, 0, sizeof(output)); - pbkdf2_sha1(ap->key, ap->ssid, strlen(ap->ssid), 4096, output, 32); - - ptr = key_str_buf; - for (i = 0; i < (WSEC_MAX_PSK_LEN/8); i++) { - sprintf(ptr, "%02x%02x%02x%02x", (uint)output[i*4], \ - (uint)output[i*4+1], (uint)output[i*4+2], \ - (uint)output[i*4+3]); - ptr += 8; - } - WL_SOFTAP(("%s: passphase = %s\n", __FUNCTION__, key_str_buf)); - - psk.key_len = htod16((ushort)WSEC_MAX_PSK_LEN); - memcpy(psk.key, key_str_buf, psk.key_len); - } else { - psk.key_len = htod16((ushort) key_len); - memcpy(psk.key, ap->key, key_len); - } - psk.flags = htod16(WSEC_PASSPHRASE); - dev_wlc_ioctl(dev, WLC_SET_WSEC_PMK, &psk, sizeof(psk)); - - wpa_auth = WPA2_AUTH_PSK; - dev_wlc_intvar_set(dev, "wpa_auth", wpa_auth); - - } else if (strnicmp(ap->sec, "wpa-psk", strlen("wpa-psk")) == 0) { - - wsec_pmk_t psk; - size_t key_len; - - wsec = TKIP_ENABLED; - res = dev_wlc_intvar_set(dev, "wsec", wsec); - - key_len = strlen(ap->key); - if (key_len < WSEC_MIN_PSK_LEN || key_len > WSEC_MAX_PSK_LEN) { - WL_SOFTAP(("passphrase must be between %d and %d characters long\n", - WSEC_MIN_PSK_LEN, WSEC_MAX_PSK_LEN)); - return -1; - } - - if (key_len < WSEC_MAX_PSK_LEN) { - unsigned char output[2*SHA1HashSize]; - char key_str_buf[WSEC_MAX_PSK_LEN+1]; - bzero(output, 2*SHA1HashSize); - - WL_SOFTAP(("%s: do passhash...\n", __FUNCTION__)); - - pbkdf2_sha1(ap->key, ap->ssid, strlen(ap->ssid), 4096, output, 32); - - ptr = key_str_buf; - for (i = 0; i < (WSEC_MAX_PSK_LEN/8); i++) { - WL_SOFTAP(("[%02d]: %08x\n", i, *((unsigned int *)&output[i*4]))); - - sprintf(ptr, "%02x%02x%02x%02x", (uint)output[i*4], - (uint)output[i*4+1], (uint)output[i*4+2], - (uint)output[i*4+3]); - ptr += 8; - } - WL_SOFTAP(("%s: passphase = %s\n", __FUNCTION__, key_str_buf)); - - psk.key_len = htod16((ushort)WSEC_MAX_PSK_LEN); - memcpy(psk.key, key_str_buf, psk.key_len); - } else { - psk.key_len = htod16((ushort) key_len); - memcpy(psk.key, ap->key, key_len); - } - - psk.flags = htod16(WSEC_PASSPHRASE); - res |= dev_wlc_ioctl(dev, WLC_SET_WSEC_PMK, &psk, sizeof(psk)); - - wpa_auth = WPA_AUTH_PSK; - res |= dev_wlc_intvar_set(dev, "wpa_auth", wpa_auth); - - WL_SOFTAP((" wsec & auth set 'wpa-psk' (TKIP), result:&d %d\n", res)); - } - -#ifdef AP_ONLY - ap_ssid.SSID_len = strlen(ap->ssid); - strncpy(ap_ssid.SSID, ap->ssid, ap_ssid.SSID_len); - res |= dev_wlc_ioctl(dev, WLC_SET_SSID, &ap_ssid, sizeof(ap_ssid)); - mpc = 0; - res |= dev_wlc_intvar_set(dev, "mpc", mpc); - if (strnicmp(ap->sec, "wep", strlen("wep")) == 0) { - res |= dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - } -#endif - return res; -} - - - -int get_parmeter_from_string( - char **str_ptr, const char *token, - int param_type, void *dst, int param_max_len) -{ - char int_str[7] = "0"; - int parm_str_len; - char *param_str_begin; - char *param_str_end; - - if ((*str_ptr) && !strncmp(*str_ptr, token, strlen(token))) { - - strsep(str_ptr, "=,"); - param_str_begin = *str_ptr; - strsep(str_ptr, "=,"); - - if (*str_ptr == NULL) { - parm_str_len = strlen(param_str_begin); - } else { - param_str_end = *str_ptr-1; - parm_str_len = param_str_end - param_str_begin; - } - - WL_TRACE((" 'token:%s', len:%d, ", token, parm_str_len)); - - if (parm_str_len > param_max_len) { - WL_TRACE((" WARNING: extracted param len:%d is > MAX:%d\n", - parm_str_len, param_max_len)); - - parm_str_len = param_max_len; - } - - switch (param_type) { - - case PTYPE_INTDEC: { - int *pdst_int = dst; - char *eptr; - - if (parm_str_len > sizeof(int_str)) - parm_str_len = sizeof(int_str); - - memcpy(int_str, param_str_begin, parm_str_len); - - *pdst_int = simple_strtoul(int_str, &eptr, 10); - - WL_TRACE((" written as integer:%d\n", *pdst_int)); - } - break; - case PTYPE_STR_HEX: { - u8 *buf = dst; - - param_max_len = param_max_len >> 1; - hstr_2_buf(param_str_begin, buf, param_max_len); - print_buf(buf, param_max_len, 0); - } - break; - default: - memcpy(dst, param_str_begin, parm_str_len); - *((char *)dst + parm_str_len) = 0; - WL_TRACE((" written as a string:%s\n", (char *)dst)); - break; - } - - return 0; - } else { - WL_ERROR(("\n %s: No token:%s in str:%s\n", - __FUNCTION__, token, *str_ptr)); - - return -1; - } -} - -static int wl_iw_softap_deassoc_stations(struct net_device *dev, u8 *mac) -{ - int i; - int res = 0; - char mac_buf[128] = {0}; - char z_mac[6] = {0, 0, 0, 0, 0, 0}; - char *sta_mac; - struct maclist *assoc_maclist = (struct maclist *) mac_buf; - bool deauth_all = false; - - if (mac == NULL) { - deauth_all = true; - sta_mac = z_mac; - } else { - sta_mac = mac; - } - - memset(assoc_maclist, 0, sizeof(mac_buf)); - assoc_maclist->count = 8; - - res = dev_wlc_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist, 128); - if (res != 0) { - WL_SOFTAP(("%s: Error:%d Couldn't get ASSOC List\n", __FUNCTION__, res)); - return res; - } - - if (assoc_maclist->count) { - for (i = 0; i < assoc_maclist->count; i++) { - scb_val_t scbval; - - scbval.val = htod32(1); - bcopy(&assoc_maclist->ea[i], &scbval.ea, ETHER_ADDR_LEN); - - if (deauth_all || (memcmp(&scbval.ea, sta_mac, ETHER_ADDR_LEN) == 0)) { - WL_SOFTAP(("%s, deauth STA:%d \n", __FUNCTION__, i)); - res |= dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, - &scbval, sizeof(scb_val_t)); - } - } - } else { - WL_SOFTAP((" STA ASSOC list is empty\n")); - } - - if (res != 0) { - WL_ERROR(("%s: Error:%d\n", __FUNCTION__, res)); - } else if (assoc_maclist->count) { - bcm_mdelay(200); - } - return res; -} - - -static int iwpriv_softap_stop(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int res = 0; - - WL_SOFTAP(("got iwpriv AP_BSS_STOP\n")); - - if ((!dev) && (!ap_net_dev)) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return res; - } - - net_os_wake_lock(dev); - - if ((ap_cfg_running == TRUE)) { -#ifdef AP_ONLY - wl_iw_softap_deassoc_stations(dev, NULL); -#else - wl_iw_softap_deassoc_stations(ap_net_dev, NULL); - - if ((res = dev_iw_write_cfg1_bss_var(dev, 2)) < 0) - WL_ERROR(("%s failed to del BSS err = %d", __FUNCTION__, res)); -#endif - - bcm_mdelay(100); - - wrqu->data.length = 0; - ap_cfg_running = FALSE; - } - else - WL_ERROR(("%s: was called when SoftAP is OFF : move on\n", __FUNCTION__)); - - WL_SOFTAP(("%s Done with %d\n", __FUNCTION__, res)); - - net_os_wake_unlock(dev); - - return res; -} - - -static int iwpriv_fw_reload(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int ret = -1; - char extra[256]; - char *fwstr = fw_path; - - WL_SOFTAP(("current firmware_path[]=%s\n", fwstr)); - - WL_TRACE((">Got FW_RELOAD cmd:" - "info->cmd:%x, info->flags:%x, u.data:%p, u.len:%d, \ - fw_path:%p, len:%d \n", - info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length, fwstr, strlen(fwstr))); - - if ((wrqu->data.length > 4) && (wrqu->data.length < sizeof(extra))) { - - char *str_ptr; - - if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) { - ret = -EFAULT; - goto exit_proc; - } - - extra[wrqu->data.length] = 8; - str_ptr = extra; - - if (get_parmeter_from_string(&str_ptr, "FW_PATH=", PTYPE_STRING, fwstr, 255) != 0) { - WL_ERROR(("Error: extracting FW_PATH='' string\n")); - goto exit_proc; - } - - if (strstr(fwstr, "apsta") != NULL) { - WL_SOFTAP(("GOT APSTA FIRMWARE\n")); - ap_fw_loaded = TRUE; - } else { - WL_SOFTAP(("GOT STA FIRMWARE\n")); - ap_fw_loaded = FALSE; - } - - WL_SOFTAP(("SET firmware_path[]=%s , str_p:%p\n", fwstr, fwstr)); - ret = 0; - } else { - WL_ERROR(("Error: ivalid param len:%d\n", wrqu->data.length)); - } - -exit_proc: - return ret; -} -#endif - -#ifdef SOFTAP -static int iwpriv_wpasupp_loop_tst(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int res = 0; - char *params = NULL; - - WL_TRACE((">Got IWPRIV wp_supp loopback cmd test:" - "info->cmd:%x, info->flags:%x, u.data:%p, u.len:%d\n", - info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (wrqu->data.length != 0) { - - if (!(params = kmalloc(wrqu->data.length+1, GFP_KERNEL))) - return -ENOMEM; - - if (copy_from_user(params, wrqu->data.pointer, wrqu->data.length)) { - kfree(params); - return -EFAULT; - } - - params[wrqu->data.length] = 0; - WL_SOFTAP(("\n>> copied from user:\n %s\n", params)); - } else { - WL_ERROR(("ERROR param length is 0\n")); - return -EFAULT; - } - - res = wl_iw_send_priv_event(dev, params); - kfree(params); - - return res; -} -#endif - - -static int -iwpriv_en_ap_bss( - struct net_device *dev, - struct iw_request_info *info, - void *wrqu, - char *extra) -{ - int res = 0; - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -1; - } - - net_os_wake_lock(dev); - - WL_SOFTAP(("%s: rcvd IWPRIV IOCTL: for dev:%s\n", __FUNCTION__, dev->name)); - -#ifndef AP_ONLY - if (ap_cfg_pid >= 0) { - wait_for_completion(&ap_cfg_exited); - ap_cfg_pid = -1; - } - - if ((res = wl_iw_set_ap_security(dev, &my_ap)) != 0) { - WL_ERROR((" %s ERROR setting SOFTAP security in :%d\n", __FUNCTION__, res)); - } - else { - if ((res = dev_iw_write_cfg1_bss_var(dev, 1)) < 0) - WL_ERROR(("%s fail to set bss up err=%d\n", __FUNCTION__, res)); - else - bcm_mdelay(100); - } - -#endif - WL_SOFTAP(("%s done with res %d \n", __FUNCTION__, res)); - - net_os_wake_unlock(dev); - - return res; -} - -static int -get_assoc_sta_list(struct net_device *dev, char *buf, int len) -{ - WL_TRACE(("%s: dev_wlc_ioctl(dev:%p, cmd:%d, buf:%p, len:%d)\n", - __FUNCTION__, dev, WLC_GET_ASSOCLIST, buf, len)); - - return dev_wlc_ioctl(dev, WLC_GET_ASSOCLIST, buf, len); - -} - - -void check_error(int res, const char *msg, const char *func, int line) -{ - if (res != 0) - WL_ERROR(("%s, %d function:%s, line:%d\n", msg, res, func, line)); -} - -static int -set_ap_mac_list(struct net_device *dev, void *buf) -{ - struct mac_list_set *mac_list_set = (struct mac_list_set *)buf; - struct maclist *maclist = (struct maclist *)&mac_list_set->mac_list; - int length; - int i; - int mac_mode = mac_list_set->mode; - int ioc_res = 0; - ap_macmode = mac_list_set->mode; - - bzero(&ap_black_list, sizeof(struct mflist)); - - if (mac_mode == MACLIST_MODE_DISABLED) { - - ioc_res = dev_wlc_ioctl(dev, WLC_SET_MACMODE, &mac_mode, sizeof(mac_mode)); - check_error(ioc_res, "ioctl ERROR:", __FUNCTION__, __LINE__); - WL_SOFTAP(("%s: MAC filtering disabled\n", __FUNCTION__)); - } else { - - scb_val_t scbval; - char mac_buf[256] = {0}; - struct maclist *assoc_maclist = (struct maclist *) mac_buf; - - bcopy(maclist, &ap_black_list, sizeof(ap_black_list)); - - ioc_res = dev_wlc_ioctl(dev, WLC_SET_MACMODE, &mac_mode, sizeof(mac_mode)); - check_error(ioc_res, "ioctl ERROR:", __FUNCTION__, __LINE__); - - length = sizeof(maclist->count) + maclist->count*ETHER_ADDR_LEN; - dev_wlc_ioctl(dev, WLC_SET_MACLIST, maclist, length); - - WL_SOFTAP(("%s: applied MAC List, mode:%d, length %d:\n", - __FUNCTION__, mac_mode, length)); - for (i = 0; i < maclist->count; i++) - WL_SOFTAP(("mac %d: %02X:%02X:%02X:%02X:%02X:%02X\n", - i, maclist->ea[i].octet[0], maclist->ea[i].octet[1], \ - maclist->ea[i].octet[2], \ - maclist->ea[i].octet[3], maclist->ea[i].octet[4], \ - maclist->ea[i].octet[5])); - - assoc_maclist->count = 8; - ioc_res = dev_wlc_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist, 256); - check_error(ioc_res, "ioctl ERROR:", __FUNCTION__, __LINE__); - WL_SOFTAP((" Cur assoc clients:%d\n", assoc_maclist->count)); - - if (assoc_maclist->count) - for (i = 0; i < assoc_maclist->count; i++) { - int j; - bool assoc_mac_matched = false; - - WL_SOFTAP(("\n Cheking assoc STA: ")); - print_buf(&assoc_maclist->ea[i], 6, 7); - WL_SOFTAP(("with the b/w list:")); - - for (j = 0; j < maclist->count; j++) - if (!bcmp(&assoc_maclist->ea[i], &maclist->ea[j], - ETHER_ADDR_LEN)) { - - assoc_mac_matched = true; - break; - } - - if (((mac_mode == MACLIST_MODE_ALLOW) && !assoc_mac_matched) || - ((mac_mode == MACLIST_MODE_DENY) && assoc_mac_matched)) { - - WL_SOFTAP(("b-match or w-mismatch," - " do deauth/disassoc \n")); - scbval.val = htod32(1); - bcopy(&assoc_maclist->ea[i], &scbval.ea, \ - ETHER_ADDR_LEN); - ioc_res = dev_wlc_ioctl(dev, - WLC_SCB_DEAUTHENTICATE_FOR_REASON, - &scbval, sizeof(scb_val_t)); - check_error(ioc_res, - "ioctl ERROR:", - __FUNCTION__, __LINE__); - - } else { - WL_SOFTAP((" no b/w list hits, let it be\n")); - } - } else { - WL_SOFTAP(("No ASSOC CLIENTS\n")); - } - } - - WL_SOFTAP(("%s iocres:%d\n", __FUNCTION__, ioc_res)); - return ioc_res; -} -#endif - - -#ifdef SOFTAP -int set_macfilt_from_string(struct mflist *pmflist, char **param_str) -{ - return 0; -} -#endif - - -#ifdef SOFTAP -#define PARAM_OFFSET PROFILE_OFFSET - -int wl_iw_process_private_ascii_cmd( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *dwrq, - char *cmd_str) -{ - int ret = 0; - char *sub_cmd = cmd_str + PROFILE_OFFSET + strlen("ASCII_CMD="); - - WL_SOFTAP(("\n %s: ASCII_CMD: offs_0:%s, offset_32:\n'%s'\n", - __FUNCTION__, cmd_str, cmd_str + PROFILE_OFFSET)); - - if (strnicmp(sub_cmd, "AP_CFG", strlen("AP_CFG")) == 0) { - - WL_SOFTAP((" AP_CFG \n")); - - - if (init_ap_profile_from_string(cmd_str+PROFILE_OFFSET, &my_ap) != 0) { - WL_ERROR(("ERROR: SoftAP CFG prams !\n")); - ret = -1; - } else { - ret = set_ap_cfg(dev, &my_ap); - } - - } else if (strnicmp(sub_cmd, "AP_BSS_START", strlen("AP_BSS_START")) == 0) { - - WL_SOFTAP(("\n SOFTAP - ENABLE BSS \n")); - - WL_SOFTAP(("\n!!! got 'WL_AP_EN_BSS' from WPA supplicant, dev:%s\n", dev->name)); - -#ifndef AP_ONLY - if (ap_net_dev == NULL) { - printf("\n ERROR: SOFTAP net_dev* is NULL !!!\n"); - } else { - if ((ret = iwpriv_en_ap_bss(ap_net_dev, info, dwrq, cmd_str)) < 0) - WL_ERROR(("%s line %d fail to set bss up\n", \ - __FUNCTION__, __LINE__)); - } -#else - if ((ret = iwpriv_en_ap_bss(dev, info, dwrq, cmd_str)) < 0) - WL_ERROR(("%s line %d fail to set bss up\n", \ - __FUNCTION__, __LINE__)); -#endif - } else if (strnicmp(sub_cmd, "ASSOC_LST", strlen("ASSOC_LST")) == 0) { - /* no code yet */ - } else if (strnicmp(sub_cmd, "AP_BSS_STOP", strlen("AP_BSS_STOP")) == 0) { - WL_SOFTAP((" \n temp DOWN SOFTAP\n")); -#ifndef AP_ONLY - if ((ret = dev_iw_write_cfg1_bss_var(dev, 0)) < 0) { - WL_ERROR(("%s line %d fail to set bss down\n", \ - __FUNCTION__, __LINE__)); - } -#endif - } - - return ret; -} -#endif - -static int wl_iw_set_priv( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *ext -) -{ - int ret = 0; - char * extra; - - if (!(extra = kmalloc(dwrq->length, GFP_KERNEL))) - return -ENOMEM; - - if (copy_from_user(extra, dwrq->pointer, dwrq->length)) { - kfree(extra); - return -EFAULT; - } - - WL_TRACE(("%s: SIOCSIWPRIV request %s, info->cmd:%x, info->flags:%d\n dwrq->length:%d", - dev->name, extra, info->cmd, info->flags, dwrq->length)); - - net_os_wake_lock(dev); - - if (dwrq->length && extra) { - if (strnicmp(extra, "START", strlen("START")) == 0) { - wl_iw_control_wl_on(dev, info); - WL_TRACE(("%s, Received regular START command\n", __FUNCTION__)); - } - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s, missing START, Fail\n", __FUNCTION__)); - kfree(extra); - net_os_wake_unlock(dev); - return -EFAULT; - } - - if (strnicmp(extra, "SCAN-ACTIVE", strlen("SCAN-ACTIVE")) == 0) { -#ifdef ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS - WL_TRACE(("%s: active scan setting suppressed\n", dev->name)); -#else - ret = wl_iw_set_active_scan(dev, info, (union iwreq_data *)dwrq, extra); -#endif - } else if (strnicmp(extra, "SCAN-PASSIVE", strlen("SCAN-PASSIVE")) == 0) -#ifdef ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS - WL_TRACE(("%s: passive scan setting suppressed\n", dev->name)); -#else - ret = wl_iw_set_passive_scan(dev, info, (union iwreq_data *)dwrq, extra); -#endif - else if (strnicmp(extra, "RSSI", strlen("RSSI")) == 0) - ret = wl_iw_get_rssi(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "LINKSPEED", strlen("LINKSPEED")) == 0) - ret = wl_iw_get_link_speed(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "MACADDR", strlen("MACADDR")) == 0) - ret = wl_iw_get_macaddr(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "COUNTRY", strlen("COUNTRY")) == 0) - ret = wl_iw_set_country(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "STOP", strlen("STOP")) == 0) - ret = wl_iw_control_wl_off(dev, info); - else if (strnicmp(extra, BAND_GET_CMD, strlen(BAND_GET_CMD)) == 0) - ret = wl_iw_get_band(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, BAND_SET_CMD, strlen(BAND_SET_CMD)) == 0) - ret = wl_iw_set_band(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, DTIM_SKIP_GET_CMD, strlen(DTIM_SKIP_GET_CMD)) == 0) - ret = wl_iw_get_dtim_skip(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, DTIM_SKIP_SET_CMD, strlen(DTIM_SKIP_SET_CMD)) == 0) - ret = wl_iw_set_dtim_skip(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, SETSUSPEND_CMD, strlen(SETSUSPEND_CMD)) == 0) - ret = wl_iw_set_suspend(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, TXPOWER_SET_CMD, strlen(TXPOWER_SET_CMD)) == 0) - ret = wl_iw_set_txpower(dev, info, (union iwreq_data *)dwrq, extra); -#if defined(PNO_SUPPORT) - else if (strnicmp(extra, PNOSSIDCLR_SET_CMD, strlen(PNOSSIDCLR_SET_CMD)) == 0) - ret = wl_iw_set_pno_reset(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, PNOSETUP_SET_CMD, strlen(PNOSETUP_SET_CMD)) == 0) - ret = wl_iw_set_pno_set(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, PNOENABLE_SET_CMD, strlen(PNOENABLE_SET_CMD)) == 0) - ret = wl_iw_set_pno_enable(dev, info, (union iwreq_data *)dwrq, extra); -#endif -#if defined(CSCAN) - else if (strnicmp(extra, CSCAN_COMMAND, strlen(CSCAN_COMMAND)) == 0) - ret = wl_iw_set_cscan(dev, info, (union iwreq_data *)dwrq, extra); -#endif -#ifdef CUSTOMER_HW2 - else if (strnicmp(extra, "POWERMODE", strlen("POWERMODE")) == 0) - ret = wl_iw_set_power_mode(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "BTCOEXMODE", strlen("BTCOEXMODE")) == 0) { - WL_TRACE_COEX(("%s:got Framwrork cmd: 'BTCOEXMODE'\n", __FUNCTION__)); - ret = wl_iw_set_btcoex_dhcp(dev, info, (union iwreq_data *)dwrq, extra); - } -#else - else if (strnicmp(extra, "POWERMODE", strlen("POWERMODE")) == 0) - ret = wl_iw_set_btcoex_dhcp(dev, info, (union iwreq_data *)dwrq, extra); -#endif - else if (strnicmp(extra, "GETPOWER", strlen("GETPOWER")) == 0) - ret = wl_iw_get_power_mode(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, RXFILTER_START_CMD, strlen(RXFILTER_START_CMD)) == 0) - ret = net_os_set_packet_filter(dev, 1); - else if (strnicmp(extra, RXFILTER_STOP_CMD, strlen(RXFILTER_STOP_CMD)) == 0) - ret = net_os_set_packet_filter(dev, 0); - else if (strnicmp(extra, RXFILTER_ADD_CMD, strlen(RXFILTER_ADD_CMD)) == 0) { - int filter_num = *(extra + strlen(RXFILTER_ADD_CMD) + 1) - '0'; - ret = net_os_rxfilter_add_remove(dev, TRUE, filter_num); - } - else if (strnicmp(extra, RXFILTER_REMOVE_CMD, strlen(RXFILTER_REMOVE_CMD)) == 0) { - int filter_num = *(extra + strlen(RXFILTER_REMOVE_CMD) + 1) - '0'; - ret = net_os_rxfilter_add_remove(dev, FALSE, filter_num); - } -#ifdef SOFTAP -#ifdef SOFTAP_TLV_CFG - else if (strnicmp(extra, SOFTAP_SET_CMD, strlen(SOFTAP_SET_CMD)) == 0) { - wl_iw_softap_cfg_tlv(dev, info, (union iwreq_data *)dwrq, extra); - } -#endif - else if (strnicmp(extra, "ASCII_CMD", strlen("ASCII_CMD")) == 0) { - wl_iw_process_private_ascii_cmd(dev, info, (union iwreq_data *)dwrq, extra); - } else if (strnicmp(extra, "AP_MAC_LIST_SET", strlen("AP_MAC_LIST_SET")) == 0) { - WL_SOFTAP(("penguin, set AP_MAC_LIST_SET\n")); - set_ap_mac_list(dev, (extra + PROFILE_OFFSET)); - } -#endif - else { - WL_TRACE(("Unknown PRIVATE command: %s: ignored\n", extra)); - snprintf(extra, MAX_WX_STRING, "OK"); - dwrq->length = strlen("OK") + 1; - } - } - - net_os_wake_unlock(dev); - - if (extra) { - if (copy_to_user(dwrq->pointer, extra, dwrq->length)) { - kfree(extra); - return -EFAULT; - } - - kfree(extra); - } - - return ret; -} - -static const iw_handler wl_iw_handler[] = -{ - (iw_handler) wl_iw_config_commit, - (iw_handler) wl_iw_get_name, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_freq, - (iw_handler) wl_iw_get_freq, - (iw_handler) wl_iw_set_mode, - (iw_handler) wl_iw_get_mode, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_get_range, - (iw_handler) wl_iw_set_priv, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_spy, - (iw_handler) wl_iw_get_spy, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_wap, - (iw_handler) wl_iw_get_wap, -#if WIRELESS_EXT > 17 - (iw_handler) wl_iw_mlme, -#else - (iw_handler) NULL, -#endif -#if defined(WL_IW_USE_ISCAN) - (iw_handler) wl_iw_iscan_get_aplist, -#else - (iw_handler) wl_iw_get_aplist, -#endif -#if WIRELESS_EXT > 13 -#if defined(WL_IW_USE_ISCAN) - (iw_handler) wl_iw_iscan_set_scan, - (iw_handler) wl_iw_iscan_get_scan, -#else - (iw_handler) wl_iw_set_scan, - (iw_handler) wl_iw_get_scan, -#endif -#else - (iw_handler) NULL, - (iw_handler) NULL, -#endif - (iw_handler) wl_iw_set_essid, - (iw_handler) wl_iw_get_essid, - (iw_handler) wl_iw_set_nick, - (iw_handler) wl_iw_get_nick, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_rate, - (iw_handler) wl_iw_get_rate, - (iw_handler) wl_iw_set_rts, - (iw_handler) wl_iw_get_rts, - (iw_handler) wl_iw_set_frag, - (iw_handler) wl_iw_get_frag, - (iw_handler) wl_iw_set_txpow, - (iw_handler) wl_iw_get_txpow, -#if WIRELESS_EXT > 10 - (iw_handler) wl_iw_set_retry, - (iw_handler) wl_iw_get_retry, -#endif - (iw_handler) wl_iw_set_encode, - (iw_handler) wl_iw_get_encode, - (iw_handler) wl_iw_set_power, - (iw_handler) wl_iw_get_power, -#if WIRELESS_EXT > 17 - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_wpaie, - (iw_handler) wl_iw_get_wpaie, - (iw_handler) wl_iw_set_wpaauth, - (iw_handler) wl_iw_get_wpaauth, - (iw_handler) wl_iw_set_encodeext, - (iw_handler) wl_iw_get_encodeext, -#ifdef BCMWPA2 - (iw_handler) wl_iw_set_pmksa, -#endif -#endif -}; - -#if WIRELESS_EXT > 12 -static const iw_handler wl_iw_priv_handler[] = { - NULL, - (iw_handler)wl_iw_set_active_scan, - NULL, - (iw_handler)wl_iw_get_rssi, - NULL, - (iw_handler)wl_iw_set_passive_scan, - NULL, - (iw_handler)wl_iw_get_link_speed, - NULL, - (iw_handler)wl_iw_get_macaddr, - NULL, - (iw_handler)wl_iw_control_wl_off, - NULL, - (iw_handler)wl_iw_control_wl_on, -#ifdef SOFTAP - NULL, - (iw_handler)iwpriv_set_ap_config, - - NULL, - (iw_handler)iwpriv_get_assoc_list, - - NULL, - (iw_handler)iwpriv_set_mac_filters, - - NULL, - (iw_handler)iwpriv_en_ap_bss, - - NULL, - (iw_handler)iwpriv_wpasupp_loop_tst, - - NULL, - (iw_handler)iwpriv_softap_stop, - - NULL, - (iw_handler)iwpriv_fw_reload, - - NULL, - (iw_handler)iwpriv_set_ap_sta_disassoc, -#endif -#if defined(CSCAN) - - NULL, - (iw_handler)iwpriv_set_cscan -#endif -}; - -static const struct iw_priv_args wl_iw_priv_args[] = { - { - WL_IW_SET_ACTIVE_SCAN, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "SCAN-ACTIVE" - }, - { - WL_IW_GET_RSSI, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "RSSI" - }, - { - WL_IW_SET_PASSIVE_SCAN, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "SCAN-PASSIVE" - }, - { - WL_IW_GET_LINK_SPEED, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "LINKSPEED" - }, - { - WL_IW_GET_CURR_MACADDR, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "Macaddr" - }, - { - WL_IW_SET_STOP, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "STOP" - }, - { - WL_IW_SET_START, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "START" - }, - -#ifdef SOFTAP - { - WL_SET_AP_CFG, - IW_PRIV_TYPE_CHAR | 256, - 0, - "AP_SET_CFG" - }, - - { - WL_AP_STA_LIST, - IW_PRIV_TYPE_CHAR | 0, - IW_PRIV_TYPE_CHAR | 1024, - "AP_GET_STA_LIST" - }, - - { - WL_AP_MAC_FLTR, - IW_PRIV_TYPE_CHAR | 256, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - "AP_SET_MAC_FLTR" - }, - - { - WL_AP_BSS_START, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "AP_BSS_START" - }, - - { - AP_LPB_CMD, - IW_PRIV_TYPE_CHAR | 256, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - "AP_LPB_CMD" - }, - - { - WL_AP_STOP, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - "AP_BSS_STOP" - }, - - { - WL_FW_RELOAD, - IW_PRIV_TYPE_CHAR | 256, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - "WL_FW_RELOAD" - }, - - { - WL_AP_STA_DISASSOC, - IW_PRIV_TYPE_CHAR | 256, - IW_PRIV_TYPE_CHAR | 0, - "AP_STA_DISASSOC" - }, -#endif -#if defined(CSCAN) - { - WL_COMBO_SCAN, - IW_PRIV_TYPE_CHAR | 1024, - 0, - "CSCAN" - }, -#endif -}; - -const struct iw_handler_def wl_iw_handler_def = -{ - .num_standard = ARRAYSIZE(wl_iw_handler), - .standard = (iw_handler *) wl_iw_handler, - .num_private = ARRAYSIZE(wl_iw_priv_handler), - .num_private_args = ARRAY_SIZE(wl_iw_priv_args), - .private = (iw_handler *)wl_iw_priv_handler, - .private_args = (void *) wl_iw_priv_args, - -#if WIRELESS_EXT >= 19 - get_wireless_stats: dhd_get_wireless_stats, -#endif -}; -#endif - - -int wl_iw_ioctl( - struct net_device *dev, - struct ifreq *rq, - int cmd -) -{ - struct iwreq *wrq = (struct iwreq *) rq; - struct iw_request_info info; - iw_handler handler; - char *extra = NULL; - int token_size = 1, max_tokens = 0, ret = 0; - - net_os_wake_lock(dev); - - WL_TRACE(("%s: cmd:%x alled via dhd->do_ioctl()entry point\n", __FUNCTION__, cmd)); - if (cmd < SIOCIWFIRST || - IW_IOCTL_IDX(cmd) >= ARRAYSIZE(wl_iw_handler) || - !(handler = wl_iw_handler[IW_IOCTL_IDX(cmd)])) { - WL_ERROR(("%s: error in cmd=%x : not supported\n", __FUNCTION__, cmd)); - net_os_wake_unlock(dev); - return -EOPNOTSUPP; - } - - switch (cmd) { - - case SIOCSIWESSID: - case SIOCGIWESSID: - case SIOCSIWNICKN: - case SIOCGIWNICKN: - max_tokens = IW_ESSID_MAX_SIZE + 1; - break; - - case SIOCSIWENCODE: - case SIOCGIWENCODE: -#if WIRELESS_EXT > 17 - case SIOCSIWENCODEEXT: - case SIOCGIWENCODEEXT: -#endif - max_tokens = wrq->u.data.length; - break; - - case SIOCGIWRANGE: - max_tokens = sizeof(struct iw_range) + 500; - break; - - case SIOCGIWAPLIST: - token_size = sizeof(struct sockaddr) + sizeof(struct iw_quality); - max_tokens = IW_MAX_AP; - break; - -#if WIRELESS_EXT > 13 - case SIOCGIWSCAN: -#if defined(WL_IW_USE_ISCAN) - if (g_iscan) - max_tokens = wrq->u.data.length; - else -#endif - max_tokens = IW_SCAN_MAX_DATA; - break; -#endif - - case SIOCSIWSPY: - token_size = sizeof(struct sockaddr); - max_tokens = IW_MAX_SPY; - break; - - case SIOCGIWSPY: - token_size = sizeof(struct sockaddr) + sizeof(struct iw_quality); - max_tokens = IW_MAX_SPY; - break; - -#if WIRELESS_EXT > 17 - case SIOCSIWPMKSA: - case SIOCSIWGENIE: -#endif - case SIOCSIWPRIV: - max_tokens = wrq->u.data.length; - break; - } - - if (max_tokens && wrq->u.data.pointer) { - if (wrq->u.data.length > max_tokens) { - WL_ERROR(("%s: error in cmd=%x wrq->u.data.length=%d > max_tokens=%d\n", \ - __FUNCTION__, cmd, wrq->u.data.length, max_tokens)); - ret = -E2BIG; - goto wl_iw_ioctl_done; - } - if (!(extra = kmalloc(max_tokens * token_size, GFP_KERNEL))) { - ret = -ENOMEM; - goto wl_iw_ioctl_done; - } - - if (copy_from_user(extra, wrq->u.data.pointer, wrq->u.data.length * token_size)) { - kfree(extra); - ret = -EFAULT; - goto wl_iw_ioctl_done; - } - } - - info.cmd = cmd; - info.flags = 0; - - ret = handler(dev, &info, &wrq->u, extra); - - if (extra) { - if (copy_to_user(wrq->u.data.pointer, extra, wrq->u.data.length * token_size)) { - kfree(extra); - ret = -EFAULT; - goto wl_iw_ioctl_done; - } - - kfree(extra); - } - -wl_iw_ioctl_done: - - net_os_wake_unlock(dev); - - return ret; -} - - -bool -wl_iw_conn_status_str(uint32 event_type, uint32 status, uint32 reason, - char* stringBuf, uint buflen) -{ - typedef struct conn_fail_event_map_t { - uint32 inEvent; - uint32 inStatus; - uint32 inReason; - const char* outName; - const char* outCause; - } conn_fail_event_map_t; - - -# define WL_IW_DONT_CARE 9999 - const conn_fail_event_map_t event_map [] = { - - - {WLC_E_SET_SSID, WLC_E_STATUS_SUCCESS, WL_IW_DONT_CARE, - "Conn", "Success"}, - {WLC_E_SET_SSID, WLC_E_STATUS_NO_NETWORKS, WL_IW_DONT_CARE, - "Conn", "NoNetworks"}, - {WLC_E_SET_SSID, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE, - "Conn", "ConfigMismatch"}, - {WLC_E_PRUNE, WL_IW_DONT_CARE, WLC_E_PRUNE_ENCR_MISMATCH, - "Conn", "EncrypMismatch"}, - {WLC_E_PRUNE, WL_IW_DONT_CARE, WLC_E_RSN_MISMATCH, - "Conn", "RsnMismatch"}, - {WLC_E_AUTH, WLC_E_STATUS_TIMEOUT, WL_IW_DONT_CARE, - "Conn", "AuthTimeout"}, - {WLC_E_AUTH, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE, - "Conn", "AuthFail"}, - {WLC_E_AUTH, WLC_E_STATUS_NO_ACK, WL_IW_DONT_CARE, - "Conn", "AuthNoAck"}, - {WLC_E_REASSOC, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE, - "Conn", "ReassocFail"}, - {WLC_E_REASSOC, WLC_E_STATUS_TIMEOUT, WL_IW_DONT_CARE, - "Conn", "ReassocTimeout"}, - {WLC_E_REASSOC, WLC_E_STATUS_ABORT, WL_IW_DONT_CARE, - "Conn", "ReassocAbort"}, - {WLC_E_PSK_SUP, WLC_SUP_KEYED, WL_IW_DONT_CARE, - "Sup", "ConnSuccess"}, - {WLC_E_PSK_SUP, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Sup", "WpaHandshakeFail"}, - {WLC_E_DEAUTH_IND, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Conn", "Deauth"}, - {WLC_E_DISASSOC_IND, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Conn", "DisassocInd"}, - {WLC_E_DISASSOC, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Conn", "Disassoc"} - }; - - const char* name = ""; - const char* cause = NULL; - int i; - - - for (i = 0; i < sizeof(event_map)/sizeof(event_map[0]); i++) { - const conn_fail_event_map_t* row = &event_map[i]; - if (row->inEvent == event_type && - (row->inStatus == status || row->inStatus == WL_IW_DONT_CARE) && - (row->inReason == reason || row->inReason == WL_IW_DONT_CARE)) { - name = row->outName; - cause = row->outCause; - break; - } - } - - - if (cause) { - memset(stringBuf, 0, buflen); - snprintf(stringBuf, buflen, "%s %s %02d %02d", - name, cause, status, reason); - WL_INFORM(("Connection status: %s\n", stringBuf)); - return TRUE; - } else { - return FALSE; - } -} - -#if WIRELESS_EXT > 14 - -static bool -wl_iw_check_conn_fail(wl_event_msg_t *e, char* stringBuf, uint buflen) -{ - uint32 event = ntoh32(e->event_type); - uint32 status = ntoh32(e->status); - uint32 reason = ntoh32(e->reason); - - if (wl_iw_conn_status_str(event, status, reason, stringBuf, buflen)) { - return TRUE; - } - else - return FALSE; -} -#endif - -#ifndef IW_CUSTOM_MAX -#define IW_CUSTOM_MAX 256 -#endif - -void -wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data) -{ -#if WIRELESS_EXT > 13 - union iwreq_data wrqu; - char extra[IW_CUSTOM_MAX + 1]; - int cmd = 0; - uint32 event_type = ntoh32(e->event_type); - uint16 flags = ntoh16(e->flags); - uint32 datalen = ntoh32(e->datalen); - uint32 status = ntoh32(e->status); - uint32 toto; -#if defined(ROAM_NOT_USED) - static uint32 roam_no_success = 0; - static bool roam_no_success_send = FALSE; -#endif - memset(&wrqu, 0, sizeof(wrqu)); - memset(extra, 0, sizeof(extra)); - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return; - } - - net_os_wake_lock(dev); - - WL_TRACE(("%s: dev=%s event=%d \n", __FUNCTION__, dev->name, event_type)); - - switch (event_type) { - - case WLC_E_RELOAD: - WL_ERROR(("%s: Firmware ERROR %d\n", __FUNCTION__, status)); - net_os_send_hang_message(dev); - goto wl_iw_event_end; - -#if defined(SOFTAP) - case WLC_E_PRUNE: - if (ap_cfg_running) { - char *macaddr = (char *)&e->addr; - WL_SOFTAP(("PRUNE received, %02X:%02X:%02X:%02X:%02X:%02X!\n", - macaddr[0], macaddr[1], macaddr[2], macaddr[3], \ - macaddr[4], macaddr[5])); - - if (ap_macmode) { - int i; - for (i = 0; i < ap_black_list.count; i++) { - if (!bcmp(macaddr, &ap_black_list.ea[i], \ - sizeof(struct ether_addr))) { - WL_SOFTAP(("mac in black list, ignore it\n")); - break; - } - } - - if (i == ap_black_list.count) { - char mac_buf[32] = {0}; - sprintf(mac_buf, "STA_BLOCK %02X:%02X:%02X:%02X:%02X:%02X", - macaddr[0], macaddr[1], macaddr[2], - macaddr[3], macaddr[4], macaddr[5]); - wl_iw_send_priv_event(priv_dev, mac_buf); - } - } - } - break; -#endif - case WLC_E_TXFAIL: - cmd = IWEVTXDROP; - memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - break; -#if WIRELESS_EXT > 14 - case WLC_E_JOIN: - case WLC_E_ASSOC_IND: - case WLC_E_REASSOC_IND: -#if defined(SOFTAP) - WL_SOFTAP(("STA connect received %d\n", event_type)); - if (ap_cfg_running) { - wl_iw_send_priv_event(priv_dev, "STA_JOIN"); - goto wl_iw_event_end; - } -#endif - memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - cmd = IWEVREGISTERED; - break; - case WLC_E_ROAM: - if (status == WLC_E_STATUS_SUCCESS) { - WL_ASSOC(("%s: WLC_E_ROAM: success\n", __FUNCTION__)); -#if defined(ROAM_NOT_USED) - roam_no_success_send = FALSE; - roam_no_success = 0; -#endif - goto wl_iw_event_end; - } -#if defined(ROAM_NOT_USED) - else if (status == WLC_E_STATUS_NO_NETWORKS) { - roam_no_success++; - if ((roam_no_success == 5) && (roam_no_success_send == FALSE)) { - roam_no_success_send = TRUE; - bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN); - bzero(&extra, ETHER_ADDR_LEN); - cmd = SIOCGIWAP; - WL_ERROR(("%s ROAMING did not succeeded , send Link Down\n", \ - __FUNCTION__)); - } else { - WL_TRACE(("##### ROAMING did not succeeded %d\n", roam_no_success)); - goto wl_iw_event_end; - } - } -#endif - break; - case WLC_E_DEAUTH_IND: - case WLC_E_DISASSOC_IND: -#if defined(SOFTAP) - WL_SOFTAP(("STA disconnect received %d\n", event_type)); - if (ap_cfg_running) { - wl_iw_send_priv_event(priv_dev, "STA_LEAVE"); - goto wl_iw_event_end; - } -#endif - cmd = SIOCGIWAP; - bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - bzero(&extra, ETHER_ADDR_LEN); - break; - case WLC_E_LINK: - case WLC_E_NDIS_LINK: - cmd = SIOCGIWAP; - if (!(flags & WLC_EVENT_MSG_LINK)) { -#ifdef SOFTAP -#ifdef AP_ONLY - if (ap_cfg_running) { -#else - if (ap_cfg_running && !strncmp(dev->name, "wl0.1", 5)) { -#endif - WL_SOFTAP(("AP DOWN %d\n", event_type)); - wl_iw_send_priv_event(priv_dev, "AP_DOWN"); - } else { - WL_TRACE(("STA_Link Down\n")); - g_ss_cache_ctrl.m_link_down = 1; - } -#else - g_ss_cache_ctrl.m_link_down = 1; -#endif - WL_TRACE(("Link Down\n")); - - bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN); - bzero(&extra, ETHER_ADDR_LEN); - } - else { - memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN); - g_ss_cache_ctrl.m_link_down = 0; - - memcpy(g_ss_cache_ctrl.m_active_bssid, &e->addr, ETHER_ADDR_LEN); - -#ifdef SOFTAP -#ifdef AP_ONLY - if (ap_cfg_running) { -#else - if (ap_cfg_running && !strncmp(dev->name, "wl0.1", 5)) { -#endif - WL_SOFTAP(("AP UP %d\n", event_type)); - wl_iw_send_priv_event(priv_dev, "AP_UP"); - } else { - WL_TRACE(("STA_LINK_UP\n")); -#if defined(ROAM_NOT_USED) - roam_no_success_send = FALSE; - roam_no_success = 0; -#endif - } -#endif - WL_TRACE(("Link UP\n")); - - } - net_os_wake_lock_timeout_enable(dev); - wrqu.addr.sa_family = ARPHRD_ETHER; - break; - case WLC_E_ACTION_FRAME: - cmd = IWEVCUSTOM; - if (datalen + 1 <= sizeof(extra)) { - wrqu.data.length = datalen + 1; - extra[0] = WLC_E_ACTION_FRAME; - memcpy(&extra[1], data, datalen); - WL_TRACE(("WLC_E_ACTION_FRAME len %d \n", wrqu.data.length)); - } - break; - - case WLC_E_ACTION_FRAME_COMPLETE: - cmd = IWEVCUSTOM; - memcpy(&toto, data, 4); - if (sizeof(status) + 1 <= sizeof(extra)) { - wrqu.data.length = sizeof(status) + 1; - extra[0] = WLC_E_ACTION_FRAME_COMPLETE; - memcpy(&extra[1], &status, sizeof(status)); - printf("wl_iw_event status %d PacketId %d \n", status, toto); - printf("WLC_E_ACTION_FRAME_COMPLETE len %d \n", wrqu.data.length); - } - break; -#endif -#if WIRELESS_EXT > 17 - case WLC_E_MIC_ERROR: { - struct iw_michaelmicfailure *micerrevt = (struct iw_michaelmicfailure *)&extra; - cmd = IWEVMICHAELMICFAILURE; - wrqu.data.length = sizeof(struct iw_michaelmicfailure); - if (flags & WLC_EVENT_MSG_GROUP) - micerrevt->flags |= IW_MICFAILURE_GROUP; - else - micerrevt->flags |= IW_MICFAILURE_PAIRWISE; - memcpy(micerrevt->src_addr.sa_data, &e->addr, ETHER_ADDR_LEN); - micerrevt->src_addr.sa_family = ARPHRD_ETHER; - - break; - } -#ifdef BCMWPA2 - case WLC_E_PMKID_CACHE: { - if (data) - { - struct iw_pmkid_cand *iwpmkidcand = (struct iw_pmkid_cand *)&extra; - pmkid_cand_list_t *pmkcandlist; - pmkid_cand_t *pmkidcand; - int count; - - cmd = IWEVPMKIDCAND; - pmkcandlist = data; - count = ntoh32_ua((uint8 *)&pmkcandlist->npmkid_cand); - ASSERT(count >= 0); - wrqu.data.length = sizeof(struct iw_pmkid_cand); - pmkidcand = pmkcandlist->pmkid_cand; - while (count) { - bzero(iwpmkidcand, sizeof(struct iw_pmkid_cand)); - if (pmkidcand->preauth) - iwpmkidcand->flags |= IW_PMKID_CAND_PREAUTH; - bcopy(&pmkidcand->BSSID, &iwpmkidcand->bssid.sa_data, - ETHER_ADDR_LEN); -#ifndef SANDGATE2G - wireless_send_event(dev, cmd, &wrqu, extra); -#endif - pmkidcand++; - count--; - } - } - goto wl_iw_event_end; - } -#endif -#endif - - case WLC_E_SCAN_COMPLETE: -#if defined(WL_IW_USE_ISCAN) - if ((g_iscan) && (g_iscan->sysioc_pid >= 0) && - (g_iscan->iscan_state != ISCAN_STATE_IDLE)) - { - up(&g_iscan->sysioc_sem); - } else { - cmd = SIOCGIWSCAN; - wrqu.data.length = strlen(extra); - WL_TRACE(("Event WLC_E_SCAN_COMPLETE from specific scan %d\n", \ - g_iscan->iscan_state)); - } -#else - cmd = SIOCGIWSCAN; - wrqu.data.length = strlen(extra); - WL_TRACE(("Event WLC_E_SCAN_COMPLETE\n")); -#endif - break; - - case WLC_E_PFN_NET_FOUND: - { - wlc_ssid_t * ssid; - ssid = (wlc_ssid_t *)data; - WL_TRACE(("%s Event WLC_E_PFN_NET_FOUND, send %s up : find %s len=%d\n", \ - __FUNCTION__, PNO_EVENT_UP, ssid->SSID, ssid->SSID_len)); - net_os_wake_lock_timeout_enable(dev); - cmd = IWEVCUSTOM; - memset(&wrqu, 0, sizeof(wrqu)); - strcpy(extra, PNO_EVENT_UP); - wrqu.data.length = strlen(extra); - } - break; - - default: - - WL_TRACE(("Unknown Event %d: ignoring\n", event_type)); - break; - } -#ifndef SANDGATE2G - if (cmd) { -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31)) - if (cmd == SIOCGIWSCAN) - wireless_send_event(dev, cmd, &wrqu, NULL); - else -#endif - wireless_send_event(dev, cmd, &wrqu, extra); - } -#endif - -#if WIRELESS_EXT > 14 - memset(extra, 0, sizeof(extra)); - if (wl_iw_check_conn_fail(e, extra, sizeof(extra))) { - cmd = IWEVCUSTOM; - wrqu.data.length = strlen(extra); -#ifndef SANDGATE2G - wireless_send_event(dev, cmd, &wrqu, extra); -#endif - } -#endif -wl_iw_event_end: - net_os_wake_unlock(dev); -#endif -} - -int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) -{ - int res = 0; - wl_cnt_t cnt; - int phy_noise; - int rssi; - scb_val_t scb_val; - - phy_noise = 0; - if ((res = dev_wlc_ioctl(dev, WLC_GET_PHY_NOISE, &phy_noise, sizeof(phy_noise)))) - goto done; - - phy_noise = dtoh32(phy_noise); - WL_TRACE(("wl_iw_get_wireless_stats phy noise=%d\n", phy_noise)); - - bzero(&scb_val, sizeof(scb_val_t)); - if ((res = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)))) - goto done; - - rssi = dtoh32(scb_val.val); - WL_TRACE(("wl_iw_get_wireless_stats rssi=%d\n", rssi)); - if (rssi <= WL_IW_RSSI_NO_SIGNAL) - wstats->qual.qual = 0; - else if (rssi <= WL_IW_RSSI_VERY_LOW) - wstats->qual.qual = 1; - else if (rssi <= WL_IW_RSSI_LOW) - wstats->qual.qual = 2; - else if (rssi <= WL_IW_RSSI_GOOD) - wstats->qual.qual = 3; - else if (rssi <= WL_IW_RSSI_VERY_GOOD) - wstats->qual.qual = 4; - else - wstats->qual.qual = 5; - - - wstats->qual.level = 0x100 + rssi; - wstats->qual.noise = 0x100 + phy_noise; -#if WIRELESS_EXT > 18 - wstats->qual.updated |= (IW_QUAL_ALL_UPDATED | IW_QUAL_DBM); -#else - wstats->qual.updated |= 7; -#endif - -#if WIRELESS_EXT > 11 - WL_TRACE(("wl_iw_get_wireless_stats counters=%d\n", (int)sizeof(wl_cnt_t))); - - memset(&cnt, 0, sizeof(wl_cnt_t)); - res = dev_wlc_bufvar_get(dev, "counters", (char *)&cnt, sizeof(wl_cnt_t)); - if (res) - { - WL_ERROR(("wl_iw_get_wireless_stats counters failed error=%d\n", res)); - goto done; - } - - cnt.version = dtoh16(cnt.version); - if (cnt.version != WL_CNT_T_VERSION) { - WL_TRACE(("\tIncorrect version of counters struct: expected %d; got %d\n", - WL_CNT_T_VERSION, cnt.version)); - goto done; - } - - wstats->discard.nwid = 0; - wstats->discard.code = dtoh32(cnt.rxundec); - wstats->discard.fragment = dtoh32(cnt.rxfragerr); - wstats->discard.retries = dtoh32(cnt.txfail); - wstats->discard.misc = dtoh32(cnt.rxrunt) + dtoh32(cnt.rxgiant); - wstats->miss.beacon = 0; - - WL_TRACE(("wl_iw_get_wireless_stats counters txframe=%d txbyte=%d\n", - dtoh32(cnt.txframe), dtoh32(cnt.txbyte))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxfrmtoolong=%d\n", dtoh32(cnt.rxfrmtoolong))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxbadplcp=%d\n", dtoh32(cnt.rxbadplcp))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxundec=%d\n", dtoh32(cnt.rxundec))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxfragerr=%d\n", dtoh32(cnt.rxfragerr))); - WL_TRACE(("wl_iw_get_wireless_stats counters txfail=%d\n", dtoh32(cnt.txfail))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxrunt=%d\n", dtoh32(cnt.rxrunt))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxgiant=%d\n", dtoh32(cnt.rxgiant))); - -#endif - -done: - return res; -} -static void -wl_iw_bt_flag_set( - struct net_device *dev, - bool set) -{ -#if defined(BT_DHCP_USE_FLAGS) - char buf_flag7_dhcp_on[8] = { 7, 00, 00, 00, 0x1, 0x0, 0x00, 0x00 }; - char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00}; -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_lock(); -#endif - -#if defined(BT_DHCP_eSCO_FIX) - set_btc_esco_params(dev, set); -#endif - -#if defined(BT_DHCP_USE_FLAGS) - WL_TRACE_COEX(("WI-FI priority boost via bt flags, set:%d\n", set)); - if (set == TRUE) { - dev_wlc_bufvar_set(dev, "btc_flags", - (char *)&buf_flag7_dhcp_on[0], sizeof(buf_flag7_dhcp_on)); - } - else { - dev_wlc_bufvar_set(dev, "btc_flags", - (char *)&buf_flag7_default[0], sizeof(buf_flag7_default)); - } -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_unlock(); -#endif -} - -static void -wl_iw_bt_timerfunc(ulong data) -{ - bt_info_t *bt_local = (bt_info_t *)data; - bt_local->timer_on = 0; - WL_TRACE(("%s\n", __FUNCTION__)); - - up(&bt_local->bt_sem); -} - -static int -_bt_dhcp_sysioc_thread(void *data) -{ - DAEMONIZE("dhcp_sysioc"); - - while (down_interruptible(&g_bt->bt_sem) == 0) { - - net_os_wake_lock(g_bt->dev); - - if (g_bt->timer_on) { - g_bt->timer_on = 0; - del_timer_sync(&g_bt->timer); - } - - switch (g_bt->bt_state) { - case BT_DHCP_START: - WL_TRACE_COEX(("%s bt_dhcp stm: started \n", __FUNCTION__)); - g_bt->bt_state = BT_DHCP_OPPORTUNITY_WINDOW; - mod_timer(&g_bt->timer, jiffies + BT_DHCP_OPPORTUNITY_WINDOW_TIME*HZ/1000); - g_bt->timer_on = 1; - break; - - case BT_DHCP_OPPORTUNITY_WINDOW: - if (g_bt->dhcp_done) { - WL_TRACE_COEX(("%s DHCP Done before T1 expiration\n", \ - __FUNCTION__)); - g_bt->bt_state = BT_DHCP_IDLE; - g_bt->timer_on = 0; - break; - } - - WL_TRACE_COEX(("%s DHCP T1:%d expired\n", \ - __FUNCTION__, BT_DHCP_OPPORTUNITY_WINDOW_TIME)); - if (g_bt->dev) wl_iw_bt_flag_set(g_bt->dev, TRUE); - g_bt->bt_state = BT_DHCP_FLAG_FORCE_TIMEOUT; - mod_timer(&g_bt->timer, jiffies + BT_DHCP_FLAG_FORCE_TIME*HZ/1000); - g_bt->timer_on = 1; - break; - - case BT_DHCP_FLAG_FORCE_TIMEOUT: - if (g_bt->dhcp_done) { - WL_TRACE_COEX(("%s DHCP Done before T2 expiration\n", \ - __FUNCTION__)); - } else { - WL_TRACE_COEX(("%s DHCP wait interval T2:%d msec expired\n", - __FUNCTION__, BT_DHCP_FLAG_FORCE_TIME)); - } - - if (g_bt->dev) wl_iw_bt_flag_set(g_bt->dev, FALSE); - g_bt->bt_state = BT_DHCP_IDLE; - g_bt->timer_on = 0; - break; - - default: - WL_ERROR(("%s error g_status=%d !!!\n", __FUNCTION__, \ - g_bt->bt_state)); - if (g_bt->dev) wl_iw_bt_flag_set(g_bt->dev, FALSE); - g_bt->bt_state = BT_DHCP_IDLE; - g_bt->timer_on = 0; - break; - } - - net_os_wake_unlock(g_bt->dev); - } - - if (g_bt->timer_on) { - g_bt->timer_on = 0; - del_timer_sync(&g_bt->timer); - } - - complete_and_exit(&g_bt->bt_exited, 0); -} - -static void -wl_iw_bt_release(void) -{ - bt_info_t *bt_local = g_bt; - - if (!bt_local) { - return; - } - - if (bt_local->bt_pid >= 0) { - KILL_PROC(bt_local->bt_pid, SIGTERM); - wait_for_completion(&bt_local->bt_exited); - } - kfree(bt_local); - g_bt = NULL; -} - -static int -wl_iw_bt_init(struct net_device *dev) -{ - bt_info_t *bt_dhcp = NULL; - - bt_dhcp = kmalloc(sizeof(bt_info_t), GFP_KERNEL); - if (!bt_dhcp) - return -ENOMEM; - - memset(bt_dhcp, 0, sizeof(bt_info_t)); - bt_dhcp->bt_pid = -1; - g_bt = bt_dhcp; - bt_dhcp->dev = dev; - bt_dhcp->bt_state = BT_DHCP_IDLE; - - - bt_dhcp->timer_ms = 10; - init_timer(&bt_dhcp->timer); - bt_dhcp->timer.data = (ulong)bt_dhcp; - bt_dhcp->timer.function = wl_iw_bt_timerfunc; - - sema_init(&bt_dhcp->bt_sem, 0); - init_completion(&bt_dhcp->bt_exited); - bt_dhcp->bt_pid = kernel_thread(_bt_dhcp_sysioc_thread, bt_dhcp, 0); - if (bt_dhcp->bt_pid < 0) { - WL_ERROR(("Failed in %s\n", __FUNCTION__)); - return -ENOMEM; - } - - return 0; -} - -int wl_iw_attach(struct net_device *dev, void *dhdp) -{ - int params_size; - wl_iw_t *iw; -#if defined(WL_IW_USE_ISCAN) - iscan_info_t *iscan = NULL; -#endif - - mutex_init(&wl_cache_lock); - -#if defined(WL_IW_USE_ISCAN) - if (!dev) - return 0; - - memset(&g_wl_iw_params, 0, sizeof(wl_iw_extra_params_t)); - -#ifdef CSCAN - params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params)) + - (WL_NUMCHANNELS * sizeof(uint16)) + WL_SCAN_PARAMS_SSID_MAX * sizeof(wlc_ssid_t); -#else - params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params)); -#endif - iscan = kmalloc(sizeof(iscan_info_t), GFP_KERNEL); - if (!iscan) - return -ENOMEM; - memset(iscan, 0, sizeof(iscan_info_t)); - - iscan->iscan_ex_params_p = (wl_iscan_params_t*)kmalloc(params_size, GFP_KERNEL); - if (!iscan->iscan_ex_params_p) - return -ENOMEM; - iscan->iscan_ex_param_size = params_size; - iscan->sysioc_pid = -1; - - g_iscan = iscan; - iscan->dev = dev; - iscan->iscan_state = ISCAN_STATE_IDLE; -#if defined(CONFIG_FIRST_SCAN) - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_IDLE; - g_first_counter_scans = 0; - g_iscan->scan_flag = 0; -#endif - - iscan->timer_ms = 8000; - init_timer(&iscan->timer); - iscan->timer.data = (ulong)iscan; - iscan->timer.function = wl_iw_timerfunc; - - sema_init(&iscan->sysioc_sem, 0); - init_completion(&iscan->sysioc_exited); - iscan->sysioc_pid = kernel_thread(_iscan_sysioc_thread, iscan, 0); - if (iscan->sysioc_pid < 0) - return -ENOMEM; -#endif - - iw = *(wl_iw_t **)netdev_priv(dev); - iw->pub = (dhd_pub_t *)dhdp; -#ifdef SOFTAP - priv_dev = dev; -#endif - g_scan = NULL; - - g_scan = (void *)kmalloc(G_SCAN_RESULTS, GFP_KERNEL); - if (!g_scan) - return -ENOMEM; - - memset(g_scan, 0, G_SCAN_RESULTS); - g_scan_specified_ssid = 0; - -#if !defined(CSCAN) - wl_iw_init_ss_cache_ctrl(); -#endif - - wl_iw_bt_init(dev); - - return 0; -} - -void wl_iw_detach(void) -{ -#if defined(WL_IW_USE_ISCAN) - iscan_buf_t *buf; - iscan_info_t *iscan = g_iscan; - - if (!iscan) - return; - if (iscan->sysioc_pid >= 0) { - KILL_PROC(iscan->sysioc_pid, SIGTERM); - wait_for_completion(&iscan->sysioc_exited); - } - mutex_lock(&wl_cache_lock); - while (iscan->list_hdr) { - buf = iscan->list_hdr->next; - kfree(iscan->list_hdr); - iscan->list_hdr = buf; - } - kfree(iscan->iscan_ex_params_p); - kfree(iscan); - g_iscan = NULL; - mutex_unlock(&wl_cache_lock); -#endif - - if (g_scan) - kfree(g_scan); - - g_scan = NULL; -#if !defined(CSCAN) - wl_iw_release_ss_cache_ctrl(); -#endif - wl_iw_bt_release(); -#ifdef SOFTAP - if (ap_cfg_running) { - WL_TRACE(("\n%s AP is going down\n", __FUNCTION__)); - wl_iw_send_priv_event(priv_dev, "AP_DOWN"); - } -#endif -} diff --git a/drivers/net/wireless/bcm4329/wl_iw.h b/drivers/net/wireless/bcm4329/wl_iw.h deleted file mode 100644 index ee6c699936ea..000000000000 --- a/drivers/net/wireless/bcm4329/wl_iw.h +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Linux Wireless Extensions support - * - * Copyright (C) 1999-2010, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wl_iw.h,v 1.5.34.1.6.36.4.18 2011/02/10 19:33:12 Exp $ - */ - - -#ifndef _wl_iw_h_ -#define _wl_iw_h_ - -#include - -#include -#include -#include - -#define WL_SCAN_PARAMS_SSID_MAX 10 -#define GET_SSID "SSID=" -#define GET_CHANNEL "CH=" -#define GET_NPROBE "NPROBE=" -#define GET_ACTIVE_ASSOC_DWELL "ACTIVE=" -#define GET_PASSIVE_ASSOC_DWELL "PASSIVE=" -#define GET_HOME_DWELL "HOME=" -#define GET_SCAN_TYPE "TYPE=" - -#define BAND_GET_CMD "GETBAND" -#define BAND_SET_CMD "SETBAND" -#define DTIM_SKIP_GET_CMD "DTIMSKIPGET" -#define DTIM_SKIP_SET_CMD "DTIMSKIPSET" -#define SETSUSPEND_CMD "SETSUSPENDOPT" -#define PNOSSIDCLR_SET_CMD "PNOSSIDCLR" -#define PNOSETUP_SET_CMD "PNOSETUP " -#define PNOENABLE_SET_CMD "PNOFORCE" -#define PNODEBUG_SET_CMD "PNODEBUG" -#define TXPOWER_SET_CMD "TXPOWER" -#define RXFILTER_START_CMD "RXFILTER-START" -#define RXFILTER_STOP_CMD "RXFILTER-STOP" -#define RXFILTER_ADD_CMD "RXFILTER-ADD" -#define RXFILTER_REMOVE_CMD "RXFILTER-REMOVE" - -#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] -#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" - - -typedef struct wl_iw_extra_params { - int target_channel; -} wl_iw_extra_params_t; - -struct cntry_locales_custom { - char iso_abbrev[WLC_CNTRY_BUF_SZ]; - char custom_locale[WLC_CNTRY_BUF_SZ]; - int32 custom_locale_rev; -}; - -#define WL_IW_RSSI_MINVAL -200 -#define WL_IW_RSSI_NO_SIGNAL -91 -#define WL_IW_RSSI_VERY_LOW -80 -#define WL_IW_RSSI_LOW -70 -#define WL_IW_RSSI_GOOD -68 -#define WL_IW_RSSI_VERY_GOOD -58 -#define WL_IW_RSSI_EXCELLENT -57 -#define WL_IW_RSSI_INVALID 0 -#define MAX_WX_STRING 80 -#define isprint(c) bcm_isprint(c) -#define WL_IW_SET_ACTIVE_SCAN (SIOCIWFIRSTPRIV+1) -#define WL_IW_GET_RSSI (SIOCIWFIRSTPRIV+3) -#define WL_IW_SET_PASSIVE_SCAN (SIOCIWFIRSTPRIV+5) -#define WL_IW_GET_LINK_SPEED (SIOCIWFIRSTPRIV+7) -#define WL_IW_GET_CURR_MACADDR (SIOCIWFIRSTPRIV+9) -#define WL_IW_SET_STOP (SIOCIWFIRSTPRIV+11) -#define WL_IW_SET_START (SIOCIWFIRSTPRIV+13) - - -#define WL_SET_AP_CFG (SIOCIWFIRSTPRIV+15) -#define WL_AP_STA_LIST (SIOCIWFIRSTPRIV+17) -#define WL_AP_MAC_FLTR (SIOCIWFIRSTPRIV+19) -#define WL_AP_BSS_START (SIOCIWFIRSTPRIV+21) -#define AP_LPB_CMD (SIOCIWFIRSTPRIV+23) -#define WL_AP_STOP (SIOCIWFIRSTPRIV+25) -#define WL_FW_RELOAD (SIOCIWFIRSTPRIV+27) -#define WL_AP_STA_DISASSOC (SIOCIWFIRSTPRIV+29) -#define WL_COMBO_SCAN (SIOCIWFIRSTPRIV+31) - -#define G_SCAN_RESULTS (8*1024) -#define WE_ADD_EVENT_FIX 0x80 -#define G_WLAN_SET_ON 0 -#define G_WLAN_SET_OFF 1 - -#define CHECK_EXTRA_FOR_NULL(extra) \ -if (!extra) { \ - WL_ERROR(("%s: error : extra is null pointer\n", __FUNCTION__)); \ - return -EINVAL; \ -} - -typedef struct wl_iw { - char nickname[IW_ESSID_MAX_SIZE]; - - struct iw_statistics wstats; - - int spy_num; - uint32 pwsec; - uint32 gwsec; - bool privacy_invoked; - - struct ether_addr spy_addr[IW_MAX_SPY]; - struct iw_quality spy_qual[IW_MAX_SPY]; - void *wlinfo; - dhd_pub_t * pub; -} wl_iw_t; - -#define WLC_IW_SS_CACHE_MAXLEN 2048 -#define WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN 32 -#define WLC_IW_BSS_INFO_MAXLEN \ - (WLC_IW_SS_CACHE_MAXLEN - WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN) - -typedef struct wl_iw_ss_cache { - struct wl_iw_ss_cache *next; - int dirty; - uint32 buflen; - uint32 version; - uint32 count; - wl_bss_info_t bss_info[1]; -} wl_iw_ss_cache_t; - -typedef struct wl_iw_ss_cache_ctrl { - wl_iw_ss_cache_t *m_cache_head; - int m_link_down; - int m_timer_expired; - char m_active_bssid[ETHER_ADDR_LEN]; - uint m_prev_scan_mode; - uint m_cons_br_scan_cnt; - struct timer_list *m_timer; -} wl_iw_ss_cache_ctrl_t; - -typedef enum broadcast_first_scan { - BROADCAST_SCAN_FIRST_IDLE = 0, - BROADCAST_SCAN_FIRST_STARTED, - BROADCAST_SCAN_FIRST_RESULT_READY, - BROADCAST_SCAN_FIRST_RESULT_CONSUMED -} broadcast_first_scan_t; -#ifdef SOFTAP -#define SSID_LEN 33 -#define SEC_LEN 16 -#define KEY_LEN 65 -#define PROFILE_OFFSET 32 -struct ap_profile { - uint8 ssid[SSID_LEN]; - uint8 sec[SEC_LEN]; - uint8 key[KEY_LEN]; - uint32 channel; - uint32 preamble; - uint32 max_scb; - uint32 closednet; - char country_code[WLC_CNTRY_BUF_SZ]; -}; - - -#define MACLIST_MODE_DISABLED 0 -#define MACLIST_MODE_DENY 1 -#define MACLIST_MODE_ALLOW 2 -struct mflist { - uint count; - struct ether_addr ea[16]; -}; - -struct mac_list_set { - uint32 mode; - struct mflist mac_list; -}; -#endif - -#if WIRELESS_EXT > 12 -#include -extern const struct iw_handler_def wl_iw_handler_def; -#endif - -extern int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -extern void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data); -extern int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats); -int wl_iw_attach(struct net_device *dev, void * dhdp); -void wl_iw_detach(void); -int wl_control_wl_start(struct net_device *dev); - -extern int net_os_wake_lock(struct net_device *dev); -extern int net_os_wake_unlock(struct net_device *dev); -extern int net_os_wake_lock_timeout(struct net_device *dev); -extern int net_os_wake_lock_timeout_enable(struct net_device *dev); -extern int net_os_set_suspend_disable(struct net_device *dev, int val); -extern int net_os_set_suspend(struct net_device *dev, int val); -extern int net_os_set_dtim_skip(struct net_device *dev, int val); -extern void get_customized_country_code(char *country_iso_code, wl_country_t *cspec); -extern char *dhd_bus_country_get(struct net_device *dev); -extern int dhd_get_dtim_skip(dhd_pub_t *dhd); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) -#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \ - iwe_stream_add_event(info, stream, ends, iwe, extra) -#define IWE_STREAM_ADD_VALUE(info, event, value, ends, iwe, event_len) \ - iwe_stream_add_value(info, event, value, ends, iwe, event_len) -#define IWE_STREAM_ADD_POINT(info, stream, ends, iwe, extra) \ - iwe_stream_add_point(info, stream, ends, iwe, extra) -#else -#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \ - iwe_stream_add_event(stream, ends, iwe, extra) -#define IWE_STREAM_ADD_VALUE(info, event, value, ends, iwe, event_len) \ - iwe_stream_add_value(event, value, ends, iwe, event_len) -#define IWE_STREAM_ADD_POINT(info, stream, ends, iwe, extra) \ - iwe_stream_add_point(stream, ends, iwe, extra) -#endif - -extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled); -extern int dhd_pno_clean(dhd_pub_t *dhd); -extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, \ - ushort scan_fr, int pno_repeat, int pno_freq_expo_max); -extern int dhd_pno_get_status(dhd_pub_t *dhd); -extern int dhd_dev_pno_reset(struct net_device *dev); -extern int dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local, \ - int nssid, ushort scan_fr, int pno_repeat, int pno_freq_expo_max); -extern int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled); -extern int dhd_dev_get_pno_status(struct net_device *dev); -extern void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec); - -#define PNO_TLV_PREFIX 'S' -#define PNO_TLV_VERSION '1' -#define PNO_TLV_SUBVERSION '2' -#define PNO_TLV_RESERVED '0' -#define PNO_TLV_TYPE_SSID_IE 'S' -#define PNO_TLV_TYPE_TIME 'T' -#define PNO_TLV_FREQ_REPEAT 'R' -#define PNO_TLV_FREQ_EXPO_MAX 'M' -#define PNO_EVENT_UP "PNO_EVENT" - -typedef struct cmd_tlv { - char prefix; - char version; - char subver; - char reserved; -} cmd_tlv_t; - -#ifdef SOFTAP_TLV_CFG -#define SOFTAP_SET_CMD "SOFTAPSET " -#define SOFTAP_TLV_PREFIX 'A' -#define SOFTAP_TLV_VERSION '1' -#define SOFTAP_TLV_SUBVERSION '0' -#define SOFTAP_TLV_RESERVED '0' - -#define TLV_TYPE_SSID 'S' -#define TLV_TYPE_SECUR 'E' -#define TLV_TYPE_KEY 'K' -#define TLV_TYPE_CHANNEL 'C' -#endif - -#if defined(CSCAN) - -typedef struct cscan_tlv { - char prefix; - char version; - char subver; - char reserved; -} cscan_tlv_t; - -#define CSCAN_COMMAND "CSCAN " -#define CSCAN_TLV_PREFIX 'S' -#define CSCAN_TLV_VERSION 1 -#define CSCAN_TLV_SUBVERSION 0 -#define CSCAN_TLV_TYPE_SSID_IE 'S' -#define CSCAN_TLV_TYPE_CHANNEL_IE 'C' -#define CSCAN_TLV_TYPE_NPROBE_IE 'N' -#define CSCAN_TLV_TYPE_ACTIVE_IE 'A' -#define CSCAN_TLV_TYPE_PASSIVE_IE 'P' -#define CSCAN_TLV_TYPE_HOME_IE 'H' -#define CSCAN_TLV_TYPE_STYPE_IE 'T' - -extern int wl_iw_parse_channel_list_tlv(char** list_str, uint16* channel_list, \ - int channel_num, int *bytes_left); - -extern int wl_iw_parse_data_tlv(char** list_str, void *dst, int dst_size, \ - const char token, int input_size, int *bytes_left); - -extern int wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, \ - int max, int *bytes_left); - -extern int wl_iw_parse_ssid_list(char** list_str, wlc_ssid_t* ssid, int idx, int max); - -extern int wl_iw_parse_channel_list(char** list_str, uint16* channel_list, int channel_num); - -#endif - -#endif diff --git a/drivers/net/wireless/bcmdhd/Kconfig b/drivers/net/wireless/bcmdhd/Kconfig deleted file mode 100644 index 8b6b92f62437..000000000000 --- a/drivers/net/wireless/bcmdhd/Kconfig +++ /dev/null @@ -1,54 +0,0 @@ -config BCMDHD - tristate "Broadcom 4329/30 wireless cards support" - depends on MMC - ---help--- - This module adds support for wireless adapters based on - Broadcom 4329/30 chipset. - - This driver uses the kernel's wireless extensions subsystem. - - If you choose to build a module, it'll be called dhd. Say M if - unsure. - -config BCMDHD_FW_PATH - depends on BCMDHD - string "Firmware path" - default "/system/etc/firmware/fw_bcmdhd.bin" - ---help--- - Path to the firmware file. - -config BCMDHD_NVRAM_PATH - depends on BCMDHD - string "NVRAM path" - default "/system/etc/wifi/bcmdhd.cal" - ---help--- - Path to the calibration file. - -config BCMDHD_WEXT - bool "Enable WEXT support" - depends on BCMDHD && CFG80211 = n - select WIRELESS_EXT - select WEXT_PRIV - help - Enables WEXT support - -config DHD_USE_STATIC_BUF - bool "Enable memory preallocation" - depends on BCMDHD - default n - ---help--- - Use memory preallocated in platform - -config DHD_USE_SCHED_SCAN - bool "Use CFG80211 sched scan" - depends on BCMDHD && CFG80211 - default n - ---help--- - Use CFG80211 sched scan - -config DHD_ENABLE_P2P - bool "Enable Wifi Direct" - depends on BCMDHD && CFG80211 - default n - ---help--- - Use Enable Wifi Direct diff --git a/drivers/net/wireless/bcmdhd/Makefile b/drivers/net/wireless/bcmdhd/Makefile deleted file mode 100644 index 40816c4ac57f..000000000000 --- a/drivers/net/wireless/bcmdhd/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -# bcmdhd -DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER \ - -DBCMDONGLEHOST -DUNRELEASEDCHIP -DBCMDMA32 -DWLBTAMP -DBCMFILEIMAGE \ - -DDHDTHREAD -DDHD_GPL -DDHD_SCHED -DDHD_DEBUG -DSDTEST -DBDC -DTOE \ - -DDHD_BCMEVENTS -DSHOW_EVENTS -DDONGLEOVERLAYS -DBCMDBG \ - -DCUSTOMER_HW2 -DCUSTOM_OOB_GPIO_NUM=2 -DOOB_INTR_ONLY -DHW_OOB \ - -DMMC_SDIO_ABORT -DBCMSDIO -DBCMLXSDMMC -DBCMPLATFORM_BUS -DWLP2P \ - -DNEW_COMPAT_WIRELESS -DWIFI_ACT_FRAME -DARP_OFFLOAD_SUPPORT \ - -DKEEP_ALIVE -DCSCAN -DGET_CUSTOM_MAC_ENABLE -DPKT_FILTER_SUPPORT \ - -DEMBEDDED_PLATFORM -DENABLE_INSMOD_NO_FW_LOAD -DPNO_SUPPORT \ - -DSET_RANDOM_MAC_SOFTAP -DWL_CFG80211_STA_EVENT -DSUPPORT_PM2_ONLY \ - -Idrivers/net/wireless/bcmdhd -Idrivers/net/wireless/bcmdhd/include - -DHDOFILES = aiutils.o bcmsdh_sdmmc_linux.o dhd_linux.o siutils.o bcmutils.o \ - dhd_linux_sched.o bcmwifi.o dhd_sdio.o bcmevent.o dhd_bta.o hndpmu.o \ - bcmsdh.o dhd_cdc.o bcmsdh_linux.o dhd_common.o linux_osl.o \ - bcmsdh_sdmmc.o dhd_custom_gpio.o sbutils.o wldev_common.o wl_android.o dhd_cfg80211.o - -obj-$(CONFIG_BCMDHD) += bcmdhd.o -bcmdhd-objs += $(DHDOFILES) -ifneq ($(CONFIG_WIRELESS_EXT),) -bcmdhd-objs += wl_iw.o -DHDCFLAGS += -DSOFTAP -DWL_WIRELESS_EXT -endif -ifneq ($(CONFIG_CFG80211),) -bcmdhd-objs += wl_cfg80211.o wl_cfgp2p.o wl_linux_mon.o -DHDCFLAGS += -DWL_CFG80211 -DHDCFLAGS += -DCUSTOM_ROAM_TRIGGER_SETTING=-65 -DHDCFLAGS += -DCUSTOM_ROAM_DELTA_SETTING=15 -endif -ifneq ($(CONFIG_DHD_USE_SCHED_SCAN),) -DHDCFLAGS += -DWL_SCHED_SCAN -endif -ifneq ($(CONFIG_DHD_ENABLE_P2P),) -DHDCFLAGS += -DWL_ENABLE_P2P_IF -endif -EXTRA_CFLAGS = $(DHDCFLAGS) -ifeq ($(CONFIG_BCMDHD),m) -EXTRA_LDFLAGS += --strip-debug -endif diff --git a/drivers/net/wireless/bcmdhd/aiutils.c b/drivers/net/wireless/bcmdhd/aiutils.c deleted file mode 100644 index 5ca0993c9333..000000000000 --- a/drivers/net/wireless/bcmdhd/aiutils.c +++ /dev/null @@ -1,675 +0,0 @@ -/* - * Misc utility routines for accessing chip-specific features - * of the SiliconBackplane-based Broadcom chips. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: aiutils.c,v 1.26.2.1 2010-03-09 18:41:21 $ - */ - - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "siutils_priv.h" - - - - - -static uint32 -get_erom_ent(si_t *sih, uint32 **eromptr, uint32 mask, uint32 match) -{ - uint32 ent; - uint inv = 0, nom = 0; - - while (TRUE) { - ent = R_REG(si_osh(sih), *eromptr); - (*eromptr)++; - - if (mask == 0) - break; - - if ((ent & ER_VALID) == 0) { - inv++; - continue; - } - - if (ent == (ER_END | ER_VALID)) - break; - - if ((ent & mask) == match) - break; - - nom++; - } - - SI_VMSG(("%s: Returning ent 0x%08x\n", __FUNCTION__, ent)); - if (inv + nom) { - SI_VMSG((" after %d invalid and %d non-matching entries\n", inv, nom)); - } - return ent; -} - -static uint32 -get_asd(si_t *sih, uint32 **eromptr, uint sp, uint ad, uint st, uint32 *addrl, uint32 *addrh, - uint32 *sizel, uint32 *sizeh) -{ - uint32 asd, sz, szd; - - asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID); - if (((asd & ER_TAG1) != ER_ADD) || - (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) || - ((asd & AD_ST_MASK) != st)) { - - (*eromptr)--; - return 0; - } - *addrl = asd & AD_ADDR_MASK; - if (asd & AD_AG32) - *addrh = get_erom_ent(sih, eromptr, 0, 0); - else - *addrh = 0; - *sizeh = 0; - sz = asd & AD_SZ_MASK; - if (sz == AD_SZ_SZD) { - szd = get_erom_ent(sih, eromptr, 0, 0); - *sizel = szd & SD_SZ_MASK; - if (szd & SD_SG32) - *sizeh = get_erom_ent(sih, eromptr, 0, 0); - } else - *sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT); - - SI_VMSG((" SP %d, ad %d: st = %d, 0x%08x_0x%08x @ 0x%08x_0x%08x\n", - sp, ad, st, *sizeh, *sizel, *addrh, *addrl)); - - return asd; -} - -static void -ai_hwfixup(si_info_t *sii) -{ -} - - -void -ai_scan(si_t *sih, void *regs, uint devid) -{ - si_info_t *sii = SI_INFO(sih); - chipcregs_t *cc = (chipcregs_t *)regs; - uint32 erombase, *eromptr, *eromlim; - - erombase = R_REG(sii->osh, &cc->eromptr); - - switch (BUSTYPE(sih->bustype)) { - case SI_BUS: - eromptr = (uint32 *)REG_MAP(erombase, SI_CORE_SIZE); - break; - - case PCI_BUS: - - sii->curwrap = (void *)((uintptr)regs + SI_CORE_SIZE); - - - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, erombase); - eromptr = regs; - break; - - case SPI_BUS: - case SDIO_BUS: - eromptr = (uint32 *)(uintptr)erombase; - break; - - case PCMCIA_BUS: - default: - SI_ERROR(("Don't know how to do AXI enumertion on bus %d\n", sih->bustype)); - ASSERT(0); - return; - } - eromlim = eromptr + (ER_REMAPCONTROL / sizeof(uint32)); - - SI_VMSG(("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%p, eromlim = 0x%p\n", - regs, erombase, eromptr, eromlim)); - while (eromptr < eromlim) { - uint32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp; - uint32 mpd, asd, addrl, addrh, sizel, sizeh; - uint32 *base; - uint i, j, idx; - bool br; - - br = FALSE; - - - cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI); - if (cia == (ER_END | ER_VALID)) { - SI_VMSG(("Found END of erom after %d cores\n", sii->numcores)); - ai_hwfixup(sii); - return; - } - base = eromptr - 1; - cib = get_erom_ent(sih, &eromptr, 0, 0); - - if ((cib & ER_TAG) != ER_CI) { - SI_ERROR(("CIA not followed by CIB\n")); - goto error; - } - - cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT; - mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT; - crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT; - nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT; - nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT; - nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT; - nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT; - - SI_VMSG(("Found component 0x%04x/0x%04x rev %d at erom addr 0x%p, with nmw = %d, " - "nsw = %d, nmp = %d & nsp = %d\n", - mfg, cid, crev, base, nmw, nsw, nmp, nsp)); - - if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0)) - continue; - if ((nmw + nsw == 0)) { - - if (cid == OOB_ROUTER_CORE_ID) { - asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, - &addrl, &addrh, &sizel, &sizeh); - if (asd != 0) { - sii->oob_router = addrl; - } - } - continue; - } - - idx = sii->numcores; - - sii->cia[idx] = cia; - sii->cib[idx] = cib; - sii->coreid[idx] = cid; - - for (i = 0; i < nmp; i++) { - mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID); - if ((mpd & ER_TAG) != ER_MP) { - SI_ERROR(("Not enough MP entries for component 0x%x\n", cid)); - goto error; - } - SI_VMSG((" Master port %d, mp: %d id: %d\n", i, - (mpd & MPD_MP_MASK) >> MPD_MP_SHIFT, - (mpd & MPD_MUI_MASK) >> MPD_MUI_SHIFT)); - } - - - asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh, &sizel, &sizeh); - if (asd == 0) { - - asd = get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl, &addrh, - &sizel, &sizeh); - if (asd != 0) - br = TRUE; - else - if ((addrh != 0) || (sizeh != 0) || (sizel != SI_CORE_SIZE)) { - SI_ERROR(("First Slave ASD for core 0x%04x malformed " - "(0x%08x)\n", cid, asd)); - goto error; - } - } - sii->coresba[idx] = addrl; - sii->coresba_size[idx] = sizel; - - j = 1; - do { - asd = get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl, &addrh, - &sizel, &sizeh); - if ((asd != 0) && (j == 1) && (sizel == SI_CORE_SIZE)) { - sii->coresba2[idx] = addrl; - sii->coresba2_size[idx] = sizel; - } - j++; - } while (asd != 0); - - - for (i = 1; i < nsp; i++) { - j = 0; - do { - asd = get_asd(sih, &eromptr, i, j++, AD_ST_SLAVE, &addrl, &addrh, - &sizel, &sizeh); - } while (asd != 0); - if (j == 0) { - SI_ERROR((" SP %d has no address descriptors\n", i)); - goto error; - } - } - - - for (i = 0; i < nmw; i++) { - asd = get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl, &addrh, - &sizel, &sizeh); - if (asd == 0) { - SI_ERROR(("Missing descriptor for MW %d\n", i)); - goto error; - } - if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) { - SI_ERROR(("Master wrapper %d is not 4KB\n", i)); - goto error; - } - if (i == 0) - sii->wrapba[idx] = addrl; - } - - - for (i = 0; i < nsw; i++) { - uint fwp = (nsp == 1) ? 0 : 1; - asd = get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP, &addrl, &addrh, - &sizel, &sizeh); - if (asd == 0) { - SI_ERROR(("Missing descriptor for SW %d\n", i)); - goto error; - } - if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) { - SI_ERROR(("Slave wrapper %d is not 4KB\n", i)); - goto error; - } - if ((nmw == 0) && (i == 0)) - sii->wrapba[idx] = addrl; - } - - - if (br) - continue; - - - sii->numcores++; - } - - SI_ERROR(("Reached end of erom without finding END")); - -error: - sii->numcores = 0; - return; -} - - -void * -ai_setcoreidx(si_t *sih, uint coreidx) -{ - si_info_t *sii = SI_INFO(sih); - uint32 addr = sii->coresba[coreidx]; - uint32 wrap = sii->wrapba[coreidx]; - void *regs; - - if (coreidx >= sii->numcores) - return (NULL); - - - ASSERT((sii->intrsenabled_fn == NULL) || !(*(sii)->intrsenabled_fn)((sii)->intr_arg)); - - switch (BUSTYPE(sih->bustype)) { - case SI_BUS: - - if (!sii->regs[coreidx]) { - sii->regs[coreidx] = REG_MAP(addr, SI_CORE_SIZE); - ASSERT(GOODREGS(sii->regs[coreidx])); - } - sii->curmap = regs = sii->regs[coreidx]; - if (!sii->wrappers[coreidx]) { - sii->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE); - ASSERT(GOODREGS(sii->wrappers[coreidx])); - } - sii->curwrap = sii->wrappers[coreidx]; - break; - - - case SPI_BUS: - case SDIO_BUS: - sii->curmap = regs = (void *)((uintptr)addr); - sii->curwrap = (void *)((uintptr)wrap); - break; - - case PCMCIA_BUS: - default: - ASSERT(0); - regs = NULL; - break; - } - - sii->curmap = regs; - sii->curidx = coreidx; - - return regs; -} - - -int -ai_numaddrspaces(si_t *sih) -{ - return 2; -} - - -uint32 -ai_addrspace(si_t *sih, uint asidx) -{ - si_info_t *sii; - uint cidx; - - sii = SI_INFO(sih); - cidx = sii->curidx; - - if (asidx == 0) - return sii->coresba[cidx]; - else if (asidx == 1) - return sii->coresba2[cidx]; - else { - SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", - __FUNCTION__, asidx)); - return 0; - } -} - - -uint32 -ai_addrspacesize(si_t *sih, uint asidx) -{ - si_info_t *sii; - uint cidx; - - sii = SI_INFO(sih); - cidx = sii->curidx; - - if (asidx == 0) - return sii->coresba_size[cidx]; - else if (asidx == 1) - return sii->coresba2_size[cidx]; - else { - SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", - __FUNCTION__, asidx)); - return 0; - } -} - -uint -ai_flag(si_t *sih) -{ - si_info_t *sii; - aidmp_t *ai; - - sii = SI_INFO(sih); - ai = sii->curwrap; - - return (R_REG(sii->osh, &ai->oobselouta30) & 0x1f); -} - -void -ai_setint(si_t *sih, int siflag) -{ -} - -uint -ai_wrap_reg(si_t *sih, uint32 offset, uint32 mask, uint32 val) -{ - si_info_t *sii = SI_INFO(sih); - uint32 *map = (uint32 *) sii->curwrap; - - if (mask || val) { - uint32 w = R_REG(sii->osh, map+(offset/4)); - w &= ~mask; - w |= val; - W_REG(sii->osh, map+(offset/4), val); - } - - return (R_REG(sii->osh, map+(offset/4))); -} - -uint -ai_corevendor(si_t *sih) -{ - si_info_t *sii; - uint32 cia; - - sii = SI_INFO(sih); - cia = sii->cia[sii->curidx]; - return ((cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT); -} - -uint -ai_corerev(si_t *sih) -{ - si_info_t *sii; - uint32 cib; - - sii = SI_INFO(sih); - cib = sii->cib[sii->curidx]; - return ((cib & CIB_REV_MASK) >> CIB_REV_SHIFT); -} - -bool -ai_iscoreup(si_t *sih) -{ - si_info_t *sii; - aidmp_t *ai; - - sii = SI_INFO(sih); - ai = sii->curwrap; - - return (((R_REG(sii->osh, &ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) == SICF_CLOCK_EN) && - ((R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) == 0)); -} - - -uint -ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) -{ - uint origidx = 0; - uint32 *r = NULL; - uint w; - uint intr_val = 0; - bool fast = FALSE; - si_info_t *sii; - - sii = SI_INFO(sih); - - ASSERT(GOODIDX(coreidx)); - ASSERT(regoff < SI_CORE_SIZE); - ASSERT((val & ~mask) == 0); - - if (coreidx >= SI_MAXCORES) - return 0; - - if (BUSTYPE(sih->bustype) == SI_BUS) { - - fast = TRUE; - - if (!sii->regs[coreidx]) { - sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx], - SI_CORE_SIZE); - ASSERT(GOODREGS(sii->regs[coreidx])); - } - r = (uint32 *)((uchar *)sii->regs[coreidx] + regoff); - } else if (BUSTYPE(sih->bustype) == PCI_BUS) { - - - if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) { - - - fast = TRUE; - r = (uint32 *)((char *)sii->curmap + PCI_16KB0_CCREGS_OFFSET + regoff); - } else if (sii->pub.buscoreidx == coreidx) { - - fast = TRUE; - if (SI_FAST(sii)) - r = (uint32 *)((char *)sii->curmap + - PCI_16KB0_PCIREGS_OFFSET + regoff); - else - r = (uint32 *)((char *)sii->curmap + - ((regoff >= SBCONFIGOFF) ? - PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) + - regoff); - } - } - - if (!fast) { - INTR_OFF(sii, intr_val); - - - origidx = si_coreidx(&sii->pub); - - - r = (uint32*) ((uchar*) ai_setcoreidx(&sii->pub, coreidx) + regoff); - } - ASSERT(r != NULL); - - - if (mask || val) { - w = (R_REG(sii->osh, r) & ~mask) | val; - W_REG(sii->osh, r, w); - } - - - w = R_REG(sii->osh, r); - - if (!fast) { - - if (origidx != coreidx) - ai_setcoreidx(&sii->pub, origidx); - - INTR_RESTORE(sii, intr_val); - } - - return (w); -} - -void -ai_core_disable(si_t *sih, uint32 bits) -{ - si_info_t *sii; - volatile uint32 dummy; - aidmp_t *ai; - - sii = SI_INFO(sih); - - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - - if (R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) - return; - - W_REG(sii->osh, &ai->ioctrl, bits); - dummy = R_REG(sii->osh, &ai->ioctrl); - OSL_DELAY(10); - - W_REG(sii->osh, &ai->resetctrl, AIRC_RESET); - OSL_DELAY(1); -} - - -void -ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits) -{ - si_info_t *sii; - aidmp_t *ai; - volatile uint32 dummy; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - - ai_core_disable(sih, (bits | resetbits)); - - - W_REG(sii->osh, &ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN)); - dummy = R_REG(sii->osh, &ai->ioctrl); - W_REG(sii->osh, &ai->resetctrl, 0); - OSL_DELAY(1); - - W_REG(sii->osh, &ai->ioctrl, (bits | SICF_CLOCK_EN)); - dummy = R_REG(sii->osh, &ai->ioctrl); - OSL_DELAY(1); -} - - -void -ai_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - aidmp_t *ai; - uint32 w; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - ASSERT((val & ~mask) == 0); - - if (mask || val) { - w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val); - W_REG(sii->osh, &ai->ioctrl, w); - } -} - -uint32 -ai_core_cflags(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - aidmp_t *ai; - uint32 w; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - ASSERT((val & ~mask) == 0); - - if (mask || val) { - w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val); - W_REG(sii->osh, &ai->ioctrl, w); - } - - return R_REG(sii->osh, &ai->ioctrl); -} - -uint32 -ai_core_sflags(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - aidmp_t *ai; - uint32 w; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - ASSERT((val & ~mask) == 0); - ASSERT((mask & ~SISF_CORE_BITS) == 0); - - if (mask || val) { - w = ((R_REG(sii->osh, &ai->iostatus) & ~mask) | val); - W_REG(sii->osh, &ai->iostatus, w); - } - - return R_REG(sii->osh, &ai->iostatus); -} diff --git a/drivers/net/wireless/bcmdhd/bcmevent.c b/drivers/net/wireless/bcmdhd/bcmevent.c deleted file mode 100644 index 6a25d9a5a57f..000000000000 --- a/drivers/net/wireless/bcmdhd/bcmevent.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * bcmevent read-only data shared by kernel or app layers - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * $Id: bcmevent.c,v 1.8.2.7 2011-02-01 06:23:39 $ - */ - -#include -#include -#include -#include -#include - -#if WLC_E_LAST != 87 -#error "You need to add an entry to bcmevent_names[] for the new event" -#endif - -const bcmevent_name_t bcmevent_names[] = { - { WLC_E_SET_SSID, "SET_SSID" }, - { WLC_E_JOIN, "JOIN" }, - { WLC_E_START, "START" }, - { WLC_E_AUTH, "AUTH" }, - { WLC_E_AUTH_IND, "AUTH_IND" }, - { WLC_E_DEAUTH, "DEAUTH" }, - { WLC_E_DEAUTH_IND, "DEAUTH_IND" }, - { WLC_E_ASSOC, "ASSOC" }, - { WLC_E_ASSOC_IND, "ASSOC_IND" }, - { WLC_E_REASSOC, "REASSOC" }, - { WLC_E_REASSOC_IND, "REASSOC_IND" }, - { WLC_E_DISASSOC, "DISASSOC" }, - { WLC_E_DISASSOC_IND, "DISASSOC_IND" }, - { WLC_E_QUIET_START, "START_QUIET" }, - { WLC_E_QUIET_END, "END_QUIET" }, - { WLC_E_BEACON_RX, "BEACON_RX" }, - { WLC_E_LINK, "LINK" }, - { WLC_E_MIC_ERROR, "MIC_ERROR" }, - { WLC_E_NDIS_LINK, "NDIS_LINK" }, - { WLC_E_ROAM, "ROAM" }, - { WLC_E_TXFAIL, "TXFAIL" }, - { WLC_E_PMKID_CACHE, "PMKID_CACHE" }, - { WLC_E_RETROGRADE_TSF, "RETROGRADE_TSF" }, - { WLC_E_PRUNE, "PRUNE" }, - { WLC_E_AUTOAUTH, "AUTOAUTH" }, - { WLC_E_EAPOL_MSG, "EAPOL_MSG" }, - { WLC_E_SCAN_COMPLETE, "SCAN_COMPLETE" }, - { WLC_E_ADDTS_IND, "ADDTS_IND" }, - { WLC_E_DELTS_IND, "DELTS_IND" }, - { WLC_E_BCNSENT_IND, "BCNSENT_IND" }, - { WLC_E_BCNRX_MSG, "BCNRX_MSG" }, - { WLC_E_BCNLOST_MSG, "BCNLOST_IND" }, - { WLC_E_ROAM_PREP, "ROAM_PREP" }, - { WLC_E_PFN_NET_FOUND, "PFNFOUND_IND" }, - { WLC_E_PFN_NET_LOST, "PFNLOST_IND" }, -#if defined(IBSS_PEER_DISCOVERY_EVENT) - { WLC_E_IBSS_ASSOC, "IBSS_ASSOC" }, -#endif /* defined(IBSS_PEER_DISCOVERY_EVENT) */ - { WLC_E_RADIO, "RADIO" }, - { WLC_E_PSM_WATCHDOG, "PSM_WATCHDOG" }, - { WLC_E_PROBREQ_MSG, "PROBE_REQ_MSG" }, - { WLC_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND" }, - { WLC_E_PSK_SUP, "PSK_SUP" }, - { WLC_E_COUNTRY_CODE_CHANGED, "CNTRYCODE_IND" }, - { WLC_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME" }, - { WLC_E_ICV_ERROR, "ICV_ERROR" }, - { WLC_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR" }, - { WLC_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR" }, - { WLC_E_TRACE, "TRACE" }, - { WLC_E_BTA_HCI_EVENT, "BTA_HCI_EVENT" }, - { WLC_E_IF, "IF" }, -#ifdef WLP2P - { WLC_E_P2P_DISC_LISTEN_COMPLETE, "WLC_E_P2P_DISC_LISTEN_COMPLETE" }, -#endif - { WLC_E_RSSI, "RSSI" }, - { WLC_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE" }, - { WLC_E_EXTLOG_MSG, "EXTERNAL LOG MESSAGE" }, -#ifdef WIFI_ACT_FRAME - { WLC_E_ACTION_FRAME, "ACTION_FRAME" }, - { WLC_E_ACTION_FRAME_RX, "ACTION_FRAME_RX" }, - { WLC_E_ACTION_FRAME_COMPLETE, "ACTION_FRAME_COMPLETE" }, -#endif - { WLC_E_ESCAN_RESULT, "WLC_E_ESCAN_RESULT" }, - { WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE, "WLC_E_AF_OFF_CHAN_COMPLETE" }, -#ifdef WLP2P - { WLC_E_PROBRESP_MSG, "PROBE_RESP_MSG" }, - { WLC_E_P2P_PROBREQ_MSG, "P2P PROBE_REQ_MSG" }, -#endif -#ifdef PROP_TXSTATUS - { WLC_E_FIFO_CREDIT_MAP, "FIFO_CREDIT_MAP" }, -#endif - { WLC_E_WAKE_EVENT, "WAKE_EVENT" }, - { WLC_E_DCS_REQUEST, "DCS_REQUEST" }, - { WLC_E_RM_COMPLETE, "RM_COMPLETE" }, -#ifdef WLMEDIA_HTSF - { WLC_E_HTSFSYNC, "HTSF_SYNC_EVENT" }, -#endif - { WLC_E_OVERLAY_REQ, "OVERLAY_REQ_EVENT" }, - { WLC_E_CSA_COMPLETE_IND, "WLC_E_CSA_COMPLETE_IND" }, - { WLC_E_EXCESS_PM_WAKE_EVENT, "EXCESS_PM_WAKE_EVENT" }, - { WLC_E_PFN_SCAN_NONE, "PFN_SCAN_NONE" }, - { WLC_E_PFN_SCAN_ALLGONE, "PFN_SCAN_ALLGONE" }, -#ifdef SOFTAP - { WLC_E_GTK_PLUMBED, "GTK_PLUMBED" }, -#endif - { WLC_E_ASSOC_REQ_IE, "ASSOC_REQ_IE" }, - { WLC_E_ASSOC_RESP_IE, "ASSOC_RESP_IE" } -}; - - -const int bcmevent_names_size = ARRAYSIZE(bcmevent_names); diff --git a/drivers/net/wireless/bcmdhd/bcmsdh.c b/drivers/net/wireless/bcmdhd/bcmsdh.c deleted file mode 100644 index 89320b6f53d4..000000000000 --- a/drivers/net/wireless/bcmdhd/bcmsdh.c +++ /dev/null @@ -1,691 +0,0 @@ -/* - * BCMSDH interface glue - * implement bcmsdh API for SDIOH driver - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdh.c 344235 2012-07-11 23:47:18Z $ - */ - -/** - * @file bcmsdh.c - */ - -/* ****************** BCMSDH Interface Functions *************************** */ - -#include -#include -#include -#include -#include -#include -#include - -#include /* BRCM API for SDIO clients (such as wl, dhd) */ -#include /* common SDIO/controller interface */ -#include /* SDIO device core hardware definitions. */ - -#include /* SDIO Device and Protocol Specs */ - -#define SDIOH_API_ACCESS_RETRY_LIMIT 2 -const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL; - -/** - * BCMSDH API context - */ -struct bcmsdh_info -{ - bool init_success; /* underlying driver successfully attached */ - void *sdioh; /* handler for sdioh */ - uint32 vendevid; /* Target Vendor and Device ID on SD bus */ - osl_t *osh; - bool regfail; /* Save status of last reg_read/reg_write call */ - uint32 sbwad; /* Save backplane window address */ -}; -/* local copy of bcm sd handler */ -bcmsdh_info_t * l_bcmsdh = NULL; - -#if defined(OOB_INTR_ONLY) && defined(HW_OOB) -extern int -sdioh_enable_hw_oob_intr(void *sdioh, bool enable); - -void -bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable) -{ - sdioh_enable_hw_oob_intr(sdh->sdioh, enable); -} -#endif - -/* Attach BCMSDH layer to SDIO Host Controller Driver - * - * @param osh OSL Handle. - * @param cfghdl Configuration Handle. - * @param regsva Virtual address of controller registers. - * @param irq Interrupt number of SDIO controller. - * - * @return bcmsdh_info_t Handle to BCMSDH context. - */ -bcmsdh_info_t * -bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq) -{ - bcmsdh_info_t *bcmsdh; - - if ((bcmsdh = (bcmsdh_info_t *)MALLOC(osh, sizeof(bcmsdh_info_t))) == NULL) { - BCMSDH_ERROR(("bcmsdh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh))); - return NULL; - } - bzero((char *)bcmsdh, sizeof(bcmsdh_info_t)); - - /* save the handler locally */ - l_bcmsdh = bcmsdh; - - if (!(bcmsdh->sdioh = sdioh_attach(osh, cfghdl, irq))) { - bcmsdh_detach(osh, bcmsdh); - return NULL; - } - - bcmsdh->osh = osh; - bcmsdh->init_success = TRUE; - - *regsva = (uint32 *)SI_ENUM_BASE; - - /* Report the BAR, to fix if needed */ - bcmsdh->sbwad = SI_ENUM_BASE; - return bcmsdh; -} - -int -bcmsdh_detach(osl_t *osh, void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - if (bcmsdh != NULL) { - if (bcmsdh->sdioh) { - sdioh_detach(osh, bcmsdh->sdioh); - bcmsdh->sdioh = NULL; - } - MFREE(osh, bcmsdh, sizeof(bcmsdh_info_t)); - } - - l_bcmsdh = NULL; - return 0; -} - -int -bcmsdh_iovar_op(void *sdh, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - return sdioh_iovar_op(bcmsdh->sdioh, name, params, plen, arg, len, set); -} - -bool -bcmsdh_intr_query(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - bool on; - - ASSERT(bcmsdh); - status = sdioh_interrupt_query(bcmsdh->sdioh, &on); - if (SDIOH_API_SUCCESS(status)) - return FALSE; - else - return on; -} - -int -bcmsdh_intr_enable(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - ASSERT(bcmsdh); - - status = sdioh_interrupt_set(bcmsdh->sdioh, TRUE); - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - -int -bcmsdh_intr_disable(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - ASSERT(bcmsdh); - - status = sdioh_interrupt_set(bcmsdh->sdioh, FALSE); - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - -int -bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - ASSERT(bcmsdh); - - status = sdioh_interrupt_register(bcmsdh->sdioh, fn, argh); - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - -int -bcmsdh_intr_dereg(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - ASSERT(bcmsdh); - - status = sdioh_interrupt_deregister(bcmsdh->sdioh); - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - -#if defined(DHD_DEBUG) -bool -bcmsdh_intr_pending(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - ASSERT(sdh); - return sdioh_interrupt_pending(bcmsdh->sdioh); -} -#endif - - -int -bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh) -{ - ASSERT(sdh); - - /* don't support yet */ - return BCME_UNSUPPORTED; -} - -/** - * Read from SDIO Configuration Space - * @param sdh SDIO Host context. - * @param func_num Function number to read from. - * @param addr Address to read from. - * @param err Error return. - * @return value read from SDIO configuration space. - */ -uint8 -bcmsdh_cfg_read(void *sdh, uint fnc_num, uint32 addr, int *err) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - int32 retry = 0; -#endif - uint8 data = 0; - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - do { - if (retry) /* wait for 1 ms till bus get settled down */ - OSL_DELAY(1000); -#endif - status = sdioh_cfg_read(bcmsdh->sdioh, fnc_num, addr, (uint8 *)&data); -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - } while (!SDIOH_API_SUCCESS(status) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT)); -#endif - if (err) - *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint8data = 0x%x\n", __FUNCTION__, - fnc_num, addr, data)); - - return data; -} - -void -bcmsdh_cfg_write(void *sdh, uint fnc_num, uint32 addr, uint8 data, int *err) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - int32 retry = 0; -#endif - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - do { - if (retry) /* wait for 1 ms till bus get settled down */ - OSL_DELAY(1000); -#endif - status = sdioh_cfg_write(bcmsdh->sdioh, fnc_num, addr, (uint8 *)&data); -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - } while (!SDIOH_API_SUCCESS(status) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT)); -#endif - if (err) - *err = SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR; - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint8data = 0x%x\n", __FUNCTION__, - fnc_num, addr, data)); -} - -uint32 -bcmsdh_cfg_read_word(void *sdh, uint fnc_num, uint32 addr, int *err) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - uint32 data = 0; - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - - status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_READ, fnc_num, - addr, &data, 4); - - if (err) - *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint32data = 0x%x\n", __FUNCTION__, - fnc_num, addr, data)); - - return data; -} - -void -bcmsdh_cfg_write_word(void *sdh, uint fnc_num, uint32 addr, uint32 data, int *err) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - - status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_WRITE, fnc_num, - addr, &data, 4); - - if (err) - *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint32data = 0x%x\n", __FUNCTION__, fnc_num, - addr, data)); -} - - -int -bcmsdh_cis_read(void *sdh, uint func, uint8 *cis, uint length) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - - uint8 *tmp_buf, *tmp_ptr; - uint8 *ptr; - bool ascii = func & ~0xf; - func &= 0x7; - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - ASSERT(cis); - ASSERT(length <= SBSDIO_CIS_SIZE_LIMIT); - - status = sdioh_cis_read(bcmsdh->sdioh, func, cis, length); - - if (ascii) { - /* Move binary bits to tmp and format them into the provided buffer. */ - if ((tmp_buf = (uint8 *)MALLOC(bcmsdh->osh, length)) == NULL) { - BCMSDH_ERROR(("%s: out of memory\n", __FUNCTION__)); - return BCME_NOMEM; - } - bcopy(cis, tmp_buf, length); - for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4); tmp_ptr++) { - ptr += snprintf((char*)ptr, (cis + length - ptr - 4), - "%.2x ", *tmp_ptr & 0xff); - if ((((tmp_ptr - tmp_buf) + 1) & 0xf) == 0) - ptr += snprintf((char *)ptr, (cis + length - ptr -4), "\n"); - } - MFREE(bcmsdh->osh, tmp_buf, length); - } - - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - - -int -bcmsdhsdio_set_sbaddr_window(void *sdh, uint32 address, bool force_set) -{ - int err = 0; - uint bar0 = address & ~SBSDIO_SB_OFT_ADDR_MASK; - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - if (bar0 != bcmsdh->sbwad || force_set) { - bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, - (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); - if (!err) - bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, - (address >> 16) & SBSDIO_SBADDRMID_MASK, &err); - if (!err) - bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, - (address >> 24) & SBSDIO_SBADDRHIGH_MASK, &err); - - if (!err) - bcmsdh->sbwad = bar0; - else - /* invalidate cached window var */ - bcmsdh->sbwad = 0; - - } - - return err; -} - -uint32 -bcmsdh_reg_read(void *sdh, uint32 addr, uint size) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - uint32 word = 0; - - BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, ", __FUNCTION__, addr)); - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - - if (bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE)) - return 0xFFFFFFFF; - - addr &= SBSDIO_SB_OFT_ADDR_MASK; - if (size == 4) - addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - - status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, - SDIOH_READ, SDIO_FUNC_1, addr, &word, size); - - bcmsdh->regfail = !(SDIOH_API_SUCCESS(status)); - - BCMSDH_INFO(("uint32data = 0x%x\n", word)); - - /* if ok, return appropriately masked word */ - if (SDIOH_API_SUCCESS(status)) { - switch (size) { - case sizeof(uint8): - return (word & 0xff); - case sizeof(uint16): - return (word & 0xffff); - case sizeof(uint32): - return word; - default: - bcmsdh->regfail = TRUE; - - } - } - - /* otherwise, bad sdio access or invalid size */ - BCMSDH_ERROR(("%s: error reading addr 0x%04x size %d\n", __FUNCTION__, addr, size)); - return 0xFFFFFFFF; -} - -uint32 -bcmsdh_reg_write(void *sdh, uint32 addr, uint size, uint32 data) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - int err = 0; - - BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n", - __FUNCTION__, addr, size*8, data)); - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - - if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE))) - return err; - - addr &= SBSDIO_SB_OFT_ADDR_MASK; - if (size == 4) - addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_WRITE, SDIO_FUNC_1, - addr, &data, size); - bcmsdh->regfail = !(SDIOH_API_SUCCESS(status)); - - if (SDIOH_API_SUCCESS(status)) - return 0; - - BCMSDH_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n", - __FUNCTION__, data, addr, size)); - return 0xFFFFFFFF; -} - -bool -bcmsdh_regfail(void *sdh) -{ - return ((bcmsdh_info_t *)sdh)->regfail; -} - -int -bcmsdh_recv_buf(void *sdh, uint32 addr, uint fn, uint flags, - uint8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete_fn, void *handle) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - uint incr_fix; - uint width; - int err = 0; - - ASSERT(bcmsdh); - ASSERT(bcmsdh->init_success); - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n", - __FUNCTION__, fn, addr, nbytes)); - - /* Async not implemented yet */ - ASSERT(!(flags & SDIO_REQ_ASYNC)); - if (flags & SDIO_REQ_ASYNC) - return BCME_UNSUPPORTED; - - if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE))) - return err; - - addr &= SBSDIO_SB_OFT_ADDR_MASK; - - incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC; - width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; - if (width == 4) - addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - - status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix, - SDIOH_READ, fn, addr, width, nbytes, buf, pkt); - - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); -} - -int -bcmsdh_send_buf(void *sdh, uint32 addr, uint fn, uint flags, - uint8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete_fn, void *handle) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - uint incr_fix; - uint width; - int err = 0; - - ASSERT(bcmsdh); - ASSERT(bcmsdh->init_success); - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n", - __FUNCTION__, fn, addr, nbytes)); - - /* Async not implemented yet */ - ASSERT(!(flags & SDIO_REQ_ASYNC)); - if (flags & SDIO_REQ_ASYNC) - return BCME_UNSUPPORTED; - - if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE))) - return err; - - addr &= SBSDIO_SB_OFT_ADDR_MASK; - - incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC; - width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; - if (width == 4) - addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - - status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix, - SDIOH_WRITE, fn, addr, width, nbytes, buf, pkt); - - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - -int -bcmsdh_rwdata(void *sdh, uint rw, uint32 addr, uint8 *buf, uint nbytes) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - - ASSERT(bcmsdh); - ASSERT(bcmsdh->init_success); - ASSERT((addr & SBSDIO_SBWINDOW_MASK) == 0); - - addr &= SBSDIO_SB_OFT_ADDR_MASK; - addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - - status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, SDIOH_DATA_INC, - (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1, - addr, 4, nbytes, buf, NULL); - - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - -int -bcmsdh_abort(void *sdh, uint fn) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - return sdioh_abort(bcmsdh->sdioh, fn); -} - -int -bcmsdh_start(void *sdh, int stage) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - return sdioh_start(bcmsdh->sdioh, stage); -} - -int -bcmsdh_stop(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - return sdioh_stop(bcmsdh->sdioh); -} - -int -bcmsdh_waitlockfree(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - return sdioh_waitlockfree(bcmsdh->sdioh); -} - - -int -bcmsdh_query_device(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - bcmsdh->vendevid = (VENDOR_BROADCOM << 16) | 0; - return (bcmsdh->vendevid); -} - -uint -bcmsdh_query_iofnum(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - return (sdioh_query_iofnum(bcmsdh->sdioh)); -} - -int -bcmsdh_reset(bcmsdh_info_t *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - return sdioh_sdio_reset(bcmsdh->sdioh); -} - -void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh) -{ - ASSERT(sdh); - return sdh->sdioh; -} - -/* Function to pass device-status bits to DHD. */ -uint32 -bcmsdh_get_dstatus(void *sdh) -{ - return 0; -} -uint32 -bcmsdh_cur_sbwad(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - return (bcmsdh->sbwad); -} - -void -bcmsdh_chipinfo(void *sdh, uint32 chip, uint32 chiprev) -{ - return; -} - - -int -bcmsdh_sleep(void *sdh, bool enab) -{ -#ifdef SDIOH_SLEEP_ENABLED - bcmsdh_info_t *p = (bcmsdh_info_t *)sdh; - sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh); - - return sdioh_sleep(sd, enab); -#else - return BCME_UNSUPPORTED; -#endif -} diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_linux.c deleted file mode 100644 index 91232bdb2755..000000000000 --- a/drivers/net/wireless/bcmdhd/bcmsdh_linux.c +++ /dev/null @@ -1,736 +0,0 @@ -/* - * SDIO access interface for drivers - linux specific (pci only) - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdh_linux.c 352863 2012-08-24 04:48:50Z $ - */ - -/** - * @file bcmsdh_linux.c - */ - -#define __UNDEF_NO_VERSION__ - -#include -#include - -#include -#include - -#include -#include -#include -#include - -#if defined(OOB_INTR_ONLY) -#include -extern void dhdsdio_isr(void * args); -#include -#include -#include -#endif /* defined(OOB_INTR_ONLY) */ - -/** - * SDIO Host Controller info - */ -typedef struct bcmsdh_hc bcmsdh_hc_t; - -struct bcmsdh_hc { - bcmsdh_hc_t *next; -#ifdef BCMPLATFORM_BUS - struct device *dev; /* platform device handle */ -#else - struct pci_dev *dev; /* pci device handle */ -#endif /* BCMPLATFORM_BUS */ - osl_t *osh; - void *regs; /* SDIO Host Controller address */ - bcmsdh_info_t *sdh; /* SDIO Host Controller handle */ - void *ch; - unsigned int oob_irq; - unsigned long oob_flags; /* OOB Host specifiction as edge and etc */ - bool oob_irq_registered; - bool oob_irq_enable_flag; -#if defined(OOB_INTR_ONLY) - spinlock_t irq_lock; -#endif -}; -static bcmsdh_hc_t *sdhcinfo = NULL; - -/* driver info, initialized when bcmsdh_register is called */ -static bcmsdh_driver_t drvinfo = {NULL, NULL}; - -/* debugging macros */ -#define SDLX_MSG(x) - -/** - * Checks to see if vendor and device IDs match a supported SDIO Host Controller. - */ -bool -bcmsdh_chipmatch(uint16 vendor, uint16 device) -{ - /* Add other vendors and devices as required */ - -#ifdef BCMSDIOH_STD - /* Check for Arasan host controller */ - if (vendor == VENDOR_SI_IMAGE) { - return (TRUE); - } - /* Check for BRCM 27XX Standard host controller */ - if (device == BCM27XX_SDIOH_ID && vendor == VENDOR_BROADCOM) { - return (TRUE); - } - /* Check for BRCM Standard host controller */ - if (device == SDIOH_FPGA_ID && vendor == VENDOR_BROADCOM) { - return (TRUE); - } - /* Check for TI PCIxx21 Standard host controller */ - if (device == PCIXX21_SDIOH_ID && vendor == VENDOR_TI) { - return (TRUE); - } - if (device == PCIXX21_SDIOH0_ID && vendor == VENDOR_TI) { - return (TRUE); - } - /* Ricoh R5C822 Standard SDIO Host */ - if (device == R5C822_SDIOH_ID && vendor == VENDOR_RICOH) { - return (TRUE); - } - /* JMicron Standard SDIO Host */ - if (device == JMICRON_SDIOH_ID && vendor == VENDOR_JMICRON) { - return (TRUE); - } - -#endif /* BCMSDIOH_STD */ -#ifdef BCMSDIOH_SPI - /* This is the PciSpiHost. */ - if (device == SPIH_FPGA_ID && vendor == VENDOR_BROADCOM) { - printf("Found PCI SPI Host Controller\n"); - return (TRUE); - } - -#endif /* BCMSDIOH_SPI */ - - return (FALSE); -} - -#if defined(BCMPLATFORM_BUS) -#if defined(BCMLXSDMMC) -/* forward declarations */ -int bcmsdh_probe(struct device *dev); -int bcmsdh_remove(struct device *dev); - -EXPORT_SYMBOL(bcmsdh_probe); -EXPORT_SYMBOL(bcmsdh_remove); - -#else -/* forward declarations */ -static int __devinit bcmsdh_probe(struct device *dev); -static int __devexit bcmsdh_remove(struct device *dev); -#endif /* BCMLXSDMMC */ - -#ifndef BCMLXSDMMC -static -#endif /* BCMLXSDMMC */ -int bcmsdh_probe(struct device *dev) -{ - osl_t *osh = NULL; - bcmsdh_hc_t *sdhc = NULL; - ulong regs = 0; - bcmsdh_info_t *sdh = NULL; -#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) - struct platform_device *pdev; - struct resource *r; -#endif /* BCMLXSDMMC */ - int irq = 0; - uint32 vendevid; - unsigned long irq_flags = 0; - -#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) - pdev = to_platform_device(dev); - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - irq = platform_get_irq(pdev, 0); - if (!r || irq == NO_IRQ) - return -ENXIO; -#endif /* BCMLXSDMMC */ - -#if defined(OOB_INTR_ONLY) -#ifdef HW_OOB - irq_flags = - IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE; -#else - irq_flags = IRQF_TRIGGER_FALLING; -#endif /* HW_OOB */ - - /* Get customer specific OOB IRQ parametres: IRQ number as IRQ type */ - irq = dhd_customer_oob_irq_map(&irq_flags); - if (irq < 0) { - SDLX_MSG(("%s: Host irq is not defined\n", __FUNCTION__)); - return 1; - } -#endif /* defined(OOB_INTR_ONLY) */ - /* allocate SDIO Host Controller state info */ - if (!(osh = osl_attach(dev, PCI_BUS, FALSE))) { - SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__)); - goto err; - } - if (!(sdhc = MALLOC(osh, sizeof(bcmsdh_hc_t)))) { - SDLX_MSG(("%s: out of memory, allocated %d bytes\n", - __FUNCTION__, - MALLOCED(osh))); - goto err; - } - bzero(sdhc, sizeof(bcmsdh_hc_t)); - sdhc->osh = osh; - - sdhc->dev = (void *)dev; - -#ifdef BCMLXSDMMC - if (!(sdh = bcmsdh_attach(osh, (void *)0, - (void **)®s, irq))) { - SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); - goto err; - } -#else - if (!(sdh = bcmsdh_attach(osh, (void *)r->start, - (void **)®s, irq))) { - SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); - goto err; - } -#endif /* BCMLXSDMMC */ - sdhc->sdh = sdh; - sdhc->oob_irq = irq; - sdhc->oob_flags = irq_flags; - sdhc->oob_irq_registered = FALSE; /* to make sure.. */ - sdhc->oob_irq_enable_flag = FALSE; -#if defined(OOB_INTR_ONLY) - spin_lock_init(&sdhc->irq_lock); -#endif - - /* chain SDIO Host Controller info together */ - sdhc->next = sdhcinfo; - sdhcinfo = sdhc; - - /* Read the vendor/device ID from the CIS */ - vendevid = bcmsdh_query_device(sdh); - /* try to attach to the target device */ - if (!(sdhc->ch = drvinfo.attach((vendevid >> 16), - (vendevid & 0xFFFF), 0, 0, 0, 0, - (void *)regs, NULL, sdh))) { - SDLX_MSG(("%s: device attach failed\n", __FUNCTION__)); - goto err; - } - - return 0; - - /* error handling */ -err: - if (sdhc) { - if (sdhc->sdh) - bcmsdh_detach(sdhc->osh, sdhc->sdh); - MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); - } - if (osh) - osl_detach(osh); - return -ENODEV; -} - -#ifndef BCMLXSDMMC -static -#endif /* BCMLXSDMMC */ -int bcmsdh_remove(struct device *dev) -{ - bcmsdh_hc_t *sdhc, *prev; - osl_t *osh; - - sdhc = sdhcinfo; - drvinfo.detach(sdhc->ch); - bcmsdh_detach(sdhc->osh, sdhc->sdh); - - /* find the SDIO Host Controller state for this pdev and take it out from the list */ - for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { - if (sdhc->dev == (void *)dev) { - if (prev) - prev->next = sdhc->next; - else - sdhcinfo = NULL; - break; - } - prev = sdhc; - } - if (!sdhc) { - SDLX_MSG(("%s: failed\n", __FUNCTION__)); - return 0; - } - - /* release SDIO Host Controller info */ - osh = sdhc->osh; - MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); - osl_detach(osh); - -#if !defined(BCMLXSDMMC) || defined(OOB_INTR_ONLY) - dev_set_drvdata(dev, NULL); -#endif /* !defined(BCMLXSDMMC) || defined(OOB_INTR_ONLY) */ - - return 0; -} - -#else /* BCMPLATFORM_BUS */ - -#if !defined(BCMLXSDMMC) -/* forward declarations for PCI probe and remove functions. */ -static int __devinit bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent); -static void __devexit bcmsdh_pci_remove(struct pci_dev *pdev); - -/** - * pci id table - */ -static struct pci_device_id bcmsdh_pci_devid[] __devinitdata = { - { vendor: PCI_ANY_ID, - device: PCI_ANY_ID, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID, - class: 0, - class_mask: 0, - driver_data: 0, - }, - { 0, } -}; -MODULE_DEVICE_TABLE(pci, bcmsdh_pci_devid); - -/** - * SDIO Host Controller pci driver info - */ -static struct pci_driver bcmsdh_pci_driver = { - node: {}, - name: "bcmsdh", - id_table: bcmsdh_pci_devid, - probe: bcmsdh_pci_probe, - remove: bcmsdh_pci_remove, -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) - save_state: NULL, -#endif - suspend: NULL, - resume: NULL, - }; - - -extern uint sd_pci_slot; /* Force detection to a particular PCI */ - /* slot only . Allows for having multiple */ - /* WL devices at once in a PC */ - /* Only one instance of dhd will be */ - /* usable at a time */ - /* Upper word is bus number, */ - /* lower word is slot number */ - /* Default value of 0xffffffff turns this */ - /* off */ -module_param(sd_pci_slot, uint, 0); - - -/** - * Detect supported SDIO Host Controller and attach if found. - * - * Determine if the device described by pdev is a supported SDIO Host - * Controller. If so, attach to it and attach to the target device. - */ -static int __devinit -bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - osl_t *osh = NULL; - bcmsdh_hc_t *sdhc = NULL; - ulong regs; - bcmsdh_info_t *sdh = NULL; - int rc; - - if (sd_pci_slot != 0xFFFFffff) { - if (pdev->bus->number != (sd_pci_slot>>16) || - PCI_SLOT(pdev->devfn) != (sd_pci_slot&0xffff)) { - SDLX_MSG(("%s: %s: bus %X, slot %X, vend %X, dev %X\n", - __FUNCTION__, - bcmsdh_chipmatch(pdev->vendor, pdev->device) - ?"Found compatible SDIOHC" - :"Probing unknown device", - pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor, - pdev->device)); - return -ENODEV; - } - SDLX_MSG(("%s: %s: bus %X, slot %X, vendor %X, device %X (good PCI location)\n", - __FUNCTION__, - bcmsdh_chipmatch(pdev->vendor, pdev->device) - ?"Using compatible SDIOHC" - :"WARNING, forced use of unkown device", - pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor, pdev->device)); - } - - if ((pdev->vendor == VENDOR_TI) && ((pdev->device == PCIXX21_FLASHMEDIA_ID) || - (pdev->device == PCIXX21_FLASHMEDIA0_ID))) { - uint32 config_reg; - - SDLX_MSG(("%s: Disabling TI FlashMedia Controller.\n", __FUNCTION__)); - if (!(osh = osl_attach(pdev, PCI_BUS, FALSE))) { - SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__)); - goto err; - } - - config_reg = OSL_PCI_READ_CONFIG(osh, 0x4c, 4); - - /* - * Set MMC_SD_DIS bit in FlashMedia Controller. - * Disbling the SD/MMC Controller in the FlashMedia Controller - * allows the Standard SD Host Controller to take over control - * of the SD Slot. - */ - config_reg |= 0x02; - OSL_PCI_WRITE_CONFIG(osh, 0x4c, 4, config_reg); - osl_detach(osh); - } - /* match this pci device with what we support */ - /* we can't solely rely on this to believe it is our SDIO Host Controller! */ - if (!bcmsdh_chipmatch(pdev->vendor, pdev->device)) { - if (pdev->vendor == VENDOR_BROADCOM) { - SDLX_MSG(("%s: Unknown Broadcom device (vendor: %#x, device: %#x).\n", - __FUNCTION__, pdev->vendor, pdev->device)); - } - return -ENODEV; - } - - /* this is a pci device we might support */ - SDLX_MSG(("%s: Found possible SDIO Host Controller: bus %d slot %d func %d irq %d\n", - __FUNCTION__, - pdev->bus->number, PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn), pdev->irq)); - - /* use bcmsdh_query_device() to get the vendor ID of the target device so - * it will eventually appear in the Broadcom string on the console - */ - - /* allocate SDIO Host Controller state info */ - if (!(osh = osl_attach(pdev, PCI_BUS, FALSE))) { - SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__)); - goto err; - } - if (!(sdhc = MALLOC(osh, sizeof(bcmsdh_hc_t)))) { - SDLX_MSG(("%s: out of memory, allocated %d bytes\n", - __FUNCTION__, - MALLOCED(osh))); - goto err; - } - bzero(sdhc, sizeof(bcmsdh_hc_t)); - sdhc->osh = osh; - - sdhc->dev = pdev; - - /* map to address where host can access */ - pci_set_master(pdev); - rc = pci_enable_device(pdev); - if (rc) { - SDLX_MSG(("%s: Cannot enable PCI device\n", __FUNCTION__)); - goto err; - } - if (!(sdh = bcmsdh_attach(osh, (void *)(uintptr)pci_resource_start(pdev, 0), - (void **)®s, pdev->irq))) { - SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); - goto err; - } - - sdhc->sdh = sdh; - - /* try to attach to the target device */ - if (!(sdhc->ch = drvinfo.attach(VENDOR_BROADCOM, /* pdev->vendor, */ - bcmsdh_query_device(sdh) & 0xFFFF, 0, 0, 0, 0, - (void *)regs, NULL, sdh))) { - SDLX_MSG(("%s: device attach failed\n", __FUNCTION__)); - goto err; - } - - /* chain SDIO Host Controller info together */ - sdhc->next = sdhcinfo; - sdhcinfo = sdhc; - - return 0; - - /* error handling */ -err: - if (sdhc) { - if (sdhc->sdh) - bcmsdh_detach(sdhc->osh, sdhc->sdh); - MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); - } - if (osh) - osl_detach(osh); - return -ENODEV; -} - - -/** - * Detach from target devices and SDIO Host Controller - */ -static void __devexit -bcmsdh_pci_remove(struct pci_dev *pdev) -{ - bcmsdh_hc_t *sdhc, *prev; - osl_t *osh; - - /* find the SDIO Host Controller state for this pdev and take it out from the list */ - for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { - if (sdhc->dev == pdev) { - if (prev) - prev->next = sdhc->next; - else - sdhcinfo = NULL; - break; - } - prev = sdhc; - } - if (!sdhc) - return; - - drvinfo.detach(sdhc->ch); - - bcmsdh_detach(sdhc->osh, sdhc->sdh); - - /* release SDIO Host Controller info */ - osh = sdhc->osh; - MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); - osl_detach(osh); -} -#endif /* BCMLXSDMMC */ -#endif /* BCMPLATFORM_BUS */ - -extern int sdio_function_init(void); - -int -bcmsdh_register(bcmsdh_driver_t *driver) -{ - int error = 0; - - drvinfo = *driver; - -#if defined(BCMPLATFORM_BUS) - SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n")); - error = sdio_function_init(); - return error; -#endif /* defined(BCMPLATFORM_BUS) */ - -#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) - if (!(error = pci_module_init(&bcmsdh_pci_driver))) - return 0; -#else - if (!(error = pci_register_driver(&bcmsdh_pci_driver))) - return 0; -#endif - - SDLX_MSG(("%s: pci_module_init failed 0x%x\n", __FUNCTION__, error)); -#endif /* BCMPLATFORM_BUS */ - - return error; -} - -extern void sdio_function_cleanup(void); - -void -bcmsdh_unregister(void) -{ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) - if (bcmsdh_pci_driver.node.next) -#endif - -#if defined(BCMLXSDMMC) - sdio_function_cleanup(); -#endif /* BCMLXSDMMC */ - -#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) - pci_unregister_driver(&bcmsdh_pci_driver); -#endif /* BCMPLATFORM_BUS */ -} - -#if defined(OOB_INTR_ONLY) -void bcmsdh_oob_intr_set(bool enable) -{ - static bool curstate = 1; - unsigned long flags; - - spin_lock_irqsave(&sdhcinfo->irq_lock, flags); - if (curstate != enable) { - if (enable) - enable_irq(sdhcinfo->oob_irq); - else - disable_irq_nosync(sdhcinfo->oob_irq); - curstate = enable; - } - spin_unlock_irqrestore(&sdhcinfo->irq_lock, flags); -} - -static irqreturn_t wlan_oob_irq(int irq, void *dev_id) -{ - dhd_pub_t *dhdp; - - dhdp = (dhd_pub_t *)dev_get_drvdata(sdhcinfo->dev); - - bcmsdh_oob_intr_set(0); - - if (dhdp == NULL) { - SDLX_MSG(("Out of band GPIO interrupt fired way too early\n")); - return IRQ_HANDLED; - } - - dhdsdio_isr((void *)dhdp->bus); - - return IRQ_HANDLED; -} - -int bcmsdh_register_oob_intr(void * dhdp) -{ - int error = 0; - - SDLX_MSG(("%s Enter \n", __FUNCTION__)); - - /* IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE; */ - - dev_set_drvdata(sdhcinfo->dev, dhdp); - - if (!sdhcinfo->oob_irq_registered) { - SDLX_MSG(("%s IRQ=%d Type=%X \n", __FUNCTION__, - (int)sdhcinfo->oob_irq, (int)sdhcinfo->oob_flags)); - /* Refer to customer Host IRQ docs about proper irqflags definition */ - error = request_irq(sdhcinfo->oob_irq, wlan_oob_irq, sdhcinfo->oob_flags, - "bcmsdh_sdmmc", NULL); - if (error) - return -ENODEV; - - enable_irq_wake(sdhcinfo->oob_irq); - sdhcinfo->oob_irq_registered = TRUE; - sdhcinfo->oob_irq_enable_flag = TRUE; - } - - return 0; -} - -void bcmsdh_set_irq(int flag) -{ - if (sdhcinfo->oob_irq_registered && sdhcinfo->oob_irq_enable_flag != flag) { - SDLX_MSG(("%s Flag = %d", __FUNCTION__, flag)); - sdhcinfo->oob_irq_enable_flag = flag; - if (flag) { - enable_irq(sdhcinfo->oob_irq); - enable_irq_wake(sdhcinfo->oob_irq); - } else { - disable_irq_wake(sdhcinfo->oob_irq); - disable_irq(sdhcinfo->oob_irq); - } - } -} - -void bcmsdh_unregister_oob_intr(void) -{ - SDLX_MSG(("%s: Enter\n", __FUNCTION__)); - - if (sdhcinfo->oob_irq_registered == TRUE) { - bcmsdh_set_irq(FALSE); - free_irq(sdhcinfo->oob_irq, NULL); - sdhcinfo->oob_irq_registered = FALSE; - } -} -#endif /* defined(OOB_INTR_ONLY) */ - -#if defined(BCMLXSDMMC) -void *bcmsdh_get_drvdata(void) -{ - if (!sdhcinfo) - return NULL; - return dev_get_drvdata(sdhcinfo->dev); -} -#endif - -/* Module parameters specific to each host-controller driver */ - -extern uint sd_msglevel; /* Debug message level */ -module_param(sd_msglevel, uint, 0); - -extern uint sd_power; /* 0 = SD Power OFF, 1 = SD Power ON. */ -module_param(sd_power, uint, 0); - -extern uint sd_clock; /* SD Clock Control, 0 = SD Clock OFF, 1 = SD Clock ON */ -module_param(sd_clock, uint, 0); - -extern uint sd_divisor; /* Divisor (-1 means external clock) */ -module_param(sd_divisor, uint, 0); - -extern uint sd_sdmode; /* Default is SD4, 0=SPI, 1=SD1, 2=SD4 */ -module_param(sd_sdmode, uint, 0); - -extern uint sd_hiok; /* Ok to use hi-speed mode */ -module_param(sd_hiok, uint, 0); - -extern uint sd_f2_blocksize; -module_param(sd_f2_blocksize, int, 0); - -#ifdef BCMSDIOH_STD -extern int sd_uhsimode; -module_param(sd_uhsimode, int, 0); -#endif - -#ifdef BCMSDIOH_TXGLOM -extern uint sd_txglom; -module_param(sd_txglom, uint, 0); -#endif - -#ifdef BCMSDH_MODULE -EXPORT_SYMBOL(bcmsdh_attach); -EXPORT_SYMBOL(bcmsdh_detach); -EXPORT_SYMBOL(bcmsdh_intr_query); -EXPORT_SYMBOL(bcmsdh_intr_enable); -EXPORT_SYMBOL(bcmsdh_intr_disable); -EXPORT_SYMBOL(bcmsdh_intr_reg); -EXPORT_SYMBOL(bcmsdh_intr_dereg); - -#if defined(DHD_DEBUG) -EXPORT_SYMBOL(bcmsdh_intr_pending); -#endif - -EXPORT_SYMBOL(bcmsdh_devremove_reg); -EXPORT_SYMBOL(bcmsdh_cfg_read); -EXPORT_SYMBOL(bcmsdh_cfg_write); -EXPORT_SYMBOL(bcmsdh_cis_read); -EXPORT_SYMBOL(bcmsdh_reg_read); -EXPORT_SYMBOL(bcmsdh_reg_write); -EXPORT_SYMBOL(bcmsdh_regfail); -EXPORT_SYMBOL(bcmsdh_send_buf); -EXPORT_SYMBOL(bcmsdh_recv_buf); - -EXPORT_SYMBOL(bcmsdh_rwdata); -EXPORT_SYMBOL(bcmsdh_abort); -EXPORT_SYMBOL(bcmsdh_query_device); -EXPORT_SYMBOL(bcmsdh_query_iofnum); -EXPORT_SYMBOL(bcmsdh_iovar_op); -EXPORT_SYMBOL(bcmsdh_register); -EXPORT_SYMBOL(bcmsdh_unregister); -EXPORT_SYMBOL(bcmsdh_chipmatch); -EXPORT_SYMBOL(bcmsdh_reset); -EXPORT_SYMBOL(bcmsdh_waitlockfree); - -EXPORT_SYMBOL(bcmsdh_get_dstatus); -EXPORT_SYMBOL(bcmsdh_cfg_read_word); -EXPORT_SYMBOL(bcmsdh_cfg_write_word); -EXPORT_SYMBOL(bcmsdh_cur_sbwad); -EXPORT_SYMBOL(bcmsdh_chipinfo); - -#endif /* BCMSDH_MODULE */ diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c deleted file mode 100644 index db051a41f7b9..000000000000 --- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c +++ /dev/null @@ -1,1421 +0,0 @@ -/* - * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdh_sdmmc.c 351910 2012-08-21 22:39:46Z $ - */ -#include - -#include -#include -#include -#include -#include /* SDIO Device and Protocol Specs */ -#include /* Standard SDIO Host Controller Specification */ -#include /* bcmsdh to/from specific controller APIs */ -#include /* ioctl/iovars */ - -#include -#include -#include -#include - -#include -#include - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) -#include -extern volatile bool dhd_mmc_suspend; -#endif -#include "bcmsdh_sdmmc.h" - -#ifndef BCMSDH_MODULE -extern int sdio_function_init(void); -extern void sdio_function_cleanup(void); -#endif /* BCMSDH_MODULE */ - -#if !defined(OOB_INTR_ONLY) -static void IRQHandler(struct sdio_func *func); -static void IRQHandlerF2(struct sdio_func *func); -#endif /* !defined(OOB_INTR_ONLY) */ -static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, uint32 regaddr); -extern int sdio_reset_comm(struct mmc_card *card); - -extern PBCMSDH_SDMMC_INSTANCE gInstance; - -uint sd_sdmode = SDIOH_MODE_SD4; /* Use SD4 mode by default */ -uint sd_f2_blocksize = 512; /* Default blocksize */ - -uint sd_divisor = 2; /* Default 48MHz/2 = 24MHz */ - -uint sd_power = 1; /* Default to SD Slot powered ON */ -uint sd_clock = 1; /* Default to SD Clock turned ON */ -uint sd_hiok = FALSE; /* Don't use hi-speed mode by default */ -uint sd_msglevel = 0x01; -uint sd_use_dma = TRUE; -DHD_PM_RESUME_WAIT_INIT(sdioh_request_byte_wait); -DHD_PM_RESUME_WAIT_INIT(sdioh_request_word_wait); -DHD_PM_RESUME_WAIT_INIT(sdioh_request_packet_wait); -DHD_PM_RESUME_WAIT_INIT(sdioh_request_buffer_wait); - -#define DMA_ALIGN_MASK 0x03 - -int sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data); - -static int -sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd) -{ - int err_ret; - uint32 fbraddr; - uint8 func; - - sd_trace(("%s\n", __FUNCTION__)); - - /* Get the Card's common CIS address */ - sd->com_cis_ptr = sdioh_sdmmc_get_cisaddr(sd, SDIOD_CCCR_CISPTR_0); - sd->func_cis_ptr[0] = sd->com_cis_ptr; - sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __FUNCTION__, sd->com_cis_ptr)); - - /* Get the Card's function CIS (for each function) */ - for (fbraddr = SDIOD_FBR_STARTADDR, func = 1; - func <= sd->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) { - sd->func_cis_ptr[func] = sdioh_sdmmc_get_cisaddr(sd, SDIOD_FBR_CISPTR_0 + fbraddr); - sd_info(("%s: Function %d CIS Ptr = 0x%x\n", - __FUNCTION__, func, sd->func_cis_ptr[func])); - } - - sd->func_cis_ptr[0] = sd->com_cis_ptr; - sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __FUNCTION__, sd->com_cis_ptr)); - - /* Enable Function 1 */ - sdio_claim_host(gInstance->func[1]); - err_ret = sdio_enable_func(gInstance->func[1]); - sdio_release_host(gInstance->func[1]); - if (err_ret) { - sd_err(("bcmsdh_sdmmc: Failed to enable F1 Err: 0x%08x", err_ret)); - } - - return FALSE; -} - -/* - * Public entry points & extern's - */ -extern sdioh_info_t * -sdioh_attach(osl_t *osh, void *bar0, uint irq) -{ - sdioh_info_t *sd; - int err_ret; - - sd_trace(("%s\n", __FUNCTION__)); - - if (gInstance == NULL) { - sd_err(("%s: SDIO Device not present\n", __FUNCTION__)); - return NULL; - } - - if ((sd = (sdioh_info_t *)MALLOC(osh, sizeof(sdioh_info_t))) == NULL) { - sd_err(("sdioh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh))); - return NULL; - } - bzero((char *)sd, sizeof(sdioh_info_t)); - sd->osh = osh; - if (sdioh_sdmmc_osinit(sd) != 0) { - sd_err(("%s:sdioh_sdmmc_osinit() failed\n", __FUNCTION__)); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return NULL; - } - - sd->num_funcs = 2; - sd->sd_blockmode = TRUE; - sd->use_client_ints = TRUE; - sd->client_block_size[0] = 64; - sd->use_rxchain = FALSE; - - gInstance->sd = sd; - - /* Claim host controller */ - sdio_claim_host(gInstance->func[1]); - - sd->client_block_size[1] = 64; - err_ret = sdio_set_block_size(gInstance->func[1], 64); - if (err_ret) { - sd_err(("bcmsdh_sdmmc: Failed to set F1 blocksize\n")); - } - - /* Release host controller F1 */ - sdio_release_host(gInstance->func[1]); - - if (gInstance->func[2]) { - /* Claim host controller F2 */ - sdio_claim_host(gInstance->func[2]); - - sd->client_block_size[2] = sd_f2_blocksize; - err_ret = sdio_set_block_size(gInstance->func[2], sd_f2_blocksize); - if (err_ret) { - sd_err(("bcmsdh_sdmmc: Failed to set F2 blocksize to %d\n", - sd_f2_blocksize)); - } - - /* Release host controller F2 */ - sdio_release_host(gInstance->func[2]); - } - - sdioh_sdmmc_card_enablefuncs(sd); - - sd_trace(("%s: Done\n", __FUNCTION__)); - return sd; -} - - -extern SDIOH_API_RC -sdioh_detach(osl_t *osh, sdioh_info_t *sd) -{ - sd_trace(("%s\n", __FUNCTION__)); - - if (sd) { - - /* Disable Function 2 */ - sdio_claim_host(gInstance->func[2]); - sdio_disable_func(gInstance->func[2]); - sdio_release_host(gInstance->func[2]); - - /* Disable Function 1 */ - if (gInstance->func[1]) { - sdio_claim_host(gInstance->func[1]); - sdio_disable_func(gInstance->func[1]); - sdio_release_host(gInstance->func[1]); - } - - gInstance->func[1] = NULL; - gInstance->func[2] = NULL; - - /* deregister irq */ - sdioh_sdmmc_osfree(sd); - - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - } - return SDIOH_API_RC_SUCCESS; -} - -#if defined(OOB_INTR_ONLY) && defined(HW_OOB) - -extern SDIOH_API_RC -sdioh_enable_func_intr(void) -{ - uint8 reg; - int err; - - if (gInstance->func[0]) { - sdio_claim_host(gInstance->func[0]); - - reg = sdio_readb(gInstance->func[0], SDIOD_CCCR_INTEN, &err); - if (err) { - sd_err(("%s: error for read SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err)); - sdio_release_host(gInstance->func[0]); - return SDIOH_API_RC_FAIL; - } - - /* Enable F1 and F2 interrupts, set master enable */ - reg |= (INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN | INTR_CTL_MASTER_EN); - - sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err); - sdio_release_host(gInstance->func[0]); - - if (err) { - sd_err(("%s: error for write SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err)); - return SDIOH_API_RC_FAIL; - } - } - - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_disable_func_intr(void) -{ - uint8 reg; - int err; - - if (gInstance->func[0]) { - sdio_claim_host(gInstance->func[0]); - reg = sdio_readb(gInstance->func[0], SDIOD_CCCR_INTEN, &err); - if (err) { - sd_err(("%s: error for read SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err)); - sdio_release_host(gInstance->func[0]); - return SDIOH_API_RC_FAIL; - } - - reg &= ~(INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN); - /* Disable master interrupt with the last function interrupt */ - if (!(reg & 0xFE)) - reg = 0; - sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err); - - sdio_release_host(gInstance->func[0]); - if (err) { - sd_err(("%s: error for write SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err)); - return SDIOH_API_RC_FAIL; - } - } - return SDIOH_API_RC_SUCCESS; -} -#endif /* defined(OOB_INTR_ONLY) && defined(HW_OOB) */ - -/* Configure callback to client when we recieve client interrupt */ -extern SDIOH_API_RC -sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - if (fn == NULL) { - sd_err(("%s: interrupt handler is NULL, not registering\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } -#if !defined(OOB_INTR_ONLY) - sd->intr_handler = fn; - sd->intr_handler_arg = argh; - sd->intr_handler_valid = TRUE; - - /* register and unmask irq */ - if (gInstance->func[2]) { - sdio_claim_host(gInstance->func[2]); - sdio_claim_irq(gInstance->func[2], IRQHandlerF2); - sdio_release_host(gInstance->func[2]); - } - - if (gInstance->func[1]) { - sdio_claim_host(gInstance->func[1]); - sdio_claim_irq(gInstance->func[1], IRQHandler); - sdio_release_host(gInstance->func[1]); - } -#elif defined(HW_OOB) - sdioh_enable_func_intr(); -#endif /* !defined(OOB_INTR_ONLY) */ - - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_interrupt_deregister(sdioh_info_t *sd) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - -#if !defined(OOB_INTR_ONLY) - if (gInstance->func[1]) { - /* register and unmask irq */ - sdio_claim_host(gInstance->func[1]); - sdio_release_irq(gInstance->func[1]); - sdio_release_host(gInstance->func[1]); - } - - if (gInstance->func[2]) { - /* Claim host controller F2 */ - sdio_claim_host(gInstance->func[2]); - sdio_release_irq(gInstance->func[2]); - /* Release host controller F2 */ - sdio_release_host(gInstance->func[2]); - } - - sd->intr_handler_valid = FALSE; - sd->intr_handler = NULL; - sd->intr_handler_arg = NULL; -#elif defined(HW_OOB) - sdioh_disable_func_intr(); -#endif /* !defined(OOB_INTR_ONLY) */ - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - *onoff = sd->client_intr_enabled; - return SDIOH_API_RC_SUCCESS; -} - -#if defined(DHD_DEBUG) -extern bool -sdioh_interrupt_pending(sdioh_info_t *sd) -{ - return (0); -} -#endif - -uint -sdioh_query_iofnum(sdioh_info_t *sd) -{ - return sd->num_funcs; -} - -/* IOVar table */ -enum { - IOV_MSGLEVEL = 1, - IOV_BLOCKMODE, - IOV_BLOCKSIZE, - IOV_DMA, - IOV_USEINTS, - IOV_NUMINTS, - IOV_NUMLOCALINTS, - IOV_HOSTREG, - IOV_DEVREG, - IOV_DIVISOR, - IOV_SDMODE, - IOV_HISPEED, - IOV_HCIREGS, - IOV_POWER, - IOV_CLOCK, - IOV_RXCHAIN -}; - -const bcm_iovar_t sdioh_iovars[] = { - {"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 }, - {"sd_blockmode", IOV_BLOCKMODE, 0, IOVT_BOOL, 0 }, - {"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0 }, /* ((fn << 16) | size) */ - {"sd_dma", IOV_DMA, 0, IOVT_BOOL, 0 }, - {"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0 }, - {"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0 }, - {"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32, 0 }, - {"sd_hostreg", IOV_HOSTREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_divisor", IOV_DIVISOR, 0, IOVT_UINT32, 0 }, - {"sd_power", IOV_POWER, 0, IOVT_UINT32, 0 }, - {"sd_clock", IOV_CLOCK, 0, IOVT_UINT32, 0 }, - {"sd_mode", IOV_SDMODE, 0, IOVT_UINT32, 100}, - {"sd_highspeed", IOV_HISPEED, 0, IOVT_UINT32, 0 }, - {"sd_rxchain", IOV_RXCHAIN, 0, IOVT_BOOL, 0 }, - {NULL, 0, 0, 0, 0 } -}; - -int -sdioh_iovar_op(sdioh_info_t *si, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - const bcm_iovar_t *vi = NULL; - int bcmerror = 0; - int val_size; - int32 int_val = 0; - bool bool_val; - uint32 actionid; - - ASSERT(name); - ASSERT(len >= 0); - - /* Get must have return space; Set does not take qualifiers */ - ASSERT(set || (arg && len)); - ASSERT(!set || (!params && !plen)); - - sd_trace(("%s: Enter (%s %s)\n", __FUNCTION__, (set ? "set" : "get"), name)); - - if ((vi = bcm_iovar_lookup(sdioh_iovars, name)) == NULL) { - bcmerror = BCME_UNSUPPORTED; - goto exit; - } - - if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, set)) != 0) - goto exit; - - /* Set up params so get and set can share the convenience variables */ - if (params == NULL) { - params = arg; - plen = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - val_size = sizeof(int); - - if (plen >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); - - bool_val = (int_val != 0) ? TRUE : FALSE; - BCM_REFERENCE(bool_val); - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - switch (actionid) { - case IOV_GVAL(IOV_MSGLEVEL): - int_val = (int32)sd_msglevel; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_MSGLEVEL): - sd_msglevel = int_val; - break; - - case IOV_GVAL(IOV_BLOCKMODE): - int_val = (int32)si->sd_blockmode; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_BLOCKMODE): - si->sd_blockmode = (bool)int_val; - /* Haven't figured out how to make non-block mode with DMA */ - break; - - case IOV_GVAL(IOV_BLOCKSIZE): - if ((uint32)int_val > si->num_funcs) { - bcmerror = BCME_BADARG; - break; - } - int_val = (int32)si->client_block_size[int_val]; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_BLOCKSIZE): - { - uint func = ((uint32)int_val >> 16); - uint blksize = (uint16)int_val; - uint maxsize; - - if (func > si->num_funcs) { - bcmerror = BCME_BADARG; - break; - } - - switch (func) { - case 0: maxsize = 32; break; - case 1: maxsize = BLOCK_SIZE_4318; break; - case 2: maxsize = BLOCK_SIZE_4328; break; - default: maxsize = 0; - } - if (blksize > maxsize) { - bcmerror = BCME_BADARG; - break; - } - if (!blksize) { - blksize = maxsize; - } - - /* Now set it */ - si->client_block_size[func] = blksize; - - break; - } - - case IOV_GVAL(IOV_RXCHAIN): - int_val = (int32)si->use_rxchain; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_DMA): - int_val = (int32)si->sd_use_dma; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DMA): - si->sd_use_dma = (bool)int_val; - break; - - case IOV_GVAL(IOV_USEINTS): - int_val = (int32)si->use_client_ints; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_USEINTS): - si->use_client_ints = (bool)int_val; - if (si->use_client_ints) - si->intmask |= CLIENT_INTR; - else - si->intmask &= ~CLIENT_INTR; - - break; - - case IOV_GVAL(IOV_DIVISOR): - int_val = (uint32)sd_divisor; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DIVISOR): - sd_divisor = int_val; - break; - - case IOV_GVAL(IOV_POWER): - int_val = (uint32)sd_power; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_POWER): - sd_power = int_val; - break; - - case IOV_GVAL(IOV_CLOCK): - int_val = (uint32)sd_clock; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_CLOCK): - sd_clock = int_val; - break; - - case IOV_GVAL(IOV_SDMODE): - int_val = (uint32)sd_sdmode; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_SDMODE): - sd_sdmode = int_val; - break; - - case IOV_GVAL(IOV_HISPEED): - int_val = (uint32)sd_hiok; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_HISPEED): - sd_hiok = int_val; - break; - - case IOV_GVAL(IOV_NUMINTS): - int_val = (int32)si->intrcount; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_NUMLOCALINTS): - int_val = (int32)0; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_HOSTREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - - if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) { - sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset)); - bcmerror = BCME_BADARG; - break; - } - - sd_trace(("%s: rreg%d at offset %d\n", __FUNCTION__, - (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32), - sd_ptr->offset)); - if (sd_ptr->offset & 1) - int_val = 8; /* sdioh_sdmmc_rreg8(si, sd_ptr->offset); */ - else if (sd_ptr->offset & 2) - int_val = 16; /* sdioh_sdmmc_rreg16(si, sd_ptr->offset); */ - else - int_val = 32; /* sdioh_sdmmc_rreg(si, sd_ptr->offset); */ - - bcopy(&int_val, arg, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_HOSTREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - - if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) { - sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset)); - bcmerror = BCME_BADARG; - break; - } - - sd_trace(("%s: wreg%d value 0x%08x at offset %d\n", __FUNCTION__, sd_ptr->value, - (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32), - sd_ptr->offset)); - break; - } - - case IOV_GVAL(IOV_DEVREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - uint8 data = 0; - - if (sdioh_cfg_read(si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = BCME_SDIO_ERROR; - break; - } - - int_val = (int)data; - bcopy(&int_val, arg, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_DEVREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - uint8 data = (uint8)sd_ptr->value; - - if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = BCME_SDIO_ERROR; - break; - } - break; - } - - default: - bcmerror = BCME_UNSUPPORTED; - break; - } -exit: - - return bcmerror; -} - -#if defined(OOB_INTR_ONLY) && defined(HW_OOB) - -SDIOH_API_RC -sdioh_enable_hw_oob_intr(sdioh_info_t *sd, bool enable) -{ - SDIOH_API_RC status; - uint8 data; - - if (enable) - data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE | SDIO_SEPINT_ACT_HI; - else - data = SDIO_SEPINT_ACT_HI; - - status = sdioh_request_byte(sd, SDIOH_WRITE, 0, SDIOD_CCCR_BRCM_SEPINT, &data); - return status; -} -#endif /* defined(OOB_INTR_ONLY) && defined(HW_OOB) */ - -extern SDIOH_API_RC -sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) -{ - SDIOH_API_RC status; - /* No lock needed since sdioh_request_byte does locking */ - status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data); - return status; -} - -extern SDIOH_API_RC -sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) -{ - /* No lock needed since sdioh_request_byte does locking */ - SDIOH_API_RC status; - status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data); - return status; -} - -static int -sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, uint32 regaddr) -{ - /* read 24 bits and return valid 17 bit addr */ - int i; - uint32 scratch, regdata; - uint8 *ptr = (uint8 *)&scratch; - for (i = 0; i < 3; i++) { - if ((sdioh_sdmmc_card_regread (sd, 0, regaddr, 1, ®data)) != SUCCESS) - sd_err(("%s: Can't read!\n", __FUNCTION__)); - - *ptr++ = (uint8) regdata; - regaddr++; - } - - /* Only the lower 17-bits are valid */ - scratch = ltoh32(scratch); - scratch &= 0x0001FFFF; - return (scratch); -} - -extern SDIOH_API_RC -sdioh_cis_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 length) -{ - uint32 count; - int offset; - uint32 foo; - uint8 *cis = cisd; - - sd_trace(("%s: Func = %d\n", __FUNCTION__, func)); - - if (!sd->func_cis_ptr[func]) { - bzero(cis, length); - sd_err(("%s: no func_cis_ptr[%d]\n", __FUNCTION__, func)); - return SDIOH_API_RC_FAIL; - } - - sd_err(("%s: func_cis_ptr[%d]=0x%04x\n", __FUNCTION__, func, sd->func_cis_ptr[func])); - - for (count = 0; count < length; count++) { - offset = sd->func_cis_ptr[func] + count; - if (sdioh_sdmmc_card_regread (sd, 0, offset, 1, &foo) < 0) { - sd_err(("%s: regread failed: Can't read CIS\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } - - *cis = (uint8)(foo & 0xff); - cis++; - } - - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte) -{ - int err_ret; - - sd_info(("%s: rw=%d, func=%d, addr=0x%05x\n", __FUNCTION__, rw, func, regaddr)); - - DHD_PM_RESUME_WAIT(sdioh_request_byte_wait); - DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); - if(rw) { /* CMD52 Write */ - if (func == 0) { - /* Can only directly write to some F0 registers. Handle F2 enable - * as a special case. - */ - if (regaddr == SDIOD_CCCR_IOEN) { - if (gInstance->func[2]) { - sdio_claim_host(gInstance->func[2]); - if (*byte & SDIO_FUNC_ENABLE_2) { - /* Enable Function 2 */ - err_ret = sdio_enable_func(gInstance->func[2]); - if (err_ret) { - sd_err(("bcmsdh_sdmmc: enable F2 failed:%d", - err_ret)); - } - } else { - /* Disable Function 2 */ - err_ret = sdio_disable_func(gInstance->func[2]); - if (err_ret) { - sd_err(("bcmsdh_sdmmc: Disab F2 failed:%d", - err_ret)); - } - } - sdio_release_host(gInstance->func[2]); - } - } -#if defined(MMC_SDIO_ABORT) - /* to allow abort command through F1 */ - else if (regaddr == SDIOD_CCCR_IOABORT) { - if (gInstance->func[func]) { - sdio_claim_host(gInstance->func[func]); - /* - * this sdio_f0_writeb() can be replaced with another api - * depending upon MMC driver change. - * As of this time, this is temporaray one - */ - sdio_writeb(gInstance->func[func], - *byte, regaddr, &err_ret); - sdio_release_host(gInstance->func[func]); - } - } -#endif /* MMC_SDIO_ABORT */ - else if (regaddr < 0xF0) { - sd_err(("bcmsdh_sdmmc: F0 Wr:0x%02x: write disallowed\n", regaddr)); - } else { - /* Claim host controller, perform F0 write, and release */ - if (gInstance->func[func]) { - sdio_claim_host(gInstance->func[func]); - sdio_f0_writeb(gInstance->func[func], - *byte, regaddr, &err_ret); - sdio_release_host(gInstance->func[func]); - } - } - } else { - /* Claim host controller, perform Fn write, and release */ - if (gInstance->func[func]) { - sdio_claim_host(gInstance->func[func]); - sdio_writeb(gInstance->func[func], *byte, regaddr, &err_ret); - sdio_release_host(gInstance->func[func]); - } - } - } else { /* CMD52 Read */ - /* Claim host controller, perform Fn read, and release */ - if (gInstance->func[func]) { - sdio_claim_host(gInstance->func[func]); - if (func == 0) { - *byte = sdio_f0_readb(gInstance->func[func], regaddr, &err_ret); - } else { - *byte = sdio_readb(gInstance->func[func], regaddr, &err_ret); - } - sdio_release_host(gInstance->func[func]); - } - } - - if (err_ret) { - sd_err(("bcmsdh_sdmmc: Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", - rw ? "Write" : "Read", func, regaddr, *byte, err_ret)); - } - - return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); -} - -extern SDIOH_API_RC -sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint addr, - uint32 *word, uint nbytes) -{ - int err_ret = SDIOH_API_RC_FAIL; - - if (func == 0) { - sd_err(("%s: Only CMD52 allowed to F0.\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } - - sd_info(("%s: cmd_type=%d, rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", - __FUNCTION__, cmd_type, rw, func, addr, nbytes)); - - DHD_PM_RESUME_WAIT(sdioh_request_word_wait); - DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); - /* Claim host controller */ - sdio_claim_host(gInstance->func[func]); - - if(rw) { /* CMD52 Write */ - if (nbytes == 4) { - sdio_writel(gInstance->func[func], *word, addr, &err_ret); - } else if (nbytes == 2) { - sdio_writew(gInstance->func[func], (*word & 0xFFFF), addr, &err_ret); - } else { - sd_err(("%s: Invalid nbytes: %d\n", __FUNCTION__, nbytes)); - } - } else { /* CMD52 Read */ - if (nbytes == 4) { - *word = sdio_readl(gInstance->func[func], addr, &err_ret); - } else if (nbytes == 2) { - *word = sdio_readw(gInstance->func[func], addr, &err_ret) & 0xFFFF; - } else { - sd_err(("%s: Invalid nbytes: %d\n", __FUNCTION__, nbytes)); - } - } - - /* Release host controller */ - sdio_release_host(gInstance->func[func]); - - if (err_ret) { - sd_err(("bcmsdh_sdmmc: Failed to %s word, Err: 0x%08x", - rw ? "Write" : "Read", err_ret)); - } - - return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); -} - -static SDIOH_API_RC -sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func, - uint addr, void *pkt) -{ - bool fifo = (fix_inc == SDIOH_DATA_FIX); - uint32 SGCount = 0; - int err_ret = 0; - void *pnext, *pprev; - uint ttl_len, dma_len, lft_len, xfred_len, pkt_len; - uint blk_num; - struct mmc_request mmc_req; - struct mmc_command mmc_cmd; - struct mmc_data mmc_dat; - - sd_trace(("%s: Enter\n", __FUNCTION__)); - - ASSERT(pkt); - DHD_PM_RESUME_WAIT(sdioh_request_packet_wait); - DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); - - ttl_len = xfred_len = 0; - /* at least 4 bytes alignment of skb buff is guaranteed */ - for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext)) - ttl_len += PKTLEN(sd->osh, pnext); - - if (!sd->use_rxchain || ttl_len <= sd->client_block_size[func]) { - blk_num = 0; - dma_len = 0; - } else { - blk_num = ttl_len / sd->client_block_size[func]; - dma_len = blk_num * sd->client_block_size[func]; - } - lft_len = ttl_len - dma_len; - - sd_trace(("%s: %s %dB to func%d:%08x, %d blks with DMA, %dB leftover\n", - __FUNCTION__, write ? "W" : "R", - ttl_len, func, addr, blk_num, lft_len)); - - if (0 != dma_len) { - memset(&mmc_req, 0, sizeof(struct mmc_request)); - memset(&mmc_cmd, 0, sizeof(struct mmc_command)); - memset(&mmc_dat, 0, sizeof(struct mmc_data)); - - /* Set up DMA descriptors */ - pprev = pkt; - for (pnext = pkt; - pnext && dma_len; - pnext = PKTNEXT(sd->osh, pnext)) { - pkt_len = PKTLEN(sd->osh, pnext); - - if (dma_len > pkt_len) - dma_len -= pkt_len; - else { - pkt_len = xfred_len = dma_len; - dma_len = 0; - pkt = pnext; - } - - sg_set_buf(&sd->sg_list[SGCount++], - (uint8*)PKTDATA(sd->osh, pnext), - pkt_len); - - if (SGCount >= SDIOH_SDMMC_MAX_SG_ENTRIES) { - sd_err(("%s: sg list entries exceed limit\n", - __FUNCTION__)); - return (SDIOH_API_RC_FAIL); - } - } - - mmc_dat.sg = sd->sg_list; - mmc_dat.sg_len = SGCount; - mmc_dat.blksz = sd->client_block_size[func]; - mmc_dat.blocks = blk_num; - mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; - - mmc_cmd.opcode = 53; /* SD_IO_RW_EXTENDED */ - mmc_cmd.arg = write ? 1<<31 : 0; - mmc_cmd.arg |= (func & 0x7) << 28; - mmc_cmd.arg |= 1<<27; - mmc_cmd.arg |= fifo ? 0 : 1<<26; - mmc_cmd.arg |= (addr & 0x1FFFF) << 9; - mmc_cmd.arg |= blk_num & 0x1FF; - mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; - - mmc_req.cmd = &mmc_cmd; - mmc_req.data = &mmc_dat; - - sdio_claim_host(gInstance->func[func]); - mmc_set_data_timeout(&mmc_dat, gInstance->func[func]->card); - mmc_wait_for_req(gInstance->func[func]->card->host, &mmc_req); - sdio_release_host(gInstance->func[func]); - - err_ret = mmc_cmd.error? mmc_cmd.error : mmc_dat.error; - if (0 != err_ret) { - sd_err(("%s:CMD53 %s failed with code %d\n", - __FUNCTION__, - write ? "write" : "read", - err_ret)); - sd_err(("%s:Disabling rxchain and fire it with PIO\n", - __FUNCTION__)); - sd->use_rxchain = FALSE; - pkt = pprev; - lft_len = ttl_len; - } else if (!fifo) { - addr = addr + ttl_len - lft_len - dma_len; - } - } - - /* PIO mode */ - if (0 != lft_len) { - /* Claim host controller */ - sdio_claim_host(gInstance->func[func]); - for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext)) { - uint8 *buf = (uint8*)PKTDATA(sd->osh, pnext) + - xfred_len; - pkt_len = PKTLEN(sd->osh, pnext); - if (0 != xfred_len) { - pkt_len -= xfred_len; - xfred_len = 0; - } - - /* Align Patch */ - if (!write || pkt_len < 32) - pkt_len = (pkt_len + 3) & 0xFFFFFFFC; - else if (pkt_len % DHD_SDALIGN) - pkt_len += DHD_SDALIGN - (pkt_len % DHD_SDALIGN); - -#ifdef CONFIG_MMC_MSM7X00A - if ((pkt_len % 64) == 32) { - sd_trace(("%s: Rounding up TX packet +=32\n", __FUNCTION__)); - pkt_len += 32; - } -#endif /* CONFIG_MMC_MSM7X00A */ - - if ((write) && (!fifo)) - err_ret = sdio_memcpy_toio( - gInstance->func[func], - addr, buf, pkt_len); - else if (write) - err_ret = sdio_memcpy_toio( - gInstance->func[func], - addr, buf, pkt_len); - else if (fifo) - err_ret = sdio_readsb( - gInstance->func[func], - buf, addr, pkt_len); - else - err_ret = sdio_memcpy_fromio( - gInstance->func[func], - buf, addr, pkt_len); - - if (err_ret) - sd_err(("%s: %s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=%d\n", - __FUNCTION__, - (write) ? "TX" : "RX", - pnext, SGCount, addr, pkt_len, err_ret)); - else - sd_trace(("%s: %s xfr'd %p[%d], addr=0x%05x, len=%d\n", - __FUNCTION__, - (write) ? "TX" : "RX", - pnext, SGCount, addr, pkt_len)); - - if (!fifo) - addr += pkt_len; - SGCount ++; - } - sdio_release_host(gInstance->func[func]); - } - - sd_trace(("%s: Exit\n", __FUNCTION__)); - return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); -} - - -/* - * This function takes a buffer or packet, and fixes everything up so that in the - * end, a DMA-able packet is created. - * - * A buffer does not have an associated packet pointer, and may or may not be aligned. - * A packet may consist of a single packet, or a packet chain. If it is a packet chain, - * then all the packets in the chain must be properly aligned. If the packet data is not - * aligned, then there may only be one packet, and in this case, it is copied to a new - * aligned packet. - * - */ -extern SDIOH_API_RC -sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, uint func, - uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt) -{ - SDIOH_API_RC Status; - void *mypkt = NULL; - - sd_trace(("%s: Enter\n", __FUNCTION__)); - - DHD_PM_RESUME_WAIT(sdioh_request_buffer_wait); - DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); - /* Case 1: we don't have a packet. */ - if (pkt == NULL) { - sd_data(("%s: Creating new %s Packet, len=%d\n", - __FUNCTION__, write ? "TX" : "RX", buflen_u)); -#ifdef CONFIG_DHD_USE_STATIC_BUF - if (!(mypkt = PKTGET_STATIC(sd->osh, buflen_u, write ? TRUE : FALSE))) { -#else - if (!(mypkt = PKTGET(sd->osh, buflen_u, write ? TRUE : FALSE))) { -#endif /* CONFIG_DHD_USE_STATIC_BUF */ - sd_err(("%s: PKTGET failed: len %d\n", - __FUNCTION__, buflen_u)); - return SDIOH_API_RC_FAIL; - } - - /* For a write, copy the buffer data into the packet. */ - if (write) { - bcopy(buffer, PKTDATA(sd->osh, mypkt), buflen_u); - } - - Status = sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt); - - /* For a read, copy the packet data back to the buffer. */ - if (!write) { - bcopy(PKTDATA(sd->osh, mypkt), buffer, buflen_u); - } -#ifdef CONFIG_DHD_USE_STATIC_BUF - PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE); -#else - PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE); -#endif /* CONFIG_DHD_USE_STATIC_BUF */ - } else if (((uint32)(PKTDATA(sd->osh, pkt)) & DMA_ALIGN_MASK) != 0) { - /* Case 2: We have a packet, but it is unaligned. */ - - /* In this case, we cannot have a chain. */ - ASSERT(PKTNEXT(sd->osh, pkt) == NULL); - - sd_data(("%s: Creating aligned %s Packet, len=%d\n", - __FUNCTION__, write ? "TX" : "RX", PKTLEN(sd->osh, pkt))); -#ifdef CONFIG_DHD_USE_STATIC_BUF - if (!(mypkt = PKTGET_STATIC(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE))) { -#else - if (!(mypkt = PKTGET(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE))) { -#endif /* CONFIG_DHD_USE_STATIC_BUF */ - sd_err(("%s: PKTGET failed: len %d\n", - __FUNCTION__, PKTLEN(sd->osh, pkt))); - return SDIOH_API_RC_FAIL; - } - - /* For a write, copy the buffer data into the packet. */ - if (write) { - bcopy(PKTDATA(sd->osh, pkt), - PKTDATA(sd->osh, mypkt), - PKTLEN(sd->osh, pkt)); - } - - Status = sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt); - - /* For a read, copy the packet data back to the buffer. */ - if (!write) { - bcopy(PKTDATA(sd->osh, mypkt), - PKTDATA(sd->osh, pkt), - PKTLEN(sd->osh, mypkt)); - } -#ifdef CONFIG_DHD_USE_STATIC_BUF - PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE); -#else - PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE); -#endif /* CONFIG_DHD_USE_STATIC_BUF */ - } else { /* case 3: We have a packet and it is aligned. */ - sd_data(("%s: Aligned %s Packet, direct DMA\n", - __FUNCTION__, write ? "Tx" : "Rx")); - Status = sdioh_request_packet(sd, fix_inc, write, func, addr, pkt); - } - - return (Status); -} - -/* this function performs "abort" for both of host & device */ -extern int -sdioh_abort(sdioh_info_t *sd, uint func) -{ -#if defined(MMC_SDIO_ABORT) - char t_func = (char) func; -#endif /* defined(MMC_SDIO_ABORT) */ - sd_trace(("%s: Enter\n", __FUNCTION__)); - -#if defined(MMC_SDIO_ABORT) - /* issue abort cmd52 command through F1 */ - sdioh_request_byte(sd, SD_IO_OP_WRITE, SDIO_FUNC_0, SDIOD_CCCR_IOABORT, &t_func); -#endif /* defined(MMC_SDIO_ABORT) */ - - sd_trace(("%s: Exit\n", __FUNCTION__)); - return SDIOH_API_RC_SUCCESS; -} - -/* Reset and re-initialize the device */ -int sdioh_sdio_reset(sdioh_info_t *si) -{ - sd_trace(("%s: Enter\n", __FUNCTION__)); - sd_trace(("%s: Exit\n", __FUNCTION__)); - return SDIOH_API_RC_SUCCESS; -} - -/* Disable device interrupt */ -void -sdioh_sdmmc_devintr_off(sdioh_info_t *sd) -{ - sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints)); - sd->intmask &= ~CLIENT_INTR; -} - -/* Enable device interrupt */ -void -sdioh_sdmmc_devintr_on(sdioh_info_t *sd) -{ - sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints)); - sd->intmask |= CLIENT_INTR; -} - -/* Read client card reg */ -int -sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data) -{ - - if ((func == 0) || (regsize == 1)) { - uint8 temp = 0; - - sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp); - *data = temp; - *data &= 0xff; - sd_data(("%s: byte read data=0x%02x\n", - __FUNCTION__, *data)); - } else { - sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, data, regsize); - if (regsize == 2) - *data &= 0xffff; - - sd_data(("%s: word read data=0x%08x\n", - __FUNCTION__, *data)); - } - - return SUCCESS; -} - -#if !defined(OOB_INTR_ONLY) -/* bcmsdh_sdmmc interrupt handler */ -static void IRQHandler(struct sdio_func *func) -{ - sdioh_info_t *sd; - - sd_trace(("bcmsdh_sdmmc: ***IRQHandler\n")); - sd = gInstance->sd; - - ASSERT(sd != NULL); - sdio_release_host(gInstance->func[0]); - - if (sd->use_client_ints) { - sd->intrcount++; - ASSERT(sd->intr_handler); - ASSERT(sd->intr_handler_arg); - (sd->intr_handler)(sd->intr_handler_arg); - } else { - sd_err(("bcmsdh_sdmmc: ***IRQHandler\n")); - - sd_err(("%s: Not ready for intr: enabled %d, handler %p\n", - __FUNCTION__, sd->client_intr_enabled, sd->intr_handler)); - } - - sdio_claim_host(gInstance->func[0]); -} - -/* bcmsdh_sdmmc interrupt handler for F2 (dummy handler) */ -static void IRQHandlerF2(struct sdio_func *func) -{ - sdioh_info_t *sd; - - sd_trace(("bcmsdh_sdmmc: ***IRQHandlerF2\n")); - - sd = gInstance->sd; - - ASSERT(sd != NULL); - BCM_REFERENCE(sd); -} -#endif /* !defined(OOB_INTR_ONLY) */ - -#ifdef NOTUSED -/* Write client card reg */ -static int -sdioh_sdmmc_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 data) -{ - - if ((func == 0) || (regsize == 1)) { - uint8 temp; - - temp = data & 0xff; - sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp); - sd_data(("%s: byte write data=0x%02x\n", - __FUNCTION__, data)); - } else { - if (regsize == 2) - data &= 0xffff; - - sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, &data, regsize); - - sd_data(("%s: word write data=0x%08x\n", - __FUNCTION__, data)); - } - - return SUCCESS; -} -#endif /* NOTUSED */ - -int -sdioh_start(sdioh_info_t *si, int stage) -{ - int ret; - sdioh_info_t *sd = gInstance->sd; - - /* Need to do this stages as we can't enable the interrupt till - downloading of the firmware is complete, other wise polling - sdio access will come in way - */ - if (gInstance->func[0]) { - if (stage == 0) { - /* Since the power to the chip is killed, we will have - re enumerate the device again. Set the block size - and enable the fucntion 1 for in preparation for - downloading the code - */ - /* sdio_reset_comm() - has been fixed in latest kernel/msm.git for Linux - 2.6.27. The implementation prior to that is buggy, and needs broadcom's - patch for it - */ - if ((ret = sdio_reset_comm(gInstance->func[0]->card))) { - sd_err(("%s Failed, error = %d\n", __FUNCTION__, ret)); - return ret; - } - else { - sd->num_funcs = 2; - sd->sd_blockmode = TRUE; - sd->use_client_ints = TRUE; - sd->client_block_size[0] = 64; - - /* Claim host controller */ - sdio_claim_host(gInstance->func[1]); - - sd->client_block_size[1] = 64; - if (sdio_set_block_size(gInstance->func[1], 64)) { - sd_err(("bcmsdh_sdmmc: Failed to set F1 blocksize\n")); - } - - /* Release host controller F1 */ - sdio_release_host(gInstance->func[1]); - - if (gInstance->func[2]) { - /* Claim host controller F2 */ - sdio_claim_host(gInstance->func[2]); - - sd->client_block_size[2] = sd_f2_blocksize; - if (sdio_set_block_size(gInstance->func[2], - sd_f2_blocksize)) { - sd_err(("bcmsdh_sdmmc: Failed to set F2 " - "blocksize to %d\n", sd_f2_blocksize)); - } - - /* Release host controller F2 */ - sdio_release_host(gInstance->func[2]); - } - - sdioh_sdmmc_card_enablefuncs(sd); - } - } else { -#if !defined(OOB_INTR_ONLY) - sdio_claim_host(gInstance->func[0]); - sdio_claim_irq(gInstance->func[2], IRQHandlerF2); - sdio_claim_irq(gInstance->func[1], IRQHandler); - sdio_release_host(gInstance->func[0]); -#else /* defined(OOB_INTR_ONLY) */ -#if defined(HW_OOB) - sdioh_enable_func_intr(); -#endif - bcmsdh_oob_intr_set(TRUE); -#endif /* !defined(OOB_INTR_ONLY) */ - } - } - else - sd_err(("%s Failed\n", __FUNCTION__)); - - return (0); -} - -int -sdioh_stop(sdioh_info_t *si) -{ - /* MSM7201A Android sdio stack has bug with interrupt - So internaly within SDIO stack they are polling - which cause issue when device is turned off. So - unregister interrupt with SDIO stack to stop the - polling - */ - if (gInstance->func[0]) { -#if !defined(OOB_INTR_ONLY) - sdio_claim_host(gInstance->func[0]); - sdio_release_irq(gInstance->func[1]); - sdio_release_irq(gInstance->func[2]); - sdio_release_host(gInstance->func[0]); -#else /* defined(OOB_INTR_ONLY) */ -#if defined(HW_OOB) - sdioh_disable_func_intr(); -#endif - bcmsdh_oob_intr_set(FALSE); -#endif /* !defined(OOB_INTR_ONLY) */ - } - else - sd_err(("%s Failed\n", __FUNCTION__)); - return (0); -} - -int -sdioh_waitlockfree(sdioh_info_t *sd) -{ - return (1); -} diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c deleted file mode 100644 index c93e41c6fb40..000000000000 --- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdh_sdmmc_linux.c 331154 2012-05-04 00:41:40Z $ - */ - -#include -#include -#include /* SDIO Device and Protocol Specs */ -#include /* bcmsdh to/from specific controller APIs */ -#include /* to get msglevel bit values */ - -#include /* request_irq() */ - -#include -#include -#include -#include - -#if !defined(SDIO_VENDOR_ID_BROADCOM) -#define SDIO_VENDOR_ID_BROADCOM 0x02d0 -#endif /* !defined(SDIO_VENDOR_ID_BROADCOM) */ - -#define SDIO_DEVICE_ID_BROADCOM_DEFAULT 0x0000 - -#if !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) -#define SDIO_DEVICE_ID_BROADCOM_4325_SDGWB 0x0492 /* BCM94325SDGWB */ -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) */ -#if !defined(SDIO_DEVICE_ID_BROADCOM_4325) -#define SDIO_DEVICE_ID_BROADCOM_4325 0x0493 -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325) */ -#if !defined(SDIO_DEVICE_ID_BROADCOM_4329) -#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */ -#if !defined(SDIO_DEVICE_ID_BROADCOM_4319) -#define SDIO_DEVICE_ID_BROADCOM_4319 0x4319 -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4319) */ -#if !defined(SDIO_DEVICE_ID_BROADCOM_4330) -#define SDIO_DEVICE_ID_BROADCOM_4330 0x4330 -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4330) */ -#if !defined(SDIO_DEVICE_ID_BROADCOM_4334) -#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4334) */ -#if !defined(SDIO_DEVICE_ID_BROADCOM_4324) -#define SDIO_DEVICE_ID_BROADCOM_4324 0x4324 -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4324) */ -#if !defined(SDIO_DEVICE_ID_BROADCOM_43239) -#define SDIO_DEVICE_ID_BROADCOM_43239 43239 -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_43239) */ - -#include - -#include - -#ifdef WL_CFG80211 -extern void wl_cfg80211_set_parent_dev(void *dev); -#endif - -extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd); -extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd); -extern int dhd_os_check_wakelock(void *dhdp); -extern int dhd_os_check_if_up(void *dhdp); -extern void *bcmsdh_get_drvdata(void); - -int sdio_function_init(void); -void sdio_function_cleanup(void); - -#define DESCRIPTION "bcmsdh_sdmmc Driver" -#define AUTHOR "Broadcom Corporation" - -/* module param defaults */ -static int clockoverride = 0; - -module_param(clockoverride, int, 0644); -MODULE_PARM_DESC(clockoverride, "SDIO card clock override"); - -PBCMSDH_SDMMC_INSTANCE gInstance; - -/* Maximum number of bcmsdh_sdmmc devices supported by driver */ -#define BCMSDH_SDMMC_MAX_DEVICES 1 - -extern int bcmsdh_probe(struct device *dev); -extern int bcmsdh_remove(struct device *dev); -extern volatile bool dhd_mmc_suspend; - -static int bcmsdh_sdmmc_probe(struct sdio_func *func, - const struct sdio_device_id *id) -{ - int ret = 0; - static struct sdio_func sdio_func_0; - sd_trace(("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__)); - sd_trace(("sdio_bcmsdh: func->class=%x\n", func->class)); - sd_trace(("sdio_vendor: 0x%04x\n", func->vendor)); - sd_trace(("sdio_device: 0x%04x\n", func->device)); - sd_trace(("Function#: 0x%04x\n", func->num)); - - if (func->num == 1) { - sdio_func_0.num = 0; - sdio_func_0.card = func->card; - gInstance->func[0] = &sdio_func_0; - if(func->device == 0x4) { /* 4318 */ - gInstance->func[2] = NULL; - sd_trace(("NIC found, calling bcmsdh_probe...\n")); - ret = bcmsdh_probe(&func->dev); - } - } - - gInstance->func[func->num] = func; - - if (func->num == 2) { -#ifdef WL_CFG80211 - wl_cfg80211_set_parent_dev(&func->dev); -#endif - sd_trace(("F2 found, calling bcmsdh_probe...\n")); - ret = bcmsdh_probe(&func->dev); - } - - return ret; -} - -static void bcmsdh_sdmmc_remove(struct sdio_func *func) -{ - sd_trace(("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__)); - sd_info(("sdio_bcmsdh: func->class=%x\n", func->class)); - sd_info(("sdio_vendor: 0x%04x\n", func->vendor)); - sd_info(("sdio_device: 0x%04x\n", func->device)); - sd_info(("Function#: 0x%04x\n", func->num)); - - if (func->num == 2) { - sd_trace(("F2 found, calling bcmsdh_remove...\n")); - bcmsdh_remove(&func->dev); - } else if (func->num == 1) { - sdio_claim_host(func); - sdio_disable_func(func); - sdio_release_host(func); - gInstance->func[1] = NULL; - } -} - -/* devices we support, null terminated */ -static const struct sdio_device_id bcmsdh_sdmmc_ids[] = { - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_DEFAULT) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4319) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4324) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43239) }, - { SDIO_DEVICE_CLASS(SDIO_CLASS_NONE) }, - { /* end: all zeroes */ }, -}; - -MODULE_DEVICE_TABLE(sdio, bcmsdh_sdmmc_ids); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) -static int bcmsdh_sdmmc_suspend(struct device *pdev) -{ - struct sdio_func *func = dev_to_sdio_func(pdev); - mmc_pm_flag_t sdio_flags; - int ret; - - if (func->num != 2) - return 0; - - sd_trace(("%s Enter\n", __FUNCTION__)); - - if (dhd_os_check_wakelock(bcmsdh_get_drvdata())) - return -EBUSY; - sdio_flags = sdio_get_host_pm_caps(func); - - if (!(sdio_flags & MMC_PM_KEEP_POWER)) { - sd_err(("%s: can't keep power while host is suspended\n", __FUNCTION__)); - return -EINVAL; - } - - /* keep power while host suspended */ - ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); - if (ret) { - sd_err(("%s: error while trying to keep power\n", __FUNCTION__)); - return ret; - } -#if defined(OOB_INTR_ONLY) - bcmsdh_oob_intr_set(0); -#endif /* defined(OOB_INTR_ONLY) */ - dhd_mmc_suspend = TRUE; - smp_mb(); - - return 0; -} - -static int bcmsdh_sdmmc_resume(struct device *pdev) -{ -#if defined(OOB_INTR_ONLY) - struct sdio_func *func = dev_to_sdio_func(pdev); -#endif - sd_trace(("%s Enter\n", __FUNCTION__)); - dhd_mmc_suspend = FALSE; -#if defined(OOB_INTR_ONLY) - if ((func->num == 2) && dhd_os_check_if_up(bcmsdh_get_drvdata())) - bcmsdh_oob_intr_set(1); -#endif /* (OOB_INTR_ONLY) */ - - smp_mb(); - return 0; -} - -static const struct dev_pm_ops bcmsdh_sdmmc_pm_ops = { - .suspend = bcmsdh_sdmmc_suspend, - .resume = bcmsdh_sdmmc_resume, -}; -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) */ - -static struct sdio_driver bcmsdh_sdmmc_driver = { - .probe = bcmsdh_sdmmc_probe, - .remove = bcmsdh_sdmmc_remove, - .name = "bcmsdh_sdmmc", - .id_table = bcmsdh_sdmmc_ids, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) - .drv = { - .pm = &bcmsdh_sdmmc_pm_ops, - }, -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) */ -}; - -struct sdos_info { - sdioh_info_t *sd; - spinlock_t lock; -}; - - -int -sdioh_sdmmc_osinit(sdioh_info_t *sd) -{ - struct sdos_info *sdos; - - sdos = (struct sdos_info*)MALLOC(sd->osh, sizeof(struct sdos_info)); - sd->sdos_info = (void*)sdos; - if (sdos == NULL) - return BCME_NOMEM; - - sdos->sd = sd; - spin_lock_init(&sdos->lock); - return BCME_OK; -} - -void -sdioh_sdmmc_osfree(sdioh_info_t *sd) -{ - struct sdos_info *sdos; - ASSERT(sd && sd->sdos_info); - - sdos = (struct sdos_info *)sd->sdos_info; - MFREE(sd->osh, sdos, sizeof(struct sdos_info)); -} - -/* Interrupt enable/disable */ -SDIOH_API_RC -sdioh_interrupt_set(sdioh_info_t *sd, bool enable) -{ - ulong flags; - struct sdos_info *sdos; - - sd_trace(("%s: %s\n", __FUNCTION__, enable ? "Enabling" : "Disabling")); - - sdos = (struct sdos_info *)sd->sdos_info; - ASSERT(sdos); - -#if !defined(OOB_INTR_ONLY) - if (enable && !(sd->intr_handler && sd->intr_handler_arg)) { - sd_err(("%s: no handler registered, will not enable\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } -#endif /* !defined(OOB_INTR_ONLY) */ - - /* Ensure atomicity for enable/disable calls */ - spin_lock_irqsave(&sdos->lock, flags); - - sd->client_intr_enabled = enable; - if (enable) { - sdioh_sdmmc_devintr_on(sd); - } else { - sdioh_sdmmc_devintr_off(sd); - } - - spin_unlock_irqrestore(&sdos->lock, flags); - - return SDIOH_API_RC_SUCCESS; -} - - -#ifdef BCMSDH_MODULE -static int __init -bcmsdh_module_init(void) -{ - int error = 0; - sdio_function_init(); - return error; -} - -static void __exit -bcmsdh_module_cleanup(void) -{ - sdio_function_cleanup(); -} - -module_init(bcmsdh_module_init); -module_exit(bcmsdh_module_cleanup); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION(DESCRIPTION); -MODULE_AUTHOR(AUTHOR); - -#endif /* BCMSDH_MODULE */ -/* - * module init -*/ -int sdio_function_init(void) -{ - int error = 0; - sd_trace(("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__)); - - gInstance = kzalloc(sizeof(BCMSDH_SDMMC_INSTANCE), GFP_KERNEL); - if (!gInstance) - return -ENOMEM; - - error = sdio_register_driver(&bcmsdh_sdmmc_driver); - - return error; -} - -/* - * module cleanup -*/ -extern int bcmsdh_remove(struct device *dev); -void sdio_function_cleanup(void) -{ - sd_trace(("%s Enter\n", __FUNCTION__)); - - - sdio_unregister_driver(&bcmsdh_sdmmc_driver); - - if (gInstance) - kfree(gInstance); -} diff --git a/drivers/net/wireless/bcmdhd/bcmutils.c b/drivers/net/wireless/bcmdhd/bcmutils.c deleted file mode 100644 index 6b578e653648..000000000000 --- a/drivers/net/wireless/bcmdhd/bcmutils.c +++ /dev/null @@ -1,1965 +0,0 @@ -/* - * Driver O/S-independent utility routines - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * $Id: bcmutils.c,v 1.277.2.18 2011-01-26 02:32:08 $ - */ - -#include -#include -#include - -#ifdef BCMDRIVER - -#include -#include -#include - -#else /* !BCMDRIVER */ - -#include -#include -#include - -#if defined(BCMEXTSUP) -#include -#endif - - -#endif /* !BCMDRIVER */ - -#include -#include -#include -#include -#include -#include -#include - -void *_bcmutils_dummy_fn = NULL; - -#ifdef BCMDRIVER - - - -/* copy a pkt buffer chain into a buffer */ -uint -pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) -{ - uint n, ret = 0; - - if (len < 0) - len = 4096; /* "infinite" */ - - /* skip 'offset' bytes */ - for (; p && offset; p = PKTNEXT(osh, p)) { - if (offset < (uint)PKTLEN(osh, p)) - break; - offset -= PKTLEN(osh, p); - } - - if (!p) - return 0; - - /* copy the data */ - for (; p && len; p = PKTNEXT(osh, p)) { - n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); - bcopy(PKTDATA(osh, p) + offset, buf, n); - buf += n; - len -= n; - ret += n; - offset = 0; - } - - return ret; -} - -/* copy a buffer into a pkt buffer chain */ -uint -pktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf) -{ - uint n, ret = 0; - - /* skip 'offset' bytes */ - for (; p && offset; p = PKTNEXT(osh, p)) { - if (offset < (uint)PKTLEN(osh, p)) - break; - offset -= PKTLEN(osh, p); - } - - if (!p) - return 0; - - /* copy the data */ - for (; p && len; p = PKTNEXT(osh, p)) { - n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); - bcopy(buf, PKTDATA(osh, p) + offset, n); - buf += n; - len -= n; - ret += n; - offset = 0; - } - - return ret; -} - - - -/* return total length of buffer chain */ -uint BCMFASTPATH -pkttotlen(osl_t *osh, void *p) -{ - uint total; - - total = 0; - for (; p; p = PKTNEXT(osh, p)) - total += PKTLEN(osh, p); - return (total); -} - -/* return the last buffer of chained pkt */ -void * -pktlast(osl_t *osh, void *p) -{ - for (; PKTNEXT(osh, p); p = PKTNEXT(osh, p)) - ; - - return (p); -} - -/* count segments of a chained packet */ -uint BCMFASTPATH -pktsegcnt(osl_t *osh, void *p) -{ - uint cnt; - - for (cnt = 0; p; p = PKTNEXT(osh, p)) - cnt++; - - return cnt; -} - - -/* - * osl multiple-precedence packet queue - * hi_prec is always >= the number of the highest non-empty precedence - */ -void * BCMFASTPATH -pktq_penq(struct pktq *pq, int prec, void *p) -{ - struct pktq_prec *q; - - ASSERT(prec >= 0 && prec < pq->num_prec); - ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ - - ASSERT(!pktq_full(pq)); - ASSERT(!pktq_pfull(pq, prec)); - - q = &pq->q[prec]; - - if (q->head) - PKTSETLINK(q->tail, p); - else - q->head = p; - - q->tail = p; - q->len++; - - pq->len++; - - if (pq->hi_prec < prec) - pq->hi_prec = (uint8)prec; - - return p; -} - -void * BCMFASTPATH -pktq_penq_head(struct pktq *pq, int prec, void *p) -{ - struct pktq_prec *q; - - ASSERT(prec >= 0 && prec < pq->num_prec); - ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ - - ASSERT(!pktq_full(pq)); - ASSERT(!pktq_pfull(pq, prec)); - - q = &pq->q[prec]; - - if (q->head == NULL) - q->tail = p; - - PKTSETLINK(p, q->head); - q->head = p; - q->len++; - - pq->len++; - - if (pq->hi_prec < prec) - pq->hi_prec = (uint8)prec; - - return p; -} - -void * BCMFASTPATH -pktq_pdeq(struct pktq *pq, int prec) -{ - struct pktq_prec *q; - void *p; - - ASSERT(prec >= 0 && prec < pq->num_prec); - - q = &pq->q[prec]; - - if ((p = q->head) == NULL) - return NULL; - - if ((q->head = PKTLINK(p)) == NULL) - q->tail = NULL; - - q->len--; - - pq->len--; - - PKTSETLINK(p, NULL); - - return p; -} - -void * BCMFASTPATH -pktq_pdeq_tail(struct pktq *pq, int prec) -{ - struct pktq_prec *q; - void *p, *prev; - - ASSERT(prec >= 0 && prec < pq->num_prec); - - q = &pq->q[prec]; - - if ((p = q->head) == NULL) - return NULL; - - for (prev = NULL; p != q->tail; p = PKTLINK(p)) - prev = p; - - if (prev) - PKTSETLINK(prev, NULL); - else - q->head = NULL; - - q->tail = prev; - q->len--; - - pq->len--; - - return p; -} - -void -pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir, ifpkt_cb_t fn, int arg) -{ - struct pktq_prec *q; - void *p, *prev = NULL; - - q = &pq->q[prec]; - p = q->head; - while (p) { - if (fn == NULL || (*fn)(p, arg)) { - bool head = (p == q->head); - if (head) - q->head = PKTLINK(p); - else - PKTSETLINK(prev, PKTLINK(p)); - PKTSETLINK(p, NULL); - PKTFREE(osh, p, dir); - q->len--; - pq->len--; - p = (head ? q->head : PKTLINK(prev)); - } else { - prev = p; - p = PKTLINK(p); - } - } - - if (q->head == NULL) { - ASSERT(q->len == 0); - q->tail = NULL; - } -} - -bool BCMFASTPATH -pktq_pdel(struct pktq *pq, void *pktbuf, int prec) -{ - struct pktq_prec *q; - void *p; - - ASSERT(prec >= 0 && prec < pq->num_prec); - - if (!pktbuf) - return FALSE; - - q = &pq->q[prec]; - - if (q->head == pktbuf) { - if ((q->head = PKTLINK(pktbuf)) == NULL) - q->tail = NULL; - } else { - for (p = q->head; p && PKTLINK(p) != pktbuf; p = PKTLINK(p)) - ; - if (p == NULL) - return FALSE; - - PKTSETLINK(p, PKTLINK(pktbuf)); - if (q->tail == pktbuf) - q->tail = p; - } - - q->len--; - pq->len--; - PKTSETLINK(pktbuf, NULL); - return TRUE; -} - -void -pktq_init(struct pktq *pq, int num_prec, int max_len) -{ - int prec; - - ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC); - - /* pq is variable size; only zero out what's requested */ - bzero(pq, OFFSETOF(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec)); - - pq->num_prec = (uint16)num_prec; - - pq->max = (uint16)max_len; - - for (prec = 0; prec < num_prec; prec++) - pq->q[prec].max = pq->max; -} - -void * BCMFASTPATH -pktq_deq(struct pktq *pq, int *prec_out) -{ - struct pktq_prec *q; - void *p; - int prec; - - if (pq->len == 0) - return NULL; - - while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) - pq->hi_prec--; - - q = &pq->q[prec]; - - if ((p = q->head) == NULL) - return NULL; - - if ((q->head = PKTLINK(p)) == NULL) - q->tail = NULL; - - q->len--; - - pq->len--; - - if (prec_out) - *prec_out = prec; - - PKTSETLINK(p, NULL); - - return p; -} - -void * BCMFASTPATH -pktq_deq_tail(struct pktq *pq, int *prec_out) -{ - struct pktq_prec *q; - void *p, *prev; - int prec; - - if (pq->len == 0) - return NULL; - - for (prec = 0; prec < pq->hi_prec; prec++) - if (pq->q[prec].head) - break; - - q = &pq->q[prec]; - - if ((p = q->head) == NULL) - return NULL; - - for (prev = NULL; p != q->tail; p = PKTLINK(p)) - prev = p; - - if (prev) - PKTSETLINK(prev, NULL); - else - q->head = NULL; - - q->tail = prev; - q->len--; - - pq->len--; - - if (prec_out) - *prec_out = prec; - - PKTSETLINK(p, NULL); - - return p; -} - -void * -pktq_peek(struct pktq *pq, int *prec_out) -{ - int prec; - - if (pq->len == 0) - return NULL; - - while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) - pq->hi_prec--; - - if (prec_out) - *prec_out = prec; - - return (pq->q[prec].head); -} - -void * -pktq_peek_tail(struct pktq *pq, int *prec_out) -{ - int prec; - - if (pq->len == 0) - return NULL; - - for (prec = 0; prec < pq->hi_prec; prec++) - if (pq->q[prec].head) - break; - - if (prec_out) - *prec_out = prec; - - return (pq->q[prec].tail); -} - -void -pktq_flush(osl_t *osh, struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg) -{ - int prec; - for (prec = 0; prec < pq->num_prec; prec++) - pktq_pflush(osh, pq, prec, dir, fn, arg); - if (fn == NULL) - ASSERT(pq->len == 0); -} - -/* Return sum of lengths of a specific set of precedences */ -int -pktq_mlen(struct pktq *pq, uint prec_bmp) -{ - int prec, len; - - len = 0; - - for (prec = 0; prec <= pq->hi_prec; prec++) - if (prec_bmp & (1 << prec)) - len += pq->q[prec].len; - - return len; -} - -/* Priority dequeue from a specific set of precedences */ -void * BCMFASTPATH -pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out) -{ - struct pktq_prec *q; - void *p; - int prec; - - if (pq->len == 0) - return NULL; - - while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) - pq->hi_prec--; - - while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) - if (prec-- == 0) - return NULL; - - q = &pq->q[prec]; - - if ((p = q->head) == NULL) - return NULL; - - if ((q->head = PKTLINK(p)) == NULL) - q->tail = NULL; - - q->len--; - - if (prec_out) - *prec_out = prec; - - pq->len--; - - PKTSETLINK(p, NULL); - - return p; -} - -#endif /* BCMDRIVER */ - -const unsigned char bcm_ctype[] = { - - _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ - _BCM_C, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C, - _BCM_C, /* 8-15 */ - _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */ - _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */ - _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */ - _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */ - _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */ - _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */ - _BCM_P, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, - _BCM_U|_BCM_X, _BCM_U, /* 64-71 */ - _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */ - _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */ - _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */ - _BCM_P, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, - _BCM_L|_BCM_X, _BCM_L, /* 96-103 */ - _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */ - _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */ - _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128-143 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 144-159 */ - _BCM_S|_BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, - _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 160-175 */ - _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, - _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 176-191 */ - _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, - _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 192-207 */ - _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_U, _BCM_U, _BCM_U, - _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L, /* 208-223 */ - _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, - _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 224-239 */ - _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_L, _BCM_L, _BCM_L, - _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L /* 240-255 */ -}; - -ulong -bcm_strtoul(char *cp, char **endp, uint base) -{ - ulong result, last_result = 0, value; - bool minus; - - minus = FALSE; - - while (bcm_isspace(*cp)) - cp++; - - if (cp[0] == '+') - cp++; - else if (cp[0] == '-') { - minus = TRUE; - cp++; - } - - if (base == 0) { - if (cp[0] == '0') { - if ((cp[1] == 'x') || (cp[1] == 'X')) { - base = 16; - cp = &cp[2]; - } else { - base = 8; - cp = &cp[1]; - } - } else - base = 10; - } else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) { - cp = &cp[2]; - } - - result = 0; - - while (bcm_isxdigit(*cp) && - (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) - { - result = result*base + value; - /* Detected overflow */ - if (result < last_result && !minus) - return (ulong)-1; - last_result = result; - cp++; - } - - if (minus) - result = (ulong)(-(long)result); - - if (endp) - *endp = (char *)cp; - - return (result); -} - -int -bcm_atoi(char *s) -{ - return (int)bcm_strtoul(s, NULL, 10); -} - -/* return pointer to location of substring 'needle' in 'haystack' */ -char* -bcmstrstr(char *haystack, char *needle) -{ - int len, nlen; - int i; - - if ((haystack == NULL) || (needle == NULL)) - return (haystack); - - nlen = strlen(needle); - len = strlen(haystack) - nlen + 1; - - for (i = 0; i < len; i++) - if (memcmp(needle, &haystack[i], nlen) == 0) - return (&haystack[i]); - return (NULL); -} - -char* -bcmstrcat(char *dest, const char *src) -{ - char *p; - - p = dest + strlen(dest); - - while ((*p++ = *src++) != '\0') - ; - - return (dest); -} - -char* -bcmstrncat(char *dest, const char *src, uint size) -{ - char *endp; - char *p; - - p = dest + strlen(dest); - endp = p + size; - - while (p != endp && (*p++ = *src++) != '\0') - ; - - return (dest); -} - - -/**************************************************************************** -* Function: bcmstrtok -* -* Purpose: -* Tokenizes a string. This function is conceptually similiar to ANSI C strtok(), -* but allows strToken() to be used by different strings or callers at the same -* time. Each call modifies '*string' by substituting a NULL character for the -* first delimiter that is encountered, and updates 'string' to point to the char -* after the delimiter. Leading delimiters are skipped. -* -* Parameters: -* string (mod) Ptr to string ptr, updated by token. -* delimiters (in) Set of delimiter characters. -* tokdelim (out) Character that delimits the returned token. (May -* be set to NULL if token delimiter is not required). -* -* Returns: Pointer to the next token found. NULL when no more tokens are found. -***************************************************************************** -*/ -char * -bcmstrtok(char **string, const char *delimiters, char *tokdelim) -{ - unsigned char *str; - unsigned long map[8]; - int count; - char *nextoken; - - if (tokdelim != NULL) { - /* Prime the token delimiter */ - *tokdelim = '\0'; - } - - /* Clear control map */ - for (count = 0; count < 8; count++) { - map[count] = 0; - } - - /* Set bits in delimiter table */ - do { - map[*delimiters >> 5] |= (1 << (*delimiters & 31)); - } - while (*delimiters++); - - str = (unsigned char*)*string; - - /* Find beginning of token (skip over leading delimiters). Note that - * there is no token iff this loop sets str to point to the terminal - * null (*str == '\0') - */ - while (((map[*str >> 5] & (1 << (*str & 31))) && *str) || (*str == ' ')) { - str++; - } - - nextoken = (char*)str; - - /* Find the end of the token. If it is not the end of the string, - * put a null there. - */ - for (; *str; str++) { - if (map[*str >> 5] & (1 << (*str & 31))) { - if (tokdelim != NULL) { - *tokdelim = *str; - } - - *str++ = '\0'; - break; - } - } - - *string = (char*)str; - - /* Determine if a token has been found. */ - if (nextoken == (char *) str) { - return NULL; - } - else { - return nextoken; - } -} - - -#define xToLower(C) \ - ((C >= 'A' && C <= 'Z') ? (char)((int)C - (int)'A' + (int)'a') : C) - - -/**************************************************************************** -* Function: bcmstricmp -* -* Purpose: Compare to strings case insensitively. -* -* Parameters: s1 (in) First string to compare. -* s2 (in) Second string to compare. -* -* Returns: Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if -* t1 > t2, when ignoring case sensitivity. -***************************************************************************** -*/ -int -bcmstricmp(const char *s1, const char *s2) -{ - char dc, sc; - - while (*s2 && *s1) { - dc = xToLower(*s1); - sc = xToLower(*s2); - if (dc < sc) return -1; - if (dc > sc) return 1; - s1++; - s2++; - } - - if (*s1 && !*s2) return 1; - if (!*s1 && *s2) return -1; - return 0; -} - - -/**************************************************************************** -* Function: bcmstrnicmp -* -* Purpose: Compare to strings case insensitively, upto a max of 'cnt' -* characters. -* -* Parameters: s1 (in) First string to compare. -* s2 (in) Second string to compare. -* cnt (in) Max characters to compare. -* -* Returns: Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if -* t1 > t2, when ignoring case sensitivity. -***************************************************************************** -*/ -int -bcmstrnicmp(const char* s1, const char* s2, int cnt) -{ - char dc, sc; - - while (*s2 && *s1 && cnt) { - dc = xToLower(*s1); - sc = xToLower(*s2); - if (dc < sc) return -1; - if (dc > sc) return 1; - s1++; - s2++; - cnt--; - } - - if (!cnt) return 0; - if (*s1 && !*s2) return 1; - if (!*s1 && *s2) return -1; - return 0; -} - -/* parse a xx:xx:xx:xx:xx:xx format ethernet address */ -int -bcm_ether_atoe(char *p, struct ether_addr *ea) -{ - int i = 0; - - for (;;) { - ea->octet[i++] = (char) bcm_strtoul(p, &p, 16); - if (!*p++ || i == 6) - break; - } - - return (i == 6); -} - - -#if defined(CONFIG_USBRNDIS_RETAIL) || defined(NDIS_MINIPORT_DRIVER) -/* registry routine buffer preparation utility functions: - * parameter order is like strncpy, but returns count - * of bytes copied. Minimum bytes copied is null char(1)/wchar(2) - */ -ulong -wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen) -{ - ulong copyct = 1; - ushort i; - - if (abuflen == 0) - return 0; - - /* wbuflen is in bytes */ - wbuflen /= sizeof(ushort); - - for (i = 0; i < wbuflen; ++i) { - if (--abuflen == 0) - break; - *abuf++ = (char) *wbuf++; - ++copyct; - } - *abuf = '\0'; - - return copyct; -} -#endif /* CONFIG_USBRNDIS_RETAIL || NDIS_MINIPORT_DRIVER */ - -char * -bcm_ether_ntoa(const struct ether_addr *ea, char *buf) -{ - static const char template[] = "%02x:%02x:%02x:%02x:%02x:%02x"; - snprintf(buf, 18, template, - ea->octet[0]&0xff, ea->octet[1]&0xff, ea->octet[2]&0xff, - ea->octet[3]&0xff, ea->octet[4]&0xff, ea->octet[5]&0xff); - return (buf); -} - -char * -bcm_ip_ntoa(struct ipv4_addr *ia, char *buf) -{ - snprintf(buf, 16, "%d.%d.%d.%d", - ia->addr[0], ia->addr[1], ia->addr[2], ia->addr[3]); - return (buf); -} - -#ifdef BCMDRIVER - -void -bcm_mdelay(uint ms) -{ - uint i; - - for (i = 0; i < ms; i++) { - OSL_DELAY(1000); - } -} - - - - - -#if defined(DHD_DEBUG) -/* pretty hex print a pkt buffer chain */ -void -prpkt(const char *msg, osl_t *osh, void *p0) -{ - void *p; - - if (msg && (msg[0] != '\0')) - printf("%s:\n", msg); - - for (p = p0; p; p = PKTNEXT(osh, p)) - prhex(NULL, PKTDATA(osh, p), PKTLEN(osh, p)); -} -#endif - -/* Takes an Ethernet frame and sets out-of-bound PKTPRIO. - * Also updates the inplace vlan tag if requested. - * For debugging, it returns an indication of what it did. - */ -uint BCMFASTPATH -pktsetprio(void *pkt, bool update_vtag) -{ - struct ether_header *eh; - struct ethervlan_header *evh; - uint8 *pktdata; - int priority = 0; - int rc = 0; - - pktdata = (uint8 *) PKTDATA(NULL, pkt); - ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16))); - - eh = (struct ether_header *) pktdata; - - if (ntoh16(eh->ether_type) == ETHER_TYPE_8021Q) { - uint16 vlan_tag; - int vlan_prio, dscp_prio = 0; - - evh = (struct ethervlan_header *)eh; - - vlan_tag = ntoh16(evh->vlan_tag); - vlan_prio = (int) (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK; - - if (ntoh16(evh->ether_type) == ETHER_TYPE_IP) { - uint8 *ip_body = pktdata + sizeof(struct ethervlan_header); - uint8 tos_tc = IP_TOS46(ip_body); - dscp_prio = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); - } - - /* DSCP priority gets precedence over 802.1P (vlan tag) */ - if (dscp_prio != 0) { - priority = dscp_prio; - rc |= PKTPRIO_VDSCP; - } else { - priority = vlan_prio; - rc |= PKTPRIO_VLAN; - } - /* - * If the DSCP priority is not the same as the VLAN priority, - * then overwrite the priority field in the vlan tag, with the - * DSCP priority value. This is required for Linux APs because - * the VLAN driver on Linux, overwrites the skb->priority field - * with the priority value in the vlan tag - */ - if (update_vtag && (priority != vlan_prio)) { - vlan_tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT); - vlan_tag |= (uint16)priority << VLAN_PRI_SHIFT; - evh->vlan_tag = hton16(vlan_tag); - rc |= PKTPRIO_UPD; - } - } else if (ntoh16(eh->ether_type) == ETHER_TYPE_IP) { - uint8 *ip_body = pktdata + sizeof(struct ether_header); - uint8 tos_tc = IP_TOS46(ip_body); - priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); - rc |= PKTPRIO_DSCP; - } - - ASSERT(priority >= 0 && priority <= MAXPRIO); - PKTSETPRIO(pkt, priority); - return (rc | priority); -} - - -static char bcm_undeferrstr[32]; -static const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE; - -/* Convert the error codes into related error strings */ -const char * -bcmerrorstr(int bcmerror) -{ - /* check if someone added a bcmerror code but forgot to add errorstring */ - ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1)); - - if (bcmerror > 0 || bcmerror < BCME_LAST) { - snprintf(bcm_undeferrstr, sizeof(bcm_undeferrstr), "Undefined error %d", bcmerror); - return bcm_undeferrstr; - } - - ASSERT(strlen(bcmerrorstrtable[-bcmerror]) < BCME_STRLEN); - - return bcmerrorstrtable[-bcmerror]; -} - - - - -/* iovar table lookup */ -const bcm_iovar_t* -bcm_iovar_lookup(const bcm_iovar_t *table, const char *name) -{ - const bcm_iovar_t *vi; - const char *lookup_name; - - /* skip any ':' delimited option prefixes */ - lookup_name = strrchr(name, ':'); - if (lookup_name != NULL) - lookup_name++; - else - lookup_name = name; - - ASSERT(table != NULL); - - for (vi = table; vi->name; vi++) { - if (!strcmp(vi->name, lookup_name)) - return vi; - } - /* ran to end of table */ - - return NULL; /* var name not found */ -} - -int -bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set) -{ - int bcmerror = 0; - - /* length check on io buf */ - switch (vi->type) { - case IOVT_BOOL: - case IOVT_INT8: - case IOVT_INT16: - case IOVT_INT32: - case IOVT_UINT8: - case IOVT_UINT16: - case IOVT_UINT32: - /* all integers are int32 sized args at the ioctl interface */ - if (len < (int)sizeof(int)) { - bcmerror = BCME_BUFTOOSHORT; - } - break; - - case IOVT_BUFFER: - /* buffer must meet minimum length requirement */ - if (len < vi->minlen) { - bcmerror = BCME_BUFTOOSHORT; - } - break; - - case IOVT_VOID: - if (!set) { - /* Cannot return nil... */ - bcmerror = BCME_UNSUPPORTED; - } else if (len) { - /* Set is an action w/o parameters */ - bcmerror = BCME_BUFTOOLONG; - } - break; - - default: - /* unknown type for length check in iovar info */ - ASSERT(0); - bcmerror = BCME_UNSUPPORTED; - } - - return bcmerror; -} - -#endif /* BCMDRIVER */ - - -/******************************************************************************* - * crc8 - * - * Computes a crc8 over the input data using the polynomial: - * - * x^8 + x^7 +x^6 + x^4 + x^2 + 1 - * - * The caller provides the initial value (either CRC8_INIT_VALUE - * or the previous returned value) to allow for processing of - * discontiguous blocks of data. When generating the CRC the - * caller is responsible for complementing the final return value - * and inserting it into the byte stream. When checking, a final - * return value of CRC8_GOOD_VALUE indicates a valid CRC. - * - * Reference: Dallas Semiconductor Application Note 27 - * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", - * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., - * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt - * - * **************************************************************************** - */ - -static const uint8 crc8_table[256] = { - 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, - 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, - 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, - 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, - 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, - 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, - 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, - 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, - 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, - 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, - 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, - 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, - 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, - 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, - 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, - 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, - 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, - 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, - 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, - 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, - 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, - 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, - 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, - 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, - 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, - 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, - 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, - 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, - 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, - 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, - 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, - 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F -}; - -#define CRC_INNER_LOOP(n, c, x) \ - (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff] - -uint8 -hndcrc8( - uint8 *pdata, /* pointer to array of data to process */ - uint nbytes, /* number of input data bytes to process */ - uint8 crc /* either CRC8_INIT_VALUE or previous return value */ -) -{ - /* hard code the crc loop instead of using CRC_INNER_LOOP macro - * to avoid the undefined and unnecessary (uint8 >> 8) operation. - */ - while (nbytes-- > 0) - crc = crc8_table[(crc ^ *pdata++) & 0xff]; - - return crc; -} - -/******************************************************************************* - * crc16 - * - * Computes a crc16 over the input data using the polynomial: - * - * x^16 + x^12 +x^5 + 1 - * - * The caller provides the initial value (either CRC16_INIT_VALUE - * or the previous returned value) to allow for processing of - * discontiguous blocks of data. When generating the CRC the - * caller is responsible for complementing the final return value - * and inserting it into the byte stream. When checking, a final - * return value of CRC16_GOOD_VALUE indicates a valid CRC. - * - * Reference: Dallas Semiconductor Application Note 27 - * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", - * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., - * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt - * - * **************************************************************************** - */ - -static const uint16 crc16_table[256] = { - 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, - 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, - 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, - 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, - 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, - 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, - 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, - 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, - 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, - 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, - 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, - 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, - 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, - 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, - 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, - 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, - 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, - 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, - 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, - 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, - 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, - 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, - 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, - 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, - 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, - 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, - 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, - 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, - 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, - 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, - 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, - 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 -}; - -uint16 -hndcrc16( - uint8 *pdata, /* pointer to array of data to process */ - uint nbytes, /* number of input data bytes to process */ - uint16 crc /* either CRC16_INIT_VALUE or previous return value */ -) -{ - while (nbytes-- > 0) - CRC_INNER_LOOP(16, crc, *pdata++); - return crc; -} - -static const uint32 crc32_table[256] = { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, - 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, - 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, - 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, - 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, - 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, - 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, - 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, - 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, - 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, - 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, - 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, - 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, - 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, - 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, - 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, - 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, - 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, - 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -}; - -/* - * crc input is CRC32_INIT_VALUE for a fresh start, or previous return value if - * accumulating over multiple pieces. - */ -uint32 -hndcrc32(uint8 *pdata, uint nbytes, uint32 crc) -{ - uint8 *pend; -#ifdef __mips__ - uint8 tmp[4]; - ulong *tptr = (ulong *)tmp; - - /* in case the beginning of the buffer isn't aligned */ - pend = (uint8 *)((uint)(pdata + 3) & 0xfffffffc); - nbytes -= (pend - pdata); - while (pdata < pend) - CRC_INNER_LOOP(32, crc, *pdata++); - - /* handle bulk of data as 32-bit words */ - pend = pdata + (nbytes & 0xfffffffc); - while (pdata < pend) { - *tptr = *(ulong *)pdata; - pdata += sizeof(ulong *); - CRC_INNER_LOOP(32, crc, tmp[0]); - CRC_INNER_LOOP(32, crc, tmp[1]); - CRC_INNER_LOOP(32, crc, tmp[2]); - CRC_INNER_LOOP(32, crc, tmp[3]); - } - - /* 1-3 bytes at end of buffer */ - pend = pdata + (nbytes & 0x03); - while (pdata < pend) - CRC_INNER_LOOP(32, crc, *pdata++); -#else - pend = pdata + nbytes; - while (pdata < pend) - CRC_INNER_LOOP(32, crc, *pdata++); -#endif /* __mips__ */ - - return crc; -} - -#ifdef notdef -#define CLEN 1499 /* CRC Length */ -#define CBUFSIZ (CLEN+4) -#define CNBUFS 5 /* # of bufs */ - -void -testcrc32(void) -{ - uint j, k, l; - uint8 *buf; - uint len[CNBUFS]; - uint32 crcr; - uint32 crc32tv[CNBUFS] = - {0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110}; - - ASSERT((buf = MALLOC(CBUFSIZ*CNBUFS)) != NULL); - - /* step through all possible alignments */ - for (l = 0; l <= 4; l++) { - for (j = 0; j < CNBUFS; j++) { - len[j] = CLEN; - for (k = 0; k < len[j]; k++) - *(buf + j*CBUFSIZ + (k+l)) = (j+k) & 0xff; - } - - for (j = 0; j < CNBUFS; j++) { - crcr = crc32(buf + j*CBUFSIZ + l, len[j], CRC32_INIT_VALUE); - ASSERT(crcr == crc32tv[j]); - } - } - - MFREE(buf, CBUFSIZ*CNBUFS); - return; -} -#endif /* notdef */ - -/* - * Advance from the current 1-byte tag/1-byte length/variable-length value - * triple, to the next, returning a pointer to the next. - * If the current or next TLV is invalid (does not fit in given buffer length), - * NULL is returned. - * *buflen is not modified if the TLV elt parameter is invalid, or is decremented - * by the TLV parameter's length if it is valid. - */ -bcm_tlv_t * -bcm_next_tlv(bcm_tlv_t *elt, int *buflen) -{ - int len; - - /* validate current elt */ - if (!bcm_valid_tlv(elt, *buflen)) - return NULL; - - /* advance to next elt */ - len = elt->len; - elt = (bcm_tlv_t*)(elt->data + len); - *buflen -= (2 + len); - - /* validate next elt */ - if (!bcm_valid_tlv(elt, *buflen)) - return NULL; - - return elt; -} - -/* - * Traverse a string of 1-byte tag/1-byte length/variable-length value - * triples, returning a pointer to the substring whose first element - * matches tag - */ -bcm_tlv_t * -bcm_parse_tlvs(void *buf, int buflen, uint key) -{ - bcm_tlv_t *elt; - int totlen; - - elt = (bcm_tlv_t*)buf; - totlen = buflen; - - /* find tagged parameter */ - while (totlen >= 2) { - int len = elt->len; - - /* validate remaining totlen */ - if ((elt->id == key) && (totlen >= (len + 2))) - return (elt); - - elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); - totlen -= (len + 2); - } - - return NULL; -} - -/* - * Traverse a string of 1-byte tag/1-byte length/variable-length value - * triples, returning a pointer to the substring whose first element - * matches tag. Stop parsing when we see an element whose ID is greater - * than the target key. - */ -bcm_tlv_t * -bcm_parse_ordered_tlvs(void *buf, int buflen, uint key) -{ - bcm_tlv_t *elt; - int totlen; - - elt = (bcm_tlv_t*)buf; - totlen = buflen; - - /* find tagged parameter */ - while (totlen >= 2) { - uint id = elt->id; - int len = elt->len; - - /* Punt if we start seeing IDs > than target key */ - if (id > key) - return (NULL); - - /* validate remaining totlen */ - if ((id == key) && (totlen >= (len + 2))) - return (elt); - - elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); - totlen -= (len + 2); - } - return NULL; -} - -#if defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || defined(WLMSG_ASSOC) || \ - defined(DHD_DEBUG) -int -bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len) -{ - int i; - char* p = buf; - char hexstr[16]; - int slen = 0, nlen = 0; - uint32 bit; - const char* name; - - if (len < 2 || !buf) - return 0; - - buf[0] = '\0'; - - for (i = 0; flags != 0; i++) { - bit = bd[i].bit; - name = bd[i].name; - if (bit == 0 && flags != 0) { - /* print any unnamed bits */ - snprintf(hexstr, 16, "0x%X", flags); - name = hexstr; - flags = 0; /* exit loop */ - } else if ((flags & bit) == 0) - continue; - flags &= ~bit; - nlen = strlen(name); - slen += nlen; - /* count btwn flag space */ - if (flags != 0) - slen += 1; - /* need NULL char as well */ - if (len <= slen) - break; - /* copy NULL char but don't count it */ - strncpy(p, name, nlen + 1); - p += nlen; - /* copy btwn flag space and NULL char */ - if (flags != 0) - p += snprintf(p, 2, " "); - len -= slen; - } - - /* indicate the str was too short */ - if (flags != 0) { - if (len < 2) - p -= 2 - len; /* overwrite last char */ - p += snprintf(p, 2, ">"); - } - - return (int)(p - buf); -} -#endif - -#if defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || defined(WLMSG_ASSOC) || \ - defined(DHD_DEBUG) || defined(WLMEDIA_PEAKRATE) -/* print bytes formatted as hex to a string. return the resulting string length */ -int -bcm_format_hex(char *str, const void *bytes, int len) -{ - int i; - char *p = str; - const uint8 *src = (const uint8*)bytes; - - for (i = 0; i < len; i++) { - p += snprintf(p, 3, "%02X", *src); - src++; - } - return (int)(p - str); -} -#endif - -/* pretty hex print a contiguous buffer */ -void -prhex(const char *msg, uchar *buf, uint nbytes) -{ - char line[128], *p; - int len = sizeof(line); - int nchar; - uint i; - - if (msg && (msg[0] != '\0')) - printf("%s:\n", msg); - - p = line; - for (i = 0; i < nbytes; i++) { - if (i % 16 == 0) { - nchar = snprintf(p, len, " %04d: ", i); /* line prefix */ - p += nchar; - len -= nchar; - } - if (len > 0) { - nchar = snprintf(p, len, "%02x ", buf[i]); - p += nchar; - len -= nchar; - } - - if (i % 16 == 15) { - printf("%s\n", line); /* flush line */ - p = line; - len = sizeof(line); - } - } - - /* flush last partial line */ - if (p != line) - printf("%s\n", line); -} - -static const char *crypto_algo_names[] = { - "NONE", - "WEP1", - "TKIP", - "WEP128", - "AES_CCM", - "AES_OCB_MSDU", - "AES_OCB_MPDU", - "NALG" - "UNDEF", - "UNDEF", - "UNDEF", - "UNDEF" -}; - -const char * -bcm_crypto_algo_name(uint algo) -{ - return (algo < ARRAYSIZE(crypto_algo_names)) ? crypto_algo_names[algo] : "ERR"; -} - - -char * -bcm_chipname(uint chipid, char *buf, uint len) -{ - const char *fmt; - - fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x"; - snprintf(buf, len, fmt, chipid); - return buf; -} - -/* Produce a human-readable string for boardrev */ -char * -bcm_brev_str(uint32 brev, char *buf) -{ - if (brev < 0x100) - snprintf(buf, 8, "%d.%d", (brev & 0xf0) >> 4, brev & 0xf); - else - snprintf(buf, 8, "%c%03x", ((brev & 0xf000) == 0x1000) ? 'P' : 'A', brev & 0xfff); - - return (buf); -} - -#define BUFSIZE_TODUMP_ATONCE 512 /* Buffer size */ - -/* dump large strings to console */ -void -printbig(char *buf) -{ - uint len, max_len; - char c; - - len = strlen(buf); - - max_len = BUFSIZE_TODUMP_ATONCE; - - while (len > max_len) { - c = buf[max_len]; - buf[max_len] = '\0'; - printf("%s", buf); - buf[max_len] = c; - - buf += max_len; - len -= max_len; - } - /* print the remaining string */ - printf("%s\n", buf); - return; -} - -/* routine to dump fields in a fileddesc structure */ -uint -bcmdumpfields(bcmutl_rdreg_rtn read_rtn, void *arg0, uint arg1, struct fielddesc *fielddesc_array, - char *buf, uint32 bufsize) -{ - uint filled_len; - int len; - struct fielddesc *cur_ptr; - - filled_len = 0; - cur_ptr = fielddesc_array; - - while (bufsize > 1) { - if (cur_ptr->nameandfmt == NULL) - break; - len = snprintf(buf, bufsize, cur_ptr->nameandfmt, - read_rtn(arg0, arg1, cur_ptr->offset)); - /* check for snprintf overflow or error */ - if (len < 0 || (uint32)len >= bufsize) - len = bufsize - 1; - buf += len; - bufsize -= len; - filled_len += len; - cur_ptr++; - } - return filled_len; -} - -uint -bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) -{ - uint len; - - len = strlen(name) + 1; - - if ((len + datalen) > buflen) - return 0; - - strncpy(buf, name, buflen); - - /* append data onto the end of the name string */ - memcpy(&buf[len], data, datalen); - len += datalen; - - return len; -} - -/* Quarter dBm units to mW - * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 - * Table is offset so the last entry is largest mW value that fits in - * a uint16. - */ - -#define QDBM_OFFSET 153 /* Offset for first entry */ -#define QDBM_TABLE_LEN 40 /* Table size */ - -/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET. - * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2 - */ -#define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */ - -/* Largest mW value that will round down to the last table entry, - * QDBM_OFFSET + QDBM_TABLE_LEN-1. - * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2. - */ -#define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */ - -static const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = { -/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */ -/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, -/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849, -/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119, -/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811, -/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096 -}; - -uint16 -bcm_qdbm_to_mw(uint8 qdbm) -{ - uint factor = 1; - int idx = qdbm - QDBM_OFFSET; - - if (idx >= QDBM_TABLE_LEN) { - /* clamp to max uint16 mW value */ - return 0xFFFF; - } - - /* scale the qdBm index up to the range of the table 0-40 - * where an offset of 40 qdBm equals a factor of 10 mW. - */ - while (idx < 0) { - idx += 40; - factor *= 10; - } - - /* return the mW value scaled down to the correct factor of 10, - * adding in factor/2 to get proper rounding. - */ - return ((nqdBm_to_mW_map[idx] + factor/2) / factor); -} - -uint8 -bcm_mw_to_qdbm(uint16 mw) -{ - uint8 qdbm; - int offset; - uint mw_uint = mw; - uint boundary; - - /* handle boundary case */ - if (mw_uint <= 1) - return 0; - - offset = QDBM_OFFSET; - - /* move mw into the range of the table */ - while (mw_uint < QDBM_TABLE_LOW_BOUND) { - mw_uint *= 10; - offset -= 40; - } - - for (qdbm = 0; qdbm < QDBM_TABLE_LEN-1; qdbm++) { - boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm+1] - - nqdBm_to_mW_map[qdbm])/2; - if (mw_uint < boundary) - break; - } - - qdbm += (uint8)offset; - - return (qdbm); -} - - -uint -bcm_bitcount(uint8 *bitmap, uint length) -{ - uint bitcount = 0, i; - uint8 tmp; - for (i = 0; i < length; i++) { - tmp = bitmap[i]; - while (tmp) { - bitcount++; - tmp &= (tmp - 1); - } - } - return bitcount; -} - -#ifdef BCMDRIVER - -/* Initialization of bcmstrbuf structure */ -void -bcm_binit(struct bcmstrbuf *b, char *buf, uint size) -{ - b->origsize = b->size = size; - b->origbuf = b->buf = buf; -} - -/* Buffer sprintf wrapper to guard against buffer overflow */ -int -bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) -{ - va_list ap; - int r; - - va_start(ap, fmt); - r = vsnprintf(b->buf, b->size, fmt, ap); - - /* Non Ansi C99 compliant returns -1, - * Ansi compliant return r >= b->size, - * bcmstdlib returns 0, handle all - */ - if ((r == -1) || (r >= (int)b->size) || (r == 0)) { - b->size = 0; - } else { - b->size -= r; - b->buf += r; - } - - va_end(ap); - - return r; -} - -void -bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount) -{ - int i; - - for (i = 0; i < num_bytes; i++) { - num[i] += amount; - if (num[i] >= amount) - break; - amount = 1; - } -} - -int -bcm_cmp_bytes(uchar *arg1, uchar *arg2, uint8 nbytes) -{ - int i; - - for (i = nbytes - 1; i >= 0; i--) { - if (arg1[i] != arg2[i]) - return (arg1[i] - arg2[i]); - } - return 0; -} - -void -bcm_print_bytes(char *name, const uchar *data, int len) -{ - int i; - int per_line = 0; - - printf("%s: %d \n", name ? name : "", len); - for (i = 0; i < len; i++) { - printf("%02x ", *data++); - per_line++; - if (per_line == 16) { - per_line = 0; - printf("\n"); - } - } - printf("\n"); -} -#if defined(WLTINYDUMP) || defined(WLMSG_INFORM) || defined(WLMSG_ASSOC) || \ - defined(WLMSG_PRPKT) || defined(WLMSG_WSEC) -#define SSID_FMT_BUF_LEN ((4 * DOT11_MAX_SSID_LEN) + 1) - -int -bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len) -{ - uint i, c; - char *p = buf; - char *endp = buf + SSID_FMT_BUF_LEN; - - if (ssid_len > DOT11_MAX_SSID_LEN) ssid_len = DOT11_MAX_SSID_LEN; - - for (i = 0; i < ssid_len; i++) { - c = (uint)ssid[i]; - if (c == '\\') { - *p++ = '\\'; - *p++ = '\\'; - } else if (bcm_isprint((uchar)c)) { - *p++ = (char)c; - } else { - p += snprintf(p, (endp - p), "\\x%02X", c); - } - } - *p = '\0'; - ASSERT(p < endp); - - return (int)(p - buf); -} -#endif - -#endif /* BCMDRIVER */ - -/* - * ProcessVars:Takes a buffer of "=\n" lines read from a file and ending in a NUL. - * also accepts nvram files which are already in the format of =\0\=\0 - * Removes carriage returns, empty lines, comment lines, and converts newlines to NULs. - * Shortens buffer as needed and pads with NULs. End of buffer is marked by two NULs. -*/ - -unsigned int -process_nvram_vars(char *varbuf, unsigned int len) -{ - char *dp; - bool findNewline; - int column; - unsigned int buf_len, n; - unsigned int pad = 0; - - dp = varbuf; - - findNewline = FALSE; - column = 0; - - for (n = 0; n < len; n++) { - if (varbuf[n] == '\r') - continue; - if (findNewline && varbuf[n] != '\n') - continue; - findNewline = FALSE; - if (varbuf[n] == '#') { - findNewline = TRUE; - continue; - } - if (varbuf[n] == '\n') { - if (column == 0) - continue; - *dp++ = 0; - column = 0; - continue; - } - *dp++ = varbuf[n]; - column++; - } - buf_len = (unsigned int)(dp - varbuf); - if (buf_len % 4) { - pad = 4 - buf_len % 4; - if (pad && (buf_len + pad <= len)) { - buf_len += pad; - } - } - - while (dp < varbuf + n) - *dp++ = 0; - - return buf_len; -} diff --git a/drivers/net/wireless/bcmdhd/bcmwifi.c b/drivers/net/wireless/bcmdhd/bcmwifi.c deleted file mode 100644 index 70722170bdfd..000000000000 --- a/drivers/net/wireless/bcmdhd/bcmwifi.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Misc utility routines used by kernel or app-level. - * Contents are wifi-specific, used by any kernel or app-level - * software that might want wifi things as it grows. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * $Id: bcmwifi.c,v 1.31.8.1 2010-08-03 17:47:05 Exp $ - */ - - -#include - -#ifdef BCMDRIVER -#include -#include -#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) -#define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c)) -#else -#include -#include -#include -#ifndef ASSERT -#define ASSERT(exp) -#endif -#endif -#include - -#if defined(WIN32) && (defined(BCMDLL) || defined(WLMDLL)) -#include -#endif - - - - - -char * -wf_chspec_ntoa(chanspec_t chspec, char *buf) -{ - const char *band, *bw, *sb; - uint channel; - - band = ""; - bw = ""; - sb = ""; - channel = CHSPEC_CHANNEL(chspec); - - if ((CHSPEC_IS2G(chspec) && channel > CH_MAX_2G_CHANNEL) || - (CHSPEC_IS5G(chspec) && channel <= CH_MAX_2G_CHANNEL)) - band = (CHSPEC_IS2G(chspec)) ? "b" : "a"; - if (CHSPEC_IS40(chspec)) { - if (CHSPEC_SB_UPPER(chspec)) { - sb = "u"; - channel += CH_10MHZ_APART; - } else { - sb = "l"; - channel -= CH_10MHZ_APART; - } - } else if (CHSPEC_IS10(chspec)) { - bw = "n"; - } - - - snprintf(buf, 6, "%d%s%s%s", channel, band, bw, sb); - return (buf); -} - - -chanspec_t -wf_chspec_aton(char *a) -{ - char *endp = NULL; - uint channel, band, bw, ctl_sb; - char c; - - channel = strtoul(a, &endp, 10); - - - if (endp == a) - return 0; - - if (channel > MAXCHANNEL) - return 0; - - band = ((channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G); - bw = WL_CHANSPEC_BW_20; - ctl_sb = WL_CHANSPEC_CTL_SB_NONE; - - a = endp; - - c = tolower(a[0]); - if (c == '\0') - goto done; - - - if (c == 'a' || c == 'b') { - band = (c == 'a') ? WL_CHANSPEC_BAND_5G : WL_CHANSPEC_BAND_2G; - a++; - c = tolower(a[0]); - if (c == '\0') - goto done; - } - - - if (c == 'n') { - bw = WL_CHANSPEC_BW_10; - } else if (c == 'l') { - bw = WL_CHANSPEC_BW_40; - ctl_sb = WL_CHANSPEC_CTL_SB_LOWER; - - if (channel <= (MAXCHANNEL - CH_20MHZ_APART)) - channel += CH_10MHZ_APART; - else - return 0; - } else if (c == 'u') { - bw = WL_CHANSPEC_BW_40; - ctl_sb = WL_CHANSPEC_CTL_SB_UPPER; - - if (channel > CH_20MHZ_APART) - channel -= CH_10MHZ_APART; - else - return 0; - } else { - return 0; - } - -done: - return (channel | band | bw | ctl_sb); -} - - -bool -wf_chspec_malformed(chanspec_t chanspec) -{ - - if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec)) - return TRUE; - - if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec)) - return TRUE; - - - if (CHSPEC_IS20_UNCOND(chanspec)) { - if (!CHSPEC_SB_NONE(chanspec)) - return TRUE; - } else { - if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec)) - return TRUE; - } - - return FALSE; -} - - -uint8 -wf_chspec_ctlchan(chanspec_t chspec) -{ - uint8 ctl_chan; - - - if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) { - return CHSPEC_CHANNEL(chspec); - } else { - - ASSERT(CHSPEC_BW(chspec) == WL_CHANSPEC_BW_40); - - if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) { - - ctl_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec)); - } else { - ASSERT(CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_LOWER); - - ctl_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec)); - } - } - - return ctl_chan; -} - -chanspec_t -wf_chspec_ctlchspec(chanspec_t chspec) -{ - chanspec_t ctl_chspec = 0; - uint8 channel; - - ASSERT(!wf_chspec_malformed(chspec)); - - - if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) { - return chspec; - } else { - if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) { - channel = UPPER_20_SB(CHSPEC_CHANNEL(chspec)); - } else { - channel = LOWER_20_SB(CHSPEC_CHANNEL(chspec)); - } - ctl_chspec = channel | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE; - ctl_chspec |= CHSPEC_BAND(chspec); - } - return ctl_chspec; -} - - -int -wf_mhz2channel(uint freq, uint start_factor) -{ - int ch = -1; - uint base; - int offset; - - - if (start_factor == 0) { - if (freq >= 2400 && freq <= 2500) - start_factor = WF_CHAN_FACTOR_2_4_G; - else if (freq >= 5000 && freq <= 6000) - start_factor = WF_CHAN_FACTOR_5_G; - } - - if (freq == 2484 && start_factor == WF_CHAN_FACTOR_2_4_G) - return 14; - - base = start_factor / 2; - - - if ((freq < base) || (freq > base + 1000)) - return -1; - - offset = freq - base; - ch = offset / 5; - - - if (offset != (ch * 5)) - return -1; - - - if (start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 13)) - return -1; - - return ch; -} - - -int -wf_channel2mhz(uint ch, uint start_factor) -{ - int freq; - - if ((start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 14)) || - (ch > 200)) - freq = -1; - else if ((start_factor == WF_CHAN_FACTOR_2_4_G) && (ch == 14)) - freq = 2484; - else - freq = ch * 5 + start_factor / 2; - - return freq; -} diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h deleted file mode 100644 index c5a74cde1fe5..000000000000 --- a/drivers/net/wireless/bcmdhd/dhd.h +++ /dev/null @@ -1,788 +0,0 @@ -/* - * Header file describing the internal (inter-module) DHD interfaces. - * - * Provides type definitions and function prototypes used to link the - * DHD OS, bus, and protocol modules. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd.h 357954 2012-09-20 18:22:31Z $ - */ - -/**************** - * Common types * - */ - -#ifndef _dhd_h_ -#define _dhd_h_ - -#if defined(CHROMIUMOS_COMPAT_WIRELESS) -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK) -#include -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */ - -/* The kernel threading is sdio-specific */ -struct task_struct; -struct sched_param; -int setScheduler(struct task_struct *p, int policy, struct sched_param *param); - -#define ALL_INTERFACES 0xff - -#include - - -/* Forward decls */ -struct dhd_bus; -struct dhd_prot; -struct dhd_info; -struct dhd_cmn; - -/* The level of bus communication with the dongle */ -enum dhd_bus_state { - DHD_BUS_DOWN, /* Not ready for frame transfers */ - DHD_BUS_LOAD, /* Download access only (CPU reset) */ - DHD_BUS_DATA /* Ready for frame transfers */ -}; - -/* Firmware requested operation mode */ -#define STA_MASK 0x0001 -#define HOSTAPD_MASK 0x0002 -#define WFD_MASK 0x0004 -#define SOFTAP_FW_MASK 0x0008 -#define P2P_GO_ENABLED 0x0010 -#define P2P_GC_ENABLED 0x0020 -#define CONCURENT_MASK 0x00F0 - -#define MANUFACTRING_FW "WLTEST" - -/* max sequential rxcntl timeouts to set HANG event */ -#define MAX_CNTL_TIMEOUT 2 - -#define DHD_SCAN_ACTIVE_TIME 40 /* ms : Embedded default Active setting from DHD Driver */ -#define DHD_SCAN_PASSIVE_TIME 130 /* ms: Embedded default Passive setting from DHD Driver */ - -#define DHD_BEACON_TIMEOUT_NORMAL 4 -#define DHD_BEACON_TIMEOUT_HIGH 10 - -enum dhd_bus_wake_state { - WAKE_LOCK_OFF, - WAKE_LOCK_PRIV, - WAKE_LOCK_DPC, - WAKE_LOCK_IOCTL, - WAKE_LOCK_DOWNLOAD, - WAKE_LOCK_TMOUT, - WAKE_LOCK_WATCHDOG, - WAKE_LOCK_LINK_DOWN_TMOUT, - WAKE_LOCK_PNO_FIND_TMOUT, - WAKE_LOCK_SOFTAP_SET, - WAKE_LOCK_SOFTAP_STOP, - WAKE_LOCK_SOFTAP_START, - WAKE_LOCK_SOFTAP_THREAD, - WAKE_LOCK_MAX -}; - -enum dhd_prealloc_index { - DHD_PREALLOC_PROT = 0, - DHD_PREALLOC_RXBUF, - DHD_PREALLOC_DATABUF, - DHD_PREALLOC_OSL_BUF -}; - -typedef enum { - DHD_IF_NONE = 0, - DHD_IF_ADD, - DHD_IF_DEL, - DHD_IF_CHANGE, - DHD_IF_DELETING -} dhd_if_state_t; - -#if defined(CONFIG_DHD_USE_STATIC_BUF) - -uint8* dhd_os_prealloc(void *osh, int section, uint size); -void dhd_os_prefree(void *osh, void *addr, uint size); -#define DHD_OS_PREALLOC(osh, section, size) dhd_os_prealloc(osh, section, size) -#define DHD_OS_PREFREE(osh, addr, size) dhd_os_prefree(osh, addr, size) - -#else - -#define DHD_OS_PREALLOC(osh, section, size) MALLOC(osh, size) -#define DHD_OS_PREFREE(osh, addr, size) MFREE(osh, addr, size) - -#endif /* defined(CONFIG_DHD_USE_STATIC_BUF) */ - -/* Packet alignment for most efficient SDIO (can change based on platform) */ -#ifndef DHD_SDALIGN -#define DHD_SDALIGN 32 -#endif - -/* Common structure for module and instance linkage */ -typedef struct dhd_pub { - /* Linkage ponters */ - osl_t *osh; /* OSL handle */ - struct dhd_bus *bus; /* Bus module handle */ - struct dhd_prot *prot; /* Protocol module handle */ - struct dhd_info *info; /* Info module handle */ - struct dhd_cmn *cmn; /* dhd_common module handle */ - - /* Internal dhd items */ - bool up; /* Driver up/down (to OS) */ - bool txoff; /* Transmit flow-controlled */ - bool dongle_reset; /* TRUE = DEVRESET put dongle into reset */ - enum dhd_bus_state busstate; - uint hdrlen; /* Total DHD header length (proto + bus) */ - uint maxctl; /* Max size rxctl request from proto to bus */ - uint rxsz; /* Rx buffer size bus module should use */ - uint8 wme_dp; /* wme discard priority */ - - /* Dongle media info */ - bool iswl; /* Dongle-resident driver is wl */ - ulong drv_version; /* Version of dongle-resident driver */ - struct ether_addr mac; /* MAC address obtained from dongle */ - dngl_stats_t dstats; /* Stats for dongle-based data */ - - /* Additional stats for the bus level */ - ulong tx_packets; /* Data packets sent to dongle */ - ulong tx_multicast; /* Multicast data packets sent to dongle */ - ulong tx_errors; /* Errors in sending data to dongle */ - ulong tx_ctlpkts; /* Control packets sent to dongle */ - ulong tx_ctlerrs; /* Errors sending control frames to dongle */ - ulong rx_packets; /* Packets sent up the network interface */ - ulong rx_multicast; /* Multicast packets sent up the network interface */ - ulong rx_errors; /* Errors processing rx data packets */ - ulong rx_ctlpkts; /* Control frames processed from dongle */ - ulong rx_ctlerrs; /* Errors in processing rx control frames */ - ulong rx_dropped; /* Packets dropped locally (no memory) */ - ulong rx_flushed; /* Packets flushed due to unscheduled sendup thread */ - ulong wd_dpc_sched; /* Number of times dhd dpc scheduled by watchdog timer */ - - ulong rx_readahead_cnt; /* Number of packets where header read-ahead was used. */ - ulong tx_realloc; /* Number of tx packets we had to realloc for headroom */ - ulong fc_packets; /* Number of flow control pkts recvd */ - - /* Last error return */ - int bcmerror; - uint tickcnt; - - /* Last error from dongle */ - int dongle_error; - - /* Suspend disable flag and "in suspend" flag */ - int suspend_disable_flag; /* "1" to disable all extra powersaving during suspend */ - int in_suspend; /* flag set to 1 when early suspend called */ -#ifdef PNO_SUPPORT - int pno_enable; /* pno status : "1" is pno enable */ -#endif /* PNO_SUPPORT */ - int dtim_skip; /* dtim skip , default 0 means wake each dtim */ - - /* Pkt filter defination */ - char * pktfilter[100]; - int pktfilter_count; - - wl_country_t dhd_cspec; /* Current Locale info */ - char eventmask[WL_EVENTING_MASK_LEN]; - int op_mode; /* STA, HostAPD, WFD, SoftAP */ - -/* Set this to 1 to use a seperate interface (p2p0) for p2p operations. - * For ICS MR1 releases it should be disable to be compatable with ICS MR1 Framework - * see target dhd-cdc-sdmmc-panda-cfg80211-icsmr1-gpl-debug in Makefile - */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 - struct mutex wl_start_stop_lock; /* lock/unlock for Android start/stop */ - struct mutex wl_softap_lock; /* lock/unlock for any SoftAP/STA settings */ -#endif - - uint16 maxdatablks; -#ifdef PROP_TXSTATUS - int wlfc_enabled; - void* wlfc_state; -#endif - bool dongle_isolation; - int hang_was_sent; - int rxcnt_timeout; /* counter rxcnt timeout to send HANG */ - int txcnt_timeout; /* counter txcnt timeout to send HANG */ -#ifdef WLMEDIA_HTSF - uint8 htsfdlystat_sz; /* Size of delay stats, max 255B */ -#endif -} dhd_pub_t; - -typedef struct dhd_cmn { - osl_t *osh; /* OSL handle */ - dhd_pub_t *dhd; -} dhd_cmn_t; - - - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) - - #define DHD_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); - #define _DHD_PM_RESUME_WAIT(a, b) do {\ - int retry = 0; \ - SMP_RD_BARRIER_DEPENDS(); \ - while (dhd_mmc_suspend && retry++ != b) { \ - SMP_RD_BARRIER_DEPENDS(); \ - wait_event_interruptible_timeout(a, !dhd_mmc_suspend, 1); \ - } \ - } while (0) - #define DHD_PM_RESUME_WAIT(a) _DHD_PM_RESUME_WAIT(a, 200) - #define DHD_PM_RESUME_WAIT_FOREVER(a) _DHD_PM_RESUME_WAIT(a, ~0) - #define DHD_PM_RESUME_RETURN_ERROR(a) do { if (dhd_mmc_suspend) return a; } while (0) - #define DHD_PM_RESUME_RETURN do { if (dhd_mmc_suspend) return; } while (0) - - #define DHD_SPINWAIT_SLEEP_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); - #define SPINWAIT_SLEEP(a, exp, us) do { \ - uint countdown = (us) + 9999; \ - while ((exp) && (countdown >= 10000)) { \ - wait_event_interruptible_timeout(a, FALSE, 1); \ - countdown -= 10000; \ - } \ - } while (0) - - #else - - #define DHD_PM_RESUME_WAIT_INIT(a) - #define DHD_PM_RESUME_WAIT(a) - #define DHD_PM_RESUME_WAIT_FOREVER(a) - #define DHD_PM_RESUME_RETURN_ERROR(a) - #define DHD_PM_RESUME_RETURN - - #define DHD_SPINWAIT_SLEEP_INIT(a) - #define SPINWAIT_SLEEP(a, exp, us) do { \ - uint countdown = (us) + 9; \ - while ((exp) && (countdown >= 10)) { \ - OSL_DELAY(10); \ - countdown -= 10; \ - } \ - } while (0) - - #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ -#ifndef DHDTHREAD -#undef SPINWAIT_SLEEP -#define SPINWAIT_SLEEP(a, exp, us) SPINWAIT(exp, us) -#endif /* DHDTHREAD */ -#define DHD_IF_VIF 0x01 /* Virtual IF (Hidden from user) */ - -unsigned long dhd_os_spin_lock(dhd_pub_t *pub); -void dhd_os_spin_unlock(dhd_pub_t *pub, unsigned long flags); - -/* Wakelock Functions */ -extern int dhd_os_wake_lock(dhd_pub_t *pub); -extern int dhd_os_wake_unlock(dhd_pub_t *pub); -extern int dhd_os_wake_lock_timeout(dhd_pub_t *pub); -extern int dhd_os_wake_lock_rx_timeout_enable(dhd_pub_t *pub, int val); -extern int dhd_os_wake_lock_ctrl_timeout_enable(dhd_pub_t *pub, int val); -extern int dhd_os_wd_wake_lock(dhd_pub_t *pub); -extern int dhd_os_wd_wake_unlock(dhd_pub_t *pub); - -inline static void MUTEX_LOCK_SOFTAP_SET_INIT(dhd_pub_t * dhdp) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 - mutex_init(&dhdp->wl_softap_lock); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -} - -inline static void MUTEX_LOCK_SOFTAP_SET(dhd_pub_t * dhdp) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 - mutex_lock(&dhdp->wl_softap_lock); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -} - -inline static void MUTEX_UNLOCK_SOFTAP_SET(dhd_pub_t * dhdp) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 - mutex_unlock(&dhdp->wl_softap_lock); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -} - -#define DHD_OS_WAKE_LOCK(pub) dhd_os_wake_lock(pub) -#define DHD_OS_WAKE_UNLOCK(pub) dhd_os_wake_unlock(pub) -#define DHD_OS_WD_WAKE_LOCK(pub) dhd_os_wd_wake_lock(pub) -#define DHD_OS_WD_WAKE_UNLOCK(pub) dhd_os_wd_wake_unlock(pub) -#define DHD_OS_WAKE_LOCK_TIMEOUT(pub) dhd_os_wake_lock_timeout(pub) -#define DHD_OS_WAKE_LOCK_RX_TIMEOUT_ENABLE(pub, val) dhd_os_wake_lock_rx_timeout_enable(pub, val) -#define DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(pub, val) dhd_os_wake_lock_ctrl_timeout_enable(pub, val) -#define DHD_PACKET_TIMEOUT_MS 1000 -#define DHD_EVENT_TIMEOUT_MS 1500 - -/* interface operations (register, remove) should be atomic, use this lock to prevent race - * condition among wifi on/off and interface operation functions - */ -void dhd_net_if_lock(struct net_device *dev); -void dhd_net_if_unlock(struct net_device *dev); - -typedef struct dhd_if_event { - uint8 ifidx; - uint8 action; - uint8 flags; - uint8 bssidx; - uint8 is_AP; -} dhd_if_event_t; - -typedef enum dhd_attach_states -{ - DHD_ATTACH_STATE_INIT = 0x0, - DHD_ATTACH_STATE_NET_ALLOC = 0x1, - DHD_ATTACH_STATE_DHD_ALLOC = 0x2, - DHD_ATTACH_STATE_ADD_IF = 0x4, - DHD_ATTACH_STATE_PROT_ATTACH = 0x8, - DHD_ATTACH_STATE_WL_ATTACH = 0x10, - DHD_ATTACH_STATE_THREADS_CREATED = 0x20, - DHD_ATTACH_STATE_WAKELOCKS_INIT = 0x40, - DHD_ATTACH_STATE_CFG80211 = 0x80, - DHD_ATTACH_STATE_EARLYSUSPEND_DONE = 0x100, - DHD_ATTACH_STATE_DONE = 0x200 -} dhd_attach_states_t; - -/* Value -1 means we are unsuccessful in creating the kthread. */ -#define DHD_PID_KT_INVALID -1 -/* Value -2 means we are unsuccessful in both creating the kthread and tasklet */ -#define DHD_PID_KT_TL_INVALID -2 - -/* - * Exported from dhd OS modules (dhd_linux/dhd_ndis) - */ - -/* To allow osl_attach/detach calls from os-independent modules */ -osl_t *dhd_osl_attach(void *pdev, uint bustype); -void dhd_osl_detach(osl_t *osh); - -/* Indication from bus module regarding presence/insertion of dongle. - * Return dhd_pub_t pointer, used as handle to OS module in later calls. - * Returned structure should have bus and prot pointers filled in. - * bus_hdrlen specifies required headroom for bus module header. - */ -extern dhd_pub_t *dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen); -#if defined(WLP2P) && defined(WL_CFG80211) -/* To allow attach/detach calls corresponding to p2p0 interface */ -extern int dhd_attach_p2p(dhd_pub_t *); -extern int dhd_detach_p2p(dhd_pub_t *); -#endif /* WLP2P && WL_CFG80211 */ -extern int dhd_net_attach(dhd_pub_t *dhdp, int idx); - -/* Indication from bus module regarding removal/absence of dongle */ -extern void dhd_detach(dhd_pub_t *dhdp); -extern void dhd_free(dhd_pub_t *dhdp); - -/* Indication from bus module to change flow-control state */ -extern void dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool on); - -extern bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec); - -/* Receive frame for delivery to OS. Callee disposes of rxp. */ -extern void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *rxp, int numpkt, uint8 chan); - -/* Return pointer to interface name */ -extern char *dhd_ifname(dhd_pub_t *dhdp, int idx); - -/* Request scheduling of the bus dpc */ -extern void dhd_sched_dpc(dhd_pub_t *dhdp); - -/* Notify tx completion */ -extern void dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success); - -/* OS independent layer functions */ -extern int dhd_os_proto_block(dhd_pub_t * pub); -extern int dhd_os_proto_unblock(dhd_pub_t * pub); -extern int dhd_os_ioctl_resp_wait(dhd_pub_t * pub, uint * condition, bool * pending); -extern int dhd_os_ioctl_resp_wake(dhd_pub_t * pub); -extern unsigned int dhd_os_get_ioctl_resp_timeout(void); -extern void dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec); -extern void * dhd_os_open_image(char * filename); -extern int dhd_os_get_image_block(char * buf, int len, void * image); -extern void dhd_os_close_image(void * image); -extern void dhd_os_wd_timer(void *bus, uint wdtick); -extern void dhd_os_sdlock(dhd_pub_t * pub); -extern void dhd_os_sdunlock(dhd_pub_t * pub); -extern void dhd_os_sdlock_txq(dhd_pub_t * pub); -extern void dhd_os_sdunlock_txq(dhd_pub_t * pub); -extern void dhd_os_sdlock_rxq(dhd_pub_t * pub); -extern void dhd_os_sdunlock_rxq(dhd_pub_t * pub); -extern void dhd_os_sdlock_sndup_rxq(dhd_pub_t * pub); -extern void dhd_customer_gpio_wlan_ctrl(int onoff); -extern int dhd_custom_get_mac_address(unsigned char *buf); -extern void dhd_os_sdunlock_sndup_rxq(dhd_pub_t * pub); -extern void dhd_os_sdlock_eventq(dhd_pub_t * pub); -extern void dhd_os_sdunlock_eventq(dhd_pub_t * pub); -extern bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret); -extern int dhd_os_send_hang_message(dhd_pub_t *dhdp); -extern int net_os_send_hang_message(struct net_device *dev); -extern void dhd_set_version_info(dhd_pub_t *pub, char *fw); - -#ifdef PNO_SUPPORT -extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled); -extern int dhd_pno_clean(dhd_pub_t *dhd); -extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, - ushort scan_fr, int pno_repeat, int pno_freq_expo_max); -extern int dhd_pno_set_ex(dhd_pub_t *dhd, wl_pfn_t* ssidnet, int nssid, - ushort pno_interval, int pno_repeat, int pno_expo_max, int pno_lost_time); -extern int dhd_pno_get_status(dhd_pub_t *dhd); -extern int dhd_dev_pno_reset(struct net_device *dev); -extern int dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local, - int nssid, ushort scan_fr, int pno_repeat, int pno_freq_expo_max); -extern int dhd_dev_pno_set_ex(struct net_device *dev, wl_pfn_t* ssidnet, int nssid, - ushort pno_interval, int pno_repeat, int pno_expo_max, int pno_lost_time); -extern int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled); -extern int dhd_dev_get_pno_status(struct net_device *dev); -#endif /* PNO_SUPPORT */ - -#define DHD_UNICAST_FILTER_NUM 0 -#define DHD_BROADCAST_FILTER_NUM 1 -#define DHD_MULTICAST4_FILTER_NUM 2 -#define DHD_MULTICAST6_FILTER_NUM 3 -#define DHD_MDNS_FILTER_NUM 4 -extern int dhd_os_set_packet_filter(dhd_pub_t *dhdp, int val); -extern int net_os_set_packet_filter(struct net_device *dev, int val); -extern int net_os_rxfilter_add_remove(struct net_device *dev, int val, int num); - -extern int dhd_get_dtim_skip(dhd_pub_t *dhd); -extern bool dhd_check_ap_wfd_mode_set(dhd_pub_t *dhd); - -#ifdef DHD_DEBUG -extern int write_to_file(dhd_pub_t *dhd, uint8 *buf, int size); -#endif /* DHD_DEBUG */ -#if defined(OOB_INTR_ONLY) -extern int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr); -#endif /* defined(OOB_INTR_ONLY) */ -extern void dhd_os_sdtxlock(dhd_pub_t * pub); -extern void dhd_os_sdtxunlock(dhd_pub_t * pub); - -typedef struct { - uint32 limit; /* Expiration time (usec) */ - uint32 increment; /* Current expiration increment (usec) */ - uint32 elapsed; /* Current elapsed time (usec) */ - uint32 tick; /* O/S tick time (usec) */ -} dhd_timeout_t; - -extern void dhd_timeout_start(dhd_timeout_t *tmo, uint usec); -extern int dhd_timeout_expired(dhd_timeout_t *tmo); - -extern int dhd_ifname2idx(struct dhd_info *dhd, char *name); -extern int dhd_net2idx(struct dhd_info *dhd, struct net_device *net); -extern struct net_device * dhd_idx2net(void *pub, int ifidx); -extern int wl_host_event(dhd_pub_t *dhd_pub, int *idx, void *pktdata, - wl_event_msg_t *, void **data_ptr); -extern void wl_event_to_host_order(wl_event_msg_t * evt); - -extern int dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifindex, wl_ioctl_t *ioc, void *buf, int len); -extern int dhd_wl_ioctl_cmd(dhd_pub_t *dhd_pub, int cmd, void *arg, int len, uint8 set, - int ifindex); - -extern struct dhd_cmn *dhd_common_init(osl_t *osh); -extern void dhd_common_deinit(dhd_pub_t *dhd_pub, dhd_cmn_t *sa_cmn); - -extern int dhd_do_driver_init(struct net_device *net); -extern int dhd_add_if(struct dhd_info *dhd, int ifidx, void *handle, - char *name, uint8 *mac_addr, uint32 flags, uint8 bssidx); -extern void dhd_del_if(struct dhd_info *dhd, int ifidx); - -extern void dhd_vif_add(struct dhd_info *dhd, int ifidx, char * name); -extern void dhd_vif_del(struct dhd_info *dhd, int ifidx); - -extern void dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx); -extern void dhd_vif_sendup(struct dhd_info *dhd, int ifidx, uchar *cp, int len); - - -/* Send packet to dongle via data channel */ -extern int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pkt); - -/* send up locally generated event */ -extern void dhd_sendup_event_common(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data); -/* Send event to host */ -extern void dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data); -extern int dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag); -extern uint dhd_bus_status(dhd_pub_t *dhdp); -extern int dhd_bus_start(dhd_pub_t *dhdp); -extern int dhd_bus_membytes(dhd_pub_t *dhdp, bool set, uint32 address, uint8 *data, uint size); -extern void dhd_print_buf(void *pbuf, int len, int bytes_per_line); -extern bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf, int *retval); -extern uint dhd_bus_chip_id(dhd_pub_t *dhdp); -extern uint dhd_bus_chiprev_id(dhd_pub_t *dhdp); -extern uint dhd_bus_chippkg_id(dhd_pub_t *dhdp); - -#if defined(KEEP_ALIVE) -extern int dhd_keep_alive_onoff(dhd_pub_t *dhd); -#endif /* KEEP_ALIVE */ - -#ifdef ARP_OFFLOAD_SUPPORT -extern void dhd_arp_offload_set(dhd_pub_t * dhd, int arp_mode); -extern void dhd_arp_offload_enable(dhd_pub_t * dhd, int arp_enable); -#endif /* ARP_OFFLOAD_SUPPORT */ - - -typedef enum cust_gpio_modes { - WLAN_RESET_ON, - WLAN_RESET_OFF, - WLAN_POWER_ON, - WLAN_POWER_OFF -} cust_gpio_modes_t; - -extern int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag); -extern int wl_iw_send_priv_event(struct net_device *dev, char *flag); -/* - * Insmod parameters for debug/test - */ - -/* Watchdog timer interval */ -extern uint dhd_watchdog_ms; - -#if defined(DHD_DEBUG) -/* Console output poll interval */ -extern uint dhd_console_ms; -extern uint wl_msg_level; -#endif /* defined(DHD_DEBUG) */ - -/* Use interrupts */ -extern uint dhd_intr; - -/* Use polling */ -extern uint dhd_poll; - -/* ARP offload agent mode */ -extern uint dhd_arp_mode; - -/* ARP offload enable */ -extern uint dhd_arp_enable; - -/* Pkt filte enable control */ -extern uint dhd_pkt_filter_enable; - -/* Pkt filter init setup */ -extern uint dhd_pkt_filter_init; - -/* Pkt filter mode control */ -extern uint dhd_master_mode; - -/* Roaming mode control */ -extern uint dhd_roam_disable; - -/* Roaming mode control */ -extern uint dhd_radio_up; - -/* Initial idletime ticks (may be -1 for immediate idle, 0 for no idle) */ -extern int dhd_idletime; -#define DHD_IDLETIME_TICKS 1 - -/* SDIO Drive Strength */ -extern uint dhd_sdiod_drive_strength; - -/* Override to force tx queueing all the time */ -extern uint dhd_force_tx_queueing; -/* Default KEEP_ALIVE Period is 55 sec to prevent AP from sending Keep Alive probe frame */ -#define KEEP_ALIVE_PERIOD 55000 -#define NULL_PKT_STR "null_pkt" - -#ifdef SDTEST -/* Echo packet generator (SDIO), pkts/s */ -extern uint dhd_pktgen; - -/* Echo packet len (0 => sawtooth, max 1800) */ -extern uint dhd_pktgen_len; -#define MAX_PKTGEN_LEN 1800 -#endif - -/* hooks for custom glom setting option via Makefile */ -#define DEFAULT_GLOM_VALUE -1 -#ifndef CUSTOM_GLOM_SETTING -#define CUSTOM_GLOM_SETTING DEFAULT_GLOM_VALUE -#endif - -/* hooks for custom Roaming Trigger setting via Makefile */ -#define DEFAULT_ROAM_TRIGGER_VALUE -65 /* dBm default roam trigger all band */ -#define DEFAULT_ROAM_TRIGGER_SETTING -1 -#ifndef CUSTOM_ROAM_TRIGGER_SETTING -#define CUSTOM_ROAM_TRIGGER_SETTING DEFAULT_ROAM_TRIGGER_VALUE -#endif - -/* hooks for custom Roaming Romaing setting via Makefile */ -#define DEFAULT_ROAM_DELTA_VALUE 10 /* dBm default roam delta all band */ -#define DEFAULT_ROAM_DELTA_SETTING -1 -#ifndef CUSTOM_ROAM_DELTA_SETTING -#define CUSTOM_ROAM_DELTA_SETTING DEFAULT_ROAM_DELTA_VALUE -#endif - -/* optionally set by a module_param_string() */ -#define MOD_PARAM_PATHLEN 2048 -extern char fw_path[MOD_PARAM_PATHLEN]; -extern char nv_path[MOD_PARAM_PATHLEN]; - -#define MOD_PARAM_INFOLEN 512 - -#ifdef SOFTAP -extern char fw_path2[MOD_PARAM_PATHLEN]; -#endif - -/* Flag to indicate if we should download firmware on driver load */ -extern uint dhd_download_fw_on_driverload; - -/* For supporting multiple interfaces */ -#define DHD_MAX_IFS 16 -#define DHD_DEL_IF -0xe -#define DHD_BAD_IF -0xf - -#ifdef PROP_TXSTATUS -/* Please be mindful that total pkttag space is 32 octets only */ -typedef struct dhd_pkttag { - /* - b[11 ] - 1 = this packet was sent in response to one time packet request, - do not increment credit on status for this one. [WLFC_CTL_TYPE_MAC_REQUEST_PACKET]. - b[10 ] - 1 = signal-only-packet to firmware [i.e. nothing to piggyback on] - b[9 ] - 1 = packet is host->firmware (transmit direction) - - 0 = packet received from firmware (firmware->host) - b[8 ] - 1 = packet was sent due to credit_request (pspoll), - packet does not count against FIFO credit. - - 0 = normal transaction, packet counts against FIFO credit - b[7 ] - 1 = AP, 0 = STA - b[6:4] - AC FIFO number - b[3:0] - interface index - */ - uint16 if_flags; - /* destination MAC address for this packet so that not every - module needs to open the packet to find this - */ - uint8 dstn_ether[ETHER_ADDR_LEN]; - /* - This 32-bit goes from host to device for every packet. - */ - uint32 htod_tag; - /* bus specific stuff */ - union { - struct { - void* stuff; - uint32 thing1; - uint32 thing2; - } sd; - struct { - void* bus; - void* urb; - } usb; - } bus_specific; -} dhd_pkttag_t; - -#define DHD_PKTTAG_SET_H2DTAG(tag, h2dvalue) ((dhd_pkttag_t*)(tag))->htod_tag = (h2dvalue) -#define DHD_PKTTAG_H2DTAG(tag) (((dhd_pkttag_t*)(tag))->htod_tag) - -#define DHD_PKTTAG_IFMASK 0xf -#define DHD_PKTTAG_IFTYPE_MASK 0x1 -#define DHD_PKTTAG_IFTYPE_SHIFT 7 -#define DHD_PKTTAG_FIFO_MASK 0x7 -#define DHD_PKTTAG_FIFO_SHIFT 4 - -#define DHD_PKTTAG_SIGNALONLY_MASK 0x1 -#define DHD_PKTTAG_SIGNALONLY_SHIFT 10 - -#define DHD_PKTTAG_ONETIMEPKTRQST_MASK 0x1 -#define DHD_PKTTAG_ONETIMEPKTRQST_SHIFT 11 - -#define DHD_PKTTAG_PKTDIR_MASK 0x1 -#define DHD_PKTTAG_PKTDIR_SHIFT 9 - -#define DHD_PKTTAG_CREDITCHECK_MASK 0x1 -#define DHD_PKTTAG_CREDITCHECK_SHIFT 8 - -#define DHD_PKTTAG_INVALID_FIFOID 0x7 - -#define DHD_PKTTAG_SETFIFO(tag, fifo) ((dhd_pkttag_t*)(tag))->if_flags = \ - (((dhd_pkttag_t*)(tag))->if_flags & ~(DHD_PKTTAG_FIFO_MASK << DHD_PKTTAG_FIFO_SHIFT)) | \ - (((fifo) & DHD_PKTTAG_FIFO_MASK) << DHD_PKTTAG_FIFO_SHIFT) -#define DHD_PKTTAG_FIFO(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \ - DHD_PKTTAG_FIFO_SHIFT) & DHD_PKTTAG_FIFO_MASK) - -#define DHD_PKTTAG_SETIF(tag, if) ((dhd_pkttag_t*)(tag))->if_flags = \ - (((dhd_pkttag_t*)(tag))->if_flags & ~DHD_PKTTAG_IFMASK) | ((if) & DHD_PKTTAG_IFMASK) -#define DHD_PKTTAG_IF(tag) (((dhd_pkttag_t*)(tag))->if_flags & DHD_PKTTAG_IFMASK) - -#define DHD_PKTTAG_SETIFTYPE(tag, isAP) ((dhd_pkttag_t*)(tag))->if_flags = \ - (((dhd_pkttag_t*)(tag))->if_flags & \ - ~(DHD_PKTTAG_IFTYPE_MASK << DHD_PKTTAG_IFTYPE_SHIFT)) | \ - (((isAP) & DHD_PKTTAG_IFTYPE_MASK) << DHD_PKTTAG_IFTYPE_SHIFT) -#define DHD_PKTTAG_IFTYPE(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \ - DHD_PKTTAG_IFTYPE_SHIFT) & DHD_PKTTAG_IFTYPE_MASK) - -#define DHD_PKTTAG_SETCREDITCHECK(tag, check) ((dhd_pkttag_t*)(tag))->if_flags = \ - (((dhd_pkttag_t*)(tag))->if_flags & \ - ~(DHD_PKTTAG_CREDITCHECK_MASK << DHD_PKTTAG_CREDITCHECK_SHIFT)) | \ - (((check) & DHD_PKTTAG_CREDITCHECK_MASK) << DHD_PKTTAG_CREDITCHECK_SHIFT) -#define DHD_PKTTAG_CREDITCHECK(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \ - DHD_PKTTAG_CREDITCHECK_SHIFT) & DHD_PKTTAG_CREDITCHECK_MASK) - -#define DHD_PKTTAG_SETPKTDIR(tag, dir) ((dhd_pkttag_t*)(tag))->if_flags = \ - (((dhd_pkttag_t*)(tag))->if_flags & \ - ~(DHD_PKTTAG_PKTDIR_MASK << DHD_PKTTAG_PKTDIR_SHIFT)) | \ - (((dir) & DHD_PKTTAG_PKTDIR_MASK) << DHD_PKTTAG_PKTDIR_SHIFT) -#define DHD_PKTTAG_PKTDIR(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \ - DHD_PKTTAG_PKTDIR_SHIFT) & DHD_PKTTAG_PKTDIR_MASK) - -#define DHD_PKTTAG_SETSIGNALONLY(tag, signalonly) ((dhd_pkttag_t*)(tag))->if_flags = \ - (((dhd_pkttag_t*)(tag))->if_flags & \ - ~(DHD_PKTTAG_SIGNALONLY_MASK << DHD_PKTTAG_SIGNALONLY_SHIFT)) | \ - (((signalonly) & DHD_PKTTAG_SIGNALONLY_MASK) << DHD_PKTTAG_SIGNALONLY_SHIFT) -#define DHD_PKTTAG_SIGNALONLY(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \ - DHD_PKTTAG_SIGNALONLY_SHIFT) & DHD_PKTTAG_SIGNALONLY_MASK) - -#define DHD_PKTTAG_SETONETIMEPKTRQST(tag) ((dhd_pkttag_t*)(tag))->if_flags = \ - (((dhd_pkttag_t*)(tag))->if_flags & \ - ~(DHD_PKTTAG_ONETIMEPKTRQST_MASK << DHD_PKTTAG_ONETIMEPKTRQST_SHIFT)) | \ - (1 << DHD_PKTTAG_ONETIMEPKTRQST_SHIFT) -#define DHD_PKTTAG_ONETIMEPKTRQST(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \ - DHD_PKTTAG_ONETIMEPKTRQST_SHIFT) & DHD_PKTTAG_ONETIMEPKTRQST_MASK) - -#define DHD_PKTTAG_SETDSTN(tag, dstn_MAC_ea) memcpy(((dhd_pkttag_t*)((tag)))->dstn_ether, \ - (dstn_MAC_ea), ETHER_ADDR_LEN) -#define DHD_PKTTAG_DSTN(tag) ((dhd_pkttag_t*)(tag))->dstn_ether - -typedef int (*f_commitpkt_t)(void* ctx, void* p); - -#ifdef PROP_TXSTATUS_DEBUG -#define DHD_WLFC_CTRINC_MAC_CLOSE(entry) do { (entry)->closed_ct++; } while (0) -#define DHD_WLFC_CTRINC_MAC_OPEN(entry) do { (entry)->opened_ct++; } while (0) -#else -#define DHD_WLFC_CTRINC_MAC_CLOSE(entry) do {} while (0) -#define DHD_WLFC_CTRINC_MAC_OPEN(entry) do {} while (0) -#endif - -#endif /* PROP_TXSTATUS */ - -extern void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar); -extern void dhd_wait_event_wakeup(dhd_pub_t*dhd); - -#ifdef ARP_OFFLOAD_SUPPORT -#define MAX_IPV4_ENTRIES 8 -/* dhd_commn arp offload wrapers */ -void dhd_aoe_hostip_clr(dhd_pub_t *dhd); -void dhd_aoe_arp_clr(dhd_pub_t *dhd); -int dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen); -void dhd_arp_offload_add_ip(dhd_pub_t *dhd, uint32 ipaddr); -#endif /* ARP_OFFLOAD_SUPPORT */ - -#endif /* _dhd_h_ */ diff --git a/drivers/net/wireless/bcmdhd/dhd_bta.c b/drivers/net/wireless/bcmdhd/dhd_bta.c deleted file mode 100644 index 6b782ea4a4d2..000000000000 --- a/drivers/net/wireless/bcmdhd/dhd_bta.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * BT-AMP support routines - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd_bta.c,v 1.10.4.2 2010-12-22 23:47:23 Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - - -#ifdef SEND_HCI_CMD_VIA_IOCTL -#define BTA_HCI_CMD_MAX_LEN HCI_CMD_PREAMBLE_SIZE + HCI_CMD_DATA_SIZE - -/* Send HCI cmd via wl iovar HCI_cmd to the dongle. */ -int -dhd_bta_docmd(dhd_pub_t *pub, void *cmd_buf, uint cmd_len) -{ - amp_hci_cmd_t *cmd = (amp_hci_cmd_t *)cmd_buf; - uint8 buf[BTA_HCI_CMD_MAX_LEN + 16]; - uint len = sizeof(buf); - wl_ioctl_t ioc; - - if (cmd_len < HCI_CMD_PREAMBLE_SIZE) - return BCME_BADLEN; - - if ((uint)cmd->plen + HCI_CMD_PREAMBLE_SIZE > cmd_len) - return BCME_BADLEN; - - len = bcm_mkiovar("HCI_cmd", - (char *)cmd, (uint)cmd->plen + HCI_CMD_PREAMBLE_SIZE, (char *)buf, len); - - - memset(&ioc, 0, sizeof(ioc)); - - ioc.cmd = WLC_SET_VAR; - ioc.buf = buf; - ioc.len = len; - ioc.set = TRUE; - - return dhd_wl_ioctl(pub, &ioc, ioc.buf, ioc.len); -} -#else /* !SEND_HCI_CMD_VIA_IOCTL */ - -static void -dhd_bta_flush_hcidata(dhd_pub_t *pub, uint16 llh) -{ - int prec; - struct pktq *q; - uint count = 0; - - q = dhd_bus_txq(pub->bus); - if (q == NULL) - return; - - DHD_BTA(("dhd: flushing HCI ACL data for logical link %u...\n", llh)); - - dhd_os_sdlock_txq(pub); - - /* Walk through the txq and toss all HCI ACL data packets */ - PKTQ_PREC_ITER(q, prec) { - void *head_pkt = NULL; - - while (pktq_ppeek(q, prec) != head_pkt) { - void *pkt = pktq_pdeq(q, prec); - int ifidx; - - PKTPULL(pub->osh, pkt, dhd_bus_hdrlen(pub->bus)); - dhd_prot_hdrpull(pub, &ifidx, pkt); - - if (PKTLEN(pub->osh, pkt) >= RFC1042_HDR_LEN) { - struct ether_header *eh = - (struct ether_header *)PKTDATA(pub->osh, pkt); - - if (ntoh16(eh->ether_type) < ETHER_TYPE_MIN) { - struct dot11_llc_snap_header *lsh = - (struct dot11_llc_snap_header *)&eh[1]; - - if (bcmp(lsh, BT_SIG_SNAP_MPROT, - DOT11_LLC_SNAP_HDR_LEN - 2) == 0 && - ntoh16(lsh->type) == BTA_PROT_L2CAP) { - amp_hci_ACL_data_t *ACL_data = - (amp_hci_ACL_data_t *)&lsh[1]; - uint16 handle = ltoh16(ACL_data->handle); - - if (HCI_ACL_DATA_HANDLE(handle) == llh) { - PKTFREE(pub->osh, pkt, TRUE); - count ++; - continue; - } - } - } - } - - dhd_prot_hdrpush(pub, ifidx, pkt); - PKTPUSH(pub->osh, pkt, dhd_bus_hdrlen(pub->bus)); - - if (head_pkt == NULL) - head_pkt = pkt; - pktq_penq(q, prec, pkt); - } - } - - dhd_os_sdunlock_txq(pub); - - DHD_BTA(("dhd: flushed %u packet(s) for logical link %u...\n", count, llh)); -} - -/* Handle HCI cmd locally. - * Return 0: continue to send the cmd across SDIO - * < 0: stop, fail - * > 0: stop, succuess - */ -static int -_dhd_bta_docmd(dhd_pub_t *pub, amp_hci_cmd_t *cmd) -{ - int status = 0; - - switch (ltoh16_ua((uint8 *)&cmd->opcode)) { - case HCI_Enhanced_Flush: { - eflush_cmd_parms_t *cmdparms = (eflush_cmd_parms_t *)cmd->parms; - dhd_bta_flush_hcidata(pub, ltoh16_ua(cmdparms->llh)); - break; - } - default: - break; - } - - return status; -} - -/* Send HCI cmd encapsulated in BT-SIG frame via data channel to the dongle. */ -int -dhd_bta_docmd(dhd_pub_t *pub, void *cmd_buf, uint cmd_len) -{ - amp_hci_cmd_t *cmd = (amp_hci_cmd_t *)cmd_buf; - struct ether_header *eh; - struct dot11_llc_snap_header *lsh; - osl_t *osh = pub->osh; - uint len; - void *p; - int status; - - if (cmd_len < HCI_CMD_PREAMBLE_SIZE) { - DHD_ERROR(("dhd_bta_docmd: short command, cmd_len %u\n", cmd_len)); - return BCME_BADLEN; - } - - if ((len = (uint)cmd->plen + HCI_CMD_PREAMBLE_SIZE) > cmd_len) { - DHD_ERROR(("dhd_bta_docmd: malformed command, len %u cmd_len %u\n", - len, cmd_len)); - /* return BCME_BADLEN; */ - } - - p = PKTGET(osh, pub->hdrlen + RFC1042_HDR_LEN + len, TRUE); - if (p == NULL) { - DHD_ERROR(("dhd_bta_docmd: out of memory\n")); - return BCME_NOMEM; - } - - - /* intercept and handle the HCI cmd locally */ - if ((status = _dhd_bta_docmd(pub, cmd)) > 0) - return 0; - else if (status < 0) - return status; - - /* copy in HCI cmd */ - PKTPULL(osh, p, pub->hdrlen + RFC1042_HDR_LEN); - bcopy(cmd, PKTDATA(osh, p), len); - - /* copy in partial Ethernet header with BT-SIG LLC/SNAP header */ - PKTPUSH(osh, p, RFC1042_HDR_LEN); - eh = (struct ether_header *)PKTDATA(osh, p); - bzero(eh->ether_dhost, ETHER_ADDR_LEN); - ETHER_SET_LOCALADDR(eh->ether_dhost); - bcopy(&pub->mac, eh->ether_shost, ETHER_ADDR_LEN); - eh->ether_type = hton16(len + DOT11_LLC_SNAP_HDR_LEN); - lsh = (struct dot11_llc_snap_header *)&eh[1]; - bcopy(BT_SIG_SNAP_MPROT, lsh, DOT11_LLC_SNAP_HDR_LEN - 2); - lsh->type = 0; - - return dhd_sendpkt(pub, 0, p); -} -#endif /* !SEND_HCI_CMD_VIA_IOCTL */ - -/* Send HCI ACL data to dongle via data channel */ -int -dhd_bta_tx_hcidata(dhd_pub_t *pub, void *data_buf, uint data_len) -{ - amp_hci_ACL_data_t *data = (amp_hci_ACL_data_t *)data_buf; - struct ether_header *eh; - struct dot11_llc_snap_header *lsh; - osl_t *osh = pub->osh; - uint len; - void *p; - - if (data_len < HCI_ACL_DATA_PREAMBLE_SIZE) { - DHD_ERROR(("dhd_bta_tx_hcidata: short data_buf, data_len %u\n", data_len)); - return BCME_BADLEN; - } - - if ((len = (uint)ltoh16(data->dlen) + HCI_ACL_DATA_PREAMBLE_SIZE) > data_len) { - DHD_ERROR(("dhd_bta_tx_hcidata: malformed hci data, len %u data_len %u\n", - len, data_len)); - /* return BCME_BADLEN; */ - } - - p = PKTGET(osh, pub->hdrlen + RFC1042_HDR_LEN + len, TRUE); - if (p == NULL) { - DHD_ERROR(("dhd_bta_tx_hcidata: out of memory\n")); - return BCME_NOMEM; - } - - - /* copy in HCI ACL data header and HCI ACL data */ - PKTPULL(osh, p, pub->hdrlen + RFC1042_HDR_LEN); - bcopy(data, PKTDATA(osh, p), len); - - /* copy in partial Ethernet header with BT-SIG LLC/SNAP header */ - PKTPUSH(osh, p, RFC1042_HDR_LEN); - eh = (struct ether_header *)PKTDATA(osh, p); - bzero(eh->ether_dhost, ETHER_ADDR_LEN); - bcopy(&pub->mac, eh->ether_shost, ETHER_ADDR_LEN); - eh->ether_type = hton16(len + DOT11_LLC_SNAP_HDR_LEN); - lsh = (struct dot11_llc_snap_header *)&eh[1]; - bcopy(BT_SIG_SNAP_MPROT, lsh, DOT11_LLC_SNAP_HDR_LEN - 2); - lsh->type = HTON16(BTA_PROT_L2CAP); - - return dhd_sendpkt(pub, 0, p); -} - -/* txcomplete callback */ -void -dhd_bta_tx_hcidata_complete(dhd_pub_t *dhdp, void *txp, bool success) -{ - uint8 *pktdata = (uint8 *)PKTDATA(dhdp->osh, txp); - amp_hci_ACL_data_t *ACL_data = (amp_hci_ACL_data_t *)(pktdata + RFC1042_HDR_LEN); - uint16 handle = ltoh16(ACL_data->handle); - uint16 llh = HCI_ACL_DATA_HANDLE(handle); - - wl_event_msg_t event; - uint8 data[HCI_EVT_PREAMBLE_SIZE + sizeof(num_completed_data_blocks_evt_parms_t)]; - amp_hci_event_t *evt; - num_completed_data_blocks_evt_parms_t *parms; - - uint16 len = HCI_EVT_PREAMBLE_SIZE + sizeof(num_completed_data_blocks_evt_parms_t); - - /* update the event struct */ - memset(&event, 0, sizeof(event)); - event.version = hton16(BCM_EVENT_MSG_VERSION); - event.event_type = hton32(WLC_E_BTA_HCI_EVENT); - event.status = 0; - event.reason = 0; - event.auth_type = 0; - event.datalen = hton32(len); - event.flags = 0; - - /* generate Number of Completed Blocks event */ - evt = (amp_hci_event_t *)data; - evt->ecode = HCI_Number_of_Completed_Data_Blocks; - evt->plen = sizeof(num_completed_data_blocks_evt_parms_t); - - parms = (num_completed_data_blocks_evt_parms_t *)evt->parms; - htol16_ua_store(dhdp->maxdatablks, (uint8 *)&parms->num_blocks); - parms->num_handles = 1; - htol16_ua_store(llh, (uint8 *)&parms->completed[0].handle); - parms->completed[0].pkts = 1; - parms->completed[0].blocks = 1; - - dhd_sendup_event_common(dhdp, &event, data); -} - -/* event callback */ -void -dhd_bta_doevt(dhd_pub_t *dhdp, void *data_buf, uint data_len) -{ - amp_hci_event_t *evt = (amp_hci_event_t *)data_buf; - - switch (evt->ecode) { - case HCI_Command_Complete: { - cmd_complete_parms_t *parms = (cmd_complete_parms_t *)evt->parms; - switch (ltoh16_ua((uint8 *)&parms->opcode)) { - case HCI_Read_Data_Block_Size: { - read_data_block_size_evt_parms_t *parms2 = - (read_data_block_size_evt_parms_t *)parms->parms; - dhdp->maxdatablks = ltoh16_ua((uint8 *)&parms2->data_block_num); - break; - } - } - break; - } - - case HCI_Flush_Occurred: { - flush_occurred_evt_parms_t *evt_parms = (flush_occurred_evt_parms_t *)evt->parms; - dhd_bta_flush_hcidata(dhdp, ltoh16_ua((uint8 *)&evt_parms->handle)); - break; - } - default: - break; - } -} diff --git a/drivers/net/wireless/bcmdhd/dhd_bta.h b/drivers/net/wireless/bcmdhd/dhd_bta.h deleted file mode 100644 index 07d9cebb883a..000000000000 --- a/drivers/net/wireless/bcmdhd/dhd_bta.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * BT-AMP support routines - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd_bta.h,v 1.2 2009-02-26 22:35:56 Exp $ - */ -#ifndef __dhd_bta_h__ -#define __dhd_bta_h__ - -struct dhd_pub; - -extern int dhd_bta_docmd(struct dhd_pub *pub, void *cmd_buf, uint cmd_len); - -extern void dhd_bta_doevt(struct dhd_pub *pub, void *data_buf, uint data_len); - -extern int dhd_bta_tx_hcidata(struct dhd_pub *pub, void *data_buf, uint data_len); -extern void dhd_bta_tx_hcidata_complete(struct dhd_pub *dhdp, void *txp, bool success); - - -#endif /* __dhd_bta_h__ */ diff --git a/drivers/net/wireless/bcmdhd/dhd_bus.h b/drivers/net/wireless/bcmdhd/dhd_bus.h deleted file mode 100644 index bccb8b6603f8..000000000000 --- a/drivers/net/wireless/bcmdhd/dhd_bus.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Header file describing the internal (inter-module) DHD interfaces. - * - * Provides type definitions and function prototypes used to link the - * DHD OS, bus, and protocol modules. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd_bus.h,v 1.14.28.1 2010-12-23 01:13:17 Exp $ - */ - -#ifndef _dhd_bus_h_ -#define _dhd_bus_h_ - -/* - * Exported from dhd bus module (dhd_usb, dhd_sdio) - */ - -/* Indicate (dis)interest in finding dongles. */ -extern int dhd_bus_register(void); -extern void dhd_bus_unregister(void); - -/* Download firmware image and nvram image */ -extern bool dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh, - char *fw_path, char *nv_path); - -/* Stop bus module: clear pending frames, disable data flow */ -extern void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex); - -/* Initialize bus module: prepare for communication w/dongle */ -extern int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex); - -/* Get the Bus Idle Time */ -extern void dhd_bus_getidletime(dhd_pub_t *dhdp, int *idletime); - -/* Set the Bus Idle Time*/ -extern void dhd_bus_setidletime(dhd_pub_t *dhdp, int idle_time); -/* Send a data frame to the dongle. Callee disposes of txp. */ -extern int dhd_bus_txdata(struct dhd_bus *bus, void *txp); - -/* Send/receive a control message to/from the dongle. - * Expects caller to enforce a single outstanding transaction. - */ -extern int dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen); -extern int dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen); - -/* Watchdog timer function */ -extern bool dhd_bus_watchdog(dhd_pub_t *dhd); -extern void dhd_disable_intr(dhd_pub_t *dhd); - -#if defined(DHD_DEBUG) -/* Device console input function */ -extern int dhd_bus_console_in(dhd_pub_t *dhd, uchar *msg, uint msglen); -#endif /* defined(DHD_DEBUG) */ - -/* Deferred processing for the bus, return TRUE requests reschedule */ -extern bool dhd_bus_dpc(struct dhd_bus *bus); -extern void dhd_bus_isr(bool * InterruptRecognized, bool * QueueMiniportHandleInterrupt, void *arg); - - -/* Check for and handle local prot-specific iovar commands */ -extern int dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name, - void *params, int plen, void *arg, int len, bool set); - -/* Add bus dump output to a buffer */ -extern void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf); - -/* Clear any bus counters */ -extern void dhd_bus_clearcounts(dhd_pub_t *dhdp); - -/* return the dongle chipid */ -extern uint dhd_bus_chip(struct dhd_bus *bus); - -/* Set user-specified nvram parameters. */ -extern void dhd_bus_set_nvram_params(struct dhd_bus * bus, const char *nvram_params); - -extern void *dhd_bus_pub(struct dhd_bus *bus); -extern void *dhd_bus_txq(struct dhd_bus *bus); -extern uint dhd_bus_hdrlen(struct dhd_bus *bus); - -#endif /* _dhd_bus_h_ */ diff --git a/drivers/net/wireless/bcmdhd/dhd_cdc.c b/drivers/net/wireless/bcmdhd/dhd_cdc.c deleted file mode 100644 index f16d81c9e198..000000000000 --- a/drivers/net/wireless/bcmdhd/dhd_cdc.c +++ /dev/null @@ -1,2534 +0,0 @@ -/* - * DHD Protocol Module for CDC and BDC. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd_cdc.c 324280 2012-03-28 19:01:17Z $ - * - * BDC is like CDC, except it includes a header for data packets to convey - * packet priority over the bus, and flags (e.g. to indicate checksum status - * for dongle offload.) - */ - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - - -#ifdef PROP_TXSTATUS -#include -#include -#endif - - -#define RETRIES 2 /* # of retries to retrieve matching ioctl response */ -#define BUS_HEADER_LEN (16+DHD_SDALIGN) /* Must be at least SDPCM_RESERVE - * defined in dhd_sdio.c (amount of header tha might be added) - * plus any space that might be needed for alignment padding. - */ -#define ROUND_UP_MARGIN 2048 /* Biggest SDIO block size possible for - * round off at the end of buffer - */ - -#define BUS_RETRIES 1 /* # of retries before aborting a bus tx operation */ - -#ifdef PROP_TXSTATUS -typedef struct dhd_wlfc_commit_info { - uint8 needs_hdr; - uint8 ac_fifo_credit_spent; - ewlfc_packet_state_t pkt_type; - wlfc_mac_descriptor_t* mac_entry; - void* p; -} dhd_wlfc_commit_info_t; -#endif /* PROP_TXSTATUS */ - -typedef struct dhd_prot { - uint16 reqid; - uint8 pending; - uint32 lastcmd; - uint8 bus_header[BUS_HEADER_LEN]; - cdc_ioctl_t msg; - unsigned char buf[WLC_IOCTL_MAXLEN + ROUND_UP_MARGIN]; -} dhd_prot_t; - -extern int dhd_dbus_txdata(dhd_pub_t *dhdp, void *pktbuf); - -static int -dhdcdc_msg(dhd_pub_t *dhd) -{ - int err = 0; - dhd_prot_t *prot = dhd->prot; - int len = ltoh32(prot->msg.len) + sizeof(cdc_ioctl_t); - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - DHD_OS_WAKE_LOCK(dhd); - - /* NOTE : cdc->msg.len holds the desired length of the buffer to be - * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area - * is actually sent to the dongle - */ - if (len > CDC_MAX_MSG_SIZE) - len = CDC_MAX_MSG_SIZE; - - /* Send request */ - err = dhd_bus_txctl(dhd->bus, (uchar*)&prot->msg, len); - - DHD_OS_WAKE_UNLOCK(dhd); - return err; -} - -static int -dhdcdc_cmplt(dhd_pub_t *dhd, uint32 id, uint32 len) -{ - int ret; - int cdc_len = len+sizeof(cdc_ioctl_t); - dhd_prot_t *prot = dhd->prot; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - do { - ret = dhd_bus_rxctl(dhd->bus, (uchar*)&prot->msg, cdc_len); - if (ret < 0) - break; - } while (CDC_IOC_ID(ltoh32(prot->msg.flags)) != id); - - return ret; -} - -static int -dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action) -{ - dhd_prot_t *prot = dhd->prot; - cdc_ioctl_t *msg = &prot->msg; - void *info; - int ret = 0, retries = 0; - uint32 id, flags = 0; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - DHD_CTL(("%s: cmd %d len %d\n", __FUNCTION__, cmd, len)); - - - /* Respond "bcmerror" and "bcmerrorstr" with local cache */ - if (cmd == WLC_GET_VAR && buf) - { - if (!strcmp((char *)buf, "bcmerrorstr")) - { - strncpy((char *)buf, bcmerrorstr(dhd->dongle_error), BCME_STRLEN); - goto done; - } - else if (!strcmp((char *)buf, "bcmerror")) - { - *(int *)buf = dhd->dongle_error; - goto done; - } - } - - memset(msg, 0, sizeof(cdc_ioctl_t)); - - msg->cmd = htol32(cmd); - msg->len = htol32(len); - msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT); - CDC_SET_IF_IDX(msg, ifidx); - /* add additional action bits */ - action &= WL_IOCTL_ACTION_MASK; - msg->flags |= (action << CDCF_IOC_ACTION_SHIFT); - msg->flags = htol32(msg->flags); - - if (buf) - memcpy(prot->buf, buf, len); - - if ((ret = dhdcdc_msg(dhd)) < 0) { - if (!dhd->hang_was_sent) - DHD_ERROR(("dhdcdc_query_ioctl: dhdcdc_msg failed w/status %d\n", ret)); - goto done; - } - -retry: - /* wait for interrupt and get first fragment */ - if ((ret = dhdcdc_cmplt(dhd, prot->reqid, len)) < 0) - goto done; - - flags = ltoh32(msg->flags); - id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT; - - if ((id < prot->reqid) && (++retries < RETRIES)) - goto retry; - if (id != prot->reqid) { - DHD_ERROR(("%s: %s: unexpected request id %d (expected %d)\n", - dhd_ifname(dhd, ifidx), __FUNCTION__, id, prot->reqid)); - ret = -EINVAL; - goto done; - } - - /* Check info buffer */ - info = (void*)&msg[1]; - - /* Copy info buffer */ - if (buf) - { - if (ret < (int)len) - len = ret; - memcpy(buf, info, len); - } - - /* Check the ERROR flag */ - if (flags & CDCF_IOC_ERROR) - { - ret = ltoh32(msg->status); - /* Cache error from dongle */ - dhd->dongle_error = ret; - } - -done: - return ret; -} - -static int -dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action) -{ - dhd_prot_t *prot = dhd->prot; - cdc_ioctl_t *msg = &prot->msg; - int ret = 0; - uint32 flags, id; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - DHD_CTL(("%s: cmd %d len %d\n", __FUNCTION__, cmd, len)); - - if (dhd->busstate == DHD_BUS_DOWN) { - DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__)); - return -EIO; - } - - /* don't talk to the dongle if fw is about to be reloaded */ - if (dhd->hang_was_sent) { - DHD_ERROR(("%s: HANG was sent up earlier. Not talking to the chip\n", - __FUNCTION__)); - return -EIO; - } - - memset(msg, 0, sizeof(cdc_ioctl_t)); - - msg->cmd = htol32(cmd); - msg->len = htol32(len); - msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT); - CDC_SET_IF_IDX(msg, ifidx); - /* add additional action bits */ - action &= WL_IOCTL_ACTION_MASK; - msg->flags |= (action << CDCF_IOC_ACTION_SHIFT) | CDCF_IOC_SET; - msg->flags = htol32(msg->flags); - - if (buf) - memcpy(prot->buf, buf, len); - - if ((ret = dhdcdc_msg(dhd)) < 0) { - DHD_ERROR(("%s: dhdcdc_msg failed w/status %d\n", __FUNCTION__, ret)); - goto done; - } - - if ((ret = dhdcdc_cmplt(dhd, prot->reqid, len)) < 0) - goto done; - - flags = ltoh32(msg->flags); - id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT; - - if (id != prot->reqid) { - DHD_ERROR(("%s: %s: unexpected request id %d (expected %d)\n", - dhd_ifname(dhd, ifidx), __FUNCTION__, id, prot->reqid)); - ret = -EINVAL; - goto done; - } - - /* Check the ERROR flag */ - if (flags & CDCF_IOC_ERROR) - { - ret = ltoh32(msg->status); - /* Cache error from dongle */ - dhd->dongle_error = ret; - } - -done: - return ret; -} - - -int -dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len) -{ - dhd_prot_t *prot = dhd->prot; - int ret = -1; - uint8 action; - - if ((dhd->busstate == DHD_BUS_DOWN) || dhd->hang_was_sent) { - DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__)); - goto done; - } - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - ASSERT(len <= WLC_IOCTL_MAXLEN); - - if (len > WLC_IOCTL_MAXLEN) - goto done; - - if (prot->pending == TRUE) { - DHD_ERROR(("CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n", - ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd, - (unsigned long)prot->lastcmd)); - if ((ioc->cmd == WLC_SET_VAR) || (ioc->cmd == WLC_GET_VAR)) { - DHD_TRACE(("iovar cmd=%s\n", (char*)buf)); - } - goto done; - } - - prot->pending = TRUE; - prot->lastcmd = ioc->cmd; - action = ioc->set; - if (action & WL_IOCTL_ACTION_SET) - ret = dhdcdc_set_ioctl(dhd, ifidx, ioc->cmd, buf, len, action); - else { - ret = dhdcdc_query_ioctl(dhd, ifidx, ioc->cmd, buf, len, action); - if (ret > 0) - ioc->used = ret - sizeof(cdc_ioctl_t); - } - - /* Too many programs assume ioctl() returns 0 on success */ - if (ret >= 0) - ret = 0; - else { - cdc_ioctl_t *msg = &prot->msg; - ioc->needed = ltoh32(msg->len); /* len == needed when set/query fails from dongle */ - } - - /* Intercept the wme_dp ioctl here */ - if ((!ret) && (ioc->cmd == WLC_SET_VAR) && (!strcmp(buf, "wme_dp"))) { - int slen, val = 0; - - slen = strlen("wme_dp") + 1; - if (len >= (int)(slen + sizeof(int))) - bcopy(((char *)buf + slen), &val, sizeof(int)); - dhd->wme_dp = (uint8) ltoh32(val); - } - - prot->pending = FALSE; - -done: - return ret; -} - -int -dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - return BCME_UNSUPPORTED; -} - -#ifdef PROP_TXSTATUS -void -dhd_wlfc_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) -{ - int i; - uint8* ea; - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhdp->wlfc_state; - wlfc_hanger_t* h; - wlfc_mac_descriptor_t* mac_table; - wlfc_mac_descriptor_t* interfaces; - char* iftypes[] = {"STA", "AP", "WDS", "p2pGO", "p2pCL"}; - - if (wlfc == NULL) { - bcm_bprintf(strbuf, "wlfc not initialized yet\n"); - return; - } - h = (wlfc_hanger_t*)wlfc->hanger; - if (h == NULL) { - bcm_bprintf(strbuf, "wlfc-hanger not initialized yet\n"); - } - - mac_table = wlfc->destination_entries.nodes; - interfaces = wlfc->destination_entries.interfaces; - bcm_bprintf(strbuf, "---- wlfc stats ----\n"); - if (h) { - bcm_bprintf(strbuf, "wlfc hanger (pushed,popped,f_push," - "f_pop,f_slot, pending) = (%d,%d,%d,%d,%d,%d)\n", - h->pushed, - h->popped, - h->failed_to_push, - h->failed_to_pop, - h->failed_slotfind, - (h->pushed - h->popped)); - } - - bcm_bprintf(strbuf, "wlfc fail(tlv,credit_rqst,mac_update,psmode_update), " - "(dq_full,sendq_full, rollback_fail) = (%d,%d,%d,%d), (%d,%d,%d)\n", - wlfc->stats.tlv_parse_failed, - wlfc->stats.credit_request_failed, - wlfc->stats.mac_update_failed, - wlfc->stats.psmode_update_failed, - wlfc->stats.delayq_full_error, - wlfc->stats.sendq_full_error, - wlfc->stats.rollback_failed); - - bcm_bprintf(strbuf, "SENDQ (len,credit,sent) " - "(AC0[%d,%d,%d],AC1[%d,%d,%d],AC2[%d,%d,%d],AC3[%d,%d,%d],BC_MC[%d,%d,%d])\n", - wlfc->SENDQ.q[0].len, wlfc->FIFO_credit[0], wlfc->stats.sendq_pkts[0], - wlfc->SENDQ.q[1].len, wlfc->FIFO_credit[1], wlfc->stats.sendq_pkts[1], - wlfc->SENDQ.q[2].len, wlfc->FIFO_credit[2], wlfc->stats.sendq_pkts[2], - wlfc->SENDQ.q[3].len, wlfc->FIFO_credit[3], wlfc->stats.sendq_pkts[3], - wlfc->SENDQ.q[4].len, wlfc->FIFO_credit[4], wlfc->stats.sendq_pkts[4]); - -#ifdef PROP_TXSTATUS_DEBUG - bcm_bprintf(strbuf, "SENDQ dropped: AC[0-3]:(%d,%d,%d,%d), (bcmc,atim):(%d,%d)\n", - wlfc->stats.dropped_qfull[0], wlfc->stats.dropped_qfull[1], - wlfc->stats.dropped_qfull[2], wlfc->stats.dropped_qfull[3], - wlfc->stats.dropped_qfull[4], wlfc->stats.dropped_qfull[5]); -#endif - - bcm_bprintf(strbuf, "\n"); - for (i = 0; i < WLFC_MAX_IFNUM; i++) { - if (interfaces[i].occupied) { - char* iftype_desc; - - if (interfaces[i].iftype > WLC_E_IF_ROLE_P2P_CLIENT) - iftype_desc = "stats.latency_sample_count) { - moving_samples = sizeof(wlfc->stats.deltas)/sizeof(uint32); - - for (i = 0; i < moving_samples; i++) - moving_avg += wlfc->stats.deltas[i]; - moving_avg /= moving_samples; - - avg = (100 * wlfc->stats.total_status_latency) / - wlfc->stats.latency_sample_count; - bcm_bprintf(strbuf, "txstatus latency (average, last, moving[%d]) = " - "(%d.%d, %03d, %03d)\n", - moving_samples, avg/100, (avg - (avg/100)*100), - wlfc->stats.latency_most_recent, - moving_avg); - } - } - - bcm_bprintf(strbuf, "wlfc- fifo[0-5] credit stats: sent = (%d,%d,%d,%d,%d,%d), " - "back = (%d,%d,%d,%d,%d,%d)\n", - wlfc->stats.fifo_credits_sent[0], - wlfc->stats.fifo_credits_sent[1], - wlfc->stats.fifo_credits_sent[2], - wlfc->stats.fifo_credits_sent[3], - wlfc->stats.fifo_credits_sent[4], - wlfc->stats.fifo_credits_sent[5], - - wlfc->stats.fifo_credits_back[0], - wlfc->stats.fifo_credits_back[1], - wlfc->stats.fifo_credits_back[2], - wlfc->stats.fifo_credits_back[3], - wlfc->stats.fifo_credits_back[4], - wlfc->stats.fifo_credits_back[5]); - { - uint32 fifo_cr_sent = 0; - uint32 fifo_cr_acked = 0; - uint32 request_cr_sent = 0; - uint32 request_cr_ack = 0; - uint32 bc_mc_cr_ack = 0; - - for (i = 0; i < sizeof(wlfc->stats.fifo_credits_sent)/sizeof(uint32); i++) { - fifo_cr_sent += wlfc->stats.fifo_credits_sent[i]; - } - - for (i = 0; i < sizeof(wlfc->stats.fifo_credits_back)/sizeof(uint32); i++) { - fifo_cr_acked += wlfc->stats.fifo_credits_back[i]; - } - - for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { - if (wlfc->destination_entries.nodes[i].occupied) { - request_cr_sent += - wlfc->destination_entries.nodes[i].dstncredit_sent_packets; - } - } - for (i = 0; i < WLFC_MAX_IFNUM; i++) { - if (wlfc->destination_entries.interfaces[i].occupied) { - request_cr_sent += - wlfc->destination_entries.interfaces[i].dstncredit_sent_packets; - } - } - for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { - if (wlfc->destination_entries.nodes[i].occupied) { - request_cr_ack += - wlfc->destination_entries.nodes[i].dstncredit_acks; - } - } - for (i = 0; i < WLFC_MAX_IFNUM; i++) { - if (wlfc->destination_entries.interfaces[i].occupied) { - request_cr_ack += - wlfc->destination_entries.interfaces[i].dstncredit_acks; - } - } - bcm_bprintf(strbuf, "wlfc- (sent, status) => pq(%d,%d), vq(%d,%d)," - "other:%d, bc_mc:%d, signal-only, (sent,freed): (%d,%d)", - fifo_cr_sent, fifo_cr_acked, - request_cr_sent, request_cr_ack, - wlfc->destination_entries.other.dstncredit_acks, - bc_mc_cr_ack, - wlfc->stats.signal_only_pkts_sent, wlfc->stats.signal_only_pkts_freed); - } -#endif /* PROP_TXSTATUS_DEBUG */ - bcm_bprintf(strbuf, "\n"); - bcm_bprintf(strbuf, "wlfc- pkt((in,2bus,txstats,hdrpull),(dropped,hdr_only,wlc_tossed)" - "(freed,free_err,rollback)) = " - "((%d,%d,%d,%d),(%d,%d,%d),(%d,%d,%d))\n", - wlfc->stats.pktin, - wlfc->stats.pkt2bus, - wlfc->stats.txstatus_in, - wlfc->stats.dhd_hdrpulls, - - wlfc->stats.pktdropped, - wlfc->stats.wlfc_header_only_pkt, - wlfc->stats.wlc_tossed_pkts, - - wlfc->stats.pkt_freed, - wlfc->stats.pkt_free_err, wlfc->stats.rollback); - - bcm_bprintf(strbuf, "wlfc- suppress((d11,wlc,err),enq(d11,wl,hq,mac?),retx(d11,wlc,hq)) = " - "((%d,%d,%d),(%d,%d,%d,%d),(%d,%d,%d))\n", - - wlfc->stats.d11_suppress, - wlfc->stats.wl_suppress, - wlfc->stats.bad_suppress, - - wlfc->stats.psq_d11sup_enq, - wlfc->stats.psq_wlsup_enq, - wlfc->stats.psq_hostq_enq, - wlfc->stats.mac_handle_notfound, - - wlfc->stats.psq_d11sup_retx, - wlfc->stats.psq_wlsup_retx, - wlfc->stats.psq_hostq_retx); - return; -} - -/* Create a place to store all packet pointers submitted to the firmware until - a status comes back, suppress or otherwise. - - hang-er: noun, a contrivance on which things are hung, as a hook. -*/ -static void* -dhd_wlfc_hanger_create(osl_t *osh, int max_items) -{ - int i; - wlfc_hanger_t* hanger; - - /* allow only up to a specific size for now */ - ASSERT(max_items == WLFC_HANGER_MAXITEMS); - - if ((hanger = (wlfc_hanger_t*)MALLOC(osh, WLFC_HANGER_SIZE(max_items))) == NULL) - return NULL; - - memset(hanger, 0, WLFC_HANGER_SIZE(max_items)); - hanger->max_items = max_items; - - for (i = 0; i < hanger->max_items; i++) { - hanger->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; - } - return hanger; -} - -static int -dhd_wlfc_hanger_delete(osl_t *osh, void* hanger) -{ - wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; - - if (h) { - MFREE(osh, h, WLFC_HANGER_SIZE(h->max_items)); - return BCME_OK; - } - return BCME_BADARG; -} - -static uint16 -dhd_wlfc_hanger_get_free_slot(void* hanger) -{ - int i; - wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; - - if (h) { - for (i = 0; i < h->max_items; i++) { - if (h->items[i].state == WLFC_HANGER_ITEM_STATE_FREE) - return (uint16)i; - } - h->failed_slotfind++; - } - return WLFC_HANGER_MAXITEMS; -} - -static int -dhd_wlfc_hanger_pushpkt(void* hanger, void* pkt, uint32 slot_id) -{ - int rc = BCME_OK; - wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; - - if (h && (slot_id < WLFC_HANGER_MAXITEMS)) { - if (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_FREE) { - h->items[slot_id].state = WLFC_HANGER_ITEM_STATE_INUSE; - h->items[slot_id].pkt = pkt; - h->items[slot_id].identifier = slot_id; - h->pushed++; - } - else { - h->failed_to_push++; - rc = BCME_NOTFOUND; - } - } - else - rc = BCME_BADARG; - return rc; -} - -static int -dhd_wlfc_hanger_poppkt(void* hanger, uint32 slot_id, void** pktout, int remove_from_hanger) -{ - int rc = BCME_OK; - wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; - - /* this packet was not pushed at the time it went to the firmware */ - if (slot_id == WLFC_HANGER_MAXITEMS) - return BCME_NOTFOUND; - - if (h) { - if (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE) { - *pktout = h->items[slot_id].pkt; - if (remove_from_hanger) { - h->items[slot_id].state = - WLFC_HANGER_ITEM_STATE_FREE; - h->items[slot_id].pkt = NULL; - h->items[slot_id].identifier = 0; - h->popped++; - } - } - else { - h->failed_to_pop++; - rc = BCME_NOTFOUND; - } - } - else - rc = BCME_BADARG; - return rc; -} - -static int -_dhd_wlfc_pushheader(athost_wl_status_info_t* ctx, void* p, bool tim_signal, - uint8 tim_bmp, uint8 mac_handle, uint32 htodtag) -{ - uint32 wl_pktinfo = 0; - uint8* wlh; - uint8 dataOffset; - uint8 fillers; - uint8 tim_signal_len = 0; - - struct bdc_header *h; - - if (tim_signal) { - tim_signal_len = 1 + 1 + WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP; - } - - /* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */ - dataOffset = WLFC_CTL_VALUE_LEN_PKTTAG + 2 + tim_signal_len; - fillers = ROUNDUP(dataOffset, 4) - dataOffset; - dataOffset += fillers; - - PKTPUSH(ctx->osh, p, dataOffset); - wlh = (uint8*) PKTDATA(ctx->osh, p); - - wl_pktinfo = htol32(htodtag); - - wlh[0] = WLFC_CTL_TYPE_PKTTAG; - wlh[1] = WLFC_CTL_VALUE_LEN_PKTTAG; - memcpy(&wlh[2], &wl_pktinfo, sizeof(uint32)); - - if (tim_signal_len) { - wlh[dataOffset - fillers - tim_signal_len ] = - WLFC_CTL_TYPE_PENDING_TRAFFIC_BMP; - wlh[dataOffset - fillers - tim_signal_len + 1] = - WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP; - wlh[dataOffset - fillers - tim_signal_len + 2] = mac_handle; - wlh[dataOffset - fillers - tim_signal_len + 3] = tim_bmp; - } - if (fillers) - memset(&wlh[dataOffset - fillers], WLFC_CTL_TYPE_FILLER, fillers); - - PKTPUSH(ctx->osh, p, BDC_HEADER_LEN); - h = (struct bdc_header *)PKTDATA(ctx->osh, p); - h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); - if (PKTSUMNEEDED(p)) - h->flags |= BDC_FLAG_SUM_NEEDED; - - - h->priority = (PKTPRIO(p) & BDC_PRIORITY_MASK); - h->flags2 = 0; - h->dataOffset = dataOffset >> 2; - BDC_SET_IF_IDX(h, DHD_PKTTAG_IF(PKTTAG(p))); - return BCME_OK; -} - -static int -_dhd_wlfc_pullheader(athost_wl_status_info_t* ctx, void* pktbuf) -{ - struct bdc_header *h; - - if (PKTLEN(ctx->osh, pktbuf) < BDC_HEADER_LEN) { - WLFC_DBGMESG(("%s: rx data too short (%d < %d)\n", __FUNCTION__, - PKTLEN(ctx->osh, pktbuf), BDC_HEADER_LEN)); - return BCME_ERROR; - } - h = (struct bdc_header *)PKTDATA(ctx->osh, pktbuf); - - /* pull BDC header */ - PKTPULL(ctx->osh, pktbuf, BDC_HEADER_LEN); - /* pull wl-header */ - PKTPULL(ctx->osh, pktbuf, (h->dataOffset << 2)); - return BCME_OK; -} - -static wlfc_mac_descriptor_t* -_dhd_wlfc_find_table_entry(athost_wl_status_info_t* ctx, void* p) -{ - int i; - wlfc_mac_descriptor_t* table = ctx->destination_entries.nodes; - uint8 ifid = DHD_PKTTAG_IF(PKTTAG(p)); - uint8* dstn = DHD_PKTTAG_DSTN(PKTTAG(p)); - - /* no lookup necessary, only if this packet belongs to STA interface */ - if (((ctx->destination_entries.interfaces[ifid].iftype == WLC_E_IF_ROLE_STA) || - ETHER_ISMULTI(dstn) || - (ctx->destination_entries.interfaces[ifid].iftype == WLC_E_IF_ROLE_P2P_CLIENT)) && - (ctx->destination_entries.interfaces[ifid].occupied)) { - return &ctx->destination_entries.interfaces[ifid]; - } - - for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { - if (table[i].occupied) { - if (table[i].interface_id == ifid) { - if (!memcmp(table[i].ea, dstn, ETHER_ADDR_LEN)) - return &table[i]; - } - } - } - return &ctx->destination_entries.other; -} - -static int -_dhd_wlfc_rollback_packet_toq(athost_wl_status_info_t* ctx, - void* p, ewlfc_packet_state_t pkt_type, uint32 hslot) -{ - /* - put the packet back to the head of queue - - - a packet from send-q will need to go back to send-q and not delay-q - since that will change the order of packets. - - suppressed packet goes back to suppress sub-queue - - pull out the header, if new or delayed packet - - Note: hslot is used only when header removal is done. - */ - wlfc_mac_descriptor_t* entry; - void* pktout; - int rc = BCME_OK; - int prec; - - entry = _dhd_wlfc_find_table_entry(ctx, p); - prec = DHD_PKTTAG_FIFO(PKTTAG(p)); - if (entry != NULL) { - if (pkt_type == eWLFC_PKTTYPE_SUPPRESSED) { - /* wl-header is saved for suppressed packets */ - if (WLFC_PKTQ_PENQ_HEAD(&entry->psq, ((prec << 1) + 1), p) == NULL) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - rc = BCME_ERROR; - } - } - else { - /* remove header first */ - _dhd_wlfc_pullheader(ctx, p); - - if (pkt_type == eWLFC_PKTTYPE_DELAYED) { - /* delay-q packets are going to delay-q */ - if (WLFC_PKTQ_PENQ_HEAD(&entry->psq, (prec << 1), p) == NULL) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - rc = BCME_ERROR; - } - } - else { - /* these are going to SENDQ */ - if (WLFC_PKTQ_PENQ_HEAD(&ctx->SENDQ, prec, p) == NULL) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - rc = BCME_ERROR; - } - } - /* free the hanger slot */ - dhd_wlfc_hanger_poppkt(ctx->hanger, hslot, &pktout, 1); - - /* decrement sequence count */ - WLFC_DECR_SEQCOUNT(entry, prec); - } - /* - if this packet did not count against FIFO credit, it must have - taken a requested_credit from the firmware (for pspoll etc.) - */ - if (!DHD_PKTTAG_CREDITCHECK(PKTTAG(p))) { - entry->requested_credit++; - } - } - else { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - rc = BCME_ERROR; - } - if (rc != BCME_OK) - ctx->stats.rollback_failed++; - else - ctx->stats.rollback++; - - return rc; -} - -static void -_dhd_wlfc_flow_control_check(athost_wl_status_info_t* ctx, struct pktq* pq, uint8 if_id) -{ - if ((pq->len <= WLFC_FLOWCONTROL_LOWATER) && (ctx->hostif_flow_state[if_id] == ON)) { - /* start traffic */ - ctx->hostif_flow_state[if_id] = OFF; - /* - WLFC_DBGMESG(("qlen:%02d, if:%02d, ->OFF, start traffic %s()\n", - pq->len, if_id, __FUNCTION__)); - */ - WLFC_DBGMESG(("F")); - /* dhd_txflowcontrol(ctx->dhdp, if_id, OFF); */ - ctx->toggle_host_if = 0; - } - if ((pq->len >= WLFC_FLOWCONTROL_HIWATER) && (ctx->hostif_flow_state[if_id] == OFF)) { - /* stop traffic */ - ctx->hostif_flow_state[if_id] = ON; - /* - WLFC_DBGMESG(("qlen:%02d, if:%02d, ->ON, stop traffic %s()\n", - pq->len, if_id, __FUNCTION__)); - */ - WLFC_DBGMESG(("N")); - /* dhd_txflowcontrol(ctx->dhdp, if_id, ON); */ - ctx->host_ifidx = if_id; - ctx->toggle_host_if = 1; - } - return; -} - -static int -_dhd_wlfc_send_signalonly_packet(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry, - uint8 ta_bmp) -{ - int rc = BCME_OK; - void* p = NULL; - int dummylen = ((dhd_pub_t *)ctx->dhdp)->hdrlen+ 12; - - /* allocate a dummy packet */ - p = PKTGET(ctx->osh, dummylen, TRUE); - if (p) { - PKTPULL(ctx->osh, p, dummylen); - DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), 0); - _dhd_wlfc_pushheader(ctx, p, TRUE, ta_bmp, entry->mac_handle, 0); - DHD_PKTTAG_SETSIGNALONLY(PKTTAG(p), 1); -#ifdef PROP_TXSTATUS_DEBUG - ctx->stats.signal_only_pkts_sent++; -#endif - rc = dhd_bus_txdata(((dhd_pub_t *)ctx->dhdp)->bus, p); - if (rc != BCME_OK) { - PKTFREE(ctx->osh, p, TRUE); - } - } - else { - DHD_ERROR(("%s: couldn't allocate new %d-byte packet\n", - __FUNCTION__, dummylen)); - rc = BCME_NOMEM; - } - return rc; -} - -/* Return TRUE if traffic availability changed */ -static bool -_dhd_wlfc_traffic_pending_check(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry, - int prec) -{ - bool rc = FALSE; - - if (entry->state == WLFC_STATE_CLOSE) { - if ((pktq_plen(&entry->psq, (prec << 1)) == 0) && - (pktq_plen(&entry->psq, ((prec << 1) + 1)) == 0)) { - - if (entry->traffic_pending_bmp & NBITVAL(prec)) { - rc = TRUE; - entry->traffic_pending_bmp = - entry->traffic_pending_bmp & ~ NBITVAL(prec); - } - } - else { - if (!(entry->traffic_pending_bmp & NBITVAL(prec))) { - rc = TRUE; - entry->traffic_pending_bmp = - entry->traffic_pending_bmp | NBITVAL(prec); - } - } - } - if (rc) { - /* request a TIM update to firmware at the next piggyback opportunity */ - if (entry->traffic_lastreported_bmp != entry->traffic_pending_bmp) { - entry->send_tim_signal = 1; - _dhd_wlfc_send_signalonly_packet(ctx, entry, entry->traffic_pending_bmp); - entry->traffic_lastreported_bmp = entry->traffic_pending_bmp; - entry->send_tim_signal = 0; - } - else { - rc = FALSE; - } - } - return rc; -} - -static int -_dhd_wlfc_enque_suppressed(athost_wl_status_info_t* ctx, int prec, void* p) -{ - wlfc_mac_descriptor_t* entry; - - entry = _dhd_wlfc_find_table_entry(ctx, p); - if (entry == NULL) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - return BCME_NOTFOUND; - } - /* - - suppressed packets go to sub_queue[2*prec + 1] AND - - delayed packets go to sub_queue[2*prec + 0] to ensure - order of delivery. - */ - if (WLFC_PKTQ_PENQ(&entry->psq, ((prec << 1) + 1), p) == NULL) { - ctx->stats.delayq_full_error++; - /* WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); */ - WLFC_DBGMESG(("s")); - return BCME_ERROR; - } - /* A packet has been pushed, update traffic availability bitmap, if applicable */ - _dhd_wlfc_traffic_pending_check(ctx, entry, prec); - _dhd_wlfc_flow_control_check(ctx, &entry->psq, DHD_PKTTAG_IF(PKTTAG(p))); - return BCME_OK; -} - -static int -_dhd_wlfc_pretx_pktprocess(athost_wl_status_info_t* ctx, - wlfc_mac_descriptor_t* entry, void* p, int header_needed, uint32* slot) -{ - int rc = BCME_OK; - int hslot = WLFC_HANGER_MAXITEMS; - bool send_tim_update = FALSE; - uint32 htod = 0; - uint8 free_ctr; - - *slot = hslot; - - if (entry == NULL) { - entry = _dhd_wlfc_find_table_entry(ctx, p); - } - - if (entry == NULL) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - return BCME_ERROR; - } - if (entry->send_tim_signal) { - send_tim_update = TRUE; - entry->send_tim_signal = 0; - entry->traffic_lastreported_bmp = entry->traffic_pending_bmp; - } - if (header_needed) { - hslot = dhd_wlfc_hanger_get_free_slot(ctx->hanger); - free_ctr = WLFC_SEQCOUNT(entry, DHD_PKTTAG_FIFO(PKTTAG(p))); - DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), htod); - } - else { - hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); - free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); - } - WLFC_PKTID_HSLOT_SET(htod, hslot); - WLFC_PKTID_FREERUNCTR_SET(htod, free_ctr); - DHD_PKTTAG_SETPKTDIR(PKTTAG(p), 1); - WL_TXSTATUS_SET_FLAGS(htod, WLFC_PKTFLAG_PKTFROMHOST); - WL_TXSTATUS_SET_FIFO(htod, DHD_PKTTAG_FIFO(PKTTAG(p))); - WLFC_PKTFLAG_SET_GENERATION(htod, entry->generation); - - if (!DHD_PKTTAG_CREDITCHECK(PKTTAG(p))) { - /* - Indicate that this packet is being sent in response to an - explicit request from the firmware side. - */ - WLFC_PKTFLAG_SET_PKTREQUESTED(htod); - } - else { - WLFC_PKTFLAG_CLR_PKTREQUESTED(htod); - } - if (header_needed) { - rc = _dhd_wlfc_pushheader(ctx, p, send_tim_update, - entry->traffic_lastreported_bmp, entry->mac_handle, htod); - if (rc == BCME_OK) { - DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), htod); - /* - a new header was created for this packet. - push to hanger slot and scrub q. Since bus - send succeeded, increment seq number as well. - */ - rc = dhd_wlfc_hanger_pushpkt(ctx->hanger, p, hslot); - if (rc == BCME_OK) { - /* increment free running sequence count */ - WLFC_INCR_SEQCOUNT(entry, DHD_PKTTAG_FIFO(PKTTAG(p))); -#ifdef PROP_TXSTATUS_DEBUG - ((wlfc_hanger_t*)(ctx->hanger))->items[hslot].push_time = - OSL_SYSUPTIME(); -#endif - } - else { - WLFC_DBGMESG(("%s() hanger_pushpkt() failed, rc: %d\n", - __FUNCTION__, rc)); - } - } - } - else { - /* remove old header */ - _dhd_wlfc_pullheader(ctx, p); - - hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); - free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); - /* push new header */ - _dhd_wlfc_pushheader(ctx, p, send_tim_update, - entry->traffic_lastreported_bmp, entry->mac_handle, htod); - } - *slot = hslot; - return rc; -} - -static int -_dhd_wlfc_is_destination_closed(athost_wl_status_info_t* ctx, - wlfc_mac_descriptor_t* entry, int prec) -{ - if (ctx->destination_entries.interfaces[entry->interface_id].iftype == - WLC_E_IF_ROLE_P2P_GO) { - /* - destination interface is of type p2p GO. - For a p2pGO interface, if the destination is OPEN but the interface is - CLOSEd, do not send traffic. But if the dstn is CLOSEd while there is - destination-specific-credit left send packets. This is because the - firmware storing the destination-specific-requested packet in queue. - */ - if ((entry->state == WLFC_STATE_CLOSE) && (entry->requested_credit == 0) && - (entry->requested_packet == 0)) - return 1; - } - /* AP, p2p_go -> unicast desc entry, STA/p2p_cl -> interface desc. entry */ - if (((entry->state == WLFC_STATE_CLOSE) && (entry->requested_credit == 0) && - (entry->requested_packet == 0)) || - (!(entry->ac_bitmap & (1 << prec)))) - return 1; - - return 0; -} - -static void* -_dhd_wlfc_deque_delayedq(athost_wl_status_info_t* ctx, - int prec, uint8* ac_credit_spent, uint8* needs_hdr, wlfc_mac_descriptor_t** entry_out) -{ - wlfc_mac_descriptor_t* entry; - wlfc_mac_descriptor_t* table; - uint8 token_pos; - int total_entries; - void* p = NULL; - int pout; - int i; - - *entry_out = NULL; - token_pos = ctx->token_pos[prec]; - /* most cases a packet will count against FIFO credit */ - *ac_credit_spent = 1; - *needs_hdr = 1; - - /* search all entries, include nodes as well as interfaces */ - table = (wlfc_mac_descriptor_t*)&ctx->destination_entries; - total_entries = sizeof(ctx->destination_entries)/sizeof(wlfc_mac_descriptor_t); - - for (i = 0; i < total_entries; i++) { - entry = &table[(token_pos + i) % total_entries]; - if (entry->occupied) { - if (!_dhd_wlfc_is_destination_closed(ctx, entry, prec)) { - p = pktq_mdeq(&entry->psq, - /* higher precedence will be picked up first, - i.e. suppressed packets before delayed ones - */ - (NBITVAL((prec << 1) + 1) | NBITVAL((prec << 1))), - &pout); - if (p != NULL) { - /* did the packet come from suppress sub-queue? */ - if (pout == ((prec << 1) + 1)) { - /* - this packet was suppressed and was sent on the bus - previously; this already has a header - */ - *needs_hdr = 0; - } - if (entry->requested_credit > 0) { - entry->requested_credit--; -#ifdef PROP_TXSTATUS_DEBUG - entry->dstncredit_sent_packets++; -#endif - /* - if the packet was pulled out while destination is in - closed state but had a non-zero packets requested, - then this should not count against the FIFO credit. - That is due to the fact that the firmware will - most likely hold onto this packet until a suitable - time later to push it to the appropriate AC FIFO. - */ - if (entry->state == WLFC_STATE_CLOSE) - *ac_credit_spent = 0; - } - else if (entry->requested_packet > 0) { - entry->requested_packet--; - DHD_PKTTAG_SETONETIMEPKTRQST(PKTTAG(p)); - if (entry->state == WLFC_STATE_CLOSE) - *ac_credit_spent = 0; - } - /* move token to ensure fair round-robin */ - ctx->token_pos[prec] = - (token_pos + i + 1) % total_entries; - *entry_out = entry; - _dhd_wlfc_flow_control_check(ctx, &entry->psq, - DHD_PKTTAG_IF(PKTTAG(p))); - /* - A packet has been picked up, update traffic - availability bitmap, if applicable - */ - _dhd_wlfc_traffic_pending_check(ctx, entry, prec); - return p; - } - } - } - } - return NULL; -} - -static void* -_dhd_wlfc_deque_sendq(athost_wl_status_info_t* ctx, int prec, uint8* ac_credit_spent) -{ - wlfc_mac_descriptor_t* entry; - void* p; - - /* most cases a packet will count against FIFO credit */ - *ac_credit_spent = 1; - - p = pktq_pdeq(&ctx->SENDQ, prec); - if (p != NULL) { - if (ETHER_ISMULTI(DHD_PKTTAG_DSTN(PKTTAG(p)))) - /* bc/mc packets do not have a delay queue */ - return p; - - entry = _dhd_wlfc_find_table_entry(ctx, p); - - if (entry == NULL) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - return p; - } - - while ((p != NULL) && _dhd_wlfc_is_destination_closed(ctx, entry, prec)) { - /* - - suppressed packets go to sub_queue[2*prec + 1] AND - - delayed packets go to sub_queue[2*prec + 0] to ensure - order of delivery. - */ - if (WLFC_PKTQ_PENQ(&entry->psq, (prec << 1), p) == NULL) { - WLFC_DBGMESG(("D")); - /* dhd_txcomplete(ctx->dhdp, p, FALSE); */ - PKTFREE(ctx->osh, p, TRUE); - ctx->stats.delayq_full_error++; - } - /* - A packet has been pushed, update traffic availability bitmap, - if applicable - */ - _dhd_wlfc_traffic_pending_check(ctx, entry, prec); - _dhd_wlfc_flow_control_check(ctx, &entry->psq, DHD_PKTTAG_IF(PKTTAG(p))); - p = pktq_pdeq(&ctx->SENDQ, prec); - if (p == NULL) - break; - - entry = _dhd_wlfc_find_table_entry(ctx, p); - - if ((entry == NULL) || (ETHER_ISMULTI(DHD_PKTTAG_DSTN(PKTTAG(p))))) { - return p; - } - } - if (p) { - if (entry->requested_packet == 0) { - if (entry->requested_credit > 0) - entry->requested_credit--; - } - else { - entry->requested_packet--; - DHD_PKTTAG_SETONETIMEPKTRQST(PKTTAG(p)); - } - if (entry->state == WLFC_STATE_CLOSE) - *ac_credit_spent = 0; -#ifdef PROP_TXSTATUS_DEBUG - entry->dstncredit_sent_packets++; -#endif - } - if (p) - _dhd_wlfc_flow_control_check(ctx, &ctx->SENDQ, DHD_PKTTAG_IF(PKTTAG(p))); - } - return p; -} - -static int -_dhd_wlfc_mac_entry_update(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry, - ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea) -{ - int rc = BCME_OK; - - if (action == eWLFC_MAC_ENTRY_ACTION_ADD) { - entry->occupied = 1; - entry->state = WLFC_STATE_OPEN; - entry->requested_credit = 0; - entry->interface_id = ifid; - entry->iftype = iftype; - entry->ac_bitmap = 0xff; /* update this when handling APSD */ - /* for an interface entry we may not care about the MAC address */ - if (ea != NULL) - memcpy(&entry->ea[0], ea, ETHER_ADDR_LEN); - pktq_init(&entry->psq, WLFC_PSQ_PREC_COUNT, WLFC_PSQ_LEN); - } - else if (action == eWLFC_MAC_ENTRY_ACTION_DEL) { - entry->occupied = 0; - entry->state = WLFC_STATE_CLOSE; - entry->requested_credit = 0; - /* enable after packets are queued-deqeued properly. - pktq_flush(dhd->osh, &entry->psq, FALSE, NULL, 0); - */ - } - return rc; -} - -int -_dhd_wlfc_borrow_credit(athost_wl_status_info_t* ctx, uint8 available_credit_map, int borrower_ac) -{ - int lender_ac; - int rc = BCME_ERROR; - - if (ctx == NULL || available_credit_map == 0) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - return BCME_BADARG; - } - - /* Borrow from lowest priority available AC (including BC/MC credits) */ - for (lender_ac = 0; lender_ac <= AC_COUNT; lender_ac++) { - if ((available_credit_map && (1 << lender_ac)) && - (ctx->FIFO_credit[lender_ac] > 0)) { - ctx->credits_borrowed[borrower_ac][lender_ac]++; - ctx->FIFO_credit[lender_ac]--; - rc = BCME_OK; - break; - } - } - - return rc; -} - -int -dhd_wlfc_interface_entry_update(void* state, - ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea) -{ - athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state; - wlfc_mac_descriptor_t* entry; - - if (ifid >= WLFC_MAX_IFNUM) - return BCME_BADARG; - - entry = &ctx->destination_entries.interfaces[ifid]; - return _dhd_wlfc_mac_entry_update(ctx, entry, action, ifid, iftype, ea); -} - -int -dhd_wlfc_FIFOcreditmap_update(void* state, uint8* credits) -{ - athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state; - - /* update the AC FIFO credit map */ - ctx->FIFO_credit[0] = credits[0]; - ctx->FIFO_credit[1] = credits[1]; - ctx->FIFO_credit[2] = credits[2]; - ctx->FIFO_credit[3] = credits[3]; - /* credit for bc/mc packets */ - ctx->FIFO_credit[4] = credits[4]; - /* credit for ATIM FIFO is not used yet. */ - ctx->FIFO_credit[5] = 0; - return BCME_OK; -} - -int -dhd_wlfc_enque_sendq(void* state, int prec, void* p) -{ - athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state; - - if ((state == NULL) || - /* prec = AC_COUNT is used for bc/mc queue */ - (prec > AC_COUNT) || - (p == NULL)) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - return BCME_BADARG; - } - if (FALSE == dhd_prec_enq(ctx->dhdp, &ctx->SENDQ, p, prec)) { - ctx->stats.sendq_full_error++; - /* - WLFC_DBGMESG(("Error: %s():%d, qlen:%d\n", - __FUNCTION__, __LINE__, ctx->SENDQ.len)); - */ - WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, prec); - WLFC_DBGMESG(("Q")); - PKTFREE(ctx->osh, p, TRUE); - return BCME_ERROR; - } - ctx->stats.pktin++; - /* _dhd_wlfc_flow_control_check(ctx, &ctx->SENDQ, DHD_PKTTAG_IF(PKTTAG(p))); */ - return BCME_OK; -} - -int -_dhd_wlfc_handle_packet_commit(athost_wl_status_info_t* ctx, int ac, - dhd_wlfc_commit_info_t *commit_info, f_commitpkt_t fcommit, void* commit_ctx) -{ - uint32 hslot; - int rc; - - /* - if ac_fifo_credit_spent = 0 - - This packet will not count against the FIFO credit. - To ensure the txstatus corresponding to this packet - does not provide an implied credit (default behavior) - mark the packet accordingly. - - if ac_fifo_credit_spent = 1 - - This is a normal packet and it counts against the FIFO - credit count. - */ - DHD_PKTTAG_SETCREDITCHECK(PKTTAG(commit_info->p), commit_info->ac_fifo_credit_spent); - rc = _dhd_wlfc_pretx_pktprocess(ctx, commit_info->mac_entry, commit_info->p, - commit_info->needs_hdr, &hslot); - - if (rc == BCME_OK) - rc = fcommit(commit_ctx, commit_info->p); - else - ctx->stats.generic_error++; - - if (rc == BCME_OK) { - ctx->stats.pkt2bus++; - if (commit_info->ac_fifo_credit_spent) { - ctx->stats.sendq_pkts[ac]++; - WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac); - } - } - else { - /* - bus commit has failed, rollback. - - remove wl-header for a delayed packet - - save wl-header header for suppressed packets - */ - rc = _dhd_wlfc_rollback_packet_toq(ctx, commit_info->p, - (commit_info->pkt_type), hslot); - if (rc != BCME_OK) - ctx->stats.rollback_failed++; - - rc = BCME_ERROR; - } - - return rc; -} - -int -dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx) -{ - int ac; - int credit; - int rc; - dhd_wlfc_commit_info_t commit_info; - athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state; - int credit_count = 0; - int bus_retry_count = 0; - uint8 ac_available = 0; /* Bitmask for 4 ACs + BC/MC */ - - if ((state == NULL) || - (fcommit == NULL)) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - return BCME_BADARG; - } - - memset(&commit_info, 0, sizeof(commit_info)); - - /* - Commit packets for regular AC traffic. Higher priority first. - First, use up FIFO credits available to each AC. Based on distribution - and credits left, borrow from other ACs as applicable - - -NOTE: - If the bus between the host and firmware is overwhelmed by the - traffic from host, it is possible that higher priority traffic - starves the lower priority queue. If that occurs often, we may - have to employ weighted round-robin or ucode scheme to avoid - low priority packet starvation. - */ - - for (ac = AC_COUNT; ac >= 0; ac--) { - - int initial_credit_count = ctx->FIFO_credit[ac]; - - for (credit = 0; credit < ctx->FIFO_credit[ac];) { - commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac, - &(commit_info.ac_fifo_credit_spent), - &(commit_info.needs_hdr), - &(commit_info.mac_entry)); - - if (commit_info.p == NULL) - break; - - commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED : - eWLFC_PKTTYPE_SUPPRESSED; - - rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info, - fcommit, commit_ctx); - - /* Bus commits may fail (e.g. flow control); abort after retries */ - if (rc == BCME_OK) { - if (commit_info.ac_fifo_credit_spent) { - credit++; - } - } - else { - bus_retry_count++; - if (bus_retry_count >= BUS_RETRIES) { - DHD_ERROR(("dhd_wlfc_commit_packets(): bus error\n")); - ctx->FIFO_credit[ac] -= credit; - return rc; - } - } - } - - ctx->FIFO_credit[ac] -= credit; - - /* packets from SENDQ are fresh and they'd need header and have no MAC entry */ - commit_info.needs_hdr = 1; - commit_info.mac_entry = NULL; - commit_info.pkt_type = eWLFC_PKTTYPE_NEW; - - for (credit = 0; credit < ctx->FIFO_credit[ac];) { - commit_info.p = _dhd_wlfc_deque_sendq(ctx, ac, - &(commit_info.ac_fifo_credit_spent)); - if (commit_info.p == NULL) - break; - - rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info, - fcommit, commit_ctx); - - /* Bus commits may fail (e.g. flow control); abort after retries */ - if (rc == BCME_OK) { - if (commit_info.ac_fifo_credit_spent) { - credit++; - } - } - else { - bus_retry_count++; - if (bus_retry_count >= BUS_RETRIES) { - DHD_ERROR(("dhd_wlfc_commit_packets(): bus error\n")); - ctx->FIFO_credit[ac] -= credit; - return rc; - } - } - } - - ctx->FIFO_credit[ac] -= credit; - - /* If no credits were used, the queue is idle and can be re-used - Note that resv credits cannot be borrowed - */ - if (initial_credit_count == ctx->FIFO_credit[ac]) { - ac_available |= (1 << ac); - credit_count += ctx->FIFO_credit[ac]; - } - } - - /* We borrow only for AC_BE and only if no other traffic seen for DEFER_PERIOD - - Note that (ac_available & WLFC_AC_BE_TRAFFIC_ONLY) is done to: - a) ignore BC/MC for deferring borrow - b) ignore AC_BE being available along with other ACs - (this should happen only for pure BC/MC traffic) - - i.e. AC_VI, AC_VO, AC_BK all MUST be available (i.e. no traffic) and - we do not care if AC_BE and BC/MC are available or not - */ - if ((ac_available & WLFC_AC_BE_TRAFFIC_ONLY) == WLFC_AC_BE_TRAFFIC_ONLY) { - - if (ctx->allow_credit_borrow) { - ac = 1; /* Set ac to AC_BE and borrow credits */ - } - else { - int delta; - int curr_t = OSL_SYSUPTIME(); - - if (curr_t > ctx->borrow_defer_timestamp) - delta = curr_t - ctx->borrow_defer_timestamp; - else - delta = 0xffffffff + curr_t - ctx->borrow_defer_timestamp; - - if (delta >= WLFC_BORROW_DEFER_PERIOD_MS) { - /* Reset borrow but defer to next iteration (defensive borrowing) */ - ctx->allow_credit_borrow = TRUE; - ctx->borrow_defer_timestamp = 0; - } - return BCME_OK; - } - } - else { - /* If we have multiple AC traffic, turn off borrowing, mark time and bail out */ - ctx->allow_credit_borrow = FALSE; - ctx->borrow_defer_timestamp = OSL_SYSUPTIME(); - return BCME_OK; - } - - /* At this point, borrow all credits only for "ac" (which should be set above to AC_BE) - Generically use "ac" only in case we extend to all ACs in future - */ - for (; (credit_count > 0);) { - - commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac, - &(commit_info.ac_fifo_credit_spent), - &(commit_info.needs_hdr), - &(commit_info.mac_entry)); - if (commit_info.p == NULL) - break; - - commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED : - eWLFC_PKTTYPE_SUPPRESSED; - - rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info, - fcommit, commit_ctx); - - /* Bus commits may fail (e.g. flow control); abort after retries */ - if (rc == BCME_OK) { - if (commit_info.ac_fifo_credit_spent) { - (void) _dhd_wlfc_borrow_credit(ctx, ac_available, ac); - credit_count--; - } - } - else { - bus_retry_count++; - if (bus_retry_count >= BUS_RETRIES) { - DHD_ERROR(("dhd_wlfc_commit_packets(): bus error\n")); - return rc; - } - } - } - - /* packets from SENDQ are fresh and they'd need header and have no MAC entry */ - commit_info.needs_hdr = 1; - commit_info.mac_entry = NULL; - commit_info.pkt_type = eWLFC_PKTTYPE_NEW; - - for (; (credit_count > 0);) { - - commit_info.p = _dhd_wlfc_deque_sendq(ctx, ac, - &(commit_info.ac_fifo_credit_spent)); - if (commit_info.p == NULL) - break; - - rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info, - fcommit, commit_ctx); - - /* Bus commits may fail (e.g. flow control); abort after retries */ - if (rc == BCME_OK) { - if (commit_info.ac_fifo_credit_spent) { - (void) _dhd_wlfc_borrow_credit(ctx, ac_available, ac); - credit_count--; - } - } - else { - bus_retry_count++; - if (bus_retry_count >= BUS_RETRIES) { - DHD_ERROR(("dhd_wlfc_commit_packets(): bus error\n")); - return rc; - } - } - } - - return BCME_OK; -} - -static uint8 -dhd_wlfc_find_mac_desc_id_from_mac(dhd_pub_t *dhdp, uint8* ea) -{ - wlfc_mac_descriptor_t* table = - ((athost_wl_status_info_t*)dhdp->wlfc_state)->destination_entries.nodes; - uint8 table_index; - - if (ea != NULL) { - for (table_index = 0; table_index < WLFC_MAC_DESC_TABLE_SIZE; table_index++) { - if ((memcmp(ea, &table[table_index].ea[0], ETHER_ADDR_LEN) == 0) && - table[table_index].occupied) - return table_index; - } - } - return WLFC_MAC_DESC_ID_INVALID; -} - -void -dhd_wlfc_txcomplete(dhd_pub_t *dhd, void *txp, bool success) -{ - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - void* p; - int fifo_id; - - if (DHD_PKTTAG_SIGNALONLY(PKTTAG(txp))) { -#ifdef PROP_TXSTATUS_DEBUG - wlfc->stats.signal_only_pkts_freed++; -#endif - /* is this a signal-only packet? */ - PKTFREE(wlfc->osh, txp, TRUE); - return; - } - if (!success) { - WLFC_DBGMESG(("At: %s():%d, bus_complete() failure for %p, htod_tag:0x%08x\n", - __FUNCTION__, __LINE__, txp, DHD_PKTTAG_H2DTAG(PKTTAG(txp)))); - dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG - (PKTTAG(txp))), &p, 1); - - /* indicate failure and free the packet */ - dhd_txcomplete(dhd, txp, FALSE); - - /* return the credit, if necessary */ - if (DHD_PKTTAG_CREDITCHECK(PKTTAG(txp))) { - int lender, credit_returned = 0; /* Note that borrower is fifo_id */ - - fifo_id = DHD_PKTTAG_FIFO(PKTTAG(txp)); - - /* Return credits to highest priority lender first */ - for (lender = AC_COUNT; lender >= 0; lender--) { - if (wlfc->credits_borrowed[fifo_id][lender] > 0) { - wlfc->FIFO_credit[lender]++; - wlfc->credits_borrowed[fifo_id][lender]--; - credit_returned = 1; - break; - } - } - - if (!credit_returned) { - wlfc->FIFO_credit[fifo_id]++; - } - } - - PKTFREE(wlfc->osh, txp, TRUE); - } - return; -} - -/* Handle discard or suppress indication */ -static int -dhd_wlfc_txstatus_update(dhd_pub_t *dhd, uint8* pkt_info) -{ - uint8 status_flag; - uint32 status; - int ret; - int remove_from_hanger = 1; - void* pktbuf; - uint8 fifo_id; - wlfc_mac_descriptor_t* entry = NULL; - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - - memcpy(&status, pkt_info, sizeof(uint32)); - status_flag = WL_TXSTATUS_GET_FLAGS(status); - wlfc->stats.txstatus_in++; - - if (status_flag == WLFC_CTL_PKTFLAG_DISCARD) { - wlfc->stats.pkt_freed++; - } - - else if (status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) { - wlfc->stats.d11_suppress++; - remove_from_hanger = 0; - } - - else if (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS) { - wlfc->stats.wl_suppress++; - remove_from_hanger = 0; - } - - else if (status_flag == WLFC_CTL_PKTFLAG_TOSSED_BYWLC) { - wlfc->stats.wlc_tossed_pkts++; - } - - ret = dhd_wlfc_hanger_poppkt(wlfc->hanger, - WLFC_PKTID_HSLOT_GET(status), &pktbuf, remove_from_hanger); - if (ret != BCME_OK) { - /* do something */ - return ret; - } - - if (!remove_from_hanger) { - /* this packet was suppressed */ - - entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf); - entry->generation = WLFC_PKTID_GEN(status); - } - -#ifdef PROP_TXSTATUS_DEBUG - { - uint32 new_t = OSL_SYSUPTIME(); - uint32 old_t; - uint32 delta; - old_t = ((wlfc_hanger_t*)(wlfc->hanger))->items[ - WLFC_PKTID_HSLOT_GET(status)].push_time; - - - wlfc->stats.latency_sample_count++; - if (new_t > old_t) - delta = new_t - old_t; - else - delta = 0xffffffff + new_t - old_t; - wlfc->stats.total_status_latency += delta; - wlfc->stats.latency_most_recent = delta; - - wlfc->stats.deltas[wlfc->stats.idx_delta++] = delta; - if (wlfc->stats.idx_delta == sizeof(wlfc->stats.deltas)/sizeof(uint32)) - wlfc->stats.idx_delta = 0; - } -#endif /* PROP_TXSTATUS_DEBUG */ - - fifo_id = DHD_PKTTAG_FIFO(PKTTAG(pktbuf)); - - /* pick up the implicit credit from this packet */ - if (DHD_PKTTAG_CREDITCHECK(PKTTAG(pktbuf))) { - if (wlfc->proptxstatus_mode == WLFC_FCMODE_IMPLIED_CREDIT) { - - int lender, credit_returned = 0; /* Note that borrower is fifo_id */ - - /* Return credits to highest priority lender first */ - for (lender = AC_COUNT; lender >= 0; lender--) { - if (wlfc->credits_borrowed[fifo_id][lender] > 0) { - wlfc->FIFO_credit[lender]++; - wlfc->credits_borrowed[fifo_id][lender]--; - credit_returned = 1; - break; - } - } - - if (!credit_returned) { - wlfc->FIFO_credit[fifo_id]++; - } - } - } - else { - /* - if this packet did not count against FIFO credit, it must have - taken a requested_credit from the destination entry (for pspoll etc.) - */ - if (!entry) { - - entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf); - } - if (!DHD_PKTTAG_ONETIMEPKTRQST(PKTTAG(pktbuf))) - entry->requested_credit++; -#ifdef PROP_TXSTATUS_DEBUG - entry->dstncredit_acks++; -#endif - } - if ((status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) || - (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS)) { - ret = _dhd_wlfc_enque_suppressed(wlfc, fifo_id, pktbuf); - if (ret != BCME_OK) { - /* delay q is full, drop this packet */ - dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(status), - &pktbuf, 1); - - /* indicate failure and free the packet */ - dhd_txcomplete(dhd, pktbuf, FALSE); - PKTFREE(wlfc->osh, pktbuf, TRUE); - } - } - else { - dhd_txcomplete(dhd, pktbuf, TRUE); - /* free the packet */ - PKTFREE(wlfc->osh, pktbuf, TRUE); - } - return BCME_OK; -} - -static int -dhd_wlfc_fifocreditback_indicate(dhd_pub_t *dhd, uint8* credits) -{ - int i; - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - for (i = 0; i < WLFC_CTL_VALUE_LEN_FIFO_CREDITBACK; i++) { -#ifdef PROP_TXSTATUS_DEBUG - wlfc->stats.fifo_credits_back[i] += credits[i]; -#endif - /* update FIFO credits */ - if (wlfc->proptxstatus_mode == WLFC_FCMODE_EXPLICIT_CREDIT) - { - int lender; /* Note that borrower is i */ - - /* Return credits to highest priority lender first */ - for (lender = AC_COUNT; (lender >= 0) && (credits[i] > 0); lender--) { - if (wlfc->credits_borrowed[i][lender] > 0) { - if (credits[i] >= wlfc->credits_borrowed[i][lender]) { - credits[i] -= wlfc->credits_borrowed[i][lender]; - wlfc->FIFO_credit[lender] += - wlfc->credits_borrowed[i][lender]; - wlfc->credits_borrowed[i][lender] = 0; - } - else { - wlfc->credits_borrowed[i][lender] -= credits[i]; - wlfc->FIFO_credit[lender] += credits[i]; - credits[i] = 0; - } - } - } - - /* If we have more credits left over, these must belong to the AC */ - if (credits[i] > 0) { - wlfc->FIFO_credit[i] += credits[i]; - } - } - } - - return BCME_OK; -} - -static int -dhd_wlfc_rssi_indicate(dhd_pub_t *dhd, uint8* rssi) -{ - (void)dhd; - (void)rssi; - return BCME_OK; -} - -static int -dhd_wlfc_mac_table_update(dhd_pub_t *dhd, uint8* value, uint8 type) -{ - int rc; - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - wlfc_mac_descriptor_t* table; - uint8 existing_index; - uint8 table_index; - uint8 ifid; - uint8* ea; - - WLFC_DBGMESG(("%s(), mac [%02x:%02x:%02x:%02x:%02x:%02x],%s,idx:%d,id:0x%02x\n", - __FUNCTION__, value[2], value[3], value[4], value[5], value[6], value[7], - ((type == WLFC_CTL_TYPE_MACDESC_ADD) ? "ADD":"DEL"), - WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]), value[0])); - - table = wlfc->destination_entries.nodes; - table_index = WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]); - ifid = value[1]; - ea = &value[2]; - - if (type == WLFC_CTL_TYPE_MACDESC_ADD) { - existing_index = dhd_wlfc_find_mac_desc_id_from_mac(dhd, &value[2]); - if (existing_index == WLFC_MAC_DESC_ID_INVALID) { - /* this MAC entry does not exist, create one */ - if (!table[table_index].occupied) { - table[table_index].mac_handle = value[0]; - rc = _dhd_wlfc_mac_entry_update(wlfc, &table[table_index], - eWLFC_MAC_ENTRY_ACTION_ADD, ifid, - wlfc->destination_entries.interfaces[ifid].iftype, - ea); - } - else { - /* the space should have been empty, but it's not */ - wlfc->stats.mac_update_failed++; - } - } - else { - /* - there is an existing entry, move it to new index - if necessary. - */ - if (existing_index != table_index) { - /* if we already have an entry, free the old one */ - table[existing_index].occupied = 0; - table[existing_index].state = WLFC_STATE_CLOSE; - table[existing_index].requested_credit = 0; - table[existing_index].interface_id = 0; - } - } - } - if (type == WLFC_CTL_TYPE_MACDESC_DEL) { - if (table[table_index].occupied) { - rc = _dhd_wlfc_mac_entry_update(wlfc, &table[table_index], - eWLFC_MAC_ENTRY_ACTION_DEL, ifid, - wlfc->destination_entries.interfaces[ifid].iftype, - ea); - } - else { - /* the space should have been occupied, but it's not */ - wlfc->stats.mac_update_failed++; - } - } - return BCME_OK; -} - -static int -dhd_wlfc_psmode_update(dhd_pub_t *dhd, uint8* value, uint8 type) -{ - /* Handle PS on/off indication */ - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - wlfc_mac_descriptor_t* table; - wlfc_mac_descriptor_t* desc; - uint8 mac_handle = value[0]; - int i; - - table = wlfc->destination_entries.nodes; - desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)]; - if (desc->occupied) { - /* a fresh PS mode should wipe old ps credits? */ - desc->requested_credit = 0; - if (type == WLFC_CTL_TYPE_MAC_OPEN) { - desc->state = WLFC_STATE_OPEN; - DHD_WLFC_CTRINC_MAC_OPEN(desc); - } - else { - desc->state = WLFC_STATE_CLOSE; - DHD_WLFC_CTRINC_MAC_CLOSE(desc); - /* - Indicate to firmware if there is any traffic pending. - */ - for (i = AC_BE; i < AC_COUNT; i++) { - _dhd_wlfc_traffic_pending_check(wlfc, desc, i); - } - } - } - else { - wlfc->stats.psmode_update_failed++; - } - return BCME_OK; -} - -static int -dhd_wlfc_interface_update(dhd_pub_t *dhd, uint8* value, uint8 type) -{ - /* Handle PS on/off indication */ - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - wlfc_mac_descriptor_t* table; - uint8 if_id = value[0]; - - if (if_id < WLFC_MAX_IFNUM) { - table = wlfc->destination_entries.interfaces; - if (table[if_id].occupied) { - if (type == WLFC_CTL_TYPE_INTERFACE_OPEN) { - table[if_id].state = WLFC_STATE_OPEN; - /* WLFC_DBGMESG(("INTERFACE[%d] OPEN\n", if_id)); */ - } - else { - table[if_id].state = WLFC_STATE_CLOSE; - /* WLFC_DBGMESG(("INTERFACE[%d] CLOSE\n", if_id)); */ - } - return BCME_OK; - } - } - wlfc->stats.interface_update_failed++; - - return BCME_OK; -} - -static int -dhd_wlfc_credit_request(dhd_pub_t *dhd, uint8* value) -{ - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - wlfc_mac_descriptor_t* table; - wlfc_mac_descriptor_t* desc; - uint8 mac_handle; - uint8 credit; - - table = wlfc->destination_entries.nodes; - mac_handle = value[1]; - credit = value[0]; - - desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)]; - if (desc->occupied) { - desc->requested_credit = credit; - - desc->ac_bitmap = value[2]; - } - else { - wlfc->stats.credit_request_failed++; - } - return BCME_OK; -} - -static int -dhd_wlfc_packet_request(dhd_pub_t *dhd, uint8* value) -{ - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - wlfc_mac_descriptor_t* table; - wlfc_mac_descriptor_t* desc; - uint8 mac_handle; - uint8 packet_count; - - table = wlfc->destination_entries.nodes; - mac_handle = value[1]; - packet_count = value[0]; - - desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)]; - if (desc->occupied) { - desc->requested_packet = packet_count; - - desc->ac_bitmap = value[2]; - } - else { - wlfc->stats.packet_request_failed++; - } - return BCME_OK; -} - -static int -dhd_wlfc_parse_header_info(dhd_pub_t *dhd, void* pktbuf, int tlv_hdr_len) -{ - uint8 type, len; - uint8* value; - uint8* tmpbuf; - uint16 remainder = tlv_hdr_len; - uint16 processed = 0; - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - tmpbuf = (uint8*)PKTDATA(dhd->osh, pktbuf); - if (remainder) { - while ((processed < (WLFC_MAX_PENDING_DATALEN * 2)) && (remainder > 0)) { - type = tmpbuf[processed]; - if (type == WLFC_CTL_TYPE_FILLER) { - remainder -= 1; - processed += 1; - continue; - } - - len = tmpbuf[processed + 1]; - value = &tmpbuf[processed + 2]; - - if (remainder < (2 + len)) - break; - - remainder -= 2 + len; - processed += 2 + len; - if (type == WLFC_CTL_TYPE_TXSTATUS) - dhd_wlfc_txstatus_update(dhd, value); - - else if (type == WLFC_CTL_TYPE_FIFO_CREDITBACK) - dhd_wlfc_fifocreditback_indicate(dhd, value); - - else if (type == WLFC_CTL_TYPE_RSSI) - dhd_wlfc_rssi_indicate(dhd, value); - - else if (type == WLFC_CTL_TYPE_MAC_REQUEST_CREDIT) - dhd_wlfc_credit_request(dhd, value); - - else if (type == WLFC_CTL_TYPE_MAC_REQUEST_PACKET) - dhd_wlfc_packet_request(dhd, value); - - else if ((type == WLFC_CTL_TYPE_MAC_OPEN) || - (type == WLFC_CTL_TYPE_MAC_CLOSE)) - dhd_wlfc_psmode_update(dhd, value, type); - - else if ((type == WLFC_CTL_TYPE_MACDESC_ADD) || - (type == WLFC_CTL_TYPE_MACDESC_DEL)) - dhd_wlfc_mac_table_update(dhd, value, type); - - else if ((type == WLFC_CTL_TYPE_INTERFACE_OPEN) || - (type == WLFC_CTL_TYPE_INTERFACE_CLOSE)) { - dhd_wlfc_interface_update(dhd, value, type); - } - } - if (remainder != 0) { - /* trouble..., something is not right */ - wlfc->stats.tlv_parse_failed++; - } - } - return BCME_OK; -} - -int -dhd_wlfc_init(dhd_pub_t *dhd) -{ - char iovbuf[12]; /* Room for "tlv" + '\0' + parameter */ - /* enable all signals & indicate host proptxstatus logic is active */ - uint32 tlv = dhd->wlfc_enabled? - WLFC_FLAGS_RSSI_SIGNALS | - WLFC_FLAGS_XONXOFF_SIGNALS | - WLFC_FLAGS_CREDIT_STATUS_SIGNALS | - WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE : 0; - - dhd->wlfc_state = NULL; - - /* - try to enable/disable signaling by sending "tlv" iovar. if that fails, - fallback to no flow control? Print a message for now. - */ - - /* enable proptxtstatus signaling by default */ - bcm_mkiovar("tlv", (char *)&tlv, 4, iovbuf, sizeof(iovbuf)); - if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0) < 0) { - DHD_ERROR(("dhd_wlfc_init(): failed to enable/disable bdcv2 tlv signaling\n")); - } - else { - /* - Leaving the message for now, it should be removed after a while; once - the tlv situation is stable. - */ - DHD_ERROR(("dhd_wlfc_init(): successfully %s bdcv2 tlv signaling, %d\n", - dhd->wlfc_enabled?"enabled":"disabled", tlv)); - } - return BCME_OK; -} - -int -dhd_wlfc_enable(dhd_pub_t *dhd) -{ - int i; - athost_wl_status_info_t* wlfc; - - if (!dhd->wlfc_enabled || dhd->wlfc_state) - return BCME_OK; - - /* allocate space to track txstatus propagated from firmware */ - dhd->wlfc_state = MALLOC(dhd->osh, sizeof(athost_wl_status_info_t)); - if (dhd->wlfc_state == NULL) - return BCME_NOMEM; - - /* initialize state space */ - wlfc = (athost_wl_status_info_t*)dhd->wlfc_state; - memset(wlfc, 0, sizeof(athost_wl_status_info_t)); - - /* remember osh & dhdp */ - wlfc->osh = dhd->osh; - wlfc->dhdp = dhd; - - wlfc->hanger = - dhd_wlfc_hanger_create(dhd->osh, WLFC_HANGER_MAXITEMS); - if (wlfc->hanger == NULL) { - MFREE(dhd->osh, dhd->wlfc_state, sizeof(athost_wl_status_info_t)); - dhd->wlfc_state = NULL; - return BCME_NOMEM; - } - - /* initialize all interfaces to accept traffic */ - for (i = 0; i < WLFC_MAX_IFNUM; i++) { - wlfc->hostif_flow_state[i] = OFF; - } - - /* - create the SENDQ containing - sub-queues for all AC precedences + 1 for bc/mc traffic - */ - pktq_init(&wlfc->SENDQ, (AC_COUNT + 1), WLFC_SENDQ_LEN); - - wlfc->destination_entries.other.state = WLFC_STATE_OPEN; - /* bc/mc FIFO is always open [credit aside], i.e. b[5] */ - wlfc->destination_entries.other.ac_bitmap = 0x1f; - wlfc->destination_entries.other.interface_id = 0; - - wlfc->proptxstatus_mode = WLFC_FCMODE_EXPLICIT_CREDIT; - - wlfc->allow_credit_borrow = TRUE; - wlfc->borrow_defer_timestamp = 0; - - return BCME_OK; -} - -/* release all packet resources */ -void -dhd_wlfc_cleanup(dhd_pub_t *dhd) -{ - int i; - int total_entries; - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - wlfc_mac_descriptor_t* table; - wlfc_hanger_t* h; - - if (dhd->wlfc_state == NULL) - return; - - total_entries = sizeof(wlfc->destination_entries)/sizeof(wlfc_mac_descriptor_t); - /* search all entries, include nodes as well as interfaces */ - table = (wlfc_mac_descriptor_t*)&wlfc->destination_entries; - - for (i = 0; i < total_entries; i++) { - if (table[i].occupied) { - if (table[i].psq.len) { - WLFC_DBGMESG(("%s(): DELAYQ[%d].len = %d\n", - __FUNCTION__, i, table[i].psq.len)); - /* release packets held in DELAYQ */ - pktq_flush(wlfc->osh, &table[i].psq, TRUE, NULL, 0); - } - table[i].occupied = 0; - } - } - /* release packets held in SENDQ */ - if (wlfc->SENDQ.len) - pktq_flush(wlfc->osh, &wlfc->SENDQ, TRUE, NULL, 0); - /* any in the hanger? */ - h = (wlfc_hanger_t*)wlfc->hanger; - for (i = 0; i < h->max_items; i++) { - if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE) { - PKTFREE(wlfc->osh, h->items[i].pkt, TRUE); - } - } - return; -} - -void -dhd_wlfc_deinit(dhd_pub_t *dhd) -{ - /* cleanup all psq related resources */ - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - - if (dhd->wlfc_state == NULL) - return; - -#ifdef PROP_TXSTATUS_DEBUG - { - int i; - wlfc_hanger_t* h = (wlfc_hanger_t*)wlfc->hanger; - for (i = 0; i < h->max_items; i++) { - if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE) { - WLFC_DBGMESG(("%s() pkt[%d] = 0x%p, FIFO_credit_used:%d\n", - __FUNCTION__, i, h->items[i].pkt, - DHD_PKTTAG_CREDITCHECK(PKTTAG(h->items[i].pkt)))); - } - } - } -#endif - /* delete hanger */ - dhd_wlfc_hanger_delete(dhd->osh, wlfc->hanger); - - /* free top structure */ - MFREE(dhd->osh, dhd->wlfc_state, sizeof(athost_wl_status_info_t)); - dhd->wlfc_state = NULL; - return; -} -#endif /* PROP_TXSTATUS */ - -void -dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) -{ - bcm_bprintf(strbuf, "Protocol CDC: reqid %d\n", dhdp->prot->reqid); -#ifdef PROP_TXSTATUS - if (dhdp->wlfc_state) - dhd_wlfc_dump(dhdp, strbuf); -#endif -} - -void -dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *pktbuf) -{ -#ifdef BDC - struct bdc_header *h; -#endif /* BDC */ - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - -#ifdef BDC - /* Push BDC header used to convey priority for buses that don't */ - - PKTPUSH(dhd->osh, pktbuf, BDC_HEADER_LEN); - - h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf); - - h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); - if (PKTSUMNEEDED(pktbuf)) - h->flags |= BDC_FLAG_SUM_NEEDED; - - - h->priority = (PKTPRIO(pktbuf) & BDC_PRIORITY_MASK); - h->flags2 = 0; - h->dataOffset = 0; -#endif /* BDC */ - BDC_SET_IF_IDX(h, ifidx); -} - -int -dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, void *pktbuf) -{ -#ifdef BDC - struct bdc_header *h; -#endif - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - -#ifdef BDC - /* Pop BDC header used to convey priority for buses that don't */ - - if (PKTLEN(dhd->osh, pktbuf) < BDC_HEADER_LEN) { - DHD_ERROR(("%s: rx data too short (%d < %d)\n", __FUNCTION__, - PKTLEN(dhd->osh, pktbuf), BDC_HEADER_LEN)); - return BCME_ERROR; - } - - h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf); - - if ((*ifidx = BDC_GET_IF_IDX(h)) >= DHD_MAX_IFS) { - DHD_ERROR(("%s: rx data ifnum out of range (%d)\n", - __FUNCTION__, *ifidx)); - return BCME_ERROR; - } - - if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != BDC_PROTO_VER) { - DHD_ERROR(("%s: non-BDC packet received, flags = 0x%x\n", - dhd_ifname(dhd, *ifidx), h->flags)); - if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) == BDC_PROTO_VER_1) - h->dataOffset = 0; - else - return BCME_ERROR; - } - - if (h->flags & BDC_FLAG_SUM_GOOD) { - DHD_INFO(("%s: BDC packet received with good rx-csum, flags 0x%x\n", - dhd_ifname(dhd, *ifidx), h->flags)); - PKTSETSUMGOOD(pktbuf, TRUE); - } - - PKTSETPRIO(pktbuf, (h->priority & BDC_PRIORITY_MASK)); - PKTPULL(dhd->osh, pktbuf, BDC_HEADER_LEN); -#endif /* BDC */ - - if (PKTLEN(dhd->osh, pktbuf) < (uint32) (h->dataOffset << 2)) { - DHD_ERROR(("%s: rx data too short (%d < %d)\n", __FUNCTION__, - PKTLEN(dhd->osh, pktbuf), (h->dataOffset * 4))); - return BCME_ERROR; - } - -#ifdef PROP_TXSTATUS - if (dhd->wlfc_state && - ((athost_wl_status_info_t*)dhd->wlfc_state)->proptxstatus_mode - != WLFC_FCMODE_NONE && - (!DHD_PKTTAG_PKTDIR(PKTTAG(pktbuf)))) { - /* - - parse txstatus only for packets that came from the firmware - */ - dhd_os_wlfc_block(dhd); - dhd_wlfc_parse_header_info(dhd, pktbuf, (h->dataOffset << 2)); - ((athost_wl_status_info_t*)dhd->wlfc_state)->stats.dhd_hdrpulls++; - dhd_wlfc_commit_packets(dhd->wlfc_state, (f_commitpkt_t)dhd_bus_txdata, - (void *)dhd->bus); - dhd_os_wlfc_unblock(dhd); - } -#endif /* PROP_TXSTATUS */ - PKTPULL(dhd->osh, pktbuf, (h->dataOffset << 2)); - return 0; -} - -int -dhd_prot_attach(dhd_pub_t *dhd) -{ - dhd_prot_t *cdc; - - if (!(cdc = (dhd_prot_t *)DHD_OS_PREALLOC(dhd->osh, DHD_PREALLOC_PROT, - sizeof(dhd_prot_t)))) { - DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - goto fail; - } - memset(cdc, 0, sizeof(dhd_prot_t)); - - /* ensure that the msg buf directly follows the cdc msg struct */ - if ((uintptr)(&cdc->msg + 1) != (uintptr)cdc->buf) { - DHD_ERROR(("dhd_prot_t is not correctly defined\n")); - goto fail; - } - - dhd->prot = cdc; -#ifdef BDC - dhd->hdrlen += BDC_HEADER_LEN; -#endif - dhd->maxctl = WLC_IOCTL_MAXLEN + sizeof(cdc_ioctl_t) + ROUND_UP_MARGIN; - return 0; - -fail: -#ifndef CONFIG_DHD_USE_STATIC_BUF - if (cdc != NULL) - MFREE(dhd->osh, cdc, sizeof(dhd_prot_t)); -#endif /* CONFIG_DHD_USE_STATIC_BUF */ - return BCME_NOMEM; -} - -/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */ -void -dhd_prot_detach(dhd_pub_t *dhd) -{ -#ifdef PROP_TXSTATUS - dhd_wlfc_deinit(dhd); -#endif -#ifndef CONFIG_DHD_USE_STATIC_BUF - MFREE(dhd->osh, dhd->prot, sizeof(dhd_prot_t)); -#endif /* CONFIG_DHD_USE_STATIC_BUF */ - dhd->prot = NULL; -} - -void -dhd_prot_dstats(dhd_pub_t *dhd) -{ - /* No stats from dongle added yet, copy bus stats */ - dhd->dstats.tx_packets = dhd->tx_packets; - dhd->dstats.tx_errors = dhd->tx_errors; - dhd->dstats.rx_packets = dhd->rx_packets; - dhd->dstats.rx_errors = dhd->rx_errors; - dhd->dstats.rx_dropped = dhd->rx_dropped; - dhd->dstats.multicast = dhd->rx_multicast; - return; -} - -int -dhd_prot_init(dhd_pub_t *dhd) -{ - int ret = 0; - wlc_rev_info_t revinfo; - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - - /* Get the device rev info */ - memset(&revinfo, 0, sizeof(revinfo)); - ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_REVINFO, &revinfo, sizeof(revinfo), FALSE, 0); - if (ret < 0) - goto done; - - -#ifdef PROP_TXSTATUS - ret = dhd_wlfc_init(dhd); -#endif - -#if defined(WL_CFG80211) - if (dhd_download_fw_on_driverload) -#endif /* defined(WL_CFG80211) */ - ret = dhd_preinit_ioctls(dhd); - - /* Always assumes wl for now */ - dhd->iswl = TRUE; - -done: - return ret; -} - -void -dhd_prot_stop(dhd_pub_t *dhd) -{ - /* Nothing to do for CDC */ -} diff --git a/drivers/net/wireless/bcmdhd/dhd_cfg80211.c b/drivers/net/wireless/bcmdhd/dhd_cfg80211.c deleted file mode 100644 index 351c372ffa81..000000000000 --- a/drivers/net/wireless/bcmdhd/dhd_cfg80211.c +++ /dev/null @@ -1,660 +0,0 @@ -/* - * Linux cfg80211 driver - Dongle Host Driver (DHD) related - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wl_cfg80211.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $ - */ - -#include - -#include -#include -#include -#include -extern struct wl_priv *wlcfg_drv_priv; -static int dhd_dongle_up = FALSE; - -#include -#include -#include -#include -#include - -static s32 wl_dongle_up(struct net_device *ndev, u32 up); - -/** - * Function implementations - */ - -s32 dhd_cfg80211_init(struct wl_priv *wl) -{ - dhd_dongle_up = FALSE; - return 0; -} - -s32 dhd_cfg80211_deinit(struct wl_priv *wl) -{ - dhd_dongle_up = FALSE; - return 0; -} - -s32 dhd_cfg80211_get_opmode(struct wl_priv *wl) -{ - dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); - return dhd->op_mode; -} - -s32 dhd_cfg80211_down(struct wl_priv *wl) -{ - dhd_dongle_up = FALSE; - return 0; -} - -/* - * dhd_cfg80211_set_p2p_info : gets called when GO or GC created - */ -s32 dhd_cfg80211_set_p2p_info(struct wl_priv *wl, int val) -{ - dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); - int bcn_timeout = DHD_BEACON_TIMEOUT_HIGH; - char iovbuf[30]; - - dhd->op_mode |= val; - WL_ERR(("Set : op_mode=%d\n", dhd->op_mode)); - -#ifdef ARP_OFFLOAD_SUPPORT - /* IF P2P is enabled, disable arpoe */ - dhd_arp_offload_set(dhd, 0); - dhd_arp_offload_enable(dhd, false); -#endif /* ARP_OFFLOAD_SUPPORT */ - /* diable all filtering in p2p mode */ - dhd_os_set_packet_filter(dhd, 0); - - /* Setup timeout if Beacons are lost and roam is off to report link down */ - bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - - - return 0; -} - -/* - * dhd_cfg80211_clean_p2p_info : gets called when GO or GC terminated - */ -s32 dhd_cfg80211_clean_p2p_info(struct wl_priv *wl) -{ - dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); - int bcn_timeout = DHD_BEACON_TIMEOUT_NORMAL; - char iovbuf[30]; - - dhd->op_mode &= ~CONCURENT_MASK; - WL_ERR(("Clean : op_mode=%d\n", dhd->op_mode)); - -#ifdef ARP_OFFLOAD_SUPPORT - /* IF P2P is disabled, enable arpoe back for STA mode. */ - dhd_arp_offload_set(dhd, dhd_arp_mode); - dhd_arp_offload_enable(dhd, true); -#endif /* ARP_OFFLOAD_SUPPORT */ - dhd_os_set_packet_filter(dhd, 1); - - /* Setup timeout if Beacons are lost and roam is off to report link down */ - bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - - return 0; -} - -static s32 wl_dongle_up(struct net_device *ndev, u32 up) -{ - s32 err = 0; - - err = wldev_ioctl(ndev, WLC_UP, &up, sizeof(up), true); - if (unlikely(err)) { - WL_ERR(("WLC_UP error (%d)\n", err)); - } - return err; -} - -s32 dhd_config_dongle(struct wl_priv *wl, bool need_lock) -{ -#ifndef DHD_SDALIGN -#define DHD_SDALIGN 32 -#endif - struct net_device *ndev; - s32 err = 0; - - WL_TRACE(("In\n")); - if (dhd_dongle_up) { - WL_ERR(("Dongle is already up\n")); - return err; - } - - ndev = wl_to_prmry_ndev(wl); - - if (need_lock) - rtnl_lock(); - - err = wl_dongle_up(ndev, 0); - if (unlikely(err)) { - WL_ERR(("wl_dongle_up failed\n")); - goto default_conf_out; - } - dhd_dongle_up = true; - -default_conf_out: - if (need_lock) - rtnl_unlock(); - return err; - -} - - -/* TODO: clean up the BT-Coex code, it still have some legacy ioctl/iovar functions */ -#define COEX_DHCP - -#if defined(COEX_DHCP) - -/* use New SCO/eSCO smart YG suppression */ -#define BT_DHCP_eSCO_FIX -/* this flag boost wifi pkt priority to max, caution: -not fair to sco */ -#define BT_DHCP_USE_FLAGS -/* T1 start SCO/ESCo priority suppression */ -#define BT_DHCP_OPPR_WIN_TIME 2500 -/* T2 turn off SCO/SCO supperesion is (timeout) */ -#define BT_DHCP_FLAG_FORCE_TIME 5500 - -enum wl_cfg80211_btcoex_status { - BT_DHCP_IDLE, - BT_DHCP_START, - BT_DHCP_OPPR_WIN, - BT_DHCP_FLAG_FORCE_TIMEOUT -}; - -/* - * get named driver variable to uint register value and return error indication - * calling example: dev_wlc_intvar_get_reg(dev, "btc_params",66, ®_value) - */ -static int -dev_wlc_intvar_get_reg(struct net_device *dev, char *name, - uint reg, int *retval) -{ - union { - char buf[WLC_IOCTL_SMLEN]; - int val; - } var; - int error; - - bcm_mkiovar(name, (char *)(®), sizeof(reg), - (char *)(&var), sizeof(var.buf)); - error = wldev_ioctl(dev, WLC_GET_VAR, (char *)(&var), sizeof(var.buf), false); - - *retval = dtoh32(var.val); - return (error); -} - -static int -dev_wlc_bufvar_set(struct net_device *dev, char *name, char *buf, int len) -{ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) - char ioctlbuf_local[1024]; -#else - static char ioctlbuf_local[1024]; -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) */ - - bcm_mkiovar(name, buf, len, ioctlbuf_local, sizeof(ioctlbuf_local)); - - return (wldev_ioctl(dev, WLC_SET_VAR, ioctlbuf_local, sizeof(ioctlbuf_local), true)); -} -/* -get named driver variable to uint register value and return error indication -calling example: dev_wlc_intvar_set_reg(dev, "btc_params",66, value) -*/ -static int -dev_wlc_intvar_set_reg(struct net_device *dev, char *name, char *addr, char * val) -{ - char reg_addr[8]; - - memset(reg_addr, 0, sizeof(reg_addr)); - memcpy((char *)®_addr[0], (char *)addr, 4); - memcpy((char *)®_addr[4], (char *)val, 4); - - return (dev_wlc_bufvar_set(dev, name, (char *)®_addr[0], sizeof(reg_addr))); -} - -static bool btcoex_is_sco_active(struct net_device *dev) -{ - int ioc_res = 0; - bool res = FALSE; - int sco_id_cnt = 0; - int param27; - int i; - - for (i = 0; i < 12; i++) { - - ioc_res = dev_wlc_intvar_get_reg(dev, "btc_params", 27, ¶m27); - - WL_TRACE(("%s, sample[%d], btc params: 27:%x\n", - __FUNCTION__, i, param27)); - - if (ioc_res < 0) { - WL_ERR(("%s ioc read btc params error\n", __FUNCTION__)); - break; - } - - if ((param27 & 0x6) == 2) { /* count both sco & esco */ - sco_id_cnt++; - } - - if (sco_id_cnt > 2) { - WL_TRACE(("%s, sco/esco detected, pkt id_cnt:%d samples:%d\n", - __FUNCTION__, sco_id_cnt, i)); - res = TRUE; - break; - } - - msleep(5); - } - - return res; -} - -#if defined(BT_DHCP_eSCO_FIX) -/* Enhanced BT COEX settings for eSCO compatibility during DHCP window */ -static int set_btc_esco_params(struct net_device *dev, bool trump_sco) -{ - static bool saved_status = FALSE; - - char buf_reg50va_dhcp_on[8] = - { 50, 00, 00, 00, 0x22, 0x80, 0x00, 0x00 }; - char buf_reg51va_dhcp_on[8] = - { 51, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - char buf_reg64va_dhcp_on[8] = - { 64, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - char buf_reg65va_dhcp_on[8] = - { 65, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - char buf_reg71va_dhcp_on[8] = - { 71, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - uint32 regaddr; - static uint32 saved_reg50; - static uint32 saved_reg51; - static uint32 saved_reg64; - static uint32 saved_reg65; - static uint32 saved_reg71; - - if (trump_sco) { - /* this should reduce eSCO agressive retransmit - * w/o breaking it - */ - - /* 1st save current */ - WL_TRACE(("Do new SCO/eSCO coex algo {save &" - "override}\n")); - if ((!dev_wlc_intvar_get_reg(dev, "btc_params", 50, &saved_reg50)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 51, &saved_reg51)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 64, &saved_reg64)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 65, &saved_reg65)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 71, &saved_reg71))) { - saved_status = TRUE; - WL_TRACE(("%s saved bt_params[50,51,64,65,71]:" - "0x%x 0x%x 0x%x 0x%x 0x%x\n", - __FUNCTION__, saved_reg50, saved_reg51, - saved_reg64, saved_reg65, saved_reg71)); - } else { - WL_ERR((":%s: save btc_params failed\n", - __FUNCTION__)); - saved_status = FALSE; - return -1; - } - - WL_TRACE(("override with [50,51,64,65,71]:" - "0x%x 0x%x 0x%x 0x%x 0x%x\n", - *(u32 *)(buf_reg50va_dhcp_on+4), - *(u32 *)(buf_reg51va_dhcp_on+4), - *(u32 *)(buf_reg64va_dhcp_on+4), - *(u32 *)(buf_reg65va_dhcp_on+4), - *(u32 *)(buf_reg71va_dhcp_on+4))); - - dev_wlc_bufvar_set(dev, "btc_params", - (char *)&buf_reg50va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", - (char *)&buf_reg51va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", - (char *)&buf_reg64va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", - (char *)&buf_reg65va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", - (char *)&buf_reg71va_dhcp_on[0], 8); - - saved_status = TRUE; - } else if (saved_status) { - /* restore previously saved bt params */ - WL_TRACE(("Do new SCO/eSCO coex algo {save &" - "override}\n")); - - regaddr = 50; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg50); - regaddr = 51; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg51); - regaddr = 64; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg64); - regaddr = 65; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg65); - regaddr = 71; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg71); - - WL_TRACE(("restore bt_params[50,51,64,65,71]:" - "0x%x 0x%x 0x%x 0x%x 0x%x\n", - saved_reg50, saved_reg51, saved_reg64, - saved_reg65, saved_reg71)); - - saved_status = FALSE; - } else { - WL_ERR((":%s att to restore not saved BTCOEX params\n", - __FUNCTION__)); - return -1; - } - return 0; -} -#endif /* BT_DHCP_eSCO_FIX */ - -static void -wl_cfg80211_bt_setflag(struct net_device *dev, bool set) -{ -#if defined(BT_DHCP_USE_FLAGS) - char buf_flag7_dhcp_on[8] = { 7, 00, 00, 00, 0x1, 0x0, 0x00, 0x00 }; - char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00}; -#endif - - -#if defined(BT_DHCP_eSCO_FIX) - /* set = 1, save & turn on 0 - off & restore prev settings */ - set_btc_esco_params(dev, set); -#endif - -#if defined(BT_DHCP_USE_FLAGS) - WL_TRACE(("WI-FI priority boost via bt flags, set:%d\n", set)); - if (set == TRUE) - /* Forcing bt_flag7 */ - dev_wlc_bufvar_set(dev, "btc_flags", - (char *)&buf_flag7_dhcp_on[0], - sizeof(buf_flag7_dhcp_on)); - else - /* Restoring default bt flag7 */ - dev_wlc_bufvar_set(dev, "btc_flags", - (char *)&buf_flag7_default[0], - sizeof(buf_flag7_default)); -#endif -} - -static void wl_cfg80211_bt_timerfunc(ulong data) -{ - struct btcoex_info *bt_local = (struct btcoex_info *)data; - WL_TRACE(("%s\n", __FUNCTION__)); - bt_local->timer_on = 0; - schedule_work(&bt_local->work); -} - -static void wl_cfg80211_bt_handler(struct work_struct *work) -{ - struct btcoex_info *btcx_inf; - - btcx_inf = container_of(work, struct btcoex_info, work); - - if (btcx_inf->timer_on) { - btcx_inf->timer_on = 0; - del_timer_sync(&btcx_inf->timer); - } - - switch (btcx_inf->bt_state) { - case BT_DHCP_START: - /* DHCP started - * provide OPPORTUNITY window to get DHCP address - */ - WL_TRACE(("%s bt_dhcp stm: started \n", - __FUNCTION__)); - btcx_inf->bt_state = BT_DHCP_OPPR_WIN; - mod_timer(&btcx_inf->timer, - jiffies + msecs_to_jiffies(BT_DHCP_OPPR_WIN_TIME)); - btcx_inf->timer_on = 1; - break; - - case BT_DHCP_OPPR_WIN: - if (btcx_inf->dhcp_done) { - WL_TRACE(("%s DHCP Done before T1 expiration\n", - __FUNCTION__)); - goto btc_coex_idle; - } - - /* DHCP is not over yet, start lowering BT priority - * enforce btc_params + flags if necessary - */ - WL_TRACE(("%s DHCP T1:%d expired\n", __FUNCTION__, - BT_DHCP_OPPR_WIN_TIME)); - if (btcx_inf->dev) - wl_cfg80211_bt_setflag(btcx_inf->dev, TRUE); - btcx_inf->bt_state = BT_DHCP_FLAG_FORCE_TIMEOUT; - mod_timer(&btcx_inf->timer, - jiffies + msecs_to_jiffies(BT_DHCP_FLAG_FORCE_TIME)); - btcx_inf->timer_on = 1; - break; - - case BT_DHCP_FLAG_FORCE_TIMEOUT: - if (btcx_inf->dhcp_done) { - WL_TRACE(("%s DHCP Done before T2 expiration\n", - __FUNCTION__)); - } else { - /* Noo dhcp during T1+T2, restore BT priority */ - WL_TRACE(("%s DHCP wait interval T2:%d" - "msec expired\n", __FUNCTION__, - BT_DHCP_FLAG_FORCE_TIME)); - } - - /* Restoring default bt priority */ - if (btcx_inf->dev) - wl_cfg80211_bt_setflag(btcx_inf->dev, FALSE); -btc_coex_idle: - btcx_inf->bt_state = BT_DHCP_IDLE; - btcx_inf->timer_on = 0; - break; - - default: - WL_ERR(("%s error g_status=%d !!!\n", __FUNCTION__, - btcx_inf->bt_state)); - if (btcx_inf->dev) - wl_cfg80211_bt_setflag(btcx_inf->dev, FALSE); - btcx_inf->bt_state = BT_DHCP_IDLE; - btcx_inf->timer_on = 0; - break; - } - - net_os_wake_unlock(btcx_inf->dev); -} - -int wl_cfg80211_btcoex_init(struct wl_priv *wl) -{ - struct btcoex_info *btco_inf = NULL; - - btco_inf = kmalloc(sizeof(struct btcoex_info), GFP_KERNEL); - if (!btco_inf) - return -ENOMEM; - - btco_inf->bt_state = BT_DHCP_IDLE; - btco_inf->ts_dhcp_start = 0; - btco_inf->ts_dhcp_ok = 0; - /* Set up timer for BT */ - btco_inf->timer_ms = 10; - init_timer(&btco_inf->timer); - btco_inf->timer.data = (ulong)btco_inf; - btco_inf->timer.function = wl_cfg80211_bt_timerfunc; - - btco_inf->dev = wl->wdev->netdev; - - INIT_WORK(&btco_inf->work, wl_cfg80211_bt_handler); - - wl->btcoex_info = btco_inf; - return 0; -} - -void wl_cfg80211_btcoex_deinit(struct wl_priv *wl) -{ - if (!wl->btcoex_info) - return; - - if (!wl->btcoex_info->timer_on) { - wl->btcoex_info->timer_on = 0; - del_timer_sync(&wl->btcoex_info->timer); - } - - cancel_work_sync(&wl->btcoex_info->work); - - kfree(wl->btcoex_info); - wl->btcoex_info = NULL; -} - -int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command) -{ - - struct wl_priv *wl = wlcfg_drv_priv; - char powermode_val = 0; - char buf_reg66va_dhcp_on[8] = { 66, 00, 00, 00, 0x10, 0x27, 0x00, 0x00 }; - char buf_reg41va_dhcp_on[8] = { 41, 00, 00, 00, 0x33, 0x00, 0x00, 0x00 }; - char buf_reg68va_dhcp_on[8] = { 68, 00, 00, 00, 0x90, 0x01, 0x00, 0x00 }; - - uint32 regaddr; - static uint32 saved_reg66; - static uint32 saved_reg41; - static uint32 saved_reg68; - static bool saved_status = FALSE; - -#ifdef COEX_DHCP - char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00}; - struct btcoex_info *btco_inf = wl->btcoex_info; -#endif /* COEX_DHCP */ - - /* Figure out powermode 1 or o command */ - strncpy((char *)&powermode_val, command + strlen("BTCOEXMODE") +1, 1); - - if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) { - - WL_TRACE(("%s: DHCP session starts\n", __FUNCTION__)); - - /* Retrieve and saved orig regs value */ - if ((saved_status == FALSE) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 66, &saved_reg66)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 41, &saved_reg41)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 68, &saved_reg68))) { - saved_status = TRUE; - WL_TRACE(("Saved 0x%x 0x%x 0x%x\n", - saved_reg66, saved_reg41, saved_reg68)); - - /* Disable PM mode during dhpc session */ - - /* Disable PM mode during dhpc session */ -#ifdef COEX_DHCP - /* Start BT timer only for SCO connection */ - if (btcoex_is_sco_active(dev)) { - /* btc_params 66 */ - dev_wlc_bufvar_set(dev, "btc_params", - (char *)&buf_reg66va_dhcp_on[0], - sizeof(buf_reg66va_dhcp_on)); - /* btc_params 41 0x33 */ - dev_wlc_bufvar_set(dev, "btc_params", - (char *)&buf_reg41va_dhcp_on[0], - sizeof(buf_reg41va_dhcp_on)); - /* btc_params 68 0x190 */ - dev_wlc_bufvar_set(dev, "btc_params", - (char *)&buf_reg68va_dhcp_on[0], - sizeof(buf_reg68va_dhcp_on)); - saved_status = TRUE; - - btco_inf->bt_state = BT_DHCP_START; - btco_inf->timer_on = 1; - mod_timer(&btco_inf->timer, btco_inf->timer.expires); - WL_TRACE(("%s enable BT DHCP Timer\n", - __FUNCTION__)); - } -#endif /* COEX_DHCP */ - } - else if (saved_status == TRUE) { - WL_ERR(("%s was called w/o DHCP OFF. Continue\n", __FUNCTION__)); - } - } - else if (strnicmp((char *)&powermode_val, "2", strlen("2")) == 0) { - - - /* Restoring PM mode */ - -#ifdef COEX_DHCP - /* Stop any bt timer because DHCP session is done */ - WL_TRACE(("%s disable BT DHCP Timer\n", __FUNCTION__)); - if (btco_inf->timer_on) { - btco_inf->timer_on = 0; - del_timer_sync(&btco_inf->timer); - - if (btco_inf->bt_state != BT_DHCP_IDLE) { - /* need to restore original btc flags & extra btc params */ - WL_TRACE(("%s bt->bt_state:%d\n", - __FUNCTION__, btco_inf->bt_state)); - /* wake up btcoex thread to restore btlags+params */ - schedule_work(&btco_inf->work); - } - } - - /* Restoring btc_flag paramter anyway */ - if (saved_status == TRUE) - dev_wlc_bufvar_set(dev, "btc_flags", - (char *)&buf_flag7_default[0], sizeof(buf_flag7_default)); -#endif /* COEX_DHCP */ - - /* Restore original values */ - if (saved_status == TRUE) { - regaddr = 66; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg66); - regaddr = 41; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg41); - regaddr = 68; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg68); - - WL_TRACE(("restore regs {66,41,68} <- 0x%x 0x%x 0x%x\n", - saved_reg66, saved_reg41, saved_reg68)); - } - saved_status = FALSE; - - } - else { - WL_ERR(("%s Unkwown yet power setting, ignored\n", - __FUNCTION__)); - } - - snprintf(command, 3, "OK"); - - return (strlen("OK")); -} -#endif diff --git a/drivers/net/wireless/bcmdhd/dhd_cfg80211.h b/drivers/net/wireless/bcmdhd/dhd_cfg80211.h deleted file mode 100644 index ced46dbdb96c..000000000000 --- a/drivers/net/wireless/bcmdhd/dhd_cfg80211.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Linux cfg80211 driver - Dongle Host Driver (DHD) related - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wl_cfg80211.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $ - */ - - -#ifndef __DHD_CFG80211__ -#define __DHD_CFG80211__ - -#include -#include - -s32 dhd_cfg80211_init(struct wl_priv *wl); -s32 dhd_cfg80211_deinit(struct wl_priv *wl); -s32 dhd_cfg80211_get_opmode(struct wl_priv *wl); -s32 dhd_cfg80211_down(struct wl_priv *wl); -s32 dhd_cfg80211_set_p2p_info(struct wl_priv *wl, int val); -s32 dhd_cfg80211_clean_p2p_info(struct wl_priv *wl); -s32 dhd_config_dongle(struct wl_priv *wl, bool need_lock); - -int wl_cfg80211_btcoex_init(struct wl_priv *wl); -void wl_cfg80211_btcoex_deinit(struct wl_priv *wl); - -#endif /* __DHD_CFG80211__ */ diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c deleted file mode 100644 index d46864c3a2a8..000000000000 --- a/drivers/net/wireless/bcmdhd/dhd_common.c +++ /dev/null @@ -1,2471 +0,0 @@ -/* - * Broadcom Dongle Host Driver (DHD), common DHD core. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd_common.c 380760 2013-01-23 21:59:27Z $ - */ -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#ifdef WL_CFG80211 -#include -#endif -#include -#include -#ifdef SET_RANDOM_MAC_SOFTAP -#include -#include -#endif - -#ifdef PROP_TXSTATUS -#include -#include -#endif - - -#ifdef WLMEDIA_HTSF -extern void htsf_update(struct dhd_info *dhd, void *data); -#endif -int dhd_msg_level = DHD_ERROR_VAL; - - -#include - -char fw_path[MOD_PARAM_PATHLEN]; -char nv_path[MOD_PARAM_PATHLEN]; - -#ifdef SOFTAP -char fw_path2[MOD_PARAM_PATHLEN]; -extern bool softap_enabled; -#endif - -/* Last connection success/failure status */ -uint32 dhd_conn_event; -uint32 dhd_conn_status; -uint32 dhd_conn_reason; - -#define htod32(i) i -#define htod16(i) i -#define dtoh32(i) i -#define dtoh16(i) i -extern int dhd_iscan_request(void * dhdp, uint16 action); -extern void dhd_ind_scan_confirm(void *h, bool status); -extern int dhd_iscan_in_progress(void *h); -void dhd_iscan_lock(void); -void dhd_iscan_unlock(void); -extern int dhd_change_mtu(dhd_pub_t *dhd, int new_mtu, int ifidx); -bool ap_cfg_running = FALSE; -bool ap_fw_loaded = FALSE; - - -#ifdef DHD_DEBUG -const char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR "\nCompiled on " - __DATE__ " at " __TIME__; -#else -const char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR; -#endif - -void dhd_set_timer(void *bus, uint wdtick); - -/* IOVar table */ -enum { - IOV_VERSION = 1, - IOV_MSGLEVEL, - IOV_BCMERRORSTR, - IOV_BCMERROR, - IOV_WDTICK, - IOV_DUMP, - IOV_CLEARCOUNTS, - IOV_LOGDUMP, - IOV_LOGCAL, - IOV_LOGSTAMP, - IOV_GPIOOB, - IOV_IOCTLTIMEOUT, - IOV_HCI_CMD, /* HCI command */ - IOV_HCI_ACL_DATA, /* HCI data packet */ -#if defined(DHD_DEBUG) - IOV_CONS, - IOV_DCONSOLE_POLL, -#endif /* defined(DHD_DEBUG) */ -#ifdef PROP_TXSTATUS - IOV_PROPTXSTATUS_ENABLE, - IOV_PROPTXSTATUS_MODE, -#endif - IOV_BUS_TYPE, -#ifdef WLMEDIA_HTSF - IOV_WLPKTDLYSTAT_SZ, -#endif - IOV_CHANGEMTU, - IOV_LAST -}; - -const bcm_iovar_t dhd_iovars[] = { - {"version", IOV_VERSION, 0, IOVT_BUFFER, sizeof(dhd_version) }, -#ifdef DHD_DEBUG - {"msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 }, -#endif /* DHD_DEBUG */ - {"bcmerrorstr", IOV_BCMERRORSTR, 0, IOVT_BUFFER, BCME_STRLEN }, - {"bcmerror", IOV_BCMERROR, 0, IOVT_INT8, 0 }, - {"wdtick", IOV_WDTICK, 0, IOVT_UINT32, 0 }, - {"dump", IOV_DUMP, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN }, -#ifdef DHD_DEBUG - {"cons", IOV_CONS, 0, IOVT_BUFFER, 0 }, - {"dconpoll", IOV_DCONSOLE_POLL, 0, IOVT_UINT32, 0 }, -#endif - {"clearcounts", IOV_CLEARCOUNTS, 0, IOVT_VOID, 0 }, - {"gpioob", IOV_GPIOOB, 0, IOVT_UINT32, 0 }, - {"ioctl_timeout", IOV_IOCTLTIMEOUT, 0, IOVT_UINT32, 0 }, - {"HCI_cmd", IOV_HCI_CMD, 0, IOVT_BUFFER, 0}, - {"HCI_ACL_data", IOV_HCI_ACL_DATA, 0, IOVT_BUFFER, 0}, -#ifdef PROP_TXSTATUS - {"proptx", IOV_PROPTXSTATUS_ENABLE, 0, IOVT_UINT32, 0 }, - /* - set the proptxtstatus operation mode: - 0 - Do not do any proptxtstatus flow control - 1 - Use implied credit from a packet status - 2 - Use explicit credit - */ - {"ptxmode", IOV_PROPTXSTATUS_MODE, 0, IOVT_UINT32, 0 }, -#endif - {"bustype", IOV_BUS_TYPE, 0, IOVT_UINT32, 0}, -#ifdef WLMEDIA_HTSF - {"pktdlystatsz", IOV_WLPKTDLYSTAT_SZ, 0, IOVT_UINT8, 0 }, -#endif - {"changemtu", IOV_CHANGEMTU, 0, IOVT_UINT32, 0 }, - {NULL, 0, 0, 0, 0 } -}; - -struct dhd_cmn * -dhd_common_init(osl_t *osh) -{ - dhd_cmn_t *cmn; - - /* Init global variables at run-time, not as part of the declaration. - * This is required to support init/de-init of the driver. Initialization - * of globals as part of the declaration results in non-deterministic - * behavior since the value of the globals may be different on the - * first time that the driver is initialized vs subsequent initializations. - */ - /* Allocate private bus interface state */ - if (!(cmn = MALLOC(osh, sizeof(dhd_cmn_t)))) { - DHD_ERROR(("%s: MALLOC failed\n", __FUNCTION__)); - return NULL; - } - memset(cmn, 0, sizeof(dhd_cmn_t)); - cmn->osh = osh; - -#ifdef CONFIG_BCMDHD_FW_PATH - bcm_strncpy_s(fw_path, sizeof(fw_path), CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1); -#else /* CONFIG_BCMDHD_FW_PATH */ - fw_path[0] = '\0'; -#endif /* CONFIG_BCMDHD_FW_PATH */ -#ifdef CONFIG_BCMDHD_NVRAM_PATH - bcm_strncpy_s(nv_path, sizeof(nv_path), CONFIG_BCMDHD_NVRAM_PATH, MOD_PARAM_PATHLEN-1); -#else /* CONFIG_BCMDHD_NVRAM_PATH */ - nv_path[0] = '\0'; -#endif /* CONFIG_BCMDHD_NVRAM_PATH */ -#ifdef SOFTAP - fw_path2[0] = '\0'; -#endif - return cmn; -} - -void -dhd_common_deinit(dhd_pub_t *dhd_pub, dhd_cmn_t *sa_cmn) -{ - osl_t *osh; - dhd_cmn_t *cmn; - - if (dhd_pub != NULL) - cmn = dhd_pub->cmn; - else - cmn = sa_cmn; - - if (!cmn) - return; - - osh = cmn->osh; - - if (dhd_pub != NULL) - dhd_pub->cmn = NULL; - MFREE(osh, cmn, sizeof(dhd_cmn_t)); -} - -static int -dhd_dump(dhd_pub_t *dhdp, char *buf, int buflen) -{ - char eabuf[ETHER_ADDR_STR_LEN]; - - struct bcmstrbuf b; - struct bcmstrbuf *strbuf = &b; - - bcm_binit(strbuf, buf, buflen); - - /* Base DHD info */ - bcm_bprintf(strbuf, "%s\n", dhd_version); - bcm_bprintf(strbuf, "\n"); - bcm_bprintf(strbuf, "pub.up %d pub.txoff %d pub.busstate %d\n", - dhdp->up, dhdp->txoff, dhdp->busstate); - bcm_bprintf(strbuf, "pub.hdrlen %d pub.maxctl %d pub.rxsz %d\n", - dhdp->hdrlen, dhdp->maxctl, dhdp->rxsz); - bcm_bprintf(strbuf, "pub.iswl %d pub.drv_version %ld pub.mac %s\n", - dhdp->iswl, dhdp->drv_version, bcm_ether_ntoa(&dhdp->mac, eabuf)); - bcm_bprintf(strbuf, "pub.bcmerror %d tickcnt %d\n", dhdp->bcmerror, dhdp->tickcnt); - - bcm_bprintf(strbuf, "dongle stats:\n"); - bcm_bprintf(strbuf, "tx_packets %ld tx_bytes %ld tx_errors %ld tx_dropped %ld\n", - dhdp->dstats.tx_packets, dhdp->dstats.tx_bytes, - dhdp->dstats.tx_errors, dhdp->dstats.tx_dropped); - bcm_bprintf(strbuf, "rx_packets %ld rx_bytes %ld rx_errors %ld rx_dropped %ld\n", - dhdp->dstats.rx_packets, dhdp->dstats.rx_bytes, - dhdp->dstats.rx_errors, dhdp->dstats.rx_dropped); - bcm_bprintf(strbuf, "multicast %ld\n", dhdp->dstats.multicast); - - bcm_bprintf(strbuf, "bus stats:\n"); - bcm_bprintf(strbuf, "tx_packets %ld tx_multicast %ld tx_errors %ld\n", - dhdp->tx_packets, dhdp->tx_multicast, dhdp->tx_errors); - bcm_bprintf(strbuf, "tx_ctlpkts %ld tx_ctlerrs %ld\n", - dhdp->tx_ctlpkts, dhdp->tx_ctlerrs); - bcm_bprintf(strbuf, "rx_packets %ld rx_multicast %ld rx_errors %ld \n", - dhdp->rx_packets, dhdp->rx_multicast, dhdp->rx_errors); - bcm_bprintf(strbuf, "rx_ctlpkts %ld rx_ctlerrs %ld rx_dropped %ld\n", - dhdp->rx_ctlpkts, dhdp->rx_ctlerrs, dhdp->rx_dropped); - bcm_bprintf(strbuf, "rx_readahead_cnt %ld tx_realloc %ld\n", - dhdp->rx_readahead_cnt, dhdp->tx_realloc); - bcm_bprintf(strbuf, "\n"); - - /* Add any prot info */ - dhd_prot_dump(dhdp, strbuf); - bcm_bprintf(strbuf, "\n"); - - /* Add any bus info */ - dhd_bus_dump(dhdp, strbuf); - - return (!strbuf->size ? BCME_BUFTOOSHORT : 0); -} - -int -dhd_wl_ioctl_cmd(dhd_pub_t *dhd_pub, int cmd, void *arg, int len, uint8 set, int ifindex) -{ - wl_ioctl_t ioc; - - ioc.cmd = cmd; - ioc.buf = arg; - ioc.len = len; - ioc.set = set; - - return dhd_wl_ioctl(dhd_pub, ifindex, &ioc, arg, len); -} - - -int -dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifindex, wl_ioctl_t *ioc, void *buf, int len) -{ - int ret; - - dhd_os_proto_block(dhd_pub); - - ret = dhd_prot_ioctl(dhd_pub, ifindex, ioc, buf, len); - if (ret) - dhd_os_check_hang(dhd_pub, ifindex, ret); - - dhd_os_proto_unblock(dhd_pub); - return ret; -} - -static int -dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const char *name, - void *params, int plen, void *arg, int len, int val_size) -{ - int bcmerror = 0; - int32 int_val = 0; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - DHD_TRACE(("%s: actionid = %d; name %s\n", __FUNCTION__, actionid, name)); - - if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid))) != 0) - goto exit; - - if (plen >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); - - switch (actionid) { - case IOV_GVAL(IOV_VERSION): - /* Need to have checked buffer length */ - bcm_strncpy_s((char*)arg, len, dhd_version, len); - break; - - case IOV_GVAL(IOV_MSGLEVEL): - int_val = (int32)dhd_msg_level; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_MSGLEVEL): - dhd_msg_level = int_val; -#ifdef WL_CFG80211 - /* Enable DHD and WL logs in oneshot */ - if (dhd_msg_level & DHD_WL_VAL) - wl_cfg80211_enable_trace(dhd_msg_level); -#endif - break; - case IOV_GVAL(IOV_BCMERRORSTR): - bcm_strncpy_s((char *)arg, len, bcmerrorstr(dhd_pub->bcmerror), BCME_STRLEN); - ((char *)arg)[BCME_STRLEN - 1] = 0x00; - break; - - case IOV_GVAL(IOV_BCMERROR): - int_val = (int32)dhd_pub->bcmerror; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_WDTICK): - int_val = (int32)dhd_watchdog_ms; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_WDTICK): - if (!dhd_pub->up) { - bcmerror = BCME_NOTUP; - break; - } - dhd_os_wd_timer(dhd_pub, (uint)int_val); - break; - - case IOV_GVAL(IOV_DUMP): - bcmerror = dhd_dump(dhd_pub, arg, len); - break; - -#ifdef DHD_DEBUG - case IOV_GVAL(IOV_DCONSOLE_POLL): - int_val = (int32)dhd_console_ms; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DCONSOLE_POLL): - dhd_console_ms = (uint)int_val; - break; - - case IOV_SVAL(IOV_CONS): - if (len > 0) - bcmerror = dhd_bus_console_in(dhd_pub, arg, len - 1); - break; -#endif /* DHD_DEBUG */ - - case IOV_SVAL(IOV_CLEARCOUNTS): - dhd_pub->tx_packets = dhd_pub->rx_packets = 0; - dhd_pub->tx_errors = dhd_pub->rx_errors = 0; - dhd_pub->tx_ctlpkts = dhd_pub->rx_ctlpkts = 0; - dhd_pub->tx_ctlerrs = dhd_pub->rx_ctlerrs = 0; - dhd_pub->rx_dropped = 0; - dhd_pub->rx_readahead_cnt = 0; - dhd_pub->tx_realloc = 0; - dhd_pub->wd_dpc_sched = 0; - memset(&dhd_pub->dstats, 0, sizeof(dhd_pub->dstats)); - dhd_bus_clearcounts(dhd_pub); -#ifdef PROP_TXSTATUS - /* clear proptxstatus related counters */ - if (dhd_pub->wlfc_state) { - athost_wl_status_info_t *wlfc = - (athost_wl_status_info_t*)dhd_pub->wlfc_state; - wlfc_hanger_t* hanger; - - memset(&wlfc->stats, 0, sizeof(athost_wl_stat_counters_t)); - - hanger = (wlfc_hanger_t*)wlfc->hanger; - hanger->pushed = 0; - hanger->popped = 0; - hanger->failed_slotfind = 0; - hanger->failed_to_pop = 0; - hanger->failed_to_push = 0; - } -#endif /* PROP_TXSTATUS */ - break; - - - case IOV_GVAL(IOV_IOCTLTIMEOUT): { - int_val = (int32)dhd_os_get_ioctl_resp_timeout(); - bcopy(&int_val, arg, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_IOCTLTIMEOUT): { - if (int_val <= 0) - bcmerror = BCME_BADARG; - else - dhd_os_set_ioctl_resp_timeout((unsigned int)int_val); - break; - } - - case IOV_SVAL(IOV_HCI_CMD): { - amp_hci_cmd_t *cmd = (amp_hci_cmd_t *)arg; - - /* sanity check: command preamble present */ - if (len < HCI_CMD_PREAMBLE_SIZE) - return BCME_BUFTOOSHORT; - - /* sanity check: command parameters are present */ - if (len < (int)(HCI_CMD_PREAMBLE_SIZE + cmd->plen)) - return BCME_BUFTOOSHORT; - - dhd_bta_docmd(dhd_pub, cmd, len); - break; - } - - case IOV_SVAL(IOV_HCI_ACL_DATA): { - amp_hci_ACL_data_t *ACL_data = (amp_hci_ACL_data_t *)arg; - - /* sanity check: HCI header present */ - if (len < HCI_ACL_DATA_PREAMBLE_SIZE) - return BCME_BUFTOOSHORT; - - /* sanity check: ACL data is present */ - if (len < (int)(HCI_ACL_DATA_PREAMBLE_SIZE + ACL_data->dlen)) - return BCME_BUFTOOSHORT; - - dhd_bta_tx_hcidata(dhd_pub, ACL_data, len); - break; - } - -#ifdef PROP_TXSTATUS - case IOV_GVAL(IOV_PROPTXSTATUS_ENABLE): - int_val = dhd_pub->wlfc_enabled? 1 : 0; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_PROPTXSTATUS_ENABLE): - dhd_pub->wlfc_enabled = int_val? 1 : 0; - break; - - case IOV_GVAL(IOV_PROPTXSTATUS_MODE): { - athost_wl_status_info_t *wlfc = - (athost_wl_status_info_t*)dhd_pub->wlfc_state; - int_val = dhd_pub->wlfc_state ? (int32)wlfc->proptxstatus_mode : 0; - bcopy(&int_val, arg, val_size); - break; - } - - case IOV_SVAL(IOV_PROPTXSTATUS_MODE): - if (dhd_pub->wlfc_state) { - athost_wl_status_info_t *wlfc = - (athost_wl_status_info_t*)dhd_pub->wlfc_state; - wlfc->proptxstatus_mode = int_val & 0xff; - } - break; -#endif /* PROP_TXSTATUS */ - - case IOV_GVAL(IOV_BUS_TYPE): - /* The dhd application queries the driver to check if its usb or sdio. */ -#ifdef BCMDHDUSB - int_val = BUS_TYPE_USB; -#endif - int_val = BUS_TYPE_SDIO; - bcopy(&int_val, arg, val_size); - break; - - -#ifdef WLMEDIA_HTSF - case IOV_GVAL(IOV_WLPKTDLYSTAT_SZ): - int_val = dhd_pub->htsfdlystat_sz; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_WLPKTDLYSTAT_SZ): - dhd_pub->htsfdlystat_sz = int_val & 0xff; - printf("Setting tsfdlystat_sz:%d\n", dhd_pub->htsfdlystat_sz); - break; -#endif - case IOV_SVAL(IOV_CHANGEMTU): - int_val &= 0xffff; - bcmerror = dhd_change_mtu(dhd_pub, int_val, 0); - break; - - default: - bcmerror = BCME_UNSUPPORTED; - break; - } - -exit: - DHD_TRACE(("%s: actionid %d, bcmerror %d\n", __FUNCTION__, actionid, bcmerror)); - return bcmerror; -} - -/* Store the status of a connection attempt for later retrieval by an iovar */ -void -dhd_store_conn_status(uint32 event, uint32 status, uint32 reason) -{ - /* Do not overwrite a WLC_E_PRUNE with a WLC_E_SET_SSID - * because an encryption/rsn mismatch results in both events, and - * the important information is in the WLC_E_PRUNE. - */ - if (!(event == WLC_E_SET_SSID && status == WLC_E_STATUS_FAIL && - dhd_conn_event == WLC_E_PRUNE)) { - dhd_conn_event = event; - dhd_conn_status = status; - dhd_conn_reason = reason; - } -} - -bool -dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec) -{ - void *p; - int eprec = -1; /* precedence to evict from */ - bool discard_oldest; - - /* Fast case, precedence queue is not full and we are also not - * exceeding total queue length - */ - if (!pktq_pfull(q, prec) && !pktq_full(q)) { - pktq_penq(q, prec, pkt); - return TRUE; - } - - /* Determine precedence from which to evict packet, if any */ - if (pktq_pfull(q, prec)) - eprec = prec; - else if (pktq_full(q)) { - p = pktq_peek_tail(q, &eprec); - ASSERT(p); - if (eprec > prec || eprec < 0) - return FALSE; - } - - /* Evict if needed */ - if (eprec >= 0) { - /* Detect queueing to unconfigured precedence */ - ASSERT(!pktq_pempty(q, eprec)); - discard_oldest = AC_BITMAP_TST(dhdp->wme_dp, eprec); - if (eprec == prec && !discard_oldest) - return FALSE; /* refuse newer (incoming) packet */ - /* Evict packet according to discard policy */ - p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q, eprec); - ASSERT(p); - - PKTFREE(dhdp->osh, p, TRUE); - } - - /* Enqueue */ - p = pktq_penq(q, prec, pkt); - ASSERT(p); - - return TRUE; -} - -static int -dhd_iovar_op(dhd_pub_t *dhd_pub, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - int bcmerror = 0; - int val_size; - const bcm_iovar_t *vi = NULL; - uint32 actionid; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - ASSERT(name); - ASSERT(len >= 0); - - /* Get MUST have return space */ - ASSERT(set || (arg && len)); - - /* Set does NOT take qualifiers */ - ASSERT(!set || (!params && !plen)); - - if ((vi = bcm_iovar_lookup(dhd_iovars, name)) == NULL) { - bcmerror = BCME_UNSUPPORTED; - goto exit; - } - - DHD_CTL(("%s: %s %s, len %d plen %d\n", __FUNCTION__, - name, (set ? "set" : "get"), len, plen)); - - /* set up 'params' pointer in case this is a set command so that - * the convenience int and bool code can be common to set and get - */ - if (params == NULL) { - params = arg; - plen = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - /* all other types are integer sized */ - val_size = sizeof(int); - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - - bcmerror = dhd_doiovar(dhd_pub, vi, actionid, name, params, plen, arg, len, val_size); - -exit: - return bcmerror; -} - -int -dhd_ioctl(dhd_pub_t * dhd_pub, dhd_ioctl_t *ioc, void * buf, uint buflen) -{ - int bcmerror = 0; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (!buf) { - return BCME_BADARG; - } - - switch (ioc->cmd) { - case DHD_GET_MAGIC: - if (buflen < sizeof(int)) - bcmerror = BCME_BUFTOOSHORT; - else - *(int*)buf = DHD_IOCTL_MAGIC; - break; - - case DHD_GET_VERSION: - if (buflen < sizeof(int)) - bcmerror = -BCME_BUFTOOSHORT; - else - *(int*)buf = DHD_IOCTL_VERSION; - break; - - case DHD_GET_VAR: - case DHD_SET_VAR: { - char *arg; - uint arglen; - - /* scan past the name to any arguments */ - for (arg = buf, arglen = buflen; *arg && arglen; arg++, arglen--) - ; - - if (*arg) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - /* account for the NUL terminator */ - arg++, arglen--; - - /* call with the appropriate arguments */ - if (ioc->cmd == DHD_GET_VAR) - bcmerror = dhd_iovar_op(dhd_pub, buf, arg, arglen, - buf, buflen, IOV_GET); - else - bcmerror = dhd_iovar_op(dhd_pub, buf, NULL, 0, arg, arglen, IOV_SET); - if (bcmerror != BCME_UNSUPPORTED) - break; - - /* not in generic table, try protocol module */ - if (ioc->cmd == DHD_GET_VAR) - bcmerror = dhd_prot_iovar_op(dhd_pub, buf, arg, - arglen, buf, buflen, IOV_GET); - else - bcmerror = dhd_prot_iovar_op(dhd_pub, buf, - NULL, 0, arg, arglen, IOV_SET); - if (bcmerror != BCME_UNSUPPORTED) - break; - - /* if still not found, try bus module */ - if (ioc->cmd == DHD_GET_VAR) { - bcmerror = dhd_bus_iovar_op(dhd_pub, buf, - arg, arglen, buf, buflen, IOV_GET); - } else { - bcmerror = dhd_bus_iovar_op(dhd_pub, buf, - NULL, 0, arg, arglen, IOV_SET); - } - - break; - } - - default: - bcmerror = BCME_UNSUPPORTED; - } - - return bcmerror; -} - -#ifdef SHOW_EVENTS -static void -wl_show_host_event(wl_event_msg_t *event, void *event_data) -{ - uint i, status, reason; - bool group = FALSE, flush_txq = FALSE, link = FALSE; - const char *auth_str; - const char *event_name; - uchar *buf; - char err_msg[256], eabuf[ETHER_ADDR_STR_LEN]; - uint event_type, flags, auth_type, datalen; - - event_type = ntoh32(event->event_type); - flags = ntoh16(event->flags); - status = ntoh32(event->status); - reason = ntoh32(event->reason); - auth_type = ntoh32(event->auth_type); - datalen = ntoh32(event->datalen); - - /* debug dump of event messages */ - sprintf(eabuf, "%02x:%02x:%02x:%02x:%02x:%02x", - (uchar)event->addr.octet[0]&0xff, - (uchar)event->addr.octet[1]&0xff, - (uchar)event->addr.octet[2]&0xff, - (uchar)event->addr.octet[3]&0xff, - (uchar)event->addr.octet[4]&0xff, - (uchar)event->addr.octet[5]&0xff); - - event_name = "UNKNOWN"; - for (i = 0; i < (uint)bcmevent_names_size; i++) - if (bcmevent_names[i].event == event_type) - event_name = bcmevent_names[i].name; - - if (flags & WLC_EVENT_MSG_LINK) - link = TRUE; - if (flags & WLC_EVENT_MSG_GROUP) - group = TRUE; - if (flags & WLC_EVENT_MSG_FLUSHTXQ) - flush_txq = TRUE; - - switch (event_type) { - case WLC_E_START: - case WLC_E_DEAUTH: - case WLC_E_DISASSOC: - DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); - break; - - case WLC_E_ASSOC_IND: - case WLC_E_REASSOC_IND: - - DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); - break; - - case WLC_E_ASSOC: - case WLC_E_REASSOC: - if (status == WLC_E_STATUS_SUCCESS) { - DHD_EVENT(("MACEVENT: %s, MAC %s, SUCCESS\n", event_name, eabuf)); - } else if (status == WLC_E_STATUS_TIMEOUT) { - DHD_EVENT(("MACEVENT: %s, MAC %s, TIMEOUT\n", event_name, eabuf)); - } else if (status == WLC_E_STATUS_FAIL) { - DHD_EVENT(("MACEVENT: %s, MAC %s, FAILURE, reason %d\n", - event_name, eabuf, (int)reason)); - } else { - DHD_EVENT(("MACEVENT: %s, MAC %s, unexpected status %d\n", - event_name, eabuf, (int)status)); - } - break; - - case WLC_E_DEAUTH_IND: - case WLC_E_DISASSOC_IND: - DHD_EVENT(("MACEVENT: %s, MAC %s, reason %d\n", event_name, eabuf, (int)reason)); - break; - - case WLC_E_AUTH: - case WLC_E_AUTH_IND: - if (auth_type == DOT11_OPEN_SYSTEM) - auth_str = "Open System"; - else if (auth_type == DOT11_SHARED_KEY) - auth_str = "Shared Key"; - else { - sprintf(err_msg, "AUTH unknown: %d", (int)auth_type); - auth_str = err_msg; - } - if (event_type == WLC_E_AUTH_IND) { - DHD_EVENT(("MACEVENT: %s, MAC %s, %s\n", event_name, eabuf, auth_str)); - } else if (status == WLC_E_STATUS_SUCCESS) { - DHD_EVENT(("MACEVENT: %s, MAC %s, %s, SUCCESS\n", - event_name, eabuf, auth_str)); - } else if (status == WLC_E_STATUS_TIMEOUT) { - DHD_EVENT(("MACEVENT: %s, MAC %s, %s, TIMEOUT\n", - event_name, eabuf, auth_str)); - } else if (status == WLC_E_STATUS_FAIL) { - DHD_EVENT(("MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n", - event_name, eabuf, auth_str, (int)reason)); - } - - break; - - case WLC_E_JOIN: - case WLC_E_ROAM: - case WLC_E_SET_SSID: - if (status == WLC_E_STATUS_SUCCESS) { - DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); - } else if (status == WLC_E_STATUS_FAIL) { - DHD_EVENT(("MACEVENT: %s, failed\n", event_name)); - } else if (status == WLC_E_STATUS_NO_NETWORKS) { - DHD_EVENT(("MACEVENT: %s, no networks found\n", event_name)); - } else { - DHD_EVENT(("MACEVENT: %s, unexpected status %d\n", - event_name, (int)status)); - } - break; - - case WLC_E_BEACON_RX: - if (status == WLC_E_STATUS_SUCCESS) { - DHD_EVENT(("MACEVENT: %s, SUCCESS\n", event_name)); - } else if (status == WLC_E_STATUS_FAIL) { - DHD_EVENT(("MACEVENT: %s, FAIL\n", event_name)); - } else { - DHD_EVENT(("MACEVENT: %s, status %d\n", event_name, status)); - } - break; - - case WLC_E_LINK: - DHD_EVENT(("MACEVENT: %s %s\n", event_name, link?"UP":"DOWN")); - break; - - case WLC_E_MIC_ERROR: - DHD_EVENT(("MACEVENT: %s, MAC %s, Group %d, Flush %d\n", - event_name, eabuf, group, flush_txq)); - break; - - case WLC_E_ICV_ERROR: - case WLC_E_UNICAST_DECODE_ERROR: - case WLC_E_MULTICAST_DECODE_ERROR: - DHD_EVENT(("MACEVENT: %s, MAC %s\n", - event_name, eabuf)); - break; - - case WLC_E_TXFAIL: - DHD_EVENT(("MACEVENT: %s, RA %s\n", event_name, eabuf)); - break; - - case WLC_E_SCAN_COMPLETE: - case WLC_E_ASSOC_REQ_IE: - case WLC_E_ASSOC_RESP_IE: - case WLC_E_PMKID_CACHE: - DHD_EVENT(("MACEVENT: %s\n", event_name)); - break; - - case WLC_E_PFN_NET_FOUND: - case WLC_E_PFN_NET_LOST: - case WLC_E_PFN_SCAN_COMPLETE: - case WLC_E_PFN_SCAN_NONE: - case WLC_E_PFN_SCAN_ALLGONE: - DHD_EVENT(("PNOEVENT: %s\n", event_name)); - break; - - case WLC_E_PSK_SUP: - case WLC_E_PRUNE: - DHD_EVENT(("MACEVENT: %s, status %d, reason %d\n", - event_name, (int)status, (int)reason)); - break; - -#ifdef WIFI_ACT_FRAME - case WLC_E_ACTION_FRAME: - DHD_TRACE(("MACEVENT: %s Bssid %s\n", event_name, eabuf)); - break; -#endif /* WIFI_ACT_FRAME */ - - case WLC_E_TRACE: { - static uint32 seqnum_prev = 0; - msgtrace_hdr_t hdr; - uint32 nblost; - char *s, *p; - - buf = (uchar *) event_data; - memcpy(&hdr, buf, MSGTRACE_HDRLEN); - - if (hdr.version != MSGTRACE_VERSION) { - printf("\nMACEVENT: %s [unsupported version --> " - "dhd version:%d dongle version:%d]\n", - event_name, MSGTRACE_VERSION, hdr.version); - /* Reset datalen to avoid display below */ - datalen = 0; - break; - } - - /* There are 2 bytes available at the end of data */ - buf[MSGTRACE_HDRLEN + ntoh16(hdr.len)] = '\0'; - - if (ntoh32(hdr.discarded_bytes) || ntoh32(hdr.discarded_printf)) { - printf("\nWLC_E_TRACE: [Discarded traces in dongle -->" - "discarded_bytes %d discarded_printf %d]\n", - ntoh32(hdr.discarded_bytes), ntoh32(hdr.discarded_printf)); - } - - nblost = ntoh32(hdr.seqnum) - seqnum_prev - 1; - if (nblost > 0) { - printf("\nWLC_E_TRACE: [Event lost --> seqnum %d nblost %d\n", - ntoh32(hdr.seqnum), nblost); - } - seqnum_prev = ntoh32(hdr.seqnum); - - /* Display the trace buffer. Advance from \n to \n to avoid display big - * printf (issue with Linux printk ) - */ - p = (char *)&buf[MSGTRACE_HDRLEN]; - while ((s = strstr(p, "\n")) != NULL) { - *s = '\0'; - printf("%s\n", p); - p = s+1; - } - printf("%s\n", p); - - /* Reset datalen to avoid display below */ - datalen = 0; - break; - } - - - case WLC_E_RSSI: - DHD_EVENT(("MACEVENT: %s %d\n", event_name, ntoh32(*((int *)event_data)))); - break; - - default: - DHD_EVENT(("MACEVENT: %s %d, MAC %s, status %d, reason %d, auth %d\n", - event_name, event_type, eabuf, (int)status, (int)reason, - (int)auth_type)); - break; - } - - /* show any appended data */ - if (datalen) { - buf = (uchar *) event_data; - DHD_EVENT((" data (%d) : ", datalen)); - for (i = 0; i < datalen; i++) - DHD_EVENT((" 0x%02x ", *buf++)); - DHD_EVENT(("\n")); - } -} -#endif /* SHOW_EVENTS */ - -int -wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, - wl_event_msg_t *event, void **data_ptr) -{ - /* check whether packet is a BRCM event pkt */ - bcm_event_t *pvt_data = (bcm_event_t *)pktdata; - uint8 *event_data; - uint32 type, status, reason, datalen; - uint16 flags; - int evlen; - - if (bcmp(BRCM_OUI, &pvt_data->bcm_hdr.oui[0], DOT11_OUI_LEN)) { - DHD_ERROR(("%s: mismatched OUI, bailing\n", __FUNCTION__)); - return (BCME_ERROR); - } - - /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */ - if (ntoh16_ua((void *)&pvt_data->bcm_hdr.usr_subtype) != BCMILCP_BCM_SUBTYPE_EVENT) { - DHD_ERROR(("%s: mismatched subtype, bailing\n", __FUNCTION__)); - return (BCME_ERROR); - } - - *data_ptr = &pvt_data[1]; - event_data = *data_ptr; - - /* memcpy since BRCM event pkt may be unaligned. */ - memcpy(event, &pvt_data->event, sizeof(wl_event_msg_t)); - - type = ntoh32_ua((void *)&event->event_type); - flags = ntoh16_ua((void *)&event->flags); - status = ntoh32_ua((void *)&event->status); - reason = ntoh32_ua((void *)&event->reason); - datalen = ntoh32_ua((void *)&event->datalen); - evlen = datalen + sizeof(bcm_event_t); - - DHD_TRACE(("RX: event_type:%d flags:%d status:%d reason:%d \n", - type, flags, status, reason)); - - switch (type) { -#ifdef PROP_TXSTATUS - case WLC_E_FIFO_CREDIT_MAP: - dhd_wlfc_event(dhd_pub->info); - dhd_wlfc_FIFOcreditmap_event(dhd_pub->info, event_data); - WLFC_DBGMESG(("WLC_E_FIFO_CREDIT_MAP:(AC0,AC1,AC2,AC3),(BC_MC),(OTHER): " - "(%d,%d,%d,%d),(%d),(%d)\n", event_data[0], event_data[1], - event_data[2], - event_data[3], event_data[4], event_data[5])); - break; -#endif - - case WLC_E_IF: - { - dhd_if_event_t *ifevent = (dhd_if_event_t *)event_data; -#ifdef PROP_TXSTATUS - { - uint8* ea = pvt_data->eth.ether_dhost; - WLFC_DBGMESG(("WLC_E_IF: idx:%d, action:%s, iftype:%s, " - "[%02x:%02x:%02x:%02x:%02x:%02x]\n", - ifevent->ifidx, - ((ifevent->action == WLC_E_IF_ADD) ? "ADD":"DEL"), - ((ifevent->is_AP == 0) ? "STA":"AP "), - ea[0], ea[1], ea[2], ea[3], ea[4], ea[5])); - (void)ea; - - dhd_wlfc_interface_event(dhd_pub->info, - ((ifevent->action == WLC_E_IF_ADD) ? - eWLFC_MAC_ENTRY_ACTION_ADD : eWLFC_MAC_ENTRY_ACTION_DEL), - ifevent->ifidx, ifevent->is_AP, ea); - - /* dhd already has created an interface by default, for 0 */ - if (ifevent->ifidx == 0) - break; - } -#endif /* PROP_TXSTATUS */ - -#ifdef WL_CFG80211 - if (wl_cfg80211_is_progress_ifchange()) { - DHD_ERROR(("%s: ifidx %d for %s action %d\n", - __FUNCTION__, ifevent->ifidx, - event->ifname, ifevent->action)); - if (ifevent->action == WLC_E_IF_ADD) - wl_cfg80211_notify_ifchange(); - return (BCME_OK); - } -#endif /* WL_CFG80211 */ - if (ifevent->ifidx > 0 && ifevent->ifidx < DHD_MAX_IFS) { - if (ifevent->action == WLC_E_IF_ADD) { - if (dhd_add_if(dhd_pub->info, ifevent->ifidx, - NULL, event->ifname, - event->addr.octet, - ifevent->flags, ifevent->bssidx)) { - DHD_ERROR(("%s: dhd_add_if failed!!" - " ifidx: %d for %s\n", - __FUNCTION__, - ifevent->ifidx, - event->ifname)); - return (BCME_ERROR); - } - } - else - dhd_del_if(dhd_pub->info, ifevent->ifidx); - } else { -#ifndef PROP_TXSTATUS - DHD_ERROR(("%s: Invalid ifidx %d for %s\n", - __FUNCTION__, ifevent->ifidx, event->ifname)); -#endif /* !PROP_TXSTATUS */ - } - } - /* send up the if event: btamp user needs it */ - *ifidx = dhd_ifname2idx(dhd_pub->info, event->ifname); - /* push up to external supp/auth */ - dhd_event(dhd_pub->info, (char *)pvt_data, evlen, *ifidx); - break; - - -#ifdef WLMEDIA_HTSF - case WLC_E_HTSFSYNC: - htsf_update(dhd_pub->info, event_data); - break; -#endif /* WLMEDIA_HTSF */ - case WLC_E_NDIS_LINK: { - uint32 temp = hton32(WLC_E_LINK); - - memcpy((void *)(&pvt_data->event.event_type), &temp, - sizeof(pvt_data->event.event_type)); - } - /* These are what external supplicant/authenticator wants */ - /* fall through */ - case WLC_E_LINK: - case WLC_E_DEAUTH: - case WLC_E_DEAUTH_IND: - case WLC_E_DISASSOC: - case WLC_E_DISASSOC_IND: - DHD_EVENT(("%s: Link event %d, flags %x, status %x\n", - __FUNCTION__, type, flags, status)); - /* fall through */ - default: - *ifidx = dhd_ifname2idx(dhd_pub->info, event->ifname); - /* push up to external supp/auth */ - dhd_event(dhd_pub->info, (char *)pvt_data, evlen, *ifidx); - DHD_TRACE(("%s: MAC event %d, flags %x, status %x\n", - __FUNCTION__, type, flags, status)); - - /* put it back to WLC_E_NDIS_LINK */ - if (type == WLC_E_NDIS_LINK) { - uint32 temp; - - temp = ntoh32_ua((void *)&event->event_type); - DHD_TRACE(("Converted to WLC_E_LINK type %d\n", temp)); - - temp = ntoh32(WLC_E_NDIS_LINK); - memcpy((void *)(&pvt_data->event.event_type), &temp, - sizeof(pvt_data->event.event_type)); - } - break; - } - -#ifdef SHOW_EVENTS - wl_show_host_event(event, (void *)event_data); -#endif /* SHOW_EVENTS */ - - return (BCME_OK); -} - -void -wl_event_to_host_order(wl_event_msg_t * evt) -{ - /* Event struct members passed from dongle to host are stored in network - * byte order. Convert all members to host-order. - */ - evt->event_type = ntoh32(evt->event_type); - evt->flags = ntoh16(evt->flags); - evt->status = ntoh32(evt->status); - evt->reason = ntoh32(evt->reason); - evt->auth_type = ntoh32(evt->auth_type); - evt->datalen = ntoh32(evt->datalen); - evt->version = ntoh16(evt->version); -} - -void -dhd_print_buf(void *pbuf, int len, int bytes_per_line) -{ -#ifdef DHD_DEBUG - int i, j = 0; - unsigned char *buf = pbuf; - - if (bytes_per_line == 0) { - bytes_per_line = len; - } - - for (i = 0; i < len; i++) { - printf("%2.2x", *buf++); - j++; - if (j == bytes_per_line) { - printf("\n"); - j = 0; - } else { - printf(":"); - } - } - printf("\n"); -#endif /* DHD_DEBUG */ -} - -#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) - -/* Convert user's input in hex pattern to byte-size mask */ -static int -wl_pattern_atoh(char *src, char *dst) -{ - int i; - if (strncmp(src, "0x", 2) != 0 && - strncmp(src, "0X", 2) != 0) { - DHD_ERROR(("Mask invalid format. Needs to start with 0x\n")); - return -1; - } - src = src + 2; /* Skip past 0x */ - if (strlen(src) % 2 != 0) { - DHD_ERROR(("Mask invalid format. Needs to be of even length\n")); - return -1; - } - for (i = 0; *src != '\0'; i++) { - char num[3]; - bcm_strncpy_s(num, sizeof(num), src, 2); - num[2] = '\0'; - dst[i] = (uint8)strtoul(num, NULL, 16); - src += 2; - } - return i; -} - -void -dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode) -{ - char *argv[8]; - int i = 0; - const char *str; - int buf_len; - int str_len; - char *arg_save = 0, *arg_org = 0; - int rc; - char buf[128]; - wl_pkt_filter_enable_t enable_parm; - wl_pkt_filter_enable_t * pkt_filterp; - - if (!arg) - return; - - if (!(arg_save = MALLOC(dhd->osh, strlen(arg) + 1))) { - DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - goto fail; - } - arg_org = arg_save; - memcpy(arg_save, arg, strlen(arg) + 1); - - argv[i] = bcmstrtok(&arg_save, " ", 0); - - i = 0; - if (argv[i] == NULL) { - DHD_ERROR(("No args provided\n")); - goto fail; - } - - str = "pkt_filter_enable"; - str_len = strlen(str); - bcm_strncpy_s(buf, sizeof(buf), str, str_len); - buf[str_len] = '\0'; - buf_len = str_len + 1; - - pkt_filterp = (wl_pkt_filter_enable_t *)(buf + str_len + 1); - - /* Parse packet filter id. */ - enable_parm.id = htod32(strtoul(argv[i], NULL, 0)); - - /* Parse enable/disable value. */ - enable_parm.enable = htod32(enable); - - buf_len += sizeof(enable_parm); - memcpy((char *)pkt_filterp, - &enable_parm, - sizeof(enable_parm)); - - /* Enable/disable the specified filter. */ - rc = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, buf_len, TRUE, 0); - rc = rc >= 0 ? 0 : rc; - if (rc) - DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", - __FUNCTION__, arg, rc)); - else - DHD_TRACE(("%s: successfully added pktfilter %s\n", - __FUNCTION__, arg)); - - /* Contorl the master mode */ - bcm_mkiovar("pkt_filter_mode", (char *)&master_mode, 4, buf, sizeof(buf)); - rc = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0); - rc = rc >= 0 ? 0 : rc; - if (rc) - DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", - __FUNCTION__, arg, rc)); - -fail: - if (arg_org) - MFREE(dhd->osh, arg_org, strlen(arg) + 1); -} - -void -dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg) -{ - const char *str; - wl_pkt_filter_t pkt_filter; - wl_pkt_filter_t *pkt_filterp; - int buf_len; - int str_len; - int rc; - uint32 mask_size; - uint32 pattern_size; - char *argv[8], * buf = 0; - int i = 0; - char *arg_save = 0, *arg_org = 0; -#define BUF_SIZE 2048 - - if (!arg) - return; - - if (!(arg_save = MALLOC(dhd->osh, strlen(arg) + 1))) { - DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - goto fail; - } - - arg_org = arg_save; - - if (!(buf = MALLOC(dhd->osh, BUF_SIZE))) { - DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - goto fail; - } - - memcpy(arg_save, arg, strlen(arg) + 1); - - if (strlen(arg) > BUF_SIZE) { - DHD_ERROR(("Not enough buffer %d < %d\n", (int)strlen(arg), (int)sizeof(buf))); - goto fail; - } - - argv[i] = bcmstrtok(&arg_save, " ", 0); - while (argv[i++]) - argv[i] = bcmstrtok(&arg_save, " ", 0); - - i = 0; - if (argv[i] == NULL) { - DHD_ERROR(("No args provided\n")); - goto fail; - } - - str = "pkt_filter_add"; - str_len = strlen(str); - bcm_strncpy_s(buf, BUF_SIZE, str, str_len); - buf[ str_len ] = '\0'; - buf_len = str_len + 1; - - pkt_filterp = (wl_pkt_filter_t *) (buf + str_len + 1); - - /* Parse packet filter id. */ - pkt_filter.id = htod32(strtoul(argv[i], NULL, 0)); - - if (argv[++i] == NULL) { - DHD_ERROR(("Polarity not provided\n")); - goto fail; - } - - /* Parse filter polarity. */ - pkt_filter.negate_match = htod32(strtoul(argv[i], NULL, 0)); - - if (argv[++i] == NULL) { - DHD_ERROR(("Filter type not provided\n")); - goto fail; - } - - /* Parse filter type. */ - pkt_filter.type = htod32(strtoul(argv[i], NULL, 0)); - - if (argv[++i] == NULL) { - DHD_ERROR(("Offset not provided\n")); - goto fail; - } - - /* Parse pattern filter offset. */ - pkt_filter.u.pattern.offset = htod32(strtoul(argv[i], NULL, 0)); - - if (argv[++i] == NULL) { - DHD_ERROR(("Bitmask not provided\n")); - goto fail; - } - - /* Parse pattern filter mask. */ - mask_size = - htod32(wl_pattern_atoh(argv[i], (char *) pkt_filterp->u.pattern.mask_and_pattern)); - - if (argv[++i] == NULL) { - DHD_ERROR(("Pattern not provided\n")); - goto fail; - } - - /* Parse pattern filter pattern. */ - pattern_size = - htod32(wl_pattern_atoh(argv[i], - (char *) &pkt_filterp->u.pattern.mask_and_pattern[mask_size])); - - if (mask_size != pattern_size) { - DHD_ERROR(("Mask and pattern not the same size\n")); - goto fail; - } - - pkt_filter.u.pattern.size_bytes = mask_size; - buf_len += WL_PKT_FILTER_FIXED_LEN; - buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size); - - /* Keep-alive attributes are set in local variable (keep_alive_pkt), and - ** then memcpy'ed into buffer (keep_alive_pktp) since there is no - ** guarantee that the buffer is properly aligned. - */ - memcpy((char *)pkt_filterp, - &pkt_filter, - WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN); - - rc = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, buf_len, TRUE, 0); - rc = rc >= 0 ? 0 : rc; - - if (rc) - DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", - __FUNCTION__, arg, rc)); - else - DHD_TRACE(("%s: successfully added pktfilter %s\n", - __FUNCTION__, arg)); - -fail: - if (arg_org) - MFREE(dhd->osh, arg_org, strlen(arg) + 1); - - if (buf) - MFREE(dhd->osh, buf, BUF_SIZE); -} - -/* ========================== */ -/* ==== ARP OFFLOAD SUPPORT = */ -/* ========================== */ -#ifdef ARP_OFFLOAD_SUPPORT -void -dhd_arp_offload_set(dhd_pub_t * dhd, int arp_mode) -{ - char iovbuf[32]; - int retcode; - - bcm_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf)); - retcode = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - retcode = retcode >= 0 ? 0 : retcode; - if (retcode) - DHD_TRACE(("%s: failed to set ARP offload mode to 0x%x, retcode = %d\n", - __FUNCTION__, arp_mode, retcode)); - else - DHD_TRACE(("%s: successfully set ARP offload mode to 0x%x\n", - __FUNCTION__, arp_mode)); -} - -void -dhd_arp_offload_enable(dhd_pub_t * dhd, int arp_enable) -{ - char iovbuf[32]; - int retcode; - - bcm_mkiovar("arpoe", (char *)&arp_enable, 4, iovbuf, sizeof(iovbuf)); - retcode = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - retcode = retcode >= 0 ? 0 : retcode; - if (retcode) - DHD_TRACE(("%s: failed to enabe ARP offload to %d, retcode = %d\n", - __FUNCTION__, arp_enable, retcode)); - else - DHD_TRACE(("%s: successfully enabed ARP offload to %d\n", - __FUNCTION__, arp_enable)); -} - -void -dhd_aoe_arp_clr(dhd_pub_t *dhd) -{ - int ret = 0; - int iov_len = 0; - char iovbuf[128]; - - if (dhd == NULL) return; - - iov_len = bcm_mkiovar("arp_table_clear", 0, 0, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, 0) < 0)) - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); -} - -void -dhd_aoe_hostip_clr(dhd_pub_t *dhd) -{ - int ret = 0; - int iov_len = 0; - char iovbuf[128]; - - if (dhd == NULL) return; - - iov_len = bcm_mkiovar("arp_hostip_clear", 0, 0, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, 0)) < 0) - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); -} - -void -dhd_arp_offload_add_ip(dhd_pub_t *dhd, uint32 ipaddr) -{ - int iov_len = 0; - char iovbuf[32]; - int retcode; - - iov_len = bcm_mkiovar("arp_hostip", (char *)&ipaddr, 4, iovbuf, sizeof(iovbuf)); - retcode = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, 0); - - if (retcode) - DHD_TRACE(("%s: ARP ip addr add failed, retcode = %d\n", - __FUNCTION__, retcode)); - else - DHD_TRACE(("%s: sARP H ipaddr entry added \n", - __FUNCTION__)); -} - -int -dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen) -{ - int retcode, i; - int iov_len = 0; - uint32 *ptr32 = buf; - bool clr_bottom = FALSE; - - if (!buf) - return -1; - - iov_len = bcm_mkiovar("arp_hostip", 0, 0, buf, buflen); - retcode = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, buflen, FALSE, 0); - - if (retcode) { - DHD_TRACE(("%s: ioctl WLC_GET_VAR error %d\n", - __FUNCTION__, retcode)); - - return -1; - } - - /* clean up the buf, ascii reminder */ - for (i = 0; i < MAX_IPV4_ENTRIES; i++) { - if (!clr_bottom) { - if (*ptr32 == 0) - clr_bottom = TRUE; - } else { - *ptr32 = 0; - } - ptr32++; - } - - return 0; -} -#endif /* ARP_OFFLOAD_SUPPORT */ - -/* send up locally generated event */ -void -dhd_sendup_event_common(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data) -{ - switch (ntoh32(event->event_type)) { - case WLC_E_BTA_HCI_EVENT: - break; - default: - break; - } - - /* Call per-port handler. */ - dhd_sendup_event(dhdp, event, data); -} - -#ifdef SIMPLE_ISCAN - -uint iscan_thread_id = 0; -iscan_buf_t * iscan_chain = 0; - -iscan_buf_t * -dhd_iscan_allocate_buf(dhd_pub_t *dhd, iscan_buf_t **iscanbuf) -{ - iscan_buf_t *iscanbuf_alloc = 0; - iscan_buf_t *iscanbuf_head; - - DHD_ISCAN(("%s: Entered\n", __FUNCTION__)); - dhd_iscan_lock(); - - iscanbuf_alloc = (iscan_buf_t*)MALLOC(dhd->osh, sizeof(iscan_buf_t)); - if (iscanbuf_alloc == NULL) - goto fail; - - iscanbuf_alloc->next = NULL; - iscanbuf_head = *iscanbuf; - - DHD_ISCAN(("%s: addr of allocated node = 0x%X" - "addr of iscanbuf_head = 0x%X dhd = 0x%X\n", - __FUNCTION__, iscanbuf_alloc, iscanbuf_head, dhd)); - - if (iscanbuf_head == NULL) { - *iscanbuf = iscanbuf_alloc; - DHD_ISCAN(("%s: Head is allocated\n", __FUNCTION__)); - goto fail; - } - - while (iscanbuf_head->next) - iscanbuf_head = iscanbuf_head->next; - - iscanbuf_head->next = iscanbuf_alloc; - -fail: - dhd_iscan_unlock(); - return iscanbuf_alloc; -} - -void -dhd_iscan_free_buf(void *dhdp, iscan_buf_t *iscan_delete) -{ - iscan_buf_t *iscanbuf_free = 0; - iscan_buf_t *iscanbuf_prv = 0; - iscan_buf_t *iscanbuf_cur; - dhd_pub_t *dhd = dhd_bus_pub(dhdp); - DHD_ISCAN(("%s: Entered\n", __FUNCTION__)); - - dhd_iscan_lock(); - - iscanbuf_cur = iscan_chain; - - /* If iscan_delete is null then delete the entire - * chain or else delete specific one provided - */ - if (!iscan_delete) { - while (iscanbuf_cur) { - iscanbuf_free = iscanbuf_cur; - iscanbuf_cur = iscanbuf_cur->next; - iscanbuf_free->next = 0; - MFREE(dhd->osh, iscanbuf_free, sizeof(iscan_buf_t)); - } - iscan_chain = 0; - } else { - while (iscanbuf_cur) { - if (iscanbuf_cur == iscan_delete) - break; - iscanbuf_prv = iscanbuf_cur; - iscanbuf_cur = iscanbuf_cur->next; - } - if (iscanbuf_prv) - iscanbuf_prv->next = iscan_delete->next; - - iscan_delete->next = 0; - MFREE(dhd->osh, iscan_delete, sizeof(iscan_buf_t)); - - if (!iscanbuf_prv) - iscan_chain = 0; - } - dhd_iscan_unlock(); -} - -iscan_buf_t * -dhd_iscan_result_buf(void) -{ - return iscan_chain; -} - -int -dhd_iscan_issue_request(void * dhdp, wl_iscan_params_t *pParams, uint32 size) -{ - int rc = -1; - dhd_pub_t *dhd = dhd_bus_pub(dhdp); - char *buf; - char iovar[] = "iscan"; - uint32 allocSize = 0; - wl_ioctl_t ioctl; - - if (pParams) { - allocSize = (size + strlen(iovar) + 1); - if ((allocSize < size) || (allocSize < strlen(iovar))) - { - DHD_ERROR(("%s: overflow - allocation size too large %d < %d + %d!\n", - __FUNCTION__, allocSize, size, strlen(iovar))); - goto cleanUp; - } - buf = MALLOC(dhd->osh, allocSize); - - if (buf == NULL) - { - DHD_ERROR(("%s: malloc of size %d failed!\n", __FUNCTION__, allocSize)); - goto cleanUp; - } - ioctl.cmd = WLC_SET_VAR; - bcm_mkiovar(iovar, (char *)pParams, size, buf, allocSize); - rc = dhd_wl_ioctl(dhd, 0, &ioctl, buf, allocSize); - } - -cleanUp: - if (buf) { - MFREE(dhd->osh, buf, allocSize); - } - - return rc; -} - -static int -dhd_iscan_get_partial_result(void *dhdp, uint *scan_count) -{ - wl_iscan_results_t *list_buf; - wl_iscan_results_t list; - wl_scan_results_t *results; - iscan_buf_t *iscan_cur; - int status = -1; - dhd_pub_t *dhd = dhd_bus_pub(dhdp); - int rc; - wl_ioctl_t ioctl; - - DHD_ISCAN(("%s: Enter\n", __FUNCTION__)); - - iscan_cur = dhd_iscan_allocate_buf(dhd, &iscan_chain); - if (!iscan_cur) { - DHD_ERROR(("%s: Failed to allocate node\n", __FUNCTION__)); - dhd_iscan_free_buf(dhdp, 0); - dhd_iscan_request(dhdp, WL_SCAN_ACTION_ABORT); - dhd_ind_scan_confirm(dhdp, FALSE); - goto fail; - } - - dhd_iscan_lock(); - - memset(iscan_cur->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN); - list_buf = (wl_iscan_results_t*)iscan_cur->iscan_buf; - results = &list_buf->results; - results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE; - results->version = 0; - results->count = 0; - - memset(&list, 0, sizeof(list)); - list.results.buflen = htod32(WLC_IW_ISCAN_MAXLEN); - bcm_mkiovar("iscanresults", (char *)&list, WL_ISCAN_RESULTS_FIXED_SIZE, - iscan_cur->iscan_buf, WLC_IW_ISCAN_MAXLEN); - ioctl.cmd = WLC_GET_VAR; - ioctl.set = FALSE; - rc = dhd_wl_ioctl(dhd, 0, &ioctl, iscan_cur->iscan_buf, WLC_IW_ISCAN_MAXLEN); - - results->buflen = dtoh32(results->buflen); - results->version = dtoh32(results->version); - *scan_count = results->count = dtoh32(results->count); - status = dtoh32(list_buf->status); - DHD_ISCAN(("%s: Got %d resuls status = (%x)\n", __FUNCTION__, results->count, status)); - - dhd_iscan_unlock(); - - if (!(*scan_count)) { - /* TODO: race condition when FLUSH already called */ - dhd_iscan_free_buf(dhdp, 0); - } -fail: - return status; -} - -#endif /* SIMPLE_ISCAN */ - -/* - * returns = TRUE if associated, FALSE if not associated - * third paramter retval can return error from error - */ -bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf, int *retval) -{ - char bssid[6], zbuf[6]; - int ret; - - bzero(bssid, 6); - bzero(zbuf, 6); - - ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_BSSID, (char *)&bssid, ETHER_ADDR_LEN, FALSE, 0); - DHD_TRACE((" %s WLC_GET_BSSID ioctl res = %d\n", __FUNCTION__, ret)); - - if (retval) - *retval = ret; - - if (ret == BCME_NOTASSOCIATED) { - DHD_TRACE(("%s: not associated! res:%d\n", __FUNCTION__, ret)); - } - - if (ret < 0) - return FALSE; - - if ((memcmp(bssid, zbuf, ETHER_ADDR_LEN) != 0)) { - /* STA is assocoated BSSID is non zero */ - - if (bss_buf) { - /* return bss if caller provided buf */ - memcpy(bss_buf, bssid, ETHER_ADDR_LEN); - } - return TRUE; - } else { - DHD_TRACE(("%s: WLC_GET_BSSID ioctl returned zero bssid\n", __FUNCTION__)); - return FALSE; - } -} - -/* Function to estimate possible DTIM_SKIP value */ -int -dhd_get_dtim_skip(dhd_pub_t *dhd) -{ - int bcn_li_dtim = 1; - char buf[128]; - int ret = -1; - int dtim_assoc = 0; - int ap_beacon = 0; - - /* Check if associated */ - if (dhd_is_associated(dhd, NULL, NULL) == FALSE) { - DHD_TRACE(("%s NOT assoc ret %d\n", __FUNCTION__, ret)); - goto exit; - } - - /* read AP beacon if do nother if APs Beacon more that 100msec */ - bcm_mkiovar("bi_assoc", 0, 0, buf, sizeof(buf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), FALSE, 0)) < 0) { - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); - goto exit; - } - - ap_beacon = dtoh32(*(int *)buf); - - /* if APs Beacon more that 100msec do no dtim skip */ - if (ap_beacon > 100) { - DHD_ERROR(("%s no dtim skip for AP with %d beacon\n", __FUNCTION__, ap_beacon)); - goto exit; - } - - - /* Read DTIM value if associated */ - memset(buf, 0, sizeof(buf)); - bcm_mkiovar("dtim_assoc", 0, 0, buf, sizeof(buf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), FALSE, 0)) < 0) { - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); - goto exit; - } - - dtim_assoc = dtoh32(*(int *)buf); - - DHD_ERROR(("%s beacom=%d msec bcn_li_dtim=%d DTIM=%d Listen=%d\n", - __FUNCTION__, ap_beacon, bcn_li_dtim, dtim_assoc, LISTEN_INTERVAL)); - - /* if not assocated just eixt */ - if (dtim_assoc == 0) { - goto exit; - } - - /* check if sta listen interval fits into AP dtim */ - if (dtim_assoc > LISTEN_INTERVAL) { - /* AP DTIM to big for our Listen Interval : no dtim skiping */ - DHD_ERROR(("%s DTIM=%d > Listen=%d : too big ...\n", - __FUNCTION__, dtim_assoc, LISTEN_INTERVAL)); - goto exit; - } - - if ((dhd->dtim_skip == 0) || (dhd->dtim_skip == 1)) - bcn_li_dtim = 3; - else - bcn_li_dtim = dhd->dtim_skip; - - if ((bcn_li_dtim * dtim_assoc) > LISTEN_INTERVAL) { - /* Round up dtim_skip to fit into STAs Listen Interval */ - bcn_li_dtim = (int)(LISTEN_INTERVAL / dtim_assoc); - DHD_TRACE(("%s agjust dtim_skip as %d\n", __FUNCTION__, bcn_li_dtim)); - } - -exit: - return bcn_li_dtim; -} - -/* Check if HostAPD or WFD mode setup */ -bool dhd_check_ap_wfd_mode_set(dhd_pub_t *dhd) -{ -#ifdef WL_CFG80211 -#ifndef WL_ENABLE_P2P_IF - /* To be back compatble with ICS MR1 release where p2p interface - * disable but wlan0 used for p2p - */ - if (((dhd->op_mode & HOSTAPD_MASK) == HOSTAPD_MASK) || - ((dhd->op_mode & WFD_MASK) == WFD_MASK)) { - return TRUE; - } - else -#else - /* concurent mode with p2p interface for wfd and wlan0 for sta */ - if (((dhd->op_mode & P2P_GO_ENABLED) == P2P_GO_ENABLED) || - ((dhd->op_mode & P2P_GC_ENABLED) == P2P_GC_ENABLED)) { - DHD_ERROR(("%s P2P enabled for mode=%d\n", __FUNCTION__, dhd->op_mode)); - return TRUE; - } - else -#endif /* WL_ENABLE_P2P_IF */ -#endif /* WL_CFG80211 */ - return FALSE; -} - -#ifdef PNO_SUPPORT -int -dhd_pno_clean(dhd_pub_t *dhd) -{ - char iovbuf[128]; - int pfn_enabled = 0; - int iov_len = 0; - int ret; - - /* Disable pfn */ - iov_len = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) >= 0) { - /* clear pfn */ - iov_len = bcm_mkiovar("pfnclear", 0, 0, iovbuf, sizeof(iovbuf)); - if (iov_len) { - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, - iov_len, TRUE, 0)) < 0) { - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); - } - } - else { - ret = -1; - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, iov_len)); - } - } - else - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); - - return ret; -} - -int -dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled) -{ - char iovbuf[128]; - int ret = -1; - - if ((!dhd) && ((pfn_enabled != 0) || (pfn_enabled != 1))) { - DHD_ERROR(("%s error exit\n", __FUNCTION__)); - return ret; - } - - - memset(iovbuf, 0, sizeof(iovbuf)); - -#ifndef WL_SCHED_SCAN - if (dhd_check_ap_wfd_mode_set(dhd) == TRUE) - return (ret); - - if ((pfn_enabled) && (dhd_is_associated(dhd, NULL, NULL) == TRUE)) { - DHD_ERROR(("%s pno is NOT enable : called in assoc mode , ignore\n", __FUNCTION__)); - return ret; - } -#endif /* !WL_SCHED_SCAN */ - - /* Enable/disable PNO */ - if ((ret = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf))) > 0) { - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, - iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s failed for error=%d\n", __FUNCTION__, ret)); - return ret; - } - else { - dhd->pno_enable = pfn_enabled; - DHD_TRACE(("%s set pno as %s\n", - __FUNCTION__, dhd->pno_enable ? "Enable" : "Disable")); - } - } - else DHD_ERROR(("%s failed err=%d\n", __FUNCTION__, ret)); - - return ret; -} - -/* Function to execute combined scan */ -int -dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr, - int pno_repeat, int pno_freq_expo_max) -{ - int err = -1; - char iovbuf[128]; - int k, i; - wl_pfn_param_t pfn_param; - wl_pfn_t pfn_element; - uint len = 0; - - DHD_TRACE(("%s nssid=%d nchan=%d\n", __FUNCTION__, nssid, scan_fr)); - - if ((!dhd) && (!ssids_local)) { - DHD_ERROR(("%s error exit\n", __FUNCTION__)); - err = -1; - return err; - } -#ifndef WL_SCHED_SCAN - if (dhd_check_ap_wfd_mode_set(dhd) == TRUE) - return (err); -#endif /* !WL_SCHED_SCAN */ - - /* Check for broadcast ssid */ - for (k = 0; k < nssid; k++) { - if (!ssids_local[k].SSID_len) { - DHD_ERROR(("%d: Broadcast SSID is ilegal for PNO setting\n", k)); - return err; - } - } -/* #define PNO_DUMP 1 */ -#ifdef PNO_DUMP - { - int j; - for (j = 0; j < nssid; j++) { - DHD_ERROR(("%d: scan for %s size =%d\n", j, - ssids_local[j].SSID, ssids_local[j].SSID_len)); - } - } -#endif /* PNO_DUMP */ - - /* clean up everything */ - if ((err = dhd_pno_clean(dhd)) < 0) { - DHD_ERROR(("%s failed error=%d\n", __FUNCTION__, err)); - return err; - } - memset(iovbuf, 0, sizeof(iovbuf)); - memset(&pfn_param, 0, sizeof(pfn_param)); - memset(&pfn_element, 0, sizeof(pfn_element)); - - /* set pfn parameters */ - pfn_param.version = htod32(PFN_VERSION); - pfn_param.flags = htod16((PFN_LIST_ORDER << SORT_CRITERIA_BIT)); - - /* check and set extra pno params */ - if ((pno_repeat != 0) || (pno_freq_expo_max != 0)) { - pfn_param.flags |= htod16(ENABLE << ENABLE_ADAPTSCAN_BIT); - pfn_param.repeat = (uchar) (pno_repeat); - pfn_param.exp = (uchar) (pno_freq_expo_max); - } - /* set up pno scan fr */ - if (scan_fr != 0) - pfn_param.scan_freq = htod32(scan_fr); - - if (pfn_param.scan_freq > PNO_SCAN_MAX_FW_SEC) { - DHD_ERROR(("%s pno freq above %d sec\n", __FUNCTION__, PNO_SCAN_MAX_FW_SEC)); - return err; - } - if (pfn_param.scan_freq < PNO_SCAN_MIN_FW_SEC) { - DHD_ERROR(("%s pno freq less %d sec\n", __FUNCTION__, PNO_SCAN_MIN_FW_SEC)); - return err; - } - - len = bcm_mkiovar("pfn_set", (char *)&pfn_param, sizeof(pfn_param), iovbuf, sizeof(iovbuf)); - if ((err = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, len, TRUE, 0)) < 0) { - DHD_ERROR(("%s pfn_set failed for error=%d\n", - __FUNCTION__, err)); - return err; - } - - /* set all pfn ssid */ - for (i = 0; i < nssid; i++) { - - pfn_element.infra = htod32(DOT11_BSSTYPE_INFRASTRUCTURE); - pfn_element.auth = (DOT11_OPEN_SYSTEM); - pfn_element.wpa_auth = htod32(WPA_AUTH_PFN_ANY); - pfn_element.wsec = htod32(0); - pfn_element.infra = htod32(1); - pfn_element.flags = htod32(ENABLE << WL_PFN_HIDDEN_BIT); - memcpy((char *)pfn_element.ssid.SSID, ssids_local[i].SSID, ssids_local[i].SSID_len); - pfn_element.ssid.SSID_len = ssids_local[i].SSID_len; - - if ((len = - bcm_mkiovar("pfn_add", (char *)&pfn_element, - sizeof(pfn_element), iovbuf, sizeof(iovbuf))) > 0) { - if ((err = - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, len, TRUE, 0)) < 0) { - DHD_ERROR(("%s failed for i=%d error=%d\n", - __FUNCTION__, i, err)); - return err; - } - else - DHD_TRACE(("%s set OK with PNO time=%d repeat=%d max_adjust=%d\n", - __FUNCTION__, pfn_param.scan_freq, - pfn_param.repeat, pfn_param.exp)); - } - else DHD_ERROR(("%s failed err=%d\n", __FUNCTION__, err)); - } - - /* Enable PNO */ - /* dhd_pno_enable(dhd, 1); */ - return err; -} - -int -dhd_pno_set_ex(dhd_pub_t *dhd, wl_pfn_t* ssidnet, int nssid, ushort pno_interval, - int pno_repeat, int pno_expo_max, int pno_lost_time) -{ - int err = -1; - char iovbuf[128]; - int k, i; - wl_pfn_param_t pfn_param; - wl_pfn_t pfn_element; - uint len = 0; - - DHD_TRACE(("%s nssid=%d pno_interval=%d\n", __FUNCTION__, nssid, pno_interval)); - - if ((!dhd) && (!ssidnet)) { - DHD_ERROR(("%s error exit\n", __FUNCTION__)); - err = -1; - return err; - } - - if (dhd_check_ap_wfd_mode_set(dhd) == TRUE) - return (err); - - /* Check for broadcast ssid */ - for (k = 0; k < nssid; k++) { - if (!ssidnet[k].ssid.SSID_len) { - DHD_ERROR(("%d: Broadcast SSID is ilegal for PNO setting\n", k)); - return err; - } - } -/* #define PNO_DUMP 1 */ -#ifdef PNO_DUMP - { - int j; - for (j = 0; j < nssid; j++) { - DHD_ERROR(("%d: scan for %s size =%d\n", j, - ssidnet[j].ssid.SSID, ssidnet[j].ssid.SSID_len)); - } - } -#endif /* PNO_DUMP */ - - /* clean up everything */ - if ((err = dhd_pno_clean(dhd)) < 0) { - DHD_ERROR(("%s failed error=%d\n", __FUNCTION__, err)); - return err; - } - memset(iovbuf, 0, sizeof(iovbuf)); - memset(&pfn_param, 0, sizeof(pfn_param)); - memset(&pfn_element, 0, sizeof(pfn_element)); - - /* set pfn parameters */ - pfn_param.version = htod32(PFN_VERSION); - pfn_param.flags = htod16((PFN_LIST_ORDER << SORT_CRITERIA_BIT)); - - /* check and set extra pno params */ - if ((pno_repeat != 0) || (pno_expo_max != 0)) { - pfn_param.flags |= htod16(ENABLE << ENABLE_ADAPTSCAN_BIT); - pfn_param.repeat = (uchar) (pno_repeat); - pfn_param.exp = (uchar) (pno_expo_max); - } - - /* set up pno scan fr */ - if (pno_interval != 0) - pfn_param.scan_freq = htod32(pno_interval); - - if (pfn_param.scan_freq > PNO_SCAN_MAX_FW_SEC) { - DHD_ERROR(("%s pno freq above %d sec\n", __FUNCTION__, PNO_SCAN_MAX_FW_SEC)); - return err; - } - if (pfn_param.scan_freq < PNO_SCAN_MIN_FW_SEC) { - DHD_ERROR(("%s pno freq less %d sec\n", __FUNCTION__, PNO_SCAN_MIN_FW_SEC)); - return err; - } - - /* network lost time */ - pfn_param.lost_network_timeout = htod32(pno_lost_time); - - len = bcm_mkiovar("pfn_set", (char *)&pfn_param, sizeof(pfn_param), iovbuf, sizeof(iovbuf)); - if ((err = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, len, TRUE, 0)) < 0) { - DHD_ERROR(("%s pfn_set failed for error=%d\n", - __FUNCTION__, err)); - return err; - } else { - DHD_TRACE(("%s pfn_set OK with PNO time=%d repeat=%d max_adjust=%d\n", - __FUNCTION__, pfn_param.scan_freq, - pfn_param.repeat, pfn_param.exp)); - } - - /* set all pfn ssid */ - for (i = 0; i < nssid; i++) { - pfn_element.flags = htod32(ssidnet[i].flags); - pfn_element.infra = htod32(ssidnet[i].infra); - pfn_element.auth = htod32(ssidnet[i].auth); - pfn_element.wpa_auth = htod32(ssidnet[i].wpa_auth); - pfn_element.wsec = htod32(ssidnet[i].wsec); - - memcpy((char *)pfn_element.ssid.SSID, ssidnet[i].ssid.SSID, ssidnet[i].ssid.SSID_len); - pfn_element.ssid.SSID_len = htod32(ssidnet[i].ssid.SSID_len); - - if ((len = - bcm_mkiovar("pfn_add", (char *)&pfn_element, - sizeof(pfn_element), iovbuf, sizeof(iovbuf))) > 0) { - if ((err = - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, len, TRUE, 0)) < 0) { - DHD_ERROR(("%s pfn_add failed with ssidnet[%d] error=%d\n", - __FUNCTION__, i, err)); - return err; - } else { - DHD_TRACE(("%s pfn_add OK with ssidnet[%d]\n", __FUNCTION__, i)); - } - } else { - DHD_ERROR(("%s bcm_mkiovar failed with ssidnet[%d]\n", __FUNCTION__, i)); - } - } - - return err; -} - -int -dhd_pno_get_status(dhd_pub_t *dhd) -{ - int ret = -1; - - if (!dhd) - return ret; - else - return (dhd->pno_enable); -} - -#endif /* PNO_SUPPORT */ - -#if defined(KEEP_ALIVE) -int dhd_keep_alive_onoff(dhd_pub_t *dhd) -{ - char buf[256]; - const char *str; - wl_mkeep_alive_pkt_t mkeep_alive_pkt; - wl_mkeep_alive_pkt_t *mkeep_alive_pktp; - int buf_len; - int str_len; - int res = -1; - - if (dhd_check_ap_wfd_mode_set(dhd) == TRUE) - return (res); - - DHD_TRACE(("%s execution\n", __FUNCTION__)); - - str = "mkeep_alive"; - str_len = strlen(str); - strncpy(buf, str, str_len); - buf[ str_len ] = '\0'; - mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *) (buf + str_len + 1); - mkeep_alive_pkt.period_msec = KEEP_ALIVE_PERIOD; - buf_len = str_len + 1; - mkeep_alive_pkt.version = htod16(WL_MKEEP_ALIVE_VERSION); - mkeep_alive_pkt.length = htod16(WL_MKEEP_ALIVE_FIXED_LEN); - /* Setup keep alive zero for null packet generation */ - mkeep_alive_pkt.keep_alive_id = 0; - mkeep_alive_pkt.len_bytes = 0; - buf_len += WL_MKEEP_ALIVE_FIXED_LEN; - /* Keep-alive attributes are set in local variable (mkeep_alive_pkt), and - * then memcpy'ed into buffer (mkeep_alive_pktp) since there is no - * guarantee that the buffer is properly aligned. - */ - memcpy((char *)mkeep_alive_pktp, &mkeep_alive_pkt, WL_MKEEP_ALIVE_FIXED_LEN); - - res = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, buf_len, TRUE, 0); - - return res; -} -#endif /* defined(KEEP_ALIVE) */ - -/* Android ComboSCAN support */ - -/* - * data parsing from ComboScan tlv list -*/ -int -wl_iw_parse_data_tlv(char** list_str, void *dst, int dst_size, const char token, - int input_size, int *bytes_left) -{ - char* str = *list_str; - uint16 short_temp; - uint32 int_temp; - - if ((list_str == NULL) || (*list_str == NULL) ||(bytes_left == NULL) || (*bytes_left < 0)) { - DHD_ERROR(("%s error paramters\n", __FUNCTION__)); - return -1; - } - - /* Clean all dest bytes */ - memset(dst, 0, dst_size); - while (*bytes_left > 0) { - - if (str[0] != token) { - DHD_TRACE(("%s NOT Type=%d get=%d left_parse=%d \n", - __FUNCTION__, token, str[0], *bytes_left)); - return -1; - } - - *bytes_left -= 1; - str += 1; - - if (input_size == 1) { - memcpy(dst, str, input_size); - } - else if (input_size == 2) { - memcpy(dst, (char *)htod16(memcpy(&short_temp, str, input_size)), - input_size); - } - else if (input_size == 4) { - memcpy(dst, (char *)htod32(memcpy(&int_temp, str, input_size)), - input_size); - } - - *bytes_left -= input_size; - str += input_size; - *list_str = str; - return 1; - } - return 1; -} - -/* - * channel list parsing from cscan tlv list -*/ -int -wl_iw_parse_channel_list_tlv(char** list_str, uint16* channel_list, - int channel_num, int *bytes_left) -{ - char* str = *list_str; - int idx = 0; - - if ((list_str == NULL) || (*list_str == NULL) ||(bytes_left == NULL) || (*bytes_left < 0)) { - DHD_ERROR(("%s error paramters\n", __FUNCTION__)); - return -1; - } - - while (*bytes_left > 0) { - - if (str[0] != CSCAN_TLV_TYPE_CHANNEL_IE) { - *list_str = str; - DHD_TRACE(("End channel=%d left_parse=%d %d\n", idx, *bytes_left, str[0])); - return idx; - } - /* Get proper CSCAN_TLV_TYPE_CHANNEL_IE */ - *bytes_left -= 1; - str += 1; - - if (str[0] == 0) { - /* All channels */ - channel_list[idx] = 0x0; - } - else { - channel_list[idx] = (uint16)str[0]; - DHD_TRACE(("%s channel=%d \n", __FUNCTION__, channel_list[idx])); - } - *bytes_left -= 1; - str += 1; - - if (idx++ > 255) { - DHD_ERROR(("%s Too many channels \n", __FUNCTION__)); - return -1; - } - } - - *list_str = str; - return idx; -} - -/* - * SSIDs list parsing from cscan tlv list - */ -int -wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, int max, int *bytes_left) -{ - char* str; - int idx = 0; - - if ((list_str == NULL) || (*list_str == NULL) || (*bytes_left < 0)) { - DHD_ERROR(("%s error paramters\n", __FUNCTION__)); - return -1; - } - str = *list_str; - while (*bytes_left > 0) { - - if (str[0] != CSCAN_TLV_TYPE_SSID_IE) { - *list_str = str; - DHD_TRACE(("nssid=%d left_parse=%d %d\n", idx, *bytes_left, str[0])); - return idx; - } - - /* Get proper CSCAN_TLV_TYPE_SSID_IE */ - *bytes_left -= 1; - str += 1; - - if (str[0] == 0) { - /* Broadcast SSID */ - ssid[idx].SSID_len = 0; - memset((char*)ssid[idx].SSID, 0x0, DOT11_MAX_SSID_LEN); - *bytes_left -= 1; - str += 1; - - DHD_TRACE(("BROADCAST SCAN left=%d\n", *bytes_left)); - } - else if (str[0] <= DOT11_MAX_SSID_LEN) { - /* Get proper SSID size */ - ssid[idx].SSID_len = str[0]; - *bytes_left -= 1; - str += 1; - - /* Get SSID */ - if (ssid[idx].SSID_len > *bytes_left) { - DHD_ERROR(("%s out of memory range len=%d but left=%d\n", - __FUNCTION__, ssid[idx].SSID_len, *bytes_left)); - return -1; - } - - memcpy((char*)ssid[idx].SSID, str, ssid[idx].SSID_len); - - *bytes_left -= ssid[idx].SSID_len; - str += ssid[idx].SSID_len; - - DHD_TRACE(("%s :size=%d left=%d\n", - (char*)ssid[idx].SSID, ssid[idx].SSID_len, *bytes_left)); - } - else { - DHD_ERROR(("### SSID size more that %d\n", str[0])); - return -1; - } - - if (idx++ > max) { - DHD_ERROR(("%s number of SSIDs more that %d\n", __FUNCTION__, idx)); - return -1; - } - } - - *list_str = str; - return idx; -} - -/* Parse a comma-separated list from list_str into ssid array, starting - * at index idx. Max specifies size of the ssid array. Parses ssids - * and returns updated idx; if idx >= max not all fit, the excess have - * not been copied. Returns -1 on empty string, or on ssid too long. - */ -int -wl_iw_parse_ssid_list(char** list_str, wlc_ssid_t* ssid, int idx, int max) -{ - char* str, *ptr; - - if ((list_str == NULL) || (*list_str == NULL)) - return -1; - - for (str = *list_str; str != NULL; str = ptr) { - - /* check for next TAG */ - if (!strncmp(str, GET_CHANNEL, strlen(GET_CHANNEL))) { - *list_str = str + strlen(GET_CHANNEL); - return idx; - } - - if ((ptr = strchr(str, ',')) != NULL) { - *ptr++ = '\0'; - } - - if (strlen(str) > DOT11_MAX_SSID_LEN) { - DHD_ERROR(("ssid <%s> exceeds %d\n", str, DOT11_MAX_SSID_LEN)); - return -1; - } - - if (strlen(str) == 0) - ssid[idx].SSID_len = 0; - - if (idx < max) { - bcm_strcpy_s((char*)ssid[idx].SSID, sizeof(ssid[idx].SSID), str); - ssid[idx].SSID_len = strlen(str); - } - idx++; - } - return idx; -} - -/* - * Parse channel list from iwpriv CSCAN - */ -int -wl_iw_parse_channel_list(char** list_str, uint16* channel_list, int channel_num) -{ - int num; - int val; - char* str; - char* endptr = NULL; - - if ((list_str == NULL)||(*list_str == NULL)) - return -1; - - str = *list_str; - num = 0; - while (strncmp(str, GET_NPROBE, strlen(GET_NPROBE))) { - val = (int)strtoul(str, &endptr, 0); - if (endptr == str) { - printf("could not parse channel number starting at" - " substring \"%s\" in list:\n%s\n", - str, *list_str); - return -1; - } - str = endptr + strspn(endptr, " ,"); - - if (num == channel_num) { - DHD_ERROR(("too many channels (more than %d) in channel list:\n%s\n", - channel_num, *list_str)); - return -1; - } - - channel_list[num++] = (uint16)val; - } - *list_str = str; - return num; -} diff --git a/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c b/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c deleted file mode 100644 index de519a57bf8c..000000000000 --- a/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c +++ /dev/null @@ -1,293 +0,0 @@ -/* -* Customer code to add GPIO control during WLAN start/stop -* Copyright (C) 1999-2011, Broadcom Corporation -* -* Unless you and Broadcom execute a separate written software license -* agreement governing use of this software, this software is licensed to you -* under the terms of the GNU General Public License version 2 (the "GPL"), -* available at http://www.broadcom.com/licenses/GPLv2.php, with the -* following added to such license: -* -* As a special exception, the copyright holders of this software give you -* permission to link this software with independent modules, and to copy and -* distribute the resulting executable under terms of your choice, provided that -* you also meet, for each linked independent module, the terms and conditions of -* the license of that module. An independent module is a module which is not -* derived from this software. The special exception does not apply to any -* modifications of the software. -* -* Notwithstanding the above, under no circumstances may you combine this -* software in any way with any other Broadcom software provided under a license -* other than the GPL, without Broadcom's express prior written consent. -* -* $Id: dhd_custom_gpio.c 339054 2012-06-15 04:56:55Z $ -*/ - -#include -#include -#include -#include - -#include -#include - -#include -#include - -#define WL_ERROR(x) printf x -#define WL_TRACE(x) - -#ifdef CUSTOMER_HW -extern void bcm_wlan_power_off(int); -extern void bcm_wlan_power_on(int); -#endif /* CUSTOMER_HW */ -#if defined(CUSTOMER_HW2) -#ifdef CONFIG_WIFI_CONTROL_FUNC -int wifi_set_power(int on, unsigned long msec); -int wifi_get_irq_number(unsigned long *irq_flags_ptr); -int wifi_get_mac_addr(unsigned char *buf); -void *wifi_get_country_code(char *ccode); -#else -int wifi_set_power(int on, unsigned long msec) { return -1; } -int wifi_get_irq_number(unsigned long *irq_flags_ptr) { return -1; } -int wifi_get_mac_addr(unsigned char *buf) { return -1; } -void *wifi_get_country_code(char *ccode) { return NULL; } -#endif /* CONFIG_WIFI_CONTROL_FUNC */ -#endif /* CUSTOMER_HW2 */ - -#if defined(OOB_INTR_ONLY) - -#if defined(BCMLXSDMMC) -extern int sdioh_mmc_irq(int irq); -#endif /* (BCMLXSDMMC) */ - -#ifdef CUSTOMER_HW3 -#include -#endif - -/* Customer specific Host GPIO defintion */ -static int dhd_oob_gpio_num = -1; - -module_param(dhd_oob_gpio_num, int, 0644); -MODULE_PARM_DESC(dhd_oob_gpio_num, "DHD oob gpio number"); - -/* This function will return: - * 1) return : Host gpio interrupt number per customer platform - * 2) irq_flags_ptr : Type of Host interrupt as Level or Edge - * - * NOTE : - * Customer should check his platform definitions - * and his Host Interrupt spec - * to figure out the proper setting for his platform. - * Broadcom provides just reference settings as example. - * - */ -int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr) -{ - int host_oob_irq = 0; - -#ifdef CUSTOMER_HW2 - host_oob_irq = wifi_get_irq_number(irq_flags_ptr); - -#else -#if defined(CUSTOM_OOB_GPIO_NUM) - if (dhd_oob_gpio_num < 0) { - dhd_oob_gpio_num = CUSTOM_OOB_GPIO_NUM; - } -#endif /* CUSTOMER_HW2 */ - - if (dhd_oob_gpio_num < 0) { - WL_ERROR(("%s: ERROR customer specific Host GPIO is NOT defined\n", - __FUNCTION__)); - return (dhd_oob_gpio_num); - } - - WL_ERROR(("%s: customer specific Host GPIO number is (%d)\n", - __FUNCTION__, dhd_oob_gpio_num)); - -#if defined CUSTOMER_HW - host_oob_irq = MSM_GPIO_TO_INT(dhd_oob_gpio_num); -#elif defined CUSTOMER_HW3 - gpio_request(dhd_oob_gpio_num, "oob irq"); - host_oob_irq = gpio_to_irq(dhd_oob_gpio_num); - gpio_direction_input(dhd_oob_gpio_num); -#endif /* CUSTOMER_HW */ -#endif /* CUSTOMER_HW2 */ - - return (host_oob_irq); -} -#endif /* defined(OOB_INTR_ONLY) */ - -/* Customer function to control hw specific wlan gpios */ -void -dhd_customer_gpio_wlan_ctrl(int onoff) -{ - switch (onoff) { - case WLAN_RESET_OFF: - WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n", - __FUNCTION__)); -#ifdef CUSTOMER_HW - bcm_wlan_power_off(2); -#endif /* CUSTOMER_HW */ -#ifdef CUSTOMER_HW2 - wifi_set_power(0, 0); -#endif - WL_ERROR(("=========== WLAN placed in RESET ========\n")); - break; - - case WLAN_RESET_ON: - WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n", - __FUNCTION__)); -#ifdef CUSTOMER_HW - bcm_wlan_power_on(2); -#endif /* CUSTOMER_HW */ -#ifdef CUSTOMER_HW2 - wifi_set_power(1, 0); -#endif - WL_ERROR(("=========== WLAN going back to live ========\n")); - break; - - case WLAN_POWER_OFF: - WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n", - __FUNCTION__)); -#ifdef CUSTOMER_HW - bcm_wlan_power_off(1); -#endif /* CUSTOMER_HW */ - break; - - case WLAN_POWER_ON: - WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n", - __FUNCTION__)); -#ifdef CUSTOMER_HW - bcm_wlan_power_on(1); - /* Lets customer power to get stable */ - OSL_DELAY(200); -#endif /* CUSTOMER_HW */ - break; - } -} - -#ifdef GET_CUSTOM_MAC_ENABLE -/* Function to get custom MAC address */ -int -dhd_custom_get_mac_address(unsigned char *buf) -{ - int ret = 0; - - WL_TRACE(("%s Enter\n", __FUNCTION__)); - if (!buf) - return -EINVAL; - - /* Customer access to MAC address stored outside of DHD driver */ -#if defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) - ret = wifi_get_mac_addr(buf); -#endif - -#ifdef EXAMPLE_GET_MAC - /* EXAMPLE code */ - { - struct ether_addr ea_example = {{0x00, 0x11, 0x22, 0x33, 0x44, 0xFF}}; - bcopy((char *)&ea_example, buf, sizeof(struct ether_addr)); - } -#endif /* EXAMPLE_GET_MAC */ - - return ret; -} -#endif /* GET_CUSTOM_MAC_ENABLE */ - -/* Customized Locale table : OPTIONAL feature */ -const struct cntry_locales_custom translate_custom_table[] = { -/* Table should be filled out based on custom platform regulatory requirement */ -#ifdef EXAMPLE_TABLE - {"", "XY", 4}, /* Universal if Country code is unknown or empty */ - {"US", "US", 69}, /* input ISO "US" to : US regrev 69 */ - {"CA", "US", 69}, /* input ISO "CA" to : US regrev 69 */ - {"EU", "EU", 5}, /* European union countries to : EU regrev 05 */ - {"AT", "EU", 5}, - {"BE", "EU", 5}, - {"BG", "EU", 5}, - {"CY", "EU", 5}, - {"CZ", "EU", 5}, - {"DK", "EU", 5}, - {"EE", "EU", 5}, - {"FI", "EU", 5}, - {"FR", "EU", 5}, - {"DE", "EU", 5}, - {"GR", "EU", 5}, - {"HU", "EU", 5}, - {"IE", "EU", 5}, - {"IT", "EU", 5}, - {"LV", "EU", 5}, - {"LI", "EU", 5}, - {"LT", "EU", 5}, - {"LU", "EU", 5}, - {"MT", "EU", 5}, - {"NL", "EU", 5}, - {"PL", "EU", 5}, - {"PT", "EU", 5}, - {"RO", "EU", 5}, - {"SK", "EU", 5}, - {"SI", "EU", 5}, - {"ES", "EU", 5}, - {"SE", "EU", 5}, - {"GB", "EU", 5}, - {"KR", "XY", 3}, - {"AU", "XY", 3}, - {"CN", "XY", 3}, /* input ISO "CN" to : XY regrev 03 */ - {"TW", "XY", 3}, - {"AR", "XY", 3}, - {"MX", "XY", 3}, - {"IL", "IL", 0}, - {"CH", "CH", 0}, - {"TR", "TR", 0}, - {"NO", "NO", 0}, -#endif /* EXMAPLE_TABLE */ -}; - - -/* Customized Locale convertor -* input : ISO 3166-1 country abbreviation -* output: customized cspec -*/ -void get_customized_country_code(char *country_iso_code, wl_country_t *cspec) -{ -#if defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) - - struct cntry_locales_custom *cloc_ptr; - - if (!cspec) - return; - - cloc_ptr = wifi_get_country_code(country_iso_code); - if (cloc_ptr) { - strlcpy(cspec->ccode, cloc_ptr->custom_locale, WLC_CNTRY_BUF_SZ); - cspec->rev = cloc_ptr->custom_locale_rev; - } - return; -#else - int size, i; - - size = ARRAYSIZE(translate_custom_table); - - if (cspec == 0) - return; - - if (size == 0) - return; - - for (i = 0; i < size; i++) { - if (strcmp(country_iso_code, translate_custom_table[i].iso_abbrev) == 0) { - memcpy(cspec->ccode, - translate_custom_table[i].custom_locale, WLC_CNTRY_BUF_SZ); - cspec->rev = translate_custom_table[i].custom_locale_rev; - return; - } - } -#ifdef EXAMPLE_TABLE - /* if no country code matched return first universal code from translate_custom_table */ - memcpy(cspec->ccode, translate_custom_table[0].custom_locale, WLC_CNTRY_BUF_SZ); - cspec->rev = translate_custom_table[0].custom_locale_rev; -#endif /* EXMAPLE_TABLE */ - return; -#endif /* defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) */ -} diff --git a/drivers/net/wireless/bcmdhd/dhd_dbg.h b/drivers/net/wireless/bcmdhd/dhd_dbg.h deleted file mode 100644 index 01be6a1f056f..000000000000 --- a/drivers/net/wireless/bcmdhd/dhd_dbg.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Debug/trace/assert driver definitions for Dongle Host Driver. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd_dbg.h 285933 2011-09-23 21:45:31Z $ - */ - -#ifndef _dhd_dbg_ -#define _dhd_dbg_ - -#if defined(DHD_DEBUG) - -#define DHD_ERROR(args) do {if ((dhd_msg_level & DHD_ERROR_VAL) && (net_ratelimit())) \ - printf args;} while (0) -#define DHD_TRACE(args) do {if (dhd_msg_level & DHD_TRACE_VAL) printf args;} while (0) -#define DHD_INFO(args) do {if (dhd_msg_level & DHD_INFO_VAL) printf args;} while (0) -#define DHD_DATA(args) do {if (dhd_msg_level & DHD_DATA_VAL) printf args;} while (0) -#define DHD_CTL(args) do {if (dhd_msg_level & DHD_CTL_VAL) printf args;} while (0) -#define DHD_TIMER(args) do {if (dhd_msg_level & DHD_TIMER_VAL) printf args;} while (0) -#define DHD_HDRS(args) do {if (dhd_msg_level & DHD_HDRS_VAL) printf args;} while (0) -#define DHD_BYTES(args) do {if (dhd_msg_level & DHD_BYTES_VAL) printf args;} while (0) -#define DHD_INTR(args) do {if (dhd_msg_level & DHD_INTR_VAL) printf args;} while (0) -#define DHD_GLOM(args) do {if (dhd_msg_level & DHD_GLOM_VAL) printf args;} while (0) -#define DHD_EVENT(args) do {if (dhd_msg_level & DHD_EVENT_VAL) printf args;} while (0) -#define DHD_BTA(args) do {if (dhd_msg_level & DHD_BTA_VAL) printf args;} while (0) -#define DHD_ISCAN(args) do {if (dhd_msg_level & DHD_ISCAN_VAL) printf args;} while (0) -#define DHD_ARPOE(args) do {if (dhd_msg_level & DHD_ARPOE_VAL) printf args;} while (0) - -#define DHD_ERROR_ON() (dhd_msg_level & DHD_ERROR_VAL) -#define DHD_TRACE_ON() (dhd_msg_level & DHD_TRACE_VAL) -#define DHD_INFO_ON() (dhd_msg_level & DHD_INFO_VAL) -#define DHD_DATA_ON() (dhd_msg_level & DHD_DATA_VAL) -#define DHD_CTL_ON() (dhd_msg_level & DHD_CTL_VAL) -#define DHD_TIMER_ON() (dhd_msg_level & DHD_TIMER_VAL) -#define DHD_HDRS_ON() (dhd_msg_level & DHD_HDRS_VAL) -#define DHD_BYTES_ON() (dhd_msg_level & DHD_BYTES_VAL) -#define DHD_INTR_ON() (dhd_msg_level & DHD_INTR_VAL) -#define DHD_GLOM_ON() (dhd_msg_level & DHD_GLOM_VAL) -#define DHD_EVENT_ON() (dhd_msg_level & DHD_EVENT_VAL) -#define DHD_BTA_ON() (dhd_msg_level & DHD_BTA_VAL) -#define DHD_ISCAN_ON() (dhd_msg_level & DHD_ISCAN_VAL) -#define DHD_ARPOE_ON() (dhd_msg_level & DHD_ARPOE_VAL) - -#else /* defined(BCMDBG) || defined(DHD_DEBUG) */ - -#define DHD_ERROR(args) do {if (net_ratelimit()) printf args;} while (0) -#define DHD_TRACE(args) -#define DHD_INFO(args) -#define DHD_DATA(args) -#define DHD_CTL(args) -#define DHD_TIMER(args) -#define DHD_HDRS(args) -#define DHD_BYTES(args) -#define DHD_INTR(args) -#define DHD_GLOM(args) -#define DHD_EVENT(args) -#define DHD_BTA(args) -#define DHD_ISCAN(args) -#define DHD_ARPOE(args) - -#define DHD_ERROR_ON() 0 -#define DHD_TRACE_ON() 0 -#define DHD_INFO_ON() 0 -#define DHD_DATA_ON() 0 -#define DHD_CTL_ON() 0 -#define DHD_TIMER_ON() 0 -#define DHD_HDRS_ON() 0 -#define DHD_BYTES_ON() 0 -#define DHD_INTR_ON() 0 -#define DHD_GLOM_ON() 0 -#define DHD_EVENT_ON() 0 -#define DHD_BTA_ON() 0 -#define DHD_ISCAN_ON() 0 -#define DHD_ARPOE_ON() 0 -#endif - -#define DHD_LOG(args) - -#define DHD_BLOG(cp, size) -#define DHD_NONE(args) -extern int dhd_msg_level; - -/* Defines msg bits */ -#include - -#endif /* _dhd_dbg_ */ diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c deleted file mode 100644 index 476a50a99649..000000000000 --- a/drivers/net/wireless/bcmdhd/dhd_linux.c +++ /dev/null @@ -1,5486 +0,0 @@ -/* - * Broadcom Dongle Host Driver (DHD), Linux-specific network interface - * Basically selected code segments from usb-cdc.c and usb-rndis.c - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd_linux.c 352789 2012-08-24 00:01:33Z $ - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_WAKELOCK -#include -#endif -#ifdef WL_CFG80211 -#include -#endif - -#include -#include -#include - -#ifdef WLMEDIA_HTSF -#include -#include - -#define HTSF_MINLEN 200 /* min. packet length to timestamp */ -#define HTSF_BUS_DELAY 150 /* assume a fix propagation in us */ -#define TSMAX 1000 /* max no. of timing record kept */ -#define NUMBIN 34 - -static uint32 tsidx = 0; -static uint32 htsf_seqnum = 0; -uint32 tsfsync; -struct timeval tsync; -static uint32 tsport = 5010; - -typedef struct histo_ { - uint32 bin[NUMBIN]; -} histo_t; - -#if !ISPOWEROF2(DHD_SDALIGN) -#error DHD_SDALIGN is not a power of 2! -#endif - -static histo_t vi_d1, vi_d2, vi_d3, vi_d4; -#endif /* WLMEDIA_HTSF */ - -#if defined(SOFTAP) -extern bool ap_cfg_running; -extern bool ap_fw_loaded; -#endif - -/* enable HOSTIP cache update from the host side when an eth0:N is up */ -#define AOE_IP_ALIAS_SUPPORT 1 - -#ifdef PROP_TXSTATUS -#include -#include -#endif - -#include - -#ifdef ARP_OFFLOAD_SUPPORT -void aoe_update_host_ipv4_table(dhd_pub_t *dhd_pub, u32 ipa, bool add); -static int dhd_device_event(struct notifier_block *this, - unsigned long event, - void *ptr); - -static struct notifier_block dhd_notifier = { - .notifier_call = dhd_device_event -}; -#endif /* ARP_OFFLOAD_SUPPORT */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) -#include -volatile bool dhd_mmc_suspend = FALSE; -DECLARE_WAIT_QUEUE_HEAD(dhd_dpc_wait); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ - -#if defined(OOB_INTR_ONLY) -extern void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable); -#endif /* defined(OOB_INTR_ONLY) */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -static void dhd_hang_process(struct work_struct *work); -#endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -MODULE_LICENSE("GPL v2"); -#endif /* LinuxVer */ - -#include - -#ifndef PROP_TXSTATUS -#define DBUS_RX_BUFFER_SIZE_DHD(net) (net->mtu + net->hard_header_len + dhd->pub.hdrlen) -#else -#define DBUS_RX_BUFFER_SIZE_DHD(net) (net->mtu + net->hard_header_len + dhd->pub.hdrlen + 128) -#endif - -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 15) -const char * -print_tainted() -{ - return ""; -} -#endif /* LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 15) */ - -/* Linux wireless extension support */ -#if defined(WL_WIRELESS_EXT) -#include -extern wl_iw_extra_params_t g_wl_iw_params; -#endif /* defined(WL_WIRELESS_EXT) */ - -#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) -#include -#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ -extern int dhd_get_dtim_skip(dhd_pub_t *dhd); - -#ifdef PKT_FILTER_SUPPORT -extern void dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg); -extern void dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode); -#endif - -/* Interface control information */ -typedef struct dhd_if { - struct dhd_info *info; /* back pointer to dhd_info */ - /* OS/stack specifics */ - struct net_device *net; - struct net_device_stats stats; - int idx; /* iface idx in dongle */ - dhd_if_state_t state; /* interface state */ - uint subunit; /* subunit */ - uint8 mac_addr[ETHER_ADDR_LEN]; /* assigned MAC address */ - bool attached; /* Delayed attachment when unset */ - bool txflowcontrol; /* Per interface flow control indicator */ - char name[IFNAMSIZ+1]; /* linux interface name */ - uint8 bssidx; /* bsscfg index for the interface */ - bool set_multicast; -} dhd_if_t; - -#ifdef WLMEDIA_HTSF -typedef struct { - uint32 low; - uint32 high; -} tsf_t; - -typedef struct { - uint32 last_cycle; - uint32 last_sec; - uint32 last_tsf; - uint32 coef; /* scaling factor */ - uint32 coefdec1; /* first decimal */ - uint32 coefdec2; /* second decimal */ -} htsf_t; - -typedef struct { - uint32 t1; - uint32 t2; - uint32 t3; - uint32 t4; -} tstamp_t; - -static tstamp_t ts[TSMAX]; -static tstamp_t maxdelayts; -static uint32 maxdelay = 0, tspktcnt = 0, maxdelaypktno = 0; - -#endif /* WLMEDIA_HTSF */ - -/* Local private structure (extension of pub) */ -typedef struct dhd_info { -#if defined(WL_WIRELESS_EXT) - wl_iw_t iw; /* wireless extensions state (must be first) */ -#endif /* defined(WL_WIRELESS_EXT) */ - - dhd_pub_t pub; - - /* For supporting multiple interfaces */ - dhd_if_t *iflist[DHD_MAX_IFS]; - - struct semaphore proto_sem; -#ifdef PROP_TXSTATUS - spinlock_t wlfc_spinlock; -#endif /* PROP_TXSTATUS */ -#ifdef WLMEDIA_HTSF - htsf_t htsf; -#endif - wait_queue_head_t ioctl_resp_wait; - struct timer_list timer; - bool wd_timer_valid; - struct tasklet_struct tasklet; - spinlock_t sdlock; - spinlock_t txqlock; - spinlock_t dhd_lock; -#ifdef DHDTHREAD - /* Thread based operation */ - bool threads_only; - struct semaphore sdsem; - - tsk_ctl_t thr_dpc_ctl; - tsk_ctl_t thr_wdt_ctl; - -#else - bool dhd_tasklet_create; -#endif /* DHDTHREAD */ - tsk_ctl_t thr_sysioc_ctl; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - struct work_struct work_hang; -#endif - - /* Wakelocks */ -#if defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - struct wake_lock wl_wifi; /* Wifi wakelock */ - struct wake_lock wl_rxwake; /* Wifi rx wakelock */ - struct wake_lock wl_ctrlwake; /* Wifi ctrl wakelock */ - struct wake_lock wl_wdwake; /* Wifi wd wakelock */ -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - /* net_device interface lock, prevent race conditions among net_dev interface - * calls and wifi_on or wifi_off - */ - struct mutex dhd_net_if_mutex; - struct mutex dhd_suspend_mutex; -#endif - spinlock_t wakelock_spinlock; - int wakelock_counter; - int wakelock_wd_counter; - int wakelock_rx_timeout_enable; - int wakelock_ctrl_timeout_enable; - - /* Thread to issue ioctl for multicast */ - bool set_macaddress; - struct ether_addr macvalue; - wait_queue_head_t ctrl_wait; - atomic_t pend_8021x_cnt; - dhd_attach_states_t dhd_state; - -#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) - struct early_suspend early_suspend; -#endif /* CONFIG_HAS_EARLYSUSPEND */ - -#ifdef ARP_OFFLOAD_SUPPORT - u32 pend_ipaddr; -#endif /* ARP_OFFLOAD_SUPPORT */ -} dhd_info_t; - -/* Definitions to provide path to the firmware and nvram - * example nvram_path[MOD_PARAM_PATHLEN]="/projects/wlan/nvram.txt" - */ -char firmware_path[MOD_PARAM_PATHLEN]; -char nvram_path[MOD_PARAM_PATHLEN]; - -/* load firmware and/or nvram values from the filesystem */ -module_param_string(firmware_path, firmware_path, MOD_PARAM_PATHLEN, 0660); -module_param_string(nvram_path, nvram_path, MOD_PARAM_PATHLEN, 0); - -char info_string[MOD_PARAM_INFOLEN]; -module_param_string(info_string, info_string, MOD_PARAM_INFOLEN, 0444); - -int op_mode = 0; -module_param(op_mode, int, 0644); -extern int wl_control_wl_start(struct net_device *dev); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -struct semaphore dhd_registration_sem; -#define DHD_REGISTRATION_TIMEOUT 12000 /* msec : allowed time to finished dhd registration */ -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ - -/* Spawn a thread for system ioctls (set mac, set mcast) */ -uint dhd_sysioc = TRUE; -module_param(dhd_sysioc, uint, 0); - -/* Error bits */ -module_param(dhd_msg_level, int, 0); - -/* Watchdog interval */ -uint dhd_watchdog_ms = 10; -module_param(dhd_watchdog_ms, uint, 0); - -#if defined(DHD_DEBUG) -/* Console poll interval */ -uint dhd_console_ms = 0; -module_param(dhd_console_ms, uint, 0644); -#endif /* defined(DHD_DEBUG) */ - -/* ARP offload agent mode : enable ARP Peer Auto-Reply */ -uint dhd_arp_mode = ARP_OL_AGENT | ARP_OL_PEER_AUTO_REPLY; -module_param(dhd_arp_mode, uint, 0); - -/* ARP offload enable */ -uint dhd_arp_enable = TRUE; -module_param(dhd_arp_enable, uint, 0); - -/* Global Pkt filter enable control */ -uint dhd_pkt_filter_enable = TRUE; -module_param(dhd_pkt_filter_enable, uint, 0); - -/* Pkt filter init setup */ -uint dhd_pkt_filter_init = 0; -module_param(dhd_pkt_filter_init, uint, 0); - -/* Pkt filter mode control */ -uint dhd_master_mode = TRUE; -module_param(dhd_master_mode, uint, 0); - -#ifdef DHDTHREAD -/* Watchdog thread priority, -1 to use kernel timer */ -int dhd_watchdog_prio = 0; -module_param(dhd_watchdog_prio, int, 0); - -/* DPC thread priority, -1 to use tasklet */ -int dhd_dpc_prio = 1; -module_param(dhd_dpc_prio, int, 0); - -extern int dhd_dongle_memsize; -module_param(dhd_dongle_memsize, int, 0); -#endif /* DHDTHREAD */ -/* Control fw roaming */ -uint dhd_roam_disable = 0; - -/* Control radio state */ -uint dhd_radio_up = 1; - -/* Network inteface name */ -char iface_name[IFNAMSIZ] = {'\0'}; -module_param_string(iface_name, iface_name, IFNAMSIZ, 0); - -/* The following are specific to the SDIO dongle */ - -/* IOCTL response timeout */ -int dhd_ioctl_timeout_msec = IOCTL_RESP_TIMEOUT; - -/* Idle timeout for backplane clock */ -int dhd_idletime = DHD_IDLETIME_TICKS; -module_param(dhd_idletime, int, 0); - -/* Use polling */ -uint dhd_poll = FALSE; -module_param(dhd_poll, uint, 0); - -/* Use interrupts */ -uint dhd_intr = TRUE; -module_param(dhd_intr, uint, 0); - -/* SDIO Drive Strength (in milliamps) */ -uint dhd_sdiod_drive_strength = 6; -module_param(dhd_sdiod_drive_strength, uint, 0); - -/* Tx/Rx bounds */ -extern uint dhd_txbound; -extern uint dhd_rxbound; -module_param(dhd_txbound, uint, 0); -module_param(dhd_rxbound, uint, 0); - -/* Deferred transmits */ -extern uint dhd_deferred_tx; -module_param(dhd_deferred_tx, uint, 0); - -#ifdef BCMDBGFS -extern void dhd_dbg_init(dhd_pub_t *dhdp); -extern void dhd_dbg_remove(void); -#endif /* BCMDBGFS */ - - - -#ifdef SDTEST -/* Echo packet generator (pkts/s) */ -uint dhd_pktgen = 0; -module_param(dhd_pktgen, uint, 0); - -/* Echo packet len (0 => sawtooth, max 2040) */ -uint dhd_pktgen_len = 0; -module_param(dhd_pktgen_len, uint, 0); -#endif /* SDTEST */ - -/* Version string to report */ -#ifdef DHD_DEBUG -#ifndef SRCBASE -#define SRCBASE "drivers/net/wireless/bcmdhd" -#endif -#define DHD_COMPILED "\nCompiled in " SRCBASE -#else -#define DHD_COMPILED -#endif /* DHD_DEBUG */ - -static char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR -#ifdef DHD_DEBUG -"\nCompiled in " SRCBASE " on " __DATE__ " at " __TIME__ -#endif -; -static void dhd_net_if_lock_local(dhd_info_t *dhd); -static void dhd_net_if_unlock_local(dhd_info_t *dhd); -static void dhd_suspend_lock(dhd_pub_t *dhdp); -static void dhd_suspend_unlock(dhd_pub_t *dhdp); -#if !defined(AP) && defined(WLP2P) && defined(WL_ENABLE_P2P_IF) -static u32 dhd_concurrent_fw(dhd_pub_t *dhd); -#endif - -#ifdef WLMEDIA_HTSF -void htsf_update(dhd_info_t *dhd, void *data); -tsf_t prev_tsf, cur_tsf; - -uint32 dhd_get_htsf(dhd_info_t *dhd, int ifidx); -static int dhd_ioctl_htsf_get(dhd_info_t *dhd, int ifidx); -static void dhd_dump_latency(void); -static void dhd_htsf_addtxts(dhd_pub_t *dhdp, void *pktbuf); -static void dhd_htsf_addrxts(dhd_pub_t *dhdp, void *pktbuf); -static void dhd_dump_htsfhisto(histo_t *his, char *s); -#endif /* WLMEDIA_HTSF */ - -/* Monitor interface */ -int dhd_monitor_init(void *dhd_pub); -int dhd_monitor_uninit(void); - - -#if defined(WL_WIRELESS_EXT) -struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev); -#endif /* defined(WL_WIRELESS_EXT) */ - -static void dhd_dpc(ulong data); -/* forward decl */ -extern int dhd_wait_pend8021x(struct net_device *dev); - -#ifdef TOE -#ifndef BDC -#error TOE requires BDC -#endif /* !BDC */ -static int dhd_toe_get(dhd_info_t *dhd, int idx, uint32 *toe_ol); -static int dhd_toe_set(dhd_info_t *dhd, int idx, uint32 toe_ol); -#endif /* TOE */ - -static int dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, - wl_event_msg_t *event_ptr, void **data_ptr); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) -static int dhd_sleep_pm_callback(struct notifier_block *nfb, unsigned long action, void *ignored) -{ - int ret = NOTIFY_DONE; - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)) - switch (action) { - case PM_HIBERNATION_PREPARE: - case PM_SUSPEND_PREPARE: - dhd_mmc_suspend = TRUE; - ret = NOTIFY_OK; - break; - case PM_POST_HIBERNATION: - case PM_POST_SUSPEND: - dhd_mmc_suspend = FALSE; - ret = NOTIFY_OK; - break; - } - smp_mb(); -#endif - return ret; -} - -static struct notifier_block dhd_sleep_pm_notifier = { - .notifier_call = dhd_sleep_pm_callback, - .priority = 10 -}; -extern int register_pm_notifier(struct notifier_block *nb); -extern int unregister_pm_notifier(struct notifier_block *nb); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ - -static void dhd_set_packet_filter(int value, dhd_pub_t *dhd) -{ -#ifdef PKT_FILTER_SUPPORT - DHD_TRACE(("%s: %d\n", __FUNCTION__, value)); - /* 1 - Enable packet filter, only allow unicast packet to send up */ - /* 0 - Disable packet filter */ - if (dhd_pkt_filter_enable && (!value || - (dhd_check_ap_wfd_mode_set(dhd) == FALSE))) { - int i; - - for (i = 0; i < dhd->pktfilter_count; i++) { - dhd_pktfilter_offload_set(dhd, dhd->pktfilter[i]); - dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i], - value, dhd_master_mode); - } - } -#endif -} - -static int dhd_set_suspend(int value, dhd_pub_t *dhd) -{ -#if !defined(SUPPORT_PM2_ONLY) - int power_mode = PM_MAX; -#endif - /* wl_pkt_filter_enable_t enable_parm; */ - char iovbuf[32]; - int bcn_li_dtim = 3; - uint roamvar = 1; - - DHD_TRACE(("%s: enter, value = %d in_suspend=%d\n", - __FUNCTION__, value, dhd->in_suspend)); - - dhd_suspend_lock(dhd); - if (dhd && dhd->up) { - if (value && dhd->in_suspend) { - - /* Kernel suspended */ - DHD_ERROR(("%s: force extra Suspend setting\n", __FUNCTION__)); - -#if !defined(SUPPORT_PM2_ONLY) - dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, - sizeof(power_mode), TRUE, 0); -#endif - - /* Enable packet filter, only allow unicast packet to send up */ - dhd_set_packet_filter(1, dhd); - - /* If DTIM skip is set up as default, force it to wake - * each third DTIM for better power savings. Note that - * one side effect is a chance to miss BC/MC packet. - */ - bcn_li_dtim = dhd_get_dtim_skip(dhd); - bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim, - 4, iovbuf, sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - - /* Disable firmware roaming during suspend */ - bcm_mkiovar("roam_off", (char *)&roamvar, 4, - iovbuf, sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - } else { - - /* Kernel resumed */ - DHD_ERROR(("%s: Remove extra suspend setting\n", __FUNCTION__)); - -#if !defined(SUPPORT_PM2_ONLY) - power_mode = PM_FAST; - dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, - sizeof(power_mode), TRUE, 0); -#endif - - /* disable pkt filter */ - dhd_set_packet_filter(0, dhd); - - /* restore pre-suspend setting for dtim_skip */ - bcm_mkiovar("bcn_li_dtim", (char *)&dhd->dtim_skip, - 4, iovbuf, sizeof(iovbuf)); - - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - roamvar = dhd_roam_disable; - bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, - sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - } - } - dhd_suspend_unlock(dhd); - return 0; -} - -static int dhd_suspend_resume_helper(struct dhd_info *dhd, int val, int force) -{ - dhd_pub_t *dhdp = &dhd->pub; - int ret = 0; - - DHD_OS_WAKE_LOCK(dhdp); - /* Set flag when early suspend was called */ - dhdp->in_suspend = val; - if ((force || !dhdp->suspend_disable_flag) && - (dhd_check_ap_wfd_mode_set(dhdp) == FALSE)) { - ret = dhd_set_suspend(val, dhdp); - } - DHD_OS_WAKE_UNLOCK(dhdp); - return ret; -} - -#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) -static void dhd_early_suspend(struct early_suspend *h) -{ - struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend); - - DHD_TRACE(("%s: enter\n", __FUNCTION__)); - - if (dhd) - dhd_suspend_resume_helper(dhd, 1, 0); -} - -static void dhd_late_resume(struct early_suspend *h) -{ - struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend); - - DHD_TRACE(("%s: enter\n", __FUNCTION__)); - - if (dhd) - dhd_suspend_resume_helper(dhd, 0, 0); -} -#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ - -/* - * Generalized timeout mechanism. Uses spin sleep with exponential back-off until - * the sleep time reaches one jiffy, then switches over to task delay. Usage: - * - * dhd_timeout_start(&tmo, usec); - * while (!dhd_timeout_expired(&tmo)) - * if (poll_something()) - * break; - * if (dhd_timeout_expired(&tmo)) - * fatal(); - */ - -void -dhd_timeout_start(dhd_timeout_t *tmo, uint usec) -{ - tmo->limit = usec; - tmo->increment = 0; - tmo->elapsed = 0; - tmo->tick = jiffies_to_usecs(1); -} - -int -dhd_timeout_expired(dhd_timeout_t *tmo) -{ - /* Does nothing the first call */ - if (tmo->increment == 0) { - tmo->increment = 1; - return 0; - } - - if (tmo->elapsed >= tmo->limit) - return 1; - - /* Add the delay that's about to take place */ - tmo->elapsed += tmo->increment; - - if (tmo->increment < tmo->tick) { - OSL_DELAY(tmo->increment); - tmo->increment *= 2; - if (tmo->increment > tmo->tick) - tmo->increment = tmo->tick; - } else { - wait_queue_head_t delay_wait; - DECLARE_WAITQUEUE(wait, current); - init_waitqueue_head(&delay_wait); - add_wait_queue(&delay_wait, &wait); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); - remove_wait_queue(&delay_wait, &wait); - set_current_state(TASK_RUNNING); - } - - return 0; -} - -int -dhd_net2idx(dhd_info_t *dhd, struct net_device *net) -{ - int i = 0; - - ASSERT(dhd); - while (i < DHD_MAX_IFS) { - if (dhd->iflist[i] && (dhd->iflist[i]->net == net)) - return i; - i++; - } - - return DHD_BAD_IF; -} - -struct net_device * dhd_idx2net(void *pub, int ifidx) -{ - struct dhd_pub *dhd_pub = (struct dhd_pub *)pub; - struct dhd_info *dhd_info; - - if (!dhd_pub || ifidx < 0 || ifidx >= DHD_MAX_IFS) - return NULL; - dhd_info = dhd_pub->info; - if (dhd_info && dhd_info->iflist[ifidx]) - return dhd_info->iflist[ifidx]->net; - return NULL; -} - -int -dhd_ifname2idx(dhd_info_t *dhd, char *name) -{ - int i = DHD_MAX_IFS; - - ASSERT(dhd); - - if (name == NULL || *name == '\0') - return 0; - - while (--i > 0) - if (dhd->iflist[i] && !strncmp(dhd->iflist[i]->name, name, IFNAMSIZ)) - break; - - DHD_TRACE(("%s: return idx %d for \"%s\"\n", __FUNCTION__, i, name)); - - return i; /* default - the primary interface */ -} - -char * -dhd_ifname(dhd_pub_t *dhdp, int ifidx) -{ - dhd_info_t *dhd = (dhd_info_t *)dhdp->info; - - ASSERT(dhd); - - if (ifidx < 0 || ifidx >= DHD_MAX_IFS) { - DHD_ERROR(("%s: ifidx %d out of range\n", __FUNCTION__, ifidx)); - return ""; - } - - if (dhd->iflist[ifidx] == NULL) { - DHD_ERROR(("%s: null i/f %d\n", __FUNCTION__, ifidx)); - return ""; - } - - if (dhd->iflist[ifidx]->net) - return dhd->iflist[ifidx]->net->name; - - return ""; -} - -uint8 * -dhd_bssidx2bssid(dhd_pub_t *dhdp, int idx) -{ - int i; - dhd_info_t *dhd = (dhd_info_t *)dhdp; - - ASSERT(dhd); - for (i = 0; i < DHD_MAX_IFS; i++) - if (dhd->iflist[i] && dhd->iflist[i]->bssidx == idx) - return dhd->iflist[i]->mac_addr; - - return NULL; -} - - -static void -_dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) -{ - struct net_device *dev; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) - struct netdev_hw_addr *ha; -#else - struct dev_mc_list *mclist; -#endif - uint32 allmulti, cnt; - - wl_ioctl_t ioc; - char *buf, *bufp; - uint buflen; - int ret; - - ASSERT(dhd && dhd->iflist[ifidx]); - dev = dhd->iflist[ifidx]->net; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) - netif_addr_lock_bh(dev); -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) - cnt = netdev_mc_count(dev); -#else - cnt = dev->mc_count; -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) - netif_addr_unlock_bh(dev); -#endif - - /* Determine initial value of allmulti flag */ - allmulti = (dev->flags & IFF_ALLMULTI) ? TRUE : FALSE; - - /* Send down the multicast list first. */ - - - buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETHER_ADDR_LEN); - if (!(bufp = buf = MALLOC(dhd->pub.osh, buflen))) { - DHD_ERROR(("%s: out of memory for mcast_list, cnt %d\n", - dhd_ifname(&dhd->pub, ifidx), cnt)); - return; - } - - strcpy(bufp, "mcast_list"); - bufp += strlen("mcast_list") + 1; - - cnt = htol32(cnt); - memcpy(bufp, &cnt, sizeof(cnt)); - bufp += sizeof(cnt); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) - netif_addr_lock_bh(dev); -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) - netdev_for_each_mc_addr(ha, dev) { - if (!cnt) - break; - memcpy(bufp, ha->addr, ETHER_ADDR_LEN); - bufp += ETHER_ADDR_LEN; - cnt--; - } -#else - for (mclist = dev->mc_list; (mclist && (cnt > 0)); cnt--, mclist = mclist->next) { - memcpy(bufp, (void *)mclist->dmi_addr, ETHER_ADDR_LEN); - bufp += ETHER_ADDR_LEN; - } -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) - netif_addr_unlock_bh(dev); -#endif - - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = WLC_SET_VAR; - ioc.buf = buf; - ioc.len = buflen; - ioc.set = TRUE; - - ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); - if (ret < 0) { - DHD_ERROR(("%s: set mcast_list failed, cnt %d\n", - dhd_ifname(&dhd->pub, ifidx), cnt)); - allmulti = cnt ? TRUE : allmulti; - } - - MFREE(dhd->pub.osh, buf, buflen); - - /* Now send the allmulti setting. This is based on the setting in the - * net_device flags, but might be modified above to be turned on if we - * were trying to set some addresses and dongle rejected it... - */ - - buflen = sizeof("allmulti") + sizeof(allmulti); - if (!(buf = MALLOC(dhd->pub.osh, buflen))) { - DHD_ERROR(("%s: out of memory for allmulti\n", dhd_ifname(&dhd->pub, ifidx))); - return; - } - allmulti = htol32(allmulti); - - if (!bcm_mkiovar("allmulti", (void*)&allmulti, sizeof(allmulti), buf, buflen)) { - DHD_ERROR(("%s: mkiovar failed for allmulti, datalen %d buflen %u\n", - dhd_ifname(&dhd->pub, ifidx), (int)sizeof(allmulti), buflen)); - MFREE(dhd->pub.osh, buf, buflen); - return; - } - - - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = WLC_SET_VAR; - ioc.buf = buf; - ioc.len = buflen; - ioc.set = TRUE; - - ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); - if (ret < 0) { - DHD_ERROR(("%s: set allmulti %d failed\n", - dhd_ifname(&dhd->pub, ifidx), ltoh32(allmulti))); - } - - MFREE(dhd->pub.osh, buf, buflen); - - /* Finally, pick up the PROMISC flag as well, like the NIC driver does */ - - allmulti = (dev->flags & IFF_PROMISC) ? TRUE : FALSE; - allmulti = htol32(allmulti); - - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = WLC_SET_PROMISC; - ioc.buf = &allmulti; - ioc.len = sizeof(allmulti); - ioc.set = TRUE; - - ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); - if (ret < 0) { - DHD_ERROR(("%s: set promisc %d failed\n", - dhd_ifname(&dhd->pub, ifidx), ltoh32(allmulti))); - } -} - -static int -_dhd_set_mac_address(dhd_info_t *dhd, int ifidx, struct ether_addr *addr) -{ - char buf[32]; - wl_ioctl_t ioc; - int ret; - - if (!bcm_mkiovar("cur_etheraddr", (char*)addr, ETHER_ADDR_LEN, buf, 32)) { - DHD_ERROR(("%s: mkiovar failed for cur_etheraddr\n", dhd_ifname(&dhd->pub, ifidx))); - return -1; - } - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = WLC_SET_VAR; - ioc.buf = buf; - ioc.len = 32; - ioc.set = TRUE; - - ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); - if (ret < 0) { - DHD_ERROR(("%s: set cur_etheraddr failed\n", dhd_ifname(&dhd->pub, ifidx))); - } else { - memcpy(dhd->iflist[ifidx]->net->dev_addr, addr, ETHER_ADDR_LEN); - memcpy(dhd->pub.mac.octet, addr, ETHER_ADDR_LEN); - } - - return ret; -} - -#ifdef SOFTAP -extern struct net_device *ap_net_dev; -extern tsk_ctl_t ap_eth_ctl; /* ap netdev heper thread ctl */ -#endif - -static void -dhd_op_if(dhd_if_t *ifp) -{ - dhd_info_t *dhd; - int ret = 0, err = 0; -#ifdef SOFTAP - unsigned long flags; -#endif - - if (!ifp || !ifp->info || !ifp->idx) - return; - ASSERT(ifp && ifp->info && ifp->idx); /* Virtual interfaces only */ - dhd = ifp->info; - - DHD_TRACE(("%s: idx %d, state %d\n", __FUNCTION__, ifp->idx, ifp->state)); - -#ifdef WL_CFG80211 - if (wl_cfg80211_is_progress_ifchange()) - return; - -#endif - switch (ifp->state) { - case DHD_IF_ADD: - /* - * Delete the existing interface before overwriting it - * in case we missed the WLC_E_IF_DEL event. - */ - if (ifp->net != NULL) { - DHD_ERROR(("%s: ERROR: netdev:%s already exists, try free & unregister \n", - __FUNCTION__, ifp->net->name)); - netif_stop_queue(ifp->net); - unregister_netdev(ifp->net); - free_netdev(ifp->net); - } - /* Allocate etherdev, including space for private structure */ - if (!(ifp->net = alloc_etherdev(sizeof(dhd)))) { - DHD_ERROR(("%s: OOM - alloc_etherdev\n", __FUNCTION__)); - ret = -ENOMEM; - } - if (ret == 0) { - strncpy(ifp->net->name, ifp->name, IFNAMSIZ); - ifp->net->name[IFNAMSIZ - 1] = '\0'; - memcpy(netdev_priv(ifp->net), &dhd, sizeof(dhd)); -#ifdef WL_CFG80211 - if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) - if (!wl_cfg80211_notify_ifadd(ifp->net, ifp->idx, ifp->bssidx, - (void*)dhd_net_attach)) { - ifp->state = DHD_IF_NONE; - return; - } -#endif - if ((err = dhd_net_attach(&dhd->pub, ifp->idx)) != 0) { - DHD_ERROR(("%s: dhd_net_attach failed, err %d\n", - __FUNCTION__, err)); - ret = -EOPNOTSUPP; - } else { -#if defined(SOFTAP) - if (ap_fw_loaded && !(dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)) { - /* semaphore that the soft AP CODE waits on */ - flags = dhd_os_spin_lock(&dhd->pub); - - /* save ptr to wl0.1 netdev for use in wl_iw.c */ - ap_net_dev = ifp->net; - /* signal to the SOFTAP 'sleeper' thread, wl0.1 is ready */ - up(&ap_eth_ctl.sema); - dhd_os_spin_unlock(&dhd->pub, flags); - } -#endif - DHD_TRACE(("\n ==== pid:%x, net_device for if:%s created ===\n\n", - current->pid, ifp->net->name)); - ifp->state = DHD_IF_NONE; - } - } - break; - case DHD_IF_DEL: - /* Make sure that we don't enter again here if .. */ - /* dhd_op_if is called again from some other context */ - ifp->state = DHD_IF_DELETING; - if (ifp->net != NULL) { - DHD_TRACE(("\n%s: got 'DHD_IF_DEL' state\n", __FUNCTION__)); -#ifdef WL_CFG80211 - if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) { - wl_cfg80211_ifdel_ops(ifp->net); - } -#endif - netif_stop_queue(ifp->net); - unregister_netdev(ifp->net); - ret = DHD_DEL_IF; /* Make sure the free_netdev() is called */ - -#ifdef WL_CFG80211 - if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) { - wl_cfg80211_notify_ifdel(); - } -#endif - } - break; - case DHD_IF_DELETING: - break; - default: - DHD_ERROR(("%s: bad op %d\n", __FUNCTION__, ifp->state)); - ASSERT(!ifp->state); - break; - } - - if (ret < 0) { - ifp->set_multicast = FALSE; - if (ifp->net) { - free_netdev(ifp->net); - ifp->net = NULL; - } - dhd->iflist[ifp->idx] = NULL; -#ifdef SOFTAP - flags = dhd_os_spin_lock(&dhd->pub); - if (ifp->net == ap_net_dev) - ap_net_dev = NULL; /* NULL SOFTAP global wl0.1 as well */ - dhd_os_spin_unlock(&dhd->pub, flags); -#endif /* SOFTAP */ - MFREE(dhd->pub.osh, ifp, sizeof(*ifp)); - } -} - -static int -_dhd_sysioc_thread(void *data) -{ - tsk_ctl_t *tsk = (tsk_ctl_t *)data; - dhd_info_t *dhd = (dhd_info_t *)tsk->parent; - - - int i; -#ifdef SOFTAP - bool in_ap = FALSE; - unsigned long flags; -#endif - - DAEMONIZE("dhd_sysioc"); - - complete(&tsk->completed); - - while (down_interruptible(&tsk->sema) == 0) { - - SMP_RD_BARRIER_DEPENDS(); - if (tsk->terminated) { - break; - } - - dhd_net_if_lock_local(dhd); - DHD_OS_WAKE_LOCK(&dhd->pub); - - for (i = 0; i < DHD_MAX_IFS; i++) { - if (dhd->iflist[i]) { - DHD_TRACE(("%s: interface %d\n", __FUNCTION__, i)); -#ifdef SOFTAP - flags = dhd_os_spin_lock(&dhd->pub); - in_ap = (ap_net_dev != NULL); - dhd_os_spin_unlock(&dhd->pub, flags); -#endif /* SOFTAP */ - if (dhd->iflist[i] && dhd->iflist[i]->state) - dhd_op_if(dhd->iflist[i]); - - if (dhd->iflist[i] == NULL) { - DHD_TRACE(("\n\n %s: interface %d just been removed," - "!\n\n", __FUNCTION__, i)); - continue; - } -#ifdef SOFTAP - if (in_ap && dhd->set_macaddress) { - DHD_TRACE(("attempt to set MAC for %s in AP Mode," - "blocked. \n", dhd->iflist[i]->net->name)); - dhd->set_macaddress = FALSE; - continue; - } - - if (in_ap && dhd->iflist[i]->set_multicast) { - DHD_TRACE(("attempt to set MULTICAST list for %s" - "in AP Mode, blocked. \n", dhd->iflist[i]->net->name)); - dhd->iflist[i]->set_multicast = FALSE; - continue; - } -#endif /* SOFTAP */ - if (dhd->iflist[i]->set_multicast) { - dhd->iflist[i]->set_multicast = FALSE; - _dhd_set_multicast_list(dhd, i); - } - if (dhd->set_macaddress) { - dhd->set_macaddress = FALSE; - _dhd_set_mac_address(dhd, i, &dhd->macvalue); - } - } - } - - DHD_OS_WAKE_UNLOCK(&dhd->pub); - dhd_net_if_unlock_local(dhd); - } - DHD_TRACE(("%s: stopped\n", __FUNCTION__)); - complete_and_exit(&tsk->completed, 0); -} - -static int -dhd_set_mac_address(struct net_device *dev, void *addr) -{ - int ret = 0; - - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - struct sockaddr *sa = (struct sockaddr *)addr; - int ifidx; - - ifidx = dhd_net2idx(dhd, dev); - if (ifidx == DHD_BAD_IF) - return -1; - - ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0); - memcpy(&dhd->macvalue, sa->sa_data, ETHER_ADDR_LEN); - dhd->set_macaddress = TRUE; - up(&dhd->thr_sysioc_ctl.sema); - - return ret; -} - -static void -dhd_set_multicast_list(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ifidx; - - ifidx = dhd_net2idx(dhd, dev); - if (ifidx == DHD_BAD_IF) - return; - - ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0); - dhd->iflist[ifidx]->set_multicast = TRUE; - up(&dhd->thr_sysioc_ctl.sema); -} - -#ifdef PROP_TXSTATUS -int -dhd_os_wlfc_block(dhd_pub_t *pub) -{ - dhd_info_t *di = (dhd_info_t *)(pub->info); - ASSERT(di != NULL); - - spin_lock_bh(&di->wlfc_spinlock); - return 1; -} - -int -dhd_os_wlfc_unblock(dhd_pub_t *pub) -{ - dhd_info_t *di = (dhd_info_t *)(pub->info); - ASSERT(di != NULL); - spin_unlock_bh(&di->wlfc_spinlock); - return 1; -} - -const uint8 wme_fifo2ac[] = { 0, 1, 2, 3, 1, 1 }; -uint8 prio2fifo[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; -#define WME_PRIO2AC(prio) wme_fifo2ac[prio2fifo[(prio)]] - -#endif /* PROP_TXSTATUS */ -int -dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf) -{ - int ret; - dhd_info_t *dhd = (dhd_info_t *)(dhdp->info); - struct ether_header *eh = NULL; - - /* Reject if down */ - if (!dhdp->up || (dhdp->busstate == DHD_BUS_DOWN)) { - /* free the packet here since the caller won't */ - PKTFREE(dhdp->osh, pktbuf, TRUE); - return -ENODEV; - } - - /* Update multicast statistic */ - if (PKTLEN(dhdp->osh, pktbuf) >= ETHER_HDR_LEN) { - uint8 *pktdata = (uint8 *)PKTDATA(dhdp->osh, pktbuf); - eh = (struct ether_header *)pktdata; - - if (ETHER_ISMULTI(eh->ether_dhost)) - dhdp->tx_multicast++; - if (ntoh16(eh->ether_type) == ETHER_TYPE_802_1X) - atomic_inc(&dhd->pend_8021x_cnt); - } else { - PKTFREE(dhd->pub.osh, pktbuf, TRUE); - return BCME_ERROR; - } - - /* Look into the packet and update the packet priority */ - if (PKTPRIO(pktbuf) == 0) - pktsetprio(pktbuf, FALSE); - -#ifdef PROP_TXSTATUS - if (dhdp->wlfc_state) { - /* store the interface ID */ - DHD_PKTTAG_SETIF(PKTTAG(pktbuf), ifidx); - - /* store destination MAC in the tag as well */ - DHD_PKTTAG_SETDSTN(PKTTAG(pktbuf), eh->ether_dhost); - - /* decide which FIFO this packet belongs to */ - if (ETHER_ISMULTI(eh->ether_dhost)) - /* one additional queue index (highest AC + 1) is used for bc/mc queue */ - DHD_PKTTAG_SETFIFO(PKTTAG(pktbuf), AC_COUNT); - else - DHD_PKTTAG_SETFIFO(PKTTAG(pktbuf), WME_PRIO2AC(PKTPRIO(pktbuf))); - } else -#endif /* PROP_TXSTATUS */ - /* If the protocol uses a data header, apply it */ - dhd_prot_hdrpush(dhdp, ifidx, pktbuf); - - /* Use bus module to send data frame */ -#ifdef WLMEDIA_HTSF - dhd_htsf_addtxts(dhdp, pktbuf); -#endif -#ifdef PROP_TXSTATUS - if (dhdp->wlfc_state && ((athost_wl_status_info_t*)dhdp->wlfc_state)->proptxstatus_mode - != WLFC_FCMODE_NONE) { - dhd_os_wlfc_block(dhdp); - ret = dhd_wlfc_enque_sendq(dhdp->wlfc_state, DHD_PKTTAG_FIFO(PKTTAG(pktbuf)), - pktbuf); - dhd_wlfc_commit_packets(dhdp->wlfc_state, (f_commitpkt_t)dhd_bus_txdata, - dhdp->bus); - if (((athost_wl_status_info_t*)dhdp->wlfc_state)->toggle_host_if) { - ((athost_wl_status_info_t*)dhdp->wlfc_state)->toggle_host_if = 0; - } - dhd_os_wlfc_unblock(dhdp); - } - else - /* non-proptxstatus way */ - ret = dhd_bus_txdata(dhdp->bus, pktbuf); -#else - ret = dhd_bus_txdata(dhdp->bus, pktbuf); -#endif /* PROP_TXSTATUS */ - - - return ret; -} - -int -dhd_start_xmit(struct sk_buff *skb, struct net_device *net) -{ - int ret; - void *pktbuf; - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); - int ifidx; -#ifdef WLMEDIA_HTSF - uint8 htsfdlystat_sz = dhd->pub.htsfdlystat_sz; -#else - uint8 htsfdlystat_sz = 0; -#endif - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - DHD_OS_WAKE_LOCK(&dhd->pub); - - /* Reject if down */ - if (!dhd->pub.up || (dhd->pub.busstate == DHD_BUS_DOWN)) { - DHD_ERROR(("%s: xmit rejected pub.up=%d busstate=%d \n", - __FUNCTION__, dhd->pub.up, dhd->pub.busstate)); - netif_stop_queue(net); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - /* Send Event when bus down detected during data session */ - if (dhd->pub.busstate == DHD_BUS_DOWN) { - DHD_ERROR(("%s: Event HANG sent up\n", __FUNCTION__)); - net_os_send_hang_message(net); - } -#endif - DHD_OS_WAKE_UNLOCK(&dhd->pub); - return -ENODEV; - } - - ifidx = dhd_net2idx(dhd, net); - if (ifidx == DHD_BAD_IF) { - DHD_ERROR(("%s: bad ifidx %d\n", __FUNCTION__, ifidx)); - netif_stop_queue(net); - DHD_OS_WAKE_UNLOCK(&dhd->pub); - return -ENODEV; - } - - /* Make sure there's enough room for any header */ - - if (skb_headroom(skb) < dhd->pub.hdrlen + htsfdlystat_sz) { - struct sk_buff *skb2; - - DHD_INFO(("%s: insufficient headroom\n", - dhd_ifname(&dhd->pub, ifidx))); - dhd->pub.tx_realloc++; - - skb2 = skb_realloc_headroom(skb, dhd->pub.hdrlen + htsfdlystat_sz); - - dev_kfree_skb(skb); - if ((skb = skb2) == NULL) { - DHD_ERROR(("%s: skb_realloc_headroom failed\n", - dhd_ifname(&dhd->pub, ifidx))); - ret = -ENOMEM; - goto done; - } - } - - /* Convert to packet */ - if (!(pktbuf = PKTFRMNATIVE(dhd->pub.osh, skb))) { - DHD_ERROR(("%s: PKTFRMNATIVE failed\n", - dhd_ifname(&dhd->pub, ifidx))); - dev_kfree_skb_any(skb); - ret = -ENOMEM; - goto done; - } -#ifdef WLMEDIA_HTSF - if (htsfdlystat_sz && PKTLEN(dhd->pub.osh, pktbuf) >= ETHER_ADDR_LEN) { - uint8 *pktdata = (uint8 *)PKTDATA(dhd->pub.osh, pktbuf); - struct ether_header *eh = (struct ether_header *)pktdata; - - if (!ETHER_ISMULTI(eh->ether_dhost) && - (ntoh16(eh->ether_type) == ETHER_TYPE_IP)) { - eh->ether_type = hton16(ETHER_TYPE_BRCM_PKTDLYSTATS); - } - } -#endif - - ret = dhd_sendpkt(&dhd->pub, ifidx, pktbuf); - - -done: - if (ret) { - dhd->pub.dstats.tx_dropped++; - } else { - dhd->pub.tx_packets++; - } - - DHD_OS_WAKE_UNLOCK(&dhd->pub); - - /* Return ok: we always eat the packet */ - return 0; -} - -void -dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool state) -{ - struct net_device *net; - dhd_info_t *dhd = dhdp->info; - int i; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - dhdp->txoff = state; - ASSERT(dhd); - - if (ifidx == ALL_INTERFACES) { - /* Flow control on all active interfaces */ - for (i = 0; i < DHD_MAX_IFS; i++) { - if (dhd->iflist[i]) { - net = dhd->iflist[i]->net; - if (state == ON) - netif_stop_queue(net); - else - netif_wake_queue(net); - } - } - } - else { - if (dhd->iflist[ifidx]) { - net = dhd->iflist[ifidx]->net; - if (state == ON) - netif_stop_queue(net); - else - netif_wake_queue(net); - } - } -} - -void -dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) -{ - dhd_info_t *dhd = (dhd_info_t *)dhdp->info; - struct sk_buff *skb; - uchar *eth; - uint len; - void *data, *pnext = NULL, *save_pktbuf; - int i; - dhd_if_t *ifp; - wl_event_msg_t event; - int tout_rx = 0; - int tout_ctrl = 0; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - save_pktbuf = pktbuf; - - for (i = 0; pktbuf && i < numpkt; i++, pktbuf = pnext) { - struct ether_header *eh; - struct dot11_llc_snap_header *lsh; - - ifp = dhd->iflist[ifidx]; - if (ifp == NULL) { - DHD_ERROR(("%s: ifp is NULL. drop packet\n", - __FUNCTION__)); - PKTFREE(dhdp->osh, pktbuf, TRUE); - continue; - } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - /* Dropping packets before registering net device to avoid kernel panic */ - if (!ifp->net || ifp->net->reg_state != NETREG_REGISTERED || - !dhd->pub.up) { - DHD_ERROR(("%s: net device is NOT registered yet. drop packet\n", - __FUNCTION__)); - PKTFREE(dhdp->osh, pktbuf, TRUE); - continue; - } -#endif - - pnext = PKTNEXT(dhdp->osh, pktbuf); - PKTSETNEXT(wl->sh.osh, pktbuf, NULL); - - eh = (struct ether_header *)PKTDATA(wl->sh.osh, pktbuf); - lsh = (struct dot11_llc_snap_header *)&eh[1]; - - if ((ntoh16(eh->ether_type) < ETHER_TYPE_MIN) && - (PKTLEN(wl->sh.osh, pktbuf) >= RFC1042_HDR_LEN) && - bcmp(lsh, BT_SIG_SNAP_MPROT, DOT11_LLC_SNAP_HDR_LEN - 2) == 0 && - lsh->type == HTON16(BTA_PROT_L2CAP)) { - amp_hci_ACL_data_t *ACL_data = (amp_hci_ACL_data_t *) - ((uint8 *)eh + RFC1042_HDR_LEN); - ACL_data = NULL; - } - -#ifdef PROP_TXSTATUS - if (dhdp->wlfc_state && PKTLEN(wl->sh.osh, pktbuf) == 0) { - /* WLFC may send header only packet when - there is an urgent message but no packet to - piggy-back on - */ - ((athost_wl_status_info_t*)dhdp->wlfc_state)->stats.wlfc_header_only_pkt++; - PKTFREE(dhdp->osh, pktbuf, TRUE); - DHD_TRACE(("RX: wlfc header \n")); - continue; - } -#endif - - skb = PKTTONATIVE(dhdp->osh, pktbuf); - - /* Get the protocol, maintain skb around eth_type_trans() - * The main reason for this hack is for the limitation of - * Linux 2.4 where 'eth_type_trans' uses the 'net->hard_header_len' - * to perform skb_pull inside vs ETH_HLEN. Since to avoid - * coping of the packet coming from the network stack to add - * BDC, Hardware header etc, during network interface registration - * we set the 'net->hard_header_len' to ETH_HLEN + extra space required - * for BDC, Hardware header etc. and not just the ETH_HLEN - */ - eth = skb->data; - len = skb->len; - - ifp = dhd->iflist[ifidx]; - if (ifp == NULL) - ifp = dhd->iflist[0]; - - ASSERT(ifp); - skb->dev = ifp->net; - skb->protocol = eth_type_trans(skb, skb->dev); - - if (skb->pkt_type == PACKET_MULTICAST) { - dhd->pub.rx_multicast++; - } - - skb->data = eth; - skb->len = len; - -#ifdef WLMEDIA_HTSF - dhd_htsf_addrxts(dhdp, pktbuf); -#endif - /* Strip header, count, deliver upward */ - skb_pull(skb, ETH_HLEN); - - /* Process special event packets and then discard them */ - if (ntoh16(skb->protocol) == ETHER_TYPE_BRCM) { - dhd_wl_host_event(dhd, &ifidx, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) - skb->mac_header, -#else - skb->mac.raw, -#endif - &event, - &data); - - wl_event_to_host_order(&event); - if (!tout_ctrl) - tout_ctrl = DHD_PACKET_TIMEOUT_MS; -#ifdef PNO_SUPPORT - if (event.event_type == WLC_E_PFN_NET_FOUND) { - tout_ctrl = 7 * DHD_PACKET_TIMEOUT_MS; - } -#endif /* PNO_SUPPORT */ - if (event.event_type == WLC_E_BTA_HCI_EVENT) { - dhd_bta_doevt(dhdp, data, event.datalen); - } - } else { - tout_rx = DHD_PACKET_TIMEOUT_MS; - } - - ASSERT(ifidx < DHD_MAX_IFS && dhd->iflist[ifidx]); - if (dhd->iflist[ifidx] && !dhd->iflist[ifidx]->state) - ifp = dhd->iflist[ifidx]; - - if (ifp->net) - ifp->net->last_rx = jiffies; - - dhdp->dstats.rx_bytes += skb->len; - dhdp->rx_packets++; /* Local count */ - - if (in_interrupt()) { - netif_rx(skb); - } else { - /* If the receive is not processed inside an ISR, - * the softirqd must be woken explicitly to service - * the NET_RX_SOFTIRQ. In 2.6 kernels, this is handled - * by netif_rx_ni(), but in earlier kernels, we need - * to do it manually. - */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - netif_rx_ni(skb); -#else - ulong flags; - netif_rx(skb); - local_irq_save(flags); - RAISE_RX_SOFTIRQ(); - local_irq_restore(flags); -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) */ - } - } - - DHD_OS_WAKE_LOCK_RX_TIMEOUT_ENABLE(dhdp, tout_rx); - DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(dhdp, tout_ctrl); -} - -void -dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx) -{ - /* Linux version has nothing to do */ - return; -} - -void -dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success) -{ - uint ifidx; - dhd_info_t *dhd = (dhd_info_t *)(dhdp->info); - struct ether_header *eh; - uint16 type; - uint len; - - dhd_prot_hdrpull(dhdp, &ifidx, txp); - - eh = (struct ether_header *)PKTDATA(dhdp->osh, txp); - type = ntoh16(eh->ether_type); - - if (type == ETHER_TYPE_802_1X) - atomic_dec(&dhd->pend_8021x_cnt); - - /* Crack open the packet and check to see if it is BT HCI ACL data packet. - * If yes generate packet completion event. - */ - len = PKTLEN(dhdp->osh, txp); - - /* Generate ACL data tx completion event locally to avoid SDIO bus transaction */ - if ((type < ETHER_TYPE_MIN) && (len >= RFC1042_HDR_LEN)) { - struct dot11_llc_snap_header *lsh = (struct dot11_llc_snap_header *)&eh[1]; - - if (bcmp(lsh, BT_SIG_SNAP_MPROT, DOT11_LLC_SNAP_HDR_LEN - 2) == 0 && - ntoh16(lsh->type) == BTA_PROT_L2CAP) { - - dhd_bta_tx_hcidata_complete(dhdp, txp, success); - } - } -} - -static struct net_device_stats * -dhd_get_stats(struct net_device *net) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); - dhd_if_t *ifp; - int ifidx; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - ifidx = dhd_net2idx(dhd, net); - if (ifidx == DHD_BAD_IF) { - DHD_ERROR(("%s: BAD_IF\n", __FUNCTION__)); - return NULL; - } - - ifp = dhd->iflist[ifidx]; - ASSERT(dhd && ifp); - - if (dhd->pub.up) { - /* Use the protocol to get dongle stats */ - dhd_prot_dstats(&dhd->pub); - } - - /* Copy dongle stats to net device stats */ - ifp->stats.rx_packets = dhd->pub.dstats.rx_packets; - ifp->stats.tx_packets = dhd->pub.dstats.tx_packets; - ifp->stats.rx_bytes = dhd->pub.dstats.rx_bytes; - ifp->stats.tx_bytes = dhd->pub.dstats.tx_bytes; - ifp->stats.rx_errors = dhd->pub.dstats.rx_errors; - ifp->stats.tx_errors = dhd->pub.dstats.tx_errors; - ifp->stats.rx_dropped = dhd->pub.dstats.rx_dropped; - ifp->stats.tx_dropped = dhd->pub.dstats.tx_dropped; - ifp->stats.multicast = dhd->pub.dstats.multicast; - - return &ifp->stats; -} - -#ifdef DHDTHREAD -static int -dhd_watchdog_thread(void *data) -{ - tsk_ctl_t *tsk = (tsk_ctl_t *)data; - dhd_info_t *dhd = (dhd_info_t *)tsk->parent; - /* This thread doesn't need any user-level access, - * so get rid of all our resources - */ - if (dhd_watchdog_prio > 0) { - struct sched_param param; - param.sched_priority = (dhd_watchdog_prio < MAX_RT_PRIO)? - dhd_watchdog_prio:(MAX_RT_PRIO-1); - setScheduler(current, SCHED_FIFO, ¶m); - } - - DAEMONIZE("dhd_watchdog"); - - /* Run until signal received */ - complete(&tsk->completed); - - while (1) - if (down_interruptible (&tsk->sema) == 0) { - unsigned long flags; - - SMP_RD_BARRIER_DEPENDS(); - if (tsk->terminated) { - break; - } - - dhd_os_sdlock(&dhd->pub); - if (dhd->pub.dongle_reset == FALSE) { - DHD_TIMER(("%s:\n", __FUNCTION__)); - - /* Call the bus module watchdog */ - dhd_bus_watchdog(&dhd->pub); - - flags = dhd_os_spin_lock(&dhd->pub); - /* Count the tick for reference */ - dhd->pub.tickcnt++; - /* Reschedule the watchdog */ - if (dhd->wd_timer_valid) - mod_timer(&dhd->timer, - jiffies + msecs_to_jiffies(dhd_watchdog_ms)); - dhd_os_spin_unlock(&dhd->pub, flags); - } - dhd_os_sdunlock(&dhd->pub); - } else { - break; - } - - complete_and_exit(&tsk->completed, 0); -} -#endif /* DHDTHREAD */ - -static void dhd_watchdog(ulong data) -{ - dhd_info_t *dhd = (dhd_info_t *)data; - unsigned long flags; - - if (dhd->pub.dongle_reset) { - return; - } - -#ifdef DHDTHREAD - if (dhd->thr_wdt_ctl.thr_pid >= 0) { - up(&dhd->thr_wdt_ctl.sema); - return; - } -#endif /* DHDTHREAD */ - - dhd_os_sdlock(&dhd->pub); - /* Call the bus module watchdog */ - dhd_bus_watchdog(&dhd->pub); - - flags = dhd_os_spin_lock(&dhd->pub); - /* Count the tick for reference */ - dhd->pub.tickcnt++; - - /* Reschedule the watchdog */ - if (dhd->wd_timer_valid) - mod_timer(&dhd->timer, jiffies + msecs_to_jiffies(dhd_watchdog_ms)); - dhd_os_spin_unlock(&dhd->pub, flags); - dhd_os_sdunlock(&dhd->pub); -} - -#ifdef DHDTHREAD -static int -dhd_dpc_thread(void *data) -{ - tsk_ctl_t *tsk = (tsk_ctl_t *)data; - dhd_info_t *dhd = (dhd_info_t *)tsk->parent; - - /* This thread doesn't need any user-level access, - * so get rid of all our resources - */ - if (dhd_dpc_prio > 0) - { - struct sched_param param; - param.sched_priority = (dhd_dpc_prio < MAX_RT_PRIO)?dhd_dpc_prio:(MAX_RT_PRIO-1); - setScheduler(current, SCHED_FIFO, ¶m); - } - - DAEMONIZE("dhd_dpc"); - /* DHD_OS_WAKE_LOCK is called in dhd_sched_dpc[dhd_linux.c] down below */ - - /* signal: thread has started */ - complete(&tsk->completed); - - /* Run until signal received */ - while (1) { - if (down_interruptible(&tsk->sema) == 0) { - - SMP_RD_BARRIER_DEPENDS(); - if (tsk->terminated) { - break; - } - - /* Call bus dpc unless it indicated down (then clean stop) */ - if (dhd->pub.busstate != DHD_BUS_DOWN) { - if (dhd_bus_dpc(dhd->pub.bus)) { - up(&tsk->sema); - } - else { - DHD_OS_WAKE_UNLOCK(&dhd->pub); - } - } else { - if (dhd->pub.up) - dhd_bus_stop(dhd->pub.bus, TRUE); - DHD_OS_WAKE_UNLOCK(&dhd->pub); - } - } - else - break; - } - - complete_and_exit(&tsk->completed, 0); -} -#endif /* DHDTHREAD */ - -static void -dhd_dpc(ulong data) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)data; - - /* this (tasklet) can be scheduled in dhd_sched_dpc[dhd_linux.c] - * down below , wake lock is set, - * the tasklet is initialized in dhd_attach() - */ - /* Call bus dpc unless it indicated down (then clean stop) */ - if (dhd->pub.busstate != DHD_BUS_DOWN) { - if (dhd_bus_dpc(dhd->pub.bus)) - tasklet_schedule(&dhd->tasklet); - else - DHD_OS_WAKE_UNLOCK(&dhd->pub); - } else { - dhd_bus_stop(dhd->pub.bus, TRUE); - DHD_OS_WAKE_UNLOCK(&dhd->pub); - } -} - -void -dhd_sched_dpc(dhd_pub_t *dhdp) -{ - dhd_info_t *dhd = (dhd_info_t *)dhdp->info; - - DHD_OS_WAKE_LOCK(dhdp); -#ifdef DHDTHREAD - if (dhd->thr_dpc_ctl.thr_pid >= 0) { - up(&dhd->thr_dpc_ctl.sema); - return; - } -#endif /* DHDTHREAD */ - - tasklet_schedule(&dhd->tasklet); -} - -#ifdef TOE -/* Retrieve current toe component enables, which are kept as a bitmap in toe_ol iovar */ -static int -dhd_toe_get(dhd_info_t *dhd, int ifidx, uint32 *toe_ol) -{ - wl_ioctl_t ioc; - char buf[32]; - int ret; - - memset(&ioc, 0, sizeof(ioc)); - - ioc.cmd = WLC_GET_VAR; - ioc.buf = buf; - ioc.len = (uint)sizeof(buf); - ioc.set = FALSE; - - strcpy(buf, "toe_ol"); - if ((ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) { - /* Check for older dongle image that doesn't support toe_ol */ - if (ret == -EIO) { - DHD_ERROR(("%s: toe not supported by device\n", - dhd_ifname(&dhd->pub, ifidx))); - return -EOPNOTSUPP; - } - - DHD_INFO(("%s: could not get toe_ol: ret=%d\n", dhd_ifname(&dhd->pub, ifidx), ret)); - return ret; - } - - memcpy(toe_ol, buf, sizeof(uint32)); - return 0; -} - -/* Set current toe component enables in toe_ol iovar, and set toe global enable iovar */ -static int -dhd_toe_set(dhd_info_t *dhd, int ifidx, uint32 toe_ol) -{ - wl_ioctl_t ioc; - char buf[32]; - int toe, ret; - - memset(&ioc, 0, sizeof(ioc)); - - ioc.cmd = WLC_SET_VAR; - ioc.buf = buf; - ioc.len = (uint)sizeof(buf); - ioc.set = TRUE; - - /* Set toe_ol as requested */ - - strcpy(buf, "toe_ol"); - memcpy(&buf[sizeof("toe_ol")], &toe_ol, sizeof(uint32)); - - if ((ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) { - DHD_ERROR(("%s: could not set toe_ol: ret=%d\n", - dhd_ifname(&dhd->pub, ifidx), ret)); - return ret; - } - - /* Enable toe globally only if any components are enabled. */ - - toe = (toe_ol != 0); - - strcpy(buf, "toe"); - memcpy(&buf[sizeof("toe")], &toe, sizeof(uint32)); - - if ((ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) { - DHD_ERROR(("%s: could not set toe: ret=%d\n", dhd_ifname(&dhd->pub, ifidx), ret)); - return ret; - } - - return 0; -} -#endif /* TOE */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) -static void -dhd_ethtool_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); - - sprintf(info->driver, "wl"); - sprintf(info->version, "%lu", dhd->pub.drv_version); -} - -struct ethtool_ops dhd_ethtool_ops = { - .get_drvinfo = dhd_ethtool_get_drvinfo -}; -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */ - - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) -static int -dhd_ethtool(dhd_info_t *dhd, void *uaddr) -{ - struct ethtool_drvinfo info; - char drvname[sizeof(info.driver)]; - uint32 cmd; -#ifdef TOE - struct ethtool_value edata; - uint32 toe_cmpnt, csum_dir; - int ret; -#endif - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* all ethtool calls start with a cmd word */ - if (copy_from_user(&cmd, uaddr, sizeof (uint32))) - return -EFAULT; - - switch (cmd) { - case ETHTOOL_GDRVINFO: - /* Copy out any request driver name */ - if (copy_from_user(&info, uaddr, sizeof(info))) - return -EFAULT; - strncpy(drvname, info.driver, sizeof(info.driver)); - drvname[sizeof(info.driver)-1] = '\0'; - - /* clear struct for return */ - memset(&info, 0, sizeof(info)); - info.cmd = cmd; - - /* if dhd requested, identify ourselves */ - if (strcmp(drvname, "?dhd") == 0) { - sprintf(info.driver, "dhd"); - strcpy(info.version, EPI_VERSION_STR); - } - - /* otherwise, require dongle to be up */ - else if (!dhd->pub.up) { - DHD_ERROR(("%s: dongle is not up\n", __FUNCTION__)); - return -ENODEV; - } - - /* finally, report dongle driver type */ - else if (dhd->pub.iswl) - sprintf(info.driver, "wl"); - else - sprintf(info.driver, "xx"); - - sprintf(info.version, "%lu", dhd->pub.drv_version); - if (copy_to_user(uaddr, &info, sizeof(info))) - return -EFAULT; - DHD_CTL(("%s: given %*s, returning %s\n", __FUNCTION__, - (int)sizeof(drvname), drvname, info.driver)); - break; - -#ifdef TOE - /* Get toe offload components from dongle */ - case ETHTOOL_GRXCSUM: - case ETHTOOL_GTXCSUM: - if ((ret = dhd_toe_get(dhd, 0, &toe_cmpnt)) < 0) - return ret; - - csum_dir = (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL; - - edata.cmd = cmd; - edata.data = (toe_cmpnt & csum_dir) ? 1 : 0; - - if (copy_to_user(uaddr, &edata, sizeof(edata))) - return -EFAULT; - break; - - /* Set toe offload components in dongle */ - case ETHTOOL_SRXCSUM: - case ETHTOOL_STXCSUM: - if (copy_from_user(&edata, uaddr, sizeof(edata))) - return -EFAULT; - - /* Read the current settings, update and write back */ - if ((ret = dhd_toe_get(dhd, 0, &toe_cmpnt)) < 0) - return ret; - - csum_dir = (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL; - - if (edata.data != 0) - toe_cmpnt |= csum_dir; - else - toe_cmpnt &= ~csum_dir; - - if ((ret = dhd_toe_set(dhd, 0, toe_cmpnt)) < 0) - return ret; - - /* If setting TX checksum mode, tell Linux the new mode */ - if (cmd == ETHTOOL_STXCSUM) { - if (edata.data) - dhd->iflist[0]->net->features |= NETIF_F_IP_CSUM; - else - dhd->iflist[0]->net->features &= ~NETIF_F_IP_CSUM; - } - - break; -#endif /* TOE */ - - default: - return -EOPNOTSUPP; - } - - return 0; -} -#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) */ - -static bool dhd_check_hang(struct net_device *net, dhd_pub_t *dhdp, int error) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - if (!dhdp) - return FALSE; - if ((error == -ETIMEDOUT) || ((dhdp->busstate == DHD_BUS_DOWN) && - (!dhdp->dongle_reset))) { - DHD_ERROR(("%s: Event HANG send up due to re=%d te=%d e=%d s=%d\n", __FUNCTION__, - dhdp->rxcnt_timeout, dhdp->txcnt_timeout, error, dhdp->busstate)); - net_os_send_hang_message(net); - return TRUE; - } -#endif - return FALSE; -} - -static int -dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); - dhd_ioctl_t ioc; - int bcmerror = 0; - int buflen = 0; - void *buf = NULL; - uint driver = 0; - int ifidx; - int ret; - - DHD_OS_WAKE_LOCK(&dhd->pub); - - /* send to dongle only if we are not waiting for reload already */ - if (dhd->pub.hang_was_sent) { - DHD_ERROR(("%s: HANG was sent up earlier\n", __FUNCTION__)); - DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(&dhd->pub, DHD_EVENT_TIMEOUT_MS); - DHD_OS_WAKE_UNLOCK(&dhd->pub); - return OSL_ERROR(BCME_DONGLE_DOWN); - } - - ifidx = dhd_net2idx(dhd, net); - DHD_TRACE(("%s: ifidx %d, cmd 0x%04x\n", __FUNCTION__, ifidx, cmd)); - - if (ifidx == DHD_BAD_IF) { - DHD_ERROR(("%s: BAD IF\n", __FUNCTION__)); - DHD_OS_WAKE_UNLOCK(&dhd->pub); - return -1; - } - -#if defined(WL_WIRELESS_EXT) - /* linux wireless extensions */ - if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) { - /* may recurse, do NOT lock */ - ret = wl_iw_ioctl(net, ifr, cmd); - DHD_OS_WAKE_UNLOCK(&dhd->pub); - return ret; - } -#endif /* defined(WL_WIRELESS_EXT) */ - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) - if (cmd == SIOCETHTOOL) { - ret = dhd_ethtool(dhd, (void*)ifr->ifr_data); - DHD_OS_WAKE_UNLOCK(&dhd->pub); - return ret; - } -#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) */ - - if (cmd == SIOCDEVPRIVATE+1) { - ret = wl_android_priv_cmd(net, ifr, cmd); - dhd_check_hang(net, &dhd->pub, ret); - DHD_OS_WAKE_UNLOCK(&dhd->pub); - return ret; - } - - if (cmd != SIOCDEVPRIVATE) { - DHD_OS_WAKE_UNLOCK(&dhd->pub); - return -EOPNOTSUPP; - } - - memset(&ioc, 0, sizeof(ioc)); - - /* Copy the ioc control structure part of ioctl request */ - if (copy_from_user(&ioc, ifr->ifr_data, sizeof(wl_ioctl_t))) { - bcmerror = -BCME_BADADDR; - goto done; - } - - /* Copy out any buffer passed */ - if (ioc.buf) { - buflen = MIN(ioc.len, DHD_IOCTL_MAXLEN); - /* optimization for direct ioctl calls from kernel */ - /* - if (segment_eq(get_fs(), KERNEL_DS)) { - buf = ioc.buf; - } else { - */ - { - if (!(buf = (char*)MALLOC(dhd->pub.osh, buflen))) { - bcmerror = -BCME_NOMEM; - goto done; - } - if (copy_from_user(buf, ioc.buf, buflen)) { - bcmerror = -BCME_BADADDR; - goto done; - } - } - } - - /* To differentiate between wl and dhd read 4 more byes */ - if ((copy_from_user(&driver, (char *)ifr->ifr_data + sizeof(wl_ioctl_t), - sizeof(uint)) != 0)) { - bcmerror = -BCME_BADADDR; - goto done; - } - - if (!capable(CAP_NET_ADMIN)) { - bcmerror = -BCME_EPERM; - goto done; - } - - /* check for local dhd ioctl and handle it */ - if (driver == DHD_IOCTL_MAGIC) { - bcmerror = dhd_ioctl((void *)&dhd->pub, &ioc, buf, buflen); - if (bcmerror) - dhd->pub.bcmerror = bcmerror; - goto done; - } - - /* send to dongle (must be up, and wl). */ - if (dhd->pub.busstate != DHD_BUS_DATA) { - bcmerror = BCME_DONGLE_DOWN; - goto done; - } - - if (!dhd->pub.iswl) { - bcmerror = BCME_DONGLE_DOWN; - goto done; - } - - /* - * Flush the TX queue if required for proper message serialization: - * Intercept WLC_SET_KEY IOCTL - serialize M4 send and set key IOCTL to - * prevent M4 encryption and - * intercept WLC_DISASSOC IOCTL - serialize WPS-DONE and WLC_DISASSOC IOCTL to - * prevent disassoc frame being sent before WPS-DONE frame. - */ - if (ioc.cmd == WLC_SET_KEY || - (ioc.cmd == WLC_SET_VAR && ioc.buf != NULL && - strncmp("wsec_key", ioc.buf, 9) == 0) || - (ioc.cmd == WLC_SET_VAR && ioc.buf != NULL && - strncmp("bsscfg:wsec_key", ioc.buf, 15) == 0) || - ioc.cmd == WLC_DISASSOC) - dhd_wait_pend8021x(net); - -#ifdef WLMEDIA_HTSF - if (ioc.buf) { - /* short cut wl ioctl calls here */ - if (strcmp("htsf", ioc.buf) == 0) { - dhd_ioctl_htsf_get(dhd, 0); - return BCME_OK; - } - - if (strcmp("htsflate", ioc.buf) == 0) { - if (ioc.set) { - memset(ts, 0, sizeof(tstamp_t)*TSMAX); - memset(&maxdelayts, 0, sizeof(tstamp_t)); - maxdelay = 0; - tspktcnt = 0; - maxdelaypktno = 0; - memset(&vi_d1.bin, 0, sizeof(uint32)*NUMBIN); - memset(&vi_d2.bin, 0, sizeof(uint32)*NUMBIN); - memset(&vi_d3.bin, 0, sizeof(uint32)*NUMBIN); - memset(&vi_d4.bin, 0, sizeof(uint32)*NUMBIN); - } else { - dhd_dump_latency(); - } - return BCME_OK; - } - if (strcmp("htsfclear", ioc.buf) == 0) { - memset(&vi_d1.bin, 0, sizeof(uint32)*NUMBIN); - memset(&vi_d2.bin, 0, sizeof(uint32)*NUMBIN); - memset(&vi_d3.bin, 0, sizeof(uint32)*NUMBIN); - memset(&vi_d4.bin, 0, sizeof(uint32)*NUMBIN); - htsf_seqnum = 0; - return BCME_OK; - } - if (strcmp("htsfhis", ioc.buf) == 0) { - dhd_dump_htsfhisto(&vi_d1, "H to D"); - dhd_dump_htsfhisto(&vi_d2, "D to D"); - dhd_dump_htsfhisto(&vi_d3, "D to H"); - dhd_dump_htsfhisto(&vi_d4, "H to H"); - return BCME_OK; - } - if (strcmp("tsport", ioc.buf) == 0) { - if (ioc.set) { - memcpy(&tsport, ioc.buf + 7, 4); - } else { - DHD_ERROR(("current timestamp port: %d \n", tsport)); - } - return BCME_OK; - } - } -#endif /* WLMEDIA_HTSF */ - - bcmerror = dhd_wl_ioctl(&dhd->pub, ifidx, (wl_ioctl_t *)&ioc, buf, buflen); - -done: - dhd_check_hang(net, &dhd->pub, bcmerror); - - if (!bcmerror && buf && ioc.buf) { - if (copy_to_user(ioc.buf, buf, buflen)) - bcmerror = -EFAULT; - } - - if (buf) - MFREE(dhd->pub.osh, buf, buflen); - - DHD_OS_WAKE_UNLOCK(&dhd->pub); - - return OSL_ERROR(bcmerror); -} - -#ifdef WL_CFG80211 -static int -dhd_cleanup_virt_ifaces(dhd_info_t *dhd) -{ - int i = 1; /* Leave ifidx 0 [Primary Interface] */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - int rollback_lock = FALSE; -#endif - - DHD_TRACE(("%s: Enter \n", __func__)); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - /* release lock for unregister_netdev */ - if (rtnl_is_locked()) { - rtnl_unlock(); - rollback_lock = TRUE; - } -#endif - - for (i = 1; i < DHD_MAX_IFS; i++) { - dhd_net_if_lock_local(dhd); - if (dhd->iflist[i]) { - DHD_TRACE(("Deleting IF: %d \n", i)); - if ((dhd->iflist[i]->state != DHD_IF_DEL) && - (dhd->iflist[i]->state != DHD_IF_DELETING)) { - dhd->iflist[i]->state = DHD_IF_DEL; - dhd->iflist[i]->idx = i; - dhd_op_if(dhd->iflist[i]); - } - } - dhd_net_if_unlock_local(dhd); - } - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - if (rollback_lock) - rtnl_lock(); -#endif - - return 0; -} -#endif /* WL_CFG80211 */ - -static int -dhd_stop(struct net_device *net) -{ - int ifidx = 0; - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); - DHD_OS_WAKE_LOCK(&dhd->pub); - DHD_TRACE(("%s: Enter %p\n", __FUNCTION__, net)); - if (dhd->pub.up == 0) { - goto exit; - } - ifidx = dhd_net2idx(dhd, net); - -#ifdef WL_CFG80211 - if (ifidx == 0) { - wl_cfg80211_down(NULL); - - /* - * For CFG80211: Clean up all the left over virtual interfaces - * when the primary Interface is brought down. [ifconfig wlan0 down] - */ - if ((dhd->dhd_state & DHD_ATTACH_STATE_ADD_IF) && - (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)) { - dhd_cleanup_virt_ifaces(dhd); - } - } -#endif - -#ifdef PROP_TXSTATUS - dhd_wlfc_cleanup(&dhd->pub); -#endif - /* Set state and stop OS transmissions */ - dhd->pub.up = 0; - netif_stop_queue(net); - - /* Stop the protocol module */ - dhd_prot_stop(&dhd->pub); - - OLD_MOD_DEC_USE_COUNT; -exit: -#if defined(WL_CFG80211) - if (ifidx == 0 && !dhd_download_fw_on_driverload) - wl_android_wifi_off(net); -#endif - dhd->pub.rxcnt_timeout = 0; - dhd->pub.txcnt_timeout = 0; - - DHD_OS_WAKE_UNLOCK(&dhd->pub); - return 0; -} - -static int -dhd_open(struct net_device *net) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); - -#ifdef TOE - uint32 toe_ol; -#endif - int ifidx; - int32 ret = 0; - - DHD_OS_WAKE_LOCK(&dhd->pub); - /* Update FW path if it was changed */ - if ((firmware_path != NULL) && (firmware_path[0] != '\0')) { - if (firmware_path[strlen(firmware_path)-1] == '\n') - firmware_path[strlen(firmware_path)-1] = '\0'; - strcpy(fw_path, firmware_path); - firmware_path[0] = '\0'; - } - - dhd->pub.hang_was_sent = 0; -#if !defined(WL_CFG80211) - /* - * Force start if ifconfig_up gets called before START command - * We keep WEXT's wl_control_wl_start to provide backward compatibility - * This should be removed in the future - */ - ret = wl_control_wl_start(net); - if (ret != 0) { - DHD_ERROR(("%s: failed with code %d\n", __FUNCTION__, ret)); - ret = -1; - goto exit; - } -#endif - - ifidx = dhd_net2idx(dhd, net); - DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx)); - - if (ifidx < 0) { - DHD_ERROR(("%s: Error: called with invalid IF\n", __FUNCTION__)); - ret = -1; - goto exit; - } - - if (!dhd->iflist[ifidx] || dhd->iflist[ifidx]->state == DHD_IF_DEL) { - DHD_ERROR(("%s: Error: called when IF already deleted\n", __FUNCTION__)); - ret = -1; - goto exit; - } - - if (ifidx == 0) { - atomic_set(&dhd->pend_8021x_cnt, 0); -#if defined(WL_CFG80211) - DHD_ERROR(("\n%s\n", dhd_version)); - if (!dhd_download_fw_on_driverload) { - ret = wl_android_wifi_on(net); - if (ret != 0) { - DHD_ERROR(("%s: failed with code %d\n", __FUNCTION__, ret)); - ret = -1; - goto exit; - } - } -#endif /* defined(WL_CFG80211) */ - - if (dhd->pub.busstate != DHD_BUS_DATA) { - - /* try to bring up bus */ - if ((ret = dhd_bus_start(&dhd->pub)) != 0) { - DHD_ERROR(("%s: failed with code %d\n", __FUNCTION__, ret)); - ret = -1; - goto exit; - } - - } - - /* dhd_prot_init has been called in dhd_bus_start or wl_android_wifi_on */ - memcpy(net->dev_addr, dhd->pub.mac.octet, ETHER_ADDR_LEN); - -#ifdef TOE - /* Get current TOE mode from dongle */ - if (dhd_toe_get(dhd, ifidx, &toe_ol) >= 0 && (toe_ol & TOE_TX_CSUM_OL) != 0) - dhd->iflist[ifidx]->net->features |= NETIF_F_IP_CSUM; - else - dhd->iflist[ifidx]->net->features &= ~NETIF_F_IP_CSUM; -#endif /* TOE */ - -#if defined(WL_CFG80211) - if (unlikely(wl_cfg80211_up(NULL))) { - DHD_ERROR(("%s: failed to bring up cfg80211\n", __FUNCTION__)); - ret = -1; - goto exit; - } -#endif /* WL_CFG80211 */ - } - - /* Allow transmit calls */ - netif_start_queue(net); - dhd->pub.up = 1; - -#ifdef BCMDBGFS - dhd_dbg_init(&dhd->pub); -#endif - - OLD_MOD_INC_USE_COUNT; -exit: - if (ret) - dhd_stop(net); - - DHD_OS_WAKE_UNLOCK(&dhd->pub); - return ret; -} - -int dhd_do_driver_init(struct net_device *net) -{ - dhd_info_t *dhd = NULL; - - if (!net) { - DHD_ERROR(("Primary Interface not initialized \n")); - return -EINVAL; - } - - dhd = *(dhd_info_t **)netdev_priv(net); - - /* If driver is already initialized, do nothing - */ - if (dhd->pub.busstate == DHD_BUS_DATA) { - DHD_TRACE(("Driver already Inititalized. Nothing to do")); - return 0; - } - - if (dhd_open(net) < 0) { - DHD_ERROR(("Driver Init Failed \n")); - return -1; - } - - return 0; -} - -osl_t * -dhd_osl_attach(void *pdev, uint bustype) -{ - return osl_attach(pdev, bustype, TRUE); -} - -void -dhd_osl_detach(osl_t *osh) -{ - if (MALLOCED(osh)) { - DHD_ERROR(("%s: MEMORY LEAK %d bytes\n", __FUNCTION__, MALLOCED(osh))); - } - osl_detach(osh); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - up(&dhd_registration_sem); -#endif -} - -int -dhd_add_if(dhd_info_t *dhd, int ifidx, void *handle, char *name, - uint8 *mac_addr, uint32 flags, uint8 bssidx) -{ - dhd_if_t *ifp; - - DHD_TRACE(("%s: idx %d, handle->%p\n", __FUNCTION__, ifidx, handle)); - - ASSERT(dhd && (ifidx < DHD_MAX_IFS)); - - ifp = dhd->iflist[ifidx]; - if (ifp != NULL) { - if (ifp->net != NULL) { - netif_stop_queue(ifp->net); - unregister_netdev(ifp->net); - free_netdev(ifp->net); - } - } else - if ((ifp = MALLOC(dhd->pub.osh, sizeof(dhd_if_t))) == NULL) { - DHD_ERROR(("%s: OOM - dhd_if_t\n", __FUNCTION__)); - return -ENOMEM; - } - - memset(ifp, 0, sizeof(dhd_if_t)); - ifp->info = dhd; - dhd->iflist[ifidx] = ifp; - strncpy(ifp->name, name, IFNAMSIZ); - ifp->name[IFNAMSIZ] = '\0'; - if (mac_addr != NULL) - memcpy(&ifp->mac_addr, mac_addr, ETHER_ADDR_LEN); - - if (handle == NULL) { - ifp->state = DHD_IF_ADD; - ifp->idx = ifidx; - ifp->bssidx = bssidx; - ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0); - up(&dhd->thr_sysioc_ctl.sema); - } else - ifp->net = (struct net_device *)handle; - - return 0; -} - -void -dhd_del_if(dhd_info_t *dhd, int ifidx) -{ - dhd_if_t *ifp; - - DHD_TRACE(("%s: idx %d\n", __FUNCTION__, ifidx)); - - ASSERT(dhd && ifidx && (ifidx < DHD_MAX_IFS)); - ifp = dhd->iflist[ifidx]; - if (!ifp) { - DHD_ERROR(("%s: Null interface\n", __FUNCTION__)); - return; - } - - ifp->state = DHD_IF_DEL; - ifp->idx = ifidx; - ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0); - up(&dhd->thr_sysioc_ctl.sema); -} - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) -static struct net_device_ops dhd_ops_pri = { - .ndo_open = dhd_open, - .ndo_stop = dhd_stop, - .ndo_get_stats = dhd_get_stats, - .ndo_do_ioctl = dhd_ioctl_entry, - .ndo_start_xmit = dhd_start_xmit, - .ndo_set_mac_address = dhd_set_mac_address, - .ndo_set_multicast_list = dhd_set_multicast_list, -}; - -static struct net_device_ops dhd_ops_virt = { - .ndo_get_stats = dhd_get_stats, - .ndo_do_ioctl = dhd_ioctl_entry, - .ndo_start_xmit = dhd_start_xmit, - .ndo_set_mac_address = dhd_set_mac_address, - .ndo_set_multicast_list = dhd_set_multicast_list, -}; -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) */ - -dhd_pub_t * -dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) -{ - dhd_info_t *dhd = NULL; - struct net_device *net = NULL; - - dhd_attach_states_t dhd_state = DHD_ATTACH_STATE_INIT; - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* updates firmware nvram path if it was provided as module parameters */ - if ((firmware_path != NULL) && (firmware_path[0] != '\0')) - strcpy(fw_path, firmware_path); - if ((nvram_path != NULL) && (nvram_path[0] != '\0')) - strcpy(nv_path, nvram_path); - - /* Allocate etherdev, including space for private structure */ - if (!(net = alloc_etherdev(sizeof(dhd)))) { - DHD_ERROR(("%s: OOM - alloc_etherdev\n", __FUNCTION__)); - goto fail; - } - dhd_state |= DHD_ATTACH_STATE_NET_ALLOC; - - /* Allocate primary dhd_info */ - if (!(dhd = MALLOC(osh, sizeof(dhd_info_t)))) { - DHD_ERROR(("%s: OOM - alloc dhd_info\n", __FUNCTION__)); - goto fail; - } - memset(dhd, 0, sizeof(dhd_info_t)); - -#ifdef DHDTHREAD - dhd->thr_dpc_ctl.thr_pid = DHD_PID_KT_TL_INVALID; - dhd->thr_wdt_ctl.thr_pid = DHD_PID_KT_INVALID; -#else - dhd->dhd_tasklet_create = FALSE; -#endif /* DHDTHREAD */ - dhd->thr_sysioc_ctl.thr_pid = DHD_PID_KT_INVALID; - dhd_state |= DHD_ATTACH_STATE_DHD_ALLOC; - - /* - * Save the dhd_info into the priv - */ - memcpy((void *)netdev_priv(net), &dhd, sizeof(dhd)); - dhd->pub.osh = osh; - - /* Link to info module */ - dhd->pub.info = dhd; - /* Link to bus module */ - dhd->pub.bus = bus; - dhd->pub.hdrlen = bus_hdrlen; - - /* Set network interface name if it was provided as module parameter */ - if (iface_name[0]) { - int len; - char ch; - strncpy(net->name, iface_name, IFNAMSIZ); - net->name[IFNAMSIZ - 1] = 0; - len = strlen(net->name); - ch = net->name[len - 1]; - if ((ch > '9' || ch < '0') && (len < IFNAMSIZ - 2)) - strcat(net->name, "%d"); - } - - sema_init(&dhd->proto_sem, 1); -#ifdef DHDTHREAD - sema_init(&dhd->sdsem, 1); -#endif - -#ifdef PROP_TXSTATUS - spin_lock_init(&dhd->wlfc_spinlock); - dhd->pub.wlfc_enabled = TRUE; -#endif /* PROP_TXSTATUS */ - - /* Initialize other structure content */ - init_waitqueue_head(&dhd->ioctl_resp_wait); - init_waitqueue_head(&dhd->ctrl_wait); - - /* Initialize the spinlocks */ - spin_lock_init(&dhd->sdlock); - spin_lock_init(&dhd->txqlock); - spin_lock_init(&dhd->dhd_lock); - - - if (dhd_add_if(dhd, 0, (void *)net, net->name, NULL, 0, 0) == DHD_BAD_IF) - goto fail; - dhd_state |= DHD_ATTACH_STATE_ADD_IF; - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) - net->open = NULL; -#else - net->netdev_ops = NULL; -#endif - - /* Initialize Wakelock stuff */ - spin_lock_init(&dhd->wakelock_spinlock); - dhd->wakelock_counter = 0; - dhd->wakelock_wd_counter = 0; - dhd->wakelock_rx_timeout_enable = 0; - dhd->wakelock_ctrl_timeout_enable = 0; -#ifdef CONFIG_HAS_WAKELOCK - wake_lock_init(&dhd->wl_wifi, WAKE_LOCK_SUSPEND, "wlan_wake"); - wake_lock_init(&dhd->wl_rxwake, WAKE_LOCK_SUSPEND, "wlan_rx_wake"); - wake_lock_init(&dhd->wl_ctrlwake, WAKE_LOCK_SUSPEND, "wlan_ctrl_wake"); - wake_lock_init(&dhd->wl_wdwake, WAKE_LOCK_SUSPEND, "wlan_wd_wake"); -#endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - mutex_init(&dhd->dhd_net_if_mutex); - mutex_init(&dhd->dhd_suspend_mutex); -#endif - dhd_state |= DHD_ATTACH_STATE_WAKELOCKS_INIT; - - /* Attach and link in the protocol */ - if (dhd_prot_attach(&dhd->pub) != 0) { - DHD_ERROR(("dhd_prot_attach failed\n")); - goto fail; - } - dhd_state |= DHD_ATTACH_STATE_PROT_ATTACH; - -#ifdef WL_CFG80211 - /* Attach and link in the cfg80211 */ - if (unlikely(wl_cfg80211_attach(net, &dhd->pub))) { - DHD_ERROR(("wl_cfg80211_attach failed\n")); - goto fail; - } - - dhd_monitor_init(&dhd->pub); - dhd_state |= DHD_ATTACH_STATE_CFG80211; -#endif -#if defined(WL_WIRELESS_EXT) - /* Attach and link in the iw */ - if (!(dhd_state & DHD_ATTACH_STATE_CFG80211)) { - if (wl_iw_attach(net, (void *)&dhd->pub) != 0) { - DHD_ERROR(("wl_iw_attach failed\n")); - goto fail; - } - dhd_state |= DHD_ATTACH_STATE_WL_ATTACH; - } -#endif /* defined(WL_WIRELESS_EXT) */ - - - /* Set up the watchdog timer */ - init_timer(&dhd->timer); - dhd->timer.data = (ulong)dhd; - dhd->timer.function = dhd_watchdog; - -#ifdef DHDTHREAD - /* Initialize thread based operation and lock */ - if ((dhd_watchdog_prio >= 0) && (dhd_dpc_prio >= 0)) { - dhd->threads_only = TRUE; - } - else { - dhd->threads_only = FALSE; - } - - if (dhd_dpc_prio >= 0) { - /* Initialize watchdog thread */ - PROC_START(dhd_watchdog_thread, dhd, &dhd->thr_wdt_ctl, 0); - } else { - dhd->thr_wdt_ctl.thr_pid = -1; - } - - /* Set up the bottom half handler */ - if (dhd_dpc_prio >= 0) { - /* Initialize DPC thread */ - PROC_START(dhd_dpc_thread, dhd, &dhd->thr_dpc_ctl, 0); - } else { - /* use tasklet for dpc */ - tasklet_init(&dhd->tasklet, dhd_dpc, (ulong)dhd); - dhd->thr_dpc_ctl.thr_pid = -1; - } -#else - /* Set up the bottom half handler */ - tasklet_init(&dhd->tasklet, dhd_dpc, (ulong)dhd); - dhd->dhd_tasklet_create = TRUE; -#endif /* DHDTHREAD */ - - if (dhd_sysioc) { - PROC_START(_dhd_sysioc_thread, dhd, &dhd->thr_sysioc_ctl, 0); - } else { - dhd->thr_sysioc_ctl.thr_pid = -1; - } - dhd_state |= DHD_ATTACH_STATE_THREADS_CREATED; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - INIT_WORK(&dhd->work_hang, dhd_hang_process); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ - /* - * Save the dhd_info into the priv - */ - memcpy(netdev_priv(net), &dhd, sizeof(dhd)); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) - register_pm_notifier(&dhd_sleep_pm_notifier); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ - -#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) - dhd->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 20; - dhd->early_suspend.suspend = dhd_early_suspend; - dhd->early_suspend.resume = dhd_late_resume; - register_early_suspend(&dhd->early_suspend); - dhd_state |= DHD_ATTACH_STATE_EARLYSUSPEND_DONE; -#endif - -#ifdef ARP_OFFLOAD_SUPPORT - dhd->pend_ipaddr = 0; - register_inetaddr_notifier(&dhd_notifier); -#endif /* ARP_OFFLOAD_SUPPORT */ - - dhd_state |= DHD_ATTACH_STATE_DONE; - dhd->dhd_state = dhd_state; - return &dhd->pub; - -fail: - if (dhd_state < DHD_ATTACH_STATE_DHD_ALLOC) { - if (net) free_netdev(net); - } else { - DHD_TRACE(("%s: Calling dhd_detach dhd_state 0x%x &dhd->pub %p\n", - __FUNCTION__, dhd_state, &dhd->pub)); - dhd->dhd_state = dhd_state; - dhd_detach(&dhd->pub); - dhd_free(&dhd->pub); - } - - return NULL; -} - -int -dhd_bus_start(dhd_pub_t *dhdp) -{ - int ret = -1; - dhd_info_t *dhd = (dhd_info_t*)dhdp->info; - unsigned long flags; - - ASSERT(dhd); - - DHD_TRACE(("Enter %s:\n", __FUNCTION__)); - -#ifdef DHDTHREAD - if (dhd->threads_only) - dhd_os_sdlock(dhdp); -#endif /* DHDTHREAD */ - - /* try to download image and nvram to the dongle */ - if ((dhd->pub.busstate == DHD_BUS_DOWN) && - (fw_path != NULL) && (fw_path[0] != '\0') && - (nv_path != NULL) && (nv_path[0] != '\0')) { - /* wake lock moved to dhdsdio_download_firmware */ - if (!(dhd_bus_download_firmware(dhd->pub.bus, dhd->pub.osh, - fw_path, nv_path))) { - DHD_ERROR(("%s: dhdsdio_probe_download failed. firmware = %s nvram = %s\n", - __FUNCTION__, fw_path, nv_path)); -#ifdef DHDTHREAD - if (dhd->threads_only) - dhd_os_sdunlock(dhdp); -#endif /* DHDTHREAD */ - return -1; - } - } - if (dhd->pub.busstate != DHD_BUS_LOAD) { -#ifdef DHDTHREAD - if (dhd->threads_only) - dhd_os_sdunlock(dhdp); -#endif /* DHDTHREAD */ - return -ENETDOWN; - } - - /* Start the watchdog timer */ - dhd->pub.tickcnt = 0; - dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms); - - /* Bring up the bus */ - if ((ret = dhd_bus_init(&dhd->pub, FALSE)) != 0) { - - DHD_ERROR(("%s, dhd_bus_init failed %d\n", __FUNCTION__, ret)); -#ifdef DHDTHREAD - if (dhd->threads_only) - dhd_os_sdunlock(dhdp); -#endif /* DHDTHREAD */ - return ret; - } -#if defined(OOB_INTR_ONLY) - /* Host registration for OOB interrupt */ - if (bcmsdh_register_oob_intr(dhdp)) { - /* deactivate timer and wait for the handler to finish */ - - flags = dhd_os_spin_lock(&dhd->pub); - dhd->wd_timer_valid = FALSE; - dhd_os_spin_unlock(&dhd->pub, flags); - del_timer_sync(&dhd->timer); - DHD_ERROR(("%s Host failed to register for OOB\n", __FUNCTION__)); -#ifdef DHDTHREAD - if (dhd->threads_only) - dhd_os_sdunlock(dhdp); -#endif /* DHDTHREAD */ - DHD_OS_WD_WAKE_UNLOCK(&dhd->pub); - return -ENODEV; - } - - /* Enable oob at firmware */ - dhd_enable_oob_intr(dhd->pub.bus, TRUE); -#endif /* defined(OOB_INTR_ONLY) */ - - /* If bus is not ready, can't come up */ - if (dhd->pub.busstate != DHD_BUS_DATA) { - flags = dhd_os_spin_lock(&dhd->pub); - dhd->wd_timer_valid = FALSE; - dhd_os_spin_unlock(&dhd->pub, flags); - del_timer_sync(&dhd->timer); - DHD_ERROR(("%s failed bus is not ready\n", __FUNCTION__)); -#ifdef DHDTHREAD - if (dhd->threads_only) - dhd_os_sdunlock(dhdp); -#endif /* DHDTHREAD */ - DHD_OS_WD_WAKE_UNLOCK(&dhd->pub); - return -ENODEV; - } - -#ifdef DHDTHREAD - if (dhd->threads_only) - dhd_os_sdunlock(dhdp); -#endif /* DHDTHREAD */ - -#ifdef READ_MACADDR - dhd_read_macaddr(dhd); -#endif - - /* Bus is ready, do any protocol initialization */ - if ((ret = dhd_prot_init(&dhd->pub)) < 0) - return ret; - -#ifdef WRITE_MACADDR - dhd_write_macaddr(dhd->pub.mac.octet); -#endif - -#ifdef ARP_OFFLOAD_SUPPORT - if (dhd->pend_ipaddr) { -#ifdef AOE_IP_ALIAS_SUPPORT - aoe_update_host_ipv4_table(&dhd->pub, dhd->pend_ipaddr, TRUE); -#endif /* AOE_IP_ALIAS_SUPPORT */ - dhd->pend_ipaddr = 0; - } -#endif /* ARP_OFFLOAD_SUPPORT */ - - return 0; -} - -#if !defined(AP) && defined(WLP2P) && defined(WL_ENABLE_P2P_IF) -/* For Android ICS MR2 release, the concurrent mode is enabled by default and the firmware - * name would be fw_bcmdhd.bin. So we need to determine whether P2P is enabled in the STA - * firmware and accordingly enable concurrent mode (Apply P2P settings). SoftAP firmware - * would still be named as fw_bcmdhd_apsta. - */ -static u32 -dhd_concurrent_fw(dhd_pub_t *dhd) -{ - int ret = 0; - char buf[WLC_IOCTL_SMLEN]; - - if ((!op_mode) && (strstr(fw_path, "_p2p") == NULL) && - (strstr(fw_path, "_apsta") == NULL)) { - /* Given path is for the STA firmware. Check whether P2P support is present in - * the firmware. If so, set mode as P2P (concurrent support). - */ - memset(buf, 0, sizeof(buf)); - bcm_mkiovar("p2p", 0, 0, buf, sizeof(buf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), - FALSE, 0)) < 0) { - DHD_ERROR(("%s: Get P2P failed (error=%d)\n", __FUNCTION__, ret)); - } else if (buf[0] == 1) { - DHD_TRACE(("%s: P2P is supported\n", __FUNCTION__)); - return 1; - } - } - return ret; -} -#endif - -/* - * dhd_preinit_ioctls makes special pre-setting in the firmware before radio turns on - * returns : 0 if all settings passed or negative value if anything failed -*/ -int -dhd_preinit_ioctls(dhd_pub_t *dhd) -{ - int ret = 0; - char eventmask[WL_EVENTING_MASK_LEN]; - char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ -#if !defined(WL_CFG80211) - uint up = 0; -#endif /* defined(WL_CFG80211) */ - uint power_mode = PM_FAST; - uint32 dongle_align = DHD_SDALIGN; - uint32 glom = 0; - uint bcn_timeout = DHD_BEACON_TIMEOUT_NORMAL; - - uint retry_max = 3; -#if defined(ARP_OFFLOAD_SUPPORT) - int arpoe = 1; -#endif -#if defined(KEEP_ALIVE) - int res; -#endif /* defined(KEEP_ALIVE) */ - int scan_assoc_time = DHD_SCAN_ACTIVE_TIME; - int scan_unassoc_time = 40; - int scan_passive_time = DHD_SCAN_PASSIVE_TIME; - char buf[WLC_IOCTL_SMLEN]; - char *ptr; - uint32 listen_interval = LISTEN_INTERVAL; /* Default Listen Interval in Beacons */ - uint16 chipID; - int roam_trigger[2] = {CUSTOM_ROAM_TRIGGER_SETTING, WLC_BAND_ALL}; - int roam_delta[2] = {CUSTOM_ROAM_DELTA_SETTING, WLC_BAND_ALL}; -#if defined(SOFTAP) - uint dtim = 1; -#endif -#if (defined(AP) && !defined(WLP2P)) || (!defined(AP) && defined(WL_CFG80211)) - uint32 mpc = 0; /* Turn MPC off for AP/APSTA mode */ -#endif -#if defined(AP) || defined(WLP2P) - uint32 apsta = 1; /* Enable APSTA mode */ -#endif /* defined(AP) || defined(WLP2P) */ -#ifdef GET_CUSTOM_MAC_ENABLE - struct ether_addr ea_addr; -#endif /* GET_CUSTOM_MAC_ENABLE */ - DHD_TRACE(("Enter %s\n", __FUNCTION__)); - dhd->op_mode = 0; -#ifdef GET_CUSTOM_MAC_ENABLE - ret = dhd_custom_get_mac_address(ea_addr.octet); - if (!ret) { - memset(buf, 0, sizeof(buf)); - bcm_mkiovar("cur_etheraddr", (void *)&ea_addr, ETHER_ADDR_LEN, buf, sizeof(buf)); - ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0); - if (ret < 0) { - DHD_ERROR(("%s: can't set custom MAC address , error=%d\n", __FUNCTION__, ret)); - return BCME_NOTUP; - } - memcpy(dhd->mac.octet, ea_addr.octet, ETHER_ADDR_LEN); - } else { -#endif /* GET_CUSTOM_MAC_ENABLE */ - /* Get the default device MAC address directly from firmware */ - memset(buf, 0, sizeof(buf)); - bcm_mkiovar("cur_etheraddr", 0, 0, buf, sizeof(buf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), - FALSE, 0)) < 0) { - DHD_ERROR(("%s: can't get MAC address , error=%d\n", __FUNCTION__, ret)); - return BCME_NOTUP; - } - /* Update public MAC address after reading from Firmware */ - memcpy(dhd->mac.octet, buf, ETHER_ADDR_LEN); -#ifdef GET_CUSTOM_MAC_ENABLE - } -#endif /* GET_CUSTOM_MAC_ENABLE */ - -#ifdef SET_RANDOM_MAC_SOFTAP - if ((!op_mode && strstr(fw_path, "_apsta") != NULL) || (op_mode == HOSTAPD_MASK)) { - uint rand_mac; - - srandom32((uint)jiffies); - rand_mac = random32(); - iovbuf[0] = 0x02; /* locally administered bit */ - iovbuf[1] = 0x1A; - iovbuf[2] = 0x11; - iovbuf[3] = (unsigned char)(rand_mac & 0x0F) | 0xF0; - iovbuf[4] = (unsigned char)(rand_mac >> 8); - iovbuf[5] = (unsigned char)(rand_mac >> 16); - - bcm_mkiovar("cur_etheraddr", (void *)iovbuf, ETHER_ADDR_LEN, buf, sizeof(buf)); - ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0); - if (ret < 0) { - DHD_ERROR(("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret)); - } else - memcpy(dhd->mac.octet, iovbuf, ETHER_ADDR_LEN); - } -#endif /* SET_RANDOM_MAC_SOFTAP */ - - DHD_TRACE(("Firmware = %s\n", fw_path)); - -#if !defined(AP) && defined(WLP2P) - /* Check if firmware with WFD support used */ -#if defined(WL_ENABLE_P2P_IF) - if ((ret = dhd_concurrent_fw(dhd)) < 0) { - DHD_ERROR(("%s error : firmware can't support p2p mode\n", __FUNCTION__)); - goto done; - } -#endif /* (WL_ENABLE_P2P_IF) */ - - if ((!op_mode && strstr(fw_path, "_p2p") != NULL) -#if defined(WL_ENABLE_P2P_IF) - || (op_mode == WFD_MASK) || (dhd_concurrent_fw(dhd) == 1) -#endif - ) { - bcm_mkiovar("apsta", (char *)&apsta, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, - iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s APSTA setting failed ret= %d\n", __FUNCTION__, ret)); - } else { - dhd->op_mode |= WFD_MASK; -#if !defined(WL_ENABLE_P2P_IF) - /* ICS back capability : disable any packet filtering for p2p only mode */ - dhd_pkt_filter_enable = FALSE; -#endif /*!defined(WL_ENABLE_P2P_IF) */ - } - } -#endif - -#if !defined(AP) && defined(WL_CFG80211) - /* Check if firmware with HostAPD support used */ - if ((!op_mode && strstr(fw_path, "_apsta") != NULL) || (op_mode == HOSTAPD_MASK)) { - /* Disable A-band for HostAPD */ - uint band = WLC_BAND_2G; - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_BAND, (char *)&band, sizeof(band), - TRUE, 0)) < 0) { - DHD_ERROR(("%s:set band failed error (%d)\n", __FUNCTION__, ret)); - } - - /* Turn off wme if we are having only g ONLY firmware */ - bcm_mkiovar("nmode", 0, 0, buf, sizeof(buf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), - FALSE, 0)) < 0) { - DHD_ERROR(("%s:get nmode failed error (%d)\n", __FUNCTION__, ret)); - } - else { - DHD_TRACE(("%s:get nmode returned %d\n", __FUNCTION__,buf[0])); - } - if (buf[0] == 0) { - int wme = 0; - bcm_mkiovar("wme", (char *)&wme, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, - sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s set wme for HostAPD failed %d\n", __FUNCTION__, ret)); - } - else { - DHD_TRACE(("%s set wme succeeded for g ONLY firmware\n", __FUNCTION__)); - } - } - /* Turn off MPC in AP mode */ - bcm_mkiovar("mpc", (char *)&mpc, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, - sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s mpc for HostAPD failed %d\n", __FUNCTION__, ret)); - } else { - dhd->op_mode |= HOSTAPD_MASK; -#if defined(ARP_OFFLOAD_SUPPORT) - arpoe = 0; -#endif /* (ARP_OFFLOAD_SUPPORT) */ - /* disable any filtering for SoftAP mode */ - dhd_pkt_filter_enable = FALSE; - } - } -#endif - -#if !defined(WL_ENABLE_P2P_IF) - /* ICS mode setting for sta */ - if ((dhd->op_mode != WFD_MASK) && (dhd->op_mode != HOSTAPD_MASK)) { - /* STA only operation mode */ - dhd->op_mode |= STA_MASK; - dhd_pkt_filter_enable = TRUE; - } -#endif /* !defined(WL_ENABLE_P2P_IF) */ - - DHD_ERROR(("Firmware up: op_mode=%d, " - "Broadcom Dongle Host Driver mac=%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", - dhd->op_mode, - dhd->mac.octet[0], dhd->mac.octet[1], dhd->mac.octet[2], - dhd->mac.octet[3], dhd->mac.octet[4], dhd->mac.octet[5])); - - /* Set Country code */ - if (dhd->dhd_cspec.ccode[0] != 0) { - bcm_mkiovar("country", (char *)&dhd->dhd_cspec, - sizeof(wl_country_t), iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) - DHD_ERROR(("%s: country code setting failed\n", __FUNCTION__)); - } - - /* Set Listen Interval */ - bcm_mkiovar("assoc_listen", (char *)&listen_interval, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) - DHD_ERROR(("%s assoc_listen failed %d\n", __FUNCTION__, ret)); - - /* custom romaing setting */ - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_TRIGGER, roam_trigger, - sizeof(roam_trigger), TRUE, 0)) < 0) - DHD_ERROR(("%s: roam trigger set failed %d\n", __FUNCTION__, ret)); - if ((dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_DELTA, roam_delta, - sizeof(roam_delta), TRUE, 0)) < 0) - DHD_ERROR(("%s: roam delta set failed %d\n", __FUNCTION__, ret)); - - /* Set PowerSave mode */ - dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode), TRUE, 0); - - /* Match Host and Dongle rx alignment */ - bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - - /* disable glom option for some chips */ - chipID = (uint16)dhd_bus_chip_id(dhd); - if ((chipID == BCM4330_CHIP_ID) || (chipID == BCM4329_CHIP_ID)) { - DHD_INFO(("%s disable glom for chipID=0x%X\n", __FUNCTION__, chipID)); - bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - } - - /* Setup timeout if Beacons are lost and roam is off to report link down */ - bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - /* Setup assoc_retry_max count to reconnect target AP in dongle */ - bcm_mkiovar("assoc_retry_max", (char *)&retry_max, 4, iovbuf, sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - -#if defined(AP) && !defined(WLP2P) - /* Turn off MPC in AP mode */ - bcm_mkiovar("mpc", (char *)&mpc, 4, iovbuf, sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - bcm_mkiovar("apsta", (char *)&apsta, 4, iovbuf, sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -#endif /* defined(AP) && !defined(WLP2P) */ - -#if defined(SOFTAP) - if (ap_fw_loaded == TRUE) { - dhd_wl_ioctl_cmd(dhd, WLC_SET_DTIMPRD, (char *)&dtim, sizeof(dtim), TRUE, 0); - } -#endif - -#if defined(KEEP_ALIVE) - /* Set Keep Alive : be sure to use FW with -keepalive */ -#if defined(SOFTAP) - if (ap_fw_loaded == FALSE) -#endif - if ((res = dhd_keep_alive_onoff(dhd)) < 0) - DHD_ERROR(("%s set keeplive failed %d\n", - __FUNCTION__, res)); -#endif /* defined(KEEP_ALIVE) */ - - /* Read event_msgs mask */ - bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0)) < 0) { - DHD_ERROR(("%s read Event mask failed %d\n", __FUNCTION__, ret)); - goto done; - } - bcopy(iovbuf, eventmask, WL_EVENTING_MASK_LEN); - - /* Setup event_msgs */ - setbit(eventmask, WLC_E_SET_SSID); - setbit(eventmask, WLC_E_PRUNE); - setbit(eventmask, WLC_E_AUTH); - setbit(eventmask, WLC_E_ASSOC); - setbit(eventmask, WLC_E_REASSOC); - setbit(eventmask, WLC_E_REASSOC_IND); - setbit(eventmask, WLC_E_DEAUTH); - setbit(eventmask, WLC_E_DEAUTH_IND); - setbit(eventmask, WLC_E_DISASSOC_IND); - setbit(eventmask, WLC_E_DISASSOC); - setbit(eventmask, WLC_E_JOIN); - setbit(eventmask, WLC_E_ASSOC_IND); - setbit(eventmask, WLC_E_PSK_SUP); - setbit(eventmask, WLC_E_LINK); - setbit(eventmask, WLC_E_NDIS_LINK); - setbit(eventmask, WLC_E_MIC_ERROR); - setbit(eventmask, WLC_E_ASSOC_REQ_IE); - setbit(eventmask, WLC_E_ASSOC_RESP_IE); -#ifndef WL_CFG80211 - setbit(eventmask, WLC_E_PMKID_CACHE); - setbit(eventmask, WLC_E_TXFAIL); -#endif - setbit(eventmask, WLC_E_JOIN_START); - setbit(eventmask, WLC_E_SCAN_COMPLETE); -#ifdef WLMEDIA_HTSF - setbit(eventmask, WLC_E_HTSFSYNC); -#endif /* WLMEDIA_HTSF */ -#ifdef PNO_SUPPORT - setbit(eventmask, WLC_E_PFN_NET_FOUND); -#endif /* PNO_SUPPORT */ - /* enable dongle roaming event */ - setbit(eventmask, WLC_E_ROAM); -#ifdef WL_CFG80211 - setbit(eventmask, WLC_E_ESCAN_RESULT); - if ((dhd->op_mode & WFD_MASK) == WFD_MASK) { - setbit(eventmask, WLC_E_ACTION_FRAME_RX); - setbit(eventmask, WLC_E_ACTION_FRAME_COMPLETE); - setbit(eventmask, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE); - setbit(eventmask, WLC_E_P2P_DISC_LISTEN_COMPLETE); - } -#endif /* WL_CFG80211 */ - - /* Write updated Event mask */ - bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s Set Event mask failed %d\n", __FUNCTION__, ret)); - goto done; - } - - dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_CHANNEL_TIME, (char *)&scan_assoc_time, - sizeof(scan_assoc_time), TRUE, 0); - dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_UNASSOC_TIME, (char *)&scan_unassoc_time, - sizeof(scan_unassoc_time), TRUE, 0); - dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_PASSIVE_TIME, (char *)&scan_passive_time, - sizeof(scan_passive_time), TRUE, 0); - -#ifdef ARP_OFFLOAD_SUPPORT - /* Set and enable ARP offload feature for STA only */ -#if defined(SOFTAP) - if (arpoe && !ap_fw_loaded) { -#else - if (arpoe) { -#endif - dhd_arp_offload_set(dhd, dhd_arp_mode); - dhd_arp_offload_enable(dhd, arpoe); - } else { - dhd_arp_offload_set(dhd, 0); - dhd_arp_offload_enable(dhd, FALSE); - } -#endif /* ARP_OFFLOAD_SUPPORT */ - -#ifdef PKT_FILTER_SUPPORT - /* Setup defintions for pktfilter , enable in suspend */ - dhd->pktfilter_count = 5; - /* Setup filter to allow only unicast */ - dhd->pktfilter[0] = "100 0 0 0 0x01 0x00"; - dhd->pktfilter[1] = NULL; - dhd->pktfilter[2] = NULL; - dhd->pktfilter[3] = NULL; - /* Add filter to pass multicastDNS packet and NOT filter out as Broadcast */ - dhd->pktfilter[4] = "104 0 0 0 0xFFFFFFFFFFFF 0x01005E0000FB"; -#if defined(SOFTAP) - if (ap_fw_loaded) { - int i; - for (i = 0; i < dhd->pktfilter_count; i++) { - dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i], - 0, dhd_master_mode); - } - } -#endif /* defined(SOFTAP) */ -#endif /* PKT_FILTER_SUPPORT */ - -#if !defined(WL_CFG80211) - /* Force STA UP */ - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&up, sizeof(up), TRUE, 0)) < 0) { - DHD_ERROR(("%s Setting WL UP failed %d\n", __FUNCTION__, ret)); - goto done; - } -#endif - /* query for 'ver' to get version info from firmware */ - memset(buf, 0, sizeof(buf)); - ptr = buf; - bcm_mkiovar("ver", (char *)&buf, 4, buf, sizeof(buf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), FALSE, 0)) < 0) - DHD_ERROR(("%s failed %d\n", __FUNCTION__, ret)); - else { - bcmstrtok(&ptr, "\n", 0); - /* Print fw version info */ - DHD_ERROR(("Firmware version = %s\n", buf)); - - dhd_set_version_info(dhd, buf); - - DHD_BLOG(buf, strlen(buf) + 1); - DHD_BLOG(dhd_version, strlen(dhd_version) + 1); - - /* Check and adjust IOCTL response timeout for Manufactring firmware */ - if (strstr(buf, MANUFACTRING_FW) != NULL) { - dhd_os_set_ioctl_resp_timeout(IOCTL_RESP_TIMEOUT * 10); - DHD_ERROR(("%s : adjust IOCTL response time for Manufactring Firmware\n", __FUNCTION__)); - } - } - -done: - return ret; -} - - -int -dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf, uint cmd_len, int set) -{ - char buf[strlen(name) + 1 + cmd_len]; - int len = sizeof(buf); - wl_ioctl_t ioc; - int ret; - - len = bcm_mkiovar(name, cmd_buf, cmd_len, buf, len); - - memset(&ioc, 0, sizeof(ioc)); - - ioc.cmd = set? WLC_SET_VAR : WLC_GET_VAR; - ioc.buf = buf; - ioc.len = len; - ioc.set = TRUE; - - ret = dhd_wl_ioctl(pub, ifidx, &ioc, ioc.buf, ioc.len); - if (!set && ret >= 0) - memcpy(cmd_buf, buf, cmd_len); - - return ret; -} - -int dhd_change_mtu(dhd_pub_t *dhdp, int new_mtu, int ifidx) -{ - struct dhd_info *dhd = dhdp->info; - struct net_device *dev = NULL; - - ASSERT(dhd && dhd->iflist[ifidx]); - dev = dhd->iflist[ifidx]->net; - ASSERT(dev); - - if (netif_running(dev)) { - DHD_ERROR(("%s: Must be down to change its MTU", dev->name)); - return BCME_NOTDOWN; - } - -#define DHD_MIN_MTU 1500 -#define DHD_MAX_MTU 1752 - - if ((new_mtu < DHD_MIN_MTU) || (new_mtu > DHD_MAX_MTU)) { - DHD_ERROR(("%s: MTU size %d is invalid.\n", __FUNCTION__, new_mtu)); - return BCME_BADARG; - } - - dev->mtu = new_mtu; - return 0; -} - -#ifdef ARP_OFFLOAD_SUPPORT -/* add or remove AOE host ip(s) (up to 8 IPs on the interface) */ -void -aoe_update_host_ipv4_table(dhd_pub_t *dhd_pub, u32 ipa, bool add) -{ - u32 ipv4_buf[MAX_IPV4_ENTRIES]; /* temp save for AOE host_ip table */ - int i; - int ret; - - bzero(ipv4_buf, sizeof(ipv4_buf)); - - /* display what we've got */ - ret = dhd_arp_get_arp_hostip_table(dhd_pub, ipv4_buf, sizeof(ipv4_buf)); - DHD_ARPOE(("%s: hostip table read from Dongle:\n", __FUNCTION__)); -#ifdef AOE_DBG - dhd_print_buf(ipv4_buf, 32, 4); /* max 8 IPs 4b each */ -#endif - /* now we saved hoste_ip table, clr it in the dongle AOE */ - dhd_aoe_hostip_clr(dhd_pub); - - if (ret) { - DHD_ERROR(("%s failed\n", __FUNCTION__)); - return; - } - - for (i = 0; i < MAX_IPV4_ENTRIES; i++) { - if (add && (ipv4_buf[i] == 0)) { - ipv4_buf[i] = ipa; - add = FALSE; /* added ipa to local table */ - DHD_ARPOE(("%s: Saved new IP in temp arp_hostip[%d]\n", - __FUNCTION__, i)); - } else if (ipv4_buf[i] == ipa) { - ipv4_buf[i] = 0; - DHD_ARPOE(("%s: removed IP:%x from temp table %d\n", - __FUNCTION__, ipa, i)); - } - - if (ipv4_buf[i] != 0) { - /* add back host_ip entries from our local cache */ - dhd_arp_offload_add_ip(dhd_pub, ipv4_buf[i]); - DHD_ARPOE(("%s: added IP:%x to dongle arp_hostip[%d]\n\n", - __FUNCTION__, ipv4_buf[i], i)); - } - } -#ifdef AOE_DBG - /* see the resulting hostip table */ - dhd_arp_get_arp_hostip_table(dhd_pub, ipv4_buf, sizeof(ipv4_buf)); - DHD_ARPOE(("%s: read back arp_hostip table:\n", __FUNCTION__)); - dhd_print_buf(ipv4_buf, 32, 4); /* max 8 IPs 4b each */ -#endif -} - -static int dhd_device_event(struct notifier_block *this, - unsigned long event, - void *ptr) -{ - struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; - - dhd_info_t *dhd; - dhd_pub_t *dhd_pub; - - if (!ifa) - return NOTIFY_DONE; - - dhd = *(dhd_info_t **)netdev_priv(ifa->ifa_dev->dev); - dhd_pub = &dhd->pub; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) - if (ifa->ifa_dev->dev->netdev_ops == &dhd_ops_pri) { -#else - if (ifa->ifa_dev->dev) { -#endif - switch (event) { - case NETDEV_UP: - DHD_ARPOE(("%s: [%s] Up IP: 0x%x\n", - __FUNCTION__, ifa->ifa_label, ifa->ifa_address)); - - if (dhd->pub.busstate != DHD_BUS_DATA) { - DHD_ERROR(("%s: bus not ready, exit\n", __FUNCTION__)); - if (dhd->pend_ipaddr) { - DHD_ERROR(("%s: overwrite pending ipaddr: 0x%x\n", - __FUNCTION__, dhd->pend_ipaddr)); - } - dhd->pend_ipaddr = ifa->ifa_address; - break; - } - -#ifdef AOE_IP_ALIAS_SUPPORT - if (ifa->ifa_label[strlen(ifa->ifa_label)-2] == 0x3a) { - DHD_ARPOE(("%s:add aliased IP to AOE hostip cache\n", - __FUNCTION__)); - aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, TRUE); - } - else - aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, TRUE); -#endif - break; - - case NETDEV_DOWN: - DHD_ARPOE(("%s: [%s] Down IP: 0x%x\n", - __FUNCTION__, ifa->ifa_label, ifa->ifa_address)); - dhd->pend_ipaddr = 0; -#ifdef AOE_IP_ALIAS_SUPPORT - if (!(ifa->ifa_label[strlen(ifa->ifa_label)-2] == 0x3a)) { - DHD_ARPOE(("%s: primary interface is down, AOE clr all\n", - __FUNCTION__)); - dhd_aoe_hostip_clr(&dhd->pub); - dhd_aoe_arp_clr(&dhd->pub); - } else - aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, FALSE); -#else - dhd_aoe_hostip_clr(&dhd->pub); - dhd_aoe_arp_clr(&dhd->pub); -#endif - break; - - default: - DHD_ARPOE(("%s: do noting for [%s] Event: %lu\n", - __func__, ifa->ifa_label, event)); - break; - } - } - return NOTIFY_DONE; -} -#endif /* ARP_OFFLOAD_SUPPORT */ - -int -dhd_net_attach(dhd_pub_t *dhdp, int ifidx) -{ - dhd_info_t *dhd = (dhd_info_t *)dhdp->info; - struct net_device *net = NULL; - int err = 0; - uint8 temp_addr[ETHER_ADDR_LEN] = { 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33 }; - - DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx)); - - ASSERT(dhd && dhd->iflist[ifidx]); - - net = dhd->iflist[ifidx]->net; - ASSERT(net); - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) - ASSERT(!net->open); - net->get_stats = dhd_get_stats; - net->do_ioctl = dhd_ioctl_entry; - net->hard_start_xmit = dhd_start_xmit; - net->set_mac_address = dhd_set_mac_address; - net->set_multicast_list = dhd_set_multicast_list; - net->open = net->stop = NULL; -#else - ASSERT(!net->netdev_ops); - net->netdev_ops = &dhd_ops_virt; -#endif - - /* Ok, link into the network layer... */ - if (ifidx == 0) { - /* - * device functions for the primary interface only - */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) - net->open = dhd_open; - net->stop = dhd_stop; -#else - net->netdev_ops = &dhd_ops_pri; -#endif - } else { - /* - * We have to use the primary MAC for virtual interfaces - */ - memcpy(temp_addr, dhd->iflist[ifidx]->mac_addr, ETHER_ADDR_LEN); - /* - * Android sets the locally administered bit to indicate that this is a - * portable hotspot. This will not work in simultaneous AP/STA mode, - * nor with P2P. Need to set the Donlge's MAC address, and then use that. - */ - if (!memcmp(temp_addr, dhd->iflist[0]->mac_addr, - ETHER_ADDR_LEN)) { - DHD_ERROR(("%s interface [%s]: set locally administered bit in MAC\n", - __func__, net->name)); - temp_addr[0] |= 0x02; - } - } - - net->hard_header_len = ETH_HLEN + dhd->pub.hdrlen; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) - net->ethtool_ops = &dhd_ethtool_ops; -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */ - -#if defined(WL_WIRELESS_EXT) -#if WIRELESS_EXT < 19 - net->get_wireless_stats = dhd_get_wireless_stats; -#endif /* WIRELESS_EXT < 19 */ -#if WIRELESS_EXT > 12 - net->wireless_handlers = (struct iw_handler_def *)&wl_iw_handler_def; -#endif /* WIRELESS_EXT > 12 */ -#endif /* defined(WL_WIRELESS_EXT) */ - - dhd->pub.rxsz = DBUS_RX_BUFFER_SIZE_DHD(net); - - memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN); - - if ((err = register_netdev(net)) != 0) { - DHD_ERROR(("couldn't register the net device, err %d\n", err)); - goto fail; - } - printf("Broadcom Dongle Host Driver: register interface [%s]" - " MAC: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", - net->name, - net->dev_addr[0], net->dev_addr[1], net->dev_addr[2], - net->dev_addr[3], net->dev_addr[4], net->dev_addr[5]); - -#if defined(SOFTAP) && defined(WL_WIRELESS_EXT) && !defined(WL_CFG80211) - wl_iw_iscan_set_scan_broadcast_prep(net, 1); -#endif - - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - if (ifidx == 0) { - up(&dhd_registration_sem); - } -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ - return 0; - -fail: -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) - net->open = NULL; -#else - net->netdev_ops = NULL; -#endif - return err; -} - -void -dhd_bus_detach(dhd_pub_t *dhdp) -{ - dhd_info_t *dhd; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (dhdp) { - dhd = (dhd_info_t *)dhdp->info; - if (dhd) { - - /* - * In case of Android cfg80211 driver, the bus is down in dhd_stop, - * calling stop again will cuase SD read/write errors. - */ - if (dhd->pub.busstate != DHD_BUS_DOWN) { - /* Stop the protocol module */ - dhd_prot_stop(&dhd->pub); - - /* Stop the bus module */ - dhd_bus_stop(dhd->pub.bus, TRUE); - } - -#if defined(OOB_INTR_ONLY) - bcmsdh_unregister_oob_intr(); -#endif /* defined(OOB_INTR_ONLY) */ - } - } -} - - -void dhd_detach(dhd_pub_t *dhdp) -{ - dhd_info_t *dhd; - unsigned long flags; - int timer_valid = FALSE; - - if (!dhdp) - return; - - dhd = (dhd_info_t *)dhdp->info; - if (!dhd) - return; - - DHD_TRACE(("%s: Enter state 0x%x\n", __FUNCTION__, dhd->dhd_state)); - - if (!(dhd->dhd_state & DHD_ATTACH_STATE_DONE)) { - /* Give sufficient time for threads to start running in case - * dhd_attach() has failed - */ - osl_delay(1000*100); - } - -#ifdef ARP_OFFLOAD_SUPPORT - unregister_inetaddr_notifier(&dhd_notifier); -#endif /* ARP_OFFLOAD_SUPPORT */ - -#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) - if (dhd->dhd_state & DHD_ATTACH_STATE_EARLYSUSPEND_DONE) { - if (dhd->early_suspend.suspend) - unregister_early_suspend(&dhd->early_suspend); - } -#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - cancel_work_sync(&dhd->work_hang); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ - -#if defined(WL_WIRELESS_EXT) - if (dhd->dhd_state & DHD_ATTACH_STATE_WL_ATTACH) { - /* Detatch and unlink in the iw */ - wl_iw_detach(); - } -#endif /* defined(WL_WIRELESS_EXT) */ - - if (dhd->thr_sysioc_ctl.thr_pid >= 0) { - PROC_STOP(&dhd->thr_sysioc_ctl); - } - - /* delete all interfaces, start with virtual */ - if (dhd->dhd_state & DHD_ATTACH_STATE_ADD_IF) { - int i = 1; - dhd_if_t *ifp; - - /* Cleanup virtual interfaces */ - for (i = 1; i < DHD_MAX_IFS; i++) { - dhd_net_if_lock_local(dhd); - if (dhd->iflist[i]) { - dhd->iflist[i]->state = DHD_IF_DEL; - dhd->iflist[i]->idx = i; - dhd_op_if(dhd->iflist[i]); - } - dhd_net_if_unlock_local(dhd); - } - /* delete primary interface 0 */ - ifp = dhd->iflist[0]; - ASSERT(ifp); - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) - if (ifp->net->open) -#else - if (ifp->net->netdev_ops == &dhd_ops_pri) -#endif - { - if (ifp->net) { - unregister_netdev(ifp->net); - free_netdev(ifp->net); - ifp->net = NULL; - } - MFREE(dhd->pub.osh, ifp, sizeof(*ifp)); - dhd->iflist[0] = NULL; - } - } - - /* Clear the watchdog timer */ - flags = dhd_os_spin_lock(&dhd->pub); - timer_valid = dhd->wd_timer_valid; - dhd->wd_timer_valid = FALSE; - dhd_os_spin_unlock(&dhd->pub, flags); - if (timer_valid) - del_timer_sync(&dhd->timer); - - if (dhd->dhd_state & DHD_ATTACH_STATE_THREADS_CREATED) { -#ifdef DHDTHREAD - if (dhd->thr_wdt_ctl.thr_pid >= 0) { - PROC_STOP(&dhd->thr_wdt_ctl); - } - - if (dhd->thr_dpc_ctl.thr_pid >= 0) { - PROC_STOP(&dhd->thr_dpc_ctl); - } - else -#endif /* DHDTHREAD */ - tasklet_kill(&dhd->tasklet); - } - if (dhd->dhd_state & DHD_ATTACH_STATE_PROT_ATTACH) { - dhd_bus_detach(dhdp); - - if (dhdp->prot) - dhd_prot_detach(dhdp); - } - -#ifdef WL_CFG80211 - if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) { - wl_cfg80211_detach(NULL); - dhd_monitor_uninit(); - } -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) - unregister_pm_notifier(&dhd_sleep_pm_notifier); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ - - if (dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT) { -#ifdef CONFIG_HAS_WAKELOCK - dhd->wakelock_counter = 0; - dhd->wakelock_wd_counter = 0; - dhd->wakelock_rx_timeout_enable = 0; - dhd->wakelock_ctrl_timeout_enable = 0; - wake_lock_destroy(&dhd->wl_wifi); - wake_lock_destroy(&dhd->wl_rxwake); - wake_lock_destroy(&dhd->wl_ctrlwake); - wake_lock_destroy(&dhd->wl_wdwake); -#endif /* CONFIG_HAS_WAKELOCK */ - } -} - - -void -dhd_free(dhd_pub_t *dhdp) -{ - dhd_info_t *dhd; - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (dhdp) { - dhd = (dhd_info_t *)dhdp->info; - if (dhd) - MFREE(dhd->pub.osh, dhd, sizeof(*dhd)); - } -} - -static void __exit -dhd_module_cleanup(void) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - dhd_bus_unregister(); - -#if defined(CONFIG_WIFI_CONTROL_FUNC) - wl_android_wifictrl_func_del(); -#endif /* CONFIG_WIFI_CONTROL_FUNC */ - wl_android_exit(); - - /* Call customer gpio to turn off power with WL_REG_ON signal */ - dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF); -} - -static int __init -dhd_module_init(void) -{ - int error = 0; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - wl_android_init(); - -#ifdef DHDTHREAD - /* Sanity check on the module parameters */ - do { - /* Both watchdog and DPC as tasklets are ok */ - if ((dhd_watchdog_prio < 0) && (dhd_dpc_prio < 0)) - break; - - /* If both watchdog and DPC are threads, TX must be deferred */ - if ((dhd_watchdog_prio >= 0) && (dhd_dpc_prio >= 0) && dhd_deferred_tx) - break; - - DHD_ERROR(("Invalid module parameters.\n")); - return -EINVAL; - } while (0); -#endif /* DHDTHREAD */ - - /* Call customer gpio to turn on power with WL_REG_ON signal */ - dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON); - -#if defined(CONFIG_WIFI_CONTROL_FUNC) - if (wl_android_wifictrl_func_add() < 0) - goto fail_1; -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - sema_init(&dhd_registration_sem, 0); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ - error = dhd_bus_register(); - - if (!error) - printf("\n%s\n", dhd_version); - else { - DHD_ERROR(("%s: sdio_register_driver failed\n", __FUNCTION__)); - goto fail_1; - } - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - /* - * Wait till MMC sdio_register_driver callback called and made driver attach. - * It's needed to make sync up exit from dhd insmod and - * Kernel MMC sdio device callback registration - */ - if (down_timeout(&dhd_registration_sem, msecs_to_jiffies(DHD_REGISTRATION_TIMEOUT)) != 0) { - error = -ENODEV; - DHD_ERROR(("%s: sdio_register_driver timeout\n", __FUNCTION__)); - goto fail_2; - } -#endif -#if defined(WL_CFG80211) - wl_android_post_init(); -#endif /* defined(WL_CFG80211) */ - - return error; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -fail_2: - dhd_bus_unregister(); -#endif -fail_1: -#if defined(CONFIG_WIFI_CONTROL_FUNC) - wl_android_wifictrl_func_del(); -#endif - - /* Call customer gpio to turn off power with WL_REG_ON signal */ - dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF); - - return error; -} - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) -late_initcall(dhd_module_init); -#else -module_init(dhd_module_init); -#endif -module_exit(dhd_module_cleanup); - -/* - * OS specific functions required to implement DHD driver in OS independent way - */ -int -dhd_os_proto_block(dhd_pub_t *pub) -{ - dhd_info_t * dhd = (dhd_info_t *)(pub->info); - - if (dhd) { - down(&dhd->proto_sem); - return 1; - } - - return 0; -} - -int -dhd_os_proto_unblock(dhd_pub_t *pub) -{ - dhd_info_t * dhd = (dhd_info_t *)(pub->info); - - if (dhd) { - up(&dhd->proto_sem); - return 1; - } - - return 0; -} - -unsigned int -dhd_os_get_ioctl_resp_timeout(void) -{ - return ((unsigned int)dhd_ioctl_timeout_msec); -} - -void -dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec) -{ - dhd_ioctl_timeout_msec = (int)timeout_msec; -} - -int -dhd_os_ioctl_resp_wait(dhd_pub_t *pub, uint *condition, bool *pending) -{ - dhd_info_t * dhd = (dhd_info_t *)(pub->info); - int timeout; - - /* Convert timeout in millsecond to jiffies */ - timeout = msecs_to_jiffies(dhd_ioctl_timeout_msec); - - timeout = wait_event_timeout(dhd->ioctl_resp_wait, (*condition), timeout); - return timeout; -} - -int -dhd_os_ioctl_resp_wake(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - - if (waitqueue_active(&dhd->ioctl_resp_wait)) { - wake_up(&dhd->ioctl_resp_wait); - } - - return 0; -} - -void -dhd_os_wd_timer(void *bus, uint wdtick) -{ - dhd_pub_t *pub = bus; - dhd_info_t *dhd = (dhd_info_t *)pub->info; - unsigned long flags; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (!dhd) - return; - - flags = dhd_os_spin_lock(pub); - - /* don't start the wd until fw is loaded */ - if (pub->busstate == DHD_BUS_DOWN) { - dhd_os_spin_unlock(pub, flags); - if (!wdtick) - DHD_OS_WD_WAKE_UNLOCK(pub); - return; - } - - /* Totally stop the timer */ - if (!wdtick && dhd->wd_timer_valid == TRUE) { - dhd->wd_timer_valid = FALSE; - dhd_os_spin_unlock(pub, flags); -#ifdef DHDTHREAD - del_timer_sync(&dhd->timer); -#else - del_timer(&dhd->timer); -#endif /* DHDTHREAD */ - DHD_OS_WD_WAKE_UNLOCK(pub); - return; - } - - if (wdtick) { - DHD_OS_WD_WAKE_LOCK(pub); - dhd_watchdog_ms = (uint)wdtick; - /* Re arm the timer, at last watchdog period */ - mod_timer(&dhd->timer, jiffies + msecs_to_jiffies(dhd_watchdog_ms)); - dhd->wd_timer_valid = TRUE; - } - dhd_os_spin_unlock(pub, flags); -} - -void * -dhd_os_open_image(char *filename) -{ - struct file *fp; - - fp = filp_open(filename, O_RDONLY, 0); - /* - * 2.6.11 (FC4) supports filp_open() but later revs don't? - * Alternative: - * fp = open_namei(AT_FDCWD, filename, O_RD, 0); - * ??? - */ - if (IS_ERR(fp)) - fp = NULL; - - return fp; -} - -int -dhd_os_get_image_block(char *buf, int len, void *image) -{ - struct file *fp = (struct file *)image; - int rdlen; - - if (!image) - return 0; - - rdlen = kernel_read(fp, fp->f_pos, buf, len); - if (rdlen > 0) - fp->f_pos += rdlen; - - return rdlen; -} - -void -dhd_os_close_image(void *image) -{ - if (image) - filp_close((struct file *)image, NULL); -} - - -void -dhd_os_sdlock(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)(pub->info); - -#ifdef DHDTHREAD - if (dhd->threads_only) - down(&dhd->sdsem); - else -#endif /* DHDTHREAD */ - spin_lock_bh(&dhd->sdlock); -} - -void -dhd_os_sdunlock(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)(pub->info); - -#ifdef DHDTHREAD - if (dhd->threads_only) - up(&dhd->sdsem); - else -#endif /* DHDTHREAD */ - spin_unlock_bh(&dhd->sdlock); -} - -void -dhd_os_sdlock_txq(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)(pub->info); - spin_lock_bh(&dhd->txqlock); -} - -void -dhd_os_sdunlock_txq(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)(pub->info); - spin_unlock_bh(&dhd->txqlock); -} - -void -dhd_os_sdlock_rxq(dhd_pub_t *pub) -{ -} - -void -dhd_os_sdunlock_rxq(dhd_pub_t *pub) -{ -} - -void -dhd_os_sdtxlock(dhd_pub_t *pub) -{ - dhd_os_sdlock(pub); -} - -void -dhd_os_sdtxunlock(dhd_pub_t *pub) -{ - dhd_os_sdunlock(pub); -} - -#if defined(CONFIG_DHD_USE_STATIC_BUF) -uint8* dhd_os_prealloc(void *osh, int section, uint size) -{ - return (uint8*)wl_android_prealloc(section, size); -} - -void dhd_os_prefree(void *osh, void *addr, uint size) -{ -} -#endif /* defined(CONFIG_DHD_USE_STATIC_BUF) */ - -#if defined(WL_WIRELESS_EXT) -struct iw_statistics * -dhd_get_wireless_stats(struct net_device *dev) -{ - int res = 0; - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - if (!dhd->pub.up) { - return NULL; - } - - res = wl_iw_get_wireless_stats(dev, &dhd->iw.wstats); - - if (res == 0) - return &dhd->iw.wstats; - else - return NULL; -} -#endif /* defined(WL_WIRELESS_EXT) */ - -static int -dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, - wl_event_msg_t *event, void **data) -{ - int bcmerror = 0; - ASSERT(dhd != NULL); - - bcmerror = wl_host_event(&dhd->pub, ifidx, pktdata, event, data); - if (bcmerror != BCME_OK) - return (bcmerror); - -#if defined(WL_WIRELESS_EXT) - if (event->bsscfgidx == 0) { - /* - * Wireless ext is on primary interface only - */ - - ASSERT(dhd->iflist[*ifidx] != NULL); - ASSERT(dhd->iflist[*ifidx]->net != NULL); - - if (dhd->iflist[*ifidx]->net) { - wl_iw_event(dhd->iflist[*ifidx]->net, event, *data); - } - } -#endif /* defined(WL_WIRELESS_EXT) */ - -#ifdef WL_CFG80211 - if ((ntoh32(event->event_type) == WLC_E_IF) && - (((dhd_if_event_t *)*data)->action == WLC_E_IF_ADD)) - /* If ADD_IF has been called directly by wl utility then we - * should not report this. In case if ADD_IF was called from - * CFG stack, then too this event need not be reported back - */ - return (BCME_OK); - if ((wl_cfg80211_is_progress_ifchange() || - wl_cfg80211_is_progress_ifadd()) && (*ifidx != 0)) { - /* - * If IF_ADD/CHANGE operation is going on, - * discard any event received on the virtual I/F - */ - return (BCME_OK); - } - - ASSERT(dhd->iflist[*ifidx] != NULL); - ASSERT(dhd->iflist[*ifidx]->net != NULL); - if (dhd->iflist[*ifidx]->net) { - wl_cfg80211_event(dhd->iflist[*ifidx]->net, event, *data); - } -#endif /* defined(WL_CFG80211) */ - - return (bcmerror); -} - -/* send up locally generated event */ -void -dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data) -{ - switch (ntoh32(event->event_type)) { - /* Send up locally generated AMP HCI Events */ - case WLC_E_BTA_HCI_EVENT: { - struct sk_buff *p, *skb; - bcm_event_t *msg; - wl_event_msg_t *p_bcm_event; - char *ptr; - uint32 len; - uint32 pktlen; - dhd_if_t *ifp; - dhd_info_t *dhd; - uchar *eth; - int ifidx; - - len = ntoh32(event->datalen); - pktlen = sizeof(bcm_event_t) + len + 2; - dhd = dhdp->info; - ifidx = dhd_ifname2idx(dhd, event->ifname); - - if ((p = PKTGET(dhdp->osh, pktlen, FALSE))) { - ASSERT(ISALIGNED((uintptr)PKTDATA(dhdp->osh, p), sizeof(uint32))); - - msg = (bcm_event_t *) PKTDATA(dhdp->osh, p); - - bcopy(&dhdp->mac, &msg->eth.ether_dhost, ETHER_ADDR_LEN); - bcopy(&dhdp->mac, &msg->eth.ether_shost, ETHER_ADDR_LEN); - ETHER_TOGGLE_LOCALADDR(&msg->eth.ether_shost); - - msg->eth.ether_type = hton16(ETHER_TYPE_BRCM); - - /* BCM Vendor specific header... */ - msg->bcm_hdr.subtype = hton16(BCMILCP_SUBTYPE_VENDOR_LONG); - msg->bcm_hdr.version = BCMILCP_BCM_SUBTYPEHDR_VERSION; - bcopy(BRCM_OUI, &msg->bcm_hdr.oui[0], DOT11_OUI_LEN); - - /* vendor spec header length + pvt data length (private indication - * hdr + actual message itself) - */ - msg->bcm_hdr.length = hton16(BCMILCP_BCM_SUBTYPEHDR_MINLENGTH + - BCM_MSG_LEN + sizeof(wl_event_msg_t) + (uint16)len); - msg->bcm_hdr.usr_subtype = hton16(BCMILCP_BCM_SUBTYPE_EVENT); - - PKTSETLEN(dhdp->osh, p, (sizeof(bcm_event_t) + len + 2)); - - /* copy wl_event_msg_t into sk_buf */ - - /* pointer to wl_event_msg_t in sk_buf */ - p_bcm_event = &msg->event; - bcopy(event, p_bcm_event, sizeof(wl_event_msg_t)); - - /* copy hci event into sk_buf */ - bcopy(data, (p_bcm_event + 1), len); - - msg->bcm_hdr.length = hton16(sizeof(wl_event_msg_t) + - ntoh16(msg->bcm_hdr.length)); - PKTSETLEN(dhdp->osh, p, (sizeof(bcm_event_t) + len + 2)); - - ptr = (char *)(msg + 1); - /* Last 2 bytes of the message are 0x00 0x00 to signal that there - * are no ethertypes which are following this - */ - ptr[len+0] = 0x00; - ptr[len+1] = 0x00; - - skb = PKTTONATIVE(dhdp->osh, p); - eth = skb->data; - len = skb->len; - - ifp = dhd->iflist[ifidx]; - if (ifp == NULL) - ifp = dhd->iflist[0]; - - ASSERT(ifp); - skb->dev = ifp->net; - skb->protocol = eth_type_trans(skb, skb->dev); - - skb->data = eth; - skb->len = len; - - /* Strip header, count, deliver upward */ - skb_pull(skb, ETH_HLEN); - - /* Send the packet */ - if (in_interrupt()) { - netif_rx(skb); - } else { - netif_rx_ni(skb); - } - } - else { - /* Could not allocate a sk_buf */ - DHD_ERROR(("%s: unable to alloc sk_buf", __FUNCTION__)); - } - break; - } /* case WLC_E_BTA_HCI_EVENT */ - - default: - break; - } -} - -void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) - struct dhd_info *dhdinfo = dhd->info; - int timeout = msecs_to_jiffies(2000); - dhd_os_sdunlock(dhd); - wait_event_timeout(dhdinfo->ctrl_wait, (*lockvar == FALSE), timeout); - dhd_os_sdlock(dhd); -#endif - return; -} - -void dhd_wait_event_wakeup(dhd_pub_t *dhd) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) - struct dhd_info *dhdinfo = dhd->info; - if (waitqueue_active(&dhdinfo->ctrl_wait)) - wake_up(&dhdinfo->ctrl_wait); -#endif - return; -} - -int -dhd_dev_reset(struct net_device *dev, uint8 flag) -{ - int ret; - - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - if (flag == TRUE) { - /* Issue wl down command before resetting the chip */ - if (dhd_wl_ioctl_cmd(&dhd->pub, WLC_DOWN, NULL, 0, TRUE, 0) < 0) { - DHD_TRACE(("%s: wl down failed\n", __FUNCTION__)); - } - } - - ret = dhd_bus_devreset(&dhd->pub, flag); - if (ret) { - DHD_ERROR(("%s: dhd_bus_devreset: %d\n", __FUNCTION__, ret)); - return ret; - } - - return ret; -} - -int net_os_set_suspend_disable(struct net_device *dev, int val) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) { - ret = dhd->pub.suspend_disable_flag; - dhd->pub.suspend_disable_flag = val; - } - return ret; -} - -int net_os_set_suspend(struct net_device *dev, int val, int force) -{ - int ret = 0; - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - if (dhd) { -#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) - ret = dhd_set_suspend(val, &dhd->pub); -#else - ret = dhd_suspend_resume_helper(dhd, val, force); -#endif -#ifdef WL_CFG80211 - wl_cfg80211_update_power_mode(dev); -#endif - } - return ret; -} - -int net_os_set_dtim_skip(struct net_device *dev, int val) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - if (dhd) - dhd->pub.dtim_skip = val; - - return 0; -} - -int net_os_rxfilter_add_remove(struct net_device *dev, int add_remove, int num) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - char *filterp = NULL; - int ret = 0; - - if (!dhd || (num == DHD_UNICAST_FILTER_NUM) || - (num == DHD_MDNS_FILTER_NUM)) - return ret; - if (num >= dhd->pub.pktfilter_count) - return -EINVAL; - if (add_remove) { - switch (num) { - case DHD_BROADCAST_FILTER_NUM: - filterp = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF"; - break; - case DHD_MULTICAST4_FILTER_NUM: - filterp = "102 0 0 0 0xFFFFFF 0x01005E"; - break; - case DHD_MULTICAST6_FILTER_NUM: - filterp = "103 0 0 0 0xFFFF 0x3333"; - break; - default: - return -EINVAL; - } - } - dhd->pub.pktfilter[num] = filterp; - return ret; -} - -int dhd_os_set_packet_filter(dhd_pub_t *dhdp, int val) -{ - int ret = 0; - - /* Packet filtering is set only if we still in early-suspend and - * we need either to turn it ON or turn it OFF - * We can always turn it OFF in case of early-suspend, but we turn it - * back ON only if suspend_disable_flag was not set - */ - if (dhdp && dhdp->up) { - if (dhdp->in_suspend) { - if (!val || (val && !dhdp->suspend_disable_flag)) - dhd_set_packet_filter(val, dhdp); - } - } - return ret; - -} - -int net_os_set_packet_filter(struct net_device *dev, int val) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return dhd_os_set_packet_filter(&dhd->pub, val); -} - -int -dhd_dev_init_ioctl(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return dhd_preinit_ioctls(&dhd->pub); -} - -#ifdef PNO_SUPPORT -/* Linux wrapper to call common dhd_pno_clean */ -int -dhd_dev_pno_reset(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return (dhd_pno_clean(&dhd->pub)); -} - - -/* Linux wrapper to call common dhd_pno_enable */ -int -dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return (dhd_pno_enable(&dhd->pub, pfn_enabled)); -} - - -/* Linux wrapper to call common dhd_pno_set */ -int -dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid, - ushort scan_fr, int pno_repeat, int pno_freq_expo_max) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return (dhd_pno_set(&dhd->pub, ssids_local, nssid, scan_fr, pno_repeat, pno_freq_expo_max)); -} - -/* Linux wrapper to call common dhd_pno_set_ex */ -int -dhd_dev_pno_set_ex(struct net_device *dev, wl_pfn_t* ssidnet, int nssid, - ushort pno_interval, int pno_repeat, int pno_expo_max, int pno_lost_time) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return (dhd_pno_set_ex(&dhd->pub, ssidnet, nssid, - pno_interval, pno_repeat, pno_expo_max, pno_lost_time)); -} - -/* Linux wrapper to get pno status */ -int -dhd_dev_get_pno_status(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return (dhd_pno_get_status(&dhd->pub)); -} - -#endif /* PNO_SUPPORT */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -static void dhd_hang_process(struct work_struct *work) -{ - dhd_info_t *dhd; - struct net_device *dev; - - dhd = (dhd_info_t *)container_of(work, dhd_info_t, work_hang); - dev = dhd->iflist[0]->net; - - if (dev) { - rtnl_lock(); - dev_close(dev); - rtnl_unlock(); -#if defined(WL_WIRELESS_EXT) - wl_iw_send_priv_event(dev, "HANG"); -#endif -#if defined(WL_CFG80211) - wl_cfg80211_hang(dev, WLAN_REASON_DRIVER_ERROR); -#endif - } -} -#endif - -int dhd_os_send_hang_message(dhd_pub_t *dhdp) -{ - int ret = 0; - - if (dhdp) { - if (!dhdp->hang_was_sent) { - dhdp->hang_was_sent = 1; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - schedule_work(&dhdp->info->work_hang); -#endif - } - } - return ret; -} - -int net_os_send_hang_message(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) - ret = dhd_os_send_hang_message(&dhd->pub); - - return ret; -} - -void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - if (dhd && dhd->pub.up) { - memcpy(&dhd->pub.dhd_cspec, cspec, sizeof(wl_country_t)); -#ifdef WL_CFG80211 - wl_update_wiphybands(NULL); -#endif - } -} - -void dhd_bus_band_set(struct net_device *dev, uint band) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - if (dhd && dhd->pub.up) { -#ifdef WL_CFG80211 - wl_update_wiphybands(NULL); -#endif - } -} - -void dhd_net_if_lock(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - dhd_net_if_lock_local(dhd); -} - -void dhd_net_if_unlock(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - dhd_net_if_unlock_local(dhd); -} - -static void dhd_net_if_lock_local(dhd_info_t *dhd) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - if (dhd) - mutex_lock(&dhd->dhd_net_if_mutex); -#endif -} - -static void dhd_net_if_unlock_local(dhd_info_t *dhd) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - if (dhd) - mutex_unlock(&dhd->dhd_net_if_mutex); -#endif -} - -static void dhd_suspend_lock(dhd_pub_t *pub) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - if (dhd) - mutex_lock(&dhd->dhd_suspend_mutex); -#endif -} - -static void dhd_suspend_unlock(dhd_pub_t *pub) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - if (dhd) - mutex_unlock(&dhd->dhd_suspend_mutex); -#endif -} - -unsigned long dhd_os_spin_lock(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags = 0; - - if (dhd) - spin_lock_irqsave(&dhd->dhd_lock, flags); - - return flags; -} - -void dhd_os_spin_unlock(dhd_pub_t *pub, unsigned long flags) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - - if (dhd) - spin_unlock_irqrestore(&dhd->dhd_lock, flags); -} - -static int -dhd_get_pend_8021x_cnt(dhd_info_t *dhd) -{ - return (atomic_read(&dhd->pend_8021x_cnt)); -} - -#define MAX_WAIT_FOR_8021X_TX 10 - -int -dhd_wait_pend8021x(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int timeout = msecs_to_jiffies(10); - int ntimes = MAX_WAIT_FOR_8021X_TX; - int pend = dhd_get_pend_8021x_cnt(dhd); - - while (ntimes && pend) { - if (pend) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(timeout); - set_current_state(TASK_RUNNING); - ntimes--; - } - pend = dhd_get_pend_8021x_cnt(dhd); - } - return pend; -} - -#ifdef DHD_DEBUG -int -write_to_file(dhd_pub_t *dhd, uint8 *buf, int size) -{ - int ret = 0; - struct file *fp; - mm_segment_t old_fs; - loff_t pos = 0; - - /* change to KERNEL_DS address limit */ - old_fs = get_fs(); - set_fs(KERNEL_DS); - - /* open file to write */ - fp = filp_open("/tmp/mem_dump", O_WRONLY|O_CREAT, 0640); - if (!fp) { - printf("%s: open file error\n", __FUNCTION__); - ret = -1; - goto exit; - } - - /* Write buf to file */ - fp->f_op->write(fp, buf, size, &pos); - -exit: - /* free buf before return */ - MFREE(dhd->osh, buf, size); - /* close file before return */ - if (fp) - filp_close(fp, current->files); - /* restore previous address limit */ - set_fs(old_fs); - - return ret; -} -#endif /* DHD_DEBUG */ - -int dhd_os_wake_lock_timeout(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags; - int ret = 0; - - if (dhd) { - spin_lock_irqsave(&dhd->wakelock_spinlock, flags); - ret = dhd->wakelock_rx_timeout_enable > dhd->wakelock_ctrl_timeout_enable ? - dhd->wakelock_rx_timeout_enable : dhd->wakelock_ctrl_timeout_enable; -#ifdef CONFIG_HAS_WAKELOCK - if (dhd->wakelock_rx_timeout_enable) - wake_lock_timeout(&dhd->wl_rxwake, - msecs_to_jiffies(dhd->wakelock_rx_timeout_enable)); - if (dhd->wakelock_ctrl_timeout_enable) - wake_lock_timeout(&dhd->wl_ctrlwake, - msecs_to_jiffies(dhd->wakelock_ctrl_timeout_enable)); -#endif - dhd->wakelock_rx_timeout_enable = 0; - dhd->wakelock_ctrl_timeout_enable = 0; - spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); - } - return ret; -} - -int net_os_wake_lock_timeout(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) - ret = dhd_os_wake_lock_timeout(&dhd->pub); - return ret; -} - -int dhd_os_wake_lock_rx_timeout_enable(dhd_pub_t *pub, int val) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags; - - if (dhd) { - spin_lock_irqsave(&dhd->wakelock_spinlock, flags); - if (val > dhd->wakelock_rx_timeout_enable) - dhd->wakelock_rx_timeout_enable = val; - spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); - } - return 0; -} - -int dhd_os_wake_lock_ctrl_timeout_enable(dhd_pub_t *pub, int val) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags; - - if (dhd) { - spin_lock_irqsave(&dhd->wakelock_spinlock, flags); - if (val > dhd->wakelock_ctrl_timeout_enable) - dhd->wakelock_ctrl_timeout_enable = val; - spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); - } - return 0; -} - -int net_os_wake_lock_rx_timeout_enable(struct net_device *dev, int val) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) - ret = dhd_os_wake_lock_rx_timeout_enable(&dhd->pub, val); - return ret; -} - -int net_os_wake_lock_ctrl_timeout_enable(struct net_device *dev, int val) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) - ret = dhd_os_wake_lock_ctrl_timeout_enable(&dhd->pub, val); - return ret; -} - -int dhd_os_wake_lock(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags; - int ret = 0; - - if (dhd) { - spin_lock_irqsave(&dhd->wakelock_spinlock, flags); -#ifdef CONFIG_HAS_WAKELOCK - if (!dhd->wakelock_counter) - wake_lock(&dhd->wl_wifi); -#endif - dhd->wakelock_counter++; - ret = dhd->wakelock_counter; - spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); - } - return ret; -} - -int net_os_wake_lock(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) - ret = dhd_os_wake_lock(&dhd->pub); - return ret; -} - -int dhd_os_wake_unlock(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags; - int ret = 0; - - dhd_os_wake_lock_timeout(pub); - if (dhd) { - spin_lock_irqsave(&dhd->wakelock_spinlock, flags); - if (dhd->wakelock_counter) { - dhd->wakelock_counter--; -#ifdef CONFIG_HAS_WAKELOCK - if (!dhd->wakelock_counter) - wake_unlock(&dhd->wl_wifi); -#endif - ret = dhd->wakelock_counter; - } - spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); - } - return ret; -} - -int dhd_os_check_wakelock(void *dhdp) -{ -#ifdef CONFIG_HAS_WAKELOCK - dhd_pub_t *pub = (dhd_pub_t *)dhdp; - dhd_info_t *dhd; - - if (!pub) - return 0; - dhd = (dhd_info_t *)(pub->info); - - if (dhd && (wake_lock_active(&dhd->wl_wifi) || - wake_lock_active(&dhd->wl_wdwake))) - return 1; -#endif - return 0; -} - -int net_os_wake_unlock(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) - ret = dhd_os_wake_unlock(&dhd->pub); - return ret; -} - -int dhd_os_wd_wake_lock(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags; - int ret = 0; - - if (dhd) { - spin_lock_irqsave(&dhd->wakelock_spinlock, flags); -#ifdef CONFIG_HAS_WAKELOCK - if (!dhd->wakelock_wd_counter) - wake_lock(&dhd->wl_wdwake); -#endif - dhd->wakelock_wd_counter++; - ret = dhd->wakelock_wd_counter; - spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); - } - return ret; -} - -int dhd_os_wd_wake_unlock(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags; - int ret = 0; - - if (dhd) { - spin_lock_irqsave(&dhd->wakelock_spinlock, flags); - if (dhd->wakelock_wd_counter) { - dhd->wakelock_wd_counter = 0; -#ifdef CONFIG_HAS_WAKELOCK - wake_unlock(&dhd->wl_wdwake); -#endif - } - spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); - } - return ret; -} - -int dhd_os_check_if_up(void *dhdp) -{ - dhd_pub_t *pub = (dhd_pub_t *)dhdp; - - if (!pub) - return 0; - return pub->up; -} - -void dhd_set_version_info(dhd_pub_t *dhdp, char *fw) -{ - int i; - - i = snprintf(info_string, sizeof(info_string), - " Driver: %s\n Firmware: %s ", EPI_VERSION_STR, fw); - - if (!dhdp) - return; - i = snprintf(&info_string[i], sizeof(info_string) - i, - "\n Chip: %x Rev %x Pkg %x", dhd_bus_chip_id(dhdp), - dhd_bus_chiprev_id(dhdp), dhd_bus_chippkg_id(dhdp)); -} - -int dhd_ioctl_entry_local(struct net_device *net, wl_ioctl_t *ioc, int cmd) -{ - int ifidx; - int ret = 0; - dhd_info_t *dhd = NULL; - - if (!net || !netdev_priv(net)) { - DHD_ERROR(("%s invalid parameter\n", __FUNCTION__)); - return -EINVAL; - } - - dhd = *(dhd_info_t **)netdev_priv(net); - ifidx = dhd_net2idx(dhd, net); - if (ifidx == DHD_BAD_IF) { - DHD_ERROR(("%s bad ifidx\n", __FUNCTION__)); - return -ENODEV; - } - - DHD_OS_WAKE_LOCK(&dhd->pub); - ret = dhd_wl_ioctl(&dhd->pub, ifidx, ioc, ioc->buf, ioc->len); - dhd_check_hang(net, &dhd->pub, ret); - DHD_OS_WAKE_UNLOCK(&dhd->pub); - - return ret; -} - -bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret) -{ - struct net_device *net; - - net = dhd_idx2net(dhdp, ifidx); - return dhd_check_hang(net, dhdp, ret); -} - -#ifdef PROP_TXSTATUS -extern int dhd_wlfc_interface_entry_update(void* state, ewlfc_mac_entry_action_t action, uint8 ifid, - uint8 iftype, uint8* ea); -extern int dhd_wlfc_FIFOcreditmap_update(void* state, uint8* credits); - -int dhd_wlfc_interface_event(struct dhd_info *dhd, - ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea) -{ - if (dhd->pub.wlfc_state == NULL) - return BCME_OK; - - return dhd_wlfc_interface_entry_update(dhd->pub.wlfc_state, action, ifid, iftype, ea); -} - -int dhd_wlfc_FIFOcreditmap_event(struct dhd_info *dhd, uint8* event_data) -{ - if (dhd->pub.wlfc_state == NULL) - return BCME_OK; - - return dhd_wlfc_FIFOcreditmap_update(dhd->pub.wlfc_state, event_data); -} - -int dhd_wlfc_event(struct dhd_info *dhd) -{ - return dhd_wlfc_enable(&dhd->pub); -} -#endif /* PROP_TXSTATUS */ - -#ifdef BCMDBGFS - -#include - -extern uint32 dhd_readregl(void *bp, uint32 addr); -extern uint32 dhd_writeregl(void *bp, uint32 addr, uint32 data); - -typedef struct dhd_dbgfs { - struct dentry *debugfs_dir; - struct dentry *debugfs_mem; - dhd_pub_t *dhdp; - uint32 size; -} dhd_dbgfs_t; - -dhd_dbgfs_t g_dbgfs; - -static int -dhd_dbg_state_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t -dhd_dbg_state_read(struct file *file, char __user *ubuf, - size_t count, loff_t *ppos) -{ - ssize_t rval; - uint32 tmp; - loff_t pos = *ppos; - size_t ret; - - if (pos < 0) - return -EINVAL; - if (pos >= g_dbgfs.size || !count) - return 0; - if (count > g_dbgfs.size - pos) - count = g_dbgfs.size - pos; - - /* Basically enforce aligned 4 byte reads. It's up to the user to work out the details */ - tmp = dhd_readregl(g_dbgfs.dhdp->bus, file->f_pos & (~3)); - - ret = copy_to_user(ubuf, &tmp, 4); - if (ret == count) - return -EFAULT; - - count -= ret; - *ppos = pos + count; - rval = count; - - return rval; -} - - -static ssize_t -dhd_debugfs_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) -{ - loff_t pos = *ppos; - size_t ret; - uint32 buf; - - if (pos < 0) - return -EINVAL; - if (pos >= g_dbgfs.size || !count) - return 0; - if (count > g_dbgfs.size - pos) - count = g_dbgfs.size - pos; - - ret = copy_from_user(&buf, ubuf, sizeof(uint32)); - if (ret == count) - return -EFAULT; - - /* Basically enforce aligned 4 byte writes. It's up to the user to work out the details */ - dhd_writeregl(g_dbgfs.dhdp->bus, file->f_pos & (~3), buf); - - return count; -} - - -loff_t -dhd_debugfs_lseek(struct file *file, loff_t off, int whence) -{ - loff_t pos = -1; - - switch (whence) { - case 0: - pos = off; - break; - case 1: - pos = file->f_pos + off; - break; - case 2: - pos = g_dbgfs.size - off; - } - return (pos < 0 || pos > g_dbgfs.size) ? -EINVAL : (file->f_pos = pos); -} - -static const struct file_operations dhd_dbg_state_ops = { - .read = dhd_dbg_state_read, - .write = dhd_debugfs_write, - .open = dhd_dbg_state_open, - .llseek = dhd_debugfs_lseek -}; - -static void dhd_dbg_create(void) -{ - if (g_dbgfs.debugfs_dir) { - g_dbgfs.debugfs_mem = debugfs_create_file("mem", 0644, g_dbgfs.debugfs_dir, - NULL, &dhd_dbg_state_ops); - } -} - -void dhd_dbg_init(dhd_pub_t *dhdp) -{ - int err; - - g_dbgfs.dhdp = dhdp; - g_dbgfs.size = 0x20000000; /* Allow access to various cores regs */ - - g_dbgfs.debugfs_dir = debugfs_create_dir("dhd", 0); - if (IS_ERR(g_dbgfs.debugfs_dir)) { - err = PTR_ERR(g_dbgfs.debugfs_dir); - g_dbgfs.debugfs_dir = NULL; - return; - } - - dhd_dbg_create(); - - return; -} - -void dhd_dbg_remove(void) -{ - debugfs_remove(g_dbgfs.debugfs_mem); - debugfs_remove(g_dbgfs.debugfs_dir); - - bzero((unsigned char *) &g_dbgfs, sizeof(g_dbgfs)); - -} -#endif /* ifdef BCMDBGFS */ - -#ifdef WLMEDIA_HTSF - -static -void dhd_htsf_addtxts(dhd_pub_t *dhdp, void *pktbuf) -{ - dhd_info_t *dhd = (dhd_info_t *)(dhdp->info); - struct sk_buff *skb; - uint32 htsf = 0; - uint16 dport = 0, oldmagic = 0xACAC; - char *p1; - htsfts_t ts; - - /* timestamp packet */ - - p1 = (char*) PKTDATA(dhdp->osh, pktbuf); - - if (PKTLEN(dhdp->osh, pktbuf) > HTSF_MINLEN) { -/* memcpy(&proto, p1+26, 4); */ - memcpy(&dport, p1+40, 2); -/* proto = ((ntoh32(proto))>> 16) & 0xFF; */ - dport = ntoh16(dport); - } - - /* timestamp only if icmp or udb iperf with port 5555 */ -/* if (proto == 17 && dport == tsport) { */ - if (dport >= tsport && dport <= tsport + 20) { - - skb = (struct sk_buff *) pktbuf; - - htsf = dhd_get_htsf(dhd, 0); - memset(skb->data + 44, 0, 2); /* clear checksum */ - memcpy(skb->data+82, &oldmagic, 2); - memcpy(skb->data+84, &htsf, 4); - - memset(&ts, 0, sizeof(htsfts_t)); - ts.magic = HTSFMAGIC; - ts.prio = PKTPRIO(pktbuf); - ts.seqnum = htsf_seqnum++; - ts.c10 = get_cycles(); - ts.t10 = htsf; - ts.endmagic = HTSFENDMAGIC; - - memcpy(skb->data + HTSF_HOSTOFFSET, &ts, sizeof(ts)); - } -} - -static void dhd_dump_htsfhisto(histo_t *his, char *s) -{ - int pktcnt = 0, curval = 0, i; - for (i = 0; i < (NUMBIN-2); i++) { - curval += 500; - printf("%d ", his->bin[i]); - pktcnt += his->bin[i]; - } - printf(" max: %d TotPkt: %d neg: %d [%s]\n", his->bin[NUMBIN-2], pktcnt, - his->bin[NUMBIN-1], s); -} - -static -void sorttobin(int value, histo_t *histo) -{ - int i, binval = 0; - - if (value < 0) { - histo->bin[NUMBIN-1]++; - return; - } - if (value > histo->bin[NUMBIN-2]) /* store the max value */ - histo->bin[NUMBIN-2] = value; - - for (i = 0; i < (NUMBIN-2); i++) { - binval += 500; /* 500m s bins */ - if (value <= binval) { - histo->bin[i]++; - return; - } - } - histo->bin[NUMBIN-3]++; -} - -static -void dhd_htsf_addrxts(dhd_pub_t *dhdp, void *pktbuf) -{ - dhd_info_t *dhd = (dhd_info_t *)dhdp->info; - struct sk_buff *skb; - char *p1; - uint16 old_magic; - int d1, d2, d3, end2end; - htsfts_t *htsf_ts; - uint32 htsf; - - skb = PKTTONATIVE(dhdp->osh, pktbuf); - p1 = (char*)PKTDATA(dhdp->osh, pktbuf); - - if (PKTLEN(osh, pktbuf) > HTSF_MINLEN) { - memcpy(&old_magic, p1+78, 2); - htsf_ts = (htsfts_t*) (p1 + HTSF_HOSTOFFSET - 4); - } - else - return; - - if (htsf_ts->magic == HTSFMAGIC) { - htsf_ts->tE0 = dhd_get_htsf(dhd, 0); - htsf_ts->cE0 = get_cycles(); - } - - if (old_magic == 0xACAC) { - - tspktcnt++; - htsf = dhd_get_htsf(dhd, 0); - memcpy(skb->data+92, &htsf, sizeof(uint32)); - - memcpy(&ts[tsidx].t1, skb->data+80, 16); - - d1 = ts[tsidx].t2 - ts[tsidx].t1; - d2 = ts[tsidx].t3 - ts[tsidx].t2; - d3 = ts[tsidx].t4 - ts[tsidx].t3; - end2end = ts[tsidx].t4 - ts[tsidx].t1; - - sorttobin(d1, &vi_d1); - sorttobin(d2, &vi_d2); - sorttobin(d3, &vi_d3); - sorttobin(end2end, &vi_d4); - - if (end2end > 0 && end2end > maxdelay) { - maxdelay = end2end; - maxdelaypktno = tspktcnt; - memcpy(&maxdelayts, &ts[tsidx], 16); - } - if (++tsidx >= TSMAX) - tsidx = 0; - } -} - -uint32 dhd_get_htsf(dhd_info_t *dhd, int ifidx) -{ - uint32 htsf = 0, cur_cycle, delta, delta_us; - uint32 factor, baseval, baseval2; - cycles_t t; - - t = get_cycles(); - cur_cycle = t; - - if (cur_cycle > dhd->htsf.last_cycle) - delta = cur_cycle - dhd->htsf.last_cycle; - else { - delta = cur_cycle + (0xFFFFFFFF - dhd->htsf.last_cycle); - } - - delta = delta >> 4; - - if (dhd->htsf.coef) { - /* times ten to get the first digit */ - factor = (dhd->htsf.coef*10 + dhd->htsf.coefdec1); - baseval = (delta*10)/factor; - baseval2 = (delta*10)/(factor+1); - delta_us = (baseval - (((baseval - baseval2) * dhd->htsf.coefdec2)) / 10); - htsf = (delta_us << 4) + dhd->htsf.last_tsf + HTSF_BUS_DELAY; - } - else { - DHD_ERROR(("-------dhd->htsf.coef = 0 -------\n")); - } - - return htsf; -} - -static void dhd_dump_latency(void) -{ - int i, max = 0; - int d1, d2, d3, d4, d5; - - printf("T1 T2 T3 T4 d1 d2 t4-t1 i \n"); - for (i = 0; i < TSMAX; i++) { - d1 = ts[i].t2 - ts[i].t1; - d2 = ts[i].t3 - ts[i].t2; - d3 = ts[i].t4 - ts[i].t3; - d4 = ts[i].t4 - ts[i].t1; - d5 = ts[max].t4-ts[max].t1; - if (d4 > d5 && d4 > 0) { - max = i; - } - printf("%08X %08X %08X %08X \t%d %d %d %d i=%d\n", - ts[i].t1, ts[i].t2, ts[i].t3, ts[i].t4, - d1, d2, d3, d4, i); - } - - printf("current idx = %d \n", tsidx); - - printf("Highest latency %d pkt no.%d total=%d\n", maxdelay, maxdelaypktno, tspktcnt); - printf("%08X %08X %08X %08X \t%d %d %d %d\n", - maxdelayts.t1, maxdelayts.t2, maxdelayts.t3, maxdelayts.t4, - maxdelayts.t2 - maxdelayts.t1, - maxdelayts.t3 - maxdelayts.t2, - maxdelayts.t4 - maxdelayts.t3, - maxdelayts.t4 - maxdelayts.t1); -} - - -static int -dhd_ioctl_htsf_get(dhd_info_t *dhd, int ifidx) -{ - wl_ioctl_t ioc; - char buf[32]; - int ret; - uint32 s1, s2; - - struct tsf { - uint32 low; - uint32 high; - } tsf_buf; - - memset(&ioc, 0, sizeof(ioc)); - memset(&tsf_buf, 0, sizeof(tsf_buf)); - - ioc.cmd = WLC_GET_VAR; - ioc.buf = buf; - ioc.len = (uint)sizeof(buf); - ioc.set = FALSE; - - strcpy(buf, "tsf"); - s1 = dhd_get_htsf(dhd, 0); - if ((ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) { - if (ret == -EIO) { - DHD_ERROR(("%s: tsf is not supported by device\n", - dhd_ifname(&dhd->pub, ifidx))); - return -EOPNOTSUPP; - } - return ret; - } - s2 = dhd_get_htsf(dhd, 0); - - memcpy(&tsf_buf, buf, sizeof(tsf_buf)); - printf(" TSF_h=%04X lo=%08X Calc:htsf=%08X, coef=%d.%d%d delta=%d ", - tsf_buf.high, tsf_buf.low, s2, dhd->htsf.coef, dhd->htsf.coefdec1, - dhd->htsf.coefdec2, s2-tsf_buf.low); - printf("lasttsf=%08X lastcycle=%08X\n", dhd->htsf.last_tsf, dhd->htsf.last_cycle); - return 0; -} - -void htsf_update(dhd_info_t *dhd, void *data) -{ - static ulong cur_cycle = 0, prev_cycle = 0; - uint32 htsf, tsf_delta = 0; - uint32 hfactor = 0, cyc_delta, dec1 = 0, dec2, dec3, tmp; - ulong b, a; - cycles_t t; - - /* cycles_t in inlcude/mips/timex.h */ - - t = get_cycles(); - - prev_cycle = cur_cycle; - cur_cycle = t; - - if (cur_cycle > prev_cycle) - cyc_delta = cur_cycle - prev_cycle; - else { - b = cur_cycle; - a = prev_cycle; - cyc_delta = cur_cycle + (0xFFFFFFFF - prev_cycle); - } - - if (data == NULL) - printf(" tsf update ata point er is null \n"); - - memcpy(&prev_tsf, &cur_tsf, sizeof(tsf_t)); - memcpy(&cur_tsf, data, sizeof(tsf_t)); - - if (cur_tsf.low == 0) { - DHD_INFO((" ---- 0 TSF, do not update, return\n")); - return; - } - - if (cur_tsf.low > prev_tsf.low) - tsf_delta = (cur_tsf.low - prev_tsf.low); - else { - DHD_INFO((" ---- tsf low is smaller cur_tsf= %08X, prev_tsf=%08X, \n", - cur_tsf.low, prev_tsf.low)); - if (cur_tsf.high > prev_tsf.high) { - tsf_delta = cur_tsf.low + (0xFFFFFFFF - prev_tsf.low); - DHD_INFO((" ---- Wrap around tsf coutner adjusted TSF=%08X\n", tsf_delta)); - } - else - return; /* do not update */ - } - - if (tsf_delta) { - hfactor = cyc_delta / tsf_delta; - tmp = (cyc_delta - (hfactor * tsf_delta))*10; - dec1 = tmp/tsf_delta; - dec2 = ((tmp - dec1*tsf_delta)*10) / tsf_delta; - tmp = (tmp - (dec1*tsf_delta))*10; - dec3 = ((tmp - dec2*tsf_delta)*10) / tsf_delta; - - if (dec3 > 4) { - if (dec2 == 9) { - dec2 = 0; - if (dec1 == 9) { - dec1 = 0; - hfactor++; - } - else { - dec1++; - } - } - else - dec2++; - } - } - - if (hfactor) { - htsf = ((cyc_delta * 10) / (hfactor*10+dec1)) + prev_tsf.low; - dhd->htsf.coef = hfactor; - dhd->htsf.last_cycle = cur_cycle; - dhd->htsf.last_tsf = cur_tsf.low; - dhd->htsf.coefdec1 = dec1; - dhd->htsf.coefdec2 = dec2; - } - else { - htsf = prev_tsf.low; - } -} - -#endif /* WLMEDIA_HTSF */ diff --git a/drivers/net/wireless/bcmdhd/dhd_linux_sched.c b/drivers/net/wireless/bcmdhd/dhd_linux_sched.c deleted file mode 100644 index aadd122f5b07..000000000000 --- a/drivers/net/wireless/bcmdhd/dhd_linux_sched.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Expose some of the kernel scheduler routines - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd_linux_sched.c,v 1.3 2009-04-10 04:14:49 Exp $ - */ -#include -#include -#include -#include -#include - -int setScheduler(struct task_struct *p, int policy, struct sched_param *param) -{ - int rc = 0; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) - rc = sched_setscheduler(p, policy, param); -#endif /* LinuxVer */ - return rc; -} diff --git a/drivers/net/wireless/bcmdhd/dhd_proto.h b/drivers/net/wireless/bcmdhd/dhd_proto.h deleted file mode 100644 index bb1d7365ea94..000000000000 --- a/drivers/net/wireless/bcmdhd/dhd_proto.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Header file describing the internal (inter-module) DHD interfaces. - * - * Provides type definitions and function prototypes used to link the - * DHD OS, bus, and protocol modules. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd_proto.h,v 1.8.10.6 2010-12-22 23:47:24 Exp $ - */ - -#ifndef _dhd_proto_h_ -#define _dhd_proto_h_ - -#include -#include - -#ifndef IOCTL_RESP_TIMEOUT -#define IOCTL_RESP_TIMEOUT 2000 /* In milli second */ -#endif - -/* - * Exported from the dhd protocol module (dhd_cdc, dhd_rndis) - */ - -/* Linkage, sets prot link and updates hdrlen in pub */ -extern int dhd_prot_attach(dhd_pub_t *dhdp); - -/* Unlink, frees allocated protocol memory (including dhd_prot) */ -extern void dhd_prot_detach(dhd_pub_t *dhdp); - -/* Initialize protocol: sync w/dongle state. - * Sets dongle media info (iswl, drv_version, mac address). - */ -extern int dhd_prot_init(dhd_pub_t *dhdp); - -/* Stop protocol: sync w/dongle state. */ -extern void dhd_prot_stop(dhd_pub_t *dhdp); - -/* Add any protocol-specific data header. - * Caller must reserve prot_hdrlen prepend space. - */ -extern void dhd_prot_hdrpush(dhd_pub_t *, int ifidx, void *txp); - -/* Remove any protocol-specific data header. */ -extern int dhd_prot_hdrpull(dhd_pub_t *, int *ifidx, void *rxp); - -/* Use protocol to issue ioctl to dongle */ -extern int dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len); - -/* Handles a protocol control response asynchronously */ -extern int dhd_prot_ctl_complete(dhd_pub_t *dhd); - -/* Check for and handle local prot-specific iovar commands */ -extern int dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name, - void *params, int plen, void *arg, int len, bool set); - -/* Add prot dump output to a buffer */ -extern void dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf); - -/* Update local copy of dongle statistics */ -extern void dhd_prot_dstats(dhd_pub_t *dhdp); - -extern int dhd_ioctl(dhd_pub_t * dhd_pub, dhd_ioctl_t *ioc, void * buf, uint buflen); - -extern int dhd_preinit_ioctls(dhd_pub_t *dhd); - -#ifdef PROP_TXSTATUS -extern int dhd_wlfc_enque_sendq(void* state, int prec, void* p); -extern int dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx); -extern void dhd_wlfc_cleanup(dhd_pub_t *dhd); -#endif /* PROP_TXSTATUS */ - -/******************************** - * For version-string expansion * - */ -#if defined(BDC) -#define DHD_PROTOCOL "bdc" -#elif defined(CDC) -#define DHD_PROTOCOL "cdc" -#elif defined(RNDIS) -#define DHD_PROTOCOL "rndis" -#else -#define DHD_PROTOCOL "unknown" -#endif /* proto */ - -#endif /* _dhd_proto_h_ */ diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c deleted file mode 100644 index 9ad997098b73..000000000000 --- a/drivers/net/wireless/bcmdhd/dhd_sdio.c +++ /dev/null @@ -1,6361 +0,0 @@ -/* - * DHD Bus Module for SDIO - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhd_sdio.c 352730 2012-08-23 20:55:11Z $ - */ - -#include -#include -#include - -#ifdef BCMEMBEDIMAGE -#include BCMEMBEDIMAGE -#endif /* BCMEMBEDIMAGE */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#if defined(DHD_DEBUG) -#include -#include -#endif /* defined(DHD_DEBUG) */ -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifndef DHDSDIO_MEM_DUMP_FNAME -#define DHDSDIO_MEM_DUMP_FNAME "mem_dump" -#endif - -#define QLEN 256 /* bulk rx and tx queue lengths */ -#define FCHI (QLEN - 10) -#define FCLOW (FCHI / 2) -#define PRIOMASK 7 - -#define TXRETRIES 2 /* # of retries for tx frames */ - -#define DHD_RXBOUND 50 /* Default for max rx frames in one scheduling */ - -#define DHD_TXBOUND 20 /* Default for max tx frames in one scheduling */ - -#define DHD_TXMINMAX 1 /* Max tx frames if rx still pending */ - -#define MEMBLOCK 2048 /* Block size used for downloading of dongle image */ -#define MAX_NVRAMBUF_SIZE 4096 /* max nvram buf size */ -#define MAX_DATA_BUF (32 * 1024) /* Must be large enough to hold biggest possible glom */ - -#ifndef DHD_FIRSTREAD -#define DHD_FIRSTREAD 32 -#endif -#if !ISPOWEROF2(DHD_FIRSTREAD) -#error DHD_FIRSTREAD is not a power of 2! -#endif - -/* Total length of frame header for dongle protocol */ -#define SDPCM_HDRLEN (SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN) -#ifdef SDTEST -#define SDPCM_RESERVE (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN) -#else -#define SDPCM_RESERVE (SDPCM_HDRLEN + DHD_SDALIGN) -#endif - -/* Space for header read, limit for data packets */ -#ifndef MAX_HDR_READ -#define MAX_HDR_READ 32 -#endif -#if !ISPOWEROF2(MAX_HDR_READ) -#error MAX_HDR_READ is not a power of 2! -#endif - -#define MAX_RX_DATASZ 2048 - -/* Maximum milliseconds to wait for F2 to come up */ -#define DHD_WAIT_F2RDY 3000 - -/* Bump up limit on waiting for HT to account for first startup; - * if the image is doing a CRC calculation before programming the PMU - * for HT availability, it could take a couple hundred ms more, so - * max out at a 1 second (1000000us). - */ -#if (PMU_MAX_TRANSITION_DLY <= 1000000) -#undef PMU_MAX_TRANSITION_DLY -#define PMU_MAX_TRANSITION_DLY 1000000 -#endif - -/* Value for ChipClockCSR during initial setup */ -#define DHD_INIT_CLKCTL1 (SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ) -#define DHD_INIT_CLKCTL2 (SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP) - -/* Flags for SDH calls */ -#define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED) - -/* Packet free applicable unconditionally for sdio and sdspi. Conditional if - * bufpool was present for gspi bus. - */ -#define PKTFREE2() if ((bus->bus != SPI_BUS) || bus->usebufpool) \ - PKTFREE(bus->dhd->osh, pkt, FALSE); -DHD_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep); -#if defined(OOB_INTR_ONLY) -extern void bcmsdh_set_irq(int flag); -#endif /* defined(OOB_INTR_ONLY) */ -#ifdef PROP_TXSTATUS -extern void dhd_wlfc_txcomplete(dhd_pub_t *dhd, void *txp, bool success); -#endif - -#ifdef DHD_DEBUG -/* Device console log buffer state */ -#define CONSOLE_LINE_MAX 192 -#define CONSOLE_BUFFER_MAX 2024 -typedef struct dhd_console { - uint count; /* Poll interval msec counter */ - uint log_addr; /* Log struct address (fixed) */ - hndrte_log_t log; /* Log struct (host copy) */ - uint bufsize; /* Size of log buffer */ - uint8 *buf; /* Log buffer (host copy) */ - uint last; /* Last buffer read index */ -} dhd_console_t; -#endif /* DHD_DEBUG */ - -/* Private data for SDIO bus interaction */ -typedef struct dhd_bus { - dhd_pub_t *dhd; - - bcmsdh_info_t *sdh; /* Handle for BCMSDH calls */ - si_t *sih; /* Handle for SI calls */ - char *vars; /* Variables (from CIS and/or other) */ - uint varsz; /* Size of variables buffer */ - uint32 sbaddr; /* Current SB window pointer (-1, invalid) */ - - sdpcmd_regs_t *regs; /* Registers for SDIO core */ - uint sdpcmrev; /* SDIO core revision */ - uint armrev; /* CPU core revision */ - uint ramrev; /* SOCRAM core revision */ - uint32 ramsize; /* Size of RAM in SOCRAM (bytes) */ - uint32 orig_ramsize; /* Size of RAM in SOCRAM (bytes) */ - - uint32 bus; /* gSPI or SDIO bus */ - uint32 hostintmask; /* Copy of Host Interrupt Mask */ - uint32 intstatus; /* Intstatus bits (events) pending */ - bool dpc_sched; /* Indicates DPC schedule (intrpt rcvd) */ - bool fcstate; /* State of dongle flow-control */ - - uint16 cl_devid; /* cached devid for dhdsdio_probe_attach() */ - char *fw_path; /* module_param: path to firmware image */ - char *nv_path; /* module_param: path to nvram vars file */ - const char *nvram_params; /* user specified nvram params. */ - - uint blocksize; /* Block size of SDIO transfers */ - uint roundup; /* Max roundup limit */ - - struct pktq txq; /* Queue length used for flow-control */ - uint8 flowcontrol; /* per prio flow control bitmask */ - uint8 tx_seq; /* Transmit sequence number (next) */ - uint8 tx_max; /* Maximum transmit sequence allowed */ - - uint8 hdrbuf[MAX_HDR_READ + DHD_SDALIGN]; - uint8 *rxhdr; /* Header of current rx frame (in hdrbuf) */ - uint16 nextlen; /* Next Read Len from last header */ - uint8 rx_seq; /* Receive sequence number (expected) */ - bool rxskip; /* Skip receive (awaiting NAK ACK) */ - - void *glomd; /* Packet containing glomming descriptor */ - void *glom; /* Packet chain for glommed superframe */ - uint glomerr; /* Glom packet read errors */ - - uint8 *rxbuf; /* Buffer for receiving control packets */ - uint rxblen; /* Allocated length of rxbuf */ - uint8 *rxctl; /* Aligned pointer into rxbuf */ - uint8 *databuf; /* Buffer for receiving big glom packet */ - uint8 *dataptr; /* Aligned pointer into databuf */ - uint rxlen; /* Length of valid data in buffer */ - - uint8 sdpcm_ver; /* Bus protocol reported by dongle */ - - bool intr; /* Use interrupts */ - bool poll; /* Use polling */ - bool ipend; /* Device interrupt is pending */ - bool intdis; /* Interrupts disabled by isr */ - uint intrcount; /* Count of device interrupt callbacks */ - uint lastintrs; /* Count as of last watchdog timer */ - uint spurious; /* Count of spurious interrupts */ - uint pollrate; /* Ticks between device polls */ - uint polltick; /* Tick counter */ - uint pollcnt; /* Count of active polls */ - -#ifdef DHD_DEBUG - dhd_console_t console; /* Console output polling support */ - uint console_addr; /* Console address from shared struct */ -#endif /* DHD_DEBUG */ - - uint regfails; /* Count of R_REG/W_REG failures */ - - uint clkstate; /* State of sd and backplane clock(s) */ - bool activity; /* Activity flag for clock down */ - int32 idletime; /* Control for activity timeout */ - int32 idlecount; /* Activity timeout counter */ - int32 idleclock; /* How to set bus driver when idle */ - int32 sd_divisor; /* Speed control to bus driver */ - int32 sd_mode; /* Mode control to bus driver */ - int32 sd_rxchain; /* If bcmsdh api accepts PKT chains */ - bool use_rxchain; /* If dhd should use PKT chains */ - bool sleeping; /* Is SDIO bus sleeping? */ - bool rxflow_mode; /* Rx flow control mode */ - bool rxflow; /* Is rx flow control on */ - uint prev_rxlim_hit; /* Is prev rx limit exceeded (per dpc schedule) */ - bool alp_only; /* Don't use HT clock (ALP only) */ - /* Field to decide if rx of control frames happen in rxbuf or lb-pool */ - bool usebufpool; - -#ifdef SDTEST - /* external loopback */ - bool ext_loop; - uint8 loopid; - - /* pktgen configuration */ - uint pktgen_freq; /* Ticks between bursts */ - uint pktgen_count; /* Packets to send each burst */ - uint pktgen_print; /* Bursts between count displays */ - uint pktgen_total; /* Stop after this many */ - uint pktgen_minlen; /* Minimum packet data len */ - uint pktgen_maxlen; /* Maximum packet data len */ - uint pktgen_mode; /* Configured mode: tx, rx, or echo */ - uint pktgen_stop; /* Number of tx failures causing stop */ - - /* active pktgen fields */ - uint pktgen_tick; /* Tick counter for bursts */ - uint pktgen_ptick; /* Burst counter for printing */ - uint pktgen_sent; /* Number of test packets generated */ - uint pktgen_rcvd; /* Number of test packets received */ - uint pktgen_fail; /* Number of failed send attempts */ - uint16 pktgen_len; /* Length of next packet to send */ -#define PKTGEN_RCV_IDLE (0) -#define PKTGEN_RCV_ONGOING (1) - uint16 pktgen_rcv_state; /* receive state */ - uint pktgen_rcvd_rcvsession; /* test pkts rcvd per rcv session. */ -#endif /* SDTEST */ - - /* Some additional counters */ - uint tx_sderrs; /* Count of tx attempts with sd errors */ - uint fcqueued; /* Tx packets that got queued */ - uint rxrtx; /* Count of rtx requests (NAK to dongle) */ - uint rx_toolong; /* Receive frames too long to receive */ - uint rxc_errors; /* SDIO errors when reading control frames */ - uint rx_hdrfail; /* SDIO errors on header reads */ - uint rx_badhdr; /* Bad received headers (roosync?) */ - uint rx_badseq; /* Mismatched rx sequence number */ - uint fc_rcvd; /* Number of flow-control events received */ - uint fc_xoff; /* Number which turned on flow-control */ - uint fc_xon; /* Number which turned off flow-control */ - uint rxglomfail; /* Failed deglom attempts */ - uint rxglomframes; /* Number of glom frames (superframes) */ - uint rxglompkts; /* Number of packets from glom frames */ - uint f2rxhdrs; /* Number of header reads */ - uint f2rxdata; /* Number of frame data reads */ - uint f2txdata; /* Number of f2 frame writes */ - uint f1regdata; /* Number of f1 register accesses */ - - uint8 *ctrl_frame_buf; - uint32 ctrl_frame_len; - bool ctrl_frame_stat; - uint32 rxint_mode; /* rx interrupt mode */ -} dhd_bus_t; - -/* clkstate */ -#define CLK_NONE 0 -#define CLK_SDONLY 1 -#define CLK_PENDING 2 /* Not used yet */ -#define CLK_AVAIL 3 - -#define DHD_NOPMU(dhd) (FALSE) - -#ifdef DHD_DEBUG -static int qcount[NUMPRIO]; -static int tx_packets[NUMPRIO]; -#endif /* DHD_DEBUG */ - -/* Deferred transmit */ -const uint dhd_deferred_tx = 1; - -extern uint dhd_watchdog_ms; -extern void dhd_os_wd_timer(void *bus, uint wdtick); - -/* Tx/Rx bounds */ -uint dhd_txbound; -uint dhd_rxbound; -uint dhd_txminmax = DHD_TXMINMAX; - -/* override the RAM size if possible */ -#define DONGLE_MIN_MEMSIZE (128 *1024) -int dhd_dongle_memsize; - -static bool dhd_doflow; -static bool dhd_alignctl; - -static bool sd1idle; - -static bool retrydata; -#define RETRYCHAN(chan) (((chan) == SDPCM_EVENT_CHANNEL) || retrydata) - -static const uint watermark = 8; -static const uint firstread = DHD_FIRSTREAD; - -#define HDATLEN (firstread - (SDPCM_HDRLEN)) - -/* Retry count for register access failures */ -static const uint retry_limit = 2; - -/* Force even SD lengths (some host controllers mess up on odd bytes) */ -static bool forcealign; - -/* Flag to indicate if we should download firmware on driver load */ -uint dhd_download_fw_on_driverload = TRUE; - -#define ALIGNMENT 4 - -#if defined(OOB_INTR_ONLY) && defined(HW_OOB) -extern void bcmsdh_enable_hw_oob_intr(void *sdh, bool enable); -#endif - -#if defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD) -#error OOB_INTR_ONLY is NOT working with SDIO_ISR_THREAD -#endif /* defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD) */ -#define PKTALIGN(osh, p, len, align) \ - do { \ - uint datalign; \ - datalign = (uintptr)PKTDATA((osh), (p)); \ - datalign = ROUNDUP(datalign, (align)) - datalign; \ - ASSERT(datalign < (align)); \ - ASSERT(PKTLEN((osh), (p)) >= ((len) + datalign)); \ - if (datalign) \ - PKTPULL((osh), (p), datalign); \ - PKTSETLEN((osh), (p), (len)); \ - } while (0) - -/* Limit on rounding up frames */ -static const uint max_roundup = 512; - -/* Try doing readahead */ -static bool dhd_readahead; - -/* To check if there's window offered */ -#define DATAOK(bus) \ - (((uint8)(bus->tx_max - bus->tx_seq) > 1) && \ - (((uint8)(bus->tx_max - bus->tx_seq) & 0x80) == 0)) - -/* To check if there's window offered for ctrl frame */ -#define TXCTLOK(bus) \ - (((uint8)(bus->tx_max - bus->tx_seq) != 0) && \ - (((uint8)(bus->tx_max - bus->tx_seq) & 0x80) == 0)) - -/* Macros to get register read/write status */ -/* NOTE: these assume a local dhdsdio_bus_t *bus! */ -#define R_SDREG(regvar, regaddr, retryvar) \ -do { \ - retryvar = 0; \ - do { \ - regvar = R_REG(bus->dhd->osh, regaddr); \ - } while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \ - if (retryvar) { \ - bus->regfails += (retryvar-1); \ - if (retryvar > retry_limit) { \ - DHD_ERROR(("%s: FAILED" #regvar "READ, LINE %d\n", \ - __FUNCTION__, __LINE__)); \ - regvar = 0; \ - } \ - } \ -} while (0) - -#define W_SDREG(regval, regaddr, retryvar) \ -do { \ - retryvar = 0; \ - do { \ - W_REG(bus->dhd->osh, regaddr, regval); \ - } while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \ - if (retryvar) { \ - bus->regfails += (retryvar-1); \ - if (retryvar > retry_limit) \ - DHD_ERROR(("%s: FAILED REGISTER WRITE, LINE %d\n", \ - __FUNCTION__, __LINE__)); \ - } \ -} while (0) - -#define BUS_WAKE(bus) \ - do { \ - if ((bus)->sleeping) \ - dhdsdio_bussleep((bus), FALSE); \ - } while (0); - -/* - * pktavail interrupts from dongle to host can be managed in 3 different ways - * whenever there is a packet available in dongle to transmit to host. - * - * Mode 0: Dongle writes the software host mailbox and host is interrupted. - * Mode 1: (sdiod core rev >= 4) - * Device sets a new bit in the intstatus whenever there is a packet - * available in fifo. Host can't clear this specific status bit until all the - * packets are read from the FIFO. No need to ack dongle intstatus. - * Mode 2: (sdiod core rev >= 4) - * Device sets a bit in the intstatus, and host acks this by writing - * one to this bit. Dongle won't generate anymore packet interrupts - * until host reads all the packets from the dongle and reads a zero to - * figure that there are no more packets. No need to disable host ints. - * Need to ack the intstatus. - */ - -#define SDIO_DEVICE_HMB_RXINT 0 /* default old way */ -#define SDIO_DEVICE_RXDATAINT_MODE_0 1 /* from sdiod rev 4 */ -#define SDIO_DEVICE_RXDATAINT_MODE_1 2 /* from sdiod rev 4 */ - - -#define FRAME_AVAIL_MASK(bus) \ - ((bus->rxint_mode == SDIO_DEVICE_HMB_RXINT) ? I_HMB_FRAME_IND : I_XMTDATA_AVAIL) - -#define DHD_BUS SDIO_BUS - -#define PKT_AVAILABLE(bus, intstatus) ((intstatus) & (FRAME_AVAIL_MASK(bus))) - -#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE) - -#define GSPI_PR55150_BAILOUT - - -#ifdef SDTEST -static void dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq); -static void dhdsdio_sdtest_set(dhd_bus_t *bus, uint8 count); -#endif - -#ifdef DHD_DEBUG -static int dhdsdio_checkdied(dhd_bus_t *bus, char *data, uint size); -static int dhd_serialconsole(dhd_bus_t *bus, bool get, bool enable, int *bcmerror); -#endif /* DHD_DEBUG */ - -static int dhdsdio_download_state(dhd_bus_t *bus, bool enter); - -static void dhdsdio_release(dhd_bus_t *bus, osl_t *osh); -static void dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh); -static void dhdsdio_disconnect(void *ptr); -static bool dhdsdio_chipmatch(uint16 chipid); -static bool dhdsdio_probe_attach(dhd_bus_t *bus, osl_t *osh, void *sdh, - void * regsva, uint16 devid); -static bool dhdsdio_probe_malloc(dhd_bus_t *bus, osl_t *osh, void *sdh); -static bool dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh); -static void dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh, bool dongle_isolation, - bool reset_flag); - -static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size); -static int dhd_bcmsdh_recv_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, - uint8 *buf, uint nbytes, - void *pkt, bcmsdh_cmplt_fn_t complete, void *handle); -static int dhd_bcmsdh_send_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, - uint8 *buf, uint nbytes, - void *pkt, bcmsdh_cmplt_fn_t complete, void *handle); - -static bool dhdsdio_download_firmware(dhd_bus_t *bus, osl_t *osh, void *sdh); -static int _dhdsdio_download_firmware(dhd_bus_t *bus); - -static int dhdsdio_download_code_file(dhd_bus_t *bus, char *image_path); -static int dhdsdio_download_nvram(dhd_bus_t *bus); -#ifdef BCMEMBEDIMAGE -static int dhdsdio_download_code_array(dhd_bus_t *bus); -#endif - -#ifdef WLMEDIA_HTSF -#include -extern uint32 dhd_get_htsf(void *dhd, int ifidx); -#endif /* WLMEDIA_HTSF */ - -static void -dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size) -{ - int32 min_size = DONGLE_MIN_MEMSIZE; - /* Restrict the memsize to user specified limit */ - DHD_ERROR(("user: Restrict the dongle ram size to %d, min accepted %d\n", - dhd_dongle_memsize, min_size)); - if ((dhd_dongle_memsize > min_size) && - (dhd_dongle_memsize < (int32)bus->orig_ramsize)) - bus->ramsize = dhd_dongle_memsize; -} - -static int -dhdsdio_set_siaddr_window(dhd_bus_t *bus, uint32 address) -{ - int err = 0; - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, - (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); - if (!err) - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, - (address >> 16) & SBSDIO_SBADDRMID_MASK, &err); - if (!err) - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, - (address >> 24) & SBSDIO_SBADDRHIGH_MASK, &err); - return err; -} - - -/* Turn backplane clock on or off */ -static int -dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) -{ -#define HT_AVAIL_ERROR_MAX 10 - static int ht_avail_error = 0; - int err; - uint8 clkctl, clkreq, devctl; - bcmsdh_info_t *sdh; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - -#if defined(OOB_INTR_ONLY) - pendok = FALSE; -#endif - clkctl = 0; - sdh = bus->sdh; - - if (on) { - /* Request HT Avail */ - clkreq = bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ; - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); - if (err) { - ht_avail_error++; - if (ht_avail_error < HT_AVAIL_ERROR_MAX) { - DHD_ERROR(("%s: HT Avail request error: %d\n", __FUNCTION__, err)); - } else { - if (ht_avail_error == HT_AVAIL_ERROR_MAX) - dhd_os_send_hang_message(bus->dhd); - } - return BCME_ERROR; - } else { - ht_avail_error = 0; - } - - if (pendok && - ((bus->sih->buscoretype == PCMCIA_CORE_ID) && (bus->sih->buscorerev == 9))) { - uint32 dummy, retries; - R_SDREG(dummy, &bus->regs->clockctlstatus, retries); - } - - /* Check current status */ - clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); - if (err) { - DHD_ERROR(("%s: HT Avail read error: %d\n", __FUNCTION__, err)); - return BCME_ERROR; - } - - /* Go to pending and await interrupt if appropriate */ - if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) { - /* Allow only clock-available interrupt */ - devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); - if (err) { - DHD_ERROR(("%s: Devctl access error setting CA: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - - devctl |= SBSDIO_DEVCTL_CA_INT_ONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); - DHD_INFO(("CLKCTL: set PENDING\n")); - bus->clkstate = CLK_PENDING; - return BCME_OK; - } else if (bus->clkstate == CLK_PENDING) { - /* Cancel CA-only interrupt filter */ - devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); - devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); - } - - /* Otherwise, wait here (polling) for HT Avail */ - if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { - SPINWAIT_SLEEP(sdioh_spinwait_sleep, - ((clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_CHIPCLKCSR, &err)), - !SBSDIO_CLKAV(clkctl, bus->alp_only)), PMU_MAX_TRANSITION_DLY); - } - if (err) { - DHD_ERROR(("%s: HT Avail request error: %d\n", __FUNCTION__, err)); - return BCME_ERROR; - } - if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { - DHD_ERROR(("%s: HT Avail timeout (%d): clkctl 0x%02x\n", - __FUNCTION__, PMU_MAX_TRANSITION_DLY, clkctl)); - dhd_os_send_hang_message(bus->dhd); - return BCME_ERROR; - } - - - /* Mark clock available */ - bus->clkstate = CLK_AVAIL; - DHD_INFO(("CLKCTL: turned ON\n")); - -#if defined(DHD_DEBUG) - if (bus->alp_only == TRUE) { -#if !defined(BCMLXSDMMC) - if (!SBSDIO_ALPONLY(clkctl)) { - DHD_ERROR(("%s: HT Clock, when ALP Only\n", __FUNCTION__)); - } -#endif /* !defined(BCMLXSDMMC) */ - } else { - if (SBSDIO_ALPONLY(clkctl)) { - DHD_ERROR(("%s: HT Clock should be on.\n", __FUNCTION__)); - } - } -#endif /* defined (DHD_DEBUG) */ - - bus->activity = TRUE; - } else { - clkreq = 0; - - if (bus->clkstate == CLK_PENDING) { - /* Cancel CA-only interrupt filter */ - devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); - devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); - } - - bus->clkstate = CLK_SDONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); - DHD_INFO(("CLKCTL: turned OFF\n")); - if (err) { - DHD_ERROR(("%s: Failed access turning clock off: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - } - return BCME_OK; -} - -/* Change idle/active SD state */ -static int -dhdsdio_sdclk(dhd_bus_t *bus, bool on) -{ - int err; - int32 iovalue; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (on) { - if (bus->idleclock == DHD_IDLE_STOP) { - /* Turn on clock and restore mode */ - iovalue = 1; - err = bcmsdh_iovar_op(bus->sdh, "sd_clock", NULL, 0, - &iovalue, sizeof(iovalue), TRUE); - if (err) { - DHD_ERROR(("%s: error enabling sd_clock: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - - iovalue = bus->sd_mode; - err = bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0, - &iovalue, sizeof(iovalue), TRUE); - if (err) { - DHD_ERROR(("%s: error changing sd_mode: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - } else if (bus->idleclock != DHD_IDLE_ACTIVE) { - /* Restore clock speed */ - iovalue = bus->sd_divisor; - err = bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0, - &iovalue, sizeof(iovalue), TRUE); - if (err) { - DHD_ERROR(("%s: error restoring sd_divisor: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - } - bus->clkstate = CLK_SDONLY; - } else { - /* Stop or slow the SD clock itself */ - if ((bus->sd_divisor == -1) || (bus->sd_mode == -1)) { - DHD_TRACE(("%s: can't idle clock, divisor %d mode %d\n", - __FUNCTION__, bus->sd_divisor, bus->sd_mode)); - return BCME_ERROR; - } - if (bus->idleclock == DHD_IDLE_STOP) { - if (sd1idle) { - /* Change to SD1 mode and turn off clock */ - iovalue = 1; - err = bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0, - &iovalue, sizeof(iovalue), TRUE); - if (err) { - DHD_ERROR(("%s: error changing sd_clock: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - } - - iovalue = 0; - err = bcmsdh_iovar_op(bus->sdh, "sd_clock", NULL, 0, - &iovalue, sizeof(iovalue), TRUE); - if (err) { - DHD_ERROR(("%s: error disabling sd_clock: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - } else if (bus->idleclock != DHD_IDLE_ACTIVE) { - /* Set divisor to idle value */ - iovalue = bus->idleclock; - err = bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0, - &iovalue, sizeof(iovalue), TRUE); - if (err) { - DHD_ERROR(("%s: error changing sd_divisor: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - } - bus->clkstate = CLK_NONE; - } - - return BCME_OK; -} - -/* Transition SD and backplane clock readiness */ -static int -dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok) -{ - int ret = BCME_OK; -#ifdef DHD_DEBUG - uint oldstate = bus->clkstate; -#endif /* DHD_DEBUG */ - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* Early exit if we're already there */ - if (bus->clkstate == target) { - if (target == CLK_AVAIL) { - dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); - bus->activity = TRUE; - } - return ret; - } - - switch (target) { - case CLK_AVAIL: - /* Make sure SD clock is available */ - if (bus->clkstate == CLK_NONE) - dhdsdio_sdclk(bus, TRUE); - /* Now request HT Avail on the backplane */ - ret = dhdsdio_htclk(bus, TRUE, pendok); - if (ret == BCME_OK) { - dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); - bus->activity = TRUE; - } - break; - - case CLK_SDONLY: - /* Remove HT request, or bring up SD clock */ - if (bus->clkstate == CLK_NONE) - ret = dhdsdio_sdclk(bus, TRUE); - else if (bus->clkstate == CLK_AVAIL) - ret = dhdsdio_htclk(bus, FALSE, FALSE); - else - DHD_ERROR(("dhdsdio_clkctl: request for %d -> %d\n", - bus->clkstate, target)); - if (ret == BCME_OK) { - dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); - } - break; - - case CLK_NONE: - /* Make sure to remove HT request */ - if (bus->clkstate == CLK_AVAIL) - ret = dhdsdio_htclk(bus, FALSE, FALSE); - /* Now remove the SD clock */ - ret = dhdsdio_sdclk(bus, FALSE); -#ifdef DHD_DEBUG - if (dhd_console_ms == 0) -#endif /* DHD_DEBUG */ - if (bus->poll == 0) - dhd_os_wd_timer(bus->dhd, 0); - break; - } -#ifdef DHD_DEBUG - DHD_INFO(("dhdsdio_clkctl: %d -> %d\n", oldstate, bus->clkstate)); -#endif /* DHD_DEBUG */ - - return ret; -} - -static int -dhdsdio_bussleep(dhd_bus_t *bus, bool sleep) -{ - bcmsdh_info_t *sdh = bus->sdh; - sdpcmd_regs_t *regs = bus->regs; - uint retries = 0; - - DHD_INFO(("dhdsdio_bussleep: request %s (currently %s)\n", - (sleep ? "SLEEP" : "WAKE"), - (bus->sleeping ? "SLEEP" : "WAKE"))); - - /* Done if we're already in the requested state */ - if (sleep == bus->sleeping) - return BCME_OK; - - /* Going to sleep: set the alarm and turn off the lights... */ - if (sleep) { - /* Don't sleep if something is pending */ - if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq)) - return BCME_BUSY; - - - /* Disable SDIO interrupts (no longer interested) */ - bcmsdh_intr_disable(bus->sdh); - - /* Make sure the controller has the bus up */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - /* Tell device to start using OOB wakeup */ - W_SDREG(SMB_USE_OOB, ®s->tosbmailbox, retries); - if (retries > retry_limit) - DHD_ERROR(("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n")); - - /* Turn off our contribution to the HT clock request */ - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - SBSDIO_FORCE_HW_CLKREQ_OFF, NULL); - - /* Isolate the bus */ - if (bus->sih->chip != BCM4329_CHIP_ID && bus->sih->chip != BCM4319_CHIP_ID) { - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, - SBSDIO_DEVCTL_PADS_ISO, NULL); - } - - /* Change state */ - bus->sleeping = TRUE; - - } else { - /* Waking up: bus power up is ok, set local state */ - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - 0, NULL); - - /* Force pad isolation off if possible (in case power never toggled) */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, 0, NULL); - - - /* Make sure the controller has the bus up */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - /* Send misc interrupt to indicate OOB not needed */ - W_SDREG(0, ®s->tosbmailboxdata, retries); - if (retries <= retry_limit) - W_SDREG(SMB_DEV_INT, ®s->tosbmailbox, retries); - - if (retries > retry_limit) - DHD_ERROR(("CANNOT SIGNAL CHIP TO CLEAR OOB!!\n")); - - /* Make sure we have SD bus access */ - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); - - /* Change state */ - bus->sleeping = FALSE; - - /* Enable interrupts again */ - if (bus->intr && (bus->dhd->busstate == DHD_BUS_DATA)) { - bus->intdis = FALSE; - bcmsdh_intr_enable(bus->sdh); - } - } - - return BCME_OK; -} - -#if defined(OOB_INTR_ONLY) -void -dhd_enable_oob_intr(struct dhd_bus *bus, bool enable) -{ -#if defined(HW_OOB) - bcmsdh_enable_hw_oob_intr(bus->sdh, enable); -#else - sdpcmd_regs_t *regs = bus->regs; - uint retries = 0; - - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - if (enable == TRUE) { - - /* Tell device to start using OOB wakeup */ - W_SDREG(SMB_USE_OOB, ®s->tosbmailbox, retries); - if (retries > retry_limit) - DHD_ERROR(("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n")); - - } else { - /* Send misc interrupt to indicate OOB not needed */ - W_SDREG(0, ®s->tosbmailboxdata, retries); - if (retries <= retry_limit) - W_SDREG(SMB_DEV_INT, ®s->tosbmailbox, retries); - } - - /* Turn off our contribution to the HT clock request */ - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); -#endif /* !defined(HW_OOB) */ -} -#endif /* defined(OOB_INTR_ONLY) */ - -/* Writes a HW/SW header into the packet and sends it. */ -/* Assumes: (a) header space already there, (b) caller holds lock */ -static int -dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, uint chan, bool free_pkt) -{ - int ret; - osl_t *osh; - uint8 *frame; - uint16 len, pad1 = 0; - uint32 swheader; - uint retries = 0; - bcmsdh_info_t *sdh; - void *new; - int i; -#ifdef WLMEDIA_HTSF - char *p; - htsfts_t *htsf_ts; -#endif - - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - sdh = bus->sdh; - osh = bus->dhd->osh; - - if (bus->dhd->dongle_reset) { - ret = BCME_NOTREADY; - goto done; - } - - frame = (uint8*)PKTDATA(osh, pkt); - -#ifdef WLMEDIA_HTSF - if (PKTLEN(osh, pkt) >= 100) { - p = PKTDATA(osh, pkt); - htsf_ts = (htsfts_t*) (p + HTSF_HOSTOFFSET + 12); - if (htsf_ts->magic == HTSFMAGIC) { - htsf_ts->c20 = get_cycles(); - htsf_ts->t20 = dhd_get_htsf(bus->dhd->info, 0); - } - } -#endif /* WLMEDIA_HTSF */ - - /* Add alignment padding, allocate new packet if needed */ - if ((pad1 = ((uintptr)frame % DHD_SDALIGN))) { - if (PKTHEADROOM(osh, pkt) < pad1) { - DHD_INFO(("%s: insufficient headroom %d for %d pad1\n", - __FUNCTION__, (int)PKTHEADROOM(osh, pkt), pad1)); - bus->dhd->tx_realloc++; - new = PKTGET(osh, (PKTLEN(osh, pkt) + DHD_SDALIGN), TRUE); - if (!new) { - DHD_ERROR(("%s: couldn't allocate new %d-byte packet\n", - __FUNCTION__, PKTLEN(osh, pkt) + DHD_SDALIGN)); - ret = BCME_NOMEM; - goto done; - } - - PKTALIGN(osh, new, PKTLEN(osh, pkt), DHD_SDALIGN); - bcopy(PKTDATA(osh, pkt), PKTDATA(osh, new), PKTLEN(osh, pkt)); - if (free_pkt) - PKTFREE(osh, pkt, TRUE); - /* free the pkt if canned one is not used */ - free_pkt = TRUE; - pkt = new; - frame = (uint8*)PKTDATA(osh, pkt); - ASSERT(((uintptr)frame % DHD_SDALIGN) == 0); - pad1 = 0; - } else { - PKTPUSH(osh, pkt, pad1); - frame = (uint8*)PKTDATA(osh, pkt); - - ASSERT((pad1 + SDPCM_HDRLEN) <= (int) PKTLEN(osh, pkt)); - bzero(frame, pad1 + SDPCM_HDRLEN); - } - } - ASSERT(pad1 < DHD_SDALIGN); - - /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ - len = (uint16)PKTLEN(osh, pkt); - *(uint16*)frame = htol16(len); - *(((uint16*)frame) + 1) = htol16(~len); - - /* Software tag: channel, sequence number, data offset */ - swheader = ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | bus->tx_seq | - (((pad1 + SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK); - htol32_ua_store(swheader, frame + SDPCM_FRAMETAG_LEN); - htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); - -#ifdef DHD_DEBUG - if (PKTPRIO(pkt) < ARRAYSIZE(tx_packets)) { - tx_packets[PKTPRIO(pkt)]++; - } - if (DHD_BYTES_ON() && - (((DHD_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) || - (DHD_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) { - prhex("Tx Frame", frame, len); - } else if (DHD_HDRS_ON()) { - prhex("TxHdr", frame, MIN(len, 16)); - } -#endif - - /* Raise len to next SDIO block to eliminate tail command */ - if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { - uint16 pad2 = bus->blocksize - (len % bus->blocksize); - if ((pad2 <= bus->roundup) && (pad2 < bus->blocksize)) -#ifdef NOTUSED - if (pad2 <= PKTTAILROOM(osh, pkt)) -#endif /* NOTUSED */ - len += pad2; - } else if (len % DHD_SDALIGN) { - len += DHD_SDALIGN - (len % DHD_SDALIGN); - } - - /* Some controllers have trouble with odd bytes -- round to even */ - if (forcealign && (len & (ALIGNMENT - 1))) { -#ifdef NOTUSED - if (PKTTAILROOM(osh, pkt)) -#endif - len = ROUNDUP(len, ALIGNMENT); -#ifdef NOTUSED - else - DHD_ERROR(("%s: sending unrounded %d-byte packet\n", __FUNCTION__, len)); -#endif - } - - do { - ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - frame, len, pkt, NULL, NULL); - bus->f2txdata++; - ASSERT(ret != BCME_PENDING); - - if (ret < 0) { - /* On failure, abort the command and terminate the frame */ - DHD_INFO(("%s: sdio error %d, abort command and terminate frame.\n", - __FUNCTION__, ret)); - bus->tx_sderrs++; - - bcmsdh_abort(sdh, SDIO_FUNC_2); - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, - SFC_WF_TERM, NULL); - bus->f1regdata++; - - for (i = 0; i < 3; i++) { - uint8 hi, lo; - hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCLO, NULL); - bus->f1regdata += 2; - if ((hi == 0) && (lo == 0)) - break; - } - - } - if (ret == 0) { - bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; - } - } while ((ret < 0) && retrydata && retries++ < TXRETRIES); - -done: - /* restore pkt buffer pointer before calling tx complete routine */ - PKTPULL(osh, pkt, SDPCM_HDRLEN + pad1); -#ifdef PROP_TXSTATUS - if (bus->dhd->wlfc_state) { - dhd_os_sdunlock(bus->dhd); - dhd_wlfc_txcomplete(bus->dhd, pkt, ret == 0); - dhd_os_sdlock(bus->dhd); - } else { -#endif /* PROP_TXSTATUS */ - dhd_txcomplete(bus->dhd, pkt, ret != 0); - if (free_pkt) - PKTFREE(osh, pkt, TRUE); - -#ifdef PROP_TXSTATUS - } -#endif - return ret; -} - -int -dhd_bus_txdata(struct dhd_bus *bus, void *pkt) -{ - int ret = BCME_ERROR; - osl_t *osh; - uint datalen, prec; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - osh = bus->dhd->osh; - datalen = PKTLEN(osh, pkt); - -#ifdef SDTEST - /* Push the test header if doing loopback */ - if (bus->ext_loop) { - uint8* data; - PKTPUSH(osh, pkt, SDPCM_TEST_HDRLEN); - data = PKTDATA(osh, pkt); - *data++ = SDPCM_TEST_ECHOREQ; - *data++ = (uint8)bus->loopid++; - *data++ = (datalen >> 0); - *data++ = (datalen >> 8); - datalen += SDPCM_TEST_HDRLEN; - } -#endif /* SDTEST */ - - /* Add space for the header */ - PKTPUSH(osh, pkt, SDPCM_HDRLEN); - ASSERT(ISALIGNED((uintptr)PKTDATA(osh, pkt), 2)); - - prec = PRIO2PREC((PKTPRIO(pkt) & PRIOMASK)); -#ifndef DHDTHREAD - /* Lock: we're about to use shared data/code (and SDIO) */ - dhd_os_sdlock(bus->dhd); -#endif /* DHDTHREAD */ - - /* Check for existing queue, current flow-control, pending event, or pending clock */ - if (dhd_deferred_tx || bus->fcstate || pktq_len(&bus->txq) || bus->dpc_sched || - (!DATAOK(bus)) || (bus->flowcontrol & NBITVAL(prec)) || - (bus->clkstate != CLK_AVAIL)) { - DHD_TRACE(("%s: deferring pktq len %d\n", __FUNCTION__, - pktq_len(&bus->txq))); - bus->fcqueued++; - - /* Priority based enq */ - dhd_os_sdlock_txq(bus->dhd); - if (dhd_prec_enq(bus->dhd, &bus->txq, pkt, prec) == FALSE) { - PKTPULL(osh, pkt, SDPCM_HDRLEN); -#ifndef DHDTHREAD - /* Need to also release txqlock before releasing sdlock. - * This thread still has txqlock and releases sdlock. - * Deadlock happens when dpc() grabs sdlock first then - * attempts to grab txqlock. - */ - dhd_os_sdunlock_txq(bus->dhd); - dhd_os_sdunlock(bus->dhd); -#endif -#ifdef PROP_TXSTATUS - if (bus->dhd->wlfc_state) - dhd_wlfc_txcomplete(bus->dhd, pkt, FALSE); - else -#endif - dhd_txcomplete(bus->dhd, pkt, FALSE); -#ifndef DHDTHREAD - dhd_os_sdlock(bus->dhd); - dhd_os_sdlock_txq(bus->dhd); -#endif -#ifdef PROP_TXSTATUS - /* let the caller decide whether to free the packet */ - if (!bus->dhd->wlfc_state) -#endif - PKTFREE(osh, pkt, TRUE); - ret = BCME_NORESOURCE; - } - else - ret = BCME_OK; - dhd_os_sdunlock_txq(bus->dhd); - - if ((pktq_len(&bus->txq) >= FCHI) && dhd_doflow) - dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, ON); - -#ifdef DHD_DEBUG - if (pktq_plen(&bus->txq, prec) > qcount[prec]) - qcount[prec] = pktq_plen(&bus->txq, prec); -#endif - /* Schedule DPC if needed to send queued packet(s) */ - if (dhd_deferred_tx && !bus->dpc_sched) { - bus->dpc_sched = TRUE; - dhd_sched_dpc(bus->dhd); - } - } else { -#ifdef DHDTHREAD - /* Lock: we're about to use shared data/code (and SDIO) */ - dhd_os_sdlock(bus->dhd); -#endif /* DHDTHREAD */ - - /* Otherwise, send it now */ - BUS_WAKE(bus); - /* Make sure back plane ht clk is on, no pending allowed */ - dhdsdio_clkctl(bus, CLK_AVAIL, TRUE); -#ifndef SDTEST - ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, TRUE); -#else - ret = dhdsdio_txpkt(bus, pkt, - (bus->ext_loop ? SDPCM_TEST_CHANNEL : SDPCM_DATA_CHANNEL), TRUE); -#endif - if (ret) - bus->dhd->tx_errors++; - else - bus->dhd->dstats.tx_bytes += datalen; - - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, TRUE); - } - -#ifdef DHDTHREAD - dhd_os_sdunlock(bus->dhd); -#endif /* DHDTHREAD */ - } - -#ifndef DHDTHREAD - dhd_os_sdunlock(bus->dhd); -#endif /* DHDTHREAD */ - - return ret; -} - -static uint -dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes) -{ - void *pkt; - uint32 intstatus = 0; - uint retries = 0; - int ret = 0, prec_out; - uint cnt = 0; - uint datalen; - uint8 tx_prec_map; - - dhd_pub_t *dhd = bus->dhd; - sdpcmd_regs_t *regs = bus->regs; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - tx_prec_map = ~bus->flowcontrol; - - /* Send frames until the limit or some other event */ - for (cnt = 0; (cnt < maxframes) && DATAOK(bus); cnt++) { - dhd_os_sdlock_txq(bus->dhd); - if ((pkt = pktq_mdeq(&bus->txq, tx_prec_map, &prec_out)) == NULL) { - dhd_os_sdunlock_txq(bus->dhd); - break; - } - dhd_os_sdunlock_txq(bus->dhd); - datalen = PKTLEN(bus->dhd->osh, pkt) - SDPCM_HDRLEN; - -#ifndef SDTEST - ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, TRUE); -#else - ret = dhdsdio_txpkt(bus, pkt, - (bus->ext_loop ? SDPCM_TEST_CHANNEL : SDPCM_DATA_CHANNEL), TRUE); -#endif - if (ret) - bus->dhd->tx_errors++; - else - bus->dhd->dstats.tx_bytes += datalen; - - /* In poll mode, need to check for other events */ - if (!bus->intr && cnt) - { - /* Check device status, signal pending interrupt */ - R_SDREG(intstatus, ®s->intstatus, retries); - bus->f2txdata++; - if (bcmsdh_regfail(bus->sdh)) - break; - if (intstatus & bus->hostintmask) - bus->ipend = TRUE; - } - } - - /* Deflow-control stack if needed */ - if (dhd_doflow && dhd->up && (dhd->busstate == DHD_BUS_DATA) && - dhd->txoff && (pktq_len(&bus->txq) < FCLOW)) - dhd_txflowcontrol(dhd, ALL_INTERFACES, OFF); - - return cnt; -} - -int -dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen) -{ - uint8 *frame; - uint16 len; - uint32 swheader; - uint retries = 0; - bcmsdh_info_t *sdh = bus->sdh; - uint8 doff = 0; - int ret = -1; - int i; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (bus->dhd->dongle_reset) - return -EIO; - - /* Back the pointer to make a room for bus header */ - frame = msg - SDPCM_HDRLEN; - len = (msglen += SDPCM_HDRLEN); - - /* Add alignment padding (optional for ctl frames) */ - if (dhd_alignctl) { - if ((doff = ((uintptr)frame % DHD_SDALIGN))) { - frame -= doff; - len += doff; - msglen += doff; - bzero(frame, doff + SDPCM_HDRLEN); - } - ASSERT(doff < DHD_SDALIGN); - } - doff += SDPCM_HDRLEN; - - /* Round send length to next SDIO block */ - if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { - uint16 pad = bus->blocksize - (len % bus->blocksize); - if ((pad <= bus->roundup) && (pad < bus->blocksize)) - len += pad; - } else if (len % DHD_SDALIGN) { - len += DHD_SDALIGN - (len % DHD_SDALIGN); - } - - /* Satisfy length-alignment requirements */ - if (forcealign && (len & (ALIGNMENT - 1))) - len = ROUNDUP(len, ALIGNMENT); - - ASSERT(ISALIGNED((uintptr)frame, 2)); - - - /* Need to lock here to protect txseq and SDIO tx calls */ - dhd_os_sdlock(bus->dhd); - - BUS_WAKE(bus); - - /* Make sure backplane clock is on */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ - *(uint16*)frame = htol16((uint16)msglen); - *(((uint16*)frame) + 1) = htol16(~msglen); - - /* Software tag: channel, sequence number, data offset */ - swheader = ((SDPCM_CONTROL_CHANNEL << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) - | bus->tx_seq | ((doff << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK); - htol32_ua_store(swheader, frame + SDPCM_FRAMETAG_LEN); - htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); - - if (!TXCTLOK(bus)) { - DHD_INFO(("%s: No bus credit bus->tx_max %d, bus->tx_seq %d\n", - __FUNCTION__, bus->tx_max, bus->tx_seq)); - bus->ctrl_frame_stat = TRUE; - /* Send from dpc */ - bus->ctrl_frame_buf = frame; - bus->ctrl_frame_len = len; - if (!bus->dpc_sched) { - bus->dpc_sched = TRUE; - dhd_sched_dpc(bus->dhd); - } - if (bus->ctrl_frame_stat) { - dhd_wait_for_event(bus->dhd, &bus->ctrl_frame_stat); - } - if (bus->ctrl_frame_stat == FALSE) { - DHD_INFO(("%s: ctrl_frame_stat == FALSE\n", __FUNCTION__)); - ret = 0; - } else { - bus->dhd->txcnt_timeout++; - if (!bus->dhd->hang_was_sent) - DHD_ERROR(("%s: ctrl_frame_stat == TRUE txcnt_timeout=%d\n", - __FUNCTION__, bus->dhd->txcnt_timeout)); - ret = -1; - bus->ctrl_frame_stat = FALSE; - goto done; - } - } - - bus->dhd->txcnt_timeout = 0; - - if (ret == -1) { -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_CTL_ON()) { - prhex("Tx Frame", frame, len); - } else if (DHD_HDRS_ON()) { - prhex("TxHdr", frame, MIN(len, 16)); - } -#endif - - do { - ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - frame, len, NULL, NULL, NULL); - ASSERT(ret != BCME_PENDING); - - if (ret < 0) { - /* On failure, abort the command and terminate the frame */ - DHD_INFO(("%s: sdio error %d, abort command and terminate frame.\n", - __FUNCTION__, ret)); - bus->tx_sderrs++; - - bcmsdh_abort(sdh, SDIO_FUNC_2); - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, - SFC_WF_TERM, NULL); - bus->f1regdata++; - - for (i = 0; i < 3; i++) { - uint8 hi, lo; - hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCLO, NULL); - bus->f1regdata += 2; - if ((hi == 0) && (lo == 0)) - break; - } - - } - if (ret == 0) { - bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; - } - } while ((ret < 0) && retries++ < TXRETRIES); - } - -done: - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, TRUE); - } - - dhd_os_sdunlock(bus->dhd); - - if (ret) - bus->dhd->tx_ctlerrs++; - else - bus->dhd->tx_ctlpkts++; - - if (bus->dhd->txcnt_timeout >= MAX_CNTL_TIMEOUT) - return -ETIMEDOUT; - - return ret ? -EIO : 0; -} - -int -dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen) -{ - int timeleft; - uint rxlen = 0; - bool pending = FALSE; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (bus->dhd->dongle_reset) - return -EIO; - - /* Wait until control frame is available */ - timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->rxlen, &pending); - - dhd_os_sdlock(bus->dhd); - rxlen = bus->rxlen; - bcopy(bus->rxctl, msg, MIN(msglen, rxlen)); - bus->rxlen = 0; - dhd_os_sdunlock(bus->dhd); - - if (rxlen) { - DHD_CTL(("%s: resumed on rxctl frame, got %d expected %d\n", - __FUNCTION__, rxlen, msglen)); - } else if (timeleft == 0) { - DHD_ERROR(("%s: resumed on timeout\n", __FUNCTION__)); -#ifdef DHD_DEBUG - dhd_os_sdlock(bus->dhd); - dhdsdio_checkdied(bus, NULL, 0); - dhd_os_sdunlock(bus->dhd); -#endif /* DHD_DEBUG */ - } else if (pending == TRUE) { - /* possibly fw hangs so never responsed back */ - DHD_ERROR(("%s: signal pending\n", __FUNCTION__)); - return -EINTR; - } else { - DHD_CTL(("%s: resumed for unknown reason?\n", __FUNCTION__)); -#ifdef DHD_DEBUG - dhd_os_sdlock(bus->dhd); - dhdsdio_checkdied(bus, NULL, 0); - dhd_os_sdunlock(bus->dhd); -#endif /* DHD_DEBUG */ - } - if (timeleft == 0) { - bus->dhd->rxcnt_timeout++; - DHD_ERROR(("%s: rxcnt_timeout=%d\n", __FUNCTION__, bus->dhd->rxcnt_timeout)); - } - else - bus->dhd->rxcnt_timeout = 0; - - if (rxlen) - bus->dhd->rx_ctlpkts++; - else - bus->dhd->rx_ctlerrs++; - - if (bus->dhd->rxcnt_timeout >= MAX_CNTL_TIMEOUT) - return -ETIMEDOUT; - - return rxlen ? (int)rxlen : -EIO; -} - -/* IOVar table */ -enum { - IOV_INTR = 1, - IOV_POLLRATE, - IOV_SDREG, - IOV_SBREG, - IOV_SDCIS, - IOV_MEMBYTES, - IOV_MEMSIZE, -#ifdef DHD_DEBUG - IOV_CHECKDIED, - IOV_SERIALCONS, -#endif /* DHD_DEBUG */ - IOV_DOWNLOAD, - IOV_SOCRAM_STATE, - IOV_FORCEEVEN, - IOV_SDIOD_DRIVE, - IOV_READAHEAD, - IOV_SDRXCHAIN, - IOV_ALIGNCTL, - IOV_SDALIGN, - IOV_DEVRESET, - IOV_CPU, -#ifdef SDTEST - IOV_PKTGEN, - IOV_EXTLOOP, -#endif /* SDTEST */ - IOV_SPROM, - IOV_TXBOUND, - IOV_RXBOUND, - IOV_TXMINMAX, - IOV_IDLETIME, - IOV_IDLECLOCK, - IOV_SD1IDLE, - IOV_SLEEP, - IOV_DONGLEISOLATION, - IOV_VARS, -#ifdef SOFTAP - IOV_FWPATH -#endif -}; - -const bcm_iovar_t dhdsdio_iovars[] = { - {"intr", IOV_INTR, 0, IOVT_BOOL, 0 }, - {"sleep", IOV_SLEEP, 0, IOVT_BOOL, 0 }, - {"pollrate", IOV_POLLRATE, 0, IOVT_UINT32, 0 }, - {"idletime", IOV_IDLETIME, 0, IOVT_INT32, 0 }, - {"idleclock", IOV_IDLECLOCK, 0, IOVT_INT32, 0 }, - {"sd1idle", IOV_SD1IDLE, 0, IOVT_BOOL, 0 }, - {"membytes", IOV_MEMBYTES, 0, IOVT_BUFFER, 2 * sizeof(int) }, - {"memsize", IOV_MEMSIZE, 0, IOVT_UINT32, 0 }, - {"download", IOV_DOWNLOAD, 0, IOVT_BOOL, 0 }, - {"socram_state", IOV_SOCRAM_STATE, 0, IOVT_BOOL, 0 }, - {"vars", IOV_VARS, 0, IOVT_BUFFER, 0 }, - {"sdiod_drive", IOV_SDIOD_DRIVE, 0, IOVT_UINT32, 0 }, - {"readahead", IOV_READAHEAD, 0, IOVT_BOOL, 0 }, - {"sdrxchain", IOV_SDRXCHAIN, 0, IOVT_BOOL, 0 }, - {"alignctl", IOV_ALIGNCTL, 0, IOVT_BOOL, 0 }, - {"sdalign", IOV_SDALIGN, 0, IOVT_BOOL, 0 }, - {"devreset", IOV_DEVRESET, 0, IOVT_BOOL, 0 }, -#ifdef DHD_DEBUG - {"sdreg", IOV_SDREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sbreg", IOV_SBREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_cis", IOV_SDCIS, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN }, - {"forcealign", IOV_FORCEEVEN, 0, IOVT_BOOL, 0 }, - {"txbound", IOV_TXBOUND, 0, IOVT_UINT32, 0 }, - {"rxbound", IOV_RXBOUND, 0, IOVT_UINT32, 0 }, - {"txminmax", IOV_TXMINMAX, 0, IOVT_UINT32, 0 }, - {"cpu", IOV_CPU, 0, IOVT_BOOL, 0 }, -#ifdef DHD_DEBUG - {"checkdied", IOV_CHECKDIED, 0, IOVT_BUFFER, 0 }, - {"serial", IOV_SERIALCONS, 0, IOVT_UINT32, 0 }, -#endif /* DHD_DEBUG */ -#endif /* DHD_DEBUG */ -#ifdef SDTEST - {"extloop", IOV_EXTLOOP, 0, IOVT_BOOL, 0 }, - {"pktgen", IOV_PKTGEN, 0, IOVT_BUFFER, sizeof(dhd_pktgen_t) }, -#endif /* SDTEST */ - {"dngl_isolation", IOV_DONGLEISOLATION, 0, IOVT_UINT32, 0 }, -#ifdef SOFTAP - {"fwpath", IOV_FWPATH, 0, IOVT_BUFFER, 0 }, -#endif - {NULL, 0, 0, 0, 0 } -}; - -static void -dhd_dump_pct(struct bcmstrbuf *strbuf, char *desc, uint num, uint div) -{ - uint q1, q2; - - if (!div) { - bcm_bprintf(strbuf, "%s N/A", desc); - } else { - q1 = num / div; - q2 = (100 * (num - (q1 * div))) / div; - bcm_bprintf(strbuf, "%s %d.%02d", desc, q1, q2); - } -} - -void -dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) -{ - dhd_bus_t *bus = dhdp->bus; - - bcm_bprintf(strbuf, "Bus SDIO structure:\n"); - bcm_bprintf(strbuf, "hostintmask 0x%08x intstatus 0x%08x sdpcm_ver %d\n", - bus->hostintmask, bus->intstatus, bus->sdpcm_ver); - bcm_bprintf(strbuf, "fcstate %d qlen %d tx_seq %d, max %d, rxskip %d rxlen %d rx_seq %d\n", - bus->fcstate, pktq_len(&bus->txq), bus->tx_seq, bus->tx_max, bus->rxskip, - bus->rxlen, bus->rx_seq); - bcm_bprintf(strbuf, "intr %d intrcount %d lastintrs %d spurious %d\n", - bus->intr, bus->intrcount, bus->lastintrs, bus->spurious); - bcm_bprintf(strbuf, "pollrate %d pollcnt %d regfails %d\n", - bus->pollrate, bus->pollcnt, bus->regfails); - - bcm_bprintf(strbuf, "\nAdditional counters:\n"); - bcm_bprintf(strbuf, "tx_sderrs %d fcqueued %d rxrtx %d rx_toolong %d rxc_errors %d\n", - bus->tx_sderrs, bus->fcqueued, bus->rxrtx, bus->rx_toolong, - bus->rxc_errors); - bcm_bprintf(strbuf, "rx_hdrfail %d badhdr %d badseq %d\n", - bus->rx_hdrfail, bus->rx_badhdr, bus->rx_badseq); - bcm_bprintf(strbuf, "fc_rcvd %d, fc_xoff %d, fc_xon %d\n", - bus->fc_rcvd, bus->fc_xoff, bus->fc_xon); - bcm_bprintf(strbuf, "rxglomfail %d, rxglomframes %d, rxglompkts %d\n", - bus->rxglomfail, bus->rxglomframes, bus->rxglompkts); - bcm_bprintf(strbuf, "f2rx (hdrs/data) %d (%d/%d), f2tx %d f1regs %d\n", - (bus->f2rxhdrs + bus->f2rxdata), bus->f2rxhdrs, bus->f2rxdata, - bus->f2txdata, bus->f1regdata); - { - dhd_dump_pct(strbuf, "\nRx: pkts/f2rd", bus->dhd->rx_packets, - (bus->f2rxhdrs + bus->f2rxdata)); - dhd_dump_pct(strbuf, ", pkts/f1sd", bus->dhd->rx_packets, bus->f1regdata); - dhd_dump_pct(strbuf, ", pkts/sd", bus->dhd->rx_packets, - (bus->f2rxhdrs + bus->f2rxdata + bus->f1regdata)); - dhd_dump_pct(strbuf, ", pkts/int", bus->dhd->rx_packets, bus->intrcount); - bcm_bprintf(strbuf, "\n"); - - dhd_dump_pct(strbuf, "Rx: glom pct", (100 * bus->rxglompkts), - bus->dhd->rx_packets); - dhd_dump_pct(strbuf, ", pkts/glom", bus->rxglompkts, bus->rxglomframes); - bcm_bprintf(strbuf, "\n"); - - dhd_dump_pct(strbuf, "Tx: pkts/f2wr", bus->dhd->tx_packets, bus->f2txdata); - dhd_dump_pct(strbuf, ", pkts/f1sd", bus->dhd->tx_packets, bus->f1regdata); - dhd_dump_pct(strbuf, ", pkts/sd", bus->dhd->tx_packets, - (bus->f2txdata + bus->f1regdata)); - dhd_dump_pct(strbuf, ", pkts/int", bus->dhd->tx_packets, bus->intrcount); - bcm_bprintf(strbuf, "\n"); - - dhd_dump_pct(strbuf, "Total: pkts/f2rw", - (bus->dhd->tx_packets + bus->dhd->rx_packets), - (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata)); - dhd_dump_pct(strbuf, ", pkts/f1sd", - (bus->dhd->tx_packets + bus->dhd->rx_packets), bus->f1regdata); - dhd_dump_pct(strbuf, ", pkts/sd", - (bus->dhd->tx_packets + bus->dhd->rx_packets), - (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata + bus->f1regdata)); - dhd_dump_pct(strbuf, ", pkts/int", - (bus->dhd->tx_packets + bus->dhd->rx_packets), bus->intrcount); - bcm_bprintf(strbuf, "\n\n"); - } - -#ifdef SDTEST - if (bus->pktgen_count) { - bcm_bprintf(strbuf, "pktgen config and count:\n"); - bcm_bprintf(strbuf, "freq %d count %d print %d total %d min %d len %d\n", - bus->pktgen_freq, bus->pktgen_count, bus->pktgen_print, - bus->pktgen_total, bus->pktgen_minlen, bus->pktgen_maxlen); - bcm_bprintf(strbuf, "send attempts %d rcvd %d fail %d\n", - bus->pktgen_sent, bus->pktgen_rcvd, bus->pktgen_fail); - } -#endif /* SDTEST */ -#ifdef DHD_DEBUG - bcm_bprintf(strbuf, "dpc_sched %d host interrupt%spending\n", - bus->dpc_sched, (bcmsdh_intr_pending(bus->sdh) ? " " : " not ")); - bcm_bprintf(strbuf, "blocksize %d roundup %d\n", bus->blocksize, bus->roundup); -#endif /* DHD_DEBUG */ - bcm_bprintf(strbuf, "clkstate %d activity %d idletime %d idlecount %d sleeping %d\n", - bus->clkstate, bus->activity, bus->idletime, bus->idlecount, bus->sleeping); -} - -void -dhd_bus_clearcounts(dhd_pub_t *dhdp) -{ - dhd_bus_t *bus = (dhd_bus_t *)dhdp->bus; - - bus->intrcount = bus->lastintrs = bus->spurious = bus->regfails = 0; - bus->rxrtx = bus->rx_toolong = bus->rxc_errors = 0; - bus->rx_hdrfail = bus->rx_badhdr = bus->rx_badseq = 0; - bus->tx_sderrs = bus->fc_rcvd = bus->fc_xoff = bus->fc_xon = 0; - bus->rxglomfail = bus->rxglomframes = bus->rxglompkts = 0; - bus->f2rxhdrs = bus->f2rxdata = bus->f2txdata = bus->f1regdata = 0; -} - -#ifdef SDTEST -static int -dhdsdio_pktgen_get(dhd_bus_t *bus, uint8 *arg) -{ - dhd_pktgen_t pktgen; - - pktgen.version = DHD_PKTGEN_VERSION; - pktgen.freq = bus->pktgen_freq; - pktgen.count = bus->pktgen_count; - pktgen.print = bus->pktgen_print; - pktgen.total = bus->pktgen_total; - pktgen.minlen = bus->pktgen_minlen; - pktgen.maxlen = bus->pktgen_maxlen; - pktgen.numsent = bus->pktgen_sent; - pktgen.numrcvd = bus->pktgen_rcvd; - pktgen.numfail = bus->pktgen_fail; - pktgen.mode = bus->pktgen_mode; - pktgen.stop = bus->pktgen_stop; - - bcopy(&pktgen, arg, sizeof(pktgen)); - - return 0; -} - -static int -dhdsdio_pktgen_set(dhd_bus_t *bus, uint8 *arg) -{ - dhd_pktgen_t pktgen; - uint oldcnt, oldmode; - - bcopy(arg, &pktgen, sizeof(pktgen)); - if (pktgen.version != DHD_PKTGEN_VERSION) - return BCME_BADARG; - - oldcnt = bus->pktgen_count; - oldmode = bus->pktgen_mode; - - bus->pktgen_freq = pktgen.freq; - bus->pktgen_count = pktgen.count; - bus->pktgen_print = pktgen.print; - bus->pktgen_total = pktgen.total; - bus->pktgen_minlen = pktgen.minlen; - bus->pktgen_maxlen = pktgen.maxlen; - bus->pktgen_mode = pktgen.mode; - bus->pktgen_stop = pktgen.stop; - - bus->pktgen_tick = bus->pktgen_ptick = 0; - bus->pktgen_len = MAX(bus->pktgen_len, bus->pktgen_minlen); - bus->pktgen_len = MIN(bus->pktgen_len, bus->pktgen_maxlen); - - /* Clear counts for a new pktgen (mode change, or was stopped) */ - if (bus->pktgen_count && (!oldcnt || oldmode != bus->pktgen_mode)) - bus->pktgen_sent = bus->pktgen_rcvd = bus->pktgen_fail = 0; - - return 0; -} -#endif /* SDTEST */ - -static int -dhdsdio_membytes(dhd_bus_t *bus, bool write, uint32 address, uint8 *data, uint size) -{ - int bcmerror = 0; - uint32 sdaddr; - uint dsize; - - /* Determine initial transfer parameters */ - sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK; - if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK) - dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr); - else - dsize = size; - - /* Set the backplane window to include the start address */ - if ((bcmerror = dhdsdio_set_siaddr_window(bus, address))) { - DHD_ERROR(("%s: window change failed\n", __FUNCTION__)); - goto xfer_done; - } - - /* Do the transfer(s) */ - while (size) { - DHD_INFO(("%s: %s %d bytes at offset 0x%08x in window 0x%08x\n", - __FUNCTION__, (write ? "write" : "read"), dsize, sdaddr, - (address & SBSDIO_SBWINDOW_MASK))); - if ((bcmerror = bcmsdh_rwdata(bus->sdh, write, sdaddr, data, dsize))) { - DHD_ERROR(("%s: membytes transfer failed\n", __FUNCTION__)); - break; - } - - /* Adjust for next transfer (if any) */ - if ((size -= dsize)) { - data += dsize; - address += dsize; - if ((bcmerror = dhdsdio_set_siaddr_window(bus, address))) { - DHD_ERROR(("%s: window change failed\n", __FUNCTION__)); - break; - } - sdaddr = 0; - dsize = MIN(SBSDIO_SB_OFT_ADDR_LIMIT, size); - } - - } - -xfer_done: - /* Return the window to backplane enumeration space for core access */ - if (dhdsdio_set_siaddr_window(bus, bcmsdh_cur_sbwad(bus->sdh))) { - DHD_ERROR(("%s: FAILED to set window back to 0x%x\n", __FUNCTION__, - bcmsdh_cur_sbwad(bus->sdh))); - } - - return bcmerror; -} - -#ifdef DHD_DEBUG -static int -dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh) -{ - uint32 addr; - int rv; - - /* Read last word in memory to determine address of sdpcm_shared structure */ - if ((rv = dhdsdio_membytes(bus, FALSE, bus->ramsize - 4, (uint8 *)&addr, 4)) < 0) - return rv; - - addr = ltoh32(addr); - - DHD_INFO(("sdpcm_shared address 0x%08X\n", addr)); - - /* - * Check if addr is valid. - * NVRAM length at the end of memory should have been overwritten. - */ - if (addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)) { - DHD_ERROR(("%s: address (0x%08x) of sdpcm_shared invalid\n", __FUNCTION__, addr)); - return BCME_ERROR; - } - - /* Read hndrte_shared structure */ - if ((rv = dhdsdio_membytes(bus, FALSE, addr, (uint8 *)sh, sizeof(sdpcm_shared_t))) < 0) - return rv; - - /* Endianness */ - sh->flags = ltoh32(sh->flags); - sh->trap_addr = ltoh32(sh->trap_addr); - sh->assert_exp_addr = ltoh32(sh->assert_exp_addr); - sh->assert_file_addr = ltoh32(sh->assert_file_addr); - sh->assert_line = ltoh32(sh->assert_line); - sh->console_addr = ltoh32(sh->console_addr); - sh->msgtrace_addr = ltoh32(sh->msgtrace_addr); - - if ((sh->flags & SDPCM_SHARED_VERSION_MASK) == 3 && SDPCM_SHARED_VERSION == 1) - return BCME_OK; - - if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) { - DHD_ERROR(("%s: sdpcm_shared version %d in dhd " - "is different than sdpcm_shared version %d in dongle\n", - __FUNCTION__, SDPCM_SHARED_VERSION, - sh->flags & SDPCM_SHARED_VERSION_MASK)); - return BCME_ERROR; - } - - return BCME_OK; -} - - -static int -dhdsdio_readconsole(dhd_bus_t *bus) -{ - dhd_console_t *c = &bus->console; - uint8 line[CONSOLE_LINE_MAX], ch; - uint32 n, idx, addr; - int rv; - - /* Don't do anything until FWREADY updates console address */ - if (bus->console_addr == 0) - return 0; - - /* Read console log struct */ - addr = bus->console_addr + OFFSETOF(hndrte_cons_t, log); - if ((rv = dhdsdio_membytes(bus, FALSE, addr, (uint8 *)&c->log, sizeof(c->log))) < 0) - return rv; - - /* Allocate console buffer (one time only) */ - if (c->buf == NULL) { - c->bufsize = ltoh32(c->log.buf_size); - if ((c->buf = MALLOC(bus->dhd->osh, c->bufsize)) == NULL) - return BCME_NOMEM; - } - - idx = ltoh32(c->log.idx); - - /* Protect against corrupt value */ - if (idx > c->bufsize) - return BCME_ERROR; - - /* Skip reading the console buffer if the index pointer has not moved */ - if (idx == c->last) - return BCME_OK; - - /* Read the console buffer */ - addr = ltoh32(c->log.buf); - if ((rv = dhdsdio_membytes(bus, FALSE, addr, c->buf, c->bufsize)) < 0) - return rv; - - while (c->last != idx) { - for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) { - if (c->last == idx) { - /* This would output a partial line. Instead, back up - * the buffer pointer and output this line next time around. - */ - if (c->last >= n) - c->last -= n; - else - c->last = c->bufsize - n; - goto break2; - } - ch = c->buf[c->last]; - c->last = (c->last + 1) % c->bufsize; - if (ch == '\n') - break; - line[n] = ch; - } - - if (n > 0) { - if (line[n - 1] == '\r') - n--; - line[n] = 0; - printf("CONSOLE: %s\n", line); - } - } -break2: - - return BCME_OK; -} - -static int -dhdsdio_checkdied(dhd_bus_t *bus, char *data, uint size) -{ - int bcmerror = 0; - uint msize = 512; - char *mbuffer = NULL; - char *console_buffer = NULL; - uint maxstrlen = 256; - char *str = NULL; - trap_t tr; - sdpcm_shared_t sdpcm_shared; - struct bcmstrbuf strbuf; - uint32 console_ptr, console_size, console_index; - uint8 line[CONSOLE_LINE_MAX], ch; - uint32 n, i, addr; - int rv; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (data == NULL) { - /* - * Called after a rx ctrl timeout. "data" is NULL. - * allocate memory to trace the trap or assert. - */ - size = msize; - mbuffer = data = MALLOC(bus->dhd->osh, msize); - if (mbuffer == NULL) { - DHD_ERROR(("%s: MALLOC(%d) failed \n", __FUNCTION__, msize)); - bcmerror = BCME_NOMEM; - goto done; - } - } - - if ((str = MALLOC(bus->dhd->osh, maxstrlen)) == NULL) { - DHD_ERROR(("%s: MALLOC(%d) failed \n", __FUNCTION__, maxstrlen)); - bcmerror = BCME_NOMEM; - goto done; - } - - if ((bcmerror = dhdsdio_readshared(bus, &sdpcm_shared)) < 0) - goto done; - - bcm_binit(&strbuf, data, size); - - bcm_bprintf(&strbuf, "msgtrace address : 0x%08X\nconsole address : 0x%08X\n", - sdpcm_shared.msgtrace_addr, sdpcm_shared.console_addr); - - if ((sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) == 0) { - /* NOTE: Misspelled assert is intentional - DO NOT FIX. - * (Avoids conflict with real asserts for programmatic parsing of output.) - */ - bcm_bprintf(&strbuf, "Assrt not built in dongle\n"); - } - - if ((sdpcm_shared.flags & (SDPCM_SHARED_ASSERT|SDPCM_SHARED_TRAP)) == 0) { - /* NOTE: Misspelled assert is intentional - DO NOT FIX. - * (Avoids conflict with real asserts for programmatic parsing of output.) - */ - bcm_bprintf(&strbuf, "No trap%s in dongle", - (sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) - ?"/assrt" :""); - } else { - if (sdpcm_shared.flags & SDPCM_SHARED_ASSERT) { - /* Download assert */ - bcm_bprintf(&strbuf, "Dongle assert"); - if (sdpcm_shared.assert_exp_addr != 0) { - str[0] = '\0'; - if ((bcmerror = dhdsdio_membytes(bus, FALSE, - sdpcm_shared.assert_exp_addr, - (uint8 *)str, maxstrlen)) < 0) - goto done; - - str[maxstrlen - 1] = '\0'; - bcm_bprintf(&strbuf, " expr \"%s\"", str); - } - - if (sdpcm_shared.assert_file_addr != 0) { - str[0] = '\0'; - if ((bcmerror = dhdsdio_membytes(bus, FALSE, - sdpcm_shared.assert_file_addr, - (uint8 *)str, maxstrlen)) < 0) - goto done; - - str[maxstrlen - 1] = '\0'; - bcm_bprintf(&strbuf, " file \"%s\"", str); - } - - bcm_bprintf(&strbuf, " line %d ", sdpcm_shared.assert_line); - } - - if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) { - if ((bcmerror = dhdsdio_membytes(bus, FALSE, - sdpcm_shared.trap_addr, - (uint8*)&tr, sizeof(trap_t))) < 0) - goto done; - - bcm_bprintf(&strbuf, - "Dongle trap type 0x%x @ epc 0x%x, cpsr 0x%x, spsr 0x%x, sp 0x%x," - "lp 0x%x, rpc 0x%x Trap offset 0x%x, " - "r0 0x%x, r1 0x%x, r2 0x%x, r3 0x%x, " - "r4 0x%x, r5 0x%x, r6 0x%x, r7 0x%x\n\n", - ltoh32(tr.type), ltoh32(tr.epc), ltoh32(tr.cpsr), ltoh32(tr.spsr), - ltoh32(tr.r13), ltoh32(tr.r14), ltoh32(tr.pc), - ltoh32(sdpcm_shared.trap_addr), - ltoh32(tr.r0), ltoh32(tr.r1), ltoh32(tr.r2), ltoh32(tr.r3), - ltoh32(tr.r4), ltoh32(tr.r5), ltoh32(tr.r6), ltoh32(tr.r7)); - - addr = sdpcm_shared.console_addr + OFFSETOF(hndrte_cons_t, log); - if ((rv = dhdsdio_membytes(bus, FALSE, addr, - (uint8 *)&console_ptr, sizeof(console_ptr))) < 0) - goto printbuf; - - addr = sdpcm_shared.console_addr + OFFSETOF(hndrte_cons_t, log.buf_size); - if ((rv = dhdsdio_membytes(bus, FALSE, addr, - (uint8 *)&console_size, sizeof(console_size))) < 0) - goto printbuf; - - addr = sdpcm_shared.console_addr + OFFSETOF(hndrte_cons_t, log.idx); - if ((rv = dhdsdio_membytes(bus, FALSE, addr, - (uint8 *)&console_index, sizeof(console_index))) < 0) - goto printbuf; - - console_ptr = ltoh32(console_ptr); - console_size = ltoh32(console_size); - console_index = ltoh32(console_index); - - if (console_size > CONSOLE_BUFFER_MAX || - !(console_buffer = MALLOC(bus->dhd->osh, console_size))) - goto printbuf; - - if ((rv = dhdsdio_membytes(bus, FALSE, console_ptr, - (uint8 *)console_buffer, console_size)) < 0) - goto printbuf; - - for (i = 0, n = 0; i < console_size; i += n + 1) { - for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) { - ch = console_buffer[(console_index + i + n) % console_size]; - if (ch == '\n') - break; - line[n] = ch; - } - - - if (n > 0) { - if (line[n - 1] == '\r') - n--; - line[n] = 0; - /* Don't use DHD_ERROR macro since we print - * a lot of information quickly. The macro - * will truncate a lot of the printfs - */ - - if (dhd_msg_level & DHD_ERROR_VAL) { - printf("CONSOLE: %s\n", line); - DHD_BLOG(line, strlen(line) + 1); - } - } - } - } - } - -printbuf: - if (sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP)) { - DHD_ERROR(("%s: %s\n", __FUNCTION__, strbuf.origbuf)); - } - - -done: - if (mbuffer) - MFREE(bus->dhd->osh, mbuffer, msize); - if (str) - MFREE(bus->dhd->osh, str, maxstrlen); - if (console_buffer) - MFREE(bus->dhd->osh, console_buffer, console_size); - - return bcmerror; -} -#endif /* #ifdef DHD_DEBUG */ - - -int -dhdsdio_downloadvars(dhd_bus_t *bus, void *arg, int len) -{ - int bcmerror = BCME_OK; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* Basic sanity checks */ - if (bus->dhd->up) { - bcmerror = BCME_NOTDOWN; - goto err; - } - if (!len) { - bcmerror = BCME_BUFTOOSHORT; - goto err; - } - - /* Free the old ones and replace with passed variables */ - if (bus->vars) - MFREE(bus->dhd->osh, bus->vars, bus->varsz); - - bus->vars = MALLOC(bus->dhd->osh, len); - bus->varsz = bus->vars ? len : 0; - if (bus->vars == NULL) { - bcmerror = BCME_NOMEM; - goto err; - } - - /* Copy the passed variables, which should include the terminating double-null */ - bcopy(arg, bus->vars, bus->varsz); -err: - return bcmerror; -} - -#ifdef DHD_DEBUG - -#define CC_PLL_CHIPCTRL_SERIAL_ENAB (1 << 24) -static int -dhd_serialconsole(dhd_bus_t *bus, bool set, bool enable, int *bcmerror) -{ - int int_val; - uint32 addr, data; - - - addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_addr); - data = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_data); - *bcmerror = 0; - - bcmsdh_reg_write(bus->sdh, addr, 4, 1); - if (bcmsdh_regfail(bus->sdh)) { - *bcmerror = BCME_SDIO_ERROR; - return -1; - } - int_val = bcmsdh_reg_read(bus->sdh, data, 4); - if (bcmsdh_regfail(bus->sdh)) { - *bcmerror = BCME_SDIO_ERROR; - return -1; - } - if (!set) - return (int_val & CC_PLL_CHIPCTRL_SERIAL_ENAB); - if (enable) - int_val |= CC_PLL_CHIPCTRL_SERIAL_ENAB; - else - int_val &= ~CC_PLL_CHIPCTRL_SERIAL_ENAB; - bcmsdh_reg_write(bus->sdh, data, 4, int_val); - if (bcmsdh_regfail(bus->sdh)) { - *bcmerror = BCME_SDIO_ERROR; - return -1; - } - if (bus->sih->chip == BCM4330_CHIP_ID) { - uint32 chipcontrol; - addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol); - chipcontrol = bcmsdh_reg_read(bus->sdh, addr, 4); - chipcontrol &= ~0x8; - if (enable) { - chipcontrol |= 0x8; - chipcontrol &= ~0x3; - } - bcmsdh_reg_write(bus->sdh, addr, 4, chipcontrol); - } - - return (int_val & CC_PLL_CHIPCTRL_SERIAL_ENAB); -} -#endif - -static int -dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const char *name, - void *params, int plen, void *arg, int len, int val_size) -{ - int bcmerror = 0; - int32 int_val = 0; - bool bool_val = 0; - - DHD_TRACE(("%s: Enter, action %d name %s params %p plen %d arg %p len %d val_size %d\n", - __FUNCTION__, actionid, name, params, plen, arg, len, val_size)); - - if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid))) != 0) - goto exit; - - if (plen >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); - - bool_val = (int_val != 0) ? TRUE : FALSE; - - - /* Some ioctls use the bus */ - dhd_os_sdlock(bus->dhd); - - /* Check if dongle is in reset. If so, only allow DEVRESET iovars */ - if (bus->dhd->dongle_reset && !(actionid == IOV_SVAL(IOV_DEVRESET) || - actionid == IOV_GVAL(IOV_DEVRESET))) { - bcmerror = BCME_NOTREADY; - goto exit; - } - - /* Handle sleep stuff before any clock mucking */ - if (vi->varid == IOV_SLEEP) { - if (IOV_ISSET(actionid)) { - bcmerror = dhdsdio_bussleep(bus, bool_val); - } else { - int_val = (int32)bus->sleeping; - bcopy(&int_val, arg, val_size); - } - goto exit; - } - - /* Request clock to allow SDIO accesses */ - if (!bus->dhd->dongle_reset) { - BUS_WAKE(bus); - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - } - - switch (actionid) { - case IOV_GVAL(IOV_INTR): - int_val = (int32)bus->intr; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_INTR): - bus->intr = bool_val; - bus->intdis = FALSE; - if (bus->dhd->up) { - if (bus->intr) { - DHD_INTR(("%s: enable SDIO device interrupts\n", __FUNCTION__)); - bcmsdh_intr_enable(bus->sdh); - } else { - DHD_INTR(("%s: disable SDIO interrupts\n", __FUNCTION__)); - bcmsdh_intr_disable(bus->sdh); - } - } - break; - - case IOV_GVAL(IOV_POLLRATE): - int_val = (int32)bus->pollrate; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_POLLRATE): - bus->pollrate = (uint)int_val; - bus->poll = (bus->pollrate != 0); - break; - - case IOV_GVAL(IOV_IDLETIME): - int_val = bus->idletime; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_IDLETIME): - if ((int_val < 0) && (int_val != DHD_IDLE_IMMEDIATE)) { - bcmerror = BCME_BADARG; - } else { - bus->idletime = int_val; - } - break; - - case IOV_GVAL(IOV_IDLECLOCK): - int_val = (int32)bus->idleclock; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_IDLECLOCK): - bus->idleclock = int_val; - break; - - case IOV_GVAL(IOV_SD1IDLE): - int_val = (int32)sd1idle; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_SD1IDLE): - sd1idle = bool_val; - break; - - - case IOV_SVAL(IOV_MEMBYTES): - case IOV_GVAL(IOV_MEMBYTES): - { - uint32 address; - uint size, dsize; - uint8 *data; - - bool set = (actionid == IOV_SVAL(IOV_MEMBYTES)); - - ASSERT(plen >= 2*sizeof(int)); - - address = (uint32)int_val; - bcopy((char *)params + sizeof(int_val), &int_val, sizeof(int_val)); - size = (uint)int_val; - - /* Do some validation */ - dsize = set ? plen - (2 * sizeof(int)) : len; - if (dsize < size) { - DHD_ERROR(("%s: error on %s membytes, addr 0x%08x size %d dsize %d\n", - __FUNCTION__, (set ? "set" : "get"), address, size, dsize)); - bcmerror = BCME_BADARG; - break; - } - - DHD_INFO(("%s: Request to %s %d bytes at address 0x%08x\n", __FUNCTION__, - (set ? "write" : "read"), size, address)); - - /* If we know about SOCRAM, check for a fit */ - if ((bus->orig_ramsize) && - ((address > bus->orig_ramsize) || (address + size > bus->orig_ramsize))) - { - uint8 enable, protect; - si_socdevram(bus->sih, FALSE, &enable, &protect); - if (!enable || protect) { - DHD_ERROR(("%s: ramsize 0x%08x doesn't have %d bytes at 0x%08x\n", - __FUNCTION__, bus->orig_ramsize, size, address)); - DHD_ERROR(("%s: socram enable %d, protect %d\n", - __FUNCTION__, enable, protect)); - bcmerror = BCME_BADARG; - break; - } - if (enable && (bus->sih->chip == BCM4330_CHIP_ID)) { - uint32 devramsize = si_socdevram_size(bus->sih); - if ((address < SOCDEVRAM_4330_ARM_ADDR) || - (address + size > (SOCDEVRAM_4330_ARM_ADDR + devramsize))) { - DHD_ERROR(("%s: bad address 0x%08x, size 0x%08x\n", - __FUNCTION__, address, size)); - DHD_ERROR(("%s: socram range 0x%08x,size 0x%08x\n", - __FUNCTION__, SOCDEVRAM_4330_ARM_ADDR, devramsize)); - bcmerror = BCME_BADARG; - break; - } - /* move it such that address is real now */ - address -= SOCDEVRAM_4330_ARM_ADDR; - address += SOCDEVRAM_4330_BP_ADDR; - DHD_INFO(("%s: Request to %s %d bytes @ Mapped address 0x%08x\n", - __FUNCTION__, (set ? "write" : "read"), size, address)); - } - } - - /* Generate the actual data pointer */ - data = set ? (uint8*)params + 2 * sizeof(int): (uint8*)arg; - - /* Call to do the transfer */ - bcmerror = dhdsdio_membytes(bus, set, address, data, size); - - break; - } - - case IOV_GVAL(IOV_MEMSIZE): - int_val = (int32)bus->ramsize; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_SDIOD_DRIVE): - int_val = (int32)dhd_sdiod_drive_strength; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_SDIOD_DRIVE): - dhd_sdiod_drive_strength = int_val; - si_sdiod_drive_strength_init(bus->sih, bus->dhd->osh, dhd_sdiod_drive_strength); - break; - - case IOV_SVAL(IOV_DOWNLOAD): - bcmerror = dhdsdio_download_state(bus, bool_val); - break; - - case IOV_SVAL(IOV_SOCRAM_STATE): - bcmerror = dhdsdio_download_state(bus, bool_val); - break; - - case IOV_SVAL(IOV_VARS): - bcmerror = dhdsdio_downloadvars(bus, arg, len); - break; - - case IOV_GVAL(IOV_READAHEAD): - int_val = (int32)dhd_readahead; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_READAHEAD): - if (bool_val && !dhd_readahead) - bus->nextlen = 0; - dhd_readahead = bool_val; - break; - - case IOV_GVAL(IOV_SDRXCHAIN): - int_val = (int32)bus->use_rxchain; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_SDRXCHAIN): - if (bool_val && !bus->sd_rxchain) - bcmerror = BCME_UNSUPPORTED; - else - bus->use_rxchain = bool_val; - break; - case IOV_GVAL(IOV_ALIGNCTL): - int_val = (int32)dhd_alignctl; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_ALIGNCTL): - dhd_alignctl = bool_val; - break; - - case IOV_GVAL(IOV_SDALIGN): - int_val = DHD_SDALIGN; - bcopy(&int_val, arg, val_size); - break; - -#ifdef DHD_DEBUG - case IOV_GVAL(IOV_VARS): - if (bus->varsz < (uint)len) - bcopy(bus->vars, arg, bus->varsz); - else - bcmerror = BCME_BUFTOOSHORT; - break; -#endif /* DHD_DEBUG */ - -#ifdef DHD_DEBUG - case IOV_GVAL(IOV_SDREG): - { - sdreg_t *sd_ptr; - uint32 addr, size; - - sd_ptr = (sdreg_t *)params; - - addr = (uintptr)bus->regs + sd_ptr->offset; - size = sd_ptr->func; - int_val = (int32)bcmsdh_reg_read(bus->sdh, addr, size); - if (bcmsdh_regfail(bus->sdh)) - bcmerror = BCME_SDIO_ERROR; - bcopy(&int_val, arg, sizeof(int32)); - break; - } - - case IOV_SVAL(IOV_SDREG): - { - sdreg_t *sd_ptr; - uint32 addr, size; - - sd_ptr = (sdreg_t *)params; - - addr = (uintptr)bus->regs + sd_ptr->offset; - size = sd_ptr->func; - bcmsdh_reg_write(bus->sdh, addr, size, sd_ptr->value); - if (bcmsdh_regfail(bus->sdh)) - bcmerror = BCME_SDIO_ERROR; - break; - } - - /* Same as above, but offset is not backplane (not SDIO core) */ - case IOV_GVAL(IOV_SBREG): - { - sdreg_t sdreg; - uint32 addr, size; - - bcopy(params, &sdreg, sizeof(sdreg)); - - addr = SI_ENUM_BASE + sdreg.offset; - size = sdreg.func; - int_val = (int32)bcmsdh_reg_read(bus->sdh, addr, size); - if (bcmsdh_regfail(bus->sdh)) - bcmerror = BCME_SDIO_ERROR; - bcopy(&int_val, arg, sizeof(int32)); - break; - } - - case IOV_SVAL(IOV_SBREG): - { - sdreg_t sdreg; - uint32 addr, size; - - bcopy(params, &sdreg, sizeof(sdreg)); - - addr = SI_ENUM_BASE + sdreg.offset; - size = sdreg.func; - bcmsdh_reg_write(bus->sdh, addr, size, sdreg.value); - if (bcmsdh_regfail(bus->sdh)) - bcmerror = BCME_SDIO_ERROR; - break; - } - - case IOV_GVAL(IOV_SDCIS): - { - *(char *)arg = 0; - - bcmstrcat(arg, "\nFunc 0\n"); - bcmsdh_cis_read(bus->sdh, 0x10, (uint8 *)arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT); - bcmstrcat(arg, "\nFunc 1\n"); - bcmsdh_cis_read(bus->sdh, 0x11, (uint8 *)arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT); - bcmstrcat(arg, "\nFunc 2\n"); - bcmsdh_cis_read(bus->sdh, 0x12, (uint8 *)arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT); - break; - } - - case IOV_GVAL(IOV_FORCEEVEN): - int_val = (int32)forcealign; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_FORCEEVEN): - forcealign = bool_val; - break; - - case IOV_GVAL(IOV_TXBOUND): - int_val = (int32)dhd_txbound; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_TXBOUND): - dhd_txbound = (uint)int_val; - break; - - case IOV_GVAL(IOV_RXBOUND): - int_val = (int32)dhd_rxbound; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_RXBOUND): - dhd_rxbound = (uint)int_val; - break; - - case IOV_GVAL(IOV_TXMINMAX): - int_val = (int32)dhd_txminmax; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_TXMINMAX): - dhd_txminmax = (uint)int_val; - break; - - case IOV_GVAL(IOV_SERIALCONS): - int_val = dhd_serialconsole(bus, FALSE, 0, &bcmerror); - if (bcmerror != 0) - break; - - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_SERIALCONS): - dhd_serialconsole(bus, TRUE, bool_val, &bcmerror); - break; - - - -#endif /* DHD_DEBUG */ - - -#ifdef SDTEST - case IOV_GVAL(IOV_EXTLOOP): - int_val = (int32)bus->ext_loop; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_EXTLOOP): - bus->ext_loop = bool_val; - break; - - case IOV_GVAL(IOV_PKTGEN): - bcmerror = dhdsdio_pktgen_get(bus, arg); - break; - - case IOV_SVAL(IOV_PKTGEN): - bcmerror = dhdsdio_pktgen_set(bus, arg); - break; -#endif /* SDTEST */ - - - case IOV_GVAL(IOV_DONGLEISOLATION): - int_val = bus->dhd->dongle_isolation; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DONGLEISOLATION): - bus->dhd->dongle_isolation = bool_val; - break; - - case IOV_SVAL(IOV_DEVRESET): - DHD_TRACE(("%s: Called set IOV_DEVRESET=%d dongle_reset=%d busstate=%d\n", - __FUNCTION__, bool_val, bus->dhd->dongle_reset, - bus->dhd->busstate)); - - ASSERT(bus->dhd->osh); - /* ASSERT(bus->cl_devid); */ - - dhd_bus_devreset(bus->dhd, (uint8)bool_val); - - break; -#ifdef SOFTAP - case IOV_GVAL(IOV_FWPATH): - { - uint32 fw_path_len; - - fw_path_len = strlen(bus->fw_path); - DHD_INFO(("[softap] get fwpath, l=%d\n", len)); - - if (fw_path_len > len-1) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - if (fw_path_len) { - bcopy(bus->fw_path, arg, fw_path_len); - ((uchar*)arg)[fw_path_len] = 0; - } - break; - } - - case IOV_SVAL(IOV_FWPATH): - DHD_INFO(("[softap] set fwpath, idx=%d\n", int_val)); - - switch (int_val) { - case 1: - bus->fw_path = fw_path; /* ordinary one */ - break; - case 2: - bus->fw_path = fw_path2; - break; - default: - bcmerror = BCME_BADARG; - break; - } - - DHD_INFO(("[softap] new fw path: %s\n", (bus->fw_path[0] ? bus->fw_path : "NULL"))); - break; - -#endif /* SOFTAP */ - case IOV_GVAL(IOV_DEVRESET): - DHD_TRACE(("%s: Called get IOV_DEVRESET\n", __FUNCTION__)); - - /* Get its status */ - int_val = (bool) bus->dhd->dongle_reset; - bcopy(&int_val, arg, val_size); - - break; - - default: - bcmerror = BCME_UNSUPPORTED; - break; - } - -exit: - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, TRUE); - } - - dhd_os_sdunlock(bus->dhd); - - if (actionid == IOV_SVAL(IOV_DEVRESET) && bool_val == FALSE) - dhd_preinit_ioctls((dhd_pub_t *) bus->dhd); - - return bcmerror; -} - -static int -dhdsdio_write_vars(dhd_bus_t *bus) -{ - int bcmerror = 0; - uint32 varsize; - uint32 varaddr; - uint8 *vbuffer; - uint32 varsizew; -#ifdef DHD_DEBUG - uint8 *nvram_ularray; -#endif /* DHD_DEBUG */ - - /* Even if there are no vars are to be written, we still need to set the ramsize. */ - varsize = bus->varsz ? ROUNDUP(bus->varsz, 4) : 0; - varaddr = (bus->ramsize - 4) - varsize; - - if (bus->vars) { - if ((bus->sih->buscoretype == SDIOD_CORE_ID) && (bus->sdpcmrev == 7)) { - if (((varaddr & 0x3C) == 0x3C) && (varsize > 4)) { - DHD_ERROR(("PR85623WAR in place\n")); - varsize += 4; - varaddr -= 4; - } - } - - vbuffer = (uint8 *)MALLOC(bus->dhd->osh, varsize); - if (!vbuffer) - return BCME_NOMEM; - - bzero(vbuffer, varsize); - bcopy(bus->vars, vbuffer, bus->varsz); - - /* Write the vars list */ - bcmerror = dhdsdio_membytes(bus, TRUE, varaddr, vbuffer, varsize); -#ifdef DHD_DEBUG - /* Verify NVRAM bytes */ - DHD_INFO(("Compare NVRAM dl & ul; varsize=%d\n", varsize)); - nvram_ularray = (uint8*)MALLOC(bus->dhd->osh, varsize); - if (!nvram_ularray) - return BCME_NOMEM; - - /* Upload image to verify downloaded contents. */ - memset(nvram_ularray, 0xaa, varsize); - - /* Read the vars list to temp buffer for comparison */ - bcmerror = dhdsdio_membytes(bus, FALSE, varaddr, nvram_ularray, varsize); - if (bcmerror) { - DHD_ERROR(("%s: error %d on reading %d nvram bytes at 0x%08x\n", - __FUNCTION__, bcmerror, varsize, varaddr)); - } - /* Compare the org NVRAM with the one read from RAM */ - if (memcmp(vbuffer, nvram_ularray, varsize)) { - DHD_ERROR(("%s: Downloaded NVRAM image is corrupted.\n", __FUNCTION__)); - } else - DHD_ERROR(("%s: Download, Upload and compare of NVRAM succeeded.\n", - __FUNCTION__)); - - MFREE(bus->dhd->osh, nvram_ularray, varsize); -#endif /* DHD_DEBUG */ - - MFREE(bus->dhd->osh, vbuffer, varsize); - } - - /* adjust to the user specified RAM */ - DHD_INFO(("Physical memory size: %d, usable memory size: %d\n", - bus->orig_ramsize, bus->ramsize)); - DHD_INFO(("Vars are at %d, orig varsize is %d\n", - varaddr, varsize)); - varsize = ((bus->orig_ramsize - 4) - varaddr); - - /* - * Determine the length token: - * Varsize, converted to words, in lower 16-bits, checksum in upper 16-bits. - */ - if (bcmerror) { - varsizew = 0; - } else { - varsizew = varsize / 4; - varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF); - varsizew = htol32(varsizew); - } - - DHD_INFO(("New varsize is %d, length token=0x%08x\n", varsize, varsizew)); - - /* Write the length token to the last word */ - bcmerror = dhdsdio_membytes(bus, TRUE, (bus->orig_ramsize - 4), - (uint8*)&varsizew, 4); - - return bcmerror; -} - -static int -dhdsdio_download_state(dhd_bus_t *bus, bool enter) -{ - uint retries; - int bcmerror = 0; - - if (!bus->sih) - return BCME_ERROR; - - /* To enter download state, disable ARM and reset SOCRAM. - * To exit download state, simply reset ARM (default is RAM boot). - */ - if (enter) { - bus->alp_only = TRUE; - - if (!(si_setcore(bus->sih, ARM7S_CORE_ID, 0)) && - !(si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find ARM core!\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } - - si_core_disable(bus->sih, 0); - if (bcmsdh_regfail(bus->sdh)) { - bcmerror = BCME_SDIO_ERROR; - goto fail; - } - - if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find SOCRAM core!\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } - - si_core_reset(bus->sih, 0, 0); - if (bcmsdh_regfail(bus->sdh)) { - DHD_ERROR(("%s: Failure trying reset SOCRAM core?\n", __FUNCTION__)); - bcmerror = BCME_SDIO_ERROR; - goto fail; - } - - /* Clear the top bit of memory */ - if (bus->ramsize) { - uint32 zeros = 0; - if (dhdsdio_membytes(bus, TRUE, bus->ramsize - 4, (uint8*)&zeros, 4) < 0) { - bcmerror = BCME_SDIO_ERROR; - goto fail; - } - } - } else { - if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find SOCRAM core!\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } - - if (!si_iscoreup(bus->sih)) { - DHD_ERROR(("%s: SOCRAM core is down after reset?\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } - - if ((bcmerror = dhdsdio_write_vars(bus))) { - DHD_ERROR(("%s: could not write vars to RAM\n", __FUNCTION__)); - goto fail; - } - - if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0) && - !si_setcore(bus->sih, SDIOD_CORE_ID, 0)) { - DHD_ERROR(("%s: Can't change back to SDIO core?\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } - W_SDREG(0xFFFFFFFF, &bus->regs->intstatus, retries); - - - if (!(si_setcore(bus->sih, ARM7S_CORE_ID, 0)) && - !(si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find ARM core!\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } - - si_core_reset(bus->sih, 0, 0); - if (bcmsdh_regfail(bus->sdh)) { - DHD_ERROR(("%s: Failure trying to reset ARM core?\n", __FUNCTION__)); - bcmerror = BCME_SDIO_ERROR; - goto fail; - } - - /* Allow HT Clock now that the ARM is running. */ - bus->alp_only = FALSE; - - bus->dhd->busstate = DHD_BUS_LOAD; - } - -fail: - /* Always return to SDIOD core */ - if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0)) - si_setcore(bus->sih, SDIOD_CORE_ID, 0); - - return bcmerror; -} - -int -dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - dhd_bus_t *bus = dhdp->bus; - const bcm_iovar_t *vi = NULL; - int bcmerror = 0; - int val_size; - uint32 actionid; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - ASSERT(name); - ASSERT(len >= 0); - - /* Get MUST have return space */ - ASSERT(set || (arg && len)); - - /* Set does NOT take qualifiers */ - ASSERT(!set || (!params && !plen)); - - /* Look up var locally; if not found pass to host driver */ - if ((vi = bcm_iovar_lookup(dhdsdio_iovars, name)) == NULL) { - dhd_os_sdlock(bus->dhd); - - BUS_WAKE(bus); - - /* Turn on clock in case SD command needs backplane */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - bcmerror = bcmsdh_iovar_op(bus->sdh, name, params, plen, arg, len, set); - - /* Check for bus configuration changes of interest */ - - /* If it was divisor change, read the new one */ - if (set && strcmp(name, "sd_divisor") == 0) { - if (bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0, - &bus->sd_divisor, sizeof(int32), FALSE) != BCME_OK) { - bus->sd_divisor = -1; - DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__, name)); - } else { - DHD_INFO(("%s: noted %s update, value now %d\n", - __FUNCTION__, name, bus->sd_divisor)); - } - } - /* If it was a mode change, read the new one */ - if (set && strcmp(name, "sd_mode") == 0) { - if (bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0, - &bus->sd_mode, sizeof(int32), FALSE) != BCME_OK) { - bus->sd_mode = -1; - DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__, name)); - } else { - DHD_INFO(("%s: noted %s update, value now %d\n", - __FUNCTION__, name, bus->sd_mode)); - } - } - /* Similar check for blocksize change */ - if (set && strcmp(name, "sd_blocksize") == 0) { - int32 fnum = 2; - if (bcmsdh_iovar_op(bus->sdh, "sd_blocksize", &fnum, sizeof(int32), - &bus->blocksize, sizeof(int32), FALSE) != BCME_OK) { - bus->blocksize = 0; - DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__, "sd_blocksize")); - } else { - DHD_INFO(("%s: noted %s update, value now %d\n", - __FUNCTION__, "sd_blocksize", bus->blocksize)); - } - } - bus->roundup = MIN(max_roundup, bus->blocksize); - - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, TRUE); - } - - dhd_os_sdunlock(bus->dhd); - goto exit; - } - - DHD_CTL(("%s: %s %s, len %d plen %d\n", __FUNCTION__, - name, (set ? "set" : "get"), len, plen)); - - /* set up 'params' pointer in case this is a set command so that - * the convenience int and bool code can be common to set and get - */ - if (params == NULL) { - params = arg; - plen = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - /* all other types are integer sized */ - val_size = sizeof(int); - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - bcmerror = dhdsdio_doiovar(bus, vi, actionid, name, params, plen, arg, len, val_size); - -exit: - return bcmerror; -} - -void -dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex) -{ - osl_t *osh; - uint32 local_hostintmask; - uint8 saveclk; - uint retries; - int err; - if (!bus->dhd) - return; - - osh = bus->dhd->osh; - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - bcmsdh_waitlockfree(NULL); - - if (enforce_mutex) - dhd_os_sdlock(bus->dhd); - - BUS_WAKE(bus); - - /* Change our idea of bus state */ - bus->dhd->busstate = DHD_BUS_DOWN; - - /* Enable clock for device interrupts */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - /* Disable and clear interrupts at the chip level also */ - W_SDREG(0, &bus->regs->hostintmask, retries); - local_hostintmask = bus->hostintmask; - bus->hostintmask = 0; - - /* Force clocks on backplane to be sure F2 interrupt propagates */ - saveclk = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); - if (!err) { - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - (saveclk | SBSDIO_FORCE_HT), &err); - } - if (err) { - DHD_ERROR(("%s: Failed to force clock for F2: err %d\n", __FUNCTION__, err)); - } - - /* Turn off the bus (F2), free any pending packets */ - DHD_INTR(("%s: disable SDIO interrupts\n", __FUNCTION__)); - bcmsdh_intr_disable(bus->sdh); - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, SDIO_FUNC_ENABLE_1, NULL); - - /* Clear any pending interrupts now that F2 is disabled */ - W_SDREG(local_hostintmask, &bus->regs->intstatus, retries); - - /* Turn off the backplane clock (only) */ - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); - - /* Clear the data packet queues */ - pktq_flush(osh, &bus->txq, TRUE, NULL, 0); - - /* Clear any held glomming stuff */ - if (bus->glomd) - PKTFREE(osh, bus->glomd, FALSE); - - if (bus->glom) - PKTFREE(osh, bus->glom, FALSE); - - bus->glom = bus->glomd = NULL; - - /* Clear rx control and wake any waiters */ - bus->rxlen = 0; - dhd_os_ioctl_resp_wake(bus->dhd); - - /* Reset some F2 state stuff */ - bus->rxskip = FALSE; - bus->tx_seq = bus->rx_seq = 0; - - /* Set to a safe default. It gets updated when we - * receive a packet from the fw but when we reset, - * we need a safe default to be able to send the - * initial mac address. - */ - bus->tx_max = 4; - - if (enforce_mutex) - dhd_os_sdunlock(bus->dhd); -} - - -int -dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex) -{ - dhd_bus_t *bus = dhdp->bus; - dhd_timeout_t tmo; - uint retries = 0; - uint8 ready, enable; - int err, ret = 0; - uint8 saveclk; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - ASSERT(bus->dhd); - if (!bus->dhd) - return 0; - - if (enforce_mutex) - dhd_os_sdlock(bus->dhd); - - /* Make sure backplane clock is on, needed to generate F2 interrupt */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - if (bus->clkstate != CLK_AVAIL) { - DHD_ERROR(("%s: clock state is wrong. state = %d\n", __FUNCTION__, bus->clkstate)); - goto exit; - } - - - /* Force clocks on backplane to be sure F2 interrupt propagates */ - saveclk = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); - if (!err) { - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - (saveclk | SBSDIO_FORCE_HT), &err); - } - if (err) { - DHD_ERROR(("%s: Failed to force clock for F2: err %d\n", __FUNCTION__, err)); - goto exit; - } - - /* Enable function 2 (frame transfers) */ - W_SDREG((SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT), - &bus->regs->tosbmailboxdata, retries); - enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2); - - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable, NULL); - - /* Give the dongle some time to do its thing and set IOR2 */ - dhd_timeout_start(&tmo, DHD_WAIT_F2RDY * 1000); - - ready = 0; - do { - ready = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IORDY, NULL); - } while (ready != enable && !dhd_timeout_expired(&tmo)); - - DHD_INFO(("%s: enable 0x%02x, ready 0x%02x (waited %uus)\n", - __FUNCTION__, enable, ready, tmo.elapsed)); - - - /* If F2 successfully enabled, set core and enable interrupts */ - if (ready == enable) { - /* Make sure we're talking to the core. */ - if (!(bus->regs = si_setcore(bus->sih, PCMCIA_CORE_ID, 0))) - bus->regs = si_setcore(bus->sih, SDIOD_CORE_ID, 0); - ASSERT(bus->regs != NULL); - - /* Set up the interrupt mask and enable interrupts */ - bus->hostintmask = HOSTINTMASK; - /* corerev 4 could use the newer interrupt logic to detect the frames */ - if ((bus->sih->buscoretype == SDIOD_CORE_ID) && (bus->sdpcmrev == 4) && - (bus->rxint_mode != SDIO_DEVICE_HMB_RXINT)) { - bus->hostintmask &= ~I_HMB_FRAME_IND; - bus->hostintmask |= I_XMTDATA_AVAIL; - } - W_SDREG(bus->hostintmask, &bus->regs->hostintmask, retries); - - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK, (uint8)watermark, &err); - - /* Set bus state according to enable result */ - dhdp->busstate = DHD_BUS_DATA; - - /* bcmsdh_intr_unmask(bus->sdh); */ - - bus->intdis = FALSE; - if (bus->intr) { - DHD_INTR(("%s: enable SDIO device interrupts\n", __FUNCTION__)); - bcmsdh_intr_enable(bus->sdh); - } else { - DHD_INTR(("%s: disable SDIO interrupts\n", __FUNCTION__)); - bcmsdh_intr_disable(bus->sdh); - } - - } - - - else { - /* Disable F2 again */ - enable = SDIO_FUNC_ENABLE_1; - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable, NULL); - } - - /* Restore previous clock setting */ - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err); - - - /* If we didn't come up, turn off backplane clock */ - if (dhdp->busstate != DHD_BUS_DATA) - dhdsdio_clkctl(bus, CLK_NONE, FALSE); - -exit: - if (enforce_mutex) - dhd_os_sdunlock(bus->dhd); - - return ret; -} - -static void -dhdsdio_rxfail(dhd_bus_t *bus, bool abort, bool rtx) -{ - bcmsdh_info_t *sdh = bus->sdh; - sdpcmd_regs_t *regs = bus->regs; - uint retries = 0; - uint16 lastrbc; - uint8 hi, lo; - int err; - - DHD_ERROR(("%s: %sterminate frame%s\n", __FUNCTION__, - (abort ? "abort command, " : ""), (rtx ? ", send NAK" : ""))); - - if (abort) { - bcmsdh_abort(sdh, SDIO_FUNC_2); - } - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM, &err); - bus->f1regdata++; - - /* Wait until the packet has been flushed (device/FIFO stable) */ - for (lastrbc = retries = 0xffff; retries > 0; retries--) { - hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCHI, NULL); - lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCLO, NULL); - bus->f1regdata += 2; - - if ((hi == 0) && (lo == 0)) - break; - - if ((hi > (lastrbc >> 8)) && (lo > (lastrbc & 0x00ff))) { - DHD_ERROR(("%s: count growing: last 0x%04x now 0x%04x\n", - __FUNCTION__, lastrbc, ((hi << 8) + lo))); - } - lastrbc = (hi << 8) + lo; - } - - if (!retries) { - DHD_ERROR(("%s: count never zeroed: last 0x%04x\n", __FUNCTION__, lastrbc)); - } else { - DHD_INFO(("%s: flush took %d iterations\n", __FUNCTION__, (0xffff - retries))); - } - - if (rtx) { - bus->rxrtx++; - W_SDREG(SMB_NAK, ®s->tosbmailbox, retries); - bus->f1regdata++; - if (retries <= retry_limit) { - bus->rxskip = TRUE; - } - } - - /* Clear partial in any case */ - bus->nextlen = 0; - - /* If we can't reach the device, signal failure */ - if (err || bcmsdh_regfail(sdh)) - bus->dhd->busstate = DHD_BUS_DOWN; -} - -static void -dhdsdio_read_control(dhd_bus_t *bus, uint8 *hdr, uint len, uint doff) -{ - bcmsdh_info_t *sdh = bus->sdh; - uint rdlen, pad; - - int sdret; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* Control data already received in aligned rxctl */ - if ((bus->bus == SPI_BUS) && (!bus->usebufpool)) - goto gotpkt; - - ASSERT(bus->rxbuf); - /* Set rxctl for frame (w/optional alignment) */ - bus->rxctl = bus->rxbuf; - if (dhd_alignctl) { - bus->rxctl += firstread; - if ((pad = ((uintptr)bus->rxctl % DHD_SDALIGN))) - bus->rxctl += (DHD_SDALIGN - pad); - bus->rxctl -= firstread; - } - ASSERT(bus->rxctl >= bus->rxbuf); - - /* Copy the already-read portion over */ - bcopy(hdr, bus->rxctl, firstread); - if (len <= firstread) - goto gotpkt; - - /* Copy the full data pkt in gSPI case and process ioctl. */ - if (bus->bus == SPI_BUS) { - bcopy(hdr, bus->rxctl, len); - goto gotpkt; - } - - /* Raise rdlen to next SDIO block to avoid tail command */ - rdlen = len - firstread; - if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) { - pad = bus->blocksize - (rdlen % bus->blocksize); - if ((pad <= bus->roundup) && (pad < bus->blocksize) && - ((len + pad) < bus->dhd->maxctl)) - rdlen += pad; - } else if (rdlen % DHD_SDALIGN) { - rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN); - } - - /* Satisfy length-alignment requirements */ - if (forcealign && (rdlen & (ALIGNMENT - 1))) - rdlen = ROUNDUP(rdlen, ALIGNMENT); - - /* Drop if the read is too big or it exceeds our maximum */ - if ((rdlen + firstread) > bus->dhd->maxctl) { - DHD_ERROR(("%s: %d-byte control read exceeds %d-byte buffer\n", - __FUNCTION__, rdlen, bus->dhd->maxctl)); - bus->dhd->rx_errors++; - dhdsdio_rxfail(bus, FALSE, FALSE); - goto done; - } - - if ((len - doff) > bus->dhd->maxctl) { - DHD_ERROR(("%s: %d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n", - __FUNCTION__, len, (len - doff), bus->dhd->maxctl)); - bus->dhd->rx_errors++; bus->rx_toolong++; - dhdsdio_rxfail(bus, FALSE, FALSE); - goto done; - } - - - /* Read remainder of frame body into the rxctl buffer */ - sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - (bus->rxctl + firstread), rdlen, NULL, NULL, NULL); - bus->f2rxdata++; - ASSERT(sdret != BCME_PENDING); - - /* Control frame failures need retransmission */ - if (sdret < 0) { - DHD_ERROR(("%s: read %d control bytes failed: %d\n", __FUNCTION__, rdlen, sdret)); - bus->rxc_errors++; /* dhd.rx_ctlerrs is higher level */ - dhdsdio_rxfail(bus, TRUE, TRUE); - goto done; - } - -gotpkt: - -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_CTL_ON()) { - prhex("RxCtrl", bus->rxctl, len); - } -#endif - - /* Point to valid data and indicate its length */ - bus->rxctl += doff; - bus->rxlen = len - doff; - -done: - /* Awake any waiters */ - dhd_os_ioctl_resp_wake(bus->dhd); -} - -static uint8 -dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq) -{ - uint16 dlen, totlen; - uint8 *dptr, num = 0; - - uint16 sublen, check; - void *pfirst, *plast, *pnext, *save_pfirst; - osl_t *osh = bus->dhd->osh; - - int errcode; - uint8 chan, seq, doff, sfdoff; - uint8 txmax; - - int ifidx = 0; - bool usechain = bus->use_rxchain; - - /* If packets, issue read(s) and send up packet chain */ - /* Return sequence numbers consumed? */ - - DHD_TRACE(("dhdsdio_rxglom: start: glomd %p glom %p\n", bus->glomd, bus->glom)); - - /* If there's a descriptor, generate the packet chain */ - if (bus->glomd) { - dhd_os_sdlock_rxq(bus->dhd); - - pfirst = plast = pnext = NULL; - dlen = (uint16)PKTLEN(osh, bus->glomd); - dptr = PKTDATA(osh, bus->glomd); - if (!dlen || (dlen & 1)) { - DHD_ERROR(("%s: bad glomd len (%d), ignore descriptor\n", - __FUNCTION__, dlen)); - dlen = 0; - } - - for (totlen = num = 0; dlen; num++) { - /* Get (and move past) next length */ - sublen = ltoh16_ua(dptr); - dlen -= sizeof(uint16); - dptr += sizeof(uint16); - if ((sublen < SDPCM_HDRLEN) || - ((num == 0) && (sublen < (2 * SDPCM_HDRLEN)))) { - DHD_ERROR(("%s: descriptor len %d bad: %d\n", - __FUNCTION__, num, sublen)); - pnext = NULL; - break; - } - if (sublen % DHD_SDALIGN) { - DHD_ERROR(("%s: sublen %d not a multiple of %d\n", - __FUNCTION__, sublen, DHD_SDALIGN)); - usechain = FALSE; - } - totlen += sublen; - - /* For last frame, adjust read len so total is a block multiple */ - if (!dlen) { - sublen += (ROUNDUP(totlen, bus->blocksize) - totlen); - totlen = ROUNDUP(totlen, bus->blocksize); - } - - /* Allocate/chain packet for next subframe */ - if ((pnext = PKTGET(osh, sublen + DHD_SDALIGN, FALSE)) == NULL) { - DHD_ERROR(("%s: PKTGET failed, num %d len %d\n", - __FUNCTION__, num, sublen)); - break; - } - ASSERT(!PKTLINK(pnext)); - if (!pfirst) { - ASSERT(!plast); - pfirst = plast = pnext; - } else { - ASSERT(plast); - PKTSETNEXT(osh, plast, pnext); - plast = pnext; - } - - /* Adhere to start alignment requirements */ - PKTALIGN(osh, pnext, sublen, DHD_SDALIGN); - } - - /* If all allocations succeeded, save packet chain in bus structure */ - if (pnext) { - DHD_GLOM(("%s: allocated %d-byte packet chain for %d subframes\n", - __FUNCTION__, totlen, num)); - if (DHD_GLOM_ON() && bus->nextlen) { - if (totlen != bus->nextlen) { - DHD_GLOM(("%s: glomdesc mismatch: nextlen %d glomdesc %d " - "rxseq %d\n", __FUNCTION__, bus->nextlen, - totlen, rxseq)); - } - } - bus->glom = pfirst; - pfirst = pnext = NULL; - } else { - if (pfirst) - PKTFREE(osh, pfirst, FALSE); - bus->glom = NULL; - num = 0; - } - - /* Done with descriptor packet */ - PKTFREE(osh, bus->glomd, FALSE); - bus->glomd = NULL; - bus->nextlen = 0; - - dhd_os_sdunlock_rxq(bus->dhd); - } - - /* Ok -- either we just generated a packet chain, or had one from before */ - if (bus->glom) { - if (DHD_GLOM_ON()) { - DHD_GLOM(("%s: attempt superframe read, packet chain:\n", __FUNCTION__)); - for (pnext = bus->glom; pnext; pnext = PKTNEXT(osh, pnext)) { - DHD_GLOM((" %p: %p len 0x%04x (%d)\n", - pnext, (uint8*)PKTDATA(osh, pnext), - PKTLEN(osh, pnext), PKTLEN(osh, pnext))); - } - } - - pfirst = bus->glom; - dlen = (uint16)pkttotlen(osh, pfirst); - - /* Do an SDIO read for the superframe. Configurable iovar to - * read directly into the chained packet, or allocate a large - * packet and and copy into the chain. - */ - if (usechain) { - errcode = dhd_bcmsdh_recv_buf(bus, - bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2, - F2SYNC, (uint8*)PKTDATA(osh, pfirst), - dlen, pfirst, NULL, NULL); - } else if (bus->dataptr) { - errcode = dhd_bcmsdh_recv_buf(bus, - bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2, - F2SYNC, bus->dataptr, - dlen, NULL, NULL, NULL); - sublen = (uint16)pktfrombuf(osh, pfirst, 0, dlen, bus->dataptr); - if (sublen != dlen) { - DHD_ERROR(("%s: FAILED TO COPY, dlen %d sublen %d\n", - __FUNCTION__, dlen, sublen)); - errcode = -1; - } - pnext = NULL; - } else { - DHD_ERROR(("COULDN'T ALLOC %d-BYTE GLOM, FORCE FAILURE\n", dlen)); - errcode = -1; - } - bus->f2rxdata++; - ASSERT(errcode != BCME_PENDING); - - /* On failure, kill the superframe, allow a couple retries */ - if (errcode < 0) { - DHD_ERROR(("%s: glom read of %d bytes failed: %d\n", - __FUNCTION__, dlen, errcode)); - bus->dhd->rx_errors++; - - if (bus->glomerr++ < 3) { - dhdsdio_rxfail(bus, TRUE, TRUE); - } else { - bus->glomerr = 0; - dhdsdio_rxfail(bus, TRUE, FALSE); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(osh, bus->glom, FALSE); - dhd_os_sdunlock_rxq(bus->dhd); - bus->rxglomfail++; - bus->glom = NULL; - } - return 0; - } - -#ifdef DHD_DEBUG - if (DHD_GLOM_ON()) { - prhex("SUPERFRAME", PKTDATA(osh, pfirst), - MIN(PKTLEN(osh, pfirst), 48)); - } -#endif - - - /* Validate the superframe header */ - dptr = (uint8 *)PKTDATA(osh, pfirst); - sublen = ltoh16_ua(dptr); - check = ltoh16_ua(dptr + sizeof(uint16)); - - chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); - seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); - bus->nextlen = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; - if ((bus->nextlen << 4) > MAX_RX_DATASZ) { - DHD_INFO(("%s: got frame w/nextlen too large (%d) seq %d\n", - __FUNCTION__, bus->nextlen, seq)); - bus->nextlen = 0; - } - doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); - txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); - - errcode = 0; - if ((uint16)~(sublen^check)) { - DHD_ERROR(("%s (superframe): HW hdr error: len/check 0x%04x/0x%04x\n", - __FUNCTION__, sublen, check)); - errcode = -1; - } else if (ROUNDUP(sublen, bus->blocksize) != dlen) { - DHD_ERROR(("%s (superframe): len 0x%04x, rounded 0x%04x, expect 0x%04x\n", - __FUNCTION__, sublen, ROUNDUP(sublen, bus->blocksize), dlen)); - errcode = -1; - } else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) != SDPCM_GLOM_CHANNEL) { - DHD_ERROR(("%s (superframe): bad channel %d\n", __FUNCTION__, - SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]))); - errcode = -1; - } else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) { - DHD_ERROR(("%s (superframe): got second descriptor?\n", __FUNCTION__)); - errcode = -1; - } else if ((doff < SDPCM_HDRLEN) || - (doff > (PKTLEN(osh, pfirst) - SDPCM_HDRLEN))) { - DHD_ERROR(("%s (superframe): Bad data offset %d: HW %d pkt %d min %d\n", - __FUNCTION__, doff, sublen, PKTLEN(osh, pfirst), SDPCM_HDRLEN)); - errcode = -1; - } - - /* Check sequence number of superframe SW header */ - if (rxseq != seq) { - DHD_INFO(("%s: (superframe) rx_seq %d, expected %d\n", - __FUNCTION__, seq, rxseq)); - bus->rx_badseq++; - rxseq = seq; - } - - /* Check window for sanity */ - if ((uint8)(txmax - bus->tx_seq) > 0x40) { - DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n", - __FUNCTION__, txmax, bus->tx_seq)); - txmax = bus->tx_max; - } - bus->tx_max = txmax; - - /* Remove superframe header, remember offset */ - PKTPULL(osh, pfirst, doff); - sfdoff = doff; - - /* Validate all the subframe headers */ - for (num = 0, pnext = pfirst; pnext && !errcode; - num++, pnext = PKTNEXT(osh, pnext)) { - dptr = (uint8 *)PKTDATA(osh, pnext); - dlen = (uint16)PKTLEN(osh, pnext); - sublen = ltoh16_ua(dptr); - check = ltoh16_ua(dptr + sizeof(uint16)); - chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); - doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); -#ifdef DHD_DEBUG - if (DHD_GLOM_ON()) { - prhex("subframe", dptr, 32); - } -#endif - - if ((uint16)~(sublen^check)) { - DHD_ERROR(("%s (subframe %d): HW hdr error: " - "len/check 0x%04x/0x%04x\n", - __FUNCTION__, num, sublen, check)); - errcode = -1; - } else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN)) { - DHD_ERROR(("%s (subframe %d): length mismatch: " - "len 0x%04x, expect 0x%04x\n", - __FUNCTION__, num, sublen, dlen)); - errcode = -1; - } else if ((chan != SDPCM_DATA_CHANNEL) && - (chan != SDPCM_EVENT_CHANNEL)) { - DHD_ERROR(("%s (subframe %d): bad channel %d\n", - __FUNCTION__, num, chan)); - errcode = -1; - } else if ((doff < SDPCM_HDRLEN) || (doff > sublen)) { - DHD_ERROR(("%s (subframe %d): Bad data offset %d: HW %d min %d\n", - __FUNCTION__, num, doff, sublen, SDPCM_HDRLEN)); - errcode = -1; - } - } - - if (errcode) { - /* Terminate frame on error, request a couple retries */ - if (bus->glomerr++ < 3) { - /* Restore superframe header space */ - PKTPUSH(osh, pfirst, sfdoff); - dhdsdio_rxfail(bus, TRUE, TRUE); - } else { - bus->glomerr = 0; - dhdsdio_rxfail(bus, TRUE, FALSE); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(osh, bus->glom, FALSE); - dhd_os_sdunlock_rxq(bus->dhd); - bus->rxglomfail++; - bus->glom = NULL; - } - bus->nextlen = 0; - return 0; - } - - /* Basic SD framing looks ok - process each packet (header) */ - save_pfirst = pfirst; - bus->glom = NULL; - plast = NULL; - - dhd_os_sdlock_rxq(bus->dhd); - for (num = 0; pfirst; rxseq++, pfirst = pnext) { - pnext = PKTNEXT(osh, pfirst); - PKTSETNEXT(osh, pfirst, NULL); - - dptr = (uint8 *)PKTDATA(osh, pfirst); - sublen = ltoh16_ua(dptr); - chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); - seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); - doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); - - DHD_GLOM(("%s: Get subframe %d, %p(%p/%d), sublen %d chan %d seq %d\n", - __FUNCTION__, num, pfirst, PKTDATA(osh, pfirst), - PKTLEN(osh, pfirst), sublen, chan, seq)); - - ASSERT((chan == SDPCM_DATA_CHANNEL) || (chan == SDPCM_EVENT_CHANNEL)); - - if (rxseq != seq) { - DHD_GLOM(("%s: rx_seq %d, expected %d\n", - __FUNCTION__, seq, rxseq)); - bus->rx_badseq++; - rxseq = seq; - } - -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) { - prhex("Rx Subframe Data", dptr, dlen); - } -#endif - - PKTSETLEN(osh, pfirst, sublen); - PKTPULL(osh, pfirst, doff); - - if (PKTLEN(osh, pfirst) == 0) { - PKTFREE(bus->dhd->osh, pfirst, FALSE); - if (plast) { - PKTSETNEXT(osh, plast, pnext); - } else { - ASSERT(save_pfirst == pfirst); - save_pfirst = pnext; - } - continue; - } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pfirst) != 0) { - DHD_ERROR(("%s: rx protocol error\n", __FUNCTION__)); - bus->dhd->rx_errors++; - PKTFREE(osh, pfirst, FALSE); - if (plast) { - PKTSETNEXT(osh, plast, pnext); - } else { - ASSERT(save_pfirst == pfirst); - save_pfirst = pnext; - } - continue; - } - - /* this packet will go up, link back into chain and count it */ - PKTSETNEXT(osh, pfirst, pnext); - plast = pfirst; - num++; - -#ifdef DHD_DEBUG - if (DHD_GLOM_ON()) { - DHD_GLOM(("%s subframe %d to stack, %p(%p/%d) nxt/lnk %p/%p\n", - __FUNCTION__, num, pfirst, - PKTDATA(osh, pfirst), PKTLEN(osh, pfirst), - PKTNEXT(osh, pfirst), PKTLINK(pfirst))); - prhex("", (uint8 *)PKTDATA(osh, pfirst), - MIN(PKTLEN(osh, pfirst), 32)); - } -#endif /* DHD_DEBUG */ - } - dhd_os_sdunlock_rxq(bus->dhd); - if (num) { - dhd_os_sdunlock(bus->dhd); - dhd_rx_frame(bus->dhd, ifidx, save_pfirst, num, 0); - dhd_os_sdlock(bus->dhd); - } - - bus->rxglomframes++; - bus->rxglompkts += num; - } - return num; -} - -/* Return TRUE if there may be more frames to read */ -static uint -dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) -{ - osl_t *osh = bus->dhd->osh; - bcmsdh_info_t *sdh = bus->sdh; - - uint16 len, check; /* Extracted hardware header fields */ - uint8 chan, seq, doff; /* Extracted software header fields */ - uint8 fcbits; /* Extracted fcbits from software header */ - uint8 delta; - - void *pkt; /* Packet for event or data frames */ - uint16 pad; /* Number of pad bytes to read */ - uint16 rdlen; /* Total number of bytes to read */ - uint8 rxseq; /* Next sequence number to expect */ - uint rxleft = 0; /* Remaining number of frames allowed */ - int sdret; /* Return code from bcmsdh calls */ - uint8 txmax; /* Maximum tx sequence offered */ - bool len_consistent; /* Result of comparing readahead len and len from hw-hdr */ - uint8 *rxbuf; - int ifidx = 0; - uint rxcount = 0; /* Total frames read */ - -#if defined(DHD_DEBUG) || defined(SDTEST) - bool sdtest = FALSE; /* To limit message spew from test mode */ -#endif - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - ASSERT(maxframes); - -#ifdef SDTEST - /* Allow pktgen to override maxframes */ - if (bus->pktgen_count && (bus->pktgen_mode == DHD_PKTGEN_RECV)) { - maxframes = bus->pktgen_count; - sdtest = TRUE; - } -#endif - - /* Not finished unless we encounter no more frames indication */ - *finished = FALSE; - - - for (rxseq = bus->rx_seq, rxleft = maxframes; - !bus->rxskip && rxleft && bus->dhd->busstate != DHD_BUS_DOWN; - rxseq++, rxleft--) { - -#ifdef DHDTHREAD - /* tx more to improve rx performance */ - if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate && - pktq_mlen(&bus->txq, ~bus->flowcontrol) && DATAOK(bus)) { - dhdsdio_sendfromq(bus, dhd_txbound); - } -#endif /* DHDTHREAD */ - - /* Handle glomming separately */ - if (bus->glom || bus->glomd) { - uint8 cnt; - DHD_GLOM(("%s: calling rxglom: glomd %p, glom %p\n", - __FUNCTION__, bus->glomd, bus->glom)); - cnt = dhdsdio_rxglom(bus, rxseq); - DHD_GLOM(("%s: rxglom returned %d\n", __FUNCTION__, cnt)); - rxseq += cnt - 1; - rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1; - continue; - } - - /* Try doing single read if we can */ - if (dhd_readahead && bus->nextlen) { - uint16 nextlen = bus->nextlen; - bus->nextlen = 0; - - if (bus->bus == SPI_BUS) { - rdlen = len = nextlen; - } - else { - rdlen = len = nextlen << 4; - - /* Pad read to blocksize for efficiency */ - if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) { - pad = bus->blocksize - (rdlen % bus->blocksize); - if ((pad <= bus->roundup) && (pad < bus->blocksize) && - ((rdlen + pad + firstread) < MAX_RX_DATASZ)) - rdlen += pad; - } else if (rdlen % DHD_SDALIGN) { - rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN); - } - } - - /* We use bus->rxctl buffer in WinXP for initial control pkt receives. - * Later we use buffer-poll for data as well as control packets. - * This is required because dhd receives full frame in gSPI unlike SDIO. - * After the frame is received we have to distinguish whether it is data - * or non-data frame. - */ - /* Allocate a packet buffer */ - dhd_os_sdlock_rxq(bus->dhd); - if (!(pkt = PKTGET(osh, rdlen + DHD_SDALIGN, FALSE))) { - if (bus->bus == SPI_BUS) { - bus->usebufpool = FALSE; - bus->rxctl = bus->rxbuf; - if (dhd_alignctl) { - bus->rxctl += firstread; - if ((pad = ((uintptr)bus->rxctl % DHD_SDALIGN))) - bus->rxctl += (DHD_SDALIGN - pad); - bus->rxctl -= firstread; - } - ASSERT(bus->rxctl >= bus->rxbuf); - rxbuf = bus->rxctl; - /* Read the entire frame */ - sdret = dhd_bcmsdh_recv_buf(bus, - bcmsdh_cur_sbwad(sdh), - SDIO_FUNC_2, - F2SYNC, rxbuf, rdlen, - NULL, NULL, NULL); - bus->f2rxdata++; - ASSERT(sdret != BCME_PENDING); - - - /* Control frame failures need retransmission */ - if (sdret < 0) { - DHD_ERROR(("%s: read %d control bytes failed: %d\n", - __FUNCTION__, rdlen, sdret)); - /* dhd.rx_ctlerrs is higher level */ - bus->rxc_errors++; - dhd_os_sdunlock_rxq(bus->dhd); - dhdsdio_rxfail(bus, TRUE, - (bus->bus == SPI_BUS) ? FALSE : TRUE); - continue; - } - } else { - /* Give up on data, request rtx of events */ - DHD_ERROR(("%s (nextlen): PKTGET failed: len %d rdlen %d " - "expected rxseq %d\n", - __FUNCTION__, len, rdlen, rxseq)); - /* Just go try again w/normal header read */ - dhd_os_sdunlock_rxq(bus->dhd); - continue; - } - } else { - if (bus->bus == SPI_BUS) - bus->usebufpool = TRUE; - - ASSERT(!PKTLINK(pkt)); - PKTALIGN(osh, pkt, rdlen, DHD_SDALIGN); - rxbuf = (uint8 *)PKTDATA(osh, pkt); - /* Read the entire frame */ - sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), - SDIO_FUNC_2, - F2SYNC, rxbuf, rdlen, - pkt, NULL, NULL); - bus->f2rxdata++; - ASSERT(sdret != BCME_PENDING); - - if (sdret < 0) { - DHD_ERROR(("%s (nextlen): read %d bytes failed: %d\n", - __FUNCTION__, rdlen, sdret)); - PKTFREE(bus->dhd->osh, pkt, FALSE); - bus->dhd->rx_errors++; - dhd_os_sdunlock_rxq(bus->dhd); - /* Force retry w/normal header read. Don't attempt NAK for - * gSPI - */ - dhdsdio_rxfail(bus, TRUE, - (bus->bus == SPI_BUS) ? FALSE : TRUE); - continue; - } - } - dhd_os_sdunlock_rxq(bus->dhd); - - /* Now check the header */ - bcopy(rxbuf, bus->rxhdr, SDPCM_HDRLEN); - - /* Extract hardware header fields */ - len = ltoh16_ua(bus->rxhdr); - check = ltoh16_ua(bus->rxhdr + sizeof(uint16)); - - /* All zeros means readahead info was bad */ - if (!(len|check)) { - DHD_INFO(("%s (nextlen): read zeros in HW header???\n", - __FUNCTION__)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - GSPI_PR55150_BAILOUT; - continue; - } - - /* Validate check bytes */ - if ((uint16)~(len^check)) { - DHD_ERROR(("%s (nextlen): HW hdr error: nextlen/len/check" - " 0x%04x/0x%04x/0x%04x\n", __FUNCTION__, nextlen, - len, check)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - bus->rx_badhdr++; - dhdsdio_rxfail(bus, FALSE, FALSE); - GSPI_PR55150_BAILOUT; - continue; - } - - /* Validate frame length */ - if (len < SDPCM_HDRLEN) { - DHD_ERROR(("%s (nextlen): HW hdr length invalid: %d\n", - __FUNCTION__, len)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - GSPI_PR55150_BAILOUT; - continue; - } - - /* Check for consistency with readahead info */ - len_consistent = (nextlen != (ROUNDUP(len, 16) >> 4)); - if (len_consistent) { - /* Mismatch, force retry w/normal header (may be >4K) */ - DHD_ERROR(("%s (nextlen): mismatch, nextlen %d len %d rnd %d; " - "expected rxseq %d\n", - __FUNCTION__, nextlen, len, ROUNDUP(len, 16), rxseq)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - dhdsdio_rxfail(bus, TRUE, (bus->bus == SPI_BUS) ? FALSE : TRUE); - GSPI_PR55150_BAILOUT; - continue; - } - - - /* Extract software header fields */ - chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - - bus->nextlen = - bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; - if ((bus->nextlen << 4) > MAX_RX_DATASZ) { - DHD_INFO(("%s (nextlen): got frame w/nextlen too large" - " (%d), seq %d\n", __FUNCTION__, bus->nextlen, - seq)); - bus->nextlen = 0; - } - - bus->dhd->rx_readahead_cnt ++; - /* Handle Flow Control */ - fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - - delta = 0; - if (~bus->flowcontrol & fcbits) { - bus->fc_xoff++; - delta = 1; - } - if (bus->flowcontrol & ~fcbits) { - bus->fc_xon++; - delta = 1; - } - - if (delta) { - bus->fc_rcvd++; - bus->flowcontrol = fcbits; - } - - /* Check and update sequence number */ - if (rxseq != seq) { - DHD_INFO(("%s (nextlen): rx_seq %d, expected %d\n", - __FUNCTION__, seq, rxseq)); - bus->rx_badseq++; - rxseq = seq; - } - - /* Check window for sanity */ - if ((uint8)(txmax - bus->tx_seq) > 0x40) { - DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n", - __FUNCTION__, txmax, bus->tx_seq)); - txmax = bus->tx_max; - } - bus->tx_max = txmax; - -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) { - prhex("Rx Data", rxbuf, len); - } else if (DHD_HDRS_ON()) { - prhex("RxHdr", bus->rxhdr, SDPCM_HDRLEN); - } -#endif - - if (chan == SDPCM_CONTROL_CHANNEL) { - if (bus->bus == SPI_BUS) { - dhdsdio_read_control(bus, rxbuf, len, doff); - if (bus->usebufpool) { - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(bus->dhd->osh, pkt, FALSE); - dhd_os_sdunlock_rxq(bus->dhd); - } - continue; - } else { - DHD_ERROR(("%s (nextlen): readahead on control" - " packet %d?\n", __FUNCTION__, seq)); - /* Force retry w/normal header read */ - bus->nextlen = 0; - dhdsdio_rxfail(bus, FALSE, TRUE); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - continue; - } - } - - if ((bus->bus == SPI_BUS) && !bus->usebufpool) { - DHD_ERROR(("Received %d bytes on %d channel. Running out of " - "rx pktbuf's or not yet malloced.\n", len, chan)); - continue; - } - - /* Validate data offset */ - if ((doff < SDPCM_HDRLEN) || (doff > len)) { - DHD_ERROR(("%s (nextlen): bad data offset %d: HW len %d min %d\n", - __FUNCTION__, doff, len, SDPCM_HDRLEN)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - ASSERT(0); - dhdsdio_rxfail(bus, FALSE, FALSE); - continue; - } - - /* All done with this one -- now deliver the packet */ - goto deliver; - } - /* gSPI frames should not be handled in fractions */ - if (bus->bus == SPI_BUS) { - break; - } - - /* Read frame header (hardware and software) */ - sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - bus->rxhdr, firstread, NULL, NULL, NULL); - bus->f2rxhdrs++; - ASSERT(sdret != BCME_PENDING); - - if (sdret < 0) { - DHD_ERROR(("%s: RXHEADER FAILED: %d\n", __FUNCTION__, sdret)); - bus->rx_hdrfail++; - dhdsdio_rxfail(bus, TRUE, TRUE); - continue; - } - -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() || DHD_HDRS_ON()) { - prhex("RxHdr", bus->rxhdr, SDPCM_HDRLEN); - } -#endif - - /* Extract hardware header fields */ - len = ltoh16_ua(bus->rxhdr); - check = ltoh16_ua(bus->rxhdr + sizeof(uint16)); - - /* All zeros means no more frames */ - if (!(len|check)) { - *finished = TRUE; - break; - } - - /* Validate check bytes */ - if ((uint16)~(len^check)) { - DHD_ERROR(("%s: HW hdr error: len/check 0x%04x/0x%04x\n", - __FUNCTION__, len, check)); - bus->rx_badhdr++; - dhdsdio_rxfail(bus, FALSE, FALSE); - continue; - } - - /* Validate frame length */ - if (len < SDPCM_HDRLEN) { - DHD_ERROR(("%s: HW hdr length invalid: %d\n", __FUNCTION__, len)); - continue; - } - - /* Extract software header fields */ - chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - - /* Validate data offset */ - if ((doff < SDPCM_HDRLEN) || (doff > len)) { - DHD_ERROR(("%s: Bad data offset %d: HW len %d, min %d seq %d\n", - __FUNCTION__, doff, len, SDPCM_HDRLEN, seq)); - bus->rx_badhdr++; - ASSERT(0); - dhdsdio_rxfail(bus, FALSE, FALSE); - continue; - } - - /* Save the readahead length if there is one */ - bus->nextlen = bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; - if ((bus->nextlen << 4) > MAX_RX_DATASZ) { - DHD_INFO(("%s (nextlen): got frame w/nextlen too large (%d), seq %d\n", - __FUNCTION__, bus->nextlen, seq)); - bus->nextlen = 0; - } - - /* Handle Flow Control */ - fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - - delta = 0; - if (~bus->flowcontrol & fcbits) { - bus->fc_xoff++; - delta = 1; - } - if (bus->flowcontrol & ~fcbits) { - bus->fc_xon++; - delta = 1; - } - - if (delta) { - bus->fc_rcvd++; - bus->flowcontrol = fcbits; - } - - /* Check and update sequence number */ - if (rxseq != seq) { - DHD_INFO(("%s: rx_seq %d, expected %d\n", __FUNCTION__, seq, rxseq)); - bus->rx_badseq++; - rxseq = seq; - } - - /* Check window for sanity */ - if ((uint8)(txmax - bus->tx_seq) > 0x40) { - DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n", - __FUNCTION__, txmax, bus->tx_seq)); - txmax = bus->tx_max; - } - bus->tx_max = txmax; - - /* Call a separate function for control frames */ - if (chan == SDPCM_CONTROL_CHANNEL) { - dhdsdio_read_control(bus, bus->rxhdr, len, doff); - continue; - } - - ASSERT((chan == SDPCM_DATA_CHANNEL) || (chan == SDPCM_EVENT_CHANNEL) || - (chan == SDPCM_TEST_CHANNEL) || (chan == SDPCM_GLOM_CHANNEL)); - - /* Length to read */ - rdlen = (len > firstread) ? (len - firstread) : 0; - - /* May pad read to blocksize for efficiency */ - if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) { - pad = bus->blocksize - (rdlen % bus->blocksize); - if ((pad <= bus->roundup) && (pad < bus->blocksize) && - ((rdlen + pad + firstread) < MAX_RX_DATASZ)) - rdlen += pad; - } else if (rdlen % DHD_SDALIGN) { - rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN); - } - - /* Satisfy length-alignment requirements */ - if (forcealign && (rdlen & (ALIGNMENT - 1))) - rdlen = ROUNDUP(rdlen, ALIGNMENT); - - if ((rdlen + firstread) > MAX_RX_DATASZ) { - /* Too long -- skip this frame */ - DHD_ERROR(("%s: too long: len %d rdlen %d\n", __FUNCTION__, len, rdlen)); - bus->dhd->rx_errors++; bus->rx_toolong++; - dhdsdio_rxfail(bus, FALSE, FALSE); - continue; - } - - dhd_os_sdlock_rxq(bus->dhd); - if (!(pkt = PKTGET(osh, (rdlen + firstread + DHD_SDALIGN), FALSE))) { - /* Give up on data, request rtx of events */ - DHD_ERROR(("%s: PKTGET failed: rdlen %d chan %d\n", - __FUNCTION__, rdlen, chan)); - bus->dhd->rx_dropped++; - dhd_os_sdunlock_rxq(bus->dhd); - dhdsdio_rxfail(bus, FALSE, RETRYCHAN(chan)); - continue; - } - dhd_os_sdunlock_rxq(bus->dhd); - - ASSERT(!PKTLINK(pkt)); - - /* Leave room for what we already read, and align remainder */ - ASSERT(firstread < (PKTLEN(osh, pkt))); - PKTPULL(osh, pkt, firstread); - PKTALIGN(osh, pkt, rdlen, DHD_SDALIGN); - - /* Read the remaining frame data */ - sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - ((uint8 *)PKTDATA(osh, pkt)), rdlen, pkt, NULL, NULL); - bus->f2rxdata++; - ASSERT(sdret != BCME_PENDING); - - if (sdret < 0) { - DHD_ERROR(("%s: read %d %s bytes failed: %d\n", __FUNCTION__, rdlen, - ((chan == SDPCM_EVENT_CHANNEL) ? "event" : - ((chan == SDPCM_DATA_CHANNEL) ? "data" : "test")), sdret)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(bus->dhd->osh, pkt, FALSE); - dhd_os_sdunlock_rxq(bus->dhd); - bus->dhd->rx_errors++; - dhdsdio_rxfail(bus, TRUE, RETRYCHAN(chan)); - continue; - } - - /* Copy the already-read portion */ - PKTPUSH(osh, pkt, firstread); - bcopy(bus->rxhdr, PKTDATA(osh, pkt), firstread); - -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) { - prhex("Rx Data", PKTDATA(osh, pkt), len); - } -#endif - -deliver: - /* Save superframe descriptor and allocate packet frame */ - if (chan == SDPCM_GLOM_CHANNEL) { - if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) { - DHD_GLOM(("%s: got glom descriptor, %d bytes:\n", - __FUNCTION__, len)); -#ifdef DHD_DEBUG - if (DHD_GLOM_ON()) { - prhex("Glom Data", PKTDATA(osh, pkt), len); - } -#endif - PKTSETLEN(osh, pkt, len); - ASSERT(doff == SDPCM_HDRLEN); - PKTPULL(osh, pkt, SDPCM_HDRLEN); - bus->glomd = pkt; - } else { - DHD_ERROR(("%s: glom superframe w/o descriptor!\n", __FUNCTION__)); - dhdsdio_rxfail(bus, FALSE, FALSE); - } - continue; - } - - /* Fill in packet len and prio, deliver upward */ - PKTSETLEN(osh, pkt, len); - PKTPULL(osh, pkt, doff); - -#ifdef SDTEST - /* Test channel packets are processed separately */ - if (chan == SDPCM_TEST_CHANNEL) { - dhdsdio_testrcv(bus, pkt, seq); - continue; - } -#endif /* SDTEST */ - - if (PKTLEN(osh, pkt) == 0) { - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(bus->dhd->osh, pkt, FALSE); - dhd_os_sdunlock_rxq(bus->dhd); - continue; - } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pkt) != 0) { - DHD_ERROR(("%s: rx protocol error\n", __FUNCTION__)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(bus->dhd->osh, pkt, FALSE); - dhd_os_sdunlock_rxq(bus->dhd); - bus->dhd->rx_errors++; - continue; - } - - - /* Unlock during rx call */ - dhd_os_sdunlock(bus->dhd); - dhd_rx_frame(bus->dhd, ifidx, pkt, 1, chan); - dhd_os_sdlock(bus->dhd); - } - rxcount = maxframes - rxleft; -#ifdef DHD_DEBUG - /* Message if we hit the limit */ - if (!rxleft && !sdtest) - DHD_DATA(("%s: hit rx limit of %d frames\n", __FUNCTION__, maxframes)); - else -#endif /* DHD_DEBUG */ - DHD_DATA(("%s: processed %d frames\n", __FUNCTION__, rxcount)); - /* Back off rxseq if awaiting rtx, update rx_seq */ - if (bus->rxskip) - rxseq--; - bus->rx_seq = rxseq; - - return rxcount; -} - -static uint32 -dhdsdio_hostmail(dhd_bus_t *bus) -{ - sdpcmd_regs_t *regs = bus->regs; - uint32 intstatus = 0; - uint32 hmb_data; - uint8 fcbits; - uint retries = 0; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* Read mailbox data and ack that we did so */ - R_SDREG(hmb_data, ®s->tohostmailboxdata, retries); - if (retries <= retry_limit) - W_SDREG(SMB_INT_ACK, ®s->tosbmailbox, retries); - bus->f1regdata += 2; - - /* Dongle recomposed rx frames, accept them again */ - if (hmb_data & HMB_DATA_NAKHANDLED) { - DHD_INFO(("Dongle reports NAK handled, expect rtx of %d\n", bus->rx_seq)); - if (!bus->rxskip) { - DHD_ERROR(("%s: unexpected NAKHANDLED!\n", __FUNCTION__)); - } - bus->rxskip = FALSE; - intstatus |= FRAME_AVAIL_MASK(bus); - } - - /* - * DEVREADY does not occur with gSPI. - */ - if (hmb_data & (HMB_DATA_DEVREADY | HMB_DATA_FWREADY)) { - bus->sdpcm_ver = (hmb_data & HMB_DATA_VERSION_MASK) >> HMB_DATA_VERSION_SHIFT; - if (bus->sdpcm_ver != SDPCM_PROT_VERSION) - DHD_ERROR(("Version mismatch, dongle reports %d, expecting %d\n", - bus->sdpcm_ver, SDPCM_PROT_VERSION)); - else - DHD_INFO(("Dongle ready, protocol version %d\n", bus->sdpcm_ver)); - /* make sure for the SDIO_DEVICE_RXDATAINT_MODE_1 corecontrol is proper */ - if ((bus->sih->buscoretype == SDIOD_CORE_ID) && (bus->sdpcmrev >= 4) && - (bus->rxint_mode == SDIO_DEVICE_RXDATAINT_MODE_1)) { - uint32 val; - - val = R_REG(bus->dhd->osh, &bus->regs->corecontrol); - val &= ~CC_XMTDATAAVAIL_MODE; - val |= CC_XMTDATAAVAIL_CTRL; - W_REG(bus->dhd->osh, &bus->regs->corecontrol, val); - - val = R_REG(bus->dhd->osh, &bus->regs->corecontrol); - } - -#ifdef DHD_DEBUG - /* Retrieve console state address now that firmware should have updated it */ - { - sdpcm_shared_t shared; - if (dhdsdio_readshared(bus, &shared) == 0) - bus->console_addr = shared.console_addr; - } -#endif /* DHD_DEBUG */ - } - - /* - * Flow Control has been moved into the RX headers and this out of band - * method isn't used any more. Leave this here for possibly remaining backward - * compatible with older dongles - */ - if (hmb_data & HMB_DATA_FC) { - fcbits = (hmb_data & HMB_DATA_FCDATA_MASK) >> HMB_DATA_FCDATA_SHIFT; - - if (fcbits & ~bus->flowcontrol) - bus->fc_xoff++; - if (bus->flowcontrol & ~fcbits) - bus->fc_xon++; - - bus->fc_rcvd++; - bus->flowcontrol = fcbits; - } - -#ifdef DHD_DEBUG - /* At least print a message if FW halted */ - if (hmb_data & HMB_DATA_FWHALT) { - DHD_ERROR(("INTERNAL ERROR: FIRMWARE HALTED\n")); - dhdsdio_checkdied(bus, NULL, 0); - } -#endif /* DHD_DEBUG */ - - /* Shouldn't be any others */ - if (hmb_data & ~(HMB_DATA_DEVREADY | - HMB_DATA_FWHALT | - HMB_DATA_NAKHANDLED | - HMB_DATA_FC | - HMB_DATA_FWREADY | - HMB_DATA_FCDATA_MASK | - HMB_DATA_VERSION_MASK)) { - DHD_ERROR(("Unknown mailbox data content: 0x%02x\n", hmb_data)); - } - - return intstatus; -} - -static bool -dhdsdio_dpc(dhd_bus_t *bus) -{ - bcmsdh_info_t *sdh = bus->sdh; - sdpcmd_regs_t *regs = bus->regs; - uint32 intstatus, newstatus = 0; - uint retries = 0; - uint rxlimit = dhd_rxbound; /* Rx frames to read before resched */ - uint txlimit = dhd_txbound; /* Tx frames to send before resched */ - uint framecnt = 0; /* Temporary counter of tx/rx frames */ - bool rxdone = TRUE; /* Flag for no more read data */ - bool resched = FALSE; /* Flag indicating resched wanted */ - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (bus->dhd->busstate == DHD_BUS_DOWN) { - DHD_ERROR(("%s: Bus down, ret\n", __FUNCTION__)); - bus->intstatus = 0; - return 0; - } - - /* Start with leftover status bits */ - intstatus = bus->intstatus; - - dhd_os_sdlock(bus->dhd); - - /* If waiting for HTAVAIL, check status */ - if (bus->clkstate == CLK_PENDING) { - int err; - uint8 clkctl, devctl = 0; - -#ifdef DHD_DEBUG - /* Check for inconsistent device control */ - devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); - if (err) { - DHD_ERROR(("%s: error reading DEVCTL: %d\n", __FUNCTION__, err)); - bus->dhd->busstate = DHD_BUS_DOWN; - } else { - ASSERT(devctl & SBSDIO_DEVCTL_CA_INT_ONLY); - } -#endif /* DHD_DEBUG */ - - /* Read CSR, if clock on switch to AVAIL, else ignore */ - clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); - if (err) { - DHD_ERROR(("%s: error reading CSR: %d\n", __FUNCTION__, err)); - bus->dhd->busstate = DHD_BUS_DOWN; - } - - DHD_INFO(("DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", devctl, clkctl)); - - if (SBSDIO_HTAV(clkctl)) { - devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); - if (err) { - DHD_ERROR(("%s: error reading DEVCTL: %d\n", - __FUNCTION__, err)); - bus->dhd->busstate = DHD_BUS_DOWN; - } - devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); - if (err) { - DHD_ERROR(("%s: error writing DEVCTL: %d\n", - __FUNCTION__, err)); - bus->dhd->busstate = DHD_BUS_DOWN; - } - bus->clkstate = CLK_AVAIL; - } else { - goto clkwait; - } - } - - BUS_WAKE(bus); - - /* Make sure backplane clock is on */ - dhdsdio_clkctl(bus, CLK_AVAIL, TRUE); - if (bus->clkstate != CLK_AVAIL) - goto clkwait; - - /* Pending interrupt indicates new device status */ - if (bus->ipend) { - bus->ipend = FALSE; - R_SDREG(newstatus, ®s->intstatus, retries); - bus->f1regdata++; - if (bcmsdh_regfail(bus->sdh)) - newstatus = 0; - newstatus &= bus->hostintmask; - bus->fcstate = !!(newstatus & I_HMB_FC_STATE); - if (newstatus) { - bus->f1regdata++; - if ((bus->rxint_mode == SDIO_DEVICE_RXDATAINT_MODE_0) && - (newstatus == I_XMTDATA_AVAIL)) { - } - else - W_SDREG(newstatus, ®s->intstatus, retries); - } - } - - /* Merge new bits with previous */ - intstatus |= newstatus; - bus->intstatus = 0; - - /* Handle flow-control change: read new state in case our ack - * crossed another change interrupt. If change still set, assume - * FC ON for safety, let next loop through do the debounce. - */ - if (intstatus & I_HMB_FC_CHANGE) { - intstatus &= ~I_HMB_FC_CHANGE; - W_SDREG(I_HMB_FC_CHANGE, ®s->intstatus, retries); - R_SDREG(newstatus, ®s->intstatus, retries); - bus->f1regdata += 2; - bus->fcstate = !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)); - intstatus |= (newstatus & bus->hostintmask); - } - - /* Just being here means nothing more to do for chipactive */ - if (intstatus & I_CHIPACTIVE) { - /* ASSERT(bus->clkstate == CLK_AVAIL); */ - intstatus &= ~I_CHIPACTIVE; - } - - /* Handle host mailbox indication */ - if (intstatus & I_HMB_HOST_INT) { - intstatus &= ~I_HMB_HOST_INT; - intstatus |= dhdsdio_hostmail(bus); - } - - /* Generally don't ask for these, can get CRC errors... */ - if (intstatus & I_WR_OOSYNC) { - DHD_ERROR(("Dongle reports WR_OOSYNC\n")); - intstatus &= ~I_WR_OOSYNC; - } - - if (intstatus & I_RD_OOSYNC) { - DHD_ERROR(("Dongle reports RD_OOSYNC\n")); - intstatus &= ~I_RD_OOSYNC; - } - - if (intstatus & I_SBINT) { - DHD_ERROR(("Dongle reports SBINT\n")); - intstatus &= ~I_SBINT; - } - - /* Would be active due to wake-wlan in gSPI */ - if (intstatus & I_CHIPACTIVE) { - DHD_INFO(("Dongle reports CHIPACTIVE\n")); - intstatus &= ~I_CHIPACTIVE; - } - - /* Ignore frame indications if rxskip is set */ - if (bus->rxskip) { - intstatus &= ~FRAME_AVAIL_MASK(bus); - } - - /* On frame indication, read available frames */ - if (PKT_AVAILABLE(bus, intstatus)) { - framecnt = dhdsdio_readframes(bus, rxlimit, &rxdone); - if (rxdone || bus->rxskip) - intstatus &= ~FRAME_AVAIL_MASK(bus); - rxlimit -= MIN(framecnt, rxlimit); - } - - /* Keep still-pending events for next scheduling */ - bus->intstatus = intstatus; - -clkwait: - /* Re-enable interrupts to detect new device events (mailbox, rx frame) - * or clock availability. (Allows tx loop to check ipend if desired.) - * (Unless register access seems hosed, as we may not be able to ACK...) - */ - if (bus->intr && bus->intdis && !bcmsdh_regfail(sdh)) { - DHD_INTR(("%s: enable SDIO interrupts, rxdone %d framecnt %d\n", - __FUNCTION__, rxdone, framecnt)); - bus->intdis = FALSE; -#if defined(OOB_INTR_ONLY) - bcmsdh_oob_intr_set(1); -#endif /* (OOB_INTR_ONLY) */ - bcmsdh_intr_enable(sdh); - } - -#if defined(OOB_INTR_ONLY) && !defined(HW_OOB) - /* In case of SW-OOB(using edge trigger), - * Check interrupt status in the dongle again after enable irq on the host. - * and rechedule dpc if interrupt is pended in the dongle. - * There is a chance to miss OOB interrupt while irq is disabled on the host. - * No need to do this with HW-OOB(level trigger) - */ - R_SDREG(newstatus, ®s->intstatus, retries); - if (bcmsdh_regfail(bus->sdh)) - newstatus = 0; - if (newstatus & bus->hostintmask) { - bus->ipend = TRUE; - resched = TRUE; - } -#endif /* defined(OOB_INTR_ONLY) && !defined(HW_OOB) */ - - if (TXCTLOK(bus) && bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL)) { - int ret, i; - uint8* frame_seq = bus->ctrl_frame_buf + SDPCM_FRAMETAG_LEN; - - if (*frame_seq != bus->tx_seq) { - DHD_INFO(("%s IOCTL frame seq lag detected!" - " frm_seq:%d != bus->tx_seq:%d, corrected\n", - __FUNCTION__, *frame_seq, bus->tx_seq)); - *frame_seq = bus->tx_seq; - } - - ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - (uint8 *)bus->ctrl_frame_buf, (uint32)bus->ctrl_frame_len, - NULL, NULL, NULL); - ASSERT(ret != BCME_PENDING); - - if (ret < 0) { - /* On failure, abort the command and terminate the frame */ - DHD_INFO(("%s: sdio error %d, abort command and terminate frame.\n", - __FUNCTION__, ret)); - bus->tx_sderrs++; - - bcmsdh_abort(sdh, SDIO_FUNC_2); - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, - SFC_WF_TERM, NULL); - bus->f1regdata++; - - for (i = 0; i < 3; i++) { - uint8 hi, lo; - hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCLO, NULL); - bus->f1regdata += 2; - if ((hi == 0) && (lo == 0)) - break; - } - } - if (ret == 0) { - bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; - } - - bus->ctrl_frame_stat = FALSE; - dhd_wait_event_wakeup(bus->dhd); - } - /* Send queued frames (limit 1 if rx may still be pending) */ - else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate && - pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit && DATAOK(bus)) { - framecnt = rxdone ? txlimit : MIN(txlimit, dhd_txminmax); - framecnt = dhdsdio_sendfromq(bus, framecnt); - txlimit -= framecnt; - } - /* Resched the DPC if ctrl cmd is pending on bus credit */ - if (bus->ctrl_frame_stat) - resched = TRUE; - - /* Resched if events or tx frames are pending, else await next interrupt */ - /* On failed register access, all bets are off: no resched or interrupts */ - if ((bus->dhd->busstate == DHD_BUS_DOWN) || bcmsdh_regfail(sdh)) { - DHD_ERROR(("%s: failed backplane access over SDIO, halting operation %d \n", - __FUNCTION__, bcmsdh_regfail(sdh))); - bus->dhd->busstate = DHD_BUS_DOWN; - bus->intstatus = 0; - } else if (bus->clkstate == CLK_PENDING) { - /* Awaiting I_CHIPACTIVE; don't resched */ - } else if (bus->intstatus || bus->ipend || - (!bus->fcstate && pktq_mlen(&bus->txq, ~bus->flowcontrol) && DATAOK(bus)) || - PKT_AVAILABLE(bus, bus->intstatus)) { /* Read multiple frames */ - resched = TRUE; - } - - bus->dpc_sched = resched; - - /* If we're done for now, turn off clock request. */ - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && (bus->clkstate != CLK_PENDING)) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, FALSE); - } - - dhd_os_sdunlock(bus->dhd); - return resched; -} - -bool -dhd_bus_dpc(struct dhd_bus *bus) -{ - bool resched; - - /* Call the DPC directly. */ - DHD_TRACE(("Calling dhdsdio_dpc() from %s\n", __FUNCTION__)); - resched = dhdsdio_dpc(bus); - - return resched; -} - -void -dhdsdio_isr(void *arg) -{ - dhd_bus_t *bus = (dhd_bus_t*)arg; - bcmsdh_info_t *sdh; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (!bus) { - DHD_ERROR(("%s : bus is null pointer , exit \n", __FUNCTION__)); - return; - } - sdh = bus->sdh; - - if (bus->dhd->busstate == DHD_BUS_DOWN) { - DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__)); - return; - } - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* Count the interrupt call */ - bus->intrcount++; - bus->ipend = TRUE; - - /* Shouldn't get this interrupt if we're sleeping? */ - if (bus->sleeping) { - DHD_ERROR(("INTERRUPT WHILE SLEEPING??\n")); - return; - } - - /* Disable additional interrupts (is this needed now)? */ - if (bus->intr) { - DHD_INTR(("%s: disable SDIO interrupts\n", __FUNCTION__)); - } else { - DHD_ERROR(("dhdsdio_isr() w/o interrupt configured!\n")); - } - - bcmsdh_intr_disable(sdh); - bus->intdis = TRUE; - -#if defined(SDIO_ISR_THREAD) - DHD_TRACE(("Calling dhdsdio_dpc() from %s\n", __FUNCTION__)); - DHD_OS_WAKE_LOCK(bus->dhd); - while (dhdsdio_dpc(bus)); - DHD_OS_WAKE_UNLOCK(bus->dhd); -#else - bus->dpc_sched = TRUE; - dhd_sched_dpc(bus->dhd); -#endif - -} - -#ifdef SDTEST -static void -dhdsdio_pktgen_init(dhd_bus_t *bus) -{ - /* Default to specified length, or full range */ - if (dhd_pktgen_len) { - bus->pktgen_maxlen = MIN(dhd_pktgen_len, MAX_PKTGEN_LEN); - bus->pktgen_minlen = bus->pktgen_maxlen; - } else { - bus->pktgen_maxlen = MAX_PKTGEN_LEN; - bus->pktgen_minlen = 0; - } - bus->pktgen_len = (uint16)bus->pktgen_minlen; - - /* Default to per-watchdog burst with 10s print time */ - bus->pktgen_freq = 1; - bus->pktgen_print = 10000 / dhd_watchdog_ms; - bus->pktgen_count = (dhd_pktgen * dhd_watchdog_ms + 999) / 1000; - - /* Default to echo mode */ - bus->pktgen_mode = DHD_PKTGEN_ECHO; - bus->pktgen_stop = 1; -} - -static void -dhdsdio_pktgen(dhd_bus_t *bus) -{ - void *pkt; - uint8 *data; - uint pktcount; - uint fillbyte; - osl_t *osh = bus->dhd->osh; - uint16 len; - - /* Display current count if appropriate */ - if (bus->pktgen_print && (++bus->pktgen_ptick >= bus->pktgen_print)) { - bus->pktgen_ptick = 0; - printf("%s: send attempts %d rcvd %d\n", - __FUNCTION__, bus->pktgen_sent, bus->pktgen_rcvd); - } - - /* For recv mode, just make sure dongle has started sending */ - if (bus->pktgen_mode == DHD_PKTGEN_RECV) { - if (bus->pktgen_rcv_state == PKTGEN_RCV_IDLE) { - bus->pktgen_rcv_state = PKTGEN_RCV_ONGOING; - dhdsdio_sdtest_set(bus, (uint8)bus->pktgen_total); - } - return; - } - - /* Otherwise, generate or request the specified number of packets */ - for (pktcount = 0; pktcount < bus->pktgen_count; pktcount++) { - /* Stop if total has been reached */ - if (bus->pktgen_total && (bus->pktgen_sent >= bus->pktgen_total)) { - bus->pktgen_count = 0; - break; - } - - /* Allocate an appropriate-sized packet */ - len = bus->pktgen_len; - if (!(pkt = PKTGET(osh, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN), - TRUE))) {; - DHD_ERROR(("%s: PKTGET failed!\n", __FUNCTION__)); - break; - } - PKTALIGN(osh, pkt, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN); - data = (uint8*)PKTDATA(osh, pkt) + SDPCM_HDRLEN; - - /* Write test header cmd and extra based on mode */ - switch (bus->pktgen_mode) { - case DHD_PKTGEN_ECHO: - *data++ = SDPCM_TEST_ECHOREQ; - *data++ = (uint8)bus->pktgen_sent; - break; - - case DHD_PKTGEN_SEND: - *data++ = SDPCM_TEST_DISCARD; - *data++ = (uint8)bus->pktgen_sent; - break; - - case DHD_PKTGEN_RXBURST: - *data++ = SDPCM_TEST_BURST; - *data++ = (uint8)bus->pktgen_count; - break; - - default: - DHD_ERROR(("Unrecognized pktgen mode %d\n", bus->pktgen_mode)); - PKTFREE(osh, pkt, TRUE); - bus->pktgen_count = 0; - return; - } - - /* Write test header length field */ - *data++ = (len >> 0); - *data++ = (len >> 8); - - /* Then fill in the remainder -- N/A for burst, but who cares... */ - for (fillbyte = 0; fillbyte < len; fillbyte++) - *data++ = SDPCM_TEST_FILL(fillbyte, (uint8)bus->pktgen_sent); - -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) { - data = (uint8*)PKTDATA(osh, pkt) + SDPCM_HDRLEN; - prhex("dhdsdio_pktgen: Tx Data", data, PKTLEN(osh, pkt) - SDPCM_HDRLEN); - } -#endif - - /* Send it */ - if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, TRUE)) { - bus->pktgen_fail++; - if (bus->pktgen_stop && bus->pktgen_stop == bus->pktgen_fail) - bus->pktgen_count = 0; - } - bus->pktgen_sent++; - - /* Bump length if not fixed, wrap at max */ - if (++bus->pktgen_len > bus->pktgen_maxlen) - bus->pktgen_len = (uint16)bus->pktgen_minlen; - - /* Special case for burst mode: just send one request! */ - if (bus->pktgen_mode == DHD_PKTGEN_RXBURST) - break; - } -} - -static void -dhdsdio_sdtest_set(dhd_bus_t *bus, uint8 count) -{ - void *pkt; - uint8 *data; - osl_t *osh = bus->dhd->osh; - - /* Allocate the packet */ - if (!(pkt = PKTGET(osh, SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN, TRUE))) { - DHD_ERROR(("%s: PKTGET failed!\n", __FUNCTION__)); - return; - } - PKTALIGN(osh, pkt, (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN); - data = (uint8*)PKTDATA(osh, pkt) + SDPCM_HDRLEN; - - /* Fill in the test header */ - *data++ = SDPCM_TEST_SEND; - *data++ = count; - *data++ = (bus->pktgen_maxlen >> 0); - *data++ = (bus->pktgen_maxlen >> 8); - - /* Send it */ - if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, TRUE)) - bus->pktgen_fail++; -} - - -static void -dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq) -{ - osl_t *osh = bus->dhd->osh; - uint8 *data; - uint pktlen; - - uint8 cmd; - uint8 extra; - uint16 len; - uint16 offset; - - /* Check for min length */ - if ((pktlen = PKTLEN(osh, pkt)) < SDPCM_TEST_HDRLEN) { - DHD_ERROR(("dhdsdio_restrcv: toss runt frame, pktlen %d\n", pktlen)); - PKTFREE(osh, pkt, FALSE); - return; - } - - /* Extract header fields */ - data = PKTDATA(osh, pkt); - cmd = *data++; - extra = *data++; - len = *data++; len += *data++ << 8; - DHD_TRACE(("%s:cmd:%d, xtra:%d,len:%d\n", __FUNCTION__, cmd, extra, len)); - /* Check length for relevant commands */ - if (cmd == SDPCM_TEST_DISCARD || cmd == SDPCM_TEST_ECHOREQ || cmd == SDPCM_TEST_ECHORSP) { - if (pktlen != len + SDPCM_TEST_HDRLEN) { - DHD_ERROR(("dhdsdio_testrcv: frame length mismatch, pktlen %d seq %d" - " cmd %d extra %d len %d\n", pktlen, seq, cmd, extra, len)); - PKTFREE(osh, pkt, FALSE); - return; - } - } - - /* Process as per command */ - switch (cmd) { - case SDPCM_TEST_ECHOREQ: - /* Rx->Tx turnaround ok (even on NDIS w/current implementation) */ - *(uint8 *)(PKTDATA(osh, pkt)) = SDPCM_TEST_ECHORSP; - if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, TRUE) == 0) { - bus->pktgen_sent++; - } else { - bus->pktgen_fail++; - PKTFREE(osh, pkt, FALSE); - } - bus->pktgen_rcvd++; - break; - - case SDPCM_TEST_ECHORSP: - if (bus->ext_loop) { - PKTFREE(osh, pkt, FALSE); - bus->pktgen_rcvd++; - break; - } - - for (offset = 0; offset < len; offset++, data++) { - if (*data != SDPCM_TEST_FILL(offset, extra)) { - DHD_ERROR(("dhdsdio_testrcv: echo data mismatch: " - "offset %d (len %d) expect 0x%02x rcvd 0x%02x\n", - offset, len, SDPCM_TEST_FILL(offset, extra), *data)); - break; - } - } - PKTFREE(osh, pkt, FALSE); - bus->pktgen_rcvd++; - break; - - case SDPCM_TEST_DISCARD: - { - int i = 0; - uint8 *prn = data; - uint8 testval = extra; - for (i = 0; i < len; i++) { - if (*prn != testval) { - DHD_ERROR(("DIErr@Pkt#:%d,Ix:%d, expected:0x%x, got:0x%x\n", - i, bus->pktgen_rcvd_rcvsession, testval, *prn)); - prn++; testval++; - } - } - } - PKTFREE(osh, pkt, FALSE); - bus->pktgen_rcvd++; - break; - - case SDPCM_TEST_BURST: - case SDPCM_TEST_SEND: - default: - DHD_INFO(("dhdsdio_testrcv: unsupported or unknown command, pktlen %d seq %d" - " cmd %d extra %d len %d\n", pktlen, seq, cmd, extra, len)); - PKTFREE(osh, pkt, FALSE); - break; - } - - /* For recv mode, stop at limit (and tell dongle to stop sending) */ - if (bus->pktgen_mode == DHD_PKTGEN_RECV) { - if (bus->pktgen_rcv_state != PKTGEN_RCV_IDLE) { - bus->pktgen_rcvd_rcvsession++; - - if (bus->pktgen_total && - (bus->pktgen_rcvd_rcvsession >= bus->pktgen_total)) { - bus->pktgen_count = 0; - DHD_ERROR(("Pktgen:rcv test complete!\n")); - bus->pktgen_rcv_state = PKTGEN_RCV_IDLE; - dhdsdio_sdtest_set(bus, FALSE); - bus->pktgen_rcvd_rcvsession = 0; - } - } - } -} -#endif /* SDTEST */ - -extern void -dhd_disable_intr(dhd_pub_t *dhdp) -{ - dhd_bus_t *bus; - bus = dhdp->bus; - bcmsdh_intr_disable(bus->sdh); -} - -extern bool -dhd_bus_watchdog(dhd_pub_t *dhdp) -{ - dhd_bus_t *bus; - - DHD_TIMER(("%s: Enter\n", __FUNCTION__)); - - bus = dhdp->bus; - - if (bus->dhd->dongle_reset) - return FALSE; - - /* Ignore the timer if simulating bus down */ - if (bus->sleeping) - return FALSE; - - if (dhdp->busstate == DHD_BUS_DOWN) - return FALSE; - - /* Poll period: check device if appropriate. */ - if (bus->poll && (++bus->polltick >= bus->pollrate)) { - uint32 intstatus = 0; - - /* Reset poll tick */ - bus->polltick = 0; - - /* Check device if no interrupts */ - if (!bus->intr || (bus->intrcount == bus->lastintrs)) { - - if (!bus->dpc_sched) { - uint8 devpend; - devpend = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, - SDIOD_CCCR_INTPEND, NULL); - intstatus = devpend & (INTR_STATUS_FUNC1 | INTR_STATUS_FUNC2); - } - - /* If there is something, make like the ISR and schedule the DPC */ - if (intstatus) { - bus->pollcnt++; - bus->ipend = TRUE; - if (bus->intr) { - bcmsdh_intr_disable(bus->sdh); - } - bus->dpc_sched = TRUE; - dhd_sched_dpc(bus->dhd); - - } - } - - /* Update interrupt tracking */ - bus->lastintrs = bus->intrcount; - } - -#ifdef DHD_DEBUG - /* Poll for console output periodically */ - if (dhdp->busstate == DHD_BUS_DATA && dhd_console_ms != 0) { - bus->console.count += dhd_watchdog_ms; - if (bus->console.count >= dhd_console_ms) { - bus->console.count -= dhd_console_ms; - /* Make sure backplane clock is on */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - if (dhdsdio_readconsole(bus) < 0) - dhd_console_ms = 0; /* On error, stop trying */ - } - } -#endif /* DHD_DEBUG */ - -#ifdef SDTEST - /* Generate packets if configured */ - if (bus->pktgen_count && (++bus->pktgen_tick >= bus->pktgen_freq)) { - /* Make sure backplane clock is on */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - bus->pktgen_tick = 0; - dhdsdio_pktgen(bus); - } -#endif - - /* On idle timeout clear activity flag and/or turn off clock */ - if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) { - if (++bus->idlecount >= bus->idletime) { - bus->idlecount = 0; - if (bus->activity) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, FALSE); - } - } - } - - return bus->ipend; -} - -#ifdef DHD_DEBUG -extern int -dhd_bus_console_in(dhd_pub_t *dhdp, uchar *msg, uint msglen) -{ - dhd_bus_t *bus = dhdp->bus; - uint32 addr, val; - int rv; - void *pkt; - - /* Address could be zero if CONSOLE := 0 in dongle Makefile */ - if (bus->console_addr == 0) - return BCME_UNSUPPORTED; - - /* Exclusive bus access */ - dhd_os_sdlock(bus->dhd); - - /* Don't allow input if dongle is in reset */ - if (bus->dhd->dongle_reset) { - dhd_os_sdunlock(bus->dhd); - return BCME_NOTREADY; - } - - /* Request clock to allow SDIO accesses */ - BUS_WAKE(bus); - /* No pend allowed since txpkt is called later, ht clk has to be on */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - /* Zero cbuf_index */ - addr = bus->console_addr + OFFSETOF(hndrte_cons_t, cbuf_idx); - val = htol32(0); - if ((rv = dhdsdio_membytes(bus, TRUE, addr, (uint8 *)&val, sizeof(val))) < 0) - goto done; - - /* Write message into cbuf */ - addr = bus->console_addr + OFFSETOF(hndrte_cons_t, cbuf); - if ((rv = dhdsdio_membytes(bus, TRUE, addr, (uint8 *)msg, msglen)) < 0) - goto done; - - /* Write length into vcons_in */ - addr = bus->console_addr + OFFSETOF(hndrte_cons_t, vcons_in); - val = htol32(msglen); - if ((rv = dhdsdio_membytes(bus, TRUE, addr, (uint8 *)&val, sizeof(val))) < 0) - goto done; - - /* Bump dongle by sending an empty packet on the event channel. - * sdpcm_sendup (RX) checks for virtual console input. - */ - if ((pkt = PKTGET(bus->dhd->osh, 4 + SDPCM_RESERVE, TRUE)) != NULL) - dhdsdio_txpkt(bus, pkt, SDPCM_EVENT_CHANNEL, TRUE); - -done: - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, TRUE); - } - - dhd_os_sdunlock(bus->dhd); - - return rv; -} -#endif /* DHD_DEBUG */ - -#if (defined DHD_DEBUG) -static void -dhd_dump_cis(uint fn, uint8 *cis) -{ - uint byte, tag, tdata; - DHD_INFO(("Function %d CIS:\n", fn)); - - for (tdata = byte = 0; byte < SBSDIO_CIS_SIZE_LIMIT; byte++) { - if ((byte % 16) == 0) - DHD_INFO((" ")); - DHD_INFO(("%02x ", cis[byte])); - if ((byte % 16) == 15) - DHD_INFO(("\n")); - if (!tdata--) { - tag = cis[byte]; - if (tag == 0xff) - break; - else if (!tag) - tdata = 0; - else if ((byte + 1) < SBSDIO_CIS_SIZE_LIMIT) - tdata = cis[byte + 1] + 1; - else - DHD_INFO(("]")); - } - } - if ((byte % 16) != 15) - DHD_INFO(("\n")); -} -#endif /* DHD_DEBUG */ - -static bool -dhdsdio_chipmatch(uint16 chipid) -{ - if (chipid == BCM4325_CHIP_ID) - return TRUE; - if (chipid == BCM4329_CHIP_ID) - return TRUE; - if (chipid == BCM4315_CHIP_ID) - return TRUE; - if (chipid == BCM4319_CHIP_ID) - return TRUE; - if (chipid == BCM4330_CHIP_ID) - return TRUE; - if (chipid == BCM43239_CHIP_ID) - return TRUE; - if (chipid == BCM4336_CHIP_ID) - return TRUE; - if (chipid == BCM43237_CHIP_ID) - return TRUE; - if (chipid == BCM43362_CHIP_ID) - return TRUE; - - return FALSE; -} - -static void * -dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot, - uint16 func, uint bustype, void *regsva, osl_t * osh, void *sdh) -{ - int ret; - dhd_bus_t *bus; - dhd_cmn_t *cmn; -#ifdef GET_CUSTOM_MAC_ENABLE - struct ether_addr ea_addr; -#endif /* GET_CUSTOM_MAC_ENABLE */ -#ifdef PROP_TXSTATUS - uint up = 0; -#endif - - /* Init global variables at run-time, not as part of the declaration. - * This is required to support init/de-init of the driver. Initialization - * of globals as part of the declaration results in non-deterministic - * behavior since the value of the globals may be different on the - * first time that the driver is initialized vs subsequent initializations. - */ - dhd_txbound = DHD_TXBOUND; - dhd_rxbound = DHD_RXBOUND; - dhd_alignctl = TRUE; - sd1idle = TRUE; - dhd_readahead = TRUE; - retrydata = FALSE; - dhd_doflow = FALSE; - dhd_dongle_memsize = 0; - dhd_txminmax = DHD_TXMINMAX; - - forcealign = TRUE; - - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - DHD_INFO(("%s: venid 0x%04x devid 0x%04x\n", __FUNCTION__, venid, devid)); - - /* We make assumptions about address window mappings */ - ASSERT((uintptr)regsva == SI_ENUM_BASE); - - /* BCMSDH passes venid and devid based on CIS parsing -- but low-power start - * means early parse could fail, so here we should get either an ID - * we recognize OR (-1) indicating we must request power first. - */ - /* Check the Vendor ID */ - switch (venid) { - case 0x0000: - case VENDOR_BROADCOM: - break; - default: - DHD_ERROR(("%s: unknown vendor: 0x%04x\n", - __FUNCTION__, venid)); - return NULL; - } - - /* Check the Device ID and make sure it's one that we support */ - switch (devid) { - case BCM4325_D11DUAL_ID: /* 4325 802.11a/g id */ - case BCM4325_D11G_ID: /* 4325 802.11g 2.4Ghz band id */ - case BCM4325_D11A_ID: /* 4325 802.11a 5Ghz band id */ - DHD_INFO(("%s: found 4325 Dongle\n", __FUNCTION__)); - break; - case BCM4329_D11N_ID: /* 4329 802.11n dualband device */ - case BCM4329_D11N2G_ID: /* 4329 802.11n 2.4G device */ - case BCM4329_D11N5G_ID: /* 4329 802.11n 5G device */ - case 0x4329: - DHD_INFO(("%s: found 4329 Dongle\n", __FUNCTION__)); - break; - case BCM4315_D11DUAL_ID: /* 4315 802.11a/g id */ - case BCM4315_D11G_ID: /* 4315 802.11g id */ - case BCM4315_D11A_ID: /* 4315 802.11a id */ - DHD_INFO(("%s: found 4315 Dongle\n", __FUNCTION__)); - break; - case BCM4319_D11N_ID: /* 4319 802.11n id */ - case BCM4319_D11N2G_ID: /* 4319 802.11n2g id */ - case BCM4319_D11N5G_ID: /* 4319 802.11n5g id */ - DHD_INFO(("%s: found 4319 Dongle\n", __FUNCTION__)); - break; - case 0: - DHD_INFO(("%s: allow device id 0, will check chip internals\n", - __FUNCTION__)); - break; - - default: - DHD_ERROR(("%s: skipping 0x%04x/0x%04x, not a dongle\n", - __FUNCTION__, venid, devid)); - return NULL; - } - - if (osh == NULL) { - /* Ask the OS interface part for an OSL handle */ - if (!(osh = dhd_osl_attach(sdh, DHD_BUS))) { - DHD_ERROR(("%s: osl_attach failed!\n", __FUNCTION__)); - return NULL; - } - } - - /* Allocate private bus interface state */ - if (!(bus = MALLOC(osh, sizeof(dhd_bus_t)))) { - DHD_ERROR(("%s: MALLOC of dhd_bus_t failed\n", __FUNCTION__)); - goto fail; - } - bzero(bus, sizeof(dhd_bus_t)); - bus->sdh = sdh; - bus->cl_devid = (uint16)devid; - bus->bus = DHD_BUS; - bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1; - bus->usebufpool = FALSE; /* Use bufpool if allocated, else use locally malloced rxbuf */ - - /* attach the common module */ - if (!(cmn = dhd_common_init(osh))) { - DHD_ERROR(("%s: dhd_common_init failed\n", __FUNCTION__)); - goto fail; - } - - /* attempt to attach to the dongle */ - if (!(dhdsdio_probe_attach(bus, osh, sdh, regsva, devid))) { - DHD_ERROR(("%s: dhdsdio_probe_attach failed\n", __FUNCTION__)); - dhd_common_deinit(NULL, cmn); - goto fail; - } - - /* Attach to the dhd/OS/network interface */ - if (!(bus->dhd = dhd_attach(osh, bus, SDPCM_RESERVE))) { - DHD_ERROR(("%s: dhd_attach failed\n", __FUNCTION__)); - goto fail; - } - - bus->dhd->cmn = cmn; - cmn->dhd = bus->dhd; - - /* Allocate buffers */ - if (!(dhdsdio_probe_malloc(bus, osh, sdh))) { - DHD_ERROR(("%s: dhdsdio_probe_malloc failed\n", __FUNCTION__)); - goto fail; - } - - if (!(dhdsdio_probe_init(bus, osh, sdh))) { - DHD_ERROR(("%s: dhdsdio_probe_init failed\n", __FUNCTION__)); - goto fail; - } - - if (bus->intr) { - /* Register interrupt callback, but mask it (not operational yet). */ - DHD_INTR(("%s: disable SDIO interrupts (not interested yet)\n", __FUNCTION__)); - bcmsdh_intr_disable(sdh); - if ((ret = bcmsdh_intr_reg(sdh, dhdsdio_isr, bus)) != 0) { - DHD_ERROR(("%s: FAILED: bcmsdh_intr_reg returned %d\n", - __FUNCTION__, ret)); - goto fail; - } - DHD_INTR(("%s: registered SDIO interrupt function ok\n", __FUNCTION__)); - } else { - DHD_INFO(("%s: SDIO interrupt function is NOT registered due to polling mode\n", - __FUNCTION__)); - } - - DHD_INFO(("%s: completed!!\n", __FUNCTION__)); - -#ifdef GET_CUSTOM_MAC_ENABLE - /* Read MAC address from external customer place */ - memset(&ea_addr, 0, sizeof(ea_addr)); - ret = dhd_custom_get_mac_address(ea_addr.octet); - if (!ret) { - memcpy(bus->dhd->mac.octet, (void *)&ea_addr, ETHER_ADDR_LEN); - } -#endif /* GET_CUSTOM_MAC_ENABLE */ - - /* if firmware path present try to download and bring up bus */ - if (dhd_download_fw_on_driverload && (ret = dhd_bus_start(bus->dhd)) != 0) { - DHD_ERROR(("%s: dhd_bus_start failed\n", __FUNCTION__)); - if (ret == BCME_NOTUP) - goto fail; - } - - /* Ok, have the per-port tell the stack we're open for business */ - if (dhd_net_attach(bus->dhd, 0) != 0) { - DHD_ERROR(("%s: Net attach failed!!\n", __FUNCTION__)); - goto fail; - } - -#ifdef PROP_TXSTATUS - if (dhd_download_fw_on_driverload) - dhd_wl_ioctl_cmd(bus->dhd, WLC_UP, (char *)&up, sizeof(up), TRUE, 0); -#endif - return bus; - -fail: - dhdsdio_release(bus, osh); - return NULL; -} - -static bool -dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva, - uint16 devid) -{ - int err = 0; - uint8 clkctl = 0; - - bus->alp_only = TRUE; - - /* Return the window to backplane enumeration space for core access */ - if (dhdsdio_set_siaddr_window(bus, SI_ENUM_BASE)) { - DHD_ERROR(("%s: FAILED to return to SI_ENUM_BASE\n", __FUNCTION__)); - } - -#ifdef DHD_DEBUG - DHD_ERROR(("F1 signature read @0x18000000=0x%4x\n", - bcmsdh_reg_read(bus->sdh, SI_ENUM_BASE, 4))); - -#endif /* DHD_DEBUG */ - - - /* Force PLL off until si_attach() programs PLL control regs */ - - - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, DHD_INIT_CLKCTL1, &err); - if (!err) - clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); - - if (err || ((clkctl & ~SBSDIO_AVBITS) != DHD_INIT_CLKCTL1)) { - DHD_ERROR(("%s: ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n", - __FUNCTION__, err, DHD_INIT_CLKCTL1, clkctl)); - goto fail; - } - -#ifdef DHD_DEBUG - if (DHD_INFO_ON()) { - uint fn, numfn; - uint8 *cis[SDIOD_MAX_IOFUNCS]; - int err = 0; - - numfn = bcmsdh_query_iofnum(sdh); - ASSERT(numfn <= SDIOD_MAX_IOFUNCS); - - /* Make sure ALP is available before trying to read CIS */ - SPINWAIT(((clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_CHIPCLKCSR, NULL)), - !SBSDIO_ALPAV(clkctl)), PMU_MAX_TRANSITION_DLY); - - /* Now request ALP be put on the bus */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - DHD_INIT_CLKCTL2, &err); - OSL_DELAY(65); - - for (fn = 0; fn <= numfn; fn++) { - if (!(cis[fn] = MALLOC(osh, SBSDIO_CIS_SIZE_LIMIT))) { - DHD_INFO(("dhdsdio_probe: fn %d cis malloc failed\n", fn)); - break; - } - bzero(cis[fn], SBSDIO_CIS_SIZE_LIMIT); - - if ((err = bcmsdh_cis_read(sdh, fn, cis[fn], SBSDIO_CIS_SIZE_LIMIT))) { - DHD_INFO(("dhdsdio_probe: fn %d cis read err %d\n", fn, err)); - MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT); - break; - } - dhd_dump_cis(fn, cis[fn]); - } - - while (fn-- > 0) { - ASSERT(cis[fn]); - MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT); - } - - if (err) { - DHD_ERROR(("dhdsdio_probe: failure reading or parsing CIS\n")); - goto fail; - } - } -#endif /* DHD_DEBUG */ - - /* si_attach() will provide an SI handle and scan the backplane */ - if (!(bus->sih = si_attach((uint)devid, osh, regsva, DHD_BUS, sdh, - &bus->vars, &bus->varsz))) { - DHD_ERROR(("%s: si_attach failed!\n", __FUNCTION__)); - goto fail; - } - - bcmsdh_chipinfo(sdh, bus->sih->chip, bus->sih->chiprev); - - if (!dhdsdio_chipmatch((uint16)bus->sih->chip)) { - DHD_ERROR(("%s: unsupported chip: 0x%04x\n", - __FUNCTION__, bus->sih->chip)); - goto fail; - } - - - si_sdiod_drive_strength_init(bus->sih, osh, dhd_sdiod_drive_strength); - - - /* Get info on the ARM and SOCRAM cores... */ - if (!DHD_NOPMU(bus)) { - if ((si_setcore(bus->sih, ARM7S_CORE_ID, 0)) || - (si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) { - bus->armrev = si_corerev(bus->sih); - } else { - DHD_ERROR(("%s: failed to find ARM core!\n", __FUNCTION__)); - goto fail; - } - if (!(bus->orig_ramsize = si_socram_size(bus->sih))) { - DHD_ERROR(("%s: failed to find SOCRAM memory!\n", __FUNCTION__)); - goto fail; - } - bus->ramsize = bus->orig_ramsize; - if (dhd_dongle_memsize) - dhd_dongle_setmemsize(bus, dhd_dongle_memsize); - - DHD_ERROR(("DHD: dongle ram size is set to %d(orig %d)\n", - bus->ramsize, bus->orig_ramsize)); - } - - /* ...but normally deal with the SDPCMDEV core */ - if (!(bus->regs = si_setcore(bus->sih, PCMCIA_CORE_ID, 0)) && - !(bus->regs = si_setcore(bus->sih, SDIOD_CORE_ID, 0))) { - DHD_ERROR(("%s: failed to find SDIODEV core!\n", __FUNCTION__)); - goto fail; - } - bus->sdpcmrev = si_corerev(bus->sih); - - /* Set core control so an SDIO reset does a backplane reset */ - OR_REG(osh, &bus->regs->corecontrol, CC_BPRESEN); - bus->rxint_mode = SDIO_DEVICE_HMB_RXINT; - - if ((bus->sih->buscoretype == SDIOD_CORE_ID) && (bus->sdpcmrev >= 4) && - (bus->rxint_mode == SDIO_DEVICE_RXDATAINT_MODE_1)) - { - uint32 val; - - val = R_REG(osh, &bus->regs->corecontrol); - val &= ~CC_XMTDATAAVAIL_MODE; - val |= CC_XMTDATAAVAIL_CTRL; - W_REG(osh, &bus->regs->corecontrol, val); - } - - - pktq_init(&bus->txq, (PRIOMASK + 1), QLEN); - - /* Locate an appropriately-aligned portion of hdrbuf */ - bus->rxhdr = (uint8 *)ROUNDUP((uintptr)&bus->hdrbuf[0], DHD_SDALIGN); - - /* Set the poll and/or interrupt flags */ - bus->intr = (bool)dhd_intr; - if ((bus->poll = (bool)dhd_poll)) - bus->pollrate = 1; - - return TRUE; - -fail: - if (bus->sih != NULL) { - si_detach(bus->sih); - bus->sih = NULL; - } - return FALSE; -} - -static bool -dhdsdio_probe_malloc(dhd_bus_t *bus, osl_t *osh, void *sdh) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (bus->dhd->maxctl) { - bus->rxblen = ROUNDUP((bus->dhd->maxctl + SDPCM_HDRLEN), ALIGNMENT) + DHD_SDALIGN; - if (!(bus->rxbuf = DHD_OS_PREALLOC(osh, DHD_PREALLOC_RXBUF, bus->rxblen))) { - DHD_ERROR(("%s: MALLOC of %d-byte rxbuf failed\n", - __FUNCTION__, bus->rxblen)); - goto fail; - } - } - /* Allocate buffer to receive glomed packet */ - if (!(bus->databuf = DHD_OS_PREALLOC(osh, DHD_PREALLOC_DATABUF, MAX_DATA_BUF))) { - DHD_ERROR(("%s: MALLOC of %d-byte databuf failed\n", - __FUNCTION__, MAX_DATA_BUF)); - /* release rxbuf which was already located as above */ - if (!bus->rxblen) - DHD_OS_PREFREE(osh, bus->rxbuf, bus->rxblen); - goto fail; - } - - /* Align the buffer */ - if ((uintptr)bus->databuf % DHD_SDALIGN) - bus->dataptr = bus->databuf + (DHD_SDALIGN - ((uintptr)bus->databuf % DHD_SDALIGN)); - else - bus->dataptr = bus->databuf; - - return TRUE; - -fail: - return FALSE; -} - -static bool -dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh) -{ - int32 fnum; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - -#ifdef SDTEST - dhdsdio_pktgen_init(bus); -#endif /* SDTEST */ - - /* Disable F2 to clear any intermediate frame state on the dongle */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, SDIO_FUNC_ENABLE_1, NULL); - - bus->dhd->busstate = DHD_BUS_DOWN; - bus->sleeping = FALSE; - bus->rxflow = FALSE; - bus->prev_rxlim_hit = 0; - - - /* Done with backplane-dependent accesses, can drop clock... */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); - - /* ...and initialize clock/power states */ - bus->clkstate = CLK_SDONLY; - bus->idletime = (int32)dhd_idletime; - bus->idleclock = DHD_IDLE_ACTIVE; - - /* Query the SD clock speed */ - if (bcmsdh_iovar_op(sdh, "sd_divisor", NULL, 0, - &bus->sd_divisor, sizeof(int32), FALSE) != BCME_OK) { - DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__, "sd_divisor")); - bus->sd_divisor = -1; - } else { - DHD_INFO(("%s: Initial value for %s is %d\n", - __FUNCTION__, "sd_divisor", bus->sd_divisor)); - } - - /* Query the SD bus mode */ - if (bcmsdh_iovar_op(sdh, "sd_mode", NULL, 0, - &bus->sd_mode, sizeof(int32), FALSE) != BCME_OK) { - DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__, "sd_mode")); - bus->sd_mode = -1; - } else { - DHD_INFO(("%s: Initial value for %s is %d\n", - __FUNCTION__, "sd_mode", bus->sd_mode)); - } - - /* Query the F2 block size, set roundup accordingly */ - fnum = 2; - if (bcmsdh_iovar_op(sdh, "sd_blocksize", &fnum, sizeof(int32), - &bus->blocksize, sizeof(int32), FALSE) != BCME_OK) { - bus->blocksize = 0; - DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__, "sd_blocksize")); - } else { - DHD_INFO(("%s: Initial value for %s is %d\n", - __FUNCTION__, "sd_blocksize", bus->blocksize)); - } - bus->roundup = MIN(max_roundup, bus->blocksize); - - /* Query if bus module supports packet chaining, default to use if supported */ - if (bcmsdh_iovar_op(sdh, "sd_rxchain", NULL, 0, - &bus->sd_rxchain, sizeof(int32), FALSE) != BCME_OK) { - bus->sd_rxchain = FALSE; - } else { - DHD_INFO(("%s: bus module (through bcmsdh API) %s chaining\n", - __FUNCTION__, (bus->sd_rxchain ? "supports" : "does not support"))); - } - bus->use_rxchain = (bool)bus->sd_rxchain; - - return TRUE; -} - -bool -dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh, - char *pfw_path, char *pnv_path) -{ - bool ret; - bus->fw_path = pfw_path; - bus->nv_path = pnv_path; - - ret = dhdsdio_download_firmware(bus, osh, bus->sdh); - - - return ret; -} - -static bool -dhdsdio_download_firmware(struct dhd_bus *bus, osl_t *osh, void *sdh) -{ - bool ret; - - /* Download the firmware */ - DHD_OS_WAKE_LOCK(bus->dhd); - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - ret = _dhdsdio_download_firmware(bus) == 0; - - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); - DHD_OS_WAKE_UNLOCK(bus->dhd); - return ret; -} - -/* Detach and free everything */ -static void -dhdsdio_release(dhd_bus_t *bus, osl_t *osh) -{ - bool dongle_isolation = FALSE; - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (bus) { - ASSERT(osh); - - /* De-register interrupt handler */ - bcmsdh_intr_disable(bus->sdh); - bcmsdh_intr_dereg(bus->sdh); - - if (bus->dhd) { - dhd_common_deinit(bus->dhd, NULL); - dongle_isolation = bus->dhd->dongle_isolation; - dhd_detach(bus->dhd); - dhdsdio_release_dongle(bus, osh, dongle_isolation, TRUE); - dhd_free(bus->dhd); - bus->dhd = NULL; - } - - dhdsdio_release_malloc(bus, osh); - -#ifdef DHD_DEBUG - if (bus->console.buf != NULL) - MFREE(osh, bus->console.buf, bus->console.bufsize); -#endif - - MFREE(osh, bus, sizeof(dhd_bus_t)); - } - - if (osh) - dhd_osl_detach(osh); - - DHD_TRACE(("%s: Disconnected\n", __FUNCTION__)); -} - -static void -dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (bus->dhd && bus->dhd->dongle_reset) - return; - - if (bus->rxbuf) { -#ifndef CONFIG_DHD_USE_STATIC_BUF - MFREE(osh, bus->rxbuf, bus->rxblen); -#endif - bus->rxctl = bus->rxbuf = NULL; - bus->rxlen = 0; - } - - if (bus->databuf) { -#ifndef CONFIG_DHD_USE_STATIC_BUF - MFREE(osh, bus->databuf, MAX_DATA_BUF); -#endif - bus->databuf = NULL; - } - - if (bus->vars && bus->varsz) { - MFREE(osh, bus->vars, bus->varsz); - bus->vars = NULL; - } - -} - - -static void -dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh, bool dongle_isolation, bool reset_flag) -{ - DHD_TRACE(("%s: Enter bus->dhd %p bus->dhd->dongle_reset %d \n", __FUNCTION__, - bus->dhd, bus->dhd->dongle_reset)); - - if ((bus->dhd && bus->dhd->dongle_reset) && reset_flag) - return; - - if (bus->sih) { - if (bus->dhd) { - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - } -#if !defined(BCMLXSDMMC) - if (dongle_isolation == FALSE) - si_watchdog(bus->sih, 4); -#endif /* !defined(BCMLXSDMMC) */ - if (bus->dhd) { - dhdsdio_clkctl(bus, CLK_NONE, FALSE); - } - si_detach(bus->sih); - bus->sih = NULL; - if (bus->vars && bus->varsz) - MFREE(osh, bus->vars, bus->varsz); - bus->vars = NULL; - } - - DHD_TRACE(("%s: Disconnected\n", __FUNCTION__)); -} - -static void -dhdsdio_disconnect(void *ptr) -{ - dhd_bus_t *bus = (dhd_bus_t *)ptr; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (bus) { - ASSERT(bus->dhd); - dhdsdio_release(bus, bus->dhd->osh); - } - - DHD_TRACE(("%s: Disconnected\n", __FUNCTION__)); -} - - -/* Register/Unregister functions are called by the main DHD entry - * point (e.g. module insertion) to link with the bus driver, in - * order to look for or await the device. - */ - -static bcmsdh_driver_t dhd_sdio = { - dhdsdio_probe, - dhdsdio_disconnect -}; - -int -dhd_bus_register(void) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - return bcmsdh_register(&dhd_sdio); -} - -void -dhd_bus_unregister(void) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - bcmsdh_unregister(); -} - -#ifdef BCMEMBEDIMAGE -static int -dhdsdio_download_code_array(struct dhd_bus *bus) -{ - int bcmerror = -1; - int offset = 0; - unsigned char *ularray = NULL; - - DHD_INFO(("%s: download embedded firmware...\n", __FUNCTION__)); - - /* Download image */ - while ((offset + MEMBLOCK) < sizeof(dlarray)) { - bcmerror = dhdsdio_membytes(bus, TRUE, offset, - (uint8 *) (dlarray + offset), MEMBLOCK); - if (bcmerror) { - DHD_ERROR(("%s: error %d on writing %d membytes at 0x%08x\n", - __FUNCTION__, bcmerror, MEMBLOCK, offset)); - goto err; - } - - offset += MEMBLOCK; - } - - if (offset < sizeof(dlarray)) { - bcmerror = dhdsdio_membytes(bus, TRUE, offset, - (uint8 *) (dlarray + offset), sizeof(dlarray) - offset); - if (bcmerror) { - DHD_ERROR(("%s: error %d on writing %d membytes at 0x%08x\n", - __FUNCTION__, bcmerror, sizeof(dlarray) - offset, offset)); - goto err; - } - } - -#ifdef DHD_DEBUG - /* Upload and compare the downloaded code */ - { - ularray = MALLOC(bus->dhd->osh, bus->ramsize); - /* Upload image to verify downloaded contents. */ - offset = 0; - memset(ularray, 0xaa, bus->ramsize); - while ((offset + MEMBLOCK) < sizeof(dlarray)) { - bcmerror = dhdsdio_membytes(bus, FALSE, offset, ularray + offset, MEMBLOCK); - if (bcmerror) { - DHD_ERROR(("%s: error %d on reading %d membytes at 0x%08x\n", - __FUNCTION__, bcmerror, MEMBLOCK, offset)); - goto err; - } - - offset += MEMBLOCK; - } - - if (offset < sizeof(dlarray)) { - bcmerror = dhdsdio_membytes(bus, FALSE, offset, - ularray + offset, sizeof(dlarray) - offset); - if (bcmerror) { - DHD_ERROR(("%s: error %d on reading %d membytes at 0x%08x\n", - __FUNCTION__, bcmerror, sizeof(dlarray) - offset, offset)); - goto err; - } - } - - if (memcmp(dlarray, ularray, sizeof(dlarray))) { - DHD_ERROR(("%s: Downloaded image is corrupted (%s, %s, %s).\n", - __FUNCTION__, dlimagename, dlimagever, dlimagedate)); - goto err; - } else - DHD_ERROR(("%s: Download, Upload and compare succeeded (%s, %s, %s).\n", - __FUNCTION__, dlimagename, dlimagever, dlimagedate)); - - } -#endif /* DHD_DEBUG */ - -err: - if (ularray) - MFREE(bus->dhd->osh, ularray, bus->ramsize); - return bcmerror; -} -#endif /* BCMEMBEDIMAGE */ - -static int -dhdsdio_download_code_file(struct dhd_bus *bus, char *pfw_path) -{ - int bcmerror = -1; - int offset = 0; - uint len; - void *image = NULL; - uint8 *memblock = NULL, *memptr; - - DHD_INFO(("%s: download firmware %s\n", __FUNCTION__, pfw_path)); - - image = dhd_os_open_image(pfw_path); - if (image == NULL) - goto err; - - memptr = memblock = MALLOC(bus->dhd->osh, MEMBLOCK + DHD_SDALIGN); - if (memblock == NULL) { - DHD_ERROR(("%s: Failed to allocate memory %d bytes\n", __FUNCTION__, MEMBLOCK)); - goto err; - } - if ((uint32)(uintptr)memblock % DHD_SDALIGN) - memptr += (DHD_SDALIGN - ((uint32)(uintptr)memblock % DHD_SDALIGN)); - - /* Download image */ - while ((len = dhd_os_get_image_block((char*)memptr, MEMBLOCK, image))) { - bcmerror = dhdsdio_membytes(bus, TRUE, offset, memptr, len); - if (bcmerror) { - DHD_ERROR(("%s: error %d on writing %d membytes at 0x%08x\n", - __FUNCTION__, bcmerror, MEMBLOCK, offset)); - goto err; - } - - offset += MEMBLOCK; - } - -err: - if (memblock) - MFREE(bus->dhd->osh, memblock, MEMBLOCK + DHD_SDALIGN); - - if (image) - dhd_os_close_image(image); - - return bcmerror; -} - -/* - EXAMPLE: nvram_array - nvram_arry format: - name=value - Use carriage return at the end of each assignment, and an empty string with - carriage return at the end of array. - - For example: - unsigned char nvram_array[] = {"name1=value1\n", "name2=value2\n", "\n"}; - Hex values start with 0x, and mac addr format: xx:xx:xx:xx:xx:xx. - - Search "EXAMPLE: nvram_array" to see how the array is activated. -*/ - -void -dhd_bus_set_nvram_params(struct dhd_bus * bus, const char *nvram_params) -{ - bus->nvram_params = nvram_params; -} - -static int -dhdsdio_download_nvram(struct dhd_bus *bus) -{ - int bcmerror = -1; - uint len; - void * image = NULL; - char * memblock = NULL; - char *bufp; - char *pnv_path; - bool nvram_file_exists; - - pnv_path = bus->nv_path; - - nvram_file_exists = ((pnv_path != NULL) && (pnv_path[0] != '\0')); - if (!nvram_file_exists && (bus->nvram_params == NULL)) - return (0); - - if (nvram_file_exists) { - image = dhd_os_open_image(pnv_path); - if (image == NULL) - goto err; - } - - memblock = MALLOC(bus->dhd->osh, MAX_NVRAMBUF_SIZE); - if (memblock == NULL) { - DHD_ERROR(("%s: Failed to allocate memory %d bytes\n", - __FUNCTION__, MAX_NVRAMBUF_SIZE)); - goto err; - } - - /* Download variables */ - if (nvram_file_exists) { - len = dhd_os_get_image_block(memblock, MAX_NVRAMBUF_SIZE, image); - } - else { - len = strlen(bus->nvram_params); - ASSERT(len <= MAX_NVRAMBUF_SIZE); - memcpy(memblock, bus->nvram_params, len); - } - if (len > 0 && len < MAX_NVRAMBUF_SIZE) { - bufp = (char *)memblock; - bufp[len] = 0; - len = process_nvram_vars(bufp, len); - if (len % 4) { - len += 4 - (len % 4); - } - bufp += len; - *bufp++ = 0; - if (len) - bcmerror = dhdsdio_downloadvars(bus, memblock, len + 1); - if (bcmerror) { - DHD_ERROR(("%s: error downloading vars: %d\n", - __FUNCTION__, bcmerror)); - } - } - else { - DHD_ERROR(("%s: error reading nvram file: %d\n", - __FUNCTION__, len)); - bcmerror = BCME_SDIO_ERROR; - } - -err: - if (memblock) - MFREE(bus->dhd->osh, memblock, MAX_NVRAMBUF_SIZE); - - if (image) - dhd_os_close_image(image); - - return bcmerror; -} - -static int -_dhdsdio_download_firmware(struct dhd_bus *bus) -{ - int bcmerror = -1; - - bool embed = FALSE; /* download embedded firmware */ - bool dlok = FALSE; /* download firmware succeeded */ - - /* Out immediately if no image to download */ - if ((bus->fw_path == NULL) || (bus->fw_path[0] == '\0')) { -#ifdef BCMEMBEDIMAGE - embed = TRUE; -#else - return 0; -#endif - } - - /* Keep arm in reset */ - if (dhdsdio_download_state(bus, TRUE)) { - DHD_ERROR(("%s: error placing ARM core in reset\n", __FUNCTION__)); - goto err; - } - - /* External image takes precedence if specified */ - if ((bus->fw_path != NULL) && (bus->fw_path[0] != '\0')) { - if (dhdsdio_download_code_file(bus, bus->fw_path)) { - DHD_ERROR(("%s: dongle image file download failed\n", __FUNCTION__)); -#ifdef BCMEMBEDIMAGE - embed = TRUE; -#else - goto err; -#endif - } - else { - embed = FALSE; - dlok = TRUE; - } - } -#ifdef BCMEMBEDIMAGE - if (embed) { - if (dhdsdio_download_code_array(bus)) { - DHD_ERROR(("%s: dongle image array download failed\n", __FUNCTION__)); - goto err; - } - else { - dlok = TRUE; - } - } -#endif - if (!dlok) { - DHD_ERROR(("%s: dongle image download failed\n", __FUNCTION__)); - goto err; - } - - /* EXAMPLE: nvram_array */ - /* If a valid nvram_arry is specified as above, it can be passed down to dongle */ - /* dhd_bus_set_nvram_params(bus, (char *)&nvram_array); */ - - /* External nvram takes precedence if specified */ - if (dhdsdio_download_nvram(bus)) { - DHD_ERROR(("%s: dongle nvram file download failed\n", __FUNCTION__)); - goto err; - } - - /* Take arm out of reset */ - if (dhdsdio_download_state(bus, FALSE)) { - DHD_ERROR(("%s: error getting out of ARM core reset\n", __FUNCTION__)); - goto err; - } - - bcmerror = 0; - -err: - return bcmerror; -} - -static int -dhd_bcmsdh_recv_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, uint8 *buf, uint nbytes, - void *pkt, bcmsdh_cmplt_fn_t complete, void *handle) -{ - int status; - - status = bcmsdh_recv_buf(bus->sdh, addr, fn, flags, buf, nbytes, pkt, complete, handle); - - return status; -} - -static int -dhd_bcmsdh_send_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, uint8 *buf, uint nbytes, - void *pkt, bcmsdh_cmplt_fn_t complete, void *handle) -{ - return (bcmsdh_send_buf(bus->sdh, addr, fn, flags, buf, nbytes, pkt, complete, handle)); -} - -uint -dhd_bus_chip(struct dhd_bus *bus) -{ - ASSERT(bus); - ASSERT(bus->sih != NULL); - return bus->sih->chip; -} - -void * -dhd_bus_pub(struct dhd_bus *bus) -{ - ASSERT(bus); - return bus->dhd; -} - -void * -dhd_bus_txq(struct dhd_bus *bus) -{ - return &bus->txq; -} - -uint -dhd_bus_hdrlen(struct dhd_bus *bus) -{ - return SDPCM_HDRLEN; -} - -int -dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag) -{ - int bcmerror = 0; - dhd_bus_t *bus; - - bus = dhdp->bus; - - if (flag == TRUE) { - if (!bus->dhd->dongle_reset) { - dhd_os_sdlock(dhdp); - dhd_os_wd_timer(dhdp, 0); -#if !defined(IGNORE_ETH0_DOWN) - /* Force flow control as protection when stop come before ifconfig_down */ - dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, ON); -#endif /* !defined(IGNORE_ETH0_DOWN) */ - /* Expect app to have torn down any connection before calling */ - /* Stop the bus, disable F2 */ - dhd_bus_stop(bus, FALSE); - -#if defined(OOB_INTR_ONLY) - /* Clean up any pending IRQ */ - bcmsdh_set_irq(FALSE); -#endif /* defined(OOB_INTR_ONLY) */ - - /* Clean tx/rx buffer pointers, detach from the dongle */ - dhdsdio_release_dongle(bus, bus->dhd->osh, TRUE, TRUE); - - bus->dhd->dongle_reset = TRUE; - bus->dhd->up = FALSE; - dhd_os_sdunlock(dhdp); - DHD_TRACE(("%s: WLAN OFF DONE\n", __FUNCTION__)); - /* App can now remove power from device */ - } else - bcmerror = BCME_SDIO_ERROR; - } else { - /* App must have restored power to device before calling */ - - DHD_TRACE(("\n\n%s: == WLAN ON ==\n", __FUNCTION__)); - - if (bus->dhd->dongle_reset) { - /* Turn on WLAN */ -#ifdef DHDTHREAD - dhd_os_sdlock(dhdp); -#endif /* DHDTHREAD */ - /* Reset SD client */ - bcmsdh_reset(bus->sdh); - - /* Attempt to re-attach & download */ - if (dhdsdio_probe_attach(bus, bus->dhd->osh, bus->sdh, - (uint32 *)SI_ENUM_BASE, - bus->cl_devid)) { - /* Attempt to download binary to the dongle */ - if (dhdsdio_probe_init(bus, bus->dhd->osh, bus->sdh) && - dhdsdio_download_firmware(bus, bus->dhd->osh, bus->sdh)) { - - /* Re-init bus, enable F2 transfer */ - bcmerror = dhd_bus_init((dhd_pub_t *) bus->dhd, FALSE); - if (bcmerror == BCME_OK) { -#if defined(OOB_INTR_ONLY) - bcmsdh_set_irq(TRUE); - dhd_enable_oob_intr(bus, TRUE); -#endif /* defined(OOB_INTR_ONLY) */ - - bus->dhd->dongle_reset = FALSE; - bus->dhd->up = TRUE; - -#if !defined(IGNORE_ETH0_DOWN) - /* Restore flow control */ - dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, OFF); -#endif - dhd_os_wd_timer(dhdp, dhd_watchdog_ms); - - DHD_TRACE(("%s: WLAN ON DONE\n", __FUNCTION__)); - } else { - dhd_bus_stop(bus, FALSE); - dhdsdio_release_dongle(bus, bus->dhd->osh, - TRUE, FALSE); - } - } else - bcmerror = BCME_SDIO_ERROR; - } else - bcmerror = BCME_SDIO_ERROR; - -#ifdef DHDTHREAD - dhd_os_sdunlock(dhdp); -#endif /* DHDTHREAD */ - } else { - bcmerror = BCME_SDIO_ERROR; - DHD_INFO(("%s called when dongle is not in reset\n", - __FUNCTION__)); - DHD_INFO(("Will call dhd_bus_start instead\n")); - sdioh_start(NULL, 1); - if ((bcmerror = dhd_bus_start(dhdp)) != 0) - DHD_ERROR(("%s: dhd_bus_start fail with %d\n", - __FUNCTION__, bcmerror)); - } - } - return bcmerror; -} - -/* Get Chip ID version */ -uint dhd_bus_chip_id(dhd_pub_t *dhdp) -{ - dhd_bus_t *bus = dhdp->bus; - - return bus->sih->chip; -} - -/* Get Chip Rev ID version */ -uint dhd_bus_chiprev_id(dhd_pub_t *dhdp) -{ - dhd_bus_t *bus = dhdp->bus; - - return bus->sih->chiprev; -} - -/* Get Chip Pkg ID version */ -uint dhd_bus_chippkg_id(dhd_pub_t *dhdp) -{ - dhd_bus_t *bus = dhdp->bus; - - return bus->sih->chippkg; -} - -int -dhd_bus_membytes(dhd_pub_t *dhdp, bool set, uint32 address, uint8 *data, uint size) -{ - dhd_bus_t *bus; - - bus = dhdp->bus; - return dhdsdio_membytes(bus, set, address, data, size); -} diff --git a/drivers/net/wireless/bcmdhd/dhd_wlfc.h b/drivers/net/wireless/bcmdhd/dhd_wlfc.h deleted file mode 100644 index c4d251806d78..000000000000 --- a/drivers/net/wireless/bcmdhd/dhd_wlfc.h +++ /dev/null @@ -1,276 +0,0 @@ -/* -* Copyright (C) 1999-2011, Broadcom Corporation -* -* Unless you and Broadcom execute a separate written software license -* agreement governing use of this software, this software is licensed to you -* under the terms of the GNU General Public License version 2 (the "GPL"), -* available at http://www.broadcom.com/licenses/GPLv2.php, with the -* following added to such license: -* -* As a special exception, the copyright holders of this software give you -* permission to link this software with independent modules, and to copy and -* distribute the resulting executable under terms of your choice, provided that -* you also meet, for each linked independent module, the terms and conditions of -* the license of that module. An independent module is a module which is not -* derived from this software. The special exception does not apply to any -* modifications of the software. -* -* Notwithstanding the above, under no circumstances may you combine this -* software in any way with any other Broadcom software provided under a license -* other than the GPL, without Broadcom's express prior written consent. -* $Id: dhd_wlfc.h 286994 2011-09-29 21:27:44Z $ -* -*/ -#ifndef __wlfc_host_driver_definitions_h__ -#define __wlfc_host_driver_definitions_h__ - -/* 16 bits will provide an absolute max of 65536 slots */ -#define WLFC_HANGER_MAXITEMS 1024 - -#define WLFC_HANGER_ITEM_STATE_FREE 1 -#define WLFC_HANGER_ITEM_STATE_INUSE 2 - -#define WLFC_PKTID_HSLOT_MASK 0xffff /* allow 16 bits only */ -#define WLFC_PKTID_HSLOT_SHIFT 8 - -/* x -> TXSTATUS TAG to/from firmware */ -#define WLFC_PKTID_HSLOT_GET(x) \ - (((x) >> WLFC_PKTID_HSLOT_SHIFT) & WLFC_PKTID_HSLOT_MASK) -#define WLFC_PKTID_HSLOT_SET(var, slot) \ - ((var) = ((var) & ~(WLFC_PKTID_HSLOT_MASK << WLFC_PKTID_HSLOT_SHIFT)) | \ - (((slot) & WLFC_PKTID_HSLOT_MASK) << WLFC_PKTID_HSLOT_SHIFT)) - -#define WLFC_PKTID_FREERUNCTR_MASK 0xff - -#define WLFC_PKTID_FREERUNCTR_GET(x) ((x) & WLFC_PKTID_FREERUNCTR_MASK) -#define WLFC_PKTID_FREERUNCTR_SET(var, ctr) \ - ((var) = (((var) & ~WLFC_PKTID_FREERUNCTR_MASK) | \ - (((ctr) & WLFC_PKTID_FREERUNCTR_MASK)))) - -#define WLFC_PKTQ_PENQ(pq, prec, p) ((pktq_full((pq)) || pktq_pfull((pq), (prec)))? \ - NULL : pktq_penq((pq), (prec), (p))) -#define WLFC_PKTQ_PENQ_HEAD(pq, prec, p) ((pktq_full((pq)) || pktq_pfull((pq), (prec))) ? \ - NULL : pktq_penq_head((pq), (prec), (p))) - -typedef enum ewlfc_packet_state { - eWLFC_PKTTYPE_NEW, - eWLFC_PKTTYPE_DELAYED, - eWLFC_PKTTYPE_SUPPRESSED, - eWLFC_PKTTYPE_MAX -} ewlfc_packet_state_t; - -typedef enum ewlfc_mac_entry_action { - eWLFC_MAC_ENTRY_ACTION_ADD, - eWLFC_MAC_ENTRY_ACTION_DEL, - eWLFC_MAC_ENTRY_ACTION_MAX -} ewlfc_mac_entry_action_t; - -typedef struct wlfc_hanger_item { - uint8 state; - uint8 pad[3]; - uint32 identifier; - void* pkt; -#ifdef PROP_TXSTATUS_DEBUG - uint32 push_time; -#endif -} wlfc_hanger_item_t; - -typedef struct wlfc_hanger { - int max_items; - uint32 pushed; - uint32 popped; - uint32 failed_to_push; - uint32 failed_to_pop; - uint32 failed_slotfind; - wlfc_hanger_item_t items[1]; -} wlfc_hanger_t; - -#define WLFC_HANGER_SIZE(n) ((sizeof(wlfc_hanger_t) - \ - sizeof(wlfc_hanger_item_t)) + ((n)*sizeof(wlfc_hanger_item_t))) - -#define WLFC_STATE_OPEN 1 -#define WLFC_STATE_CLOSE 2 - -#define WLFC_PSQ_PREC_COUNT ((AC_COUNT + 1) * 2) /* 2 for each AC traffic and bc/mc */ -#define WLFC_PSQ_LEN 64 -#define WLFC_SENDQ_LEN 256 - -#define WLFC_FLOWCONTROL_DELTA 8 -#define WLFC_FLOWCONTROL_HIWATER (WLFC_PSQ_LEN - WLFC_FLOWCONTROL_DELTA) -#define WLFC_FLOWCONTROL_LOWATER (WLFC_FLOWCONTROL_HIWATER - WLFC_FLOWCONTROL_DELTA) - -typedef struct wlfc_mac_descriptor { - uint8 occupied; - uint8 interface_id; - uint8 iftype; - uint8 state; - uint8 ac_bitmap; /* for APSD */ - uint8 requested_credit; - uint8 requested_packet; - uint8 ea[ETHER_ADDR_LEN]; - /* - maintain (MAC,AC) based seq count for - packets going to the device. As well as bc/mc. - */ - uint8 seq[AC_COUNT + 1]; - uint8 generation; - struct pktq psq; - /* The AC pending bitmap that was reported to the fw at last change */ - uint8 traffic_lastreported_bmp; - /* The new AC pending bitmap */ - uint8 traffic_pending_bmp; - /* 1= send on next opportunity */ - uint8 send_tim_signal; - uint8 mac_handle; -#ifdef PROP_TXSTATUS_DEBUG - uint32 dstncredit_sent_packets; - uint32 dstncredit_acks; - uint32 opened_ct; - uint32 closed_ct; -#endif -} wlfc_mac_descriptor_t; - -#define WLFC_DECR_SEQCOUNT(entry, prec) do { if (entry->seq[(prec)] == 0) {\ - entry->seq[prec] = 0xff; } else entry->seq[prec]--;} while (0) - -#define WLFC_INCR_SEQCOUNT(entry, prec) entry->seq[(prec)]++ -#define WLFC_SEQCOUNT(entry, prec) entry->seq[(prec)] - -typedef struct athost_wl_stat_counters { - uint32 pktin; - uint32 pkt2bus; - uint32 pktdropped; - uint32 tlv_parse_failed; - uint32 rollback; - uint32 rollback_failed; - uint32 sendq_full_error; - uint32 delayq_full_error; - uint32 credit_request_failed; - uint32 packet_request_failed; - uint32 mac_update_failed; - uint32 psmode_update_failed; - uint32 interface_update_failed; - uint32 wlfc_header_only_pkt; - uint32 txstatus_in; - uint32 d11_suppress; - uint32 wl_suppress; - uint32 bad_suppress; - uint32 pkt_freed; - uint32 pkt_free_err; - uint32 psq_wlsup_retx; - uint32 psq_wlsup_enq; - uint32 psq_d11sup_retx; - uint32 psq_d11sup_enq; - uint32 psq_hostq_retx; - uint32 psq_hostq_enq; - uint32 mac_handle_notfound; - uint32 wlc_tossed_pkts; - uint32 dhd_hdrpulls; - uint32 generic_error; - /* an extra one for bc/mc traffic */ - uint32 sendq_pkts[AC_COUNT + 1]; -#ifdef PROP_TXSTATUS_DEBUG - /* all pkt2bus -> txstatus latency accumulated */ - uint32 latency_sample_count; - uint32 total_status_latency; - uint32 latency_most_recent; - int idx_delta; - uint32 deltas[10]; - uint32 fifo_credits_sent[6]; - uint32 fifo_credits_back[6]; - uint32 dropped_qfull[6]; - uint32 signal_only_pkts_sent; - uint32 signal_only_pkts_freed; -#endif -} athost_wl_stat_counters_t; - -#ifdef PROP_TXSTATUS_DEBUG -#define WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac) do { \ - (ctx)->stats.fifo_credits_sent[(ac)]++;} while (0) -#define WLFC_HOST_FIFO_CREDIT_INC_BACKCTRS(ctx, ac) do { \ - (ctx)->stats.fifo_credits_back[(ac)]++;} while (0) -#define WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, ac) do { \ - (ctx)->stats.dropped_qfull[(ac)]++;} while (0) -#else -#define WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac) do {} while (0) -#define WLFC_HOST_FIFO_CREDIT_INC_BACKCTRS(ctx, ac) do {} while (0) -#define WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, ac) do {} while (0) -#endif - -#define WLFC_FCMODE_NONE 0 -#define WLFC_FCMODE_IMPLIED_CREDIT 1 -#define WLFC_FCMODE_EXPLICIT_CREDIT 2 - -/* How long to defer borrowing in milliseconds */ -#define WLFC_BORROW_DEFER_PERIOD_MS 100 - -/* Mask to represent available ACs (note: BC/MC is ignored */ -#define WLFC_AC_MASK 0xF - -/* Mask to check for only on-going AC_BE traffic */ -#define WLFC_AC_BE_TRAFFIC_ONLY 0xD - -typedef struct athost_wl_status_info { - uint8 last_seqid_to_wlc; - - /* OSL handle */ - osl_t* osh; - /* dhd pub */ - void* dhdp; - - /* stats */ - athost_wl_stat_counters_t stats; - - /* the additional ones are for bc/mc and ATIM FIFO */ - int FIFO_credit[AC_COUNT + 2]; - - /* Credit borrow counts for each FIFO from each of the other FIFOs */ - int credits_borrowed[AC_COUNT + 2][AC_COUNT + 2]; - - struct pktq SENDQ; - - /* packet hanger and MAC->handle lookup table */ - void* hanger; - struct { - /* table for individual nodes */ - wlfc_mac_descriptor_t nodes[WLFC_MAC_DESC_TABLE_SIZE]; - /* table for interfaces */ - wlfc_mac_descriptor_t interfaces[WLFC_MAX_IFNUM]; - /* OS may send packets to unknown (unassociated) destinations */ - /* A place holder for bc/mc and packets to unknown destinations */ - wlfc_mac_descriptor_t other; - } destination_entries; - /* token position for different priority packets */ - uint8 token_pos[AC_COUNT+1]; - /* ON/OFF state for flow control to the host network interface */ - uint8 hostif_flow_state[WLFC_MAX_IFNUM]; - uint8 host_ifidx; - /* to flow control an OS interface */ - uint8 toggle_host_if; - - /* - Mode in which the dhd flow control shall operate. Must be set before - traffic starts to the device. - 0 - Do not do any proptxtstatus flow control - 1 - Use implied credit from a packet status - 2 - Use explicit credit - */ - uint8 proptxstatus_mode; - - /* To borrow credits */ - uint8 allow_credit_borrow; - - /* Timestamp to compute how long to defer borrowing for */ - uint32 borrow_defer_timestamp; - -} athost_wl_status_info_t; - -int dhd_wlfc_enable(dhd_pub_t *dhd); -int dhd_wlfc_interface_event(struct dhd_info *, - ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea); -int dhd_wlfc_FIFOcreditmap_event(struct dhd_info *dhd, uint8* event_data); -int dhd_wlfc_event(struct dhd_info *dhd); -int dhd_os_wlfc_block(dhd_pub_t *pub); -int dhd_os_wlfc_unblock(dhd_pub_t *pub); - -#endif /* __wlfc_host_driver_definitions_h__ */ diff --git a/drivers/net/wireless/bcmdhd/dngl_stats.h b/drivers/net/wireless/bcmdhd/dngl_stats.h deleted file mode 100644 index 9cdf718b3990..000000000000 --- a/drivers/net/wireless/bcmdhd/dngl_stats.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Common stats definitions for clients of dongle - * ports - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dngl_stats.h,v 1.5 2008-06-02 16:56:20 Exp $ - */ - -#ifndef _dngl_stats_h_ -#define _dngl_stats_h_ - -typedef struct { - unsigned long rx_packets; /* total packets received */ - unsigned long tx_packets; /* total packets transmitted */ - unsigned long rx_bytes; /* total bytes received */ - unsigned long tx_bytes; /* total bytes transmitted */ - unsigned long rx_errors; /* bad packets received */ - unsigned long tx_errors; /* packet transmit problems */ - unsigned long rx_dropped; /* packets dropped by dongle */ - unsigned long tx_dropped; /* packets dropped by dongle */ - unsigned long multicast; /* multicast packets received */ -} dngl_stats_t; - -#endif /* _dngl_stats_h_ */ diff --git a/drivers/net/wireless/bcmdhd/dngl_wlhdr.h b/drivers/net/wireless/bcmdhd/dngl_wlhdr.h deleted file mode 100644 index 8b39b9ecb584..000000000000 --- a/drivers/net/wireless/bcmdhd/dngl_wlhdr.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Dongle WL Header definitions - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dngl_wlhdr.h,v 1.1 2009-01-08 01:21:12 Exp $ - */ - -#ifndef _dngl_wlhdr_h_ -#define _dngl_wlhdr_h_ - -typedef struct wl_header { - uint8 type; /* Header type */ - uint8 version; /* Header version */ - int8 rssi; /* RSSI */ - uint8 pad; /* Unused */ -} wl_header_t; - -#define WL_HEADER_LEN sizeof(wl_header_t) -#define WL_HEADER_TYPE 0 -#define WL_HEADER_VER 1 -#endif /* _dngl_wlhdr_h_ */ diff --git a/drivers/net/wireless/bcmdhd/hndpmu.c b/drivers/net/wireless/bcmdhd/hndpmu.c deleted file mode 100644 index 0e493343c806..000000000000 --- a/drivers/net/wireless/bcmdhd/hndpmu.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Misc utility routines for accessing PMU corerev specific features - * of the SiliconBackplane-based Broadcom chips. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: hndpmu.c,v 1.228.2.56 2011-02-11 22:49:07 $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PMU_ERROR(args) - -#define PMU_MSG(args) - -/* To check in verbose debugging messages not intended - * to be on except on private builds. - */ -#define PMU_NONE(args) - - -/* SDIO Pad drive strength to select value mappings. - * The last strength value in each table must be 0 (the tri-state value). - */ -typedef struct { - uint8 strength; /* Pad Drive Strength in mA */ - uint8 sel; /* Chip-specific select value */ -} sdiod_drive_str_t; - -/* SDIO Drive Strength to sel value table for PMU Rev 1 */ -static const sdiod_drive_str_t sdiod_drive_strength_tab1[] = { - {4, 0x2}, - {2, 0x3}, - {1, 0x0}, - {0, 0x0} }; - -/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */ -static const sdiod_drive_str_t sdiod_drive_strength_tab2[] = { - {12, 0x7}, - {10, 0x6}, - {8, 0x5}, - {6, 0x4}, - {4, 0x2}, - {2, 0x1}, - {0, 0x0} }; - -/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */ -static const sdiod_drive_str_t sdiod_drive_strength_tab3[] = { - {32, 0x7}, - {26, 0x6}, - {22, 0x5}, - {16, 0x4}, - {12, 0x3}, - {8, 0x2}, - {4, 0x1}, - {0, 0x0} }; - -/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8v) */ -static const sdiod_drive_str_t sdiod_drive_strength_tab4_1v8[] = { - {32, 0x6}, - {26, 0x7}, - {22, 0x4}, - {16, 0x5}, - {12, 0x2}, - {8, 0x3}, - {4, 0x0}, - {0, 0x1} }; - -/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.2v) */ - -/* SDIO Drive Strength to sel value table for PMU Rev 11 (2.5v) */ - -/* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */ -static const sdiod_drive_str_t sdiod_drive_strength_tab5_1v8[] = { - {6, 0x7}, - {5, 0x6}, - {4, 0x5}, - {3, 0x4}, - {2, 0x2}, - {1, 0x1}, - {0, 0x0} }; - -/* SDIO Drive Strength to sel value table for PMU Rev 13 (3.3v) */ - - -#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) - -void -si_sdiod_drive_strength_init(si_t *sih, osl_t *osh, uint32 drivestrength) -{ - chipcregs_t *cc; - uint origidx, intr_val = 0; - sdiod_drive_str_t *str_tab = NULL; - uint32 str_mask = 0; - uint32 str_shift = 0; - - if (!(sih->cccaps & CC_CAP_PMU)) { - return; - } - - /* Remember original core before switch to chipc */ - cc = (chipcregs_t *) si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val); - - switch (SDIOD_DRVSTR_KEY(sih->chip, sih->pmurev)) { - case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1): - str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab1; - str_mask = 0x30000000; - str_shift = 28; - break; - case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2): - case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3): - case SDIOD_DRVSTR_KEY(BCM4315_CHIP_ID, 4): - str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab2; - str_mask = 0x00003800; - str_shift = 11; - break; - case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8): - case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 11): - if (sih->pmurev == 8) { - str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab3; - } - else if (sih->pmurev == 11) { - str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab4_1v8; - } - str_mask = 0x00003800; - str_shift = 11; - break; - case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12): - str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab4_1v8; - str_mask = 0x00003800; - str_shift = 11; - break; - case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13): - str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab5_1v8; - str_mask = 0x00003800; - str_shift = 11; - break; - default: - PMU_MSG(("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", - bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev)); - - break; - } - - if (str_tab != NULL) { - uint32 cc_data_temp; - int i; - - /* Pick the lowest available drive strength equal or greater than the - * requested strength. Drive strength of 0 requests tri-state. - */ - for (i = 0; drivestrength < str_tab[i].strength; i++) - ; - - if (i > 0 && drivestrength > str_tab[i].strength) - i--; - - W_REG(osh, &cc->chipcontrol_addr, 1); - cc_data_temp = R_REG(osh, &cc->chipcontrol_data); - cc_data_temp &= ~str_mask; - cc_data_temp |= str_tab[i].sel << str_shift; - W_REG(osh, &cc->chipcontrol_data, cc_data_temp); - - PMU_MSG(("SDIO: %dmA drive strength requested; set to %dmA\n", - drivestrength, str_tab[i].strength)); - } - - /* Return to original core */ - si_restore_core(sih, origidx, intr_val); -} diff --git a/drivers/net/wireless/bcmdhd/include/Makefile b/drivers/net/wireless/bcmdhd/include/Makefile deleted file mode 100644 index 67c4906f5889..000000000000 --- a/drivers/net/wireless/bcmdhd/include/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash -# -# This script serves following purpose: -# -# 1. It generates native version information by querying -# automerger maintained database to see where src/include -# came from -# 2. For select components, as listed in compvers.sh -# it generates component version files -# -# Copyright 2005, Broadcom, Inc. -# -# $Id: Makefile 241702 2011-02-19 00:41:03Z $ -# - -SRCBASE := .. - -TARGETS := epivers.h - -ifdef VERBOSE -export VERBOSE -endif - -all release: epivers compvers - -# Generate epivers.h for native branch version -epivers: - bash epivers.sh - -# Generate epivers.h for native branch version -compvers: - @if [ -s "compvers.sh" ]; then \ - echo "Generating component versions, if any"; \ - bash compvers.sh; \ - else \ - echo "Skipping component version generation"; \ - fi - -# Generate epivers.h for native branch version -clean_compvers: - @if [ -s "compvers.sh" ]; then \ - echo "bash compvers.sh clean"; \ - bash compvers.sh clean; \ - else \ - echo "Skipping component version clean"; \ - fi - -clean: - rm -f $(TARGETS) *.prev - -clean_all: clean clean_compvers - -.PHONY: all release clean epivers compvers clean_compvers diff --git a/drivers/net/wireless/bcmdhd/include/aidmp.h b/drivers/net/wireless/bcmdhd/include/aidmp.h deleted file mode 100644 index b993a033abc2..000000000000 --- a/drivers/net/wireless/bcmdhd/include/aidmp.h +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Broadcom AMBA Interconnect definitions. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: aidmp.h 277737 2011-08-16 17:54:59Z $ - */ - - -#ifndef _AIDMP_H -#define _AIDMP_H - - -#define MFGID_ARM 0x43b -#define MFGID_BRCM 0x4bf -#define MFGID_MIPS 0x4a7 - - -#define CC_SIM 0 -#define CC_EROM 1 -#define CC_CORESIGHT 9 -#define CC_VERIF 0xb -#define CC_OPTIMO 0xd -#define CC_GEN 0xe -#define CC_PRIMECELL 0xf - - -#define ER_EROMENTRY 0x000 -#define ER_REMAPCONTROL 0xe00 -#define ER_REMAPSELECT 0xe04 -#define ER_MASTERSELECT 0xe10 -#define ER_ITCR 0xf00 -#define ER_ITIP 0xf04 - - -#define ER_TAG 0xe -#define ER_TAG1 0x6 -#define ER_VALID 1 -#define ER_CI 0 -#define ER_MP 2 -#define ER_ADD 4 -#define ER_END 0xe -#define ER_BAD 0xffffffff - - -#define CIA_MFG_MASK 0xfff00000 -#define CIA_MFG_SHIFT 20 -#define CIA_CID_MASK 0x000fff00 -#define CIA_CID_SHIFT 8 -#define CIA_CCL_MASK 0x000000f0 -#define CIA_CCL_SHIFT 4 - - -#define CIB_REV_MASK 0xff000000 -#define CIB_REV_SHIFT 24 -#define CIB_NSW_MASK 0x00f80000 -#define CIB_NSW_SHIFT 19 -#define CIB_NMW_MASK 0x0007c000 -#define CIB_NMW_SHIFT 14 -#define CIB_NSP_MASK 0x00003e00 -#define CIB_NSP_SHIFT 9 -#define CIB_NMP_MASK 0x000001f0 -#define CIB_NMP_SHIFT 4 - - -#define MPD_MUI_MASK 0x0000ff00 -#define MPD_MUI_SHIFT 8 -#define MPD_MP_MASK 0x000000f0 -#define MPD_MP_SHIFT 4 - - -#define AD_ADDR_MASK 0xfffff000 -#define AD_SP_MASK 0x00000f00 -#define AD_SP_SHIFT 8 -#define AD_ST_MASK 0x000000c0 -#define AD_ST_SHIFT 6 -#define AD_ST_SLAVE 0x00000000 -#define AD_ST_BRIDGE 0x00000040 -#define AD_ST_SWRAP 0x00000080 -#define AD_ST_MWRAP 0x000000c0 -#define AD_SZ_MASK 0x00000030 -#define AD_SZ_SHIFT 4 -#define AD_SZ_4K 0x00000000 -#define AD_SZ_8K 0x00000010 -#define AD_SZ_16K 0x00000020 -#define AD_SZ_SZD 0x00000030 -#define AD_AG32 0x00000008 -#define AD_ADDR_ALIGN 0x00000fff -#define AD_SZ_BASE 0x00001000 - - -#define SD_SZ_MASK 0xfffff000 -#define SD_SG32 0x00000008 -#define SD_SZ_ALIGN 0x00000fff - - -#ifndef _LANGUAGE_ASSEMBLY - -typedef volatile struct _aidmp { - uint32 oobselina30; - uint32 oobselina74; - uint32 PAD[6]; - uint32 oobselinb30; - uint32 oobselinb74; - uint32 PAD[6]; - uint32 oobselinc30; - uint32 oobselinc74; - uint32 PAD[6]; - uint32 oobselind30; - uint32 oobselind74; - uint32 PAD[38]; - uint32 oobselouta30; - uint32 oobselouta74; - uint32 PAD[6]; - uint32 oobseloutb30; - uint32 oobseloutb74; - uint32 PAD[6]; - uint32 oobseloutc30; - uint32 oobseloutc74; - uint32 PAD[6]; - uint32 oobseloutd30; - uint32 oobseloutd74; - uint32 PAD[38]; - uint32 oobsynca; - uint32 oobseloutaen; - uint32 PAD[6]; - uint32 oobsyncb; - uint32 oobseloutben; - uint32 PAD[6]; - uint32 oobsyncc; - uint32 oobseloutcen; - uint32 PAD[6]; - uint32 oobsyncd; - uint32 oobseloutden; - uint32 PAD[38]; - uint32 oobaextwidth; - uint32 oobainwidth; - uint32 oobaoutwidth; - uint32 PAD[5]; - uint32 oobbextwidth; - uint32 oobbinwidth; - uint32 oobboutwidth; - uint32 PAD[5]; - uint32 oobcextwidth; - uint32 oobcinwidth; - uint32 oobcoutwidth; - uint32 PAD[5]; - uint32 oobdextwidth; - uint32 oobdinwidth; - uint32 oobdoutwidth; - uint32 PAD[37]; - uint32 ioctrlset; - uint32 ioctrlclear; - uint32 ioctrl; - uint32 PAD[61]; - uint32 iostatus; - uint32 PAD[127]; - uint32 ioctrlwidth; - uint32 iostatuswidth; - uint32 PAD[62]; - uint32 resetctrl; - uint32 resetstatus; - uint32 resetreadid; - uint32 resetwriteid; - uint32 PAD[60]; - uint32 errlogctrl; - uint32 errlogdone; - uint32 errlogstatus; - uint32 errlogaddrlo; - uint32 errlogaddrhi; - uint32 errlogid; - uint32 errloguser; - uint32 errlogflags; - uint32 PAD[56]; - uint32 intstatus; - uint32 PAD[127]; - uint32 config; - uint32 PAD[63]; - uint32 itcr; - uint32 PAD[3]; - uint32 itipooba; - uint32 itipoobb; - uint32 itipoobc; - uint32 itipoobd; - uint32 PAD[4]; - uint32 itipoobaout; - uint32 itipoobbout; - uint32 itipoobcout; - uint32 itipoobdout; - uint32 PAD[4]; - uint32 itopooba; - uint32 itopoobb; - uint32 itopoobc; - uint32 itopoobd; - uint32 PAD[4]; - uint32 itopoobain; - uint32 itopoobbin; - uint32 itopoobcin; - uint32 itopoobdin; - uint32 PAD[4]; - uint32 itopreset; - uint32 PAD[15]; - uint32 peripherialid4; - uint32 peripherialid5; - uint32 peripherialid6; - uint32 peripherialid7; - uint32 peripherialid0; - uint32 peripherialid1; - uint32 peripherialid2; - uint32 peripherialid3; - uint32 componentid0; - uint32 componentid1; - uint32 componentid2; - uint32 componentid3; -} aidmp_t; - -#endif - - -#define OOB_BUSCONFIG 0x020 -#define OOB_STATUSA 0x100 -#define OOB_STATUSB 0x104 -#define OOB_STATUSC 0x108 -#define OOB_STATUSD 0x10c -#define OOB_ENABLEA0 0x200 -#define OOB_ENABLEA1 0x204 -#define OOB_ENABLEA2 0x208 -#define OOB_ENABLEA3 0x20c -#define OOB_ENABLEB0 0x280 -#define OOB_ENABLEB1 0x284 -#define OOB_ENABLEB2 0x288 -#define OOB_ENABLEB3 0x28c -#define OOB_ENABLEC0 0x300 -#define OOB_ENABLEC1 0x304 -#define OOB_ENABLEC2 0x308 -#define OOB_ENABLEC3 0x30c -#define OOB_ENABLED0 0x380 -#define OOB_ENABLED1 0x384 -#define OOB_ENABLED2 0x388 -#define OOB_ENABLED3 0x38c -#define OOB_ITCR 0xf00 -#define OOB_ITIPOOBA 0xf10 -#define OOB_ITIPOOBB 0xf14 -#define OOB_ITIPOOBC 0xf18 -#define OOB_ITIPOOBD 0xf1c -#define OOB_ITOPOOBA 0xf30 -#define OOB_ITOPOOBB 0xf34 -#define OOB_ITOPOOBC 0xf38 -#define OOB_ITOPOOBD 0xf3c - - -#define AI_OOBSELINA30 0x000 -#define AI_OOBSELINA74 0x004 -#define AI_OOBSELINB30 0x020 -#define AI_OOBSELINB74 0x024 -#define AI_OOBSELINC30 0x040 -#define AI_OOBSELINC74 0x044 -#define AI_OOBSELIND30 0x060 -#define AI_OOBSELIND74 0x064 -#define AI_OOBSELOUTA30 0x100 -#define AI_OOBSELOUTA74 0x104 -#define AI_OOBSELOUTB30 0x120 -#define AI_OOBSELOUTB74 0x124 -#define AI_OOBSELOUTC30 0x140 -#define AI_OOBSELOUTC74 0x144 -#define AI_OOBSELOUTD30 0x160 -#define AI_OOBSELOUTD74 0x164 -#define AI_OOBSYNCA 0x200 -#define AI_OOBSELOUTAEN 0x204 -#define AI_OOBSYNCB 0x220 -#define AI_OOBSELOUTBEN 0x224 -#define AI_OOBSYNCC 0x240 -#define AI_OOBSELOUTCEN 0x244 -#define AI_OOBSYNCD 0x260 -#define AI_OOBSELOUTDEN 0x264 -#define AI_OOBAEXTWIDTH 0x300 -#define AI_OOBAINWIDTH 0x304 -#define AI_OOBAOUTWIDTH 0x308 -#define AI_OOBBEXTWIDTH 0x320 -#define AI_OOBBINWIDTH 0x324 -#define AI_OOBBOUTWIDTH 0x328 -#define AI_OOBCEXTWIDTH 0x340 -#define AI_OOBCINWIDTH 0x344 -#define AI_OOBCOUTWIDTH 0x348 -#define AI_OOBDEXTWIDTH 0x360 -#define AI_OOBDINWIDTH 0x364 -#define AI_OOBDOUTWIDTH 0x368 - - -#define AI_IOCTRLSET 0x400 -#define AI_IOCTRLCLEAR 0x404 -#define AI_IOCTRL 0x408 -#define AI_IOSTATUS 0x500 -#define AI_RESETCTRL 0x800 -#define AI_RESETSTATUS 0x804 - - -#define AI_IOCTRLWIDTH 0x700 -#define AI_IOSTATUSWIDTH 0x704 - -#define AI_RESETREADID 0x808 -#define AI_RESETWRITEID 0x80c -#define AI_ERRLOGCTRL 0xa00 -#define AI_ERRLOGDONE 0xa04 -#define AI_ERRLOGSTATUS 0xa08 -#define AI_ERRLOGADDRLO 0xa0c -#define AI_ERRLOGADDRHI 0xa10 -#define AI_ERRLOGID 0xa14 -#define AI_ERRLOGUSER 0xa18 -#define AI_ERRLOGFLAGS 0xa1c -#define AI_INTSTATUS 0xa00 -#define AI_CONFIG 0xe00 -#define AI_ITCR 0xf00 -#define AI_ITIPOOBA 0xf10 -#define AI_ITIPOOBB 0xf14 -#define AI_ITIPOOBC 0xf18 -#define AI_ITIPOOBD 0xf1c -#define AI_ITIPOOBAOUT 0xf30 -#define AI_ITIPOOBBOUT 0xf34 -#define AI_ITIPOOBCOUT 0xf38 -#define AI_ITIPOOBDOUT 0xf3c -#define AI_ITOPOOBA 0xf50 -#define AI_ITOPOOBB 0xf54 -#define AI_ITOPOOBC 0xf58 -#define AI_ITOPOOBD 0xf5c -#define AI_ITOPOOBAIN 0xf70 -#define AI_ITOPOOBBIN 0xf74 -#define AI_ITOPOOBCIN 0xf78 -#define AI_ITOPOOBDIN 0xf7c -#define AI_ITOPRESET 0xf90 -#define AI_PERIPHERIALID4 0xfd0 -#define AI_PERIPHERIALID5 0xfd4 -#define AI_PERIPHERIALID6 0xfd8 -#define AI_PERIPHERIALID7 0xfdc -#define AI_PERIPHERIALID0 0xfe0 -#define AI_PERIPHERIALID1 0xfe4 -#define AI_PERIPHERIALID2 0xfe8 -#define AI_PERIPHERIALID3 0xfec -#define AI_COMPONENTID0 0xff0 -#define AI_COMPONENTID1 0xff4 -#define AI_COMPONENTID2 0xff8 -#define AI_COMPONENTID3 0xffc - - -#define AIRC_RESET 1 - - -#define AICFG_OOB 0x00000020 -#define AICFG_IOS 0x00000010 -#define AICFG_IOC 0x00000008 -#define AICFG_TO 0x00000004 -#define AICFG_ERRL 0x00000002 -#define AICFG_RST 0x00000001 - - -#define OOB_SEL_OUTEN_B_5 15 -#define OOB_SEL_OUTEN_B_6 23 - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/bcmcdc.h b/drivers/net/wireless/bcmdhd/include/bcmcdc.h deleted file mode 100644 index 77a20f87b7ea..000000000000 --- a/drivers/net/wireless/bcmdhd/include/bcmcdc.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * CDC network driver ioctl/indication encoding - * Broadcom 802.11abg Networking Device Driver - * - * Definitions subject to change without notice. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmcdc.h 277737 2011-08-16 17:54:59Z $ - */ - -#ifndef _bcmcdc_h_ -#define _bcmcdc_h_ -#include - -typedef struct cdc_ioctl { - uint32 cmd; - uint32 len; - uint32 flags; - uint32 status; -} cdc_ioctl_t; - - -#define CDC_MAX_MSG_SIZE ETHER_MAX_LEN - - -#define CDCL_IOC_OUTLEN_MASK 0x0000FFFF - -#define CDCL_IOC_OUTLEN_SHIFT 0 -#define CDCL_IOC_INLEN_MASK 0xFFFF0000 -#define CDCL_IOC_INLEN_SHIFT 16 - - -#define CDCF_IOC_ERROR 0x01 -#define CDCF_IOC_SET 0x02 -#define CDCF_IOC_OVL_IDX_MASK 0x3c -#define CDCF_IOC_OVL_RSV 0x40 -#define CDCF_IOC_OVL 0x80 -#define CDCF_IOC_ACTION_MASK 0xfe -#define CDCF_IOC_ACTION_SHIFT 1 -#define CDCF_IOC_IF_MASK 0xF000 -#define CDCF_IOC_IF_SHIFT 12 -#define CDCF_IOC_ID_MASK 0xFFFF0000 -#define CDCF_IOC_ID_SHIFT 16 - -#define CDC_IOC_IF_IDX(flags) (((flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT) -#define CDC_IOC_ID(flags) (((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT) - -#define CDC_GET_IF_IDX(hdr) \ - ((int)((((hdr)->flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT)) -#define CDC_SET_IF_IDX(hdr, idx) \ - ((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | ((idx) << CDCF_IOC_IF_SHIFT))) - - - -#define BDC_HEADER_LEN 4 - -#define BDC_PROTO_VER_1 1 -#define BDC_PROTO_VER 2 - -#define BDC_FLAG_VER_MASK 0xf0 -#define BDC_FLAG_VER_SHIFT 4 - -#define BDC_FLAG__UNUSED 0x03 -#define BDC_FLAG_SUM_GOOD 0x04 -#define BDC_FLAG_SUM_NEEDED 0x08 - -#define BDC_PRIORITY_MASK 0x7 - -#define BDC_FLAG2_FC_FLAG 0x10 - -#define BDC_PRIORITY_FC_SHIFT 4 - -#define BDC_FLAG2_IF_MASK 0x0f -#define BDC_FLAG2_IF_SHIFT 0 -#define BDC_FLAG2_PAD_MASK 0xf0 -#define BDC_FLAG_PAD_MASK 0x03 -#define BDC_FLAG2_PAD_SHIFT 2 -#define BDC_FLAG_PAD_SHIFT 0 -#define BDC_FLAG2_PAD_IDX 0x3c -#define BDC_FLAG_PAD_IDX 0x03 -#define BDC_GET_PAD_LEN(hdr) \ - ((int)(((((hdr)->flags2) & BDC_FLAG2_PAD_MASK) >> BDC_FLAG2_PAD_SHIFT) | \ - ((((hdr)->flags) & BDC_FLAG_PAD_MASK) >> BDC_FLAG_PAD_SHIFT))) -#define BDC_SET_PAD_LEN(hdr, idx) \ - ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_PAD_MASK) | \ - (((idx) & BDC_FLAG2_PAD_IDX) << BDC_FLAG2_PAD_SHIFT))); \ - ((hdr)->flags = (((hdr)->flags & ~BDC_FLAG_PAD_MASK) | \ - (((idx) & BDC_FLAG_PAD_IDX) << BDC_FLAG_PAD_SHIFT))) - -#define BDC_GET_IF_IDX(hdr) \ - ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT)) -#define BDC_SET_IF_IDX(hdr, idx) \ - ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | ((idx) << BDC_FLAG2_IF_SHIFT))) - -struct bdc_header { - uint8 flags; - uint8 priority; - uint8 flags2; - uint8 dataOffset; -}; - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/bcmdefs.h b/drivers/net/wireless/bcmdhd/include/bcmdefs.h deleted file mode 100644 index 17cc0e955f62..000000000000 --- a/drivers/net/wireless/bcmdhd/include/bcmdefs.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Misc system wide definitions - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmdefs.h 279282 2011-08-23 22:44:02Z $ - */ - - -#ifndef _bcmdefs_h_ -#define _bcmdefs_h_ - - - - -#define BCM_REFERENCE(data) ((void)(data)) - - - -#define bcmreclaimed 0 -#define _data _data -#define _fn _fn -#define BCMPREATTACHDATA(_data) _data -#define BCMPREATTACHFN(_fn) _fn -#define _data _data -#define _fn _fn -#define _fn _fn -#define BCMNMIATTACHFN(_fn) _fn -#define BCMNMIATTACHDATA(_data) _data -#define BCMOVERLAY0DATA(_sym) _sym -#define BCMOVERLAY0FN(_fn) _fn -#define BCMOVERLAY1DATA(_sym) _sym -#define BCMOVERLAY1FN(_fn) _fn -#define BCMOVERLAYERRFN(_fn) _fn -#define CONST const -#define BCMFASTPATH - - - - -#define _data _data -#define BCMROMDAT_NAME(_data) _data -#define _fn _fn -#define _fn _fn -#define STATIC static -#define BCMROMDAT_ARYSIZ(data) ARRAYSIZE(data) -#define BCMROMDAT_SIZEOF(data) sizeof(data) -#define BCMROMDAT_APATCH(data) -#define BCMROMDAT_SPATCH(data) - - - -#define OVERLAY_INLINE -#define OSTATIC static -#define BCMOVERLAYDATA(_ovly, _sym) _sym -#define BCMOVERLAYFN(_ovly, _fn) _fn -#define BCMOVERLAYERRFN(_fn) _fn -#define BCMROMOVERLAYDATA(_ovly, _data) _data -#define BCMROMOVERLAYFN(_ovly, _fn) _fn -#define BCMATTACHOVERLAYDATA(_ovly, _sym) _sym -#define BCMATTACHOVERLAYFN(_ovly, _fn) _fn -#define BCMINITOVERLAYDATA(_ovly, _sym) _sym -#define BCMINITOVERLAYFN(_ovly, _fn) _fn -#define BCMUNINITOVERLAYFN(_ovly, _fn) _fn - - - -#define SI_BUS 0 -#define PCI_BUS 1 -#define PCMCIA_BUS 2 -#define SDIO_BUS 3 -#define JTAG_BUS 4 -#define USB_BUS 5 -#define SPI_BUS 6 -#define RPC_BUS 7 - - -#ifdef BCMBUSTYPE -#define BUSTYPE(bus) (BCMBUSTYPE) -#else -#define BUSTYPE(bus) (bus) -#endif - - -#ifdef BCMCHIPTYPE -#define CHIPTYPE(bus) (BCMCHIPTYPE) -#else -#define CHIPTYPE(bus) (bus) -#endif - - - -#if defined(BCMSPROMBUS) -#define SPROMBUS (BCMSPROMBUS) -#elif defined(SI_PCMCIA_SROM) -#define SPROMBUS (PCMCIA_BUS) -#else -#define SPROMBUS (PCI_BUS) -#endif - - -#ifdef BCMCHIPID -#define CHIPID(chip) (BCMCHIPID) -#else -#define CHIPID(chip) (chip) -#endif - -#ifdef BCMCHIPREV -#define CHIPREV(rev) (BCMCHIPREV) -#else -#define CHIPREV(rev) (rev) -#endif - - -#define DMADDR_MASK_32 0x0 -#define DMADDR_MASK_30 0xc0000000 -#define DMADDR_MASK_0 0xffffffff - -#define DMADDRWIDTH_30 30 -#define DMADDRWIDTH_32 32 -#define DMADDRWIDTH_63 63 -#define DMADDRWIDTH_64 64 - -#ifdef BCMDMA64OSL -typedef struct { - uint32 loaddr; - uint32 hiaddr; -} dma64addr_t; - -typedef dma64addr_t dmaaddr_t; -#define PHYSADDRHI(_pa) ((_pa).hiaddr) -#define PHYSADDRHISET(_pa, _val) \ - do { \ - (_pa).hiaddr = (_val); \ - } while (0) -#define PHYSADDRLO(_pa) ((_pa).loaddr) -#define PHYSADDRLOSET(_pa, _val) \ - do { \ - (_pa).loaddr = (_val); \ - } while (0) - -#else -typedef unsigned long dmaaddr_t; -#define PHYSADDRHI(_pa) (0) -#define PHYSADDRHISET(_pa, _val) -#define PHYSADDRLO(_pa) ((_pa)) -#define PHYSADDRLOSET(_pa, _val) \ - do { \ - (_pa) = (_val); \ - } while (0) -#endif - - -typedef struct { - dmaaddr_t addr; - uint32 length; -} hnddma_seg_t; - -#define MAX_DMA_SEGS 4 - - -typedef struct { - void *oshdmah; - uint origsize; - uint nsegs; - hnddma_seg_t segs[MAX_DMA_SEGS]; -} hnddma_seg_map_t; - - - - -#if defined(BCM_RPC_NOCOPY) || defined(BCM_RCP_TXNOCOPY) - -#define BCMEXTRAHDROOM 220 -#else -#define BCMEXTRAHDROOM 172 -#endif - - -#define BCMDONGLEHDRSZ 12 -#define BCMDONGLEPADSZ 16 - -#define BCMDONGLEOVERHEAD (BCMDONGLEHDRSZ + BCMDONGLEPADSZ) - - -#if defined(BCMASSERT_LOG) -#define BCMASSERT_SUPPORT -#endif - - -#define BITFIELD_MASK(width) \ - (((unsigned)1 << (width)) - 1) -#define GFIELD(val, field) \ - (((val) >> field ## _S) & field ## _M) -#define SFIELD(val, field, bits) \ - (((val) & (~(field ## _M << field ## _S))) | \ - ((unsigned)(bits) << field ## _S)) - - -#ifdef BCMSMALL -#undef BCMSPACE -#define bcmspace FALSE -#else -#define BCMSPACE -#define bcmspace TRUE -#endif - - -#define MAXSZ_NVRAM_VARS 4096 - -#define LOCATOR_EXTERN static - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/bcmdevs.h b/drivers/net/wireless/bcmdhd/include/bcmdevs.h deleted file mode 100644 index cdfc5fe6c8fd..000000000000 --- a/drivers/net/wireless/bcmdhd/include/bcmdevs.h +++ /dev/null @@ -1,747 +0,0 @@ -/* - * Broadcom device-specific manifest constants. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmdevs.h 332966 2012-05-11 22:40:21Z $ - */ - - -#ifndef _BCMDEVS_H -#define _BCMDEVS_H - - -#define VENDOR_EPIGRAM 0xfeda -#define VENDOR_BROADCOM 0x14e4 -#define VENDOR_3COM 0x10b7 -#define VENDOR_NETGEAR 0x1385 -#define VENDOR_DIAMOND 0x1092 -#define VENDOR_INTEL 0x8086 -#define VENDOR_DELL 0x1028 -#define VENDOR_HP 0x103c -#define VENDOR_HP_COMPAQ 0x0e11 -#define VENDOR_APPLE 0x106b -#define VENDOR_SI_IMAGE 0x1095 -#define VENDOR_BUFFALO 0x1154 -#define VENDOR_TI 0x104c -#define VENDOR_RICOH 0x1180 -#define VENDOR_JMICRON 0x197b - - - -#define VENDOR_BROADCOM_PCMCIA 0x02d0 - - -#define VENDOR_BROADCOM_SDIO 0x00BF - - -#define BCM_DNGL_VID 0x0a5c -#define BCM_DNGL_BL_PID_4328 0xbd12 -#define BCM_DNGL_BL_PID_4322 0xbd13 -#define BCM_DNGL_BL_PID_4319 0xbd16 -#define BCM_DNGL_BL_PID_43236 0xbd17 -#define BCM_DNGL_BL_PID_4332 0xbd18 -#define BCM_DNGL_BL_PID_4330 0xbd19 -#define BCM_DNGL_BL_PID_43239 0xbd1b -#define BCM_DNGL_BDC_PID 0x0bdc -#define BCM_DNGL_JTAG_PID 0x4a44 -#define BCM_DNGL_BL_PID_4324 0xbd1c - - -#define BCM_HWUSB_PID_43239 43239 - - -#define BCM4210_DEVICE_ID 0x1072 -#define BCM4230_DEVICE_ID 0x1086 -#define BCM4401_ENET_ID 0x170c -#define BCM3352_DEVICE_ID 0x3352 -#define BCM3360_DEVICE_ID 0x3360 -#define BCM4211_DEVICE_ID 0x4211 -#define BCM4231_DEVICE_ID 0x4231 -#define BCM4303_D11B_ID 0x4303 -#define BCM4311_D11G_ID 0x4311 -#define BCM4311_D11DUAL_ID 0x4312 -#define BCM4311_D11A_ID 0x4313 -#define BCM4328_D11DUAL_ID 0x4314 -#define BCM4328_D11G_ID 0x4315 -#define BCM4328_D11A_ID 0x4316 -#define BCM4318_D11G_ID 0x4318 -#define BCM4318_D11DUAL_ID 0x4319 -#define BCM4318_D11A_ID 0x431a -#define BCM4325_D11DUAL_ID 0x431b -#define BCM4325_D11G_ID 0x431c -#define BCM4325_D11A_ID 0x431d -#define BCM4306_D11G_ID 0x4320 -#define BCM4306_D11A_ID 0x4321 -#define BCM4306_UART_ID 0x4322 -#define BCM4306_V90_ID 0x4323 -#define BCM4306_D11DUAL_ID 0x4324 -#define BCM4306_D11G_ID2 0x4325 -#define BCM4321_D11N_ID 0x4328 -#define BCM4321_D11N2G_ID 0x4329 -#define BCM4321_D11N5G_ID 0x432a -#define BCM4322_D11N_ID 0x432b -#define BCM4322_D11N2G_ID 0x432c -#define BCM4322_D11N5G_ID 0x432d -#define BCM4329_D11N_ID 0x432e -#define BCM4329_D11N2G_ID 0x432f -#define BCM4329_D11N5G_ID 0x4330 -#define BCM4315_D11DUAL_ID 0x4334 -#define BCM4315_D11G_ID 0x4335 -#define BCM4315_D11A_ID 0x4336 -#define BCM4319_D11N_ID 0x4337 -#define BCM4319_D11N2G_ID 0x4338 -#define BCM4319_D11N5G_ID 0x4339 -#define BCM43231_D11N2G_ID 0x4340 -#define BCM43221_D11N2G_ID 0x4341 -#define BCM43222_D11N_ID 0x4350 -#define BCM43222_D11N2G_ID 0x4351 -#define BCM43222_D11N5G_ID 0x4352 -#define BCM43224_D11N_ID 0x4353 -#define BCM43224_D11N_ID_VEN1 0x0576 -#define BCM43226_D11N_ID 0x4354 -#define BCM43236_D11N_ID 0x4346 -#define BCM43236_D11N2G_ID 0x4347 -#define BCM43236_D11N5G_ID 0x4348 -#define BCM43225_D11N2G_ID 0x4357 -#define BCM43421_D11N_ID 0xA99D -#define BCM4313_D11N2G_ID 0x4727 -#define BCM4330_D11N_ID 0x4360 -#define BCM4330_D11N2G_ID 0x4361 -#define BCM4330_D11N5G_ID 0x4362 -#define BCM4336_D11N_ID 0x4343 -#define BCM6362_D11N_ID 0x435f -#define BCM4331_D11N_ID 0x4331 -#define BCM4331_D11N2G_ID 0x4332 -#define BCM4331_D11N5G_ID 0x4333 -#define BCM43237_D11N_ID 0x4355 -#define BCM43237_D11N5G_ID 0x4356 -#define BCM43227_D11N2G_ID 0x4358 -#define BCM43228_D11N_ID 0x4359 -#define BCM43228_D11N5G_ID 0x435a -#define BCM43362_D11N_ID 0x4363 -#define BCM43239_D11N_ID 0x4370 -#define BCM4324_D11N_ID 0x4374 -#define BCM43217_D11N2G_ID 0x43a9 -#define BCM43131_D11N2G_ID 0x43aa - -#define BCM4314_D11N2G_ID 0x4364 -#define BCM43142_D11N2G_ID 0x4365 - -#define BCMGPRS_UART_ID 0x4333 -#define BCMGPRS2_UART_ID 0x4344 -#define FPGA_JTAGM_ID 0x43f0 -#define BCM_JTAGM_ID 0x43f1 -#define SDIOH_FPGA_ID 0x43f2 -#define BCM_SDIOH_ID 0x43f3 -#define SDIOD_FPGA_ID 0x43f4 -#define SPIH_FPGA_ID 0x43f5 -#define BCM_SPIH_ID 0x43f6 -#define MIMO_FPGA_ID 0x43f8 -#define BCM_JTAGM2_ID 0x43f9 -#define SDHCI_FPGA_ID 0x43fa -#define BCM4402_ENET_ID 0x4402 -#define BCM4402_V90_ID 0x4403 -#define BCM4410_DEVICE_ID 0x4410 -#define BCM4412_DEVICE_ID 0x4412 -#define BCM4430_DEVICE_ID 0x4430 -#define BCM4432_DEVICE_ID 0x4432 -#define BCM4704_ENET_ID 0x4706 -#define BCM4710_DEVICE_ID 0x4710 -#define BCM47XX_AUDIO_ID 0x4711 -#define BCM47XX_V90_ID 0x4712 -#define BCM47XX_ENET_ID 0x4713 -#define BCM47XX_EXT_ID 0x4714 -#define BCM47XX_GMAC_ID 0x4715 -#define BCM47XX_USBH_ID 0x4716 -#define BCM47XX_USBD_ID 0x4717 -#define BCM47XX_IPSEC_ID 0x4718 -#define BCM47XX_ROBO_ID 0x4719 -#define BCM47XX_USB20H_ID 0x471a -#define BCM47XX_USB20D_ID 0x471b -#define BCM47XX_ATA100_ID 0x471d -#define BCM47XX_SATAXOR_ID 0x471e -#define BCM47XX_GIGETH_ID 0x471f -#define BCM4712_MIPS_ID 0x4720 -#define BCM4716_DEVICE_ID 0x4722 -#define BCM47XX_SMBUS_EMU_ID 0x47fe -#define BCM47XX_XOR_EMU_ID 0x47ff -#define EPI41210_DEVICE_ID 0xa0fa -#define EPI41230_DEVICE_ID 0xa10e -#define JINVANI_SDIOH_ID 0x4743 -#define BCM27XX_SDIOH_ID 0x2702 -#define PCIXX21_FLASHMEDIA_ID 0x803b -#define PCIXX21_SDIOH_ID 0x803c -#define R5C822_SDIOH_ID 0x0822 -#define JMICRON_SDIOH_ID 0x2381 - - -#define BCM4306_CHIP_ID 0x4306 -#define BCM4311_CHIP_ID 0x4311 -#define BCM43111_CHIP_ID 43111 -#define BCM43112_CHIP_ID 43112 -#define BCM4312_CHIP_ID 0x4312 -#define BCM4313_CHIP_ID 0x4313 -#define BCM43131_CHIP_ID 43131 -#define BCM4315_CHIP_ID 0x4315 -#define BCM4318_CHIP_ID 0x4318 -#define BCM4319_CHIP_ID 0x4319 -#define BCM4320_CHIP_ID 0x4320 -#define BCM4321_CHIP_ID 0x4321 -#define BCM43217_CHIP_ID 43217 -#define BCM4322_CHIP_ID 0x4322 -#define BCM43221_CHIP_ID 43221 -#define BCM43222_CHIP_ID 43222 -#define BCM43224_CHIP_ID 43224 -#define BCM43225_CHIP_ID 43225 -#define BCM43227_CHIP_ID 43227 -#define BCM43228_CHIP_ID 43228 -#define BCM43226_CHIP_ID 43226 -#define BCM43231_CHIP_ID 43231 -#define BCM43234_CHIP_ID 43234 -#define BCM43235_CHIP_ID 43235 -#define BCM43236_CHIP_ID 43236 -#define BCM43237_CHIP_ID 43237 -#define BCM43238_CHIP_ID 43238 -#define BCM43239_CHIP_ID 43239 -#define BCM43420_CHIP_ID 43420 -#define BCM43421_CHIP_ID 43421 -#define BCM43428_CHIP_ID 43428 -#define BCM43431_CHIP_ID 43431 -#define BCM4325_CHIP_ID 0x4325 -#define BCM4328_CHIP_ID 0x4328 -#define BCM4329_CHIP_ID 0x4329 -#define BCM4331_CHIP_ID 0x4331 -#define BCM4336_CHIP_ID 0x4336 -#define BCM43362_CHIP_ID 43362 -#define BCM4330_CHIP_ID 0x4330 -#define BCM6362_CHIP_ID 0x6362 -#define BCM4314_CHIP_ID 0x4314 -#define BCM43142_CHIP_ID 43142 -#define BCM4324_CHIP_ID 0x4324 - -#define BCM4342_CHIP_ID 4342 -#define BCM4402_CHIP_ID 0x4402 -#define BCM4704_CHIP_ID 0x4704 -#define BCM4710_CHIP_ID 0x4710 -#define BCM4712_CHIP_ID 0x4712 -#define BCM4716_CHIP_ID 0x4716 -#define BCM47162_CHIP_ID 47162 -#define BCM4748_CHIP_ID 0x4748 -#define BCM4749_CHIP_ID 0x4749 -#define BCM4785_CHIP_ID 0x4785 -#define BCM5350_CHIP_ID 0x5350 -#define BCM5352_CHIP_ID 0x5352 -#define BCM5354_CHIP_ID 0x5354 -#define BCM5365_CHIP_ID 0x5365 -#define BCM5356_CHIP_ID 0x5356 -#define BCM5357_CHIP_ID 0x5357 -#define BCM53572_CHIP_ID 53572 - - -#define BCM4303_PKG_ID 2 -#define BCM4309_PKG_ID 1 -#define BCM4712LARGE_PKG_ID 0 -#define BCM4712SMALL_PKG_ID 1 -#define BCM4712MID_PKG_ID 2 -#define BCM4328USBD11G_PKG_ID 2 -#define BCM4328USBDUAL_PKG_ID 3 -#define BCM4328SDIOD11G_PKG_ID 4 -#define BCM4328SDIODUAL_PKG_ID 5 -#define BCM4329_289PIN_PKG_ID 0 -#define BCM4329_182PIN_PKG_ID 1 -#define BCM5354E_PKG_ID 1 -#define BCM4716_PKG_ID 8 -#define BCM4717_PKG_ID 9 -#define BCM4718_PKG_ID 10 -#define BCM5356_PKG_NONMODE 1 -#define BCM5358U_PKG_ID 8 -#define BCM5358_PKG_ID 9 -#define BCM47186_PKG_ID 10 -#define BCM5357_PKG_ID 11 -#define BCM5356U_PKG_ID 12 -#define BCM53572_PKG_ID 8 -#define BCM47188_PKG_ID 9 -#define BCM4331TT_PKG_ID 8 -#define BCM4331TN_PKG_ID 9 -#define BCM4331TNA0_PKG_ID 0xb - - -#define HDLSIM5350_PKG_ID 1 -#define HDLSIM_PKG_ID 14 -#define HWSIM_PKG_ID 15 -#define BCM43224_FAB_CSM 0x8 -#define BCM43224_FAB_SMIC 0xa -#define BCM4336_WLBGA_PKG_ID 0x8 -#define BCM4330_WLBGA_PKG_ID 0x0 -#define BCM4314PCIE_ARM_PKG_ID (8 | 0) -#define BCM4314SDIO_PKG_ID (8 | 1) -#define BCM4314PCIE_PKG_ID (8 | 2) -#define BCM4314SDIO_ARM_PKG_ID (8 | 3) -#define BCM4314SDIO_FPBGA_PKG_ID (8 | 4) -#define BCM4314DEV_PKG_ID (8 | 6) - -#define PCIXX21_FLASHMEDIA0_ID 0x8033 -#define PCIXX21_SDIOH0_ID 0x8034 - - -#define BFL_BTC2WIRE 0x00000001 -#define BFL_BTCOEX 0x00000001 -#define BFL_PACTRL 0x00000002 -#define BFL_AIRLINEMODE 0x00000004 -#define BFL_ADCDIV 0x00000008 -#define BFL_ENETROBO 0x00000010 -#define BFL_NOPLLDOWN 0x00000020 -#define BFL_CCKHIPWR 0x00000040 -#define BFL_ENETADM 0x00000080 -#define BFL_ENETVLAN 0x00000100 -#ifdef WLAFTERBURNER -#define BFL_AFTERBURNER 0x00000200 -#endif -#define BFL_NOPCI 0x00000400 -#define BFL_FEM 0x00000800 -#define BFL_EXTLNA 0x00001000 -#define BFL_HGPA 0x00002000 -#define BFL_BTC2WIRE_ALTGPIO 0x00004000 -#define BFL_ALTIQ 0x00008000 -#define BFL_NOPA 0x00010000 -#define BFL_RSSIINV 0x00020000 -#define BFL_PAREF 0x00040000 -#define BFL_3TSWITCH 0x00080000 -#define BFL_PHASESHIFT 0x00100000 -#define BFL_BUCKBOOST 0x00200000 -#define BFL_FEM_BT 0x00400000 -#define BFL_NOCBUCK 0x00800000 -#define BFL_CCKFAVOREVM 0x01000000 -#define BFL_PALDO 0x02000000 -#define BFL_LNLDO2_2P5 0x04000000 -#define BFL_FASTPWR 0x08000000 -#define BFL_UCPWRCTL_MININDX 0x08000000 -#define BFL_EXTLNA_5GHz 0x10000000 -#define BFL_TRSW_1by2 0x20000000 -#define BFL_LO_TRSW_R_5GHz 0x40000000 -#define BFL_ELNA_GAINDEF 0x80000000 -#define BFL_EXTLNA_TX 0x20000000 - - -#define BFL2_RXBB_INT_REG_DIS 0x00000001 -#define BFL2_APLL_WAR 0x00000002 -#define BFL2_TXPWRCTRL_EN 0x00000004 -#define BFL2_2X4_DIV 0x00000008 -#define BFL2_5G_PWRGAIN 0x00000010 -#define BFL2_PCIEWAR_OVR 0x00000020 -#define BFL2_CAESERS_BRD 0x00000040 -#define BFL2_BTC3WIRE 0x00000080 -#define BFL2_BTCLEGACY 0x00000080 -#define BFL2_SKWRKFEM_BRD 0x00000100 -#define BFL2_SPUR_WAR 0x00000200 -#define BFL2_GPLL_WAR 0x00000400 -#define BFL2_TRISTATE_LED 0x00000800 -#define BFL2_SINGLEANT_CCK 0x00001000 -#define BFL2_2G_SPUR_WAR 0x00002000 -#define BFL2_BPHY_ALL_TXCORES 0x00004000 -#define BFL2_FCC_BANDEDGE_WAR 0x00008000 -#define BFL2_GPLL_WAR2 0x00010000 -#define BFL2_IPALVLSHIFT_3P3 0x00020000 -#define BFL2_INTERNDET_TXIQCAL 0x00040000 -#define BFL2_XTALBUFOUTEN 0x00080000 -#define BFL2_ANAPACTRL_2G 0x00100000 -#define BFL2_ANAPACTRL_5G 0x00200000 -#define BFL2_ELNACTRL_TRSW_2G 0x00400000 -#define BFL2_BT_SHARE_ANT0 0x00800000 -#define BFL2_TEMPSENSE_HIGHER 0x01000000 -#define BFL2_BTC3WIREONLY 0x02000000 -#define BFL2_PWR_NOMINAL 0x04000000 -#define BFL2_EXTLNA_TX 0x08000000 - -#define BFL2_4313_RADIOREG 0x10000000 -#define BFL2_SECI_LOPWR_DIS 0x20000000 - - - -#define BOARD_GPIO_BTC3W_IN 0x850 -#define BOARD_GPIO_BTC3W_OUT 0x020 -#define BOARD_GPIO_BTCMOD_IN 0x010 -#define BOARD_GPIO_BTCMOD_OUT 0x020 -#define BOARD_GPIO_BTC_IN 0x080 -#define BOARD_GPIO_BTC_OUT 0x100 -#define BOARD_GPIO_PACTRL 0x200 -#define BOARD_GPIO_12 0x1000 -#define BOARD_GPIO_13 0x2000 -#define BOARD_GPIO_BTC4_IN 0x0800 -#define BOARD_GPIO_BTC4_BT 0x2000 -#define BOARD_GPIO_BTC4_STAT 0x4000 -#define BOARD_GPIO_BTC4_WLAN 0x8000 -#define BOARD_GPIO_1_WLAN_PWR 0x2 -#define BOARD_GPIO_4_WLAN_PWR 0x10 - -#define GPIO_BTC4W_OUT_4312 0x010 -#define GPIO_BTC4W_OUT_43224 0x020 -#define GPIO_BTC4W_OUT_43224_SHARED 0x0e0 -#define GPIO_BTC4W_OUT_43225 0x0e0 -#define GPIO_BTC4W_OUT_43421 0x020 -#define GPIO_BTC4W_OUT_4313 0x060 - -#define PCI_CFG_GPIO_SCS 0x10 -#define PCI_CFG_GPIO_HWRAD 0x20 -#define PCI_CFG_GPIO_XTAL 0x40 -#define PCI_CFG_GPIO_PLL 0x80 - - -#define PLL_DELAY 150 -#define FREF_DELAY 200 -#define MIN_SLOW_CLK 32 -#define XTAL_ON_DELAY 1000 - - -#define BU4710_BOARD 0x0400 -#define VSIM4710_BOARD 0x0401 -#define QT4710_BOARD 0x0402 - -#define BU4309_BOARD 0x040a -#define BCM94309CB_BOARD 0x040b -#define BCM94309MP_BOARD 0x040c -#define BCM4309AP_BOARD 0x040d - -#define BCM94302MP_BOARD 0x040e - -#define BU4306_BOARD 0x0416 -#define BCM94306CB_BOARD 0x0417 -#define BCM94306MP_BOARD 0x0418 - -#define BCM94710D_BOARD 0x041a -#define BCM94710R1_BOARD 0x041b -#define BCM94710R4_BOARD 0x041c -#define BCM94710AP_BOARD 0x041d - -#define BU2050_BOARD 0x041f - -#define BCM94306P50_BOARD 0x0420 - -#define BCM94309G_BOARD 0x0421 - -#define BU4704_BOARD 0x0423 -#define BU4702_BOARD 0x0424 - -#define BCM94306PC_BOARD 0x0425 - -#define MPSG4306_BOARD 0x0427 - -#define BCM94702MN_BOARD 0x0428 - - -#define BCM94702CPCI_BOARD 0x0429 - - -#define BCM95380RR_BOARD 0x042a - - -#define BCM94306CBSG_BOARD 0x042b - - -#define PCSG94306_BOARD 0x042d - - -#define BU4704SD_BOARD 0x042e - - -#define BCM94704AGR_BOARD 0x042f - - -#define BCM94308MP_BOARD 0x0430 - - -#define BCM94306GPRS_BOARD 0x0432 - - -#define BU5365_FPGA_BOARD 0x0433 - -#define BU4712_BOARD 0x0444 -#define BU4712SD_BOARD 0x045d -#define BU4712L_BOARD 0x045f - - -#define BCM94712AP_BOARD 0x0445 -#define BCM94712P_BOARD 0x0446 - - -#define BU4318_BOARD 0x0447 -#define CB4318_BOARD 0x0448 -#define MPG4318_BOARD 0x0449 -#define MP4318_BOARD 0x044a -#define SD4318_BOARD 0x044b - - -#define BCM94313BU_BOARD 0x050f -#define BCM94313HM_BOARD 0x0510 -#define BCM94313EPA_BOARD 0x0511 -#define BCM94313HMG_BOARD 0x051C - - -#define BCM96338_BOARD 0x6338 -#define BCM96348_BOARD 0x6348 -#define BCM96358_BOARD 0x6358 -#define BCM96368_BOARD 0x6368 - - -#define BCM94306P_BOARD 0x044c - - -#define BCM94303MP_BOARD 0x044e - - -#define BCM94306MPSGH_BOARD 0x044f - - -#define BCM94306MPM 0x0450 -#define BCM94306MPL 0x0453 - - -#define BCM94712AGR_BOARD 0x0451 - - -#define PC4303_BOARD 0x0454 - - -#define BCM95350K_BOARD 0x0455 - - -#define BCM95350R_BOARD 0x0456 - - -#define BCM94306MPLNA_BOARD 0x0457 - - -#define BU4320_BOARD 0x0458 -#define BU4320S_BOARD 0x0459 -#define BCM94320PH_BOARD 0x045a - - -#define BCM94306MPH_BOARD 0x045b - - -#define BCM94306PCIV_BOARD 0x045c - -#define BU4712SD_BOARD 0x045d - -#define BCM94320PFLSH_BOARD 0x045e - -#define BU4712L_BOARD 0x045f -#define BCM94712LGR_BOARD 0x0460 -#define BCM94320R_BOARD 0x0461 - -#define BU5352_BOARD 0x0462 - -#define BCM94318MPGH_BOARD 0x0463 - -#define BU4311_BOARD 0x0464 -#define BCM94311MC_BOARD 0x0465 -#define BCM94311MCAG_BOARD 0x0466 - -#define BCM95352GR_BOARD 0x0467 - - -#define BCM95351AGR_BOARD 0x0470 - - -#define BCM94704MPCB_BOARD 0x0472 - - -#define BU4785_BOARD 0x0478 - - -#define BU4321_BOARD 0x046b -#define BU4321E_BOARD 0x047c -#define MP4321_BOARD 0x046c -#define CB2_4321_BOARD 0x046d -#define CB2_4321_AG_BOARD 0x0066 -#define MC4321_BOARD 0x046e - - -#define BU4328_BOARD 0x0481 -#define BCM4328SDG_BOARD 0x0482 -#define BCM4328SDAG_BOARD 0x0483 -#define BCM4328UG_BOARD 0x0484 -#define BCM4328UAG_BOARD 0x0485 -#define BCM4328PC_BOARD 0x0486 -#define BCM4328CF_BOARD 0x0487 - - -#define BCM94325DEVBU_BOARD 0x0490 -#define BCM94325BGABU_BOARD 0x0491 - -#define BCM94325SDGWB_BOARD 0x0492 - -#define BCM94325SDGMDL_BOARD 0x04aa -#define BCM94325SDGMDL2_BOARD 0x04c6 -#define BCM94325SDGMDL3_BOARD 0x04c9 - -#define BCM94325SDABGWBA_BOARD 0x04e1 - - -#define BCM94322MC_SSID 0x04a4 -#define BCM94322USB_SSID 0x04a8 -#define BCM94322HM_SSID 0x04b0 -#define BCM94322USB2D_SSID 0x04bf - - -#define BCM4312MCGSG_BOARD 0x04b5 - - -#define BCM94315DEVBU_SSID 0x04c2 -#define BCM94315USBGP_SSID 0x04c7 -#define BCM94315BGABU_SSID 0x04ca -#define BCM94315USBGP41_SSID 0x04cb - - -#define BCM94319DEVBU_SSID 0X04e5 -#define BCM94319USB_SSID 0X04e6 -#define BCM94319SD_SSID 0X04e7 - - -#define BCM94716NR2_SSID 0x04cd - - -#define BCM94319DEVBU_SSID 0X04e5 -#define BCM94319USBNP4L_SSID 0X04e6 -#define BCM94319WLUSBN4L_SSID 0X04e7 -#define BCM94319SDG_SSID 0X04ea -#define BCM94319LCUSBSDN4L_SSID 0X04eb -#define BCM94319USBB_SSID 0x04ee -#define BCM94319LCSDN4L_SSID 0X0507 -#define BCM94319LSUSBN4L_SSID 0X0508 -#define BCM94319SDNA4L_SSID 0X0517 -#define BCM94319SDELNA4L_SSID 0X0518 -#define BCM94319SDELNA6L_SSID 0X0539 -#define BCM94319ARCADYAN_SSID 0X0546 -#define BCM94319WINDSOR_SSID 0x0561 -#define BCM94319MLAP_SSID 0x0562 -#define BCM94319SDNA_SSID 0x058b -#define BCM94319BHEMU3_SSID 0x0563 -#define BCM94319SDHMB_SSID 0x058c -#define BCM94319SDBREF_SSID 0x05a1 -#define BCM94319USBSDB_SSID 0x05a2 - - - -#define BCM94329AGB_SSID 0X04b9 -#define BCM94329TDKMDL1_SSID 0X04ba -#define BCM94329TDKMDL11_SSID 0X04fc -#define BCM94329OLYMPICN18_SSID 0X04fd -#define BCM94329OLYMPICN90_SSID 0X04fe -#define BCM94329OLYMPICN90U_SSID 0X050c -#define BCM94329OLYMPICN90M_SSID 0X050b -#define BCM94329AGBF_SSID 0X04ff -#define BCM94329OLYMPICX17_SSID 0X0504 -#define BCM94329OLYMPICX17M_SSID 0X050a -#define BCM94329OLYMPICX17U_SSID 0X0509 -#define BCM94329OLYMPICUNO_SSID 0X0564 -#define BCM94329MOTOROLA_SSID 0X0565 -#define BCM94329OLYMPICLOCO_SSID 0X0568 - -#define BCM94336SD_WLBGABU_SSID 0x0511 -#define BCM94336SD_WLBGAREF_SSID 0x0519 -#define BCM94336SDGP_SSID 0x0538 -#define BCM94336SDG_SSID 0x0519 -#define BCM94336SDGN_SSID 0x0538 -#define BCM94336SDGFC_SSID 0x056B - - -#define BCM94330SDG_SSID 0x0528 -#define BCM94330SD_FCBGABU_SSID 0x052e -#define BCM94330SD_WLBGABU_SSID 0x052f -#define BCM94330SD_FCBGA_SSID 0x0530 -#define BCM94330FCSDAGB_SSID 0x0532 -#define BCM94330OLYMPICAMG_SSID 0x0549 -#define BCM94330OLYMPICAMGEPA_SSID 0x054F -#define BCM94330OLYMPICUNO3_SSID 0x0551 -#define BCM94330WLSDAGB_SSID 0x0547 -#define BCM94330CSPSDAGBB_SSID 0x054A - - -#define BCM943224X21 0x056e -#define BCM943224X21_FCC 0x00d1 - - -#define BCM943228BU8_SSID 0x0540 -#define BCM943228BU9_SSID 0x0541 -#define BCM943228BU_SSID 0x0542 -#define BCM943227HM4L_SSID 0x0543 -#define BCM943227HMB_SSID 0x0544 -#define BCM943228HM4L_SSID 0x0545 -#define BCM943228SD_SSID 0x0573 - - -#define BCM943239MOD_SSID 0x05ac -#define BCM943239REF_SSID 0x05aa - - -#define BCM94331X19 0x00D6 -#define BCM94331PCIEBT3Ax_SSID 0x00E4 -#define BCM94331X12_2G_SSID 0x00EC -#define BCM94331X12_5G_SSID 0x00ED -#define BCM94331X29B 0x00EF -#define BCM94331BU_SSID 0x0523 -#define BCM94331S9BU_SSID 0x0524 -#define BCM94331MC_SSID 0x0525 -#define BCM94331MCI_SSID 0x0526 -#define BCM94331PCIEBT4_SSID 0x0527 -#define BCM94331HM_SSID 0x0574 -#define BCM94331PCIEDUAL_SSID 0x059B -#define BCM94331MCH5_SSID 0x05A9 -#define BCM94331PCIEDUALV2_SSID 0x05B7 -#define BCM94331CS_SSID 0x05C6 -#define BCM94331CSAX_SSID 0x00EF - - -#define BCM953572BU_SSID 0x058D -#define BCM953572NR2_SSID 0x058E -#define BCM947188NR2_SSID 0x058F -#define BCM953572SDRNR2_SSID 0x0590 - - -#define BCM943236OLYMPICSULLEY_SSID 0x594 -#define BCM943236PREPROTOBLU2O3_SSID 0x5b9 -#define BCM943236USBELNA_SSID 0x5f8 - - -#define GPIO_NUMPINS 32 - - -#define RDL_RAM_BASE_4319 0x60000000 -#define RDL_RAM_BASE_4329 0x60000000 -#define RDL_RAM_SIZE_4319 0x48000 -#define RDL_RAM_SIZE_4329 0x48000 -#define RDL_RAM_SIZE_43236 0x70000 -#define RDL_RAM_BASE_43236 0x60000000 -#define RDL_RAM_SIZE_4328 0x60000 -#define RDL_RAM_BASE_4328 0x80000000 -#define RDL_RAM_SIZE_4322 0x60000 -#define RDL_RAM_BASE_4322 0x60000000 - - -#define MUXENAB_UART 0x00000001 -#define MUXENAB_GPIO 0x00000002 -#define MUXENAB_ERCX 0x00000004 -#define MUXENAB_JTAG 0x00000008 -#define MUXENAB_HOST_WAKE 0x00000010 - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/bcmendian.h b/drivers/net/wireless/bcmdhd/include/bcmendian.h deleted file mode 100644 index f3356a724b44..000000000000 --- a/drivers/net/wireless/bcmdhd/include/bcmendian.h +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Byte order utilities - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmendian.h 277737 2011-08-16 17:54:59Z $ - * - * This file by default provides proper behavior on little-endian architectures. - * On big-endian architectures, IL_BIGENDIAN should be defined. - */ - - -#ifndef _BCMENDIAN_H_ -#define _BCMENDIAN_H_ - -#include - - -#define BCMSWAP16(val) \ - ((uint16)((((uint16)(val) & (uint16)0x00ffU) << 8) | \ - (((uint16)(val) & (uint16)0xff00U) >> 8))) - - -#define BCMSWAP32(val) \ - ((uint32)((((uint32)(val) & (uint32)0x000000ffU) << 24) | \ - (((uint32)(val) & (uint32)0x0000ff00U) << 8) | \ - (((uint32)(val) & (uint32)0x00ff0000U) >> 8) | \ - (((uint32)(val) & (uint32)0xff000000U) >> 24))) - - -#define BCMSWAP32BY16(val) \ - ((uint32)((((uint32)(val) & (uint32)0x0000ffffU) << 16) | \ - (((uint32)(val) & (uint32)0xffff0000U) >> 16))) - - -#ifndef hton16 -#define HTON16(i) BCMSWAP16(i) -#define hton16(i) bcmswap16(i) -#define HTON32(i) BCMSWAP32(i) -#define hton32(i) bcmswap32(i) -#define NTOH16(i) BCMSWAP16(i) -#define ntoh16(i) bcmswap16(i) -#define NTOH32(i) BCMSWAP32(i) -#define ntoh32(i) bcmswap32(i) -#define LTOH16(i) (i) -#define ltoh16(i) (i) -#define LTOH32(i) (i) -#define ltoh32(i) (i) -#define HTOL16(i) (i) -#define htol16(i) (i) -#define HTOL32(i) (i) -#define htol32(i) (i) -#endif - -#define ltoh16_buf(buf, i) -#define htol16_buf(buf, i) - - -#define load32_ua(a) ltoh32_ua(a) -#define store32_ua(a, v) htol32_ua_store(v, a) -#define load16_ua(a) ltoh16_ua(a) -#define store16_ua(a, v) htol16_ua_store(v, a) - -#define _LTOH16_UA(cp) ((cp)[0] | ((cp)[1] << 8)) -#define _LTOH32_UA(cp) ((cp)[0] | ((cp)[1] << 8) | ((cp)[2] << 16) | ((cp)[3] << 24)) -#define _NTOH16_UA(cp) (((cp)[0] << 8) | (cp)[1]) -#define _NTOH32_UA(cp) (((cp)[0] << 24) | ((cp)[1] << 16) | ((cp)[2] << 8) | (cp)[3]) - -#define ltoh_ua(ptr) \ - (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \ - sizeof(*(ptr)) == sizeof(uint16) ? _LTOH16_UA((const uint8 *)(ptr)) : \ - sizeof(*(ptr)) == sizeof(uint32) ? _LTOH32_UA((const uint8 *)(ptr)) : \ - *(uint8 *)0) - -#define ntoh_ua(ptr) \ - (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \ - sizeof(*(ptr)) == sizeof(uint16) ? _NTOH16_UA((const uint8 *)(ptr)) : \ - sizeof(*(ptr)) == sizeof(uint32) ? _NTOH32_UA((const uint8 *)(ptr)) : \ - *(uint8 *)0) - -#ifdef __GNUC__ - - - -#define bcmswap16(val) ({ \ - uint16 _val = (val); \ - BCMSWAP16(_val); \ -}) - -#define bcmswap32(val) ({ \ - uint32 _val = (val); \ - BCMSWAP32(_val); \ -}) - -#define bcmswap32by16(val) ({ \ - uint32 _val = (val); \ - BCMSWAP32BY16(_val); \ -}) - -#define bcmswap16_buf(buf, len) ({ \ - uint16 *_buf = (uint16 *)(buf); \ - uint _wds = (len) / 2; \ - while (_wds--) { \ - *_buf = bcmswap16(*_buf); \ - _buf++; \ - } \ -}) - -#define htol16_ua_store(val, bytes) ({ \ - uint16 _val = (val); \ - uint8 *_bytes = (uint8 *)(bytes); \ - _bytes[0] = _val & 0xff; \ - _bytes[1] = _val >> 8; \ -}) - -#define htol32_ua_store(val, bytes) ({ \ - uint32 _val = (val); \ - uint8 *_bytes = (uint8 *)(bytes); \ - _bytes[0] = _val & 0xff; \ - _bytes[1] = (_val >> 8) & 0xff; \ - _bytes[2] = (_val >> 16) & 0xff; \ - _bytes[3] = _val >> 24; \ -}) - -#define hton16_ua_store(val, bytes) ({ \ - uint16 _val = (val); \ - uint8 *_bytes = (uint8 *)(bytes); \ - _bytes[0] = _val >> 8; \ - _bytes[1] = _val & 0xff; \ -}) - -#define hton32_ua_store(val, bytes) ({ \ - uint32 _val = (val); \ - uint8 *_bytes = (uint8 *)(bytes); \ - _bytes[0] = _val >> 24; \ - _bytes[1] = (_val >> 16) & 0xff; \ - _bytes[2] = (_val >> 8) & 0xff; \ - _bytes[3] = _val & 0xff; \ -}) - -#define ltoh16_ua(bytes) ({ \ - const uint8 *_bytes = (const uint8 *)(bytes); \ - _LTOH16_UA(_bytes); \ -}) - -#define ltoh32_ua(bytes) ({ \ - const uint8 *_bytes = (const uint8 *)(bytes); \ - _LTOH32_UA(_bytes); \ -}) - -#define ntoh16_ua(bytes) ({ \ - const uint8 *_bytes = (const uint8 *)(bytes); \ - _NTOH16_UA(_bytes); \ -}) - -#define ntoh32_ua(bytes) ({ \ - const uint8 *_bytes = (const uint8 *)(bytes); \ - _NTOH32_UA(_bytes); \ -}) - -#else - - -static INLINE uint16 -bcmswap16(uint16 val) -{ - return BCMSWAP16(val); -} - -static INLINE uint32 -bcmswap32(uint32 val) -{ - return BCMSWAP32(val); -} - -static INLINE uint32 -bcmswap32by16(uint32 val) -{ - return BCMSWAP32BY16(val); -} - - - - -static INLINE void -bcmswap16_buf(uint16 *buf, uint len) -{ - len = len / 2; - - while (len--) { - *buf = bcmswap16(*buf); - buf++; - } -} - - -static INLINE void -htol16_ua_store(uint16 val, uint8 *bytes) -{ - bytes[0] = val & 0xff; - bytes[1] = val >> 8; -} - - -static INLINE void -htol32_ua_store(uint32 val, uint8 *bytes) -{ - bytes[0] = val & 0xff; - bytes[1] = (val >> 8) & 0xff; - bytes[2] = (val >> 16) & 0xff; - bytes[3] = val >> 24; -} - - -static INLINE void -hton16_ua_store(uint16 val, uint8 *bytes) -{ - bytes[0] = val >> 8; - bytes[1] = val & 0xff; -} - - -static INLINE void -hton32_ua_store(uint32 val, uint8 *bytes) -{ - bytes[0] = val >> 24; - bytes[1] = (val >> 16) & 0xff; - bytes[2] = (val >> 8) & 0xff; - bytes[3] = val & 0xff; -} - - -static INLINE uint16 -ltoh16_ua(const void *bytes) -{ - return _LTOH16_UA((const uint8 *)bytes); -} - - -static INLINE uint32 -ltoh32_ua(const void *bytes) -{ - return _LTOH32_UA((const uint8 *)bytes); -} - - -static INLINE uint16 -ntoh16_ua(const void *bytes) -{ - return _NTOH16_UA((const uint8 *)bytes); -} - - -static INLINE uint32 -ntoh32_ua(const void *bytes) -{ - return _NTOH32_UA((const uint8 *)bytes); -} - -#endif -#endif diff --git a/drivers/net/wireless/bcmdhd/include/bcmpcispi.h b/drivers/net/wireless/bcmdhd/include/bcmpcispi.h deleted file mode 100644 index 51e0427e7f60..000000000000 --- a/drivers/net/wireless/bcmdhd/include/bcmpcispi.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Broadcom PCI-SPI Host Controller Register Definitions - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmpcispi.h 277737 2011-08-16 17:54:59Z $ - */ -#ifndef _BCM_PCI_SPI_H -#define _BCM_PCI_SPI_H - -/* cpp contortions to concatenate w/arg prescan */ -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif /* PAD */ - - -typedef volatile struct { - uint32 spih_ctrl; /* 0x00 SPI Control Register */ - uint32 spih_stat; /* 0x04 SPI Status Register */ - uint32 spih_data; /* 0x08 SPI Data Register, 32-bits wide */ - uint32 spih_ext; /* 0x0C SPI Extension Register */ - uint32 PAD[4]; /* 0x10-0x1F PADDING */ - - uint32 spih_gpio_ctrl; /* 0x20 SPI GPIO Control Register */ - uint32 spih_gpio_data; /* 0x24 SPI GPIO Data Register */ - uint32 PAD[6]; /* 0x28-0x3F PADDING */ - - uint32 spih_int_edge; /* 0x40 SPI Interrupt Edge Register (0=Level, 1=Edge) */ - uint32 spih_int_pol; /* 0x44 SPI Interrupt Polarity Register (0=Active Low, */ - /* 1=Active High) */ - uint32 spih_int_mask; /* 0x48 SPI Interrupt Mask */ - uint32 spih_int_status; /* 0x4C SPI Interrupt Status */ - uint32 PAD[4]; /* 0x50-0x5F PADDING */ - - uint32 spih_hex_disp; /* 0x60 SPI 4-digit hex display value */ - uint32 spih_current_ma; /* 0x64 SPI SD card current consumption in mA */ - uint32 PAD[1]; /* 0x68 PADDING */ - uint32 spih_disp_sel; /* 0x6c SPI 4-digit hex display mode select (1=current) */ - uint32 PAD[4]; /* 0x70-0x7F PADDING */ - uint32 PAD[8]; /* 0x80-0x9F PADDING */ - uint32 PAD[8]; /* 0xA0-0xBF PADDING */ - uint32 spih_pll_ctrl; /* 0xC0 PLL Control Register */ - uint32 spih_pll_status; /* 0xC4 PLL Status Register */ - uint32 spih_xtal_freq; /* 0xC8 External Clock Frequency in units of 10000Hz */ - uint32 spih_clk_count; /* 0xCC External Clock Count Register */ - -} spih_regs_t; - -typedef volatile struct { - uint32 cfg_space[0x40]; /* 0x000-0x0FF PCI Configuration Space (Read Only) */ - uint32 P_IMG_CTRL0; /* 0x100 PCI Image0 Control Register */ - - uint32 P_BA0; /* 0x104 32 R/W PCI Image0 Base Address register */ - uint32 P_AM0; /* 0x108 32 R/W PCI Image0 Address Mask register */ - uint32 P_TA0; /* 0x10C 32 R/W PCI Image0 Translation Address register */ - uint32 P_IMG_CTRL1; /* 0x110 32 R/W PCI Image1 Control register */ - uint32 P_BA1; /* 0x114 32 R/W PCI Image1 Base Address register */ - uint32 P_AM1; /* 0x118 32 R/W PCI Image1 Address Mask register */ - uint32 P_TA1; /* 0x11C 32 R/W PCI Image1 Translation Address register */ - uint32 P_IMG_CTRL2; /* 0x120 32 R/W PCI Image2 Control register */ - uint32 P_BA2; /* 0x124 32 R/W PCI Image2 Base Address register */ - uint32 P_AM2; /* 0x128 32 R/W PCI Image2 Address Mask register */ - uint32 P_TA2; /* 0x12C 32 R/W PCI Image2 Translation Address register */ - uint32 P_IMG_CTRL3; /* 0x130 32 R/W PCI Image3 Control register */ - uint32 P_BA3; /* 0x134 32 R/W PCI Image3 Base Address register */ - uint32 P_AM3; /* 0x138 32 R/W PCI Image3 Address Mask register */ - uint32 P_TA3; /* 0x13C 32 R/W PCI Image3 Translation Address register */ - uint32 P_IMG_CTRL4; /* 0x140 32 R/W PCI Image4 Control register */ - uint32 P_BA4; /* 0x144 32 R/W PCI Image4 Base Address register */ - uint32 P_AM4; /* 0x148 32 R/W PCI Image4 Address Mask register */ - uint32 P_TA4; /* 0x14C 32 R/W PCI Image4 Translation Address register */ - uint32 P_IMG_CTRL5; /* 0x150 32 R/W PCI Image5 Control register */ - uint32 P_BA5; /* 0x154 32 R/W PCI Image5 Base Address register */ - uint32 P_AM5; /* 0x158 32 R/W PCI Image5 Address Mask register */ - uint32 P_TA5; /* 0x15C 32 R/W PCI Image5 Translation Address register */ - uint32 P_ERR_CS; /* 0x160 32 R/W PCI Error Control and Status register */ - uint32 P_ERR_ADDR; /* 0x164 32 R PCI Erroneous Address register */ - uint32 P_ERR_DATA; /* 0x168 32 R PCI Erroneous Data register */ - - uint32 PAD[5]; /* 0x16C-0x17F PADDING */ - - uint32 WB_CONF_SPC_BAR; /* 0x180 32 R WISHBONE Configuration Space Base Address */ - uint32 W_IMG_CTRL1; /* 0x184 32 R/W WISHBONE Image1 Control register */ - uint32 W_BA1; /* 0x188 32 R/W WISHBONE Image1 Base Address register */ - uint32 W_AM1; /* 0x18C 32 R/W WISHBONE Image1 Address Mask register */ - uint32 W_TA1; /* 0x190 32 R/W WISHBONE Image1 Translation Address reg */ - uint32 W_IMG_CTRL2; /* 0x194 32 R/W WISHBONE Image2 Control register */ - uint32 W_BA2; /* 0x198 32 R/W WISHBONE Image2 Base Address register */ - uint32 W_AM2; /* 0x19C 32 R/W WISHBONE Image2 Address Mask register */ - uint32 W_TA2; /* 0x1A0 32 R/W WISHBONE Image2 Translation Address reg */ - uint32 W_IMG_CTRL3; /* 0x1A4 32 R/W WISHBONE Image3 Control register */ - uint32 W_BA3; /* 0x1A8 32 R/W WISHBONE Image3 Base Address register */ - uint32 W_AM3; /* 0x1AC 32 R/W WISHBONE Image3 Address Mask register */ - uint32 W_TA3; /* 0x1B0 32 R/W WISHBONE Image3 Translation Address reg */ - uint32 W_IMG_CTRL4; /* 0x1B4 32 R/W WISHBONE Image4 Control register */ - uint32 W_BA4; /* 0x1B8 32 R/W WISHBONE Image4 Base Address register */ - uint32 W_AM4; /* 0x1BC 32 R/W WISHBONE Image4 Address Mask register */ - uint32 W_TA4; /* 0x1C0 32 R/W WISHBONE Image4 Translation Address reg */ - uint32 W_IMG_CTRL5; /* 0x1C4 32 R/W WISHBONE Image5 Control register */ - uint32 W_BA5; /* 0x1C8 32 R/W WISHBONE Image5 Base Address register */ - uint32 W_AM5; /* 0x1CC 32 R/W WISHBONE Image5 Address Mask register */ - uint32 W_TA5; /* 0x1D0 32 R/W WISHBONE Image5 Translation Address reg */ - uint32 W_ERR_CS; /* 0x1D4 32 R/W WISHBONE Error Control and Status reg */ - uint32 W_ERR_ADDR; /* 0x1D8 32 R WISHBONE Erroneous Address register */ - uint32 W_ERR_DATA; /* 0x1DC 32 R WISHBONE Erroneous Data register */ - uint32 CNF_ADDR; /* 0x1E0 32 R/W Configuration Cycle register */ - uint32 CNF_DATA; /* 0x1E4 32 R/W Configuration Cycle Generation Data reg */ - - uint32 INT_ACK; /* 0x1E8 32 R Interrupt Acknowledge register */ - uint32 ICR; /* 0x1EC 32 R/W Interrupt Control register */ - uint32 ISR; /* 0x1F0 32 R/W Interrupt Status register */ -} spih_pciregs_t; - -/* - * PCI Core interrupt enable and status bit definitions. - */ - -/* PCI Core ICR Register bit definitions */ -#define PCI_INT_PROP_EN (1 << 0) /* Interrupt Propagation Enable */ -#define PCI_WB_ERR_INT_EN (1 << 1) /* Wishbone Error Interrupt Enable */ -#define PCI_PCI_ERR_INT_EN (1 << 2) /* PCI Error Interrupt Enable */ -#define PCI_PAR_ERR_INT_EN (1 << 3) /* Parity Error Interrupt Enable */ -#define PCI_SYS_ERR_INT_EN (1 << 4) /* System Error Interrupt Enable */ -#define PCI_SOFTWARE_RESET (1U << 31) /* Software reset of the PCI Core. */ - - -/* PCI Core ISR Register bit definitions */ -#define PCI_INT_PROP_ST (1 << 0) /* Interrupt Propagation Status */ -#define PCI_WB_ERR_INT_ST (1 << 1) /* Wishbone Error Interrupt Status */ -#define PCI_PCI_ERR_INT_ST (1 << 2) /* PCI Error Interrupt Status */ -#define PCI_PAR_ERR_INT_ST (1 << 3) /* Parity Error Interrupt Status */ -#define PCI_SYS_ERR_INT_ST (1 << 4) /* System Error Interrupt Status */ - - -/* Registers on the Wishbone bus */ -#define SPIH_CTLR_INTR (1 << 0) /* SPI Host Controller Core Interrupt */ -#define SPIH_DEV_INTR (1 << 1) /* SPI Device Interrupt */ -#define SPIH_WFIFO_INTR (1 << 2) /* SPI Tx FIFO Empty Intr (FPGA Rev >= 8) */ - -/* GPIO Bit definitions */ -#define SPIH_CS (1 << 0) /* SPI Chip Select (active low) */ -#define SPIH_SLOT_POWER (1 << 1) /* SD Card Slot Power Enable */ -#define SPIH_CARD_DETECT (1 << 2) /* SD Card Detect */ - -/* SPI Status Register Bit definitions */ -#define SPIH_STATE_MASK 0x30 /* SPI Transfer State Machine state mask */ -#define SPIH_STATE_SHIFT 4 /* SPI Transfer State Machine state shift */ -#define SPIH_WFFULL (1 << 3) /* SPI Write FIFO Full */ -#define SPIH_WFEMPTY (1 << 2) /* SPI Write FIFO Empty */ -#define SPIH_RFFULL (1 << 1) /* SPI Read FIFO Full */ -#define SPIH_RFEMPTY (1 << 0) /* SPI Read FIFO Empty */ - -#define SPIH_EXT_CLK (1U << 31) /* Use External Clock as PLL Clock source. */ - -#define SPIH_PLL_NO_CLK (1 << 1) /* Set to 1 if the PLL's input clock is lost. */ -#define SPIH_PLL_LOCKED (1 << 3) /* Set to 1 when the PLL is locked. */ - -/* Spin bit loop bound check */ -#define SPI_SPIN_BOUND 0xf4240 /* 1 million */ - -#endif /* _BCM_PCI_SPI_H */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmperf.h b/drivers/net/wireless/bcmdhd/include/bcmperf.h deleted file mode 100644 index a503edbd6226..000000000000 --- a/drivers/net/wireless/bcmdhd/include/bcmperf.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Performance counters software interface. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmperf.h 277737 2011-08-16 17:54:59Z $ - */ -/* essai */ -#ifndef _BCMPERF_H_ -#define _BCMPERF_H_ -/* get cache hits and misses */ -#define BCMPERF_ENABLE_INSTRCOUNT() -#define BCMPERF_ENABLE_ICACHE_MISS() -#define BCMPERF_ENABLE_ICACHE_HIT() -#define BCMPERF_GETICACHE_MISS(x) ((x) = 0) -#define BCMPERF_GETICACHE_HIT(x) ((x) = 0) -#define BCMPERF_GETINSTRCOUNT(x) ((x) = 0) -#endif /* _BCMPERF_H_ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdbus.h b/drivers/net/wireless/bcmdhd/include/bcmsdbus.h deleted file mode 100644 index 21a58b473e91..000000000000 --- a/drivers/net/wireless/bcmdhd/include/bcmsdbus.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Definitions for API from sdio common code (bcmsdh) to individual - * host controller drivers. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdbus.h 300017 2011-12-01 20:30:27Z $ - */ - -#ifndef _sdio_api_h_ -#define _sdio_api_h_ - - -#define SDIOH_API_RC_SUCCESS (0x00) -#define SDIOH_API_RC_FAIL (0x01) -#define SDIOH_API_SUCCESS(status) (status == 0) - -#define SDIOH_READ 0 /* Read request */ -#define SDIOH_WRITE 1 /* Write request */ - -#define SDIOH_DATA_FIX 0 /* Fixed addressing */ -#define SDIOH_DATA_INC 1 /* Incremental addressing */ - -#define SDIOH_CMD_TYPE_NORMAL 0 /* Normal command */ -#define SDIOH_CMD_TYPE_APPEND 1 /* Append command */ -#define SDIOH_CMD_TYPE_CUTTHRU 2 /* Cut-through command */ - -#define SDIOH_DATA_PIO 0 /* PIO mode */ -#define SDIOH_DATA_DMA 1 /* DMA mode */ - - -typedef int SDIOH_API_RC; - -/* SDio Host structure */ -typedef struct sdioh_info sdioh_info_t; - -/* callback function, taking one arg */ -typedef void (*sdioh_cb_fn_t)(void *); - -/* attach, return handler on success, NULL if failed. - * The handler shall be provided by all subsequent calls. No local cache - * cfghdl points to the starting address of pci device mapped memory - */ -extern sdioh_info_t * sdioh_attach(osl_t *osh, void *cfghdl, uint irq); -extern SDIOH_API_RC sdioh_detach(osl_t *osh, sdioh_info_t *si); -extern SDIOH_API_RC sdioh_interrupt_register(sdioh_info_t *si, sdioh_cb_fn_t fn, void *argh); -extern SDIOH_API_RC sdioh_interrupt_deregister(sdioh_info_t *si); - -/* query whether SD interrupt is enabled or not */ -extern SDIOH_API_RC sdioh_interrupt_query(sdioh_info_t *si, bool *onoff); - -/* enable or disable SD interrupt */ -extern SDIOH_API_RC sdioh_interrupt_set(sdioh_info_t *si, bool enable_disable); - -#if defined(DHD_DEBUG) -extern bool sdioh_interrupt_pending(sdioh_info_t *si); -#endif - -/* read or write one byte using cmd52 */ -extern SDIOH_API_RC sdioh_request_byte(sdioh_info_t *si, uint rw, uint fnc, uint addr, uint8 *byte); - -/* read or write 2/4 bytes using cmd53 */ -extern SDIOH_API_RC sdioh_request_word(sdioh_info_t *si, uint cmd_type, uint rw, uint fnc, - uint addr, uint32 *word, uint nbyte); - -/* read or write any buffer using cmd53 */ -extern SDIOH_API_RC sdioh_request_buffer(sdioh_info_t *si, uint pio_dma, uint fix_inc, - uint rw, uint fnc_num, uint32 addr, uint regwidth, uint32 buflen, uint8 *buffer, - void *pkt); - -/* get cis data */ -extern SDIOH_API_RC sdioh_cis_read(sdioh_info_t *si, uint fuc, uint8 *cis, uint32 length); - -extern SDIOH_API_RC sdioh_cfg_read(sdioh_info_t *si, uint fuc, uint32 addr, uint8 *data); -extern SDIOH_API_RC sdioh_cfg_write(sdioh_info_t *si, uint fuc, uint32 addr, uint8 *data); - -/* query number of io functions */ -extern uint sdioh_query_iofnum(sdioh_info_t *si); - -/* handle iovars */ -extern int sdioh_iovar_op(sdioh_info_t *si, const char *name, - void *params, int plen, void *arg, int len, bool set); - -/* Issue abort to the specified function and clear controller as needed */ -extern int sdioh_abort(sdioh_info_t *si, uint fnc); - -/* Start and Stop SDIO without re-enumerating the SD card. */ -extern int sdioh_start(sdioh_info_t *si, int stage); -extern int sdioh_stop(sdioh_info_t *si); - -/* Wait system lock free */ -extern int sdioh_waitlockfree(sdioh_info_t *si); - -/* Reset and re-initialize the device */ -extern int sdioh_sdio_reset(sdioh_info_t *si); - -/* Helper function */ -void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh); - - - -extern SDIOH_API_RC sdioh_sleep(sdioh_info_t *si, bool enab); - -/* GPIO support */ -extern SDIOH_API_RC sdioh_gpio_init(sdioh_info_t *sd); -extern bool sdioh_gpioin(sdioh_info_t *sd, uint32 gpio); -extern SDIOH_API_RC sdioh_gpioouten(sdioh_info_t *sd, uint32 gpio); -extern SDIOH_API_RC sdioh_gpioout(sdioh_info_t *sd, uint32 gpio, bool enab); - -#endif /* _sdio_api_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdh.h b/drivers/net/wireless/bcmdhd/include/bcmsdh.h deleted file mode 100644 index def3c0269279..000000000000 --- a/drivers/net/wireless/bcmdhd/include/bcmsdh.h +++ /dev/null @@ -1,219 +0,0 @@ -/* - * SDIO host client driver interface of Broadcom HNBU - * export functions to client drivers - * abstract OS and BUS specific details of SDIO - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdh.h 300017 2011-12-01 20:30:27Z $ - */ - -#ifndef _bcmsdh_h_ -#define _bcmsdh_h_ - -#define BCMSDH_ERROR_VAL 0x0001 /* Error */ -#define BCMSDH_INFO_VAL 0x0002 /* Info */ -extern const uint bcmsdh_msglevel; - -#define BCMSDH_ERROR(x) -#define BCMSDH_INFO(x) - -/* forward declarations */ -typedef struct bcmsdh_info bcmsdh_info_t; -typedef void (*bcmsdh_cb_fn_t)(void *); - -/* Attach and build an interface to the underlying SD host driver. - * - Allocates resources (structs, arrays, mem, OS handles, etc) needed by bcmsdh. - * - Returns the bcmsdh handle and virtual address base for register access. - * The returned handle should be used in all subsequent calls, but the bcmsh - * implementation may maintain a single "default" handle (e.g. the first or - * most recent one) to enable single-instance implementations to pass NULL. - */ -extern bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq); - -/* Detach - freeup resources allocated in attach */ -extern int bcmsdh_detach(osl_t *osh, void *sdh); - -/* Query if SD device interrupts are enabled */ -extern bool bcmsdh_intr_query(void *sdh); - -/* Enable/disable SD interrupt */ -extern int bcmsdh_intr_enable(void *sdh); -extern int bcmsdh_intr_disable(void *sdh); - -/* Register/deregister device interrupt handler. */ -extern int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh); -extern int bcmsdh_intr_dereg(void *sdh); - -#if defined(DHD_DEBUG) -/* Query pending interrupt status from the host controller */ -extern bool bcmsdh_intr_pending(void *sdh); -#endif - -#ifdef BCMLXSDMMC -extern int bcmsdh_claim_host_and_lock(void *sdh); -extern int bcmsdh_release_host_and_unlock(void *sdh); -#endif /* BCMLXSDMMC */ - -/* Register a callback to be called if and when bcmsdh detects - * device removal. No-op in the case of non-removable/hardwired devices. - */ -extern int bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh); - -/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface). - * fn: function number - * addr: unmodified SDIO-space address - * data: data byte to write - * err: pointer to error code (or NULL) - */ -extern uint8 bcmsdh_cfg_read(void *sdh, uint func, uint32 addr, int *err); -extern void bcmsdh_cfg_write(void *sdh, uint func, uint32 addr, uint8 data, int *err); - -/* Read/Write 4bytes from/to cfg space */ -extern uint32 bcmsdh_cfg_read_word(void *sdh, uint fnc_num, uint32 addr, int *err); -extern void bcmsdh_cfg_write_word(void *sdh, uint fnc_num, uint32 addr, uint32 data, int *err); - -/* Read CIS content for specified function. - * fn: function whose CIS is being requested (0 is common CIS) - * cis: pointer to memory location to place results - * length: number of bytes to read - * Internally, this routine uses the values from the cis base regs (0x9-0xB) - * to form an SDIO-space address to read the data from. - */ -extern int bcmsdh_cis_read(void *sdh, uint func, uint8 *cis, uint length); - -/* Synchronous access to device (client) core registers via CMD53 to F1. - * addr: backplane address (i.e. >= regsva from attach) - * size: register width in bytes (2 or 4) - * data: data for register write - */ -extern uint32 bcmsdh_reg_read(void *sdh, uint32 addr, uint size); -extern uint32 bcmsdh_reg_write(void *sdh, uint32 addr, uint size, uint32 data); - -/* Indicate if last reg read/write failed */ -extern bool bcmsdh_regfail(void *sdh); - -/* Buffer transfer to/from device (client) core via cmd53. - * fn: function number - * addr: backplane address (i.e. >= regsva from attach) - * flags: backplane width, address increment, sync/async - * buf: pointer to memory data buffer - * nbytes: number of bytes to transfer to/from buf - * pkt: pointer to packet associated with buf (if any) - * complete: callback function for command completion (async only) - * handle: handle for completion callback (first arg in callback) - * Returns 0 or error code. - * NOTE: Async operation is not currently supported. - */ -typedef void (*bcmsdh_cmplt_fn_t)(void *handle, int status, bool sync_waiting); -extern int bcmsdh_send_buf(void *sdh, uint32 addr, uint fn, uint flags, - uint8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete, void *handle); -extern int bcmsdh_recv_buf(void *sdh, uint32 addr, uint fn, uint flags, - uint8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete, void *handle); - -/* Flags bits */ -#define SDIO_REQ_4BYTE 0x1 /* Four-byte target (backplane) width (vs. two-byte) */ -#define SDIO_REQ_FIXED 0x2 /* Fixed address (FIFO) (vs. incrementing address) */ -#define SDIO_REQ_ASYNC 0x4 /* Async request (vs. sync request) */ - -/* Pending (non-error) return code */ -#define BCME_PENDING 1 - -/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only). - * rw: read or write (0/1) - * addr: direct SDIO address - * buf: pointer to memory data buffer - * nbytes: number of bytes to transfer to/from buf - * Returns 0 or error code. - */ -extern int bcmsdh_rwdata(void *sdh, uint rw, uint32 addr, uint8 *buf, uint nbytes); - -/* Issue an abort to the specified function */ -extern int bcmsdh_abort(void *sdh, uint fn); - -/* Start SDIO Host Controller communication */ -extern int bcmsdh_start(void *sdh, int stage); - -/* Stop SDIO Host Controller communication */ -extern int bcmsdh_stop(void *sdh); - -/* Wait system lock free */ -extern int bcmsdh_waitlockfree(void *sdh); - -/* Returns the "Device ID" of target device on the SDIO bus. */ -extern int bcmsdh_query_device(void *sdh); - -/* Returns the number of IO functions reported by the device */ -extern uint bcmsdh_query_iofnum(void *sdh); - -/* Miscellaneous knob tweaker. */ -extern int bcmsdh_iovar_op(void *sdh, const char *name, - void *params, int plen, void *arg, int len, bool set); - -/* Reset and reinitialize the device */ -extern int bcmsdh_reset(bcmsdh_info_t *sdh); - -/* helper functions */ - -extern void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh); - -/* callback functions */ -typedef struct { - /* attach to device */ - void *(*attach)(uint16 vend_id, uint16 dev_id, uint16 bus, uint16 slot, - uint16 func, uint bustype, void * regsva, osl_t * osh, - void * param); - /* detach from device */ - void (*detach)(void *ch); -} bcmsdh_driver_t; - -/* platform specific/high level functions */ -extern int bcmsdh_register(bcmsdh_driver_t *driver); -extern void bcmsdh_unregister(void); -extern bool bcmsdh_chipmatch(uint16 vendor, uint16 device); -extern void bcmsdh_device_remove(void * sdh); - -#if defined(OOB_INTR_ONLY) -extern int bcmsdh_register_oob_intr(void * dhdp); -extern void bcmsdh_unregister_oob_intr(void); -extern void bcmsdh_oob_intr_set(bool enable); -#endif /* defined(OOB_INTR_ONLY) */ -/* Function to pass device-status bits to DHD. */ -extern uint32 bcmsdh_get_dstatus(void *sdh); - -/* Function to return current window addr */ -extern uint32 bcmsdh_cur_sbwad(void *sdh); - -/* Function to pass chipid and rev to lower layers for controlling pr's */ -extern void bcmsdh_chipinfo(void *sdh, uint32 chip, uint32 chiprev); - - -extern int bcmsdh_sleep(void *sdh, bool enab); - -/* GPIO support */ -extern int bcmsdh_gpio_init(void *sd); -extern bool bcmsdh_gpioin(void *sd, uint32 gpio); -extern int bcmsdh_gpioouten(void *sd, uint32 gpio); -extern int bcmsdh_gpioout(void *sd, uint32 gpio, bool enab); - -#endif /* _bcmsdh_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h b/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h deleted file mode 100644 index db8ea596304c..000000000000 --- a/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdh_sdmmc.h 314048 2012-02-09 20:31:56Z $ - */ - -#ifndef __BCMSDH_SDMMC_H__ -#define __BCMSDH_SDMMC_H__ - -#define sd_err(x) -#define sd_trace(x) -#define sd_info(x) -#define sd_debug(x) -#define sd_data(x) -#define sd_ctrl(x) - -#define sd_sync_dma(sd, read, nbytes) -#define sd_init_dma(sd) -#define sd_ack_intr(sd) -#define sd_wakeup(sd); - -/* Allocate/init/free per-OS private data */ -extern int sdioh_sdmmc_osinit(sdioh_info_t *sd); -extern void sdioh_sdmmc_osfree(sdioh_info_t *sd); - -#define sd_log(x) - -#define SDIOH_ASSERT(exp) \ - do { if (!(exp)) \ - printf("!!!ASSERT fail: file %s lines %d", __FILE__, __LINE__); \ - } while (0) - -#define BLOCK_SIZE_4318 64 -#define BLOCK_SIZE_4328 512 - -/* internal return code */ -#define SUCCESS 0 -#define ERROR 1 - -/* private bus modes */ -#define SDIOH_MODE_SD4 2 -#define CLIENT_INTR 0x100 /* Get rid of this! */ - -struct sdioh_info { - osl_t *osh; /* osh handler */ - bool client_intr_enabled; /* interrupt connnected flag */ - bool intr_handler_valid; /* client driver interrupt handler valid */ - sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ - void *intr_handler_arg; /* argument to call interrupt handler */ - uint16 intmask; /* Current active interrupts */ - void *sdos_info; /* Pointer to per-OS private data */ - - uint irq; /* Client irq */ - int intrcount; /* Client interrupts */ - - bool sd_use_dma; /* DMA on CMD53 */ - bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */ - /* Must be on for sd_multiblock to be effective */ - bool use_client_ints; /* If this is false, make sure to restore */ - int sd_mode; /* SD1/SD4/SPI */ - int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */ - uint8 num_funcs; /* Supported funcs on client */ - uint32 com_cis_ptr; - uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; - -#define SDIOH_SDMMC_MAX_SG_ENTRIES 32 - struct scatterlist sg_list[SDIOH_SDMMC_MAX_SG_ENTRIES]; - bool use_rxchain; -}; - -/************************************************************ - * Internal interfaces: per-port references into bcmsdh_sdmmc.c - */ - -/* Global message bits */ -extern uint sd_msglevel; - -/* OS-independent interrupt handler */ -extern bool check_client_intr(sdioh_info_t *sd); - -/* Core interrupt enable/disable of device interrupts */ -extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd); -extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd); - - -/************************************************************** - * Internal interfaces: bcmsdh_sdmmc.c references to per-port code - */ - -/* Register mapping routines */ -extern uint32 *sdioh_sdmmc_reg_map(osl_t *osh, int32 addr, int size); -extern void sdioh_sdmmc_reg_unmap(osl_t *osh, int32 addr, int size); - -/* Interrupt (de)registration routines */ -extern int sdioh_sdmmc_register_irq(sdioh_info_t *sd, uint irq); -extern void sdioh_sdmmc_free_irq(uint irq, sdioh_info_t *sd); - -typedef struct _BCMSDH_SDMMC_INSTANCE { - sdioh_info_t *sd; - struct sdio_func *func[SDIOD_MAX_IOFUNCS]; -} BCMSDH_SDMMC_INSTANCE, *PBCMSDH_SDMMC_INSTANCE; - -#endif /* __BCMSDH_SDMMC_H__ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h b/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h deleted file mode 100644 index 1b9d39fee8fc..000000000000 --- a/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Broadcom SDIO/PCMCIA - * Software-specific definitions shared between device and host side - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdpcm.h 277737 2011-08-16 17:54:59Z $ - */ - -#ifndef _bcmsdpcm_h_ -#define _bcmsdpcm_h_ - -/* - * Software allocation of To SB Mailbox resources - */ - -/* intstatus bits */ -#define I_SMB_NAK I_SMB_SW0 /* To SB Mailbox Frame NAK */ -#define I_SMB_INT_ACK I_SMB_SW1 /* To SB Mailbox Host Interrupt ACK */ -#define I_SMB_USE_OOB I_SMB_SW2 /* To SB Mailbox Use OOB Wakeup */ -#define I_SMB_DEV_INT I_SMB_SW3 /* To SB Mailbox Miscellaneous Interrupt */ - -#define I_TOSBMAIL (I_SMB_NAK | I_SMB_INT_ACK | I_SMB_USE_OOB | I_SMB_DEV_INT) - -/* tosbmailbox bits corresponding to intstatus bits */ -#define SMB_NAK (1 << 0) /* To SB Mailbox Frame NAK */ -#define SMB_INT_ACK (1 << 1) /* To SB Mailbox Host Interrupt ACK */ -#define SMB_USE_OOB (1 << 2) /* To SB Mailbox Use OOB Wakeup */ -#define SMB_DEV_INT (1 << 3) /* To SB Mailbox Miscellaneous Interrupt */ -#define SMB_MASK 0x0000000f /* To SB Mailbox Mask */ - -/* tosbmailboxdata */ -#define SMB_DATA_VERSION_MASK 0x00ff0000 /* host protocol version (sent with F2 enable) */ -#define SMB_DATA_VERSION_SHIFT 16 /* host protocol version (sent with F2 enable) */ - -/* - * Software allocation of To Host Mailbox resources - */ - -/* intstatus bits */ -#define I_HMB_FC_STATE I_HMB_SW0 /* To Host Mailbox Flow Control State */ -#define I_HMB_FC_CHANGE I_HMB_SW1 /* To Host Mailbox Flow Control State Changed */ -#define I_HMB_FRAME_IND I_HMB_SW2 /* To Host Mailbox Frame Indication */ -#define I_HMB_HOST_INT I_HMB_SW3 /* To Host Mailbox Miscellaneous Interrupt */ - -#define I_TOHOSTMAIL (I_HMB_FC_CHANGE | I_HMB_FRAME_IND | I_HMB_HOST_INT) - -/* tohostmailbox bits corresponding to intstatus bits */ -#define HMB_FC_ON (1 << 0) /* To Host Mailbox Flow Control State */ -#define HMB_FC_CHANGE (1 << 1) /* To Host Mailbox Flow Control State Changed */ -#define HMB_FRAME_IND (1 << 2) /* To Host Mailbox Frame Indication */ -#define HMB_HOST_INT (1 << 3) /* To Host Mailbox Miscellaneous Interrupt */ -#define HMB_MASK 0x0000000f /* To Host Mailbox Mask */ - -/* tohostmailboxdata */ -#define HMB_DATA_NAKHANDLED 0x01 /* we're ready to retransmit NAK'd frame to host */ -#define HMB_DATA_DEVREADY 0x02 /* we're ready to to talk to host after enable */ -#define HMB_DATA_FC 0x04 /* per prio flowcontrol update flag to host */ -#define HMB_DATA_FWREADY 0x08 /* firmware is ready for protocol activity */ -#define HMB_DATA_FWHALT 0x10 /* firmware has halted operation */ - -#define HMB_DATA_FCDATA_MASK 0xff000000 /* per prio flowcontrol data */ -#define HMB_DATA_FCDATA_SHIFT 24 /* per prio flowcontrol data */ - -#define HMB_DATA_VERSION_MASK 0x00ff0000 /* device protocol version (with devready) */ -#define HMB_DATA_VERSION_SHIFT 16 /* device protocol version (with devready) */ - -/* - * Software-defined protocol header - */ - -/* Current protocol version */ -#define SDPCM_PROT_VERSION 4 - -/* SW frame header */ -#define SDPCM_SEQUENCE_MASK 0x000000ff /* Sequence Number Mask */ -#define SDPCM_PACKET_SEQUENCE(p) (((uint8 *)p)[0] & 0xff) /* p starts w/SW Header */ - -#define SDPCM_CHANNEL_MASK 0x00000f00 /* Channel Number Mask */ -#define SDPCM_CHANNEL_SHIFT 8 /* Channel Number Shift */ -#define SDPCM_PACKET_CHANNEL(p) (((uint8 *)p)[1] & 0x0f) /* p starts w/SW Header */ - -#define SDPCM_FLAGS_MASK 0x0000f000 /* Mask of flag bits */ -#define SDPCM_FLAGS_SHIFT 12 /* Flag bits shift */ -#define SDPCM_PACKET_FLAGS(p) ((((uint8 *)p)[1] & 0xf0) >> 4) /* p starts w/SW Header */ - -/* Next Read Len: lookahead length of next frame, in 16-byte units (rounded up) */ -#define SDPCM_NEXTLEN_MASK 0x00ff0000 /* Next Read Len Mask */ -#define SDPCM_NEXTLEN_SHIFT 16 /* Next Read Len Shift */ -#define SDPCM_NEXTLEN_VALUE(p) ((((uint8 *)p)[2] & 0xff) << 4) /* p starts w/SW Header */ -#define SDPCM_NEXTLEN_OFFSET 2 - -/* Data Offset from SOF (HW Tag, SW Tag, Pad) */ -#define SDPCM_DOFFSET_OFFSET 3 /* Data Offset */ -#define SDPCM_DOFFSET_VALUE(p) (((uint8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff) -#define SDPCM_DOFFSET_MASK 0xff000000 -#define SDPCM_DOFFSET_SHIFT 24 - -#define SDPCM_FCMASK_OFFSET 4 /* Flow control */ -#define SDPCM_FCMASK_VALUE(p) (((uint8 *)p)[SDPCM_FCMASK_OFFSET ] & 0xff) -#define SDPCM_WINDOW_OFFSET 5 /* Credit based fc */ -#define SDPCM_WINDOW_VALUE(p) (((uint8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff) -#define SDPCM_VERSION_OFFSET 6 /* Version # */ -#define SDPCM_VERSION_VALUE(p) (((uint8 *)p)[SDPCM_VERSION_OFFSET] & 0xff) -#define SDPCM_UNUSED_OFFSET 7 /* Spare */ -#define SDPCM_UNUSED_VALUE(p) (((uint8 *)p)[SDPCM_UNUSED_OFFSET] & 0xff) - -#define SDPCM_SWHEADER_LEN 8 /* SW header is 64 bits */ - -/* logical channel numbers */ -#define SDPCM_CONTROL_CHANNEL 0 /* Control Request/Response Channel Id */ -#define SDPCM_EVENT_CHANNEL 1 /* Asyc Event Indication Channel Id */ -#define SDPCM_DATA_CHANNEL 2 /* Data Xmit/Recv Channel Id */ -#define SDPCM_GLOM_CHANNEL 3 /* For coalesced packets (superframes) */ -#define SDPCM_TEST_CHANNEL 15 /* Reserved for test/debug packets */ -#define SDPCM_MAX_CHANNEL 15 - -#define SDPCM_SEQUENCE_WRAP 256 /* wrap-around val for eight-bit frame seq number */ - -#define SDPCM_FLAG_RESVD0 0x01 -#define SDPCM_FLAG_RESVD1 0x02 -#define SDPCM_FLAG_GSPI_TXENAB 0x04 -#define SDPCM_FLAG_GLOMDESC 0x08 /* Superframe descriptor mask */ - -/* For GLOM_CHANNEL frames, use a flag to indicate descriptor frame */ -#define SDPCM_GLOMDESC_FLAG (SDPCM_FLAG_GLOMDESC << SDPCM_FLAGS_SHIFT) - -#define SDPCM_GLOMDESC(p) (((uint8 *)p)[1] & 0x80) - -/* For TEST_CHANNEL packets, define another 4-byte header */ -#define SDPCM_TEST_HDRLEN 4 /* Generally: Cmd(1), Ext(1), Len(2); - * Semantics of Ext byte depend on command. - * Len is current or requested frame length, not - * including test header; sent little-endian. - */ -#define SDPCM_TEST_DISCARD 0x01 /* Receiver discards. Ext is a pattern id. */ -#define SDPCM_TEST_ECHOREQ 0x02 /* Echo request. Ext is a pattern id. */ -#define SDPCM_TEST_ECHORSP 0x03 /* Echo response. Ext is a pattern id. */ -#define SDPCM_TEST_BURST 0x04 /* Receiver to send a burst. Ext is a frame count */ -#define SDPCM_TEST_SEND 0x05 /* Receiver sets send mode. Ext is boolean on/off */ - -/* Handy macro for filling in datagen packets with a pattern */ -#define SDPCM_TEST_FILL(byteno, id) ((uint8)(id + byteno)) - -/* - * Software counters (first part matches hardware counters) - */ - -typedef volatile struct { - uint32 cmd52rd; /* Cmd52RdCount, SDIO: cmd52 reads */ - uint32 cmd52wr; /* Cmd52WrCount, SDIO: cmd52 writes */ - uint32 cmd53rd; /* Cmd53RdCount, SDIO: cmd53 reads */ - uint32 cmd53wr; /* Cmd53WrCount, SDIO: cmd53 writes */ - uint32 abort; /* AbortCount, SDIO: aborts */ - uint32 datacrcerror; /* DataCrcErrorCount, SDIO: frames w/CRC error */ - uint32 rdoutofsync; /* RdOutOfSyncCount, SDIO/PCMCIA: Rd Frm out of sync */ - uint32 wroutofsync; /* RdOutOfSyncCount, SDIO/PCMCIA: Wr Frm out of sync */ - uint32 writebusy; /* WriteBusyCount, SDIO: device asserted "busy" */ - uint32 readwait; /* ReadWaitCount, SDIO: no data ready for a read cmd */ - uint32 readterm; /* ReadTermCount, SDIO: read frame termination cmds */ - uint32 writeterm; /* WriteTermCount, SDIO: write frames termination cmds */ - uint32 rxdescuflo; /* receive descriptor underflows */ - uint32 rxfifooflo; /* receive fifo overflows */ - uint32 txfifouflo; /* transmit fifo underflows */ - uint32 runt; /* runt (too short) frames recv'd from bus */ - uint32 badlen; /* frame's rxh len does not match its hw tag len */ - uint32 badcksum; /* frame's hw tag chksum doesn't agree with len value */ - uint32 seqbreak; /* break in sequence # space from one rx frame to the next */ - uint32 rxfcrc; /* frame rx header indicates crc error */ - uint32 rxfwoos; /* frame rx header indicates write out of sync */ - uint32 rxfwft; /* frame rx header indicates write frame termination */ - uint32 rxfabort; /* frame rx header indicates frame aborted */ - uint32 woosint; /* write out of sync interrupt */ - uint32 roosint; /* read out of sync interrupt */ - uint32 rftermint; /* read frame terminate interrupt */ - uint32 wftermint; /* write frame terminate interrupt */ -} sdpcmd_cnt_t; - -/* - * Register Access Macros - */ - -#define SDIODREV_IS(var, val) ((var) == (val)) -#define SDIODREV_GE(var, val) ((var) >= (val)) -#define SDIODREV_GT(var, val) ((var) > (val)) -#define SDIODREV_LT(var, val) ((var) < (val)) -#define SDIODREV_LE(var, val) ((var) <= (val)) - -#define SDIODDMAREG32(h, dir, chnl) \ - ((dir) == DMA_TX ? \ - (void *)(uintptr)&((h)->regs->dma.sdiod32.dma32regs[chnl].xmt) : \ - (void *)(uintptr)&((h)->regs->dma.sdiod32.dma32regs[chnl].rcv)) - -#define SDIODDMAREG64(h, dir, chnl) \ - ((dir) == DMA_TX ? \ - (void *)(uintptr)&((h)->regs->dma.sdiod64.dma64regs[chnl].xmt) : \ - (void *)(uintptr)&((h)->regs->dma.sdiod64.dma64regs[chnl].rcv)) - -#define SDIODDMAREG(h, dir, chnl) \ - (SDIODREV_LT((h)->corerev, 1) ? \ - SDIODDMAREG32((h), (dir), (chnl)) : \ - SDIODDMAREG64((h), (dir), (chnl))) - -#define PCMDDMAREG(h, dir, chnl) \ - ((dir) == DMA_TX ? \ - (void *)(uintptr)&((h)->regs->dma.pcm32.dmaregs.xmt) : \ - (void *)(uintptr)&((h)->regs->dma.pcm32.dmaregs.rcv)) - -#define SDPCMDMAREG(h, dir, chnl, coreid) \ - ((coreid) == SDIOD_CORE_ID ? \ - SDIODDMAREG(h, dir, chnl) : \ - PCMDDMAREG(h, dir, chnl)) - -#define SDIODFIFOREG(h, corerev) \ - (SDIODREV_LT((corerev), 1) ? \ - ((dma32diag_t *)(uintptr)&((h)->regs->dma.sdiod32.dmafifo)) : \ - ((dma32diag_t *)(uintptr)&((h)->regs->dma.sdiod64.dmafifo))) - -#define PCMDFIFOREG(h) \ - ((dma32diag_t *)(uintptr)&((h)->regs->dma.pcm32.dmafifo)) - -#define SDPCMFIFOREG(h, coreid, corerev) \ - ((coreid) == SDIOD_CORE_ID ? \ - SDIODFIFOREG(h, corerev) : \ - PCMDFIFOREG(h)) - -/* - * Shared structure between dongle and the host. - * The structure contains pointers to trap or assert information. - */ -#define SDPCM_SHARED_VERSION 0x0001 -#define SDPCM_SHARED_VERSION_MASK 0x00FF -#define SDPCM_SHARED_ASSERT_BUILT 0x0100 -#define SDPCM_SHARED_ASSERT 0x0200 -#define SDPCM_SHARED_TRAP 0x0400 -#define SDPCM_SHARED_IN_BRPT 0x0800 -#define SDPCM_SHARED_SET_BRPT 0x1000 -#define SDPCM_SHARED_PENDING_BRPT 0x2000 - -typedef struct { - uint32 flags; - uint32 trap_addr; - uint32 assert_exp_addr; - uint32 assert_file_addr; - uint32 assert_line; - uint32 console_addr; /* Address of hndrte_cons_t */ - uint32 msgtrace_addr; - uint32 brpt_addr; -} sdpcm_shared_t; - -extern sdpcm_shared_t sdpcm_shared; - -/* Function can be used to notify host of FW halt */ -extern void sdpcmd_fwhalt(void); - -#endif /* _bcmsdpcm_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdspi.h b/drivers/net/wireless/bcmdhd/include/bcmsdspi.h deleted file mode 100644 index a62bee42b2ba..000000000000 --- a/drivers/net/wireless/bcmdhd/include/bcmsdspi.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * SD-SPI Protocol Conversion - BCMSDH->SPI Translation Layer - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdspi.h 277737 2011-08-16 17:54:59Z $ - */ -#ifndef _BCM_SD_SPI_H -#define _BCM_SD_SPI_H - -/* global msglevel for debug messages - bitvals come from sdiovar.h */ - -#define sd_err(x) -#define sd_trace(x) -#define sd_info(x) -#define sd_debug(x) -#define sd_data(x) -#define sd_ctrl(x) - -#define sd_log(x) - -#define SDIOH_ASSERT(exp) \ - do { if (!(exp)) \ - printf("!!!ASSERT fail: file %s lines %d", __FILE__, __LINE__); \ - } while (0) - -#define BLOCK_SIZE_4318 64 -#define BLOCK_SIZE_4328 512 - -/* internal return code */ -#define SUCCESS 0 -#undef ERROR -#define ERROR 1 - -/* private bus modes */ -#define SDIOH_MODE_SPI 0 - -#define USE_BLOCKMODE 0x2 /* Block mode can be single block or multi */ -#define USE_MULTIBLOCK 0x4 - -struct sdioh_info { - uint cfg_bar; /* pci cfg address for bar */ - uint32 caps; /* cached value of capabilities reg */ - uint bar0; /* BAR0 for PCI Device */ - osl_t *osh; /* osh handler */ - void *controller; /* Pointer to SPI Controller's private data struct */ - - uint lockcount; /* nest count of sdspi_lock() calls */ - bool client_intr_enabled; /* interrupt connnected flag */ - bool intr_handler_valid; /* client driver interrupt handler valid */ - sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ - void *intr_handler_arg; /* argument to call interrupt handler */ - bool initialized; /* card initialized */ - uint32 target_dev; /* Target device ID */ - uint32 intmask; /* Current active interrupts */ - void *sdos_info; /* Pointer to per-OS private data */ - - uint32 controller_type; /* Host controller type */ - uint8 version; /* Host Controller Spec Compliance Version */ - uint irq; /* Client irq */ - uint32 intrcount; /* Client interrupts */ - uint32 local_intrcount; /* Controller interrupts */ - bool host_init_done; /* Controller initted */ - bool card_init_done; /* Client SDIO interface initted */ - bool polled_mode; /* polling for command completion */ - - bool sd_use_dma; /* DMA on CMD53 */ - bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */ - /* Must be on for sd_multiblock to be effective */ - bool use_client_ints; /* If this is false, make sure to restore */ - bool got_hcint; /* Host Controller interrupt. */ - /* polling hack in wl_linux.c:wl_timer() */ - int adapter_slot; /* Maybe dealing with multiple slots/controllers */ - int sd_mode; /* SD1/SD4/SPI */ - int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */ - uint32 data_xfer_count; /* Current register transfer size */ - uint32 cmd53_wr_data; /* Used to pass CMD53 write data */ - uint32 card_response; /* Used to pass back response status byte */ - uint32 card_rsp_data; /* Used to pass back response data word */ - uint16 card_rca; /* Current Address */ - uint8 num_funcs; /* Supported funcs on client */ - uint32 com_cis_ptr; - uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; - void *dma_buf; - ulong dma_phys; - int r_cnt; /* rx count */ - int t_cnt; /* tx_count */ -}; - -/************************************************************ - * Internal interfaces: per-port references into bcmsdspi.c - */ - -/* Global message bits */ -extern uint sd_msglevel; - -/************************************************************** - * Internal interfaces: bcmsdspi.c references to per-port code - */ - -/* Register mapping routines */ -extern uint32 *spi_reg_map(osl_t *osh, uintptr addr, int size); -extern void spi_reg_unmap(osl_t *osh, uintptr addr, int size); - -/* Interrupt (de)registration routines */ -extern int spi_register_irq(sdioh_info_t *sd, uint irq); -extern void spi_free_irq(uint irq, sdioh_info_t *sd); - -/* OS-specific interrupt wrappers (atomic interrupt enable/disable) */ -extern void spi_lock(sdioh_info_t *sd); -extern void spi_unlock(sdioh_info_t *sd); - -/* Allocate/init/free per-OS private data */ -extern int spi_osinit(sdioh_info_t *sd); -extern void spi_osfree(sdioh_info_t *sd); - -#endif /* _BCM_SD_SPI_H */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdstd.h b/drivers/net/wireless/bcmdhd/include/bcmsdstd.h deleted file mode 100644 index c7382540b84f..000000000000 --- a/drivers/net/wireless/bcmdhd/include/bcmsdstd.h +++ /dev/null @@ -1,248 +0,0 @@ -/* - * 'Standard' SDIO HOST CONTROLLER driver - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmsdstd.h 324819 2012-03-30 12:15:19Z $ - */ -#ifndef _BCM_SD_STD_H -#define _BCM_SD_STD_H - -/* global msglevel for debug messages - bitvals come from sdiovar.h */ -#define sd_err(x) do { if (sd_msglevel & SDH_ERROR_VAL) printf x; } while (0) -#define sd_trace(x) -#define sd_info(x) -#define sd_debug(x) -#define sd_data(x) -#define sd_ctrl(x) -#define sd_dma(x) - -#define sd_sync_dma(sd, read, nbytes) -#define sd_init_dma(sd) -#define sd_ack_intr(sd) -#define sd_wakeup(sd); -/* Allocate/init/free per-OS private data */ -extern int sdstd_osinit(sdioh_info_t *sd); -extern void sdstd_osfree(sdioh_info_t *sd); - -#define sd_log(x) - -#define SDIOH_ASSERT(exp) \ - do { if (!(exp)) \ - printf("!!!ASSERT fail: file %s lines %d", __FILE__, __LINE__); \ - } while (0) - -#define BLOCK_SIZE_4318 64 -#define BLOCK_SIZE_4328 512 - -/* internal return code */ -#define SUCCESS 0 -#define ERROR 1 - -/* private bus modes */ -#define SDIOH_MODE_SPI 0 -#define SDIOH_MODE_SD1 1 -#define SDIOH_MODE_SD4 2 - -#define MAX_SLOTS 6 /* For PCI: Only 6 BAR entries => 6 slots */ -#define SDIOH_REG_WINSZ 0x100 /* Number of registers in Standard Host Controller */ - -#define SDIOH_TYPE_ARASAN_HDK 1 -#define SDIOH_TYPE_BCM27XX 2 -#define SDIOH_TYPE_TI_PCIXX21 4 /* TI PCIxx21 Standard Host Controller */ -#define SDIOH_TYPE_RICOH_R5C822 5 /* Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter */ -#define SDIOH_TYPE_JMICRON 6 /* JMicron Standard SDIO Host Controller */ - -/* For linux, allow yielding for dongle */ -#define BCMSDYIELD - -/* Expected card status value for CMD7 */ -#define SDIOH_CMD7_EXP_STATUS 0x00001E00 - -#define RETRIES_LARGE 100000 -#define sdstd_os_yield(sd) do {} while (0) -#define RETRIES_SMALL 100 - - -#define USE_BLOCKMODE 0x2 /* Block mode can be single block or multi */ -#define USE_MULTIBLOCK 0x4 - -#define USE_FIFO 0x8 /* Fifo vs non-fifo */ - -#define CLIENT_INTR 0x100 /* Get rid of this! */ - -#define HC_INTR_RETUNING 0x1000 - - -struct sdioh_info { - uint cfg_bar; /* pci cfg address for bar */ - uint32 caps; /* cached value of capabilities reg */ - uint32 curr_caps; /* max current capabilities reg */ - - osl_t *osh; /* osh handler */ - volatile char *mem_space; /* pci device memory va */ - uint lockcount; /* nest count of sdstd_lock() calls */ - bool client_intr_enabled; /* interrupt connnected flag */ - bool intr_handler_valid; /* client driver interrupt handler valid */ - sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ - void *intr_handler_arg; /* argument to call interrupt handler */ - bool initialized; /* card initialized */ - uint target_dev; /* Target device ID */ - uint16 intmask; /* Current active interrupts */ - void *sdos_info; /* Pointer to per-OS private data */ - - uint32 controller_type; /* Host controller type */ - uint8 version; /* Host Controller Spec Compliance Version */ - uint irq; /* Client irq */ - int intrcount; /* Client interrupts */ - int local_intrcount; /* Controller interrupts */ - bool host_init_done; /* Controller initted */ - bool card_init_done; /* Client SDIO interface initted */ - bool polled_mode; /* polling for command completion */ - - bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */ - /* Must be on for sd_multiblock to be effective */ - bool use_client_ints; /* If this is false, make sure to restore */ - /* polling hack in wl_linux.c:wl_timer() */ - int adapter_slot; /* Maybe dealing with multiple slots/controllers */ - int sd_mode; /* SD1/SD4/SPI */ - int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */ - uint32 data_xfer_count; /* Current transfer */ - uint16 card_rca; /* Current Address */ - int8 sd_dma_mode; /* DMA Mode (PIO, SDMA, ... ADMA2) on CMD53 */ - uint8 num_funcs; /* Supported funcs on client */ - uint32 com_cis_ptr; - uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; - void *dma_buf; /* DMA Buffer virtual address */ - ulong dma_phys; /* DMA Buffer physical address */ - void *adma2_dscr_buf; /* ADMA2 Descriptor Buffer virtual address */ - ulong adma2_dscr_phys; /* ADMA2 Descriptor Buffer physical address */ - - /* adjustments needed to make the dma align properly */ - void *dma_start_buf; - ulong dma_start_phys; - uint alloced_dma_size; - void *adma2_dscr_start_buf; - ulong adma2_dscr_start_phys; - uint alloced_adma2_dscr_size; - - int r_cnt; /* rx count */ - int t_cnt; /* tx_count */ - bool got_hcint; /* local interrupt flag */ - uint16 last_intrstatus; /* to cache intrstatus */ - int host_UHSISupported; /* whether UHSI is supported for HC. */ - int card_UHSI_voltage_Supported; /* whether UHSI is supported for - * Card in terms of Voltage [1.8 or 3.3]. - */ - int global_UHSI_Supp; /* type of UHSI support in both host and card. - * HOST_SDR_UNSUPP: capabilities not supported/matched - * HOST_SDR_12_25: SDR12 and SDR25 supported - * HOST_SDR_50_104_DDR: one of SDR50/SDR104 or DDR50 supptd - */ - int sd3_dat_state; /* data transfer state used for retuning check */ - int sd3_tun_state; /* tuning state used for retuning check */ - bool sd3_tuning_reqd; /* tuning requirement parameter */ - uint32 caps3; /* cached value of 32 MSbits capabilities reg (SDIO 3.0) */ -}; - -#define DMA_MODE_NONE 0 -#define DMA_MODE_SDMA 1 -#define DMA_MODE_ADMA1 2 -#define DMA_MODE_ADMA2 3 -#define DMA_MODE_ADMA2_64 4 -#define DMA_MODE_AUTO -1 - -#define USE_DMA(sd) ((bool)((sd->sd_dma_mode > 0) ? TRUE : FALSE)) - -/* States for Tuning and corr data */ -#define TUNING_IDLE 0 -#define TUNING_START 1 -#define TUNING_START_AFTER_DAT 2 -#define TUNING_ONGOING 3 - -#define DATA_TRANSFER_IDLE 0 -#define DATA_TRANSFER_ONGOING 1 -#define CHECK_TUNING_PRE_DATA 1 -#define CHECK_TUNING_POST_DATA 2 - - -/************************************************************ - * Internal interfaces: per-port references into bcmsdstd.c - */ - -/* Global message bits */ -extern uint sd_msglevel; - -/* OS-independent interrupt handler */ -extern bool check_client_intr(sdioh_info_t *sd); - -/* Core interrupt enable/disable of device interrupts */ -extern void sdstd_devintr_on(sdioh_info_t *sd); -extern void sdstd_devintr_off(sdioh_info_t *sd); - -/* Enable/disable interrupts for local controller events */ -extern void sdstd_intrs_on(sdioh_info_t *sd, uint16 norm, uint16 err); -extern void sdstd_intrs_off(sdioh_info_t *sd, uint16 norm, uint16 err); - -/* Wait for specified interrupt and error bits to be set */ -extern void sdstd_spinbits(sdioh_info_t *sd, uint16 norm, uint16 err); - - -/************************************************************** - * Internal interfaces: bcmsdstd.c references to per-port code - */ - -/* Register mapping routines */ -extern uint32 *sdstd_reg_map(osl_t *osh, int32 addr, int size); -extern void sdstd_reg_unmap(osl_t *osh, int32 addr, int size); - -/* Interrupt (de)registration routines */ -extern int sdstd_register_irq(sdioh_info_t *sd, uint irq); -extern void sdstd_free_irq(uint irq, sdioh_info_t *sd); - -/* OS-specific interrupt wrappers (atomic interrupt enable/disable) */ -extern void sdstd_lock(sdioh_info_t *sd); -extern void sdstd_unlock(sdioh_info_t *sd); -extern void sdstd_waitlockfree(sdioh_info_t *sd); - -/* OS-specific wait-for-interrupt-or-status */ -extern int sdstd_waitbits(sdioh_info_t *sd, uint16 norm, uint16 err, bool yield, uint16 *bits); - -/* used by bcmsdstd_linux [implemented in sdstd] */ -extern void sdstd_3_enable_retuning_int(sdioh_info_t *sd); -extern void sdstd_3_disable_retuning_int(sdioh_info_t *sd); -extern bool sdstd_3_is_retuning_int_set(sdioh_info_t *sd); -extern void sdstd_3_check_and_do_tuning(sdioh_info_t *sd, int tuning_param); -extern bool sdstd_3_check_and_set_retuning(sdioh_info_t *sd); -extern int sdstd_3_get_tune_state(sdioh_info_t *sd); -extern int sdstd_3_get_data_state(sdioh_info_t *sd); -extern void sdstd_3_set_tune_state(sdioh_info_t *sd, int state); -extern void sdstd_3_set_data_state(sdioh_info_t *sd, int state); -extern uint8 sdstd_3_get_tuning_exp(sdioh_info_t *sd); -extern uint32 sdstd_3_get_uhsi_clkmode(sdioh_info_t *sd); -extern int sdstd_3_clk_tuning(sdioh_info_t *sd, uint32 sd3ClkMode); - -/* used by sdstd [implemented in bcmsdstd_linux/ndis] */ -extern void sdstd_3_start_tuning(sdioh_info_t *sd); -extern void sdstd_3_osinit_tuning(sdioh_info_t *sd); -extern void sdstd_3_osclean_tuning(sdioh_info_t *sd); - -#endif /* _BCM_SD_STD_H */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmspi.h b/drivers/net/wireless/bcmdhd/include/bcmspi.h deleted file mode 100644 index 34a02d00c6bd..000000000000 --- a/drivers/net/wireless/bcmdhd/include/bcmspi.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Broadcom SPI Low-Level Hardware Driver API - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmspi.h 277737 2011-08-16 17:54:59Z $ - */ -#ifndef _BCM_SPI_H -#define _BCM_SPI_H - -extern void spi_devintr_off(sdioh_info_t *sd); -extern void spi_devintr_on(sdioh_info_t *sd); -extern bool spi_start_clock(sdioh_info_t *sd, uint16 new_sd_divisor); -extern bool spi_controller_highspeed_mode(sdioh_info_t *sd, bool hsmode); -extern bool spi_check_client_intr(sdioh_info_t *sd, int *is_dev_intr); -extern bool spi_hw_attach(sdioh_info_t *sd); -extern bool spi_hw_detach(sdioh_info_t *sd); -extern void spi_sendrecv(sdioh_info_t *sd, uint8 *msg_out, uint8 *msg_in, int msglen); -extern void spi_spinbits(sdioh_info_t *sd); -extern void spi_waitbits(sdioh_info_t *sd, bool yield); - -#endif /* _BCM_SPI_H */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmutils.h b/drivers/net/wireless/bcmdhd/include/bcmutils.h deleted file mode 100644 index a570fa2789fb..000000000000 --- a/drivers/net/wireless/bcmdhd/include/bcmutils.h +++ /dev/null @@ -1,722 +0,0 @@ -/* - * Misc useful os-independent macros and functions. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmutils.h 294991 2011-11-09 00:17:28Z $ - */ - - -#ifndef _bcmutils_h_ -#define _bcmutils_h_ - -#define bcm_strcpy_s(dst, noOfElements, src) strcpy((dst), (src)) -#define bcm_strncpy_s(dst, noOfElements, src, count) strncpy((dst), (src), (count)) -#define bcm_strcat_s(dst, noOfElements, src) strcat((dst), (src)) - -#ifdef __cplusplus -extern "C" { -#endif - - -#define _BCM_U 0x01 -#define _BCM_L 0x02 -#define _BCM_D 0x04 -#define _BCM_C 0x08 -#define _BCM_P 0x10 -#define _BCM_S 0x20 -#define _BCM_X 0x40 -#define _BCM_SP 0x80 - -extern const unsigned char bcm_ctype[]; -#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)]) - -#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0) -#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0) -#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0) -#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0) -#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0) -#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0) -#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0) -#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0) -#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0) -#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0) -#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0) -#define bcm_tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c)) -#define bcm_toupper(c) (bcm_islower((c)) ? ((c) + 'A' - 'a') : (c)) - - - -struct bcmstrbuf { - char *buf; - unsigned int size; - char *origbuf; - unsigned int origsize; -}; - - -#ifdef BCMDRIVER -#include - -#define GPIO_PIN_NOTDEFINED 0x20 - - -#define SPINWAIT(exp, us) { \ - uint countdown = (us) + 9; \ - while ((exp) && (countdown >= 10)) {\ - OSL_DELAY(10); \ - countdown -= 10; \ - } \ -} - - -#ifndef PKTQ_LEN_DEFAULT -#define PKTQ_LEN_DEFAULT 128 -#endif -#ifndef PKTQ_MAX_PREC -#define PKTQ_MAX_PREC 16 -#endif - -typedef struct pktq_prec { - void *head; - void *tail; - uint16 len; - uint16 max; -} pktq_prec_t; - - - -struct pktq { - uint16 num_prec; - uint16 hi_prec; - uint16 max; - uint16 len; - - struct pktq_prec q[PKTQ_MAX_PREC]; -}; - - -struct spktq { - uint16 num_prec; - uint16 hi_prec; - uint16 max; - uint16 len; - - struct pktq_prec q[1]; -}; - -#define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--) - - -typedef bool (*ifpkt_cb_t)(void*, int); - -#ifdef BCMPKTPOOL -#define POOL_ENAB(pool) ((pool) && (pool)->inited) -#if defined(BCM4329C0) -#define SHARED_POOL (pktpool_shared_ptr) -#else -#define SHARED_POOL (pktpool_shared) -#endif -#else -#define POOL_ENAB(bus) 0 -#define SHARED_POOL ((struct pktpool *)NULL) -#endif - -#ifndef PKTPOOL_LEN_MAX -#define PKTPOOL_LEN_MAX 40 -#endif -#define PKTPOOL_CB_MAX 3 - -struct pktpool; -typedef void (*pktpool_cb_t)(struct pktpool *pool, void *arg); -typedef struct { - pktpool_cb_t cb; - void *arg; -} pktpool_cbinfo_t; - -#ifdef BCMDBG_POOL - -#define POOL_IDLE 0 -#define POOL_RXFILL 1 -#define POOL_RXDH 2 -#define POOL_RXD11 3 -#define POOL_TXDH 4 -#define POOL_TXD11 5 -#define POOL_AMPDU 6 -#define POOL_TXENQ 7 - -typedef struct { - void *p; - uint32 cycles; - uint32 dur; -} pktpool_dbg_t; - -typedef struct { - uint8 txdh; - uint8 txd11; - uint8 enq; - uint8 rxdh; - uint8 rxd11; - uint8 rxfill; - uint8 idle; -} pktpool_stats_t; -#endif - -typedef struct pktpool { - bool inited; - uint16 r; - uint16 w; - uint16 len; - uint16 maxlen; - uint16 plen; - bool istx; - bool empty; - uint8 cbtoggle; - uint8 cbcnt; - uint8 ecbcnt; - bool emptycb_disable; - pktpool_cbinfo_t cbs[PKTPOOL_CB_MAX]; - pktpool_cbinfo_t ecbs[PKTPOOL_CB_MAX]; - void *q[PKTPOOL_LEN_MAX + 1]; - -#ifdef BCMDBG_POOL - uint8 dbg_cbcnt; - pktpool_cbinfo_t dbg_cbs[PKTPOOL_CB_MAX]; - uint16 dbg_qlen; - pktpool_dbg_t dbg_q[PKTPOOL_LEN_MAX + 1]; -#endif -} pktpool_t; - -#if defined(BCM4329C0) -extern pktpool_t *pktpool_shared_ptr; -#else -extern pktpool_t *pktpool_shared; -#endif - -extern int pktpool_init(osl_t *osh, pktpool_t *pktp, int *pktplen, int plen, bool istx); -extern int pktpool_deinit(osl_t *osh, pktpool_t *pktp); -extern int pktpool_fill(osl_t *osh, pktpool_t *pktp, bool minimal); -extern void* pktpool_get(pktpool_t *pktp); -extern void pktpool_free(pktpool_t *pktp, void *p); -extern int pktpool_add(pktpool_t *pktp, void *p); -extern uint16 pktpool_avail(pktpool_t *pktp); -extern int pktpool_avail_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); -extern int pktpool_empty_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); -extern int pktpool_setmaxlen(pktpool_t *pktp, uint16 maxlen); -extern int pktpool_setmaxlen_strict(osl_t *osh, pktpool_t *pktp, uint16 maxlen); -extern void pktpool_emptycb_disable(pktpool_t *pktp, bool disable); -extern bool pktpool_emptycb_disabled(pktpool_t *pktp); - -#define POOLPTR(pp) ((pktpool_t *)(pp)) -#define pktpool_len(pp) (POOLPTR(pp)->len - 1) -#define pktpool_plen(pp) (POOLPTR(pp)->plen) -#define pktpool_maxlen(pp) (POOLPTR(pp)->maxlen) - -#ifdef BCMDBG_POOL -extern int pktpool_dbg_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); -extern int pktpool_start_trigger(pktpool_t *pktp, void *p); -extern int pktpool_dbg_dump(pktpool_t *pktp); -extern int pktpool_dbg_notify(pktpool_t *pktp); -extern int pktpool_stats_dump(pktpool_t *pktp, pktpool_stats_t *stats); -#endif - - - -struct ether_addr; - -extern int ether_isbcast(const void *ea); -extern int ether_isnulladdr(const void *ea); - - - -#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max)) -#define pktq_plen(pq, prec) ((pq)->q[prec].len) -#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len) -#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max) -#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0) - -#define pktq_ppeek(pq, prec) ((pq)->q[prec].head) -#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail) - -extern void *pktq_penq(struct pktq *pq, int prec, void *p); -extern void *pktq_penq_head(struct pktq *pq, int prec, void *p); -extern void *pktq_pdeq(struct pktq *pq, int prec); -extern void *pktq_pdeq_tail(struct pktq *pq, int prec); - -extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir, - ifpkt_cb_t fn, int arg); - -extern bool pktq_pdel(struct pktq *pq, void *p, int prec); - - - -extern int pktq_mlen(struct pktq *pq, uint prec_bmp); -extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); - - - -#define pktq_len(pq) ((int)(pq)->len) -#define pktq_max(pq) ((int)(pq)->max) -#define pktq_avail(pq) ((int)((pq)->max - (pq)->len)) -#define pktq_full(pq) ((pq)->len >= (pq)->max) -#define pktq_empty(pq) ((pq)->len == 0) - - -#define pktenq(pq, p) pktq_penq(((struct pktq *)pq), 0, (p)) -#define pktenq_head(pq, p) pktq_penq_head(((struct pktq *)pq), 0, (p)) -#define pktdeq(pq) pktq_pdeq(((struct pktq *)pq), 0) -#define pktdeq_tail(pq) pktq_pdeq_tail(((struct pktq *)pq), 0) -#define pktqinit(pq, len) pktq_init(((struct pktq *)pq), 1, len) - -extern void pktq_init(struct pktq *pq, int num_prec, int max_len); - -extern void *pktq_deq(struct pktq *pq, int *prec_out); -extern void *pktq_deq_tail(struct pktq *pq, int *prec_out); -extern void *pktq_peek(struct pktq *pq, int *prec_out); -extern void *pktq_peek_tail(struct pktq *pq, int *prec_out); -extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg); - - - -extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); -extern uint pktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf); -extern uint pkttotlen(osl_t *osh, void *p); -extern void *pktlast(osl_t *osh, void *p); -extern uint pktsegcnt(osl_t *osh, void *p); - - -extern uint pktsetprio(void *pkt, bool update_vtag); -#define PKTPRIO_VDSCP 0x100 -#define PKTPRIO_VLAN 0x200 -#define PKTPRIO_UPD 0x400 -#define PKTPRIO_DSCP 0x800 - - -extern int bcm_atoi(char *s); -extern ulong bcm_strtoul(char *cp, char **endp, uint base); -extern char *bcmstrstr(char *haystack, char *needle); -extern char *bcmstrcat(char *dest, const char *src); -extern char *bcmstrncat(char *dest, const char *src, uint size); -extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen); -char* bcmstrtok(char **string, const char *delimiters, char *tokdelim); -int bcmstricmp(const char *s1, const char *s2); -int bcmstrnicmp(const char* s1, const char* s2, int cnt); - - - -extern char *bcm_ether_ntoa(const struct ether_addr *ea, char *buf); -extern int bcm_ether_atoe(char *p, struct ether_addr *ea); - - -struct ipv4_addr; -extern char *bcm_ip_ntoa(struct ipv4_addr *ia, char *buf); - - -extern void bcm_mdelay(uint ms); - -#define NVRAM_RECLAIM_CHECK(name) - -extern char *getvar(char *vars, const char *name); -extern int getintvar(char *vars, const char *name); -extern int getintvararray(char *vars, const char *name, int index); -extern int getintvararraysize(char *vars, const char *name); -extern uint getgpiopin(char *vars, char *pin_name, uint def_pin); -#define bcm_perf_enable() -#define bcmstats(fmt) -#define bcmlog(fmt, a1, a2) -#define bcmdumplog(buf, size) *buf = '\0' -#define bcmdumplogent(buf, idx) -1 - -#define bcmtslog(tstamp, fmt, a1, a2) -#define bcmprinttslogs() -#define bcmprinttstamp(us) - -extern char *bcm_nvram_vars(uint *length); -extern int bcm_nvram_cache(void *sih); - - - - -typedef struct bcm_iovar { - const char *name; - uint16 varid; - uint16 flags; - uint16 type; - uint16 minlen; -} bcm_iovar_t; - - - - -#define IOV_GET 0 -#define IOV_SET 1 - - -#define IOV_GVAL(id) ((id)*2) -#define IOV_SVAL(id) (((id)*2)+IOV_SET) -#define IOV_ISSET(actionid) ((actionid & IOV_SET) == IOV_SET) -#define IOV_ID(actionid) (actionid >> 1) - - - -extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name); -extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg, int len, bool set); -#if defined(WLTINYDUMP) || defined(WLMSG_INFORM) || defined(WLMSG_ASSOC) || \ - defined(WLMSG_PRPKT) || defined(WLMSG_WSEC) -extern int bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len); -#endif -#endif - - -#define IOVT_VOID 0 -#define IOVT_BOOL 1 -#define IOVT_INT8 2 -#define IOVT_UINT8 3 -#define IOVT_INT16 4 -#define IOVT_UINT16 5 -#define IOVT_INT32 6 -#define IOVT_UINT32 7 -#define IOVT_BUFFER 8 -#define BCM_IOVT_VALID(type) (((unsigned int)(type)) <= IOVT_BUFFER) - - -#define BCM_IOV_TYPE_INIT { \ - "void", \ - "bool", \ - "int8", \ - "uint8", \ - "int16", \ - "uint16", \ - "int32", \ - "uint32", \ - "buffer", \ - "" } - -#define BCM_IOVT_IS_INT(type) (\ - (type == IOVT_BOOL) || \ - (type == IOVT_INT8) || \ - (type == IOVT_UINT8) || \ - (type == IOVT_INT16) || \ - (type == IOVT_UINT16) || \ - (type == IOVT_INT32) || \ - (type == IOVT_UINT32)) - - - -#define BCME_STRLEN 64 -#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST)) - - - - -#define BCME_OK 0 -#define BCME_ERROR -1 -#define BCME_BADARG -2 -#define BCME_BADOPTION -3 -#define BCME_NOTUP -4 -#define BCME_NOTDOWN -5 -#define BCME_NOTAP -6 -#define BCME_NOTSTA -7 -#define BCME_BADKEYIDX -8 -#define BCME_RADIOOFF -9 -#define BCME_NOTBANDLOCKED -10 -#define BCME_NOCLK -11 -#define BCME_BADRATESET -12 -#define BCME_BADBAND -13 -#define BCME_BUFTOOSHORT -14 -#define BCME_BUFTOOLONG -15 -#define BCME_BUSY -16 -#define BCME_NOTASSOCIATED -17 -#define BCME_BADSSIDLEN -18 -#define BCME_OUTOFRANGECHAN -19 -#define BCME_BADCHAN -20 -#define BCME_BADADDR -21 -#define BCME_NORESOURCE -22 -#define BCME_UNSUPPORTED -23 -#define BCME_BADLEN -24 -#define BCME_NOTREADY -25 -#define BCME_EPERM -26 -#define BCME_NOMEM -27 -#define BCME_ASSOCIATED -28 -#define BCME_RANGE -29 -#define BCME_NOTFOUND -30 -#define BCME_WME_NOT_ENABLED -31 -#define BCME_TSPEC_NOTFOUND -32 -#define BCME_ACM_NOTSUPPORTED -33 -#define BCME_NOT_WME_ASSOCIATION -34 -#define BCME_SDIO_ERROR -35 -#define BCME_DONGLE_DOWN -36 -#define BCME_VERSION -37 -#define BCME_TXFAIL -38 -#define BCME_RXFAIL -39 -#define BCME_NODEVICE -40 -#define BCME_NMODE_DISABLED -41 -#define BCME_NONRESIDENT -42 -#define BCME_LAST BCME_NONRESIDENT - - -#define BCMERRSTRINGTABLE { \ - "OK", \ - "Undefined error", \ - "Bad Argument", \ - "Bad Option", \ - "Not up", \ - "Not down", \ - "Not AP", \ - "Not STA", \ - "Bad Key Index", \ - "Radio Off", \ - "Not band locked", \ - "No clock", \ - "Bad Rate valueset", \ - "Bad Band", \ - "Buffer too short", \ - "Buffer too long", \ - "Busy", \ - "Not Associated", \ - "Bad SSID len", \ - "Out of Range Channel", \ - "Bad Channel", \ - "Bad Address", \ - "Not Enough Resources", \ - "Unsupported", \ - "Bad length", \ - "Not Ready", \ - "Not Permitted", \ - "No Memory", \ - "Associated", \ - "Not In Range", \ - "Not Found", \ - "WME Not Enabled", \ - "TSPEC Not Found", \ - "ACM Not Supported", \ - "Not WME Association", \ - "SDIO Bus Error", \ - "Dongle Not Accessible", \ - "Incorrect version", \ - "TX Failure", \ - "RX Failure", \ - "Device Not Present", \ - "NMODE Disabled", \ - "Nonresident overlay access", \ -} - -#ifndef ABS -#define ABS(a) (((a) < 0)?-(a):(a)) -#endif - -#ifndef MIN -#define MIN(a, b) (((a) < (b))?(a):(b)) -#endif - -#ifndef MAX -#define MAX(a, b) (((a) > (b))?(a):(b)) -#endif - -#define CEIL(x, y) (((x) + ((y)-1)) / (y)) -#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) -#define ISALIGNED(a, x) (((uintptr)(a) & ((x)-1)) == 0) -#define ALIGN_ADDR(addr, boundary) (void *)(((uintptr)(addr) + (boundary) - 1) \ - & ~((boundary) - 1)) -#define ISPOWEROF2(x) ((((x)-1)&(x)) == 0) -#define VALID_MASK(mask) !((mask) & ((mask) + 1)) - -#ifndef OFFSETOF -#ifdef __ARMCC_VERSION - -#include -#define OFFSETOF(type, member) offsetof(type, member) -#else -#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member) -#endif -#endif - -#ifndef ARRAYSIZE -#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0])) -#endif - - -extern void *_bcmutils_dummy_fn; -#define REFERENCE_FUNCTION(f) (_bcmutils_dummy_fn = (void *)(f)) - - -#ifndef setbit -#ifndef NBBY -#define NBBY 8 -#endif -#define setbit(a, i) (((uint8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY)) -#define clrbit(a, i) (((uint8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) -#define isset(a, i) (((const uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) -#define isclr(a, i) ((((const uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) -#endif - -#define NBITS(type) (sizeof(type) * 8) -#define NBITVAL(nbits) (1 << (nbits)) -#define MAXBITVAL(nbits) ((1 << (nbits)) - 1) -#define NBITMASK(nbits) MAXBITVAL(nbits) -#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8) - - -#define MUX(pred, true, false) ((pred) ? (true) : (false)) - - -#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1) -#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1) - - -#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1)) -#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1)) - - -#define MODADD(x, y, bound) \ - MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y)) -#define MODSUB(x, y, bound) \ - MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y)) - - -#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1)) -#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1)) - - -#define CRC8_INIT_VALUE 0xff -#define CRC8_GOOD_VALUE 0x9f -#define CRC16_INIT_VALUE 0xffff -#define CRC16_GOOD_VALUE 0xf0b8 -#define CRC32_INIT_VALUE 0xffffffff -#define CRC32_GOOD_VALUE 0xdebb20e3 - -#define MACDBG "%02x:%02x:%02x:%02x:%02x:%02x" -#define MAC2STRDBG(ea) (ea)[0], (ea)[1], (ea)[2], (ea)[3], (ea)[4], (ea)[5] - -typedef struct bcm_bit_desc { - uint32 bit; - const char* name; -} bcm_bit_desc_t; - - -typedef struct bcm_tlv { - uint8 id; - uint8 len; - uint8 data[1]; -} bcm_tlv_t; - - -#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len)) - - -#define ETHER_ADDR_STR_LEN 18 - - - -static INLINE void -xor_128bit_block(const uint8 *src1, const uint8 *src2, uint8 *dst) -{ - if ( -#ifdef __i386__ - 1 || -#endif - (((uintptr)src1 | (uintptr)src2 | (uintptr)dst) & 3) == 0) { - - - ((uint32 *)dst)[0] = ((const uint32 *)src1)[0] ^ ((const uint32 *)src2)[0]; - ((uint32 *)dst)[1] = ((const uint32 *)src1)[1] ^ ((const uint32 *)src2)[1]; - ((uint32 *)dst)[2] = ((const uint32 *)src1)[2] ^ ((const uint32 *)src2)[2]; - ((uint32 *)dst)[3] = ((const uint32 *)src1)[3] ^ ((const uint32 *)src2)[3]; - } else { - - int k; - for (k = 0; k < 16; k++) - dst[k] = src1[k] ^ src2[k]; - } -} - - - -extern uint8 hndcrc8(uint8 *p, uint nbytes, uint8 crc); -extern uint16 hndcrc16(uint8 *p, uint nbytes, uint16 crc); -extern uint32 hndcrc32(uint8 *p, uint nbytes, uint32 crc); - -#if defined(DHD_DEBUG) || defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || \ - defined(WLMSG_ASSOC) -extern int bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len); -#endif - -#if defined(DHD_DEBUG) || defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || \ - defined(WLMSG_ASSOC) || defined(WLMEDIA_PEAKRATE) -extern int bcm_format_hex(char *str, const void *bytes, int len); -#endif - -extern const char *bcm_crypto_algo_name(uint algo); -extern char *bcm_chipname(uint chipid, char *buf, uint len); -extern char *bcm_brev_str(uint32 brev, char *buf); -extern void printbig(char *buf); -extern void prhex(const char *msg, uchar *buf, uint len); - - -extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen); -extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key); -extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key); - - -extern const char *bcmerrorstr(int bcmerror); - - -typedef uint32 mbool; -#define mboolset(mb, bit) ((mb) |= (bit)) -#define mboolclr(mb, bit) ((mb) &= ~(bit)) -#define mboolisset(mb, bit) (((mb) & (bit)) != 0) -#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val))) - - -extern uint16 bcm_qdbm_to_mw(uint8 qdbm); -extern uint8 bcm_mw_to_qdbm(uint16 mw); - - -struct fielddesc { - const char *nameandfmt; - uint32 offset; - uint32 len; -}; - -extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size); -extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...); -extern void bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount); -extern int bcm_cmp_bytes(uchar *arg1, uchar *arg2, uint8 nbytes); -extern void bcm_print_bytes(char *name, const uchar *cdata, int len); - -typedef uint32 (*bcmutl_rdreg_rtn)(void *arg0, uint arg1, uint32 offset); -extern uint bcmdumpfields(bcmutl_rdreg_rtn func_ptr, void *arg0, uint arg1, struct fielddesc *str, - char *buf, uint32 bufsize); - -extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len); -extern uint bcm_bitcount(uint8 *bitmap, uint bytelength); - - - -#define SSID_FMT_BUF_LEN ((4 * DOT11_MAX_SSID_LEN) + 1) - -unsigned int process_nvram_vars(char *varbuf, unsigned int len); - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/bcmwifi.h b/drivers/net/wireless/bcmdhd/include/bcmwifi.h deleted file mode 100644 index e5207e9c4086..000000000000 --- a/drivers/net/wireless/bcmdhd/include/bcmwifi.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Misc utility routines for WL and Apps - * This header file housing the define and function prototype use by - * both the wl driver, tools & Apps. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmwifi.h 277737 2011-08-16 17:54:59Z $ - */ - - -#ifndef _bcmwifi_h_ -#define _bcmwifi_h_ - - - -typedef uint16 chanspec_t; - - -#define CH_UPPER_SB 0x01 -#define CH_LOWER_SB 0x02 -#define CH_EWA_VALID 0x04 -#define CH_20MHZ_APART 4 -#define CH_10MHZ_APART 2 -#define CH_5MHZ_APART 1 -#define CH_MAX_2G_CHANNEL 14 -#define WLC_MAX_2G_CHANNEL CH_MAX_2G_CHANNEL -#define MAXCHANNEL 224 - -#define WL_CHANSPEC_CHAN_MASK 0x00ff -#define WL_CHANSPEC_CHAN_SHIFT 0 - -#define WL_CHANSPEC_CTL_SB_MASK 0x0300 -#define WL_CHANSPEC_CTL_SB_SHIFT 8 -#define WL_CHANSPEC_CTL_SB_LOWER 0x0100 -#define WL_CHANSPEC_CTL_SB_UPPER 0x0200 -#define WL_CHANSPEC_CTL_SB_NONE 0x0300 - -#define WL_CHANSPEC_BW_MASK 0x0C00 -#define WL_CHANSPEC_BW_SHIFT 10 -#define WL_CHANSPEC_BW_10 0x0400 -#define WL_CHANSPEC_BW_20 0x0800 -#define WL_CHANSPEC_BW_40 0x0C00 - -#define WL_CHANSPEC_BAND_MASK 0xf000 -#define WL_CHANSPEC_BAND_SHIFT 12 -#define WL_CHANSPEC_BAND_5G 0x1000 -#define WL_CHANSPEC_BAND_2G 0x2000 -#define INVCHANSPEC 255 - - -#define WF_CHAN_FACTOR_2_4_G 4814 -#define WF_CHAN_FACTOR_5_G 10000 -#define WF_CHAN_FACTOR_4_G 8000 - - -#define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? ((channel) - CH_10MHZ_APART) : 0) -#define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \ - ((channel) + CH_10MHZ_APART) : 0) -#define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX) -#define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \ - WL_CHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \ - WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) -#define NEXT_20MHZ_CHAN(channel) (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \ - ((channel) + CH_20MHZ_APART) : 0) -#define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ - ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \ - ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \ - WL_CHANSPEC_BAND_5G)) -#define CHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_CHANSPEC_CHAN_MASK)) -#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK) - - -#define CHSPEC_CTL_SB(chspec) (chspec & WL_CHANSPEC_CTL_SB_MASK) -#define CHSPEC_BW(chspec) (chspec & WL_CHANSPEC_BW_MASK) - -#ifdef WL11N_20MHZONLY - -#define CHSPEC_IS10(chspec) 0 -#define CHSPEC_IS20(chspec) 1 -#ifndef CHSPEC_IS40 -#define CHSPEC_IS40(chspec) 0 -#endif - -#else - -#define CHSPEC_IS10(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10) -#define CHSPEC_IS20(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) -#ifndef CHSPEC_IS40 -#define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40) -#endif - -#endif - -#define CHSPEC_IS20_UNCOND(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) - -#define CHSPEC_IS5G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G) -#define CHSPEC_IS2G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G) -#define CHSPEC_SB_NONE(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE) -#define CHSPEC_SB_UPPER(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) -#define CHSPEC_SB_LOWER(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) -#define CHSPEC_CTL_CHAN(chspec) ((CHSPEC_SB_LOWER(chspec)) ? \ - (LOWER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \ - (UPPER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK)))) -#define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G) - -#define CHANSPEC_STR_LEN 8 - - -#define WLC_MAXRATE 108 -#define WLC_RATE_1M 2 -#define WLC_RATE_2M 4 -#define WLC_RATE_5M5 11 -#define WLC_RATE_11M 22 -#define WLC_RATE_6M 12 -#define WLC_RATE_9M 18 -#define WLC_RATE_12M 24 -#define WLC_RATE_18M 36 -#define WLC_RATE_24M 48 -#define WLC_RATE_36M 72 -#define WLC_RATE_48M 96 -#define WLC_RATE_54M 108 - -#define WLC_2G_25MHZ_OFFSET 5 - - -extern char * wf_chspec_ntoa(chanspec_t chspec, char *buf); - - -extern chanspec_t wf_chspec_aton(char *a); - - -extern bool wf_chspec_malformed(chanspec_t chanspec); - - -extern uint8 wf_chspec_ctlchan(chanspec_t chspec); - - -extern chanspec_t wf_chspec_ctlchspec(chanspec_t chspec); - - -extern int wf_mhz2channel(uint freq, uint start_factor); - - -extern int wf_channel2mhz(uint channel, uint start_factor); - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/dhdioctl.h b/drivers/net/wireless/bcmdhd/include/dhdioctl.h deleted file mode 100644 index 175ff8545a0c..000000000000 --- a/drivers/net/wireless/bcmdhd/include/dhdioctl.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Definitions for ioctls to access DHD iovars. - * Based on wlioctl.h (for Broadcom 802.11abg driver). - * (Moves towards generic ioctls for BCM drivers/iovars.) - * - * Definitions subject to change without notice. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: dhdioctl.h 323572 2012-03-26 06:28:14Z $ - */ - -#ifndef _dhdioctl_h_ -#define _dhdioctl_h_ - -#include - - -/* require default structure packing */ -#define BWL_DEFAULT_PACKING -#include - - -/* Linux network driver ioctl encoding */ -typedef struct dhd_ioctl { - uint cmd; /* common ioctl definition */ - void *buf; /* pointer to user buffer */ - uint len; /* length of user buffer */ - bool set; /* get or set request (optional) */ - uint used; /* bytes read or written (optional) */ - uint needed; /* bytes needed (optional) */ - uint driver; /* to identify target driver */ -} dhd_ioctl_t; - -/* Underlying BUS definition */ -enum { - BUS_TYPE_USB = 0, /* for USB dongles */ - BUS_TYPE_SDIO /* for SDIO dongles */ -}; - -/* per-driver magic numbers */ -#define DHD_IOCTL_MAGIC 0x00444944 - -/* bump this number if you change the ioctl interface */ -#define DHD_IOCTL_VERSION 1 - -#define DHD_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */ -#define DHD_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */ - -/* common ioctl definitions */ -#define DHD_GET_MAGIC 0 -#define DHD_GET_VERSION 1 -#define DHD_GET_VAR 2 -#define DHD_SET_VAR 3 - -/* message levels */ -#define DHD_ERROR_VAL 0x0001 -#define DHD_TRACE_VAL 0x0002 -#define DHD_INFO_VAL 0x0004 -#define DHD_DATA_VAL 0x0008 -#define DHD_CTL_VAL 0x0010 -#define DHD_TIMER_VAL 0x0020 -#define DHD_HDRS_VAL 0x0040 -#define DHD_BYTES_VAL 0x0080 -#define DHD_INTR_VAL 0x0100 -#define DHD_LOG_VAL 0x0200 -#define DHD_GLOM_VAL 0x0400 -#define DHD_EVENT_VAL 0x0800 -#define DHD_BTA_VAL 0x1000 -#define DHD_ISCAN_VAL 0x2000 -#define DHD_ARPOE_VAL 0x4000 -#define DHD_REORDER_VAL 0x8000 -#define DHD_WL_VAL 0x10000 - -#ifdef SDTEST -/* For pktgen iovar */ -typedef struct dhd_pktgen { - uint version; /* To allow structure change tracking */ - uint freq; /* Max ticks between tx/rx attempts */ - uint count; /* Test packets to send/rcv each attempt */ - uint print; /* Print counts every attempts */ - uint total; /* Total packets (or bursts) */ - uint minlen; /* Minimum length of packets to send */ - uint maxlen; /* Maximum length of packets to send */ - uint numsent; /* Count of test packets sent */ - uint numrcvd; /* Count of test packets received */ - uint numfail; /* Count of test send failures */ - uint mode; /* Test mode (type of test packets) */ - uint stop; /* Stop after this many tx failures */ -} dhd_pktgen_t; - -/* Version in case structure changes */ -#define DHD_PKTGEN_VERSION 2 - -/* Type of test packets to use */ -#define DHD_PKTGEN_ECHO 1 /* Send echo requests */ -#define DHD_PKTGEN_SEND 2 /* Send discard packets */ -#define DHD_PKTGEN_RXBURST 3 /* Request dongle send N packets */ -#define DHD_PKTGEN_RECV 4 /* Continuous rx from continuous tx dongle */ -#endif /* SDTEST */ - -/* Enter idle immediately (no timeout) */ -#define DHD_IDLE_IMMEDIATE (-1) - -/* Values for idleclock iovar: other values are the sd_divisor to use when idle */ -#define DHD_IDLE_ACTIVE 0 /* Do not request any SD clock change when idle */ -#define DHD_IDLE_STOP (-1) /* Request SD clock be stopped (and use SD1 mode) */ - - -/* require default structure packing */ -#include - -#endif /* _dhdioctl_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/epivers.h b/drivers/net/wireless/bcmdhd/include/epivers.h deleted file mode 100644 index fac87f500d15..000000000000 --- a/drivers/net/wireless/bcmdhd/include/epivers.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: epivers.h.in 277737 2011-08-16 17:54:59Z $ - * -*/ - - -#ifndef _epivers_h_ -#define _epivers_h_ - -#define EPI_MAJOR_VERSION 5 - -#define EPI_MINOR_VERSION 90 - -#define EPI_RC_NUMBER 195 - -#define EPI_INCREMENTAL_NUMBER 114 - -#define EPI_BUILD_NUMBER 0 - -#define EPI_VERSION 5, 90, 195, 114 - -#define EPI_VERSION_NUM 0x055ac372 - -#define EPI_VERSION_DEV 5.90.195 - - -#define EPI_VERSION_STR "5.90.195.114" - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/hndpmu.h b/drivers/net/wireless/bcmdhd/include/hndpmu.h deleted file mode 100644 index 9bfc8c9275a9..000000000000 --- a/drivers/net/wireless/bcmdhd/include/hndpmu.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * HND SiliconBackplane PMU support. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: hndpmu.h 335486 2012-05-28 09:47:55Z $ - */ - -#ifndef _hndpmu_h_ -#define _hndpmu_h_ - - -extern void si_pmu_otp_power(si_t *sih, osl_t *osh, bool on); -extern void si_sdiod_drive_strength_init(si_t *sih, osl_t *osh, uint32 drivestrength); - -extern void si_pmu_set_otp_wr_volts(si_t *sih); -extern void si_pmu_set_otp_rd_volts(si_t *sih); - -#endif /* _hndpmu_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/hndrte_armtrap.h b/drivers/net/wireless/bcmdhd/include/hndrte_armtrap.h deleted file mode 100644 index 7d862c4deb21..000000000000 --- a/drivers/net/wireless/bcmdhd/include/hndrte_armtrap.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * HNDRTE arm trap handling. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: hndrte_armtrap.h 277737 2011-08-16 17:54:59Z $ - */ - -#ifndef _hndrte_armtrap_h -#define _hndrte_armtrap_h - - -/* ARM trap handling */ - -/* Trap types defined by ARM (see arminc.h) */ - -/* Trap locations in lo memory */ -#define TRAP_STRIDE 4 -#define FIRST_TRAP TR_RST -#define LAST_TRAP (TR_FIQ * TRAP_STRIDE) - -#if defined(__ARM_ARCH_4T__) -#define MAX_TRAP_TYPE (TR_FIQ + 1) -#elif defined(__ARM_ARCH_7M__) -#define MAX_TRAP_TYPE (TR_ISR + ARMCM3_NUMINTS) -#endif /* __ARM_ARCH_7M__ */ - -/* The trap structure is defined here as offsets for assembly */ -#define TR_TYPE 0x00 -#define TR_EPC 0x04 -#define TR_CPSR 0x08 -#define TR_SPSR 0x0c -#define TR_REGS 0x10 -#define TR_REG(n) (TR_REGS + (n) * 4) -#define TR_SP TR_REG(13) -#define TR_LR TR_REG(14) -#define TR_PC TR_REG(15) - -#define TRAP_T_SIZE 80 - -#ifndef _LANGUAGE_ASSEMBLY - -#include - -typedef struct _trap_struct { - uint32 type; - uint32 epc; - uint32 cpsr; - uint32 spsr; - uint32 r0; - uint32 r1; - uint32 r2; - uint32 r3; - uint32 r4; - uint32 r5; - uint32 r6; - uint32 r7; - uint32 r8; - uint32 r9; - uint32 r10; - uint32 r11; - uint32 r12; - uint32 r13; - uint32 r14; - uint32 pc; -} trap_t; - -#endif /* !_LANGUAGE_ASSEMBLY */ - -#endif /* _hndrte_armtrap_h */ diff --git a/drivers/net/wireless/bcmdhd/include/hndrte_cons.h b/drivers/net/wireless/bcmdhd/include/hndrte_cons.h deleted file mode 100644 index 859ddc8953a8..000000000000 --- a/drivers/net/wireless/bcmdhd/include/hndrte_cons.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Console support for hndrte. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: hndrte_cons.h 277737 2011-08-16 17:54:59Z $ - */ - -#ifndef _HNDRTE_CONS_H -#define _HNDRTE_CONS_H - -#include - -#define CBUF_LEN (128) - -#define LOG_BUF_LEN 1024 - -typedef struct { - uint32 buf; /* Can't be pointer on (64-bit) hosts */ - uint buf_size; - uint idx; - char *_buf_compat; /* redundant pointer for backward compat. */ -} hndrte_log_t; - -typedef struct { - /* Virtual UART - * When there is no UART (e.g. Quickturn), the host should write a complete - * input line directly into cbuf and then write the length into vcons_in. - * This may also be used when there is a real UART (at risk of conflicting with - * the real UART). vcons_out is currently unused. - */ - volatile uint vcons_in; - volatile uint vcons_out; - - /* Output (logging) buffer - * Console output is written to a ring buffer log_buf at index log_idx. - * The host may read the output when it sees log_idx advance. - * Output will be lost if the output wraps around faster than the host polls. - */ - hndrte_log_t log; - - /* Console input line buffer - * Characters are read one at a time into cbuf until is received, then - * the buffer is processed as a command line. Also used for virtual UART. - */ - uint cbuf_idx; - char cbuf[CBUF_LEN]; -} hndrte_cons_t; - -#endif /* _HNDRTE_CONS_H */ diff --git a/drivers/net/wireless/bcmdhd/include/hndsoc.h b/drivers/net/wireless/bcmdhd/include/hndsoc.h deleted file mode 100644 index 34f927c6af80..000000000000 --- a/drivers/net/wireless/bcmdhd/include/hndsoc.h +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Broadcom HND chip & on-chip-interconnect-related definitions. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: hndsoc.h 277737 2011-08-16 17:54:59Z $ - */ - -#ifndef _HNDSOC_H -#define _HNDSOC_H - -/* Include the soci specific files */ -#include -#include - -/* - * SOC Interconnect Address Map. - * All regions may not exist on all chips. - */ -#define SI_SDRAM_BASE 0x00000000 /* Physical SDRAM */ -#define SI_PCI_MEM 0x08000000 /* Host Mode sb2pcitranslation0 (64 MB) */ -#define SI_PCI_MEM_SZ (64 * 1024 * 1024) -#define SI_PCI_CFG 0x0c000000 /* Host Mode sb2pcitranslation1 (64 MB) */ -#define SI_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ -#define SI_SDRAM_R2 0x80000000 /* Region 2 for sdram (512 MB) */ - -#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */ - -#define SI_WRAP_BASE 0x18100000 /* Wrapper space base */ -#define SI_CORE_SIZE 0x1000 /* each core gets 4Kbytes for registers */ -#define SI_MAXCORES 16 /* Max cores (this is arbitrary, for software - * convenience and could be changed if we - * make any larger chips - */ - -#define SI_FASTRAM 0x19000000 /* On-chip RAM on chips that also have DDR */ -#define SI_FASTRAM_SWAPPED 0x19800000 - -#define SI_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */ -#define SI_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */ -#define SI_ARMCM3_ROM 0x1e000000 /* ARM Cortex-M3 ROM */ -#define SI_FLASH1 0x1fc00000 /* MIPS Flash Region 1 */ -#define SI_FLASH1_SZ 0x00400000 /* MIPS Size of Flash Region 1 */ -#define SI_ARM7S_ROM 0x20000000 /* ARM7TDMI-S ROM */ -#define SI_ARMCM3_SRAM2 0x60000000 /* ARM Cortex-M3 SRAM Region 2 */ -#define SI_ARM7S_SRAM2 0x80000000 /* ARM7TDMI-S SRAM Region 2 */ -#define SI_ARM_FLASH1 0xffff0000 /* ARM Flash Region 1 */ -#define SI_ARM_FLASH1_SZ 0x00010000 /* ARM Size of Flash Region 1 */ - -#define SI_PCI_DMA 0x40000000 /* Client Mode sb2pcitranslation2 (1 GB) */ -#define SI_PCI_DMA2 0x80000000 /* Client Mode sb2pcitranslation2 (1 GB) */ -#define SI_PCI_DMA_SZ 0x40000000 /* Client Mode sb2pcitranslation2 size in bytes */ -#define SI_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2 - * (2 ZettaBytes), low 32 bits - */ -#define SI_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2 - * (2 ZettaBytes), high 32 bits - */ - -/* core codes */ -#define NODEV_CORE_ID 0x700 /* Invalid coreid */ -#define CC_CORE_ID 0x800 /* chipcommon core */ -#define ILINE20_CORE_ID 0x801 /* iline20 core */ -#define SRAM_CORE_ID 0x802 /* sram core */ -#define SDRAM_CORE_ID 0x803 /* sdram core */ -#define PCI_CORE_ID 0x804 /* pci core */ -#define MIPS_CORE_ID 0x805 /* mips core */ -#define ENET_CORE_ID 0x806 /* enet mac core */ -#define CODEC_CORE_ID 0x807 /* v90 codec core */ -#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */ -#define ADSL_CORE_ID 0x809 /* ADSL core */ -#define ILINE100_CORE_ID 0x80a /* iline100 core */ -#define IPSEC_CORE_ID 0x80b /* ipsec core */ -#define UTOPIA_CORE_ID 0x80c /* utopia core */ -#define PCMCIA_CORE_ID 0x80d /* pcmcia core */ -#define SOCRAM_CORE_ID 0x80e /* internal memory core */ -#define MEMC_CORE_ID 0x80f /* memc sdram core */ -#define OFDM_CORE_ID 0x810 /* OFDM phy core */ -#define EXTIF_CORE_ID 0x811 /* external interface core */ -#define D11_CORE_ID 0x812 /* 802.11 MAC core */ -#define APHY_CORE_ID 0x813 /* 802.11a phy core */ -#define BPHY_CORE_ID 0x814 /* 802.11b phy core */ -#define GPHY_CORE_ID 0x815 /* 802.11g phy core */ -#define MIPS33_CORE_ID 0x816 /* mips3302 core */ -#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */ -#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */ -#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */ -#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */ -#define SDIOH_CORE_ID 0x81b /* sdio host core */ -#define ROBO_CORE_ID 0x81c /* roboswitch core */ -#define ATA100_CORE_ID 0x81d /* parallel ATA core */ -#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */ -#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */ -#define PCIE_CORE_ID 0x820 /* pci express core */ -#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */ -#define SRAMC_CORE_ID 0x822 /* SRAM controller core */ -#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */ -#define ARM11_CORE_ID 0x824 /* ARM 1176 core */ -#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */ -#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */ -#define PMU_CORE_ID 0x827 /* PMU core */ -#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */ -#define SDIOD_CORE_ID 0x829 /* SDIO device core */ -#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */ -#define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */ -#define MIPS74K_CORE_ID 0x82c /* mips 74k core */ -#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ -#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */ -#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */ -#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */ -#define SC_CORE_ID 0x831 /* shared common core */ -#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */ -#define SPIH_CORE_ID 0x833 /* SPI host core */ -#define I2S_CORE_ID 0x834 /* I2S core */ -#define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */ -#define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */ -#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ -#define DEF_AI_COMP 0xfff /* Default component, in ai chips it maps all - * unused address ranges - */ - -/* There are TWO constants on all HND chips: SI_ENUM_BASE above, - * and chipcommon being the first core: - */ -#define SI_CC_IDX 0 - -/* SOC Interconnect types (aka chip types) */ -#define SOCI_SB 0 -#define SOCI_AI 1 -#define SOCI_UBUS 2 - -/* Common core control flags */ -#define SICF_BIST_EN 0x8000 -#define SICF_PME_EN 0x4000 -#define SICF_CORE_BITS 0x3ffc -#define SICF_FGC 0x0002 -#define SICF_CLOCK_EN 0x0001 - -/* Common core status flags */ -#define SISF_BIST_DONE 0x8000 -#define SISF_BIST_ERROR 0x4000 -#define SISF_GATED_CLK 0x2000 -#define SISF_DMA64 0x1000 -#define SISF_CORE_BITS 0x0fff - -/* A register that is common to all cores to - * communicate w/PMU regarding clock control. - */ -#define SI_CLK_CTL_ST 0x1e0 /* clock control and status */ - -/* clk_ctl_st register */ -#define CCS_FORCEALP 0x00000001 /* force ALP request */ -#define CCS_FORCEHT 0x00000002 /* force HT request */ -#define CCS_FORCEILP 0x00000004 /* force ILP request */ -#define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */ -#define CCS_HTAREQ 0x00000010 /* HT Avail Request */ -#define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */ -#define CCS_ERSRC_REQ_MASK 0x00000700 /* external resource requests */ -#define CCS_ERSRC_REQ_SHIFT 8 -#define CCS_ALPAVAIL 0x00010000 /* ALP is available */ -#define CCS_HTAVAIL 0x00020000 /* HT is available */ -#define CCS_BP_ON_APL 0x00040000 /* RO: Backplane is running on ALP clock */ -#define CCS_BP_ON_HT 0x00080000 /* RO: Backplane is running on HT clock */ -#define CCS_ERSRC_STS_MASK 0x07000000 /* external resource status */ -#define CCS_ERSRC_STS_SHIFT 24 - -#define CCS0_HTAVAIL 0x00010000 /* HT avail in chipc and pcmcia on 4328a0 */ -#define CCS0_ALPAVAIL 0x00020000 /* ALP avail in chipc and pcmcia on 4328a0 */ - -/* Not really related to SOC Interconnect, but a couple of software - * conventions for the use the flash space: - */ - -/* Minumum amount of flash we support */ -#define FLASH_MIN 0x00020000 /* Minimum flash size */ - -/* A boot/binary may have an embedded block that describes its size */ -#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */ -#define BISZ_MAGIC 0x4249535a /* Marked with this value: 'BISZ' */ -#define BISZ_MAGIC_IDX 0 /* Word 0: magic */ -#define BISZ_TXTST_IDX 1 /* 1: text start */ -#define BISZ_TXTEND_IDX 2 /* 2: text end */ -#define BISZ_DATAST_IDX 3 /* 3: data start */ -#define BISZ_DATAEND_IDX 4 /* 4: data end */ -#define BISZ_BSSST_IDX 5 /* 5: bss start */ -#define BISZ_BSSEND_IDX 6 /* 6: bss end */ -#define BISZ_SIZE 7 /* descriptor size in 32-bit integers */ - -#endif /* _HNDSOC_H */ diff --git a/drivers/net/wireless/bcmdhd/include/htsf.h b/drivers/net/wireless/bcmdhd/include/htsf.h deleted file mode 100644 index d875edb816c9..000000000000 --- a/drivers/net/wireless/bcmdhd/include/htsf.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Time stamps for latency measurements - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: htsf.h 277737 2011-08-16 17:54:59Z $ - */ -#ifndef _HTSF_H_ -#define _HTSF_H_ - -#define HTSFMAGIC 0xCDCDABAB /* in network order for tcpdump */ -#define HTSFENDMAGIC 0xEFEFABAB /* to distinguish from RT2 magic */ -#define HTSF_HOSTOFFSET 102 -#define HTSF_DNGLOFFSET HTSF_HOSTOFFSET - 4 -#define HTSF_DNGLOFFSET2 HTSF_HOSTOFFSET + 106 -#define HTSF_MIN_PKTLEN 200 -#define ETHER_TYPE_BRCM_PKTDLYSTATS 0x886d - -typedef enum htsfts_type { - T10, - T20, - T30, - T40, - T50, - T60, - T70, - T80, - T90, - TA0, - TE0 -} htsf_timestamp_t; - -typedef struct { - uint32 magic; - uint32 prio; - uint32 seqnum; - uint32 misc; - uint32 c10; - uint32 t10; - uint32 c20; - uint32 t20; - uint32 t30; - uint32 t40; - uint32 t50; - uint32 t60; - uint32 t70; - uint32 t80; - uint32 t90; - uint32 cA0; - uint32 tA0; - uint32 cE0; - uint32 tE0; - uint32 endmagic; -} htsfts_t; - -#endif /* _HTSF_H_ */ diff --git a/drivers/net/wireless/bcmdhd/include/linux_osl.h b/drivers/net/wireless/bcmdhd/include/linux_osl.h deleted file mode 100644 index 7f92966d977e..000000000000 --- a/drivers/net/wireless/bcmdhd/include/linux_osl.h +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Linux OS Independent Layer - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: linux_osl.h 301794 2011-12-08 20:41:35Z $ - */ - - -#ifndef _linux_osl_h_ -#define _linux_osl_h_ - -#include - - -extern void * osl_os_open_image(char * filename); -extern int osl_os_get_image_block(char * buf, int len, void * image); -extern void osl_os_close_image(void * image); - - -#ifdef BCMDRIVER - - -extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag); -extern void osl_detach(osl_t *osh); - - -extern uint32 g_assert_type; - - -#if defined(BCMASSERT_LOG) - #define ASSERT(exp) \ - do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0) -extern void osl_assert(char *exp, char *file, int line); -#else - #ifdef __GNUC__ - #define GCC_VERSION \ - (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) - #if GCC_VERSION > 30100 - #define ASSERT(exp) do {} while (0) - #else - - #define ASSERT(exp) - #endif - #endif -#endif - - -#define OSL_DELAY(usec) osl_delay(usec) -extern void osl_delay(uint usec); - -#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \ - osl_pcmcia_read_attr((osh), (offset), (buf), (size)) -#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \ - osl_pcmcia_write_attr((osh), (offset), (buf), (size)) -extern void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size); -extern void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size); - - -#define OSL_PCI_READ_CONFIG(osh, offset, size) \ - osl_pci_read_config((osh), (offset), (size)) -#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \ - osl_pci_write_config((osh), (offset), (size), (val)) -extern uint32 osl_pci_read_config(osl_t *osh, uint offset, uint size); -extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val); - - -#define OSL_PCI_BUS(osh) osl_pci_bus(osh) -#define OSL_PCI_SLOT(osh) osl_pci_slot(osh) -extern uint osl_pci_bus(osl_t *osh); -extern uint osl_pci_slot(osl_t *osh); - - -typedef struct { - bool pkttag; - uint pktalloced; - bool mmbus; - pktfree_cb_fn_t tx_fn; - void *tx_ctx; -} osl_pubinfo_t; - -#define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \ - do { \ - ((osl_pubinfo_t*)osh)->tx_fn = _tx_fn; \ - ((osl_pubinfo_t*)osh)->tx_ctx = _tx_ctx; \ - } while (0) - - - -#define BUS_SWAP32(v) (v) - - #define MALLOC(osh, size) osl_malloc((osh), (size)) - #define MFREE(osh, addr, size) osl_mfree((osh), (addr), (size)) - #define MALLOCED(osh) osl_malloced((osh)) - extern void *osl_malloc(osl_t *osh, uint size); - extern void osl_mfree(osl_t *osh, void *addr, uint size); - extern uint osl_malloced(osl_t *osh); - -#define NATIVE_MALLOC(osh, size) kmalloc(size, GFP_ATOMIC) -#define NATIVE_MFREE(osh, addr, size) kfree(addr) - -#define MALLOC_FAILED(osh) osl_malloc_failed((osh)) -extern uint osl_malloc_failed(osl_t *osh); - - -#define DMA_CONSISTENT_ALIGN osl_dma_consistent_align() -#define DMA_ALLOC_CONSISTENT(osh, size, align, tot, pap, dmah) \ - osl_dma_alloc_consistent((osh), (size), (align), (tot), (pap)) -#define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \ - osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) -extern uint osl_dma_consistent_align(void); -extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align, uint *tot, ulong *pap); -extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa); - - -#define DMA_TX 1 -#define DMA_RX 2 - - -#define DMA_MAP(osh, va, size, direction, p, dmah) \ - osl_dma_map((osh), (va), (size), (direction)) -#define DMA_UNMAP(osh, pa, size, direction, p, dmah) \ - osl_dma_unmap((osh), (pa), (size), (direction)) -extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction); -extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); - - -#define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0) - - - #include - #define OSL_WRITE_REG(osh, r, v) (bcmsdh_reg_write(NULL, (uintptr)(r), sizeof(*(r)), (v))) - #define OSL_READ_REG(osh, r) (bcmsdh_reg_read(NULL, (uintptr)(r), sizeof(*(r)))) - - #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) if (((osl_pubinfo_t*)(osh))->mmbus) \ - mmap_op else bus_op - #define SELECT_BUS_READ(osh, mmap_op, bus_op) (((osl_pubinfo_t*)(osh))->mmbus) ? \ - mmap_op : bus_op - -#define OSL_ERROR(bcmerror) osl_error(bcmerror) -extern int osl_error(int bcmerror); - - -#define PKTBUFSZ 2048 - - - -#define OSL_SYSUPTIME() ((uint32)jiffies_to_msecs(jiffies)) -#define printf(fmt, args...) printk(fmt , ## args) -#include -#include - -#define bcopy(src, dst, len) memcpy((dst), (src), (len)) -#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) -#define bzero(b, len) memset((b), '\0', (len)) - - - -#ifndef __mips__ -#define R_REG(osh, r) (\ - SELECT_BUS_READ(osh, sizeof(*(r)) == sizeof(uint8) ? readb((volatile uint8*)(r)) : \ - sizeof(*(r)) == sizeof(uint16) ? readw((volatile uint16*)(r)) : \ - readl((volatile uint32*)(r)), OSL_READ_REG(osh, r)) \ -) -#else -#define R_REG(osh, r) (\ - SELECT_BUS_READ(osh, \ - ({ \ - __typeof(*(r)) __osl_v; \ - __asm__ __volatile__("sync"); \ - switch (sizeof(*(r))) { \ - case sizeof(uint8): __osl_v = \ - readb((volatile uint8*)(r)); break; \ - case sizeof(uint16): __osl_v = \ - readw((volatile uint16*)(r)); break; \ - case sizeof(uint32): __osl_v = \ - readl((volatile uint32*)(r)); break; \ - } \ - __asm__ __volatile__("sync"); \ - __osl_v; \ - }), \ - ({ \ - __typeof(*(r)) __osl_v; \ - __asm__ __volatile__("sync"); \ - __osl_v = OSL_READ_REG(osh, r); \ - __asm__ __volatile__("sync"); \ - __osl_v; \ - })) \ -) -#endif - -#define W_REG(osh, r, v) do { \ - SELECT_BUS_WRITE(osh, \ - switch (sizeof(*(r))) { \ - case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ - case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ - case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ - }, \ - (OSL_WRITE_REG(osh, r, v))); \ - } while (0) - - -#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) -#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) - - -#define bcopy(src, dst, len) memcpy((dst), (src), (len)) -#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) -#define bzero(b, len) memset((b), '\0', (len)) - - -#ifdef __mips__ -#include -#define OSL_UNCACHED(va) ((void *)KSEG1ADDR((va))) -#define OSL_CACHED(va) ((void *)KSEG0ADDR((va))) -#else -#define OSL_UNCACHED(va) ((void *)va) -#define OSL_CACHED(va) ((void *)va) -#endif - - -#if defined(__i386__) -#define OSL_GETCYCLES(x) rdtscl((x)) -#else -#define OSL_GETCYCLES(x) ((x) = 0) -#endif - - -#define BUSPROBE(val, addr) ({ (val) = R_REG(NULL, (addr)); 0; }) - - -#if !defined(CONFIG_MMC_MSM7X00A) -#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) -#else -#define REG_MAP(pa, size) (void *)(0) -#endif -#define REG_UNMAP(va) iounmap((va)) - - -#define R_SM(r) *(r) -#define W_SM(r, v) (*(r) = (v)) -#define BZERO_SM(r, len) memset((r), '\0', (len)) - - -#include - - -#define PKTGET(osh, len, send) osl_pktget((osh), (len)) -#define PKTDUP(osh, skb) osl_pktdup((osh), (skb)) -#define PKTLIST_DUMP(osh, buf) -#define PKTDBG_TRACE(osh, pkt, bit) -#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) -#ifdef CONFIG_DHD_USE_STATIC_BUF -#define PKTGET_STATIC(osh, len, send) osl_pktget_static((osh), (len)) -#define PKTFREE_STATIC(osh, skb, send) osl_pktfree_static((osh), (skb), (send)) -#endif -#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data) -#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len) -#define PKTHEADROOM(osh, skb) (PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head)) -#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail)) -#define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next) -#define PKTSETNEXT(osh, skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x)) -#define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len)) -#define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes)) -#define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes)) -#define PKTTAG(skb) ((void*)(((struct sk_buff*)(skb))->cb)) -#define PKTALLOCED(osh) ((osl_pubinfo_t *)(osh))->pktalloced -#define PKTSETPOOL(osh, skb, x, y) do {} while (0) -#define PKTPOOL(osh, skb) FALSE -#define PKTSHRINK(osh, m) (m) - -#ifdef CTFPOOL -#define CTFPOOL_REFILL_THRESH 3 -typedef struct ctfpool { - void *head; - spinlock_t lock; - uint max_obj; - uint curr_obj; - uint obj_size; - uint refills; - uint fast_allocs; - uint fast_frees; - uint slow_allocs; -} ctfpool_t; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) -#define FASTBUF (1 << 4) -#define CTFBUF (1 << 5) -#define PKTSETFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) |= FASTBUF) -#define PKTCLRFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) &= (~FASTBUF)) -#define PKTSETCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) |= CTFBUF) -#define PKTCLRCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) &= (~CTFBUF)) -#define PKTISFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) & FASTBUF) -#define PKTISCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) & CTFBUF) -#define PKTFAST(osh, skb) (((struct sk_buff*)(skb))->mac_len) -#else -#define FASTBUF (1 << 0) -#define CTFBUF (1 << 1) -#define PKTSETFAST(osh, skb) ((((struct sk_buff*)(skb))->__unused) |= FASTBUF) -#define PKTCLRFAST(osh, skb) ((((struct sk_buff*)(skb))->__unused) &= (~FASTBUF)) -#define PKTSETCTF(osh, skb) ((((struct sk_buff*)(skb))->__unused) |= CTFBUF) -#define PKTCLRCTF(osh, skb) ((((struct sk_buff*)(skb))->__unused) &= (~CTFBUF)) -#define PKTISFAST(osh, skb) ((((struct sk_buff*)(skb))->__unused) & FASTBUF) -#define PKTISCTF(osh, skb) ((((struct sk_buff*)(skb))->__unused) & CTFBUF) -#define PKTFAST(osh, skb) (((struct sk_buff*)(skb))->__unused) -#endif - -#define CTFPOOLPTR(osh, skb) (((struct sk_buff*)(skb))->sk) -#define CTFPOOLHEAD(osh, skb) (((ctfpool_t *)((struct sk_buff*)(skb))->sk)->head) - -extern void *osl_ctfpool_add(osl_t *osh); -extern void osl_ctfpool_replenish(osl_t *osh, uint thresh); -extern int32 osl_ctfpool_init(osl_t *osh, uint numobj, uint size); -extern void osl_ctfpool_cleanup(osl_t *osh); -extern void osl_ctfpool_stats(osl_t *osh, void *b); -#endif - -#ifdef HNDCTF -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) -#define SKIPCT (1 << 6) -#define PKTSETSKIPCT(osh, skb) (((struct sk_buff*)(skb))->mac_len |= SKIPCT) -#define PKTCLRSKIPCT(osh, skb) (((struct sk_buff*)(skb))->mac_len &= (~SKIPCT)) -#define PKTSKIPCT(osh, skb) (((struct sk_buff*)(skb))->mac_len & SKIPCT) -#else -#define SKIPCT (1 << 2) -#define PKTSETSKIPCT(osh, skb) (((struct sk_buff*)(skb))->__unused |= SKIPCT) -#define PKTCLRSKIPCT(osh, skb) (((struct sk_buff*)(skb))->__unused &= (~SKIPCT)) -#define PKTSKIPCT(osh, skb) (((struct sk_buff*)(skb))->__unused & SKIPCT) -#endif -#else -#define PKTSETSKIPCT(osh, skb) -#define PKTCLRSKIPCT(osh, skb) -#define PKTSKIPCT(osh, skb) -#endif - -extern void osl_pktfree(osl_t *osh, void *skb, bool send); -extern void *osl_pktget_static(osl_t *osh, uint len); -extern void osl_pktfree_static(osl_t *osh, void *skb, bool send); - -extern void *osl_pktget(osl_t *osh, uint len); -extern void *osl_pktdup(osl_t *osh, void *skb); - - -static INLINE void * -osl_pkt_frmnative(osl_pubinfo_t *osh, void *pkt) -{ - struct sk_buff *nskb; - - if (osh->pkttag) - bzero((void*)((struct sk_buff*)pkt)->cb, OSL_PKTTAG_SZ); - - - for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { - osh->pktalloced++; - } - - return (void *)pkt; -} -#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_pubinfo_t *)osh), (struct sk_buff*)(skb)) - - -static INLINE struct sk_buff * -osl_pkt_tonative(osl_pubinfo_t *osh, void *pkt) -{ - struct sk_buff *nskb; - - if (osh->pkttag) - bzero(((struct sk_buff*)pkt)->cb, OSL_PKTTAG_SZ); - - - for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { - osh->pktalloced--; - } - - return (struct sk_buff *)pkt; -} -#define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osl_pubinfo_t *)(osh), (pkt)) - -#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev) -#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x)) -#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority) -#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x)) -#define PKTSUMNEEDED(skb) (((struct sk_buff*)(skb))->ip_summed == CHECKSUM_HW) -#define PKTSETSUMGOOD(skb, x) (((struct sk_buff*)(skb))->ip_summed = \ - ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE)) - -#define PKTSHARED(skb) (((struct sk_buff*)(skb))->cloned) - - - -#else - - - - #define ASSERT(exp) do {} while (0) - - -#define MALLOC(o, l) malloc(l) -#define MFREE(o, p, l) free(p) -#include - - -#include - - -#include - - -extern void bcopy(const void *src, void *dst, size_t len); -extern int bcmp(const void *b1, const void *b2, size_t len); -extern void bzero(void *b, size_t len); -#endif - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/linuxver.h b/drivers/net/wireless/bcmdhd/include/linuxver.h deleted file mode 100644 index 54d88ee923b2..000000000000 --- a/drivers/net/wireless/bcmdhd/include/linuxver.h +++ /dev/null @@ -1,614 +0,0 @@ -/* - * Linux-specific abstractions to gain some independence from linux kernel versions. - * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: linuxver.h 312264 2012-02-02 00:49:43Z $ - */ - - -#ifndef _linuxver_h_ -#define _linuxver_h_ - -#include -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) -#include -#else -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) -#include -#else -#include -#endif -#endif -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)) - -#ifdef __UNDEF_NO_VERSION__ -#undef __NO_VERSION__ -#else -#define __NO_VERSION__ -#endif -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#define module_param(_name_, _type_, _perm_) MODULE_PARM(_name_, "i") -#define module_param_string(_name_, _string_, _size_, _perm_) \ - MODULE_PARM(_string_, "c" __MODULE_STRING(_size_)) -#endif - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 9)) -#include -#else -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -#include -#endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) -#undef IP_TOS -#endif -#include - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41)) -#include -#else -#include -#ifndef work_struct -#define work_struct tq_struct -#endif -#ifndef INIT_WORK -#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data)) -#endif -#ifndef schedule_work -#define schedule_work(_work) schedule_task((_work)) -#endif -#ifndef flush_scheduled_work -#define flush_scheduled_work() flush_scheduled_tasks() -#endif -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) -#define MY_INIT_WORK(_work, _func) INIT_WORK(_work, _func) -#else -#define MY_INIT_WORK(_work, _func) INIT_WORK(_work, _func, _work) -typedef void (*work_func_t)(void *work); -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) - -#ifndef IRQ_NONE -typedef void irqreturn_t; -#define IRQ_NONE -#define IRQ_HANDLED -#define IRQ_RETVAL(x) -#endif -#else -typedef irqreturn_t(*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs); -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) -#define IRQF_SHARED SA_SHIRQ -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17) -#ifdef CONFIG_NET_RADIO -#define CONFIG_WIRELESS_EXT -#endif -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 67) -#define MOD_INC_USE_COUNT -#define MOD_DEC_USE_COUNT -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) -#include -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) -#include -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) -#include -#else -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) -#include -#endif -#endif - - -#ifndef __exit -#define __exit -#endif -#ifndef __devexit -#define __devexit -#endif -#ifndef __devinit -#define __devinit __init -#endif -#ifndef __devinitdata -#define __devinitdata -#endif -#ifndef __devexit_p -#define __devexit_p(x) x -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)) - -#define pci_get_drvdata(dev) (dev)->sysdata -#define pci_set_drvdata(dev, value) (dev)->sysdata = (value) - - - -struct pci_device_id { - unsigned int vendor, device; - unsigned int subvendor, subdevice; - unsigned int class, class_mask; - unsigned long driver_data; -}; - -struct pci_driver { - struct list_head node; - char *name; - const struct pci_device_id *id_table; - int (*probe)(struct pci_dev *dev, - const struct pci_device_id *id); - void (*remove)(struct pci_dev *dev); - void (*suspend)(struct pci_dev *dev); - void (*resume)(struct pci_dev *dev); -}; - -#define MODULE_DEVICE_TABLE(type, name) -#define PCI_ANY_ID (~0) - - -#define pci_module_init pci_register_driver -extern int pci_register_driver(struct pci_driver *drv); -extern void pci_unregister_driver(struct pci_driver *drv); - -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)) -#define pci_module_init pci_register_driver -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)) -#ifdef MODULE -#define module_init(x) int init_module(void) { return x(); } -#define module_exit(x) void cleanup_module(void) { x(); } -#else -#define module_init(x) __initcall(x); -#define module_exit(x) __exitcall(x); -#endif -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) -#define WL_USE_NETDEV_OPS -#else -#undef WL_USE_NETDEV_OPS -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) && defined(CONFIG_RFKILL_INPUT) -#define WL_CONFIG_RFKILL_INPUT -#else -#undef WL_CONFIG_RFKILL_INPUT -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 48)) -#define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 13)) -#define pci_resource_start(dev, bar) ((dev)->base_address[(bar)]) -#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 44)) -#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start) -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 23)) -#define pci_enable_device(dev) do { } while (0) -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 14)) -#define net_device device -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 42)) - - - -#ifndef PCI_DMA_TODEVICE -#define PCI_DMA_TODEVICE 1 -#define PCI_DMA_FROMDEVICE 2 -#endif - -typedef u32 dma_addr_t; - - -static inline int get_order(unsigned long size) -{ - int order; - - size = (size-1) >> (PAGE_SHIFT-1); - order = -1; - do { - size >>= 1; - order++; - } while (size); - return order; -} - -static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, - dma_addr_t *dma_handle) -{ - void *ret; - int gfp = GFP_ATOMIC | GFP_DMA; - - ret = (void *)__get_free_pages(gfp, get_order(size)); - - if (ret != NULL) { - memset(ret, 0, size); - *dma_handle = virt_to_bus(ret); - } - return ret; -} -static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - free_pages((unsigned long)vaddr, get_order(size)); -} -#define pci_map_single(cookie, address, size, dir) virt_to_bus(address) -#define pci_unmap_single(cookie, address, size, dir) - -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43)) - -#define dev_kfree_skb_any(a) dev_kfree_skb(a) -#define netif_down(dev) do { (dev)->start = 0; } while (0) - - -#ifndef _COMPAT_NETDEVICE_H - - - -#define dev_kfree_skb_irq(a) dev_kfree_skb(a) -#define netif_wake_queue(dev) \ - do { clear_bit(0, &(dev)->tbusy); mark_bh(NET_BH); } while (0) -#define netif_stop_queue(dev) set_bit(0, &(dev)->tbusy) - -static inline void netif_start_queue(struct net_device *dev) -{ - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; -} - -#define netif_queue_stopped(dev) (dev)->tbusy -#define netif_running(dev) (dev)->start - -#endif - -#define netif_device_attach(dev) netif_start_queue(dev) -#define netif_device_detach(dev) netif_stop_queue(dev) - - -#define tasklet_struct tq_struct -static inline void tasklet_schedule(struct tasklet_struct *tasklet) -{ - queue_task(tasklet, &tq_immediate); - mark_bh(IMMEDIATE_BH); -} - -static inline void tasklet_init(struct tasklet_struct *tasklet, - void (*func)(unsigned long), - unsigned long data) -{ - tasklet->next = NULL; - tasklet->sync = 0; - tasklet->routine = (void (*)(void *))func; - tasklet->data = (void *)data; -} -#define tasklet_kill(tasklet) { do {} while (0); } - - -#define del_timer_sync(timer) del_timer(timer) - -#else - -#define netif_down(dev) - -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3)) - - -#define PREPARE_TQUEUE(_tq, _routine, _data) \ - do { \ - (_tq)->routine = _routine; \ - (_tq)->data = _data; \ - } while (0) - - -#define INIT_TQUEUE(_tq, _routine, _data) \ - do { \ - INIT_LIST_HEAD(&(_tq)->list); \ - (_tq)->sync = 0; \ - PREPARE_TQUEUE((_tq), (_routine), (_data)); \ - } while (0) - -#endif - - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 9) -#define PCI_SAVE_STATE(a, b) pci_save_state(a) -#define PCI_RESTORE_STATE(a, b) pci_restore_state(a) -#else -#define PCI_SAVE_STATE(a, b) pci_save_state(a, b) -#define PCI_RESTORE_STATE(a, b) pci_restore_state(a, b) -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 6)) -static inline int -pci_save_state(struct pci_dev *dev, u32 *buffer) -{ - int i; - if (buffer) { - for (i = 0; i < 16; i++) - pci_read_config_dword(dev, i * 4, &buffer[i]); - } - return 0; -} - -static inline int -pci_restore_state(struct pci_dev *dev, u32 *buffer) -{ - int i; - - if (buffer) { - for (i = 0; i < 16; i++) - pci_write_config_dword(dev, i * 4, buffer[i]); - } - - else { - for (i = 0; i < 6; i ++) - pci_write_config_dword(dev, - PCI_BASE_ADDRESS_0 + (i * 4), - pci_resource_start(dev, i)); - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - } - return 0; -} -#endif - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 19)) -#define read_c0_count() read_32bit_cp0_register(CP0_COUNT) -#endif - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)) -#ifndef SET_MODULE_OWNER -#define SET_MODULE_OWNER(dev) do {} while (0) -#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT -#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT -#else -#define OLD_MOD_INC_USE_COUNT do {} while (0) -#define OLD_MOD_DEC_USE_COUNT do {} while (0) -#endif -#else -#ifndef SET_MODULE_OWNER -#define SET_MODULE_OWNER(dev) do {} while (0) -#endif -#ifndef MOD_INC_USE_COUNT -#define MOD_INC_USE_COUNT do {} while (0) -#endif -#ifndef MOD_DEC_USE_COUNT -#define MOD_DEC_USE_COUNT do {} while (0) -#endif -#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT -#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT -#endif - -#ifndef SET_NETDEV_DEV -#define SET_NETDEV_DEV(net, pdev) do {} while (0) -#endif - -#ifndef HAVE_FREE_NETDEV -#define free_netdev(dev) kfree(dev) -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) - -#define af_packet_priv data -#endif - - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) -#define DRV_SUSPEND_STATE_TYPE pm_message_t -#else -#define DRV_SUSPEND_STATE_TYPE uint32 -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) -#define CHECKSUM_HW CHECKSUM_PARTIAL -#endif - -typedef struct { - void *parent; - struct task_struct *p_task; - long thr_pid; - int prio; - struct semaphore sema; - bool terminated; - struct completion completed; -} tsk_ctl_t; - - - - -#ifdef DHD_DEBUG -#define DBG_THR(x) printk x -#else -#define DBG_THR(x) -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define SMP_RD_BARRIER_DEPENDS(x) smp_read_barrier_depends(x) -#else -#define SMP_RD_BARRIER_DEPENDS(x) smp_rmb(x) -#endif - - -#define PROC_START(thread_func, owner, tsk_ctl, flags) \ -{ \ - sema_init(&((tsk_ctl)->sema), 0); \ - init_completion(&((tsk_ctl)->completed)); \ - (tsk_ctl)->parent = owner; \ - (tsk_ctl)->terminated = FALSE; \ - (tsk_ctl)->thr_pid = kernel_thread(thread_func, tsk_ctl, flags); \ - if ((tsk_ctl)->thr_pid > 0) \ - wait_for_completion(&((tsk_ctl)->completed)); \ - DBG_THR(("%s thr:%lx started\n", __FUNCTION__, (tsk_ctl)->thr_pid)); \ -} - -#define PROC_STOP(tsk_ctl) \ -{ \ - (tsk_ctl)->terminated = TRUE; \ - smp_wmb(); \ - up(&((tsk_ctl)->sema)); \ - wait_for_completion(&((tsk_ctl)->completed)); \ - DBG_THR(("%s thr:%lx terminated OK\n", __FUNCTION__, (tsk_ctl)->thr_pid)); \ - (tsk_ctl)->thr_pid = -1; \ -} - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define DAEMONIZE(a) daemonize(a); \ - allow_signal(SIGKILL); \ - allow_signal(SIGTERM); -#else /* Linux 2.4 (w/o preemption patch) */ -#define RAISE_RX_SOFTIRQ() \ - cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ) -#define DAEMONIZE(a) daemonize(); \ - do { if (a) \ - strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a) + 1))); \ - } while (0); -#endif /* LINUX_VERSION_CODE */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define BLOCKABLE() (!in_atomic()) -#else -#define BLOCKABLE() (!in_interrupt()) -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) -#define KILL_PROC(nr, sig) \ -{ \ -struct task_struct *tsk; \ -struct pid *pid; \ -pid = find_get_pid((pid_t)nr); \ -tsk = pid_task(pid, PIDTYPE_PID); \ -if (tsk) send_sig(sig, tsk, 1); \ -} -#else -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (LINUX_VERSION_CODE <= \ - KERNEL_VERSION(2, 6, 30)) -#define KILL_PROC(pid, sig) \ -{ \ - struct task_struct *tsk; \ - tsk = find_task_by_vpid(pid); \ - if (tsk) send_sig(sig, tsk, 1); \ -} -#else -#define KILL_PROC(pid, sig) \ -{ \ - kill_proc(pid, sig, 1); \ -} -#endif -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#include -#include -#else -#include - -#define __wait_event_interruptible_timeout(wq, condition, ret) \ -do { \ - wait_queue_t __wait; \ - init_waitqueue_entry(&__wait, current); \ - \ - add_wait_queue(&wq, &__wait); \ - for (;;) { \ - set_current_state(TASK_INTERRUPTIBLE); \ - if (condition) \ - break; \ - if (!signal_pending(current)) { \ - ret = schedule_timeout(ret); \ - if (!ret) \ - break; \ - continue; \ - } \ - ret = -ERESTARTSYS; \ - break; \ - } \ - current->state = TASK_RUNNING; \ - remove_wait_queue(&wq, &__wait); \ -} while (0) - -#define wait_event_interruptible_timeout(wq, condition, timeout) \ -({ \ - long __ret = timeout; \ - if (!(condition)) \ - __wait_event_interruptible_timeout(wq, condition, __ret); \ - __ret; \ -}) - -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) -#define WL_DEV_IF(dev) ((wl_if_t*)netdev_priv(dev)) -#else -#define WL_DEV_IF(dev) ((wl_if_t*)(dev)->priv) -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) -#define WL_ISR(i, d, p) wl_isr((i), (d)) -#else -#define WL_ISR(i, d, p) wl_isr((i), (d), (p)) -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) -#define netdev_priv(dev) dev->priv -#endif - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/miniopt.h b/drivers/net/wireless/bcmdhd/include/miniopt.h deleted file mode 100644 index 77eace6252d7..000000000000 --- a/drivers/net/wireless/bcmdhd/include/miniopt.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Command line options parser. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * $Id: miniopt.h 277737 2011-08-16 17:54:59Z $ - */ - - -#ifndef MINI_OPT_H -#define MINI_OPT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* ---- Include Files ---------------------------------------------------- */ -/* ---- Constants and Types ---------------------------------------------- */ - -#define MINIOPT_MAXKEY 128 /* Max options */ -typedef struct miniopt { - - /* These are persistent after miniopt_init() */ - const char* name; /* name for prompt in error strings */ - const char* flags; /* option chars that take no args */ - bool longflags; /* long options may be flags */ - bool opt_end; /* at end of options (passed a "--") */ - - /* These are per-call to miniopt() */ - - int consumed; /* number of argv entries cosumed in - * the most recent call to miniopt() - */ - bool positional; - bool good_int; /* 'val' member is the result of a sucessful - * strtol conversion of the option value - */ - char opt; - char key[MINIOPT_MAXKEY]; - char* valstr; /* positional param, or value for the option, - * or null if the option had - * no accompanying value - */ - uint uval; /* strtol translation of valstr */ - int val; /* strtol translation of valstr */ -} miniopt_t; - -void miniopt_init(miniopt_t *t, const char* name, const char* flags, bool longflags); -int miniopt(miniopt_t *t, char **argv); - - -/* ---- Variable Externs ------------------------------------------------- */ -/* ---- Function Prototypes ---------------------------------------------- */ - - -#ifdef __cplusplus - } -#endif - -#endif /* MINI_OPT_H */ diff --git a/drivers/net/wireless/bcmdhd/include/msgtrace.h b/drivers/net/wireless/bcmdhd/include/msgtrace.h deleted file mode 100644 index 088f1e845a43..000000000000 --- a/drivers/net/wireless/bcmdhd/include/msgtrace.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Trace messages sent over HBUS - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: msgtrace.h 277737 2011-08-16 17:54:59Z $ - */ - -#ifndef _MSGTRACE_H -#define _MSGTRACE_H - -#ifndef _TYPEDEFS_H_ -#include -#endif - - -/* This marks the start of a packed structure section. */ -#include - -#define MSGTRACE_VERSION 1 - -/* Message trace header */ -typedef BWL_PRE_PACKED_STRUCT struct msgtrace_hdr { - uint8 version; - uint8 spare; - uint16 len; /* Len of the trace */ - uint32 seqnum; /* Sequence number of message. Useful if the messsage has been lost - * because of DMA error or a bus reset (ex: SDIO Func2) - */ - uint32 discarded_bytes; /* Number of discarded bytes because of trace overflow */ - uint32 discarded_printf; /* Number of discarded printf because of trace overflow */ -} BWL_POST_PACKED_STRUCT msgtrace_hdr_t; - -#define MSGTRACE_HDRLEN sizeof(msgtrace_hdr_t) - -/* The hbus driver generates traces when sending a trace message. This causes endless traces. - * This flag must be set to TRUE in any hbus traces. The flag is reset in the function msgtrace_put. - * This prevents endless traces but generates hasardous lost of traces only in bus device code. - * It is recommendat to set this flag in macro SD_TRACE but not in SD_ERROR for avoiding missing - * hbus error traces. hbus error trace should not generates endless traces. - */ -extern bool msgtrace_hbus_trace; - -typedef void (*msgtrace_func_send_t)(void *hdl1, void *hdl2, uint8 *hdr, - uint16 hdrlen, uint8 *buf, uint16 buflen); -extern void msgtrace_start(void); -extern void msgtrace_stop(void); -extern void msgtrace_sent(void); -extern void msgtrace_put(char *buf, int count); -extern void msgtrace_init(void *hdl1, void *hdl2, msgtrace_func_send_t func_send); -extern bool msgtrace_event_enabled(void); - -/* This marks the end of a packed structure section. */ -#include - -#endif /* _MSGTRACE_H */ diff --git a/drivers/net/wireless/bcmdhd/include/osl.h b/drivers/net/wireless/bcmdhd/include/osl.h deleted file mode 100644 index b8cc2569f506..000000000000 --- a/drivers/net/wireless/bcmdhd/include/osl.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * OS Abstraction Layer - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: osl.h 277737 2011-08-16 17:54:59Z $ - */ - - -#ifndef _osl_h_ -#define _osl_h_ - - -typedef struct osl_info osl_t; -typedef struct osl_dmainfo osldma_t; - -#define OSL_PKTTAG_SZ 32 - - -typedef void (*pktfree_cb_fn_t)(void *ctx, void *pkt, unsigned int status); - - -#include - -#ifndef PKTDBG_TRACE -#define PKTDBG_TRACE(osh, pkt, bit) -#endif - - - -#define SET_REG(osh, r, mask, val) W_REG((osh), (r), ((R_REG((osh), r) & ~(mask)) | (val))) - -#ifndef AND_REG -#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) -#endif - -#ifndef OR_REG -#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) -#endif - -#if !defined(OSL_SYSUPTIME) -#define OSL_SYSUPTIME() (0) -#define OSL_SYSUPTIME_SUPPORT FALSE -#else -#define OSL_SYSUPTIME_SUPPORT TRUE -#endif - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/packed_section_end.h b/drivers/net/wireless/bcmdhd/include/packed_section_end.h deleted file mode 100644 index 71f8b2e13b3b..000000000000 --- a/drivers/net/wireless/bcmdhd/include/packed_section_end.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Declare directives for structure packing. No padding will be provided - * between the members of packed structures, and therefore, there is no - * guarantee that structure members will be aligned. - * - * Declaring packed structures is compiler specific. In order to handle all - * cases, packed structures should be delared as: - * - * #include - * - * typedef BWL_PRE_PACKED_STRUCT struct foobar_t { - * some_struct_members; - * } BWL_POST_PACKED_STRUCT foobar_t; - * - * #include - * - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * $Id: packed_section_end.h 277737 2011-08-16 17:54:59Z $ - */ - - - - -#ifdef BWL_PACKED_SECTION - #undef BWL_PACKED_SECTION -#else - #error "BWL_PACKED_SECTION is NOT defined!" -#endif - - - - - -#undef BWL_PRE_PACKED_STRUCT -#undef BWL_POST_PACKED_STRUCT diff --git a/drivers/net/wireless/bcmdhd/include/packed_section_start.h b/drivers/net/wireless/bcmdhd/include/packed_section_start.h deleted file mode 100644 index afc2ba32fd93..000000000000 --- a/drivers/net/wireless/bcmdhd/include/packed_section_start.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Declare directives for structure packing. No padding will be provided - * between the members of packed structures, and therefore, there is no - * guarantee that structure members will be aligned. - * - * Declaring packed structures is compiler specific. In order to handle all - * cases, packed structures should be delared as: - * - * #include - * - * typedef BWL_PRE_PACKED_STRUCT struct foobar_t { - * some_struct_members; - * } BWL_POST_PACKED_STRUCT foobar_t; - * - * #include - * - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * $Id: packed_section_start.h 277737 2011-08-16 17:54:59Z $ - */ - - - - -#ifdef BWL_PACKED_SECTION - #error "BWL_PACKED_SECTION is already defined!" -#else - #define BWL_PACKED_SECTION -#endif - - - - - -#if defined(__GNUC__) - #define BWL_PRE_PACKED_STRUCT - #define BWL_POST_PACKED_STRUCT __attribute__ ((packed)) -#elif defined(__CC_ARM) - #define BWL_PRE_PACKED_STRUCT __packed - #define BWL_POST_PACKED_STRUCT -#else - #error "Unknown compiler!" -#endif diff --git a/drivers/net/wireless/bcmdhd/include/pcicfg.h b/drivers/net/wireless/bcmdhd/include/pcicfg.h deleted file mode 100644 index 66199431fb92..000000000000 --- a/drivers/net/wireless/bcmdhd/include/pcicfg.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * pcicfg.h: PCI configuration constants and structures. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: pcicfg.h 277737 2011-08-16 17:54:59Z $ - */ - - -#ifndef _h_pcicfg_ -#define _h_pcicfg_ - - -#define PCI_CFG_VID 0 -#define PCI_CFG_CMD 4 -#define PCI_CFG_REV 8 -#define PCI_CFG_BAR0 0x10 -#define PCI_CFG_BAR1 0x14 -#define PCI_BAR0_WIN 0x80 -#define PCI_INT_STATUS 0x90 -#define PCI_INT_MASK 0x94 - -#define PCIE_EXTCFG_OFFSET 0x100 -#define PCI_SPROM_CONTROL 0x88 -#define PCI_BAR1_CONTROL 0x8c -#define PCI_TO_SB_MB 0x98 -#define PCI_BACKPLANE_ADDR 0xa0 -#define PCI_BACKPLANE_DATA 0xa4 -#define PCI_CLK_CTL_ST 0xa8 -#define PCI_BAR0_WIN2 0xac -#define PCI_GPIO_IN 0xb0 -#define PCI_GPIO_OUT 0xb4 -#define PCI_GPIO_OUTEN 0xb8 - -#define PCI_BAR0_SHADOW_OFFSET (2 * 1024) -#define PCI_BAR0_SPROM_OFFSET (4 * 1024) -#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) -#define PCI_BAR0_PCISBR_OFFSET (4 * 1024) - -#define PCI_BAR0_WINSZ (16 * 1024) - - -#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) -#define PCI_16KB0_CCREGS_OFFSET (12 * 1024) -#define PCI_16KBB0_WINSZ (16 * 1024) - - -#define PCI_16KB0_WIN2_OFFSET (4 * 1024) - - - -#define SPROM_SZ_MSK 0x02 -#define SPROM_LOCKED 0x08 -#define SPROM_BLANK 0x04 -#define SPROM_WRITEEN 0x10 -#define SPROM_BOOTROM_WE 0x20 -#define SPROM_BACKPLANE_EN 0x40 -#define SPROM_OTPIN_USE 0x80 - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/proto/802.11.h b/drivers/net/wireless/bcmdhd/include/proto/802.11.h deleted file mode 100644 index fd69aac41309..000000000000 --- a/drivers/net/wireless/bcmdhd/include/proto/802.11.h +++ /dev/null @@ -1,2032 +0,0 @@ -/* - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * Fundamental types and constants relating to 802.11 - * - * $Id: 802.11.h 304058 2011-12-21 00:39:12Z $ - */ - - -#ifndef _802_11_H_ -#define _802_11_H_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - -#ifndef _NET_ETHERNET_H_ -#include -#endif - -#include - - -#include - - -#define DOT11_TU_TO_US 1024 - - -#define DOT11_A3_HDR_LEN 24 -#define DOT11_A4_HDR_LEN 30 -#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN -#define DOT11_FCS_LEN 4 -#define DOT11_ICV_LEN 4 -#define DOT11_ICV_AES_LEN 8 -#define DOT11_QOS_LEN 2 -#define DOT11_HTC_LEN 4 - -#define DOT11_KEY_INDEX_SHIFT 6 -#define DOT11_IV_LEN 4 -#define DOT11_IV_TKIP_LEN 8 -#define DOT11_IV_AES_OCB_LEN 4 -#define DOT11_IV_AES_CCM_LEN 8 -#define DOT11_IV_MAX_LEN 8 - - -#define DOT11_MAX_MPDU_BODY_LEN 2304 - -#define DOT11_MAX_MPDU_LEN (DOT11_A4_HDR_LEN + \ - DOT11_QOS_LEN + \ - DOT11_IV_AES_CCM_LEN + \ - DOT11_MAX_MPDU_BODY_LEN + \ - DOT11_ICV_LEN + \ - DOT11_FCS_LEN) - -#define DOT11_MAX_SSID_LEN 32 - - -#define DOT11_DEFAULT_RTS_LEN 2347 -#define DOT11_MAX_RTS_LEN 2347 - - -#define DOT11_MIN_FRAG_LEN 256 -#define DOT11_MAX_FRAG_LEN 2346 -#define DOT11_DEFAULT_FRAG_LEN 2346 - - -#define DOT11_MIN_BEACON_PERIOD 1 -#define DOT11_MAX_BEACON_PERIOD 0xFFFF - - -#define DOT11_MIN_DTIM_PERIOD 1 -#define DOT11_MAX_DTIM_PERIOD 0xFF - - -#define DOT11_LLC_SNAP_HDR_LEN 8 -#define DOT11_OUI_LEN 3 -BWL_PRE_PACKED_STRUCT struct dot11_llc_snap_header { - uint8 dsap; - uint8 ssap; - uint8 ctl; - uint8 oui[DOT11_OUI_LEN]; - uint16 type; -} BWL_POST_PACKED_STRUCT; - - -#define RFC1042_HDR_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN) - - - -BWL_PRE_PACKED_STRUCT struct dot11_header { - uint16 fc; - uint16 durid; - struct ether_addr a1; - struct ether_addr a2; - struct ether_addr a3; - uint16 seq; - struct ether_addr a4; -} BWL_POST_PACKED_STRUCT; - - - -BWL_PRE_PACKED_STRUCT struct dot11_rts_frame { - uint16 fc; - uint16 durid; - struct ether_addr ra; - struct ether_addr ta; -} BWL_POST_PACKED_STRUCT; -#define DOT11_RTS_LEN 16 - -BWL_PRE_PACKED_STRUCT struct dot11_cts_frame { - uint16 fc; - uint16 durid; - struct ether_addr ra; -} BWL_POST_PACKED_STRUCT; -#define DOT11_CTS_LEN 10 - -BWL_PRE_PACKED_STRUCT struct dot11_ack_frame { - uint16 fc; - uint16 durid; - struct ether_addr ra; -} BWL_POST_PACKED_STRUCT; -#define DOT11_ACK_LEN 10 - -BWL_PRE_PACKED_STRUCT struct dot11_ps_poll_frame { - uint16 fc; - uint16 durid; - struct ether_addr bssid; - struct ether_addr ta; -} BWL_POST_PACKED_STRUCT; -#define DOT11_PS_POLL_LEN 16 - -BWL_PRE_PACKED_STRUCT struct dot11_cf_end_frame { - uint16 fc; - uint16 durid; - struct ether_addr ra; - struct ether_addr bssid; -} BWL_POST_PACKED_STRUCT; -#define DOT11_CS_END_LEN 16 - - -BWL_PRE_PACKED_STRUCT struct dot11_action_wifi_vendor_specific { - uint8 category; - uint8 OUI[3]; - uint8 type; - uint8 subtype; - uint8 data[1040]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_action_wifi_vendor_specific dot11_action_wifi_vendor_specific_t; - - -BWL_PRE_PACKED_STRUCT struct dot11_action_vs_frmhdr { - uint8 category; - uint8 OUI[3]; - uint8 type; - uint8 subtype; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_action_vs_frmhdr dot11_action_vs_frmhdr_t; -#define DOT11_ACTION_VS_HDR_LEN 6 - -#define BCM_ACTION_OUI_BYTE0 0x00 -#define BCM_ACTION_OUI_BYTE1 0x90 -#define BCM_ACTION_OUI_BYTE2 0x4c - - -#define DOT11_BA_CTL_POLICY_NORMAL 0x0000 -#define DOT11_BA_CTL_POLICY_NOACK 0x0001 -#define DOT11_BA_CTL_POLICY_MASK 0x0001 - -#define DOT11_BA_CTL_MTID 0x0002 -#define DOT11_BA_CTL_COMPRESSED 0x0004 - -#define DOT11_BA_CTL_NUMMSDU_MASK 0x0FC0 -#define DOT11_BA_CTL_NUMMSDU_SHIFT 6 - -#define DOT11_BA_CTL_TID_MASK 0xF000 -#define DOT11_BA_CTL_TID_SHIFT 12 - - -BWL_PRE_PACKED_STRUCT struct dot11_ctl_header { - uint16 fc; - uint16 durid; - struct ether_addr ra; - struct ether_addr ta; -} BWL_POST_PACKED_STRUCT; -#define DOT11_CTL_HDR_LEN 16 - - -BWL_PRE_PACKED_STRUCT struct dot11_bar { - uint16 bar_control; - uint16 seqnum; -} BWL_POST_PACKED_STRUCT; -#define DOT11_BAR_LEN 4 - -#define DOT11_BA_BITMAP_LEN 128 -#define DOT11_BA_CMP_BITMAP_LEN 8 - -BWL_PRE_PACKED_STRUCT struct dot11_ba { - uint16 ba_control; - uint16 seqnum; - uint8 bitmap[DOT11_BA_BITMAP_LEN]; -} BWL_POST_PACKED_STRUCT; -#define DOT11_BA_LEN 4 - - -BWL_PRE_PACKED_STRUCT struct dot11_management_header { - uint16 fc; - uint16 durid; - struct ether_addr da; - struct ether_addr sa; - struct ether_addr bssid; - uint16 seq; -} BWL_POST_PACKED_STRUCT; -#define DOT11_MGMT_HDR_LEN 24 - - - -BWL_PRE_PACKED_STRUCT struct dot11_bcn_prb { - uint32 timestamp[2]; - uint16 beacon_interval; - uint16 capability; -} BWL_POST_PACKED_STRUCT; -#define DOT11_BCN_PRB_LEN 12 -#define DOT11_BCN_PRB_FIXED_LEN 12 - -BWL_PRE_PACKED_STRUCT struct dot11_auth { - uint16 alg; - uint16 seq; - uint16 status; -} BWL_POST_PACKED_STRUCT; -#define DOT11_AUTH_FIXED_LEN 6 - -BWL_PRE_PACKED_STRUCT struct dot11_assoc_req { - uint16 capability; - uint16 listen; -} BWL_POST_PACKED_STRUCT; -#define DOT11_ASSOC_REQ_FIXED_LEN 4 - -BWL_PRE_PACKED_STRUCT struct dot11_reassoc_req { - uint16 capability; - uint16 listen; - struct ether_addr ap; -} BWL_POST_PACKED_STRUCT; -#define DOT11_REASSOC_REQ_FIXED_LEN 10 - -BWL_PRE_PACKED_STRUCT struct dot11_assoc_resp { - uint16 capability; - uint16 status; - uint16 aid; -} BWL_POST_PACKED_STRUCT; -#define DOT11_ASSOC_RESP_FIXED_LEN 6 - -BWL_PRE_PACKED_STRUCT struct dot11_action_measure { - uint8 category; - uint8 action; - uint8 token; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT; -#define DOT11_ACTION_MEASURE_LEN 3 - -BWL_PRE_PACKED_STRUCT struct dot11_action_ht_ch_width { - uint8 category; - uint8 action; - uint8 ch_width; -} BWL_POST_PACKED_STRUCT; - -BWL_PRE_PACKED_STRUCT struct dot11_action_ht_mimops { - uint8 category; - uint8 action; - uint8 control; -} BWL_POST_PACKED_STRUCT; - -#define SM_PWRSAVE_ENABLE 1 -#define SM_PWRSAVE_MODE 2 - - -BWL_PRE_PACKED_STRUCT struct dot11_power_cnst { - uint8 id; - uint8 len; - uint8 power; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_power_cnst dot11_power_cnst_t; - -BWL_PRE_PACKED_STRUCT struct dot11_power_cap { - uint8 min; - uint8 max; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_power_cap dot11_power_cap_t; - -BWL_PRE_PACKED_STRUCT struct dot11_tpc_rep { - uint8 id; - uint8 len; - uint8 tx_pwr; - uint8 margin; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_tpc_rep dot11_tpc_rep_t; -#define DOT11_MNG_IE_TPC_REPORT_LEN 2 - -BWL_PRE_PACKED_STRUCT struct dot11_supp_channels { - uint8 id; - uint8 len; - uint8 first_channel; - uint8 num_channels; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_supp_channels dot11_supp_channels_t; - - -BWL_PRE_PACKED_STRUCT struct dot11_extch { - uint8 id; - uint8 len; - uint8 extch; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_extch dot11_extch_ie_t; - -BWL_PRE_PACKED_STRUCT struct dot11_brcm_extch { - uint8 id; - uint8 len; - uint8 oui[3]; - uint8 type; - uint8 extch; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_brcm_extch dot11_brcm_extch_ie_t; - -#define BRCM_EXTCH_IE_LEN 5 -#define BRCM_EXTCH_IE_TYPE 53 -#define DOT11_EXTCH_IE_LEN 1 -#define DOT11_EXT_CH_MASK 0x03 -#define DOT11_EXT_CH_UPPER 0x01 -#define DOT11_EXT_CH_LOWER 0x03 -#define DOT11_EXT_CH_NONE 0x00 - -BWL_PRE_PACKED_STRUCT struct dot11_action_frmhdr { - uint8 category; - uint8 action; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT; -#define DOT11_ACTION_FRMHDR_LEN 2 - - -BWL_PRE_PACKED_STRUCT struct dot11_channel_switch { - uint8 id; - uint8 len; - uint8 mode; - uint8 channel; - uint8 count; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_channel_switch dot11_chan_switch_ie_t; - -#define DOT11_SWITCH_IE_LEN 3 - -#define DOT11_CSA_MODE_ADVISORY 0 -#define DOT11_CSA_MODE_NO_TX 1 - -BWL_PRE_PACKED_STRUCT struct dot11_action_switch_channel { - uint8 category; - uint8 action; - dot11_chan_switch_ie_t chan_switch_ie; - dot11_brcm_extch_ie_t extch_ie; -} BWL_POST_PACKED_STRUCT; - -BWL_PRE_PACKED_STRUCT struct dot11_csa_body { - uint8 mode; - uint8 reg; - uint8 channel; - uint8 count; -} BWL_POST_PACKED_STRUCT; - - -BWL_PRE_PACKED_STRUCT struct dot11_ext_csa { - uint8 id; - uint8 len; - struct dot11_csa_body b; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_ext_csa dot11_ext_csa_ie_t; -#define DOT11_EXT_CSA_IE_LEN 4 - -BWL_PRE_PACKED_STRUCT struct dot11_action_ext_csa { - uint8 category; - uint8 action; - dot11_ext_csa_ie_t chan_switch_ie; -} BWL_POST_PACKED_STRUCT; - -BWL_PRE_PACKED_STRUCT struct dot11y_action_ext_csa { - uint8 category; - uint8 action; - struct dot11_csa_body b; -} BWL_POST_PACKED_STRUCT; - -BWL_PRE_PACKED_STRUCT struct dot11_obss_coex { - uint8 id; - uint8 len; - uint8 info; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_obss_coex dot11_obss_coex_t; -#define DOT11_OBSS_COEXINFO_LEN 1 - -#define DOT11_OBSS_COEX_INFO_REQ 0x01 -#define DOT11_OBSS_COEX_40MHZ_INTOLERANT 0x02 -#define DOT11_OBSS_COEX_20MHZ_WIDTH_REQ 0x04 - -BWL_PRE_PACKED_STRUCT struct dot11_obss_chanlist { - uint8 id; - uint8 len; - uint8 regclass; - uint8 chanlist[1]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_obss_chanlist dot11_obss_chanlist_t; -#define DOT11_OBSS_CHANLIST_FIXED_LEN 1 - -BWL_PRE_PACKED_STRUCT struct dot11_extcap_ie { - uint8 id; - uint8 len; - uint8 cap[1]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_extcap_ie dot11_extcap_ie_t; -#define DOT11_EXTCAP_LEN 1 -#define DOT11_EXTCAP_LEN_TDLS 5 - -BWL_PRE_PACKED_STRUCT struct dot11_extcap { - uint8 extcap[DOT11_EXTCAP_LEN_TDLS]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_extcap dot11_extcap_t; - - -#define TDLS_CAP_TDLS 37 -#define TDLS_CAP_PU_BUFFER_STA 28 -#define TDLS_CAP_PEER_PSM 20 -#define TDLS_CAP_CH_SW 30 -#define TDLS_CAP_PROH 38 -#define TDLS_CAP_CH_SW_PROH 39 - -#define TDLS_CAP_MAX_BIT 39 - - - -#define DOT11_MEASURE_TYPE_BASIC 0 -#define DOT11_MEASURE_TYPE_CCA 1 -#define DOT11_MEASURE_TYPE_RPI 2 -#define DOT11_MEASURE_TYPE_CHLOAD 3 -#define DOT11_MEASURE_TYPE_NOISE 4 -#define DOT11_MEASURE_TYPE_BEACON 5 -#define DOT11_MEASURE_TYPE_FRAME 6 -#define DOT11_MEASURE_TYPE_STATS 7 -#define DOT11_MEASURE_TYPE_LCI 8 -#define DOT11_MEASURE_TYPE_TXSTREAM 9 -#define DOT11_MEASURE_TYPE_PAUSE 255 - - -#define DOT11_MEASURE_MODE_PARALLEL (1<<0) -#define DOT11_MEASURE_MODE_ENABLE (1<<1) -#define DOT11_MEASURE_MODE_REQUEST (1<<2) -#define DOT11_MEASURE_MODE_REPORT (1<<3) -#define DOT11_MEASURE_MODE_DUR (1<<4) - -#define DOT11_MEASURE_MODE_LATE (1<<0) -#define DOT11_MEASURE_MODE_INCAPABLE (1<<1) -#define DOT11_MEASURE_MODE_REFUSED (1<<2) - -#define DOT11_MEASURE_BASIC_MAP_BSS ((uint8)(1<<0)) -#define DOT11_MEASURE_BASIC_MAP_OFDM ((uint8)(1<<1)) -#define DOT11_MEASURE_BASIC_MAP_UKNOWN ((uint8)(1<<2)) -#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3)) -#define DOT11_MEASURE_BASIC_MAP_UNMEAS ((uint8)(1<<4)) - -BWL_PRE_PACKED_STRUCT struct dot11_meas_req { - uint8 id; - uint8 len; - uint8 token; - uint8 mode; - uint8 type; - uint8 channel; - uint8 start_time[8]; - uint16 duration; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_meas_req dot11_meas_req_t; -#define DOT11_MNG_IE_MREQ_LEN 14 - -#define DOT11_MNG_IE_MREQ_FIXED_LEN 3 - -BWL_PRE_PACKED_STRUCT struct dot11_meas_rep { - uint8 id; - uint8 len; - uint8 token; - uint8 mode; - uint8 type; - BWL_PRE_PACKED_STRUCT union - { - BWL_PRE_PACKED_STRUCT struct { - uint8 channel; - uint8 start_time[8]; - uint16 duration; - uint8 map; - } BWL_POST_PACKED_STRUCT basic; - uint8 data[1]; - } BWL_POST_PACKED_STRUCT rep; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_meas_rep dot11_meas_rep_t; - - -#define DOT11_MNG_IE_MREP_FIXED_LEN 3 - -BWL_PRE_PACKED_STRUCT struct dot11_meas_rep_basic { - uint8 channel; - uint8 start_time[8]; - uint16 duration; - uint8 map; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_meas_rep_basic dot11_meas_rep_basic_t; -#define DOT11_MEASURE_BASIC_REP_LEN 12 - -BWL_PRE_PACKED_STRUCT struct dot11_quiet { - uint8 id; - uint8 len; - uint8 count; - uint8 period; - uint16 duration; - uint16 offset; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_quiet dot11_quiet_t; - -BWL_PRE_PACKED_STRUCT struct chan_map_tuple { - uint8 channel; - uint8 map; -} BWL_POST_PACKED_STRUCT; -typedef struct chan_map_tuple chan_map_tuple_t; - -BWL_PRE_PACKED_STRUCT struct dot11_ibss_dfs { - uint8 id; - uint8 len; - uint8 eaddr[ETHER_ADDR_LEN]; - uint8 interval; - chan_map_tuple_t map[1]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_ibss_dfs dot11_ibss_dfs_t; - - -#define WME_OUI "\x00\x50\xf2" -#define WME_OUI_LEN 3 -#define WME_OUI_TYPE 2 -#define WME_VER 1 -#define WME_TYPE 2 -#define WME_SUBTYPE_IE 0 -#define WME_SUBTYPE_PARAM_IE 1 -#define WME_SUBTYPE_TSPEC 2 -#define WME_VERSION_LEN 1 -#define WME_PARAMETER_IE_LEN 24 - - - -#define AC_BE 0 -#define AC_BK 1 -#define AC_VI 2 -#define AC_VO 3 -#define AC_COUNT 4 - -typedef uint8 ac_bitmap_t; - -#define AC_BITMAP_NONE 0x0 -#define AC_BITMAP_ALL 0xf -#define AC_BITMAP_TST(ab, ac) (((ab) & (1 << (ac))) != 0) -#define AC_BITMAP_SET(ab, ac) (((ab) |= (1 << (ac)))) -#define AC_BITMAP_RESET(ab, ac) (((ab) &= ~(1 << (ac)))) - - -BWL_PRE_PACKED_STRUCT struct wme_ie { - uint8 oui[3]; - uint8 type; - uint8 subtype; - uint8 version; - uint8 qosinfo; -} BWL_POST_PACKED_STRUCT; -typedef struct wme_ie wme_ie_t; -#define WME_IE_LEN 7 - -BWL_PRE_PACKED_STRUCT struct edcf_acparam { - uint8 ACI; - uint8 ECW; - uint16 TXOP; -} BWL_POST_PACKED_STRUCT; -typedef struct edcf_acparam edcf_acparam_t; - - -BWL_PRE_PACKED_STRUCT struct wme_param_ie { - uint8 oui[3]; - uint8 type; - uint8 subtype; - uint8 version; - uint8 qosinfo; - uint8 rsvd; - edcf_acparam_t acparam[AC_COUNT]; -} BWL_POST_PACKED_STRUCT; -typedef struct wme_param_ie wme_param_ie_t; -#define WME_PARAM_IE_LEN 24 - - -#define WME_QI_AP_APSD_MASK 0x80 -#define WME_QI_AP_APSD_SHIFT 7 -#define WME_QI_AP_COUNT_MASK 0x0f -#define WME_QI_AP_COUNT_SHIFT 0 - - -#define WME_QI_STA_MAXSPLEN_MASK 0x60 -#define WME_QI_STA_MAXSPLEN_SHIFT 5 -#define WME_QI_STA_APSD_ALL_MASK 0xf -#define WME_QI_STA_APSD_ALL_SHIFT 0 -#define WME_QI_STA_APSD_BE_MASK 0x8 -#define WME_QI_STA_APSD_BE_SHIFT 3 -#define WME_QI_STA_APSD_BK_MASK 0x4 -#define WME_QI_STA_APSD_BK_SHIFT 2 -#define WME_QI_STA_APSD_VI_MASK 0x2 -#define WME_QI_STA_APSD_VI_SHIFT 1 -#define WME_QI_STA_APSD_VO_MASK 0x1 -#define WME_QI_STA_APSD_VO_SHIFT 0 - - -#define EDCF_AIFSN_MIN 1 -#define EDCF_AIFSN_MAX 15 -#define EDCF_AIFSN_MASK 0x0f -#define EDCF_ACM_MASK 0x10 -#define EDCF_ACI_MASK 0x60 -#define EDCF_ACI_SHIFT 5 -#define EDCF_AIFSN_SHIFT 12 - - -#define EDCF_ECW_MIN 0 -#define EDCF_ECW_MAX 15 -#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) -#define EDCF_ECWMIN_MASK 0x0f -#define EDCF_ECWMAX_MASK 0xf0 -#define EDCF_ECWMAX_SHIFT 4 - - -#define EDCF_TXOP_MIN 0 -#define EDCF_TXOP_MAX 65535 -#define EDCF_TXOP2USEC(txop) ((txop) << 5) - - -#define NON_EDCF_AC_BE_ACI_STA 0x02 - - -#define EDCF_AC_BE_ACI_STA 0x03 -#define EDCF_AC_BE_ECW_STA 0xA4 -#define EDCF_AC_BE_TXOP_STA 0x0000 -#define EDCF_AC_BK_ACI_STA 0x27 -#define EDCF_AC_BK_ECW_STA 0xA4 -#define EDCF_AC_BK_TXOP_STA 0x0000 -#define EDCF_AC_VI_ACI_STA 0x42 -#define EDCF_AC_VI_ECW_STA 0x43 -#define EDCF_AC_VI_TXOP_STA 0x005e -#define EDCF_AC_VO_ACI_STA 0x62 -#define EDCF_AC_VO_ECW_STA 0x32 -#define EDCF_AC_VO_TXOP_STA 0x002f - - -#define EDCF_AC_BE_ACI_AP 0x03 -#define EDCF_AC_BE_ECW_AP 0x64 -#define EDCF_AC_BE_TXOP_AP 0x0000 -#define EDCF_AC_BK_ACI_AP 0x27 -#define EDCF_AC_BK_ECW_AP 0xA4 -#define EDCF_AC_BK_TXOP_AP 0x0000 -#define EDCF_AC_VI_ACI_AP 0x41 -#define EDCF_AC_VI_ECW_AP 0x43 -#define EDCF_AC_VI_TXOP_AP 0x005e -#define EDCF_AC_VO_ACI_AP 0x61 -#define EDCF_AC_VO_ECW_AP 0x32 -#define EDCF_AC_VO_TXOP_AP 0x002f - - -BWL_PRE_PACKED_STRUCT struct edca_param_ie { - uint8 qosinfo; - uint8 rsvd; - edcf_acparam_t acparam[AC_COUNT]; -} BWL_POST_PACKED_STRUCT; -typedef struct edca_param_ie edca_param_ie_t; -#define EDCA_PARAM_IE_LEN 18 - - -BWL_PRE_PACKED_STRUCT struct qos_cap_ie { - uint8 qosinfo; -} BWL_POST_PACKED_STRUCT; -typedef struct qos_cap_ie qos_cap_ie_t; - -BWL_PRE_PACKED_STRUCT struct dot11_qbss_load_ie { - uint8 id; - uint8 length; - uint16 station_count; - uint8 channel_utilization; - uint16 aac; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_qbss_load_ie dot11_qbss_load_ie_t; - - -#define FIXED_MSDU_SIZE 0x8000 -#define MSDU_SIZE_MASK 0x7fff - - - -#define INTEGER_SHIFT 13 -#define FRACTION_MASK 0x1FFF - - -BWL_PRE_PACKED_STRUCT struct dot11_management_notification { - uint8 category; - uint8 action; - uint8 token; - uint8 status; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT; -#define DOT11_MGMT_NOTIFICATION_LEN 4 - - -BWL_PRE_PACKED_STRUCT struct ti_ie { - uint8 ti_type; - uint32 ti_val; -} BWL_POST_PACKED_STRUCT; -typedef struct ti_ie ti_ie_t; -#define TI_TYPE_REASSOC_DEADLINE 1 -#define TI_TYPE_KEY_LIFETIME 2 - - -#define WME_ADDTS_REQUEST 0 -#define WME_ADDTS_RESPONSE 1 -#define WME_DELTS_REQUEST 2 - - -#define WME_ADMISSION_ACCEPTED 0 -#define WME_INVALID_PARAMETERS 1 -#define WME_ADMISSION_REFUSED 3 - - -#define BCN_PRB_SSID(body) ((char*)(body) + DOT11_BCN_PRB_LEN) - - -#define DOT11_OPEN_SYSTEM 0 -#define DOT11_SHARED_KEY 1 -#define DOT11_FAST_BSS 2 -#define DOT11_CHALLENGE_LEN 128 - - -#define FC_PVER_MASK 0x3 -#define FC_PVER_SHIFT 0 -#define FC_TYPE_MASK 0xC -#define FC_TYPE_SHIFT 2 -#define FC_SUBTYPE_MASK 0xF0 -#define FC_SUBTYPE_SHIFT 4 -#define FC_TODS 0x100 -#define FC_TODS_SHIFT 8 -#define FC_FROMDS 0x200 -#define FC_FROMDS_SHIFT 9 -#define FC_MOREFRAG 0x400 -#define FC_MOREFRAG_SHIFT 10 -#define FC_RETRY 0x800 -#define FC_RETRY_SHIFT 11 -#define FC_PM 0x1000 -#define FC_PM_SHIFT 12 -#define FC_MOREDATA 0x2000 -#define FC_MOREDATA_SHIFT 13 -#define FC_WEP 0x4000 -#define FC_WEP_SHIFT 14 -#define FC_ORDER 0x8000 -#define FC_ORDER_SHIFT 15 - - -#define SEQNUM_SHIFT 4 -#define SEQNUM_MAX 0x1000 -#define FRAGNUM_MASK 0xF - - - - -#define FC_TYPE_MNG 0 -#define FC_TYPE_CTL 1 -#define FC_TYPE_DATA 2 - - -#define FC_SUBTYPE_ASSOC_REQ 0 -#define FC_SUBTYPE_ASSOC_RESP 1 -#define FC_SUBTYPE_REASSOC_REQ 2 -#define FC_SUBTYPE_REASSOC_RESP 3 -#define FC_SUBTYPE_PROBE_REQ 4 -#define FC_SUBTYPE_PROBE_RESP 5 -#define FC_SUBTYPE_BEACON 8 -#define FC_SUBTYPE_ATIM 9 -#define FC_SUBTYPE_DISASSOC 10 -#define FC_SUBTYPE_AUTH 11 -#define FC_SUBTYPE_DEAUTH 12 -#define FC_SUBTYPE_ACTION 13 -#define FC_SUBTYPE_ACTION_NOACK 14 - - -#define FC_SUBTYPE_CTL_WRAPPER 7 -#define FC_SUBTYPE_BLOCKACK_REQ 8 -#define FC_SUBTYPE_BLOCKACK 9 -#define FC_SUBTYPE_PS_POLL 10 -#define FC_SUBTYPE_RTS 11 -#define FC_SUBTYPE_CTS 12 -#define FC_SUBTYPE_ACK 13 -#define FC_SUBTYPE_CF_END 14 -#define FC_SUBTYPE_CF_END_ACK 15 - - -#define FC_SUBTYPE_DATA 0 -#define FC_SUBTYPE_DATA_CF_ACK 1 -#define FC_SUBTYPE_DATA_CF_POLL 2 -#define FC_SUBTYPE_DATA_CF_ACK_POLL 3 -#define FC_SUBTYPE_NULL 4 -#define FC_SUBTYPE_CF_ACK 5 -#define FC_SUBTYPE_CF_POLL 6 -#define FC_SUBTYPE_CF_ACK_POLL 7 -#define FC_SUBTYPE_QOS_DATA 8 -#define FC_SUBTYPE_QOS_DATA_CF_ACK 9 -#define FC_SUBTYPE_QOS_DATA_CF_POLL 10 -#define FC_SUBTYPE_QOS_DATA_CF_ACK_POLL 11 -#define FC_SUBTYPE_QOS_NULL 12 -#define FC_SUBTYPE_QOS_CF_POLL 14 -#define FC_SUBTYPE_QOS_CF_ACK_POLL 15 - - -#define FC_SUBTYPE_ANY_QOS(s) (((s) & 8) != 0) -#define FC_SUBTYPE_ANY_NULL(s) (((s) & 4) != 0) -#define FC_SUBTYPE_ANY_CF_POLL(s) (((s) & 2) != 0) -#define FC_SUBTYPE_ANY_CF_ACK(s) (((s) & 1) != 0) - - -#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK) - -#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT)) - -#define FC_SUBTYPE(fc) (((fc) & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT) -#define FC_TYPE(fc) (((fc) & FC_TYPE_MASK) >> FC_TYPE_SHIFT) - -#define FC_ASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ) -#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP) -#define FC_REASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ) -#define FC_REASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP) -#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ) -#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP) -#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON) -#define FC_DISASSOC FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC) -#define FC_AUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH) -#define FC_DEAUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH) -#define FC_ACTION FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION) -#define FC_ACTION_NOACK FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION_NOACK) - -#define FC_CTL_WRAPPER FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTL_WRAPPER) -#define FC_BLOCKACK_REQ FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK_REQ) -#define FC_BLOCKACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK) -#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL) -#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS) -#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS) -#define FC_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK) -#define FC_CF_END FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END) -#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK) - -#define FC_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA) -#define FC_NULL_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL) -#define FC_DATA_CF_ACK FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK) -#define FC_QOS_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_DATA) -#define FC_QOS_NULL FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_NULL) - - - - -#define QOS_PRIO_SHIFT 0 -#define QOS_PRIO_MASK 0x0007 -#define QOS_PRIO(qos) (((qos) & QOS_PRIO_MASK) >> QOS_PRIO_SHIFT) - - -#define QOS_TID_SHIFT 0 -#define QOS_TID_MASK 0x000f -#define QOS_TID(qos) (((qos) & QOS_TID_MASK) >> QOS_TID_SHIFT) - - -#define QOS_EOSP_SHIFT 4 -#define QOS_EOSP_MASK 0x0010 -#define QOS_EOSP(qos) (((qos) & QOS_EOSP_MASK) >> QOS_EOSP_SHIFT) - - -#define QOS_ACK_NORMAL_ACK 0 -#define QOS_ACK_NO_ACK 1 -#define QOS_ACK_NO_EXP_ACK 2 -#define QOS_ACK_BLOCK_ACK 3 -#define QOS_ACK_SHIFT 5 -#define QOS_ACK_MASK 0x0060 -#define QOS_ACK(qos) (((qos) & QOS_ACK_MASK) >> QOS_ACK_SHIFT) - - -#define QOS_AMSDU_SHIFT 7 -#define QOS_AMSDU_MASK 0x0080 - - - - - - -#define DOT11_MNG_AUTH_ALGO_LEN 2 -#define DOT11_MNG_AUTH_SEQ_LEN 2 -#define DOT11_MNG_BEACON_INT_LEN 2 -#define DOT11_MNG_CAP_LEN 2 -#define DOT11_MNG_AP_ADDR_LEN 6 -#define DOT11_MNG_LISTEN_INT_LEN 2 -#define DOT11_MNG_REASON_LEN 2 -#define DOT11_MNG_AID_LEN 2 -#define DOT11_MNG_STATUS_LEN 2 -#define DOT11_MNG_TIMESTAMP_LEN 8 - - -#define DOT11_AID_MASK 0x3fff - - -#define DOT11_RC_RESERVED 0 -#define DOT11_RC_UNSPECIFIED 1 -#define DOT11_RC_AUTH_INVAL 2 -#define DOT11_RC_DEAUTH_LEAVING 3 -#define DOT11_RC_INACTIVITY 4 -#define DOT11_RC_BUSY 5 -#define DOT11_RC_INVAL_CLASS_2 6 -#define DOT11_RC_INVAL_CLASS_3 7 -#define DOT11_RC_DISASSOC_LEAVING 8 -#define DOT11_RC_NOT_AUTH 9 -#define DOT11_RC_BAD_PC 10 -#define DOT11_RC_BAD_CHANNELS 11 - - - -#define DOT11_RC_UNSPECIFIED_QOS 32 -#define DOT11_RC_INSUFFCIENT_BW 33 -#define DOT11_RC_EXCESSIVE_FRAMES 34 -#define DOT11_RC_TX_OUTSIDE_TXOP 35 -#define DOT11_RC_LEAVING_QBSS 36 -#define DOT11_RC_BAD_MECHANISM 37 -#define DOT11_RC_SETUP_NEEDED 38 -#define DOT11_RC_TIMEOUT 39 - -#define DOT11_RC_MAX 23 - -#define DOT11_RC_TDLS_PEER_UNREACH 25 -#define DOT11_RC_TDLS_DOWN_UNSPECIFIED 26 - - -#define DOT11_SC_SUCCESS 0 -#define DOT11_SC_FAILURE 1 -#define DOT11_SC_TDLS_WAKEUP_SCH_ALT 2 - -#define DOT11_SC_TDLS_WAKEUP_SCH_REJ 3 -#define DOT11_SC_TDLS_SEC_DISABLED 5 -#define DOT11_SC_LIFETIME_REJ 6 -#define DOT11_SC_NOT_SAME_BSS 7 -#define DOT11_SC_CAP_MISMATCH 10 -#define DOT11_SC_REASSOC_FAIL 11 -#define DOT11_SC_ASSOC_FAIL 12 -#define DOT11_SC_AUTH_MISMATCH 13 -#define DOT11_SC_AUTH_SEQ 14 -#define DOT11_SC_AUTH_CHALLENGE_FAIL 15 -#define DOT11_SC_AUTH_TIMEOUT 16 -#define DOT11_SC_ASSOC_BUSY_FAIL 17 -#define DOT11_SC_ASSOC_RATE_MISMATCH 18 -#define DOT11_SC_ASSOC_SHORT_REQUIRED 19 -#define DOT11_SC_ASSOC_PBCC_REQUIRED 20 -#define DOT11_SC_ASSOC_AGILITY_REQUIRED 21 -#define DOT11_SC_ASSOC_SPECTRUM_REQUIRED 22 -#define DOT11_SC_ASSOC_BAD_POWER_CAP 23 -#define DOT11_SC_ASSOC_BAD_SUP_CHANNELS 24 -#define DOT11_SC_ASSOC_SHORTSLOT_REQUIRED 25 -#define DOT11_SC_ASSOC_ERPBCC_REQUIRED 26 -#define DOT11_SC_ASSOC_DSSOFDM_REQUIRED 27 -#define DOT11_SC_ASSOC_R0KH_UNREACHABLE 28 -#define DOT11_SC_ASSOC_TRY_LATER 30 -#define DOT11_SC_ASSOC_MFP_VIOLATION 31 - -#define DOT11_SC_DECLINED 37 -#define DOT11_SC_INVALID_PARAMS 38 -#define DOT11_SC_INVALID_PAIRWISE_CIPHER 42 -#define DOT11_SC_INVALID_AKMP 43 -#define DOT11_SC_INVALID_RSNIE_CAP 45 -#define DOT11_SC_INVALID_PMKID 53 -#define DOT11_SC_INVALID_MDID 54 -#define DOT11_SC_INVALID_FTIE 55 - -#define DOT11_SC_UNEXP_MSG 70 -#define DOT11_SC_INVALID_SNONCE 71 -#define DOT11_SC_INVALID_RSNIE 72 - -#define DOT11_MNG_DS_PARAM_LEN 1 -#define DOT11_MNG_IBSS_PARAM_LEN 2 - - -#define DOT11_MNG_TIM_FIXED_LEN 3 -#define DOT11_MNG_TIM_DTIM_COUNT 0 -#define DOT11_MNG_TIM_DTIM_PERIOD 1 -#define DOT11_MNG_TIM_BITMAP_CTL 2 -#define DOT11_MNG_TIM_PVB 3 - - -#define TLV_TAG_OFF 0 -#define TLV_LEN_OFF 1 -#define TLV_HDR_LEN 2 -#define TLV_BODY_OFF 2 - - -#define DOT11_MNG_SSID_ID 0 -#define DOT11_MNG_RATES_ID 1 -#define DOT11_MNG_FH_PARMS_ID 2 -#define DOT11_MNG_DS_PARMS_ID 3 -#define DOT11_MNG_CF_PARMS_ID 4 -#define DOT11_MNG_TIM_ID 5 -#define DOT11_MNG_IBSS_PARMS_ID 6 -#define DOT11_MNG_COUNTRY_ID 7 -#define DOT11_MNG_HOPPING_PARMS_ID 8 -#define DOT11_MNG_HOPPING_TABLE_ID 9 -#define DOT11_MNG_REQUEST_ID 10 -#define DOT11_MNG_QBSS_LOAD_ID 11 -#define DOT11_MNG_EDCA_PARAM_ID 12 -#define DOT11_MNG_CHALLENGE_ID 16 -#define DOT11_MNG_PWR_CONSTRAINT_ID 32 -#define DOT11_MNG_PWR_CAP_ID 33 -#define DOT11_MNG_TPC_REQUEST_ID 34 -#define DOT11_MNG_TPC_REPORT_ID 35 -#define DOT11_MNG_SUPP_CHANNELS_ID 36 -#define DOT11_MNG_CHANNEL_SWITCH_ID 37 -#define DOT11_MNG_MEASURE_REQUEST_ID 38 -#define DOT11_MNG_MEASURE_REPORT_ID 39 -#define DOT11_MNG_QUIET_ID 40 -#define DOT11_MNG_IBSS_DFS_ID 41 -#define DOT11_MNG_ERP_ID 42 -#define DOT11_MNG_TS_DELAY_ID 43 -#define DOT11_MNG_HT_CAP 45 -#define DOT11_MNG_QOS_CAP_ID 46 -#define DOT11_MNG_NONERP_ID 47 -#define DOT11_MNG_RSN_ID 48 -#define DOT11_MNG_EXT_RATES_ID 50 -#define DOT11_MNG_AP_CHREP_ID 51 -#define DOT11_MNG_NBR_REP_ID 52 -#define DOT11_MNG_MDIE_ID 54 -#define DOT11_MNG_FTIE_ID 55 -#define DOT11_MNG_FT_TI_ID 56 -#define DOT11_MNG_RDE_ID 57 -#define DOT11_MNG_REGCLASS_ID 59 -#define DOT11_MNG_EXT_CSA_ID 60 -#define DOT11_MNG_HT_ADD 61 -#define DOT11_MNG_EXT_CHANNEL_OFFSET 62 - - -#define DOT11_MNG_RRM_CAP_ID 70 -#define DOT11_MNG_HT_BSS_COEXINFO_ID 72 -#define DOT11_MNG_HT_BSS_CHANNEL_REPORT_ID 73 -#define DOT11_MNG_HT_OBSS_ID 74 -#define DOT11_MNG_CHANNEL_USAGE 97 -#define DOT11_MNG_LINK_IDENTIFIER_ID 101 -#define DOT11_MNG_WAKEUP_SCHEDULE_ID 102 -#define DOT11_MNG_CHANNEL_SWITCH_TIMING_ID 104 -#define DOT11_MNG_PTI_CONTROL_ID 105 -#define DOT11_MNG_PU_BUFFER_STATUS_ID 106 -#define DOT11_MNG_EXT_CAP_ID 127 -#define DOT11_MNG_WPA_ID 221 -#define DOT11_MNG_PROPR_ID 221 - -#define DOT11_MNG_VS_ID 221 - - -#define DOT11_RATE_BASIC 0x80 -#define DOT11_RATE_MASK 0x7F - - -#define DOT11_MNG_ERP_LEN 1 -#define DOT11_MNG_NONERP_PRESENT 0x01 -#define DOT11_MNG_USE_PROTECTION 0x02 -#define DOT11_MNG_BARKER_PREAMBLE 0x04 - -#define DOT11_MGN_TS_DELAY_LEN 4 -#define TS_DELAY_FIELD_SIZE 4 - - -#define DOT11_CAP_ESS 0x0001 -#define DOT11_CAP_IBSS 0x0002 -#define DOT11_CAP_POLLABLE 0x0004 -#define DOT11_CAP_POLL_RQ 0x0008 -#define DOT11_CAP_PRIVACY 0x0010 -#define DOT11_CAP_SHORT 0x0020 -#define DOT11_CAP_PBCC 0x0040 -#define DOT11_CAP_AGILITY 0x0080 -#define DOT11_CAP_SPECTRUM 0x0100 -#define DOT11_CAP_SHORTSLOT 0x0400 -#define DOT11_CAP_RRM 0x1000 -#define DOT11_CAP_CCK_OFDM 0x2000 - - -#define DOT11_OBSS_COEX_MNG_SUPPORT 0x01 - - -#define DOT11_ACTION_HDR_LEN 2 -#define DOT11_ACTION_CAT_OFF 0 -#define DOT11_ACTION_ACT_OFF 1 - - -#define DOT11_ACTION_CAT_ERR_MASK 0x80 -#define DOT11_ACTION_CAT_MASK 0x7F -#define DOT11_ACTION_CAT_SPECT_MNG 0 -#define DOT11_ACTION_CAT_QOS 1 -#define DOT11_ACTION_CAT_DLS 2 -#define DOT11_ACTION_CAT_BLOCKACK 3 -#define DOT11_ACTION_CAT_PUBLIC 4 -#define DOT11_ACTION_CAT_RRM 5 -#define DOT11_ACTION_CAT_FBT 6 -#define DOT11_ACTION_CAT_HT 7 -#if defined(MFP) || defined(WLFBT) || defined(WLWNM) -#define DOT11_ACTION_CAT_SA_QUERY 8 -#define DOT11_ACTION_CAT_PDPA 9 -#define DOT11_ACTION_CAT_BSSMGMT 10 -#define DOT11_ACTION_NOTIFICATION 17 -#define DOT11_ACTION_CAT_VSP 126 -#endif -#define DOT11_ACTION_NOTIFICATION 17 -#define DOT11_ACTION_CAT_VS 127 - - -#define DOT11_SM_ACTION_M_REQ 0 -#define DOT11_SM_ACTION_M_REP 1 -#define DOT11_SM_ACTION_TPC_REQ 2 -#define DOT11_SM_ACTION_TPC_REP 3 -#define DOT11_SM_ACTION_CHANNEL_SWITCH 4 -#define DOT11_SM_ACTION_EXT_CSA 5 - - -#define DOT11_ACTION_ID_HT_CH_WIDTH 0 -#define DOT11_ACTION_ID_HT_MIMO_PS 1 - - -#define DOT11_PUB_ACTION_BSS_COEX_MNG 0 -#define DOT11_PUB_ACTION_CHANNEL_SWITCH 4 - - -#define DOT11_BA_ACTION_ADDBA_REQ 0 -#define DOT11_BA_ACTION_ADDBA_RESP 1 -#define DOT11_BA_ACTION_DELBA 2 - - -#define DOT11_ADDBA_PARAM_AMSDU_SUP 0x0001 -#define DOT11_ADDBA_PARAM_POLICY_MASK 0x0002 -#define DOT11_ADDBA_PARAM_POLICY_SHIFT 1 -#define DOT11_ADDBA_PARAM_TID_MASK 0x003c -#define DOT11_ADDBA_PARAM_TID_SHIFT 2 -#define DOT11_ADDBA_PARAM_BSIZE_MASK 0xffc0 -#define DOT11_ADDBA_PARAM_BSIZE_SHIFT 6 - -#define DOT11_ADDBA_POLICY_DELAYED 0 -#define DOT11_ADDBA_POLICY_IMMEDIATE 1 - - -#define DOT11_FT_ACTION_FT_RESERVED 0 -#define DOT11_FT_ACTION_FT_REQ 1 -#define DOT11_FT_ACTION_FT_RES 2 -#define DOT11_FT_ACTION_FT_CON 3 -#define DOT11_FT_ACTION_FT_ACK 4 - - - -#define DOT11_WNM_ACTION_EVENT_REQ 0 -#define DOT11_WNM_ACTION_EVENT_REP 1 -#define DOT11_WNM_ACTION_DIAG_REQ 2 -#define DOT11_WNM_ACTION_DIAG_REP 3 -#define DOT11_WNM_ACTION_LOC_CFG_REQ 4 -#define DOT11_WNM_ACTION_LOC_RFG_RESP 5 -#define DOT11_WNM_ACTION_BSS_TRANS_QURY 6 -#define DOT11_WNM_ACTION_BSS_TRANS_REQ 7 -#define DOT11_WNM_ACTION_BSS_TRANS_RESP 8 -#define DOT11_WNM_ACTION_FMS_REQ 9 -#define DOT11_WNM_ACTION_FMS_RESP 10 -#define DOT11_WNM_ACTION_COL_INTRFRNCE_REQ 11 -#define DOT11_WNM_ACTION_COL_INTRFRNCE_REP 12 -#define DOT11_WNM_ACTION_TFS_REQ 13 -#define DOT11_WNM_ACTION_TFS_RESP 14 -#define DOT11_WNM_ACTION_TFS_NOTIFY 15 -#define DOT11_WNM_ACTION_WNM_SLEEP_REQ 16 -#define DOT11_WNM_ACTION_WNM_SLEEP_RESP 17 -#define DOT11_WNM_ACTION_TIM_BCAST_REQ 18 -#define DOT11_WNM_ACTION_TIM_BCAST_RESP 19 -#define DOT11_WNM_ACTION_QOS_TRFC_CAP_UPD 20 -#define DOT11_WNM_ACTION_CHAN_USAGE_REQ 21 -#define DOT11_WNM_ACTION_CHAN_USAGE_RESP 22 -#define DOT11_WNM_ACTION_DMS_REQ 23 -#define DOT11_WNM_ACTION_DMS_RESP 24 -#define DOT11_WNM_ACTION_TMNG_MEASUR_REQ 25 -#define DOT11_WNM_ACTION_NOTFCTN_REQ 26 -#define DOT11_WNM_ACTION_NOTFCTN_RES 27 - - - -BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_query { - uint8 category; - uint8 action; - uint8 token; - uint8 reason; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_bss_trans_query dot11_bss_trans_query_t; -#define DOT11_BSS_TRANS_QUERY_LEN 4 - - -BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_req { - uint8 category; - uint8 action; - uint8 token; - uint8 reqmode; - uint16 disassoc_tmr; - uint8 validity_intrvl; - uint8 data[1]; - -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_bss_trans_req dot11_bss_trans_req_t; -#define DOT11_BSS_TRANS_REQ_LEN 7 - -#define DOT11_BSS_TERM_DUR_LEN 12 - - - -#define DOT11_BSS_TRNS_REQMODE_PREF_LIST_INCL 0x01 -#define DOT11_BSS_TRNS_REQMODE_ABRIDGED 0x02 -#define DOT11_BSS_TRNS_REQMODE_DISASSOC_IMMINENT 0x04 -#define DOT11_BSS_TRNS_REQMODE_BSS_TERM_INCL 0x08 -#define DOT11_BSS_TRNS_REQMODE_ESS_DISASSOC_IMNT 0x10 - - - -BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_res { - uint8 category; - uint8 action; - uint8 token; - uint8 status; - uint8 term_delay; - uint8 data[1]; - -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_bss_trans_res dot11_bss_trans_res_t; -#define DOT11_BSS_TRANS_RES_LEN 5 - - -#define DOT11_BSS_TRNS_RES_STATUS_ACCEPT 0 -#define DOT11_BSS_TRNS_RES_STATUS_REJECT 1 -#define DOT11_BSS_TRNS_RES_STATUS_REJ_INSUFF_BCN 2 -#define DOT11_BSS_TRNS_RES_STATUS_REJ_INSUFF_CAP 3 -#define DOT11_BSS_TRNS_RES_STATUS_REJ_TERM_UNDESIRED 4 -#define DOT11_BSS_TRNS_RES_STATUS_REJ_TERM_DELAY_REQ 5 -#define DOT11_BSS_TRNS_RES_STATUS_REJ_BSS_LIST_PROVIDED 6 -#define DOT11_BSS_TRNS_RES_STATUS_REJ_NO_SUITABLE_BSS 7 -#define DOT11_BSS_TRNS_RES_STATUS_REJ_LEAVING_ESS 8 - - - -#define DOT11_NBR_RPRT_BSSID_INFO_REACHABILTY 0x0003 -#define DOT11_NBR_RPRT_BSSID_INFO_SEC 0x0004 -#define DOT11_NBR_RPRT_BSSID_INFO_KEY_SCOPE 0x0008 -#define DOT11_NBR_RPRT_BSSID_INFO_CAP 0x03f0 - -#define DOT11_NBR_RPRT_BSSID_INFO_CAP_SPEC_MGMT 0x0010 -#define DOT11_NBR_RPRT_BSSID_INFO_CAP_QOS 0x0020 -#define DOT11_NBR_RPRT_BSSID_INFO_CAP_APSD 0x0040 -#define DOT11_NBR_RPRT_BSSID_INFO_CAP_RDIO_MSMT 0x0080 -#define DOT11_NBR_RPRT_BSSID_INFO_CAP_DEL_BA 0x0100 -#define DOT11_NBR_RPRT_BSSID_INFO_CAP_IMM_BA 0x0200 - - -#define DOT11_NBR_RPRT_SUBELEM_BSS_CANDDT_PREF_ID 3 -BWL_PRE_PACKED_STRUCT struct dot11_addba_req { - uint8 category; - uint8 action; - uint8 token; - uint16 addba_param_set; - uint16 timeout; - uint16 start_seqnum; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_addba_req dot11_addba_req_t; -#define DOT11_ADDBA_REQ_LEN 9 - -BWL_PRE_PACKED_STRUCT struct dot11_addba_resp { - uint8 category; - uint8 action; - uint8 token; - uint16 status; - uint16 addba_param_set; - uint16 timeout; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_addba_resp dot11_addba_resp_t; -#define DOT11_ADDBA_RESP_LEN 9 - - -#define DOT11_DELBA_PARAM_INIT_MASK 0x0800 -#define DOT11_DELBA_PARAM_INIT_SHIFT 11 -#define DOT11_DELBA_PARAM_TID_MASK 0xf000 -#define DOT11_DELBA_PARAM_TID_SHIFT 12 - -BWL_PRE_PACKED_STRUCT struct dot11_delba { - uint8 category; - uint8 action; - uint16 delba_param_set; - uint16 reason; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_delba dot11_delba_t; -#define DOT11_DELBA_LEN 6 - - -#define SA_QUERY_REQUEST 0 -#define SA_QUERY_RESPONSE 1 - - - - -BWL_PRE_PACKED_STRUCT struct dot11_ft_req { - uint8 category; - uint8 action; - uint8 sta_addr[ETHER_ADDR_LEN]; - uint8 tgt_ap_addr[ETHER_ADDR_LEN]; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_ft_req dot11_ft_req_t; -#define DOT11_FT_REQ_FIXED_LEN 14 - - -BWL_PRE_PACKED_STRUCT struct dot11_ft_res { - uint8 category; - uint8 action; - uint8 sta_addr[ETHER_ADDR_LEN]; - uint8 tgt_ap_addr[ETHER_ADDR_LEN]; - uint16 status; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_ft_res dot11_ft_res_t; -#define DOT11_FT_RES_FIXED_LEN 16 - - -BWL_PRE_PACKED_STRUCT struct dot11_rde_ie { - uint8 id; - uint8 length; - uint8 rde_id; - uint8 rd_count; - uint16 status; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_rde_ie dot11_rde_ie_t; - - -#define DOT11_MNG_RDE_IE_LEN sizeof(dot11_rde_ie_t) - - - - - -#define DOT11_RRM_CAP_LEN 5 -BWL_PRE_PACKED_STRUCT struct dot11_rrm_cap_ie { - uint8 cap[DOT11_RRM_CAP_LEN]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_rrm_cap_ie dot11_rrm_cap_ie_t; - - -#define DOT11_RRM_CAP_LINK 0 -#define DOT11_RRM_CAP_NEIGHBOR_REPORT 1 -#define DOT11_RRM_CAP_PARALLEL 2 -#define DOT11_RRM_CAP_REPEATED 3 -#define DOT11_RRM_CAP_BCN_PASSIVE 4 -#define DOT11_RRM_CAP_BCN_ACTIVE 5 -#define DOT11_RRM_CAP_BCN_TABLE 6 -#define DOT11_RRM_CAP_BCN_REP_COND 7 -#define DOT11_RRM_CAP_AP_CHANREP 16 - - - -#define DOT11_EXT_CAP_LEN 4 -BWL_PRE_PACKED_STRUCT struct dot11_ext_cap_ie { - uint8 cap[DOT11_EXT_CAP_LEN]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_ext_cap_ie dot11_ext_cap_ie_t; - - -#define DOT11_EXT_CAP_BSS_TRANSITION_MGMT 19 - - -#define DOT11_OP_CLASS_NONE 255 - -BWL_PRE_PACKED_STRUCT struct do11_ap_chrep { - uint8 id; - uint8 len; - uint8 reg; - uint8 chanlist[1]; -} BWL_POST_PACKED_STRUCT; -typedef struct do11_ap_chrep dot11_ap_chrep_t; - - -#define DOT11_RM_ACTION_RM_REQ 0 -#define DOT11_RM_ACTION_RM_REP 1 -#define DOT11_RM_ACTION_LM_REQ 2 -#define DOT11_RM_ACTION_LM_REP 3 -#define DOT11_RM_ACTION_NR_REQ 4 -#define DOT11_RM_ACTION_NR_REP 5 - - -BWL_PRE_PACKED_STRUCT struct dot11_rm_action { - uint8 category; - uint8 action; - uint8 token; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_rm_action dot11_rm_action_t; -#define DOT11_RM_ACTION_LEN 3 - -BWL_PRE_PACKED_STRUCT struct dot11_rmreq { - uint8 category; - uint8 action; - uint8 token; - uint16 reps; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_rmreq dot11_rmreq_t; -#define DOT11_RMREQ_LEN 5 - -BWL_PRE_PACKED_STRUCT struct dot11_rm_ie { - uint8 id; - uint8 len; - uint8 token; - uint8 mode; - uint8 type; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_rm_ie dot11_rm_ie_t; -#define DOT11_RM_IE_LEN 5 - - -#define DOT11_RMREQ_MODE_PARALLEL 1 -#define DOT11_RMREQ_MODE_ENABLE 2 -#define DOT11_RMREQ_MODE_REQUEST 4 -#define DOT11_RMREQ_MODE_REPORT 8 -#define DOT11_RMREQ_MODE_DURMAND 0x10 - - -#define DOT11_RMREP_MODE_LATE 1 -#define DOT11_RMREP_MODE_INCAPABLE 2 -#define DOT11_RMREP_MODE_REFUSED 4 - -BWL_PRE_PACKED_STRUCT struct dot11_rmreq_bcn { - uint8 id; - uint8 len; - uint8 token; - uint8 mode; - uint8 type; - uint8 reg; - uint8 channel; - uint16 interval; - uint16 duration; - uint8 bcn_mode; - struct ether_addr bssid; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_rmreq_bcn dot11_rmreq_bcn_t; -#define DOT11_RMREQ_BCN_LEN 18 - -BWL_PRE_PACKED_STRUCT struct dot11_rmrep_bcn { - uint8 reg; - uint8 channel; - uint32 starttime[2]; - uint16 duration; - uint8 frame_info; - uint8 rcpi; - uint8 rsni; - struct ether_addr bssid; - uint8 antenna_id; - uint32 parent_tsf; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_rmrep_bcn dot11_rmrep_bcn_t; -#define DOT11_RMREP_BCN_LEN 26 - - -#define DOT11_RMREQ_BCN_PASSIVE 0 -#define DOT11_RMREQ_BCN_ACTIVE 1 -#define DOT11_RMREQ_BCN_TABLE 2 - - -#define DOT11_RMREQ_BCN_SSID_ID 0 -#define DOT11_RMREQ_BCN_REPINFO_ID 1 -#define DOT11_RMREQ_BCN_REPDET_ID 2 -#define DOT11_RMREQ_BCN_REQUEST_ID 10 -#define DOT11_RMREQ_BCN_APCHREP_ID DOT11_MNG_AP_CHREP_ID - - -#define DOT11_RMREQ_BCN_REPDET_FIXED 0 -#define DOT11_RMREQ_BCN_REPDET_REQUEST 1 -#define DOT11_RMREQ_BCN_REPDET_ALL 2 - - -#define DOT11_RMREP_BCN_FRM_BODY 1 - - -BWL_PRE_PACKED_STRUCT struct dot11_rmrep_nbr { - struct ether_addr bssid; - uint32 bssid_info; - uint8 reg; - uint8 channel; - uint8 phytype; - uchar sub_elements[1]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_rmrep_nbr dot11_rmrep_nbr_t; -#define DOT11_RMREP_NBR_LEN 13 - - -#define DOT11_BSSTYPE_INFRASTRUCTURE 0 -#define DOT11_BSSTYPE_INDEPENDENT 1 -#define DOT11_BSSTYPE_ANY 2 -#define DOT11_SCANTYPE_ACTIVE 0 -#define DOT11_SCANTYPE_PASSIVE 1 - - -BWL_PRE_PACKED_STRUCT struct dot11_lmreq { - uint8 category; - uint8 action; - uint8 token; - uint8 txpwr; - uint8 maxtxpwr; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_lmreq dot11_lmreq_t; -#define DOT11_LMREQ_LEN 5 - -BWL_PRE_PACKED_STRUCT struct dot11_lmrep { - uint8 category; - uint8 action; - uint8 token; - dot11_tpc_rep_t tpc; - uint8 rxant; - uint8 txant; - uint8 rcpi; - uint8 rsni; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_lmrep dot11_lmrep_t; -#define DOT11_LMREP_LEN 11 - - -#define PREN_PREAMBLE 24 -#define PREN_MM_EXT 12 -#define PREN_PREAMBLE_EXT 4 - - -#define RIFS_11N_TIME 2 - - - -#define HT_SIG1_MCS_MASK 0x00007F -#define HT_SIG1_CBW 0x000080 -#define HT_SIG1_HT_LENGTH 0xFFFF00 - - -#define HT_SIG2_SMOOTHING 0x000001 -#define HT_SIG2_NOT_SOUNDING 0x000002 -#define HT_SIG2_RESERVED 0x000004 -#define HT_SIG2_AGGREGATION 0x000008 -#define HT_SIG2_STBC_MASK 0x000030 -#define HT_SIG2_STBC_SHIFT 4 -#define HT_SIG2_FEC_CODING 0x000040 -#define HT_SIG2_SHORT_GI 0x000080 -#define HT_SIG2_ESS_MASK 0x000300 -#define HT_SIG2_ESS_SHIFT 8 -#define HT_SIG2_CRC 0x03FC00 -#define HT_SIG2_TAIL 0x1C0000 - - -#define APHY_SLOT_TIME 9 -#define APHY_SIFS_TIME 16 -#define APHY_DIFS_TIME (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME)) -#define APHY_PREAMBLE_TIME 16 -#define APHY_SIGNAL_TIME 4 -#define APHY_SYMBOL_TIME 4 -#define APHY_SERVICE_NBITS 16 -#define APHY_TAIL_NBITS 6 -#define APHY_CWMIN 15 - - -#define BPHY_SLOT_TIME 20 -#define BPHY_SIFS_TIME 10 -#define BPHY_DIFS_TIME 50 -#define BPHY_PLCP_TIME 192 -#define BPHY_PLCP_SHORT_TIME 96 -#define BPHY_CWMIN 31 - - -#define DOT11_OFDM_SIGNAL_EXTENSION 6 - -#define PHY_CWMAX 1023 - -#define DOT11_MAXNUMFRAGS 16 - - -typedef struct d11cnt { - uint32 txfrag; - uint32 txmulti; - uint32 txfail; - uint32 txretry; - uint32 txretrie; - uint32 rxdup; - uint32 txrts; - uint32 txnocts; - uint32 txnoack; - uint32 rxfrag; - uint32 rxmulti; - uint32 rxcrc; - uint32 txfrmsnt; - uint32 rxundec; -} d11cnt_t; - - -#define BRCM_PROP_OUI "\x00\x90\x4C" - - - -#define BRCM_OUI "\x00\x10\x18" - - -BWL_PRE_PACKED_STRUCT struct brcm_ie { - uint8 id; - uint8 len; - uint8 oui[3]; - uint8 ver; - uint8 assoc; - uint8 flags; - uint8 flags1; - uint16 amsdu_mtu_pref; -} BWL_POST_PACKED_STRUCT; -typedef struct brcm_ie brcm_ie_t; -#define BRCM_IE_LEN 11 -#define BRCM_IE_VER 2 -#define BRCM_IE_LEGACY_AES_VER 1 - - -#ifdef WLAFTERBURNER -#define BRF_ABCAP 0x1 -#define BRF_ABRQRD 0x2 -#define BRF_ABCOUNTER_MASK 0xf0 -#define BRF_ABCOUNTER_SHIFT 4 -#endif -#define BRF_LZWDS 0x4 -#define BRF_BLOCKACK 0x8 - - -#define BRF1_AMSDU 0x1 -#define BRF1_WMEPS 0x4 -#define BRF1_PSOFIX 0x8 -#define BRF1_RX_LARGE_AGG 0x10 -#define BRF1_SOFTAP 0x40 - -#ifdef WLAFTERBURNER -#define AB_WDS_TIMEOUT_MAX 15 -#define AB_WDS_TIMEOUT_MIN 1 -#endif - -#define AB_GUARDCOUNT 10 - - -BWL_PRE_PACKED_STRUCT struct vndr_ie { - uchar id; - uchar len; - uchar oui [3]; - uchar data [1]; -} BWL_POST_PACKED_STRUCT; -typedef struct vndr_ie vndr_ie_t; - -#define VNDR_IE_HDR_LEN 2 -#define VNDR_IE_MIN_LEN 3 -#define VNDR_IE_MAX_LEN 256 - - -#define MCSSET_LEN 16 -#define MAX_MCS_NUM (128) - -BWL_PRE_PACKED_STRUCT struct ht_cap_ie { - uint16 cap; - uint8 params; - uint8 supp_mcs[MCSSET_LEN]; - uint16 ext_htcap; - uint32 txbf_cap; - uint8 as_cap; -} BWL_POST_PACKED_STRUCT; -typedef struct ht_cap_ie ht_cap_ie_t; - - - -BWL_PRE_PACKED_STRUCT struct ht_prop_cap_ie { - uint8 id; - uint8 len; - uint8 oui[3]; - uint8 type; - ht_cap_ie_t cap_ie; -} BWL_POST_PACKED_STRUCT; -typedef struct ht_prop_cap_ie ht_prop_cap_ie_t; - -#define HT_PROP_IE_OVERHEAD 4 -#define HT_CAP_IE_LEN 26 -#define HT_CAP_IE_TYPE 51 - -#define HT_CAP_LDPC_CODING 0x0001 -#define HT_CAP_40MHZ 0x0002 -#define HT_CAP_MIMO_PS_MASK 0x000C -#define HT_CAP_MIMO_PS_SHIFT 0x0002 -#define HT_CAP_MIMO_PS_OFF 0x0003 -#define HT_CAP_MIMO_PS_RTS 0x0001 -#define HT_CAP_MIMO_PS_ON 0x0000 -#define HT_CAP_GF 0x0010 -#define HT_CAP_SHORT_GI_20 0x0020 -#define HT_CAP_SHORT_GI_40 0x0040 -#define HT_CAP_TX_STBC 0x0080 -#define HT_CAP_RX_STBC_MASK 0x0300 -#define HT_CAP_RX_STBC_SHIFT 8 -#define HT_CAP_DELAYED_BA 0x0400 -#define HT_CAP_MAX_AMSDU 0x0800 -#define HT_CAP_DSSS_CCK 0x1000 -#define HT_CAP_PSMP 0x2000 -#define HT_CAP_40MHZ_INTOLERANT 0x4000 -#define HT_CAP_LSIG_TXOP 0x8000 - -#define HT_CAP_RX_STBC_NO 0x0 -#define HT_CAP_RX_STBC_ONE_STREAM 0x1 -#define HT_CAP_RX_STBC_TWO_STREAM 0x2 -#define HT_CAP_RX_STBC_THREE_STREAM 0x3 - -#define HT_MAX_AMSDU 7935 -#define HT_MIN_AMSDU 3835 - -#define HT_PARAMS_RX_FACTOR_MASK 0x03 -#define HT_PARAMS_DENSITY_MASK 0x1C -#define HT_PARAMS_DENSITY_SHIFT 2 - - -#define AMPDU_MAX_MPDU_DENSITY 7 -#define AMPDU_RX_FACTOR_8K 0 -#define AMPDU_RX_FACTOR_16K 1 -#define AMPDU_RX_FACTOR_32K 2 -#define AMPDU_RX_FACTOR_64K 3 -#define AMPDU_RX_FACTOR_BASE 8*1024 - -#define AMPDU_DELIMITER_LEN 4 -#define AMPDU_DELIMITER_LEN_MAX 63 - -BWL_PRE_PACKED_STRUCT struct ht_add_ie { - uint8 ctl_ch; - uint8 byte1; - uint16 opmode; - uint16 misc_bits; - uint8 basic_mcs[MCSSET_LEN]; -} BWL_POST_PACKED_STRUCT; -typedef struct ht_add_ie ht_add_ie_t; - - - -BWL_PRE_PACKED_STRUCT struct ht_prop_add_ie { - uint8 id; - uint8 len; - uint8 oui[3]; - uint8 type; - ht_add_ie_t add_ie; -} BWL_POST_PACKED_STRUCT; -typedef struct ht_prop_add_ie ht_prop_add_ie_t; - -#define HT_ADD_IE_LEN 22 -#define HT_ADD_IE_TYPE 52 - - -#define HT_BW_ANY 0x04 -#define HT_RIFS_PERMITTED 0x08 - - -#define HT_OPMODE_MASK 0x0003 -#define HT_OPMODE_SHIFT 0 -#define HT_OPMODE_PURE 0x0000 -#define HT_OPMODE_OPTIONAL 0x0001 -#define HT_OPMODE_HT20IN40 0x0002 -#define HT_OPMODE_MIXED 0x0003 -#define HT_OPMODE_NONGF 0x0004 -#define DOT11N_TXBURST 0x0008 -#define DOT11N_OBSS_NONHT 0x0010 - - -#define HT_BASIC_STBC_MCS 0x007f -#define HT_DUAL_STBC_PROT 0x0080 -#define HT_SECOND_BCN 0x0100 -#define HT_LSIG_TXOP 0x0200 -#define HT_PCO_ACTIVE 0x0400 -#define HT_PCO_PHASE 0x0800 - - -#define DOT11N_2G_TXBURST_LIMIT 6160 -#define DOT11N_5G_TXBURST_LIMIT 3080 - - -#define GET_HT_OPMODE(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ - >> HT_OPMODE_SHIFT) -#define HT_MIXEDMODE_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ - == HT_OPMODE_MIXED) -#define HT_HT20_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ - == HT_OPMODE_HT20IN40) -#define HT_OPTIONAL_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ - == HT_OPMODE_OPTIONAL) -#define HT_USE_PROTECTION(add_ie) (HT_HT20_PRESENT((add_ie)) || \ - HT_MIXEDMODE_PRESENT((add_ie))) -#define HT_NONGF_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_NONGF) \ - == HT_OPMODE_NONGF) -#define DOT11N_TXBURST_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_TXBURST) \ - == DOT11N_TXBURST) -#define DOT11N_OBSS_NONHT_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_OBSS_NONHT) \ - == DOT11N_OBSS_NONHT) - -BWL_PRE_PACKED_STRUCT struct obss_params { - uint16 passive_dwell; - uint16 active_dwell; - uint16 bss_widthscan_interval; - uint16 passive_total; - uint16 active_total; - uint16 chanwidth_transition_dly; - uint16 activity_threshold; -} BWL_POST_PACKED_STRUCT; -typedef struct obss_params obss_params_t; - -BWL_PRE_PACKED_STRUCT struct dot11_obss_ie { - uint8 id; - uint8 len; - obss_params_t obss_params; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_obss_ie dot11_obss_ie_t; -#define DOT11_OBSS_SCAN_IE_LEN sizeof(obss_params_t) - - -#define HT_CTRL_LA_TRQ 0x00000002 -#define HT_CTRL_LA_MAI 0x0000003C -#define HT_CTRL_LA_MAI_SHIFT 2 -#define HT_CTRL_LA_MAI_MRQ 0x00000004 -#define HT_CTRL_LA_MAI_MSI 0x00000038 -#define HT_CTRL_LA_MFSI 0x000001C0 -#define HT_CTRL_LA_MFSI_SHIFT 6 -#define HT_CTRL_LA_MFB_ASELC 0x0000FE00 -#define HT_CTRL_LA_MFB_ASELC_SH 9 -#define HT_CTRL_LA_ASELC_CMD 0x00000C00 -#define HT_CTRL_LA_ASELC_DATA 0x0000F000 -#define HT_CTRL_CAL_POS 0x00030000 -#define HT_CTRL_CAL_SEQ 0x000C0000 -#define HT_CTRL_CSI_STEERING 0x00C00000 -#define HT_CTRL_CSI_STEER_SHIFT 22 -#define HT_CTRL_CSI_STEER_NFB 0 -#define HT_CTRL_CSI_STEER_CSI 1 -#define HT_CTRL_CSI_STEER_NCOM 2 -#define HT_CTRL_CSI_STEER_COM 3 -#define HT_CTRL_NDP_ANNOUNCE 0x01000000 -#define HT_CTRL_AC_CONSTRAINT 0x40000000 -#define HT_CTRL_RDG_MOREPPDU 0x80000000 - -#define HT_OPMODE_OPTIONAL 0x0001 -#define HT_OPMODE_HT20IN40 0x0002 -#define HT_OPMODE_MIXED 0x0003 -#define HT_OPMODE_NONGF 0x0004 -#define DOT11N_TXBURST 0x0008 -#define DOT11N_OBSS_NONHT 0x0010 - - - -#define WPA_OUI "\x00\x50\xF2" -#define WPA_OUI_LEN 3 -#define WPA_OUI_TYPE 1 -#define WPA_VERSION 1 -#define WPA2_OUI "\x00\x0F\xAC" -#define WPA2_OUI_LEN 3 -#define WPA2_VERSION 1 -#define WPA2_VERSION_LEN 2 - - -#define WPS_OUI "\x00\x50\xF2" -#define WPS_OUI_LEN 3 -#define WPS_OUI_TYPE 4 - - -#define WFA_OUI "\x50\x6F\x9A" -#define WFA_OUI_LEN 3 - -#define WFA_OUI_TYPE_WPA 1 -#define WFA_OUI_TYPE_WPS 4 -#define WFA_OUI_TYPE_TPC 8 -#define WFA_OUI_TYPE_P2P 9 - - -#define RSN_AKM_NONE 0 -#define RSN_AKM_UNSPECIFIED 1 -#define RSN_AKM_PSK 2 -#define RSN_AKM_FBT_1X 3 -#define RSN_AKM_FBT_PSK 4 -#define RSN_AKM_MFP_1X 5 -#define RSN_AKM_MFP_PSK 6 -#define RSN_AKM_TPK 7 - - -#define DOT11_MAX_DEFAULT_KEYS 4 -#define DOT11_MAX_KEY_SIZE 32 -#define DOT11_MAX_IV_SIZE 16 -#define DOT11_EXT_IV_FLAG (1<<5) -#define DOT11_WPA_KEY_RSC_LEN 8 - -#define WEP1_KEY_SIZE 5 -#define WEP1_KEY_HEX_SIZE 10 -#define WEP128_KEY_SIZE 13 -#define WEP128_KEY_HEX_SIZE 26 -#define TKIP_MIC_SIZE 8 -#define TKIP_EOM_SIZE 7 -#define TKIP_EOM_FLAG 0x5a -#define TKIP_KEY_SIZE 32 -#define TKIP_MIC_AUTH_TX 16 -#define TKIP_MIC_AUTH_RX 24 -#define TKIP_MIC_SUP_RX TKIP_MIC_AUTH_TX -#define TKIP_MIC_SUP_TX TKIP_MIC_AUTH_RX -#define AES_KEY_SIZE 16 -#define AES_MIC_SIZE 8 - - -#define WCN_OUI "\x00\x50\xf2" -#define WCN_TYPE 4 - - - - - -BWL_PRE_PACKED_STRUCT struct dot11_mdid_ie { - uint8 id; - uint8 len; - uint16 mdid; - uint8 cap; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_mdid_ie dot11_mdid_ie_t; - -#define FBT_MDID_CAP_OVERDS 0x01 -#define FBT_MDID_CAP_RRP 0x02 - - -BWL_PRE_PACKED_STRUCT struct dot11_ft_ie { - uint8 id; - uint8 len; - uint16 mic_control; - uint8 mic[16]; - uint8 anonce[32]; - uint8 snonce[32]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_ft_ie dot11_ft_ie_t; - - -BWL_PRE_PACKED_STRUCT struct dot11_gtk_ie { - uint8 id; - uint8 len; - uint16 key_info; - uint8 key_len; - uint8 rsc[8]; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_gtk_ie dot11_gtk_ie_t; - -#define BSSID_INVALID "\x00\x00\x00\x00\x00\x00" -#define BSSID_BROADCAST "\xFF\xFF\xFF\xFF\xFF\xFF" - - - -BWL_PRE_PACKED_STRUCT struct link_id_ie { - uint8 id; - uint8 len; - struct ether_addr bssid; - struct ether_addr tdls_init_mac; - struct ether_addr tdls_resp_mac; -} BWL_POST_PACKED_STRUCT; -typedef struct link_id_ie link_id_ie_t; -#define TDLS_LINK_ID_IE_LEN 18 - - -BWL_PRE_PACKED_STRUCT struct wakeup_sch_ie { - uint8 id; - uint8 len; - uint32 offset; - uint32 interval; - uint32 awake_win_slots; - uint32 max_wake_win; - uint16 idle_cnt; -} BWL_POST_PACKED_STRUCT; -typedef struct wakeup_sch_ie wakeup_sch_ie_t; -#define TDLS_WAKEUP_SCH_IE_LEN 18 - - -BWL_PRE_PACKED_STRUCT struct channel_switch_timing_ie { - uint8 id; - uint8 len; - uint16 switch_time; - uint16 switch_timeout; -} BWL_POST_PACKED_STRUCT; -typedef struct channel_switch_timing_ie channel_switch_timing_ie_t; -#define TDLS_CHANNEL_SWITCH_TIMING_IE_LEN 4 - - -BWL_PRE_PACKED_STRUCT struct pti_control_ie { - uint8 id; - uint8 len; - uint8 tid; - uint16 seq_control; -} BWL_POST_PACKED_STRUCT; -typedef struct pti_control_ie pti_control_ie_t; -#define TDLS_PTI_CONTROL_IE_LEN 3 - - -BWL_PRE_PACKED_STRUCT struct pu_buffer_status_ie { - uint8 id; - uint8 len; - uint8 status; -} BWL_POST_PACKED_STRUCT; -typedef struct pu_buffer_status_ie pu_buffer_status_ie_t; -#define TDLS_PU_BUFFER_STATUS_IE_LEN 1 -#define TDLS_PU_BUFFER_STATUS_AC_BK 1 -#define TDLS_PU_BUFFER_STATUS_AC_BE 2 -#define TDLS_PU_BUFFER_STATUS_AC_VI 4 -#define TDLS_PU_BUFFER_STATUS_AC_VO 8 - - -#include - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h b/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h deleted file mode 100644 index cbdd05e624bc..000000000000 --- a/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * BT-AMP (BlueTooth Alternate Mac and Phy) 802.11 PAL (Protocol Adaptation Layer) - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: 802.11_bta.h 277737 2011-08-16 17:54:59Z $ -*/ - -#ifndef _802_11_BTA_H_ -#define _802_11_BTA_H_ - -#define BT_SIG_SNAP_MPROT "\xAA\xAA\x03\x00\x19\x58" - -/* BT-AMP 802.11 PAL Protocols */ -#define BTA_PROT_L2CAP 1 -#define BTA_PROT_ACTIVITY_REPORT 2 -#define BTA_PROT_SECURITY 3 -#define BTA_PROT_LINK_SUPERVISION_REQUEST 4 -#define BTA_PROT_LINK_SUPERVISION_REPLY 5 - -/* BT-AMP 802.11 PAL AMP_ASSOC Type IDs */ -#define BTA_TYPE_ID_MAC_ADDRESS 1 -#define BTA_TYPE_ID_PREFERRED_CHANNELS 2 -#define BTA_TYPE_ID_CONNECTED_CHANNELS 3 -#define BTA_TYPE_ID_CAPABILITIES 4 -#define BTA_TYPE_ID_VERSION 5 -#endif /* _802_11_bta_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/proto/802.11e.h b/drivers/net/wireless/bcmdhd/include/proto/802.11e.h deleted file mode 100644 index 0e070a475b64..000000000000 --- a/drivers/net/wireless/bcmdhd/include/proto/802.11e.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 802.11e protocol header file - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: 802.11e.h 277737 2011-08-16 17:54:59Z $ - */ - -#ifndef _802_11e_H_ -#define _802_11e_H_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - -/* This marks the start of a packed structure section. */ -#include - - -/* WME Traffic Specification (TSPEC) element */ -#define WME_TSPEC_HDR_LEN 2 /* WME TSPEC header length */ -#define WME_TSPEC_BODY_OFF 2 /* WME TSPEC body offset */ - -#define WME_CATEGORY_CODE_OFFSET 0 /* WME Category code offset */ -#define WME_ACTION_CODE_OFFSET 1 /* WME Action code offset */ -#define WME_TOKEN_CODE_OFFSET 2 /* WME Token code offset */ -#define WME_STATUS_CODE_OFFSET 3 /* WME Status code offset */ - -BWL_PRE_PACKED_STRUCT struct tsinfo { - uint8 octets[3]; -} BWL_POST_PACKED_STRUCT; - -typedef struct tsinfo tsinfo_t; - -/* 802.11e TSPEC IE */ -typedef BWL_PRE_PACKED_STRUCT struct tspec { - uint8 oui[DOT11_OUI_LEN]; /* WME_OUI */ - uint8 type; /* WME_TYPE */ - uint8 subtype; /* WME_SUBTYPE_TSPEC */ - uint8 version; /* WME_VERSION */ - tsinfo_t tsinfo; /* TS Info bit field */ - uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */ - uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */ - uint32 min_srv_interval; /* Minimum Service Interval (us) */ - uint32 max_srv_interval; /* Maximum Service Interval (us) */ - uint32 inactivity_interval; /* Inactivity Interval (us) */ - uint32 suspension_interval; /* Suspension Interval (us) */ - uint32 srv_start_time; /* Service Start Time (us) */ - uint32 min_data_rate; /* Minimum Data Rate (bps) */ - uint32 mean_data_rate; /* Mean Data Rate (bps) */ - uint32 peak_data_rate; /* Peak Data Rate (bps) */ - uint32 max_burst_size; /* Maximum Burst Size (bytes) */ - uint32 delay_bound; /* Delay Bound (us) */ - uint32 min_phy_rate; /* Minimum PHY Rate (bps) */ - uint16 surplus_bw; /* Surplus Bandwidth Allowance (range 1.0-8.0) */ - uint16 medium_time; /* Medium Time (32 us/s periods) */ -} BWL_POST_PACKED_STRUCT tspec_t; - -#define WME_TSPEC_LEN (sizeof(tspec_t)) /* not including 2-bytes of header */ - -/* ts_info */ -/* 802.1D priority is duplicated - bits 13-11 AND bits 3-1 */ -#define TS_INFO_TID_SHIFT 1 /* TS info. TID shift */ -#define TS_INFO_TID_MASK (0xf << TS_INFO_TID_SHIFT) /* TS info. TID mask */ -#define TS_INFO_CONTENTION_SHIFT 7 /* TS info. contention shift */ -#define TS_INFO_CONTENTION_MASK (0x1 << TS_INFO_CONTENTION_SHIFT) /* TS info. contention mask */ -#define TS_INFO_DIRECTION_SHIFT 5 /* TS info. direction shift */ -#define TS_INFO_DIRECTION_MASK (0x3 << TS_INFO_DIRECTION_SHIFT) /* TS info. direction mask */ -#define TS_INFO_PSB_SHIFT 2 /* TS info. PSB bit Shift */ -#define TS_INFO_PSB_MASK (1 << TS_INFO_PSB_SHIFT) /* TS info. PSB mask */ -#define TS_INFO_UPLINK (0 << TS_INFO_DIRECTION_SHIFT) /* TS info. uplink */ -#define TS_INFO_DOWNLINK (1 << TS_INFO_DIRECTION_SHIFT) /* TS info. downlink */ -#define TS_INFO_BIDIRECTIONAL (3 << TS_INFO_DIRECTION_SHIFT) /* TS info. bidirectional */ -#define TS_INFO_USER_PRIO_SHIFT 3 /* TS info. user priority shift */ -/* TS info. user priority mask */ -#define TS_INFO_USER_PRIO_MASK (0x7 << TS_INFO_USER_PRIO_SHIFT) - -/* Macro to get/set bit(s) field in TSINFO */ -#define WLC_CAC_GET_TID(pt) ((((pt).octets[0]) & TS_INFO_TID_MASK) >> TS_INFO_TID_SHIFT) -#define WLC_CAC_GET_DIR(pt) ((((pt).octets[0]) & \ - TS_INFO_DIRECTION_MASK) >> TS_INFO_DIRECTION_SHIFT) -#define WLC_CAC_GET_PSB(pt) ((((pt).octets[1]) & TS_INFO_PSB_MASK) >> TS_INFO_PSB_SHIFT) -#define WLC_CAC_GET_USER_PRIO(pt) ((((pt).octets[1]) & \ - TS_INFO_USER_PRIO_MASK) >> TS_INFO_USER_PRIO_SHIFT) - -#define WLC_CAC_SET_TID(pt, id) ((((pt).octets[0]) & (~TS_INFO_TID_MASK)) | \ - ((id) << TS_INFO_TID_SHIFT)) -#define WLC_CAC_SET_USER_PRIO(pt, prio) ((((pt).octets[0]) & (~TS_INFO_USER_PRIO_MASK)) | \ - ((prio) << TS_INFO_USER_PRIO_SHIFT)) - -/* 802.11e QBSS Load IE */ -#define QBSS_LOAD_IE_LEN 5 /* QBSS Load IE length */ -#define QBSS_LOAD_AAC_OFF 3 /* AAC offset in IE */ - -#define CAC_ADDTS_RESP_TIMEOUT 300 /* default ADDTS response timeout in ms */ - -/* 802.11e ADDTS status code */ -#define DOT11E_STATUS_ADMISSION_ACCEPTED 0 /* TSPEC Admission accepted status */ -#define DOT11E_STATUS_ADDTS_INVALID_PARAM 1 /* TSPEC invalid parameter status */ -#define DOT11E_STATUS_ADDTS_REFUSED_NSBW 3 /* ADDTS refused (non-sufficient BW) */ -#define DOT11E_STATUS_ADDTS_REFUSED_AWHILE 47 /* ADDTS refused but could retry later */ - -/* 802.11e DELTS status code */ -#define DOT11E_STATUS_QSTA_LEAVE_QBSS 36 /* STA leave QBSS */ -#define DOT11E_STATUS_END_TS 37 /* END TS */ -#define DOT11E_STATUS_UNKNOWN_TS 38 /* UNKNOWN TS */ -#define DOT11E_STATUS_QSTA_REQ_TIMEOUT 39 /* STA ADDTS request timeout */ - - -/* This marks the end of a packed structure section. */ -#include - -#endif /* _802_11e_CAC_H_ */ diff --git a/drivers/net/wireless/bcmdhd/include/proto/802.1d.h b/drivers/net/wireless/bcmdhd/include/proto/802.1d.h deleted file mode 100644 index c7e07bd5e7c3..000000000000 --- a/drivers/net/wireless/bcmdhd/include/proto/802.1d.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * Fundamental types and constants relating to 802.1D - * - * $Id: 802.1d.h 277737 2011-08-16 17:54:59Z $ - */ - - -#ifndef _802_1_D_ -#define _802_1_D_ - - -#define PRIO_8021D_NONE 2 -#define PRIO_8021D_BK 1 -#define PRIO_8021D_BE 0 -#define PRIO_8021D_EE 3 -#define PRIO_8021D_CL 4 -#define PRIO_8021D_VI 5 -#define PRIO_8021D_VO 6 -#define PRIO_8021D_NC 7 -#define MAXPRIO 7 -#define NUMPRIO (MAXPRIO + 1) - -#define ALLPRIO -1 - - -#define PRIO2PREC(prio) \ - (((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? ((prio^2)) : (prio)) - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h b/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h deleted file mode 100644 index 0f75d3c8f1d6..000000000000 --- a/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Broadcom Ethernettype protocol definitions - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bcmeth.h 277737 2011-08-16 17:54:59Z $ - */ - - - - -#ifndef _BCMETH_H_ -#define _BCMETH_H_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - - -#include - - - - - - - -#define BCMILCP_SUBTYPE_RATE 1 -#define BCMILCP_SUBTYPE_LINK 2 -#define BCMILCP_SUBTYPE_CSA 3 -#define BCMILCP_SUBTYPE_LARQ 4 -#define BCMILCP_SUBTYPE_VENDOR 5 -#define BCMILCP_SUBTYPE_FLH 17 - -#define BCMILCP_SUBTYPE_VENDOR_LONG 32769 -#define BCMILCP_SUBTYPE_CERT 32770 -#define BCMILCP_SUBTYPE_SES 32771 - - -#define BCMILCP_BCM_SUBTYPE_RESERVED 0 -#define BCMILCP_BCM_SUBTYPE_EVENT 1 -#define BCMILCP_BCM_SUBTYPE_SES 2 - - -#define BCMILCP_BCM_SUBTYPE_DPT 4 - -#define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH 8 -#define BCMILCP_BCM_SUBTYPEHDR_VERSION 0 - - -typedef BWL_PRE_PACKED_STRUCT struct bcmeth_hdr -{ - uint16 subtype; - uint16 length; - uint8 version; - uint8 oui[3]; - - uint16 usr_subtype; -} BWL_POST_PACKED_STRUCT bcmeth_hdr_t; - - - -#include - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h b/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h deleted file mode 100644 index e8c2387dd10b..000000000000 --- a/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Broadcom Event protocol definitions - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * Dependencies: proto/bcmeth.h - * - * $Id: bcmevent.h 288077 2011-10-06 00:08:47Z $ - * - */ - - - - -#ifndef _BCMEVENT_H_ -#define _BCMEVENT_H_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - - -#include - -#define BCM_EVENT_MSG_VERSION 2 -#define BCM_MSG_IFNAME_MAX 16 - - -#define WLC_EVENT_MSG_LINK 0x01 -#define WLC_EVENT_MSG_FLUSHTXQ 0x02 -#define WLC_EVENT_MSG_GROUP 0x04 -#define WLC_EVENT_MSG_UNKBSS 0x08 -#define WLC_EVENT_MSG_UNKIF 0x10 - - - - -typedef BWL_PRE_PACKED_STRUCT struct -{ - uint16 version; - uint16 flags; - uint32 event_type; - uint32 status; - uint32 reason; - uint32 auth_type; - uint32 datalen; - struct ether_addr addr; - char ifname[BCM_MSG_IFNAME_MAX]; -} BWL_POST_PACKED_STRUCT wl_event_msg_v1_t; - - -typedef BWL_PRE_PACKED_STRUCT struct -{ - uint16 version; - uint16 flags; - uint32 event_type; - uint32 status; - uint32 reason; - uint32 auth_type; - uint32 datalen; - struct ether_addr addr; - char ifname[BCM_MSG_IFNAME_MAX]; - uint8 ifidx; - uint8 bsscfgidx; -} BWL_POST_PACKED_STRUCT wl_event_msg_t; - - -typedef BWL_PRE_PACKED_STRUCT struct bcm_event { - struct ether_header eth; - bcmeth_hdr_t bcm_hdr; - wl_event_msg_t event; - -} BWL_POST_PACKED_STRUCT bcm_event_t; - -#define BCM_MSG_LEN (sizeof(bcm_event_t) - sizeof(bcmeth_hdr_t) - sizeof(struct ether_header)) - - -#define WLC_E_SET_SSID 0 -#define WLC_E_JOIN 1 -#define WLC_E_START 2 -#define WLC_E_AUTH 3 -#define WLC_E_AUTH_IND 4 -#define WLC_E_DEAUTH 5 -#define WLC_E_DEAUTH_IND 6 -#define WLC_E_ASSOC 7 -#define WLC_E_ASSOC_IND 8 -#define WLC_E_REASSOC 9 -#define WLC_E_REASSOC_IND 10 -#define WLC_E_DISASSOC 11 -#define WLC_E_DISASSOC_IND 12 -#define WLC_E_QUIET_START 13 -#define WLC_E_QUIET_END 14 -#define WLC_E_BEACON_RX 15 -#define WLC_E_LINK 16 -#define WLC_E_MIC_ERROR 17 -#define WLC_E_NDIS_LINK 18 -#define WLC_E_ROAM 19 -#define WLC_E_TXFAIL 20 -#define WLC_E_PMKID_CACHE 21 -#define WLC_E_RETROGRADE_TSF 22 -#define WLC_E_PRUNE 23 -#define WLC_E_AUTOAUTH 24 -#define WLC_E_EAPOL_MSG 25 -#define WLC_E_SCAN_COMPLETE 26 -#define WLC_E_ADDTS_IND 27 -#define WLC_E_DELTS_IND 28 -#define WLC_E_BCNSENT_IND 29 -#define WLC_E_BCNRX_MSG 30 -#define WLC_E_BCNLOST_MSG 31 -#define WLC_E_ROAM_PREP 32 -#define WLC_E_PFN_NET_FOUND 33 -#define WLC_E_PFN_NET_LOST 34 -#define WLC_E_RESET_COMPLETE 35 -#define WLC_E_JOIN_START 36 -#define WLC_E_ROAM_START 37 -#define WLC_E_ASSOC_START 38 -#define WLC_E_IBSS_ASSOC 39 -#define WLC_E_RADIO 40 -#define WLC_E_PSM_WATCHDOG 41 -#define WLC_E_PROBREQ_MSG 44 -#define WLC_E_SCAN_CONFIRM_IND 45 -#define WLC_E_PSK_SUP 46 -#define WLC_E_COUNTRY_CODE_CHANGED 47 -#define WLC_E_EXCEEDED_MEDIUM_TIME 48 -#define WLC_E_ICV_ERROR 49 -#define WLC_E_UNICAST_DECODE_ERROR 50 -#define WLC_E_MULTICAST_DECODE_ERROR 51 -#define WLC_E_TRACE 52 -#define WLC_E_BTA_HCI_EVENT 53 -#define WLC_E_IF 54 -#ifdef WLP2P -#define WLC_E_P2P_DISC_LISTEN_COMPLETE 55 -#endif -#define WLC_E_RSSI 56 -#define WLC_E_PFN_SCAN_COMPLETE 57 -#define WLC_E_EXTLOG_MSG 58 -#define WLC_E_ACTION_FRAME 59 -#define WLC_E_ACTION_FRAME_COMPLETE 60 -#define WLC_E_PRE_ASSOC_IND 61 -#define WLC_E_PRE_REASSOC_IND 62 -#define WLC_E_CHANNEL_ADOPTED 63 -#define WLC_E_AP_STARTED 64 -#define WLC_E_DFS_AP_STOP 65 -#define WLC_E_DFS_AP_RESUME 66 -#define WLC_E_WAI_STA_EVENT 67 -#define WLC_E_WAI_MSG 68 -#define WLC_E_ESCAN_RESULT 69 -#define WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70 -#if defined(WLP2P) -#define WLC_E_PROBRESP_MSG 71 -#define WLC_E_P2P_PROBREQ_MSG 72 -#endif -#define WLC_E_DCS_REQUEST 73 - -#define WLC_E_FIFO_CREDIT_MAP 74 - -#define WLC_E_ACTION_FRAME_RX 75 -#define WLC_E_WAKE_EVENT 76 -#define WLC_E_RM_COMPLETE 77 -#define WLC_E_HTSFSYNC 78 -#define WLC_E_OVERLAY_REQ 79 -#define WLC_E_CSA_COMPLETE_IND 80 -#define WLC_E_EXCESS_PM_WAKE_EVENT 81 -#define WLC_E_PFN_SCAN_NONE 82 -#define WLC_E_PFN_SCAN_ALLGONE 83 -#define WLC_E_GTK_PLUMBED 84 -#define WLC_E_ASSOC_REQ_IE 85 -#define WLC_E_ASSOC_RESP_IE 86 -#define WLC_E_LAST 87 - - - -typedef struct { - uint event; - const char *name; -} bcmevent_name_t; - -extern const bcmevent_name_t bcmevent_names[]; -extern const int bcmevent_names_size; - - -#define WLC_E_STATUS_SUCCESS 0 -#define WLC_E_STATUS_FAIL 1 -#define WLC_E_STATUS_TIMEOUT 2 -#define WLC_E_STATUS_NO_NETWORKS 3 -#define WLC_E_STATUS_ABORT 4 -#define WLC_E_STATUS_NO_ACK 5 -#define WLC_E_STATUS_UNSOLICITED 6 -#define WLC_E_STATUS_ATTEMPT 7 -#define WLC_E_STATUS_PARTIAL 8 -#define WLC_E_STATUS_NEWSCAN 9 -#define WLC_E_STATUS_NEWASSOC 10 -#define WLC_E_STATUS_11HQUIET 11 -#define WLC_E_STATUS_SUPPRESS 12 -#define WLC_E_STATUS_NOCHANS 13 -#define WLC_E_STATUS_CS_ABORT 15 -#define WLC_E_STATUS_ERROR 16 - - -#define WLC_E_REASON_INITIAL_ASSOC 0 -#define WLC_E_REASON_LOW_RSSI 1 -#define WLC_E_REASON_DEAUTH 2 -#define WLC_E_REASON_DISASSOC 3 -#define WLC_E_REASON_BCNS_LOST 4 -#define WLC_E_REASON_MINTXRATE 9 -#define WLC_E_REASON_TXFAIL 10 - - -#define WLC_E_REASON_FAST_ROAM_FAILED 5 -#define WLC_E_REASON_DIRECTED_ROAM 6 -#define WLC_E_REASON_TSPEC_REJECTED 7 -#define WLC_E_REASON_BETTER_AP 8 - -#define WLC_E_REASON_REQUESTED_ROAM 11 - - -#define WLC_E_PRUNE_ENCR_MISMATCH 1 -#define WLC_E_PRUNE_BCAST_BSSID 2 -#define WLC_E_PRUNE_MAC_DENY 3 -#define WLC_E_PRUNE_MAC_NA 4 -#define WLC_E_PRUNE_REG_PASSV 5 -#define WLC_E_PRUNE_SPCT_MGMT 6 -#define WLC_E_PRUNE_RADAR 7 -#define WLC_E_RSN_MISMATCH 8 -#define WLC_E_PRUNE_NO_COMMON_RATES 9 -#define WLC_E_PRUNE_BASIC_RATES 10 -#define WLC_E_PRUNE_CIPHER_NA 12 -#define WLC_E_PRUNE_KNOWN_STA 13 -#define WLC_E_PRUNE_WDS_PEER 15 -#define WLC_E_PRUNE_QBSS_LOAD 16 -#define WLC_E_PRUNE_HOME_AP 17 - - -#define WLC_E_SUP_OTHER 0 -#define WLC_E_SUP_DECRYPT_KEY_DATA 1 -#define WLC_E_SUP_BAD_UCAST_WEP128 2 -#define WLC_E_SUP_BAD_UCAST_WEP40 3 -#define WLC_E_SUP_UNSUP_KEY_LEN 4 -#define WLC_E_SUP_PW_KEY_CIPHER 5 -#define WLC_E_SUP_MSG3_TOO_MANY_IE 6 -#define WLC_E_SUP_MSG3_IE_MISMATCH 7 -#define WLC_E_SUP_NO_INSTALL_FLAG 8 -#define WLC_E_SUP_MSG3_NO_GTK 9 -#define WLC_E_SUP_GRP_KEY_CIPHER 10 -#define WLC_E_SUP_GRP_MSG1_NO_GTK 11 -#define WLC_E_SUP_GTK_DECRYPT_FAIL 12 -#define WLC_E_SUP_SEND_FAIL 13 -#define WLC_E_SUP_DEAUTH 14 -#define WLC_E_SUP_WPA_PSK_TMO 15 - - - -typedef BWL_PRE_PACKED_STRUCT struct wl_event_rx_frame_data { - uint16 version; - uint16 channel; - int32 rssi; - uint32 mactime; - uint32 rate; -} BWL_POST_PACKED_STRUCT wl_event_rx_frame_data_t; - -#define BCM_RX_FRAME_DATA_VERSION 1 - - -typedef struct wl_event_data_if { - uint8 ifidx; - uint8 opcode; - uint8 reserved; - uint8 bssidx; - uint8 role; -} wl_event_data_if_t; - - -#define WLC_E_IF_ADD 1 -#define WLC_E_IF_DEL 2 -#define WLC_E_IF_CHANGE 3 - - -#define WLC_E_IF_ROLE_STA 0 -#define WLC_E_IF_ROLE_AP 1 -#define WLC_E_IF_ROLE_WDS 2 -#define WLC_E_IF_ROLE_P2P_GO 3 -#define WLC_E_IF_ROLE_P2P_CLIENT 4 -#define WLC_E_IF_ROLE_BTA_CREATOR 5 -#define WLC_E_IF_ROLE_BTA_ACCEPTOR 6 - - -#define WLC_E_LINK_BCN_LOSS 1 -#define WLC_E_LINK_DISASSOC 2 -#define WLC_E_LINK_ASSOC_REC 3 -#define WLC_E_LINK_BSSCFG_DIS 4 - - -#define WLC_E_OVL_DOWNLOAD 0 -#define WLC_E_OVL_UPDATE_IND 1 - - -#include - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/proto/bcmip.h b/drivers/net/wireless/bcmdhd/include/proto/bcmip.h deleted file mode 100644 index 55eff247c492..000000000000 --- a/drivers/net/wireless/bcmdhd/include/proto/bcmip.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * Fundamental constants relating to IP Protocol - * - * $Id: bcmip.h 277737 2011-08-16 17:54:59Z $ - */ - - -#ifndef _bcmip_h_ -#define _bcmip_h_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - - -#include - - - -#define IP_VER_OFFSET 0x0 -#define IP_VER_MASK 0xf0 -#define IP_VER_SHIFT 4 -#define IP_VER_4 4 -#define IP_VER_6 6 - -#define IP_VER(ip_body) \ - ((((uint8 *)(ip_body))[IP_VER_OFFSET] & IP_VER_MASK) >> IP_VER_SHIFT) - -#define IP_PROT_ICMP 0x1 -#define IP_PROT_TCP 0x6 -#define IP_PROT_UDP 0x11 - - -#define IPV4_VER_HL_OFFSET 0 -#define IPV4_TOS_OFFSET 1 -#define IPV4_PKTLEN_OFFSET 2 -#define IPV4_PKTFLAG_OFFSET 6 -#define IPV4_PROT_OFFSET 9 -#define IPV4_CHKSUM_OFFSET 10 -#define IPV4_SRC_IP_OFFSET 12 -#define IPV4_DEST_IP_OFFSET 16 -#define IPV4_OPTIONS_OFFSET 20 - - -#define IPV4_VER_MASK 0xf0 -#define IPV4_VER_SHIFT 4 - -#define IPV4_HLEN_MASK 0x0f -#define IPV4_HLEN(ipv4_body) (4 * (((uint8 *)(ipv4_body))[IPV4_VER_HL_OFFSET] & IPV4_HLEN_MASK)) - -#define IPV4_ADDR_LEN 4 - -#define IPV4_ADDR_NULL(a) ((((uint8 *)(a))[0] | ((uint8 *)(a))[1] | \ - ((uint8 *)(a))[2] | ((uint8 *)(a))[3]) == 0) - -#define IPV4_ADDR_BCAST(a) ((((uint8 *)(a))[0] & ((uint8 *)(a))[1] & \ - ((uint8 *)(a))[2] & ((uint8 *)(a))[3]) == 0xff) - -#define IPV4_TOS_DSCP_MASK 0xfc -#define IPV4_TOS_DSCP_SHIFT 2 - -#define IPV4_TOS(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_TOS_OFFSET]) - -#define IPV4_TOS_PREC_MASK 0xe0 -#define IPV4_TOS_PREC_SHIFT 5 - -#define IPV4_TOS_LOWDELAY 0x10 -#define IPV4_TOS_THROUGHPUT 0x8 -#define IPV4_TOS_RELIABILITY 0x4 - -#define IPV4_PROT(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_PROT_OFFSET]) - -#define IPV4_FRAG_RESV 0x8000 -#define IPV4_FRAG_DONT 0x4000 -#define IPV4_FRAG_MORE 0x2000 -#define IPV4_FRAG_OFFSET_MASK 0x1fff - -#define IPV4_ADDR_STR_LEN 16 - - -BWL_PRE_PACKED_STRUCT struct ipv4_addr { - uint8 addr[IPV4_ADDR_LEN]; -} BWL_POST_PACKED_STRUCT; - -BWL_PRE_PACKED_STRUCT struct ipv4_hdr { - uint8 version_ihl; - uint8 tos; - uint16 tot_len; - uint16 id; - uint16 frag; - uint8 ttl; - uint8 prot; - uint16 hdr_chksum; - uint8 src_ip[IPV4_ADDR_LEN]; - uint8 dst_ip[IPV4_ADDR_LEN]; -} BWL_POST_PACKED_STRUCT; - - -#define IPV6_PAYLOAD_LEN_OFFSET 4 -#define IPV6_NEXT_HDR_OFFSET 6 -#define IPV6_HOP_LIMIT_OFFSET 7 -#define IPV6_SRC_IP_OFFSET 8 -#define IPV6_DEST_IP_OFFSET 24 - - -#define IPV6_TRAFFIC_CLASS(ipv6_body) \ - (((((uint8 *)(ipv6_body))[0] & 0x0f) << 4) | \ - ((((uint8 *)(ipv6_body))[1] & 0xf0) >> 4)) - -#define IPV6_FLOW_LABEL(ipv6_body) \ - (((((uint8 *)(ipv6_body))[1] & 0x0f) << 16) | \ - (((uint8 *)(ipv6_body))[2] << 8) | \ - (((uint8 *)(ipv6_body))[3])) - -#define IPV6_PAYLOAD_LEN(ipv6_body) \ - ((((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 0] << 8) | \ - ((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 1]) - -#define IPV6_NEXT_HDR(ipv6_body) \ - (((uint8 *)(ipv6_body))[IPV6_NEXT_HDR_OFFSET]) - -#define IPV6_PROT(ipv6_body) IPV6_NEXT_HDR(ipv6_body) - -#define IPV6_ADDR_LEN 16 - - -#define IP_TOS46(ip_body) \ - (IP_VER(ip_body) == IP_VER_4 ? IPV4_TOS(ip_body) : \ - IP_VER(ip_body) == IP_VER_6 ? IPV6_TRAFFIC_CLASS(ip_body) : 0) - - -#include - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h b/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h deleted file mode 100644 index 91ab4fe538f2..000000000000 --- a/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h +++ /dev/null @@ -1,442 +0,0 @@ -/* - * BT-AMP (BlueTooth Alternate Mac and Phy) HCI (Host/Controller Interface) - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: bt_amp_hci.h 277737 2011-08-16 17:54:59Z $ -*/ - -#ifndef _bt_amp_hci_h -#define _bt_amp_hci_h - -/* This marks the start of a packed structure section. */ -#include - - -/* AMP HCI CMD packet format */ -typedef BWL_PRE_PACKED_STRUCT struct amp_hci_cmd { - uint16 opcode; - uint8 plen; - uint8 parms[1]; -} BWL_POST_PACKED_STRUCT amp_hci_cmd_t; - -#define HCI_CMD_PREAMBLE_SIZE OFFSETOF(amp_hci_cmd_t, parms) -#define HCI_CMD_DATA_SIZE 255 - -/* AMP HCI CMD opcode layout */ -#define HCI_CMD_OPCODE(ogf, ocf) ((((ogf) & 0x3F) << 10) | ((ocf) & 0x03FF)) -#define HCI_CMD_OGF(opcode) ((uint8)(((opcode) >> 10) & 0x3F)) -#define HCI_CMD_OCF(opcode) ((opcode) & 0x03FF) - -/* AMP HCI command opcodes */ -#define HCI_Read_Failed_Contact_Counter HCI_CMD_OPCODE(0x05, 0x0001) -#define HCI_Reset_Failed_Contact_Counter HCI_CMD_OPCODE(0x05, 0x0002) -#define HCI_Read_Link_Quality HCI_CMD_OPCODE(0x05, 0x0003) -#define HCI_Read_Local_AMP_Info HCI_CMD_OPCODE(0x05, 0x0009) -#define HCI_Read_Local_AMP_ASSOC HCI_CMD_OPCODE(0x05, 0x000A) -#define HCI_Write_Remote_AMP_ASSOC HCI_CMD_OPCODE(0x05, 0x000B) -#define HCI_Create_Physical_Link HCI_CMD_OPCODE(0x01, 0x0035) -#define HCI_Accept_Physical_Link_Request HCI_CMD_OPCODE(0x01, 0x0036) -#define HCI_Disconnect_Physical_Link HCI_CMD_OPCODE(0x01, 0x0037) -#define HCI_Create_Logical_Link HCI_CMD_OPCODE(0x01, 0x0038) -#define HCI_Accept_Logical_Link HCI_CMD_OPCODE(0x01, 0x0039) -#define HCI_Disconnect_Logical_Link HCI_CMD_OPCODE(0x01, 0x003A) -#define HCI_Logical_Link_Cancel HCI_CMD_OPCODE(0x01, 0x003B) -#define HCI_Flow_Spec_Modify HCI_CMD_OPCODE(0x01, 0x003C) -#define HCI_Write_Flow_Control_Mode HCI_CMD_OPCODE(0x01, 0x0067) -#define HCI_Read_Best_Effort_Flush_Timeout HCI_CMD_OPCODE(0x01, 0x0069) -#define HCI_Write_Best_Effort_Flush_Timeout HCI_CMD_OPCODE(0x01, 0x006A) -#define HCI_Short_Range_Mode HCI_CMD_OPCODE(0x01, 0x006B) -#define HCI_Reset HCI_CMD_OPCODE(0x03, 0x0003) -#define HCI_Read_Connection_Accept_Timeout HCI_CMD_OPCODE(0x03, 0x0015) -#define HCI_Write_Connection_Accept_Timeout HCI_CMD_OPCODE(0x03, 0x0016) -#define HCI_Read_Link_Supervision_Timeout HCI_CMD_OPCODE(0x03, 0x0036) -#define HCI_Write_Link_Supervision_Timeout HCI_CMD_OPCODE(0x03, 0x0037) -#define HCI_Enhanced_Flush HCI_CMD_OPCODE(0x03, 0x005F) -#define HCI_Read_Logical_Link_Accept_Timeout HCI_CMD_OPCODE(0x03, 0x0061) -#define HCI_Write_Logical_Link_Accept_Timeout HCI_CMD_OPCODE(0x03, 0x0062) -#define HCI_Set_Event_Mask_Page_2 HCI_CMD_OPCODE(0x03, 0x0063) -#define HCI_Read_Location_Data_Command HCI_CMD_OPCODE(0x03, 0x0064) -#define HCI_Write_Location_Data_Command HCI_CMD_OPCODE(0x03, 0x0065) -#define HCI_Read_Local_Version_Info HCI_CMD_OPCODE(0x04, 0x0001) -#define HCI_Read_Local_Supported_Commands HCI_CMD_OPCODE(0x04, 0x0002) -#define HCI_Read_Buffer_Size HCI_CMD_OPCODE(0x04, 0x0005) -#define HCI_Read_Data_Block_Size HCI_CMD_OPCODE(0x04, 0x000A) - -/* AMP HCI command parameters */ -typedef BWL_PRE_PACKED_STRUCT struct read_local_cmd_parms { - uint8 plh; - uint8 offset[2]; /* length so far */ - uint8 max_remote[2]; -} BWL_POST_PACKED_STRUCT read_local_cmd_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct write_remote_cmd_parms { - uint8 plh; - uint8 offset[2]; - uint8 len[2]; - uint8 frag[1]; -} BWL_POST_PACKED_STRUCT write_remote_cmd_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct phy_link_cmd_parms { - uint8 plh; - uint8 key_length; - uint8 key_type; - uint8 key[1]; -} BWL_POST_PACKED_STRUCT phy_link_cmd_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct dis_phy_link_cmd_parms { - uint8 plh; - uint8 reason; -} BWL_POST_PACKED_STRUCT dis_phy_link_cmd_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct log_link_cmd_parms { - uint8 plh; - uint8 txflow[16]; - uint8 rxflow[16]; -} BWL_POST_PACKED_STRUCT log_link_cmd_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct ext_flow_spec { - uint8 id; - uint8 service_type; - uint8 max_sdu[2]; - uint8 sdu_ia_time[4]; - uint8 access_latency[4]; - uint8 flush_timeout[4]; -} BWL_POST_PACKED_STRUCT ext_flow_spec_t; - -typedef BWL_PRE_PACKED_STRUCT struct log_link_cancel_cmd_parms { - uint8 plh; - uint8 tx_fs_ID; -} BWL_POST_PACKED_STRUCT log_link_cancel_cmd_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct flow_spec_mod_cmd_parms { - uint8 llh[2]; - uint8 txflow[16]; - uint8 rxflow[16]; -} BWL_POST_PACKED_STRUCT flow_spec_mod_cmd_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct plh_pad { - uint8 plh; - uint8 pad; -} BWL_POST_PACKED_STRUCT plh_pad_t; - -typedef BWL_PRE_PACKED_STRUCT union hci_handle { - uint16 bredr; - plh_pad_t amp; -} BWL_POST_PACKED_STRUCT hci_handle_t; - -typedef BWL_PRE_PACKED_STRUCT struct ls_to_cmd_parms { - hci_handle_t handle; - uint8 timeout[2]; -} BWL_POST_PACKED_STRUCT ls_to_cmd_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct befto_cmd_parms { - uint8 llh[2]; - uint8 befto[4]; -} BWL_POST_PACKED_STRUCT befto_cmd_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct srm_cmd_parms { - uint8 plh; - uint8 srm; -} BWL_POST_PACKED_STRUCT srm_cmd_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct ld_cmd_parms { - uint8 ld_aware; - uint8 ld[2]; - uint8 ld_opts; - uint8 l_opts; -} BWL_POST_PACKED_STRUCT ld_cmd_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct eflush_cmd_parms { - uint8 llh[2]; - uint8 packet_type; -} BWL_POST_PACKED_STRUCT eflush_cmd_parms_t; - -/* Generic AMP extended flow spec service types */ -#define EFS_SVCTYPE_NO_TRAFFIC 0 -#define EFS_SVCTYPE_BEST_EFFORT 1 -#define EFS_SVCTYPE_GUARANTEED 2 - -/* AMP HCI event packet format */ -typedef BWL_PRE_PACKED_STRUCT struct amp_hci_event { - uint8 ecode; - uint8 plen; - uint8 parms[1]; -} BWL_POST_PACKED_STRUCT amp_hci_event_t; - -#define HCI_EVT_PREAMBLE_SIZE OFFSETOF(amp_hci_event_t, parms) - -/* AMP HCI event codes */ -#define HCI_Command_Complete 0x0E -#define HCI_Command_Status 0x0F -#define HCI_Flush_Occurred 0x11 -#define HCI_Enhanced_Flush_Complete 0x39 -#define HCI_Physical_Link_Complete 0x40 -#define HCI_Channel_Select 0x41 -#define HCI_Disconnect_Physical_Link_Complete 0x42 -#define HCI_Logical_Link_Complete 0x45 -#define HCI_Disconnect_Logical_Link_Complete 0x46 -#define HCI_Flow_Spec_Modify_Complete 0x47 -#define HCI_Number_of_Completed_Data_Blocks 0x48 -#define HCI_Short_Range_Mode_Change_Complete 0x4C -#define HCI_Status_Change_Event 0x4D -#define HCI_Vendor_Specific 0xFF - -/* AMP HCI event mask bit positions */ -#define HCI_Physical_Link_Complete_Event_Mask 0x0001 -#define HCI_Channel_Select_Event_Mask 0x0002 -#define HCI_Disconnect_Physical_Link_Complete_Event_Mask 0x0004 -#define HCI_Logical_Link_Complete_Event_Mask 0x0020 -#define HCI_Disconnect_Logical_Link_Complete_Event_Mask 0x0040 -#define HCI_Flow_Spec_Modify_Complete_Event_Mask 0x0080 -#define HCI_Number_of_Completed_Data_Blocks_Event_Mask 0x0100 -#define HCI_Short_Range_Mode_Change_Complete_Event_Mask 0x1000 -#define HCI_Status_Change_Event_Mask 0x2000 -#define HCI_All_Event_Mask 0x31e7 - -/* AMP HCI event parameters */ -typedef BWL_PRE_PACKED_STRUCT struct cmd_status_parms { - uint8 status; - uint8 cmdpkts; - uint16 opcode; -} BWL_POST_PACKED_STRUCT cmd_status_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct cmd_complete_parms { - uint8 cmdpkts; - uint16 opcode; - uint8 parms[1]; -} BWL_POST_PACKED_STRUCT cmd_complete_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct flush_occurred_evt_parms { - uint16 handle; -} BWL_POST_PACKED_STRUCT flush_occurred_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct write_remote_evt_parms { - uint8 status; - uint8 plh; -} BWL_POST_PACKED_STRUCT write_remote_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct read_local_evt_parms { - uint8 status; - uint8 plh; - uint16 len; - uint8 frag[1]; -} BWL_POST_PACKED_STRUCT read_local_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct read_local_info_evt_parms { - uint8 status; - uint8 AMP_status; - uint32 bandwidth; - uint32 gbandwidth; - uint32 latency; - uint32 PDU_size; - uint8 ctrl_type; - uint16 PAL_cap; - uint16 AMP_ASSOC_len; - uint32 max_flush_timeout; - uint32 be_flush_timeout; -} BWL_POST_PACKED_STRUCT read_local_info_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct log_link_evt_parms { - uint8 status; - uint16 llh; - uint8 plh; - uint8 tx_fs_ID; -} BWL_POST_PACKED_STRUCT log_link_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct disc_log_link_evt_parms { - uint8 status; - uint16 llh; - uint8 reason; -} BWL_POST_PACKED_STRUCT disc_log_link_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct log_link_cancel_evt_parms { - uint8 status; - uint8 plh; - uint8 tx_fs_ID; -} BWL_POST_PACKED_STRUCT log_link_cancel_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct flow_spec_mod_evt_parms { - uint8 status; - uint16 llh; -} BWL_POST_PACKED_STRUCT flow_spec_mod_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct phy_link_evt_parms { - uint8 status; - uint8 plh; -} BWL_POST_PACKED_STRUCT phy_link_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct dis_phy_link_evt_parms { - uint8 status; - uint8 plh; - uint8 reason; -} BWL_POST_PACKED_STRUCT dis_phy_link_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct read_ls_to_evt_parms { - uint8 status; - hci_handle_t handle; - uint16 timeout; -} BWL_POST_PACKED_STRUCT read_ls_to_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct read_lla_ca_to_evt_parms { - uint8 status; - uint16 timeout; -} BWL_POST_PACKED_STRUCT read_lla_ca_to_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct read_data_block_size_evt_parms { - uint8 status; - uint16 ACL_pkt_len; - uint16 data_block_len; - uint16 data_block_num; -} BWL_POST_PACKED_STRUCT read_data_block_size_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct data_blocks { - uint16 handle; - uint16 pkts; - uint16 blocks; -} BWL_POST_PACKED_STRUCT data_blocks_t; - -typedef BWL_PRE_PACKED_STRUCT struct num_completed_data_blocks_evt_parms { - uint16 num_blocks; - uint8 num_handles; - data_blocks_t completed[1]; -} BWL_POST_PACKED_STRUCT num_completed_data_blocks_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct befto_evt_parms { - uint8 status; - uint32 befto; -} BWL_POST_PACKED_STRUCT befto_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct srm_evt_parms { - uint8 status; - uint8 plh; - uint8 srm; -} BWL_POST_PACKED_STRUCT srm_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct contact_counter_evt_parms { - uint8 status; - uint8 llh[2]; - uint16 counter; -} BWL_POST_PACKED_STRUCT contact_counter_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct contact_counter_reset_evt_parms { - uint8 status; - uint8 llh[2]; -} BWL_POST_PACKED_STRUCT contact_counter_reset_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct read_linkq_evt_parms { - uint8 status; - hci_handle_t handle; - uint8 link_quality; -} BWL_POST_PACKED_STRUCT read_linkq_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct ld_evt_parms { - uint8 status; - uint8 ld_aware; - uint8 ld[2]; - uint8 ld_opts; - uint8 l_opts; -} BWL_POST_PACKED_STRUCT ld_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct eflush_complete_evt_parms { - uint16 handle; -} BWL_POST_PACKED_STRUCT eflush_complete_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct vendor_specific_evt_parms { - uint8 len; - uint8 parms[1]; -} BWL_POST_PACKED_STRUCT vendor_specific_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct local_version_info_evt_parms { - uint8 status; - uint8 hci_version; - uint16 hci_revision; - uint8 pal_version; - uint16 mfg_name; - uint16 pal_subversion; -} BWL_POST_PACKED_STRUCT local_version_info_evt_parms_t; - -#define MAX_SUPPORTED_CMD_BYTE 64 -typedef BWL_PRE_PACKED_STRUCT struct local_supported_cmd_evt_parms { - uint8 status; - uint8 cmd[MAX_SUPPORTED_CMD_BYTE]; -} BWL_POST_PACKED_STRUCT local_supported_cmd_evt_parms_t; - -typedef BWL_PRE_PACKED_STRUCT struct status_change_evt_parms { - uint8 status; - uint8 amp_status; -} BWL_POST_PACKED_STRUCT status_change_evt_parms_t; - -/* AMP HCI error codes */ -#define HCI_SUCCESS 0x00 -#define HCI_ERR_ILLEGAL_COMMAND 0x01 -#define HCI_ERR_NO_CONNECTION 0x02 -#define HCI_ERR_MEMORY_FULL 0x07 -#define HCI_ERR_CONNECTION_TIMEOUT 0x08 -#define HCI_ERR_MAX_NUM_OF_CONNECTIONS 0x09 -#define HCI_ERR_CONNECTION_EXISTS 0x0B -#define HCI_ERR_CONNECTION_DISALLOWED 0x0C -#define HCI_ERR_CONNECTION_ACCEPT_TIMEOUT 0x10 -#define HCI_ERR_UNSUPPORTED_VALUE 0x11 -#define HCI_ERR_ILLEGAL_PARAMETER_FMT 0x12 -#define HCI_ERR_CONN_TERM_BY_LOCAL_HOST 0x16 -#define HCI_ERR_UNSPECIFIED 0x1F -#define HCI_ERR_UNIT_KEY_USED 0x26 -#define HCI_ERR_QOS_REJECTED 0x2D -#define HCI_ERR_PARAM_OUT_OF_RANGE 0x30 -#define HCI_ERR_NO_SUITABLE_CHANNEL 0x39 -#define HCI_ERR_CHANNEL_MOVE 0xFF - -/* AMP HCI ACL Data packet format */ -typedef BWL_PRE_PACKED_STRUCT struct amp_hci_ACL_data { - uint16 handle; /* 12-bit connection handle + 2-bit PB and 2-bit BC flags */ - uint16 dlen; /* data total length */ - uint8 data[1]; -} BWL_POST_PACKED_STRUCT amp_hci_ACL_data_t; - -#define HCI_ACL_DATA_PREAMBLE_SIZE OFFSETOF(amp_hci_ACL_data_t, data) - -#define HCI_ACL_DATA_BC_FLAGS (0x0 << 14) -#define HCI_ACL_DATA_PB_FLAGS (0x3 << 12) - -#define HCI_ACL_DATA_HANDLE(handle) ((handle) & 0x0fff) -#define HCI_ACL_DATA_FLAGS(handle) ((handle) >> 12) - -/* AMP Activity Report packet formats */ -typedef BWL_PRE_PACKED_STRUCT struct amp_hci_activity_report { - uint8 ScheduleKnown; - uint8 NumReports; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT amp_hci_activity_report_t; - -typedef BWL_PRE_PACKED_STRUCT struct amp_hci_activity_report_triple { - uint32 StartTime; - uint32 Duration; - uint32 Periodicity; -} BWL_POST_PACKED_STRUCT amp_hci_activity_report_triple_t; - -#define HCI_AR_SCHEDULE_KNOWN 0x01 - - -/* This marks the end of a packed structure section. */ -#include - -#endif /* _bt_amp_hci_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/proto/eapol.h b/drivers/net/wireless/bcmdhd/include/proto/eapol.h deleted file mode 100644 index 92634c1221a6..000000000000 --- a/drivers/net/wireless/bcmdhd/include/proto/eapol.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * 802.1x EAPOL definitions - * - * See - * IEEE Std 802.1X-2001 - * IEEE 802.1X RADIUS Usage Guidelines - * - * Copyright (C) 2002 Broadcom Corporation - * - * $Id: eapol.h 277737 2011-08-16 17:54:59Z $ - */ - -#ifndef _eapol_h_ -#define _eapol_h_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - -/* This marks the start of a packed structure section. */ -#include - -#include - -/* EAPOL for 802.3/Ethernet */ -typedef struct { - struct ether_header eth; /* 802.3/Ethernet header */ - unsigned char version; /* EAPOL protocol version */ - unsigned char type; /* EAPOL type */ - unsigned short length; /* Length of body */ - unsigned char body[1]; /* Body (optional) */ -} eapol_header_t; - -#define EAPOL_HEADER_LEN 18 - -/* EAPOL version */ -#define WPA2_EAPOL_VERSION 2 -#define WPA_EAPOL_VERSION 1 -#define LEAP_EAPOL_VERSION 1 -#define SES_EAPOL_VERSION 1 - -/* EAPOL types */ -#define EAP_PACKET 0 -#define EAPOL_START 1 -#define EAPOL_LOGOFF 2 -#define EAPOL_KEY 3 -#define EAPOL_ASF 4 - -/* EAPOL-Key types */ -#define EAPOL_RC4_KEY 1 -#define EAPOL_WPA2_KEY 2 /* 802.11i/WPA2 */ -#define EAPOL_WPA_KEY 254 /* WPA */ - -/* RC4 EAPOL-Key header field sizes */ -#define EAPOL_KEY_REPLAY_LEN 8 -#define EAPOL_KEY_IV_LEN 16 -#define EAPOL_KEY_SIG_LEN 16 - -/* RC4 EAPOL-Key */ -typedef BWL_PRE_PACKED_STRUCT struct { - unsigned char type; /* Key Descriptor Type */ - unsigned short length; /* Key Length (unaligned) */ - unsigned char replay[EAPOL_KEY_REPLAY_LEN]; /* Replay Counter */ - unsigned char iv[EAPOL_KEY_IV_LEN]; /* Key IV */ - unsigned char index; /* Key Flags & Index */ - unsigned char signature[EAPOL_KEY_SIG_LEN]; /* Key Signature */ - unsigned char key[1]; /* Key (optional) */ -} BWL_POST_PACKED_STRUCT eapol_key_header_t; - -#define EAPOL_KEY_HEADER_LEN 44 - -/* RC4 EAPOL-Key flags */ -#define EAPOL_KEY_FLAGS_MASK 0x80 -#define EAPOL_KEY_BROADCAST 0 -#define EAPOL_KEY_UNICAST 0x80 - -/* RC4 EAPOL-Key index */ -#define EAPOL_KEY_INDEX_MASK 0x7f - -/* WPA/802.11i/WPA2 EAPOL-Key header field sizes */ -#define EAPOL_WPA_KEY_REPLAY_LEN 8 -#define EAPOL_WPA_KEY_NONCE_LEN 32 -#define EAPOL_WPA_KEY_IV_LEN 16 -#define EAPOL_WPA_KEY_RSC_LEN 8 -#define EAPOL_WPA_KEY_ID_LEN 8 -#define EAPOL_WPA_KEY_MIC_LEN 16 -#define EAPOL_WPA_KEY_DATA_LEN (EAPOL_WPA_MAX_KEY_SIZE + AKW_BLOCK_LEN) -#define EAPOL_WPA_MAX_KEY_SIZE 32 - -/* WPA EAPOL-Key */ -typedef BWL_PRE_PACKED_STRUCT struct { - unsigned char type; /* Key Descriptor Type */ - unsigned short key_info; /* Key Information (unaligned) */ - unsigned short key_len; /* Key Length (unaligned) */ - unsigned char replay[EAPOL_WPA_KEY_REPLAY_LEN]; /* Replay Counter */ - unsigned char nonce[EAPOL_WPA_KEY_NONCE_LEN]; /* Nonce */ - unsigned char iv[EAPOL_WPA_KEY_IV_LEN]; /* Key IV */ - unsigned char rsc[EAPOL_WPA_KEY_RSC_LEN]; /* Key RSC */ - unsigned char id[EAPOL_WPA_KEY_ID_LEN]; /* WPA:Key ID, 802.11i/WPA2: Reserved */ - unsigned char mic[EAPOL_WPA_KEY_MIC_LEN]; /* Key MIC */ - unsigned short data_len; /* Key Data Length */ - unsigned char data[EAPOL_WPA_KEY_DATA_LEN]; /* Key data */ -} BWL_POST_PACKED_STRUCT eapol_wpa_key_header_t; - -#define EAPOL_WPA_KEY_LEN 95 - -/* WPA/802.11i/WPA2 KEY KEY_INFO bits */ -#define WPA_KEY_DESC_V1 0x01 -#define WPA_KEY_DESC_V2 0x02 -#define WPA_KEY_DESC_V3 0x03 -#define WPA_KEY_PAIRWISE 0x08 -#define WPA_KEY_INSTALL 0x40 -#define WPA_KEY_ACK 0x80 -#define WPA_KEY_MIC 0x100 -#define WPA_KEY_SECURE 0x200 -#define WPA_KEY_ERROR 0x400 -#define WPA_KEY_REQ 0x800 - -/* WPA-only KEY KEY_INFO bits */ -#define WPA_KEY_INDEX_0 0x00 -#define WPA_KEY_INDEX_1 0x10 -#define WPA_KEY_INDEX_2 0x20 -#define WPA_KEY_INDEX_3 0x30 -#define WPA_KEY_INDEX_MASK 0x30 -#define WPA_KEY_INDEX_SHIFT 0x04 - -/* 802.11i/WPA2-only KEY KEY_INFO bits */ -#define WPA_KEY_ENCRYPTED_DATA 0x1000 - -/* Key Data encapsulation */ -typedef BWL_PRE_PACKED_STRUCT struct { - uint8 type; - uint8 length; - uint8 oui[3]; - uint8 subtype; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT eapol_wpa2_encap_data_t; - -#define EAPOL_WPA2_ENCAP_DATA_HDR_LEN 6 - -#define WPA2_KEY_DATA_SUBTYPE_GTK 1 -#define WPA2_KEY_DATA_SUBTYPE_STAKEY 2 -#define WPA2_KEY_DATA_SUBTYPE_MAC 3 -#define WPA2_KEY_DATA_SUBTYPE_PMKID 4 - -/* GTK encapsulation */ -typedef BWL_PRE_PACKED_STRUCT struct { - uint8 flags; - uint8 reserved; - uint8 gtk[EAPOL_WPA_MAX_KEY_SIZE]; -} BWL_POST_PACKED_STRUCT eapol_wpa2_key_gtk_encap_t; - -#define EAPOL_WPA2_KEY_GTK_ENCAP_HDR_LEN 2 - -#define WPA2_GTK_INDEX_MASK 0x03 -#define WPA2_GTK_INDEX_SHIFT 0x00 - -#define WPA2_GTK_TRANSMIT 0x04 - -/* STAKey encapsulation */ -typedef BWL_PRE_PACKED_STRUCT struct { - uint8 reserved[2]; - uint8 mac[ETHER_ADDR_LEN]; - uint8 stakey[EAPOL_WPA_MAX_KEY_SIZE]; -} BWL_POST_PACKED_STRUCT eapol_wpa2_key_stakey_encap_t; - -#define WPA2_KEY_DATA_PAD 0xdd - - -/* This marks the end of a packed structure section. */ -#include - -#endif /* _eapol_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/proto/ethernet.h b/drivers/net/wireless/bcmdhd/include/proto/ethernet.h deleted file mode 100644 index 20865dc5a231..000000000000 --- a/drivers/net/wireless/bcmdhd/include/proto/ethernet.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * From FreeBSD 2.2.7: Fundamental constants relating to ethernet. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: ethernet.h 285437 2011-09-21 22:16:56Z $ - */ - - -#ifndef _NET_ETHERNET_H_ -#define _NET_ETHERNET_H_ - -#ifndef _TYPEDEFS_H_ -#include "typedefs.h" -#endif - - -#include - - - -#define ETHER_ADDR_LEN 6 - - -#define ETHER_TYPE_LEN 2 - - -#define ETHER_CRC_LEN 4 - - -#define ETHER_HDR_LEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN) - - -#define ETHER_MIN_LEN 64 - - -#define ETHER_MIN_DATA 46 - - -#define ETHER_MAX_LEN 1518 - - -#define ETHER_MAX_DATA 1500 - - -#define ETHER_TYPE_MIN 0x0600 -#define ETHER_TYPE_IP 0x0800 -#define ETHER_TYPE_ARP 0x0806 -#define ETHER_TYPE_8021Q 0x8100 -#define ETHER_TYPE_BRCM 0x886c -#define ETHER_TYPE_802_1X 0x888e -#define ETHER_TYPE_802_1X_PREAUTH 0x88c7 -#define ETHER_TYPE_WAI 0x88b4 -#define ETHER_TYPE_89_0D 0x890d - - - -#define ETHER_BRCM_SUBTYPE_LEN 4 -#define ETHER_BRCM_CRAM 1 - - -#define ETHER_DEST_OFFSET (0 * ETHER_ADDR_LEN) -#define ETHER_SRC_OFFSET (1 * ETHER_ADDR_LEN) -#define ETHER_TYPE_OFFSET (2 * ETHER_ADDR_LEN) - - -#define ETHER_IS_VALID_LEN(foo) \ - ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN) - -#define ETHER_FILL_MCAST_ADDR_FROM_IP(ea, mgrp_ip) { \ - ((uint8 *)ea)[0] = 0x01; \ - ((uint8 *)ea)[1] = 0x00; \ - ((uint8 *)ea)[2] = 0x5e; \ - ((uint8 *)ea)[3] = ((mgrp_ip) >> 16) & 0x7f; \ - ((uint8 *)ea)[4] = ((mgrp_ip) >> 8) & 0xff; \ - ((uint8 *)ea)[5] = ((mgrp_ip) >> 0) & 0xff; \ -} - -#ifndef __INCif_etherh - -BWL_PRE_PACKED_STRUCT struct ether_header { - uint8 ether_dhost[ETHER_ADDR_LEN]; - uint8 ether_shost[ETHER_ADDR_LEN]; - uint16 ether_type; -} BWL_POST_PACKED_STRUCT; - - -BWL_PRE_PACKED_STRUCT struct ether_addr { - uint8 octet[ETHER_ADDR_LEN]; -} BWL_POST_PACKED_STRUCT; -#endif - - -#define ETHER_SET_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] | 2)) -#define ETHER_IS_LOCALADDR(ea) (((uint8 *)(ea))[0] & 2) -#define ETHER_CLR_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & 0xd)) -#define ETHER_TOGGLE_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] ^ 2)) - - -#define ETHER_SET_UNICAST(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & ~1)) - - -#define ETHER_ISMULTI(ea) (((const uint8 *)(ea))[0] & 1) - - - -#define ether_cmp(a, b) (!(((short*)a)[0] == ((short*)b)[0]) | \ - !(((short*)a)[1] == ((short*)b)[1]) | \ - !(((short*)a)[2] == ((short*)b)[2])) - - -#define ether_copy(s, d) { \ - ((short*)d)[0] = ((short*)s)[0]; \ - ((short*)d)[1] = ((short*)s)[1]; \ - ((short*)d)[2] = ((short*)s)[2]; } - - -static const struct ether_addr ether_bcast = {{255, 255, 255, 255, 255, 255}}; -static const struct ether_addr ether_null = {{0, 0, 0, 0, 0, 0}}; - -#define ETHER_ISBCAST(ea) ((((uint8 *)(ea))[0] & \ - ((uint8 *)(ea))[1] & \ - ((uint8 *)(ea))[2] & \ - ((uint8 *)(ea))[3] & \ - ((uint8 *)(ea))[4] & \ - ((uint8 *)(ea))[5]) == 0xff) -#define ETHER_ISNULLADDR(ea) ((((uint8 *)(ea))[0] | \ - ((uint8 *)(ea))[1] | \ - ((uint8 *)(ea))[2] | \ - ((uint8 *)(ea))[3] | \ - ((uint8 *)(ea))[4] | \ - ((uint8 *)(ea))[5]) == 0) - - -#define ETHER_MOVE_HDR(d, s) \ -do { \ - struct ether_header t; \ - t = *(struct ether_header *)(s); \ - *(struct ether_header *)(d) = t; \ -} while (0) - - -#include - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/proto/p2p.h b/drivers/net/wireless/bcmdhd/include/proto/p2p.h deleted file mode 100644 index d2bf3f20688c..000000000000 --- a/drivers/net/wireless/bcmdhd/include/proto/p2p.h +++ /dev/null @@ -1,512 +0,0 @@ -/* - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * Fundamental types and constants relating to WFA P2P (aka WiFi Direct) - * - * $Id: p2p.h 277737 2011-08-16 17:54:59Z $ - */ - -#ifndef _P2P_H_ -#define _P2P_H_ - -#ifndef _TYPEDEFS_H_ -#include -#endif -#include -#include - -/* This marks the start of a packed structure section. */ -#include - - -/* WiFi P2P OUI values */ -#define P2P_OUI WFA_OUI /* WiFi P2P OUI */ -#define P2P_VER WFA_OUI_TYPE_P2P /* P2P version: 9=WiFi P2P v1.0 */ - -#define P2P_IE_ID 0xdd /* P2P IE element ID */ - -/* WiFi P2P IE */ -BWL_PRE_PACKED_STRUCT struct wifi_p2p_ie { - uint8 id; /* IE ID: 0xDD */ - uint8 len; /* IE length */ - uint8 OUI[3]; /* WiFi P2P specific OUI: P2P_OUI */ - uint8 oui_type; /* Identifies P2P version: P2P_VER */ - uint8 subelts[1]; /* variable length subelements */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_ie wifi_p2p_ie_t; - -#define P2P_IE_FIXED_LEN 6 - -#define P2P_ATTR_ID_OFF 0 -#define P2P_ATTR_LEN_OFF 1 -#define P2P_ATTR_DATA_OFF 3 - -#define P2P_ATTR_HDR_LEN 3 /* ID + 2-byte length field spec 1.02 */ - -/* P2P IE Subelement IDs from WiFi P2P Technical Spec 1.00 */ -#define P2P_SEID_STATUS 0 /* Status */ -#define P2P_SEID_MINOR_RC 1 /* Minor Reason Code */ -#define P2P_SEID_P2P_INFO 2 /* P2P Capability (capabilities info) */ -#define P2P_SEID_DEV_ID 3 /* P2P Device ID */ -#define P2P_SEID_INTENT 4 /* Group Owner Intent */ -#define P2P_SEID_CFG_TIMEOUT 5 /* Configuration Timeout */ -#define P2P_SEID_CHANNEL 6 /* Channel */ -#define P2P_SEID_GRP_BSSID 7 /* P2P Group BSSID */ -#define P2P_SEID_XT_TIMING 8 /* Extended Listen Timing */ -#define P2P_SEID_INTINTADDR 9 /* Intended P2P Interface Address */ -#define P2P_SEID_P2P_MGBTY 10 /* P2P Manageability */ -#define P2P_SEID_CHAN_LIST 11 /* Channel List */ -#define P2P_SEID_ABSENCE 12 /* Notice of Absence */ -#define P2P_SEID_DEV_INFO 13 /* Device Info */ -#define P2P_SEID_GROUP_INFO 14 /* Group Info */ -#define P2P_SEID_GROUP_ID 15 /* Group ID */ -#define P2P_SEID_P2P_IF 16 /* P2P Interface */ -#define P2P_SEID_VNDR 221 /* Vendor-specific subelement */ - -#define P2P_SE_VS_ID_SERVICES 0x1b /* BRCM proprietary subel: L2 Services */ - - -/* WiFi P2P IE subelement: P2P Capability (capabilities info) */ -BWL_PRE_PACKED_STRUCT struct wifi_p2p_info_se_s { - uint8 eltId; /* SE ID: P2P_SEID_P2P_INFO */ - uint8 len[2]; /* SE length not including eltId, len fields */ - uint8 dev; /* Device Capability Bitmap */ - uint8 group; /* Group Capability Bitmap */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_info_se_s wifi_p2p_info_se_t; - -/* P2P Capability subelement's Device Capability Bitmap bit values */ -#define P2P_CAPSE_DEV_SERVICE_DIS 0x1 /* Service Discovery */ -#define P2P_CAPSE_DEV_CLIENT_DIS 0x2 /* Client Discoverability */ -#define P2P_CAPSE_DEV_CONCURRENT 0x4 /* Concurrent Operation */ -#define P2P_CAPSE_DEV_INFRA_MAN 0x8 /* P2P Infrastructure Managed */ -#define P2P_CAPSE_DEV_LIMIT 0x10 /* P2P Device Limit */ -#define P2P_CAPSE_INVITE_PROC 0x20 /* P2P Invitation Procedure */ - -/* P2P Capability subelement's Group Capability Bitmap bit values */ -#define P2P_CAPSE_GRP_OWNER 0x1 /* P2P Group Owner */ -#define P2P_CAPSE_PERSIST_GRP 0x2 /* Persistent P2P Group */ -#define P2P_CAPSE_GRP_LIMIT 0x4 /* P2P Group Limit */ -#define P2P_CAPSE_GRP_INTRA_BSS 0x8 /* Intra-BSS Distribution */ -#define P2P_CAPSE_GRP_X_CONNECT 0x10 /* Cross Connection */ -#define P2P_CAPSE_GRP_PERSISTENT 0x20 /* Persistent Reconnect */ -#define P2P_CAPSE_GRP_FORMATION 0x40 /* Group Formation */ - - -/* WiFi P2P IE subelement: Group Owner Intent */ -BWL_PRE_PACKED_STRUCT struct wifi_p2p_intent_se_s { - uint8 eltId; /* SE ID: P2P_SEID_INTENT */ - uint8 len[2]; /* SE length not including eltId, len fields */ - uint8 intent; /* Intent Value 0...15 (0=legacy 15=master only) */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_intent_se_s wifi_p2p_intent_se_t; - -/* WiFi P2P IE subelement: Configuration Timeout */ -BWL_PRE_PACKED_STRUCT struct wifi_p2p_cfg_tmo_se_s { - uint8 eltId; /* SE ID: P2P_SEID_CFG_TIMEOUT */ - uint8 len[2]; /* SE length not including eltId, len fields */ - uint8 go_tmo; /* GO config timeout in units of 10 ms */ - uint8 client_tmo; /* Client config timeout in units of 10 ms */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_cfg_tmo_se_s wifi_p2p_cfg_tmo_se_t; - - -/* WiFi P2P IE subelement: Status */ -BWL_PRE_PACKED_STRUCT struct wifi_p2p_status_se_s { - uint8 eltId; /* SE ID: P2P_SEID_STATUS */ - uint8 len[2]; /* SE length not including eltId, len fields */ - uint8 status; /* Status Code: P2P_STATSE_* */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_status_se_s wifi_p2p_status_se_t; - -/* Status subelement Status Code definitions */ -#define P2P_STATSE_SUCCESS 0 - /* Success */ -#define P2P_STATSE_FAIL_INFO_CURR_UNAVAIL 1 - /* Failed, information currently unavailable */ -#define P2P_STATSE_PASSED_UP P2P_STATSE_FAIL_INFO_CURR_UNAVAIL - /* Old name for above in P2P spec 1.08 and older */ -#define P2P_STATSE_FAIL_INCOMPAT_PARAMS 2 - /* Failed, incompatible parameters */ -#define P2P_STATSE_FAIL_LIMIT_REACHED 3 - /* Failed, limit reached */ -#define P2P_STATSE_FAIL_INVALID_PARAMS 4 - /* Failed, invalid parameters */ -#define P2P_STATSE_FAIL_UNABLE_TO_ACCOM 5 - /* Failed, unable to accomodate request */ -#define P2P_STATSE_FAIL_PROTO_ERROR 6 - /* Failed, previous protocol error or disruptive behaviour */ -#define P2P_STATSE_FAIL_NO_COMMON_CHAN 7 - /* Failed, no common channels */ -#define P2P_STATSE_FAIL_UNKNOWN_GROUP 8 - /* Failed, unknown P2P Group */ -#define P2P_STATSE_FAIL_INTENT 9 - /* Failed, both peers indicated Intent 15 in GO Negotiation */ -#define P2P_STATSE_FAIL_INCOMPAT_PROVIS 10 - /* Failed, incompatible provisioning method */ -#define P2P_STATSE_FAIL_USER_REJECT 11 - /* Failed, rejected by user */ - -/* WiFi P2P IE attribute: Extended Listen Timing */ -BWL_PRE_PACKED_STRUCT struct wifi_p2p_ext_se_s { - uint8 eltId; /* ID: P2P_SEID_EXT_TIMING */ - uint8 len[2]; /* length not including eltId, len fields */ - uint8 avail[2]; /* availibility period */ - uint8 interval[2]; /* availibility interval */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_ext_se_s wifi_p2p_ext_se_t; - -#define P2P_EXT_MIN 10 /* minimum 10ms */ - -/* WiFi P2P IE subelement: Intended P2P Interface Address */ -BWL_PRE_PACKED_STRUCT struct wifi_p2p_intintad_se_s { - uint8 eltId; /* SE ID: P2P_SEID_INTINTADDR */ - uint8 len[2]; /* SE length not including eltId, len fields */ - uint8 mac[6]; /* intended P2P interface MAC address */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_intintad_se_s wifi_p2p_intintad_se_t; - -/* WiFi P2P IE subelement: Channel */ -BWL_PRE_PACKED_STRUCT struct wifi_p2p_channel_se_s { - uint8 eltId; /* SE ID: P2P_SEID_STATUS */ - uint8 len[2]; /* SE length not including eltId, len fields */ - uint8 band; /* Regulatory Class (band) */ - uint8 channel; /* Channel */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_channel_se_s wifi_p2p_channel_se_t; - - -/* Channel Entry structure within the Channel List SE */ -BWL_PRE_PACKED_STRUCT struct wifi_p2p_chanlist_entry_s { - uint8 band; /* Regulatory Class (band) */ - uint8 num_channels; /* # of channels in the channel list */ - uint8 channels[WL_NUMCHANNELS]; /* Channel List */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_chanlist_entry_s wifi_p2p_chanlist_entry_t; -#define WIFI_P2P_CHANLIST_SE_MAX_ENTRIES 2 - -/* WiFi P2P IE subelement: Channel List */ -BWL_PRE_PACKED_STRUCT struct wifi_p2p_chanlist_se_s { - uint8 eltId; /* SE ID: P2P_SEID_STATUS */ - uint8 len[2]; /* SE length not including eltId, len fields */ - uint8 country[3]; /* Country String */ - uint8 num_entries; /* # of channel entries */ - wifi_p2p_chanlist_entry_t entries[WIFI_P2P_CHANLIST_SE_MAX_ENTRIES]; - /* Channel Entry List */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_chanlist_se_s wifi_p2p_chanlist_se_t; - -/* WiFi P2P IE's Device Info subelement */ -BWL_PRE_PACKED_STRUCT struct wifi_p2p_devinfo_se_s { - uint8 eltId; /* SE ID: P2P_SEID_DEVINFO */ - uint8 len[2]; /* SE length not including eltId, len fields */ - uint8 mac[6]; /* P2P Device MAC address */ - uint16 wps_cfg_meths; /* Config Methods: reg_prototlv.h WPS_CONFMET_* */ - uint8 pri_devtype[8]; /* Primary Device Type */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_devinfo_se_s wifi_p2p_devinfo_se_t; - -#define P2P_DEV_TYPE_LEN 8 - -/* WiFi P2P IE's Group Info subelement Client Info Descriptor */ -BWL_PRE_PACKED_STRUCT struct wifi_p2p_cid_fixed_s { - uint8 len; - uint8 devaddr[ETHER_ADDR_LEN]; /* P2P Device Address */ - uint8 ifaddr[ETHER_ADDR_LEN]; /* P2P Interface Address */ - uint8 devcap; /* Device Capability */ - uint8 cfg_meths[2]; /* Config Methods: reg_prototlv.h WPS_CONFMET_* */ - uint8 pridt[P2P_DEV_TYPE_LEN]; /* Primary Device Type */ - uint8 secdts; /* Number of Secondary Device Types */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_cid_fixed_s wifi_p2p_cid_fixed_t; - -/* WiFi P2P IE's Device ID subelement */ -BWL_PRE_PACKED_STRUCT struct wifi_p2p_devid_se_s { - uint8 eltId; - uint8 len[2]; - struct ether_addr addr; /* P2P Device MAC address */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_devid_se_s wifi_p2p_devid_se_t; - -/* WiFi P2P IE subelement: P2P Manageability */ -BWL_PRE_PACKED_STRUCT struct wifi_p2p_mgbt_se_s { - uint8 eltId; /* SE ID: P2P_SEID_P2P_MGBTY */ - uint8 len[2]; /* SE length not including eltId, len fields */ - uint8 mg_bitmap; /* manageability bitmap */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_mgbt_se_s wifi_p2p_mgbt_se_t; -/* mg_bitmap field bit values */ -#define P2P_MGBTSE_P2PDEVMGMT_FLAG 0x1 /* AP supports Managed P2P Device */ - -/* WiFi P2P IE subelement: Group Info */ -BWL_PRE_PACKED_STRUCT struct wifi_p2p_grpinfo_se_s { - uint8 eltId; /* SE ID: P2P_SEID_GROUP_INFO */ - uint8 len[2]; /* SE length not including eltId, len fields */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_grpinfo_se_s wifi_p2p_grpinfo_se_t; - - -/* WiFi P2P Action Frame */ -BWL_PRE_PACKED_STRUCT struct wifi_p2p_action_frame { - uint8 category; /* P2P_AF_CATEGORY */ - uint8 OUI[3]; /* OUI - P2P_OUI */ - uint8 type; /* OUI Type - P2P_VER */ - uint8 subtype; /* OUI Subtype - P2P_AF_* */ - uint8 dialog_token; /* nonzero, identifies req/resp tranaction */ - uint8 elts[1]; /* Variable length information elements. Max size = - * ACTION_FRAME_SIZE - sizeof(this structure) - 1 - */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_action_frame wifi_p2p_action_frame_t; -#define P2P_AF_CATEGORY 0x7f - -#define P2P_AF_FIXED_LEN 7 - -/* WiFi P2P Action Frame OUI Subtypes */ -#define P2P_AF_NOTICE_OF_ABSENCE 0 /* Notice of Absence */ -#define P2P_AF_PRESENCE_REQ 1 /* P2P Presence Request */ -#define P2P_AF_PRESENCE_RSP 2 /* P2P Presence Response */ -#define P2P_AF_GO_DISC_REQ 3 /* GO Discoverability Request */ - - -/* WiFi P2P Public Action Frame */ -BWL_PRE_PACKED_STRUCT struct wifi_p2p_pub_act_frame { - uint8 category; /* P2P_PUB_AF_CATEGORY */ - uint8 action; /* P2P_PUB_AF_ACTION */ - uint8 oui[3]; /* P2P_OUI */ - uint8 oui_type; /* OUI type - P2P_VER */ - uint8 subtype; /* OUI subtype - P2P_TYPE_* */ - uint8 dialog_token; /* nonzero, identifies req/rsp transaction */ - uint8 elts[1]; /* Variable length information elements. Max size = - * ACTION_FRAME_SIZE - sizeof(this structure) - 1 - */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_pub_act_frame wifi_p2p_pub_act_frame_t; -#define P2P_PUB_AF_FIXED_LEN 8 -#define P2P_PUB_AF_CATEGORY 0x04 -#define P2P_PUB_AF_ACTION 0x09 - -/* WiFi P2P Public Action Frame OUI Subtypes */ -#define P2P_PAF_GON_REQ 0 /* Group Owner Negotiation Req */ -#define P2P_PAF_GON_RSP 1 /* Group Owner Negotiation Rsp */ -#define P2P_PAF_GON_CONF 2 /* Group Owner Negotiation Confirm */ -#define P2P_PAF_INVITE_REQ 3 /* P2P Invitation Request */ -#define P2P_PAF_INVITE_RSP 4 /* P2P Invitation Response */ -#define P2P_PAF_DEVDIS_REQ 5 /* Device Discoverability Request */ -#define P2P_PAF_DEVDIS_RSP 6 /* Device Discoverability Response */ -#define P2P_PAF_PROVDIS_REQ 7 /* Provision Discovery Request */ -#define P2P_PAF_PROVDIS_RSP 8 /* Provision Discovery Request */ - -/* TODO: Stop using these obsolete aliases for P2P_PAF_GON_* */ -#define P2P_TYPE_MNREQ P2P_PAF_GON_REQ -#define P2P_TYPE_MNRSP P2P_PAF_GON_RSP -#define P2P_TYPE_MNCONF P2P_PAF_GON_CONF - -/* WiFi P2P IE subelement: Notice of Absence */ -BWL_PRE_PACKED_STRUCT struct wifi_p2p_noa_desc { - uint8 cnt_type; /* Count/Type */ - uint32 duration; /* Duration */ - uint32 interval; /* Interval */ - uint32 start; /* Start Time */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_noa_desc wifi_p2p_noa_desc_t; - -BWL_PRE_PACKED_STRUCT struct wifi_p2p_noa_se { - uint8 eltId; /* Subelement ID */ - uint8 len[2]; /* Length */ - uint8 index; /* Index */ - uint8 ops_ctw_parms; /* CTWindow and OppPS Parameters */ - wifi_p2p_noa_desc_t desc[1]; /* Notice of Absence Descriptor(s) */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2p_noa_se wifi_p2p_noa_se_t; - -#define P2P_NOA_SE_FIXED_LEN 5 - -/* cnt_type field values */ -#define P2P_NOA_DESC_CNT_RESERVED 0 /* reserved and should not be used */ -#define P2P_NOA_DESC_CNT_REPEAT 255 /* continuous schedule */ -#define P2P_NOA_DESC_TYPE_PREFERRED 1 /* preferred values */ -#define P2P_NOA_DESC_TYPE_ACCEPTABLE 2 /* acceptable limits */ - -/* ctw_ops_parms field values */ -#define P2P_NOA_CTW_MASK 0x7f -#define P2P_NOA_OPS_MASK 0x80 -#define P2P_NOA_OPS_SHIFT 7 - -#define P2P_CTW_MIN 10 /* minimum 10TU */ - -/* - * P2P Service Discovery related - */ -#define P2PSD_ACTION_CATEGORY 0x04 - /* Public action frame */ -#define P2PSD_ACTION_ID_GAS_IREQ 0x0a - /* Action value for GAS Initial Request AF */ -#define P2PSD_ACTION_ID_GAS_IRESP 0x0b - /* Action value for GAS Initial Response AF */ -#define P2PSD_ACTION_ID_GAS_CREQ 0x0c - /* Action value for GAS Comback Request AF */ -#define P2PSD_ACTION_ID_GAS_CRESP 0x0d - /* Action value for GAS Comback Response AF */ -#define P2PSD_AD_EID 0x6c - /* Advertisement Protocol IE ID */ -#define P2PSD_ADP_TUPLE_QLMT_PAMEBI 0x00 - /* Query Response Length Limit 7 bits plus PAME-BI 1 bit */ -#define P2PSD_ADP_PROTO_ID 0x00 - /* Advertisement Protocol ID. Always 0 for P2P SD */ -#define P2PSD_GAS_OUI P2P_OUI - /* WFA OUI */ -#define P2PSD_GAS_OUI_SUBTYPE P2P_VER - /* OUI Subtype for GAS IE */ -#define P2PSD_GAS_NQP_INFOID 0xDDDD - /* NQP Query Info ID: 56797 */ -#define P2PSD_GAS_COMEBACKDEALY 0x00 - /* Not used in the Native GAS protocol */ - -/* Service Protocol Type */ -typedef enum p2psd_svc_protype { - SVC_RPOTYPE_ALL = 0, - SVC_RPOTYPE_BONJOUR = 1, - SVC_RPOTYPE_UPNP = 2, - SVC_RPOTYPE_WSD = 3, - SVC_RPOTYPE_VENDOR = 255 -} p2psd_svc_protype_t; - -/* Service Discovery response status code */ -typedef enum { - P2PSD_RESP_STATUS_SUCCESS = 0, - P2PSD_RESP_STATUS_PROTYPE_NA = 1, - P2PSD_RESP_STATUS_DATA_NA = 2, - P2PSD_RESP_STATUS_BAD_REQUEST = 3 -} p2psd_resp_status_t; - -/* Advertisement Protocol IE tuple field */ -BWL_PRE_PACKED_STRUCT struct wifi_p2psd_adp_tpl { - uint8 llm_pamebi; /* Query Response Length Limit bit 0-6, set to 0 plus - * Pre-Associated Message Exchange BSSID Independent bit 7, set to 0 - */ - uint8 adp_id; /* Advertisement Protocol ID: 0 for NQP Native Query Protocol */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2psd_adp_tpl wifi_p2psd_adp_tpl_t; - -/* Advertisement Protocol IE */ -BWL_PRE_PACKED_STRUCT struct wifi_p2psd_adp_ie { - uint8 id; /* IE ID: 0x6c - 108 */ - uint8 len; /* IE length */ - wifi_p2psd_adp_tpl_t adp_tpl; /* Advertisement Protocol Tuple field. Only one - * tuple is defined for P2P Service Discovery - */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2psd_adp_ie wifi_p2psd_adp_ie_t; - -/* NQP Vendor-specific Content */ -BWL_PRE_PACKED_STRUCT struct wifi_p2psd_nqp_query_vsc { - uint8 oui_subtype; /* OUI Subtype: 0x09 */ - uint16 svc_updi; /* Service Update Indicator */ - uint8 svc_tlvs[1]; /* wifi_p2psd_qreq_tlv_t type for service request, - * wifi_p2psd_qresp_tlv_t type for service response - */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2psd_nqp_query_vsc wifi_p2psd_nqp_query_vsc_t; - -/* Service Request TLV */ -BWL_PRE_PACKED_STRUCT struct wifi_p2psd_qreq_tlv { - uint16 len; /* Length: 5 plus size of Query Data */ - uint8 svc_prot; /* Service Protocol Type */ - uint8 svc_tscid; /* Service Transaction ID */ - uint8 query_data[1]; /* Query Data, passed in from above Layer 2 */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2psd_qreq_tlv wifi_p2psd_qreq_tlv_t; - -/* Query Request Frame, defined in generic format, instead of NQP specific */ -BWL_PRE_PACKED_STRUCT struct wifi_p2psd_qreq_frame { - uint16 info_id; /* Info ID: 0xDDDD */ - uint16 len; /* Length of service request TLV, 5 plus the size of request data */ - uint8 oui[3]; /* WFA OUI: 0x0050F2 */ - uint8 qreq_vsc[1]; /* Vendor-specific Content: wifi_p2psd_nqp_query_vsc_t type for NQP */ - -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2psd_qreq_frame wifi_p2psd_qreq_frame_t; - -/* GAS Initial Request AF body, "elts" in wifi_p2p_pub_act_frame */ -BWL_PRE_PACKED_STRUCT struct wifi_p2psd_gas_ireq_frame { - wifi_p2psd_adp_ie_t adp_ie; /* Advertisement Protocol IE */ - uint16 qreq_len; /* Query Request Length */ - uint8 qreq_frm[1]; /* Query Request Frame wifi_p2psd_qreq_frame_t */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2psd_gas_ireq_frame wifi_p2psd_gas_ireq_frame_t; - -/* Service Response TLV */ -BWL_PRE_PACKED_STRUCT struct wifi_p2psd_qresp_tlv { - uint16 len; /* Length: 5 plus size of Query Data */ - uint8 svc_prot; /* Service Protocol Type */ - uint8 svc_tscid; /* Service Transaction ID */ - uint8 status; /* Value defined in Table 57 of P2P spec. */ - uint8 query_data[1]; /* Response Data, passed in from above Layer 2 */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2psd_qresp_tlv wifi_p2psd_qresp_tlv_t; - -/* Query Response Frame, defined in generic format, instead of NQP specific */ -BWL_PRE_PACKED_STRUCT struct wifi_p2psd_qresp_frame { - uint16 info_id; /* Info ID: 0xDDDD */ - uint16 len; /* Lenth of service response TLV, 6 plus the size of resp data */ - uint8 oui[3]; /* WFA OUI: 0x0050F2 */ - uint8 qresp_vsc[1]; /* Vendor-specific Content: wifi_p2psd_qresp_tlv_t type for NQP */ - -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2psd_qresp_frame wifi_p2psd_qresp_frame_t; - -/* GAS Initial Response AF body, "elts" in wifi_p2p_pub_act_frame */ -BWL_PRE_PACKED_STRUCT struct wifi_p2psd_gas_iresp_frame { - uint16 status; /* Value defined in Table 7-23 of IEEE P802.11u */ - uint16 cb_delay; /* GAS Comeback Delay */ - wifi_p2psd_adp_ie_t adp_ie; /* Advertisement Protocol IE */ - uint16 qresp_len; /* Query Response Length */ - uint8 qresp_frm[1]; /* Query Response Frame wifi_p2psd_qresp_frame_t */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2psd_gas_iresp_frame wifi_p2psd_gas_iresp_frame_t; - -/* GAS Comeback Response AF body, "elts" in wifi_p2p_pub_act_frame */ -BWL_PRE_PACKED_STRUCT struct wifi_p2psd_gas_cresp_frame { - uint16 status; /* Value defined in Table 7-23 of IEEE P802.11u */ - uint8 fragment_id; /* Fragmentation ID */ - uint16 cb_delay; /* GAS Comeback Delay */ - wifi_p2psd_adp_ie_t adp_ie; /* Advertisement Protocol IE */ - uint16 qresp_len; /* Query Response Length */ - uint8 qresp_frm[1]; /* Query Response Frame wifi_p2psd_qresp_frame_t */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2psd_gas_cresp_frame wifi_p2psd_gas_cresp_frame_t; - -/* Wi-Fi GAS Public Action Frame */ -BWL_PRE_PACKED_STRUCT struct wifi_p2psd_gas_pub_act_frame { - uint8 category; /* 0x04 Public Action Frame */ - uint8 action; /* 0x6c Advertisement Protocol */ - uint8 dialog_token; /* nonzero, identifies req/rsp transaction */ - uint8 query_data[1]; /* Query Data. wifi_p2psd_gas_ireq_frame_t - * or wifi_p2psd_gas_iresp_frame_t format - */ -} BWL_POST_PACKED_STRUCT; -typedef struct wifi_p2psd_gas_pub_act_frame wifi_p2psd_gas_pub_act_frame_t; - -/* This marks the end of a packed structure section. */ -#include - -#endif /* _P2P_H_ */ diff --git a/drivers/net/wireless/bcmdhd/include/proto/sdspi.h b/drivers/net/wireless/bcmdhd/include/proto/sdspi.h deleted file mode 100644 index 7353ff0d7c73..000000000000 --- a/drivers/net/wireless/bcmdhd/include/proto/sdspi.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * SD-SPI Protocol Standard - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sdspi.h 277737 2011-08-16 17:54:59Z $ - */ - -#ifndef _SD_SPI_H -#define _SD_SPI_H - -#define SPI_START_M BITFIELD_MASK(1) /* Bit [31] - Start Bit */ -#define SPI_START_S 31 -#define SPI_DIR_M BITFIELD_MASK(1) /* Bit [30] - Direction */ -#define SPI_DIR_S 30 -#define SPI_CMD_INDEX_M BITFIELD_MASK(6) /* Bits [29:24] - Command number */ -#define SPI_CMD_INDEX_S 24 -#define SPI_RW_M BITFIELD_MASK(1) /* Bit [23] - Read=0, Write=1 */ -#define SPI_RW_S 23 -#define SPI_FUNC_M BITFIELD_MASK(3) /* Bits [22:20] - Function Number */ -#define SPI_FUNC_S 20 -#define SPI_RAW_M BITFIELD_MASK(1) /* Bit [19] - Read After Wr */ -#define SPI_RAW_S 19 -#define SPI_STUFF_M BITFIELD_MASK(1) /* Bit [18] - Stuff bit */ -#define SPI_STUFF_S 18 -#define SPI_BLKMODE_M BITFIELD_MASK(1) /* Bit [19] - Blockmode 1=blk */ -#define SPI_BLKMODE_S 19 -#define SPI_OPCODE_M BITFIELD_MASK(1) /* Bit [18] - OP Code */ -#define SPI_OPCODE_S 18 -#define SPI_ADDR_M BITFIELD_MASK(17) /* Bits [17:1] - Address */ -#define SPI_ADDR_S 1 -#define SPI_STUFF0_M BITFIELD_MASK(1) /* Bit [0] - Stuff bit */ -#define SPI_STUFF0_S 0 - -#define SPI_RSP_START_M BITFIELD_MASK(1) /* Bit [7] - Start Bit (always 0) */ -#define SPI_RSP_START_S 7 -#define SPI_RSP_PARAM_ERR_M BITFIELD_MASK(1) /* Bit [6] - Parameter Error */ -#define SPI_RSP_PARAM_ERR_S 6 -#define SPI_RSP_RFU5_M BITFIELD_MASK(1) /* Bit [5] - RFU (Always 0) */ -#define SPI_RSP_RFU5_S 5 -#define SPI_RSP_FUNC_ERR_M BITFIELD_MASK(1) /* Bit [4] - Function number error */ -#define SPI_RSP_FUNC_ERR_S 4 -#define SPI_RSP_CRC_ERR_M BITFIELD_MASK(1) /* Bit [3] - COM CRC Error */ -#define SPI_RSP_CRC_ERR_S 3 -#define SPI_RSP_ILL_CMD_M BITFIELD_MASK(1) /* Bit [2] - Illegal Command error */ -#define SPI_RSP_ILL_CMD_S 2 -#define SPI_RSP_RFU1_M BITFIELD_MASK(1) /* Bit [1] - RFU (Always 0) */ -#define SPI_RSP_RFU1_S 1 -#define SPI_RSP_IDLE_M BITFIELD_MASK(1) /* Bit [0] - In idle state */ -#define SPI_RSP_IDLE_S 0 - -/* SD-SPI Protocol Definitions */ -#define SDSPI_COMMAND_LEN 6 /* Number of bytes in an SD command */ -#define SDSPI_START_BLOCK 0xFE /* SD Start Block Token */ -#define SDSPI_IDLE_PAD 0xFF /* SD-SPI idle value for MOSI */ -#define SDSPI_START_BIT_MASK 0x80 - -#endif /* _SD_SPI_H */ diff --git a/drivers/net/wireless/bcmdhd/include/proto/vlan.h b/drivers/net/wireless/bcmdhd/include/proto/vlan.h deleted file mode 100644 index 27f005537604..000000000000 --- a/drivers/net/wireless/bcmdhd/include/proto/vlan.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 802.1Q VLAN protocol definitions - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: vlan.h 277737 2011-08-16 17:54:59Z $ - */ - - -#ifndef _vlan_h_ -#define _vlan_h_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - - -#include - -#define VLAN_VID_MASK 0xfff -#define VLAN_CFI_SHIFT 12 -#define VLAN_PRI_SHIFT 13 - -#define VLAN_PRI_MASK 7 - -#define VLAN_TAG_LEN 4 -#define VLAN_TAG_OFFSET (2 * ETHER_ADDR_LEN) - -#define VLAN_TPID 0x8100 - -struct ethervlan_header { - uint8 ether_dhost[ETHER_ADDR_LEN]; - uint8 ether_shost[ETHER_ADDR_LEN]; - uint16 vlan_type; - uint16 vlan_tag; - uint16 ether_type; -}; - -#define ETHERVLAN_HDR_LEN (ETHER_HDR_LEN + VLAN_TAG_LEN) - - - -#include - -#define ETHERVLAN_MOVE_HDR(d, s) \ -do { \ - struct ethervlan_header t; \ - t = *(struct ethervlan_header *)(s); \ - *(struct ethervlan_header *)(d) = t; \ -} while (0) - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/proto/wpa.h b/drivers/net/wireless/bcmdhd/include/proto/wpa.h deleted file mode 100644 index 7361cbf20b06..000000000000 --- a/drivers/net/wireless/bcmdhd/include/proto/wpa.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Fundamental types and constants relating to WPA - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wpa.h 285437 2011-09-21 22:16:56Z $ - */ - - -#ifndef _proto_wpa_h_ -#define _proto_wpa_h_ - -#include -#include - - - -#include - - - - -#define DOT11_RC_INVALID_WPA_IE 13 -#define DOT11_RC_MIC_FAILURE 14 -#define DOT11_RC_4WH_TIMEOUT 15 -#define DOT11_RC_GTK_UPDATE_TIMEOUT 16 -#define DOT11_RC_WPA_IE_MISMATCH 17 -#define DOT11_RC_INVALID_MC_CIPHER 18 -#define DOT11_RC_INVALID_UC_CIPHER 19 -#define DOT11_RC_INVALID_AKMP 20 -#define DOT11_RC_BAD_WPA_VERSION 21 -#define DOT11_RC_INVALID_WPA_CAP 22 -#define DOT11_RC_8021X_AUTH_FAIL 23 - -#define WPA2_PMKID_LEN 16 - - -typedef BWL_PRE_PACKED_STRUCT struct -{ - uint8 tag; - uint8 length; - uint8 oui[3]; - uint8 oui_type; - BWL_PRE_PACKED_STRUCT struct { - uint8 low; - uint8 high; - } BWL_POST_PACKED_STRUCT version; -} BWL_POST_PACKED_STRUCT wpa_ie_fixed_t; -#define WPA_IE_OUITYPE_LEN 4 -#define WPA_IE_FIXED_LEN 8 -#define WPA_IE_TAG_FIXED_LEN 6 - -typedef BWL_PRE_PACKED_STRUCT struct { - uint8 tag; - uint8 length; - BWL_PRE_PACKED_STRUCT struct { - uint8 low; - uint8 high; - } BWL_POST_PACKED_STRUCT version; -} BWL_POST_PACKED_STRUCT wpa_rsn_ie_fixed_t; -#define WPA_RSN_IE_FIXED_LEN 4 -#define WPA_RSN_IE_TAG_FIXED_LEN 2 -typedef uint8 wpa_pmkid_t[WPA2_PMKID_LEN]; - - -typedef BWL_PRE_PACKED_STRUCT struct -{ - uint8 oui[3]; - uint8 type; -} BWL_POST_PACKED_STRUCT wpa_suite_t, wpa_suite_mcast_t; -#define WPA_SUITE_LEN 4 - - -typedef BWL_PRE_PACKED_STRUCT struct -{ - BWL_PRE_PACKED_STRUCT struct { - uint8 low; - uint8 high; - } BWL_POST_PACKED_STRUCT count; - wpa_suite_t list[1]; -} BWL_POST_PACKED_STRUCT wpa_suite_ucast_t, wpa_suite_auth_key_mgmt_t; -#define WPA_IE_SUITE_COUNT_LEN 2 -typedef BWL_PRE_PACKED_STRUCT struct -{ - BWL_PRE_PACKED_STRUCT struct { - uint8 low; - uint8 high; - } BWL_POST_PACKED_STRUCT count; - wpa_pmkid_t list[1]; -} BWL_POST_PACKED_STRUCT wpa_pmkid_list_t; - - -#define WPA_CIPHER_NONE 0 -#define WPA_CIPHER_WEP_40 1 -#define WPA_CIPHER_TKIP 2 -#define WPA_CIPHER_AES_OCB 3 -#define WPA_CIPHER_AES_CCM 4 -#define WPA_CIPHER_WEP_104 5 -#define WPA_CIPHER_BIP 6 -#define WPA_CIPHER_TPK 7 - - -#define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \ - (cipher) == WPA_CIPHER_WEP_40 || \ - (cipher) == WPA_CIPHER_WEP_104 || \ - (cipher) == WPA_CIPHER_TKIP || \ - (cipher) == WPA_CIPHER_AES_OCB || \ - (cipher) == WPA_CIPHER_AES_CCM || \ - (cipher) == WPA_CIPHER_TPK) - - - -#define WPA_TKIP_CM_DETECT 60 -#define WPA_TKIP_CM_BLOCK 60 - - -#define RSN_CAP_LEN 2 - - -#define RSN_CAP_PREAUTH 0x0001 -#define RSN_CAP_NOPAIRWISE 0x0002 -#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C -#define RSN_CAP_PTK_REPLAY_CNTR_SHIFT 2 -#define RSN_CAP_GTK_REPLAY_CNTR_MASK 0x0030 -#define RSN_CAP_GTK_REPLAY_CNTR_SHIFT 4 -#define RSN_CAP_1_REPLAY_CNTR 0 -#define RSN_CAP_2_REPLAY_CNTRS 1 -#define RSN_CAP_4_REPLAY_CNTRS 2 -#define RSN_CAP_16_REPLAY_CNTRS 3 - - -#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS -#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS -#define WPA_CAP_REPLAY_CNTR_SHIFT RSN_CAP_PTK_REPLAY_CNTR_SHIFT -#define WPA_CAP_REPLAY_CNTR_MASK RSN_CAP_PTK_REPLAY_CNTR_MASK - - -#define WPA_CAP_PEER_KEY_ENABLE (0x1 << 1) - - -#define WPA_CAP_LEN RSN_CAP_LEN -#define WPA_PMKID_CNT_LEN 2 - -#define WPA_CAP_WPA2_PREAUTH RSN_CAP_PREAUTH - - - -#include - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/sbchipc.h b/drivers/net/wireless/bcmdhd/include/sbchipc.h deleted file mode 100644 index 78ced30c502b..000000000000 --- a/drivers/net/wireless/bcmdhd/include/sbchipc.h +++ /dev/null @@ -1,1783 +0,0 @@ -/* - * SiliconBackplane Chipcommon core hardware definitions. - * - * The chipcommon core provides chip identification, SB control, - * JTAG, 0/1/2 UARTs, clock frequency control, a watchdog interrupt timer, - * GPIO interface, extbus, and support for serial and parallel flashes. - * - * $Id: sbchipc.h 343982 2012-07-11 00:29:37Z $ - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - */ - - -#ifndef _SBCHIPC_H -#define _SBCHIPC_H - -#ifndef _LANGUAGE_ASSEMBLY - - -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif - -typedef struct eci_prerev35 { - uint32 eci_output; - uint32 eci_control; - uint32 eci_inputlo; - uint32 eci_inputmi; - uint32 eci_inputhi; - uint32 eci_inputintpolaritylo; - uint32 eci_inputintpolaritymi; - uint32 eci_inputintpolarityhi; - uint32 eci_intmasklo; - uint32 eci_intmaskmi; - uint32 eci_intmaskhi; - uint32 eci_eventlo; - uint32 eci_eventmi; - uint32 eci_eventhi; - uint32 eci_eventmasklo; - uint32 eci_eventmaskmi; - uint32 eci_eventmaskhi; - uint32 PAD[3]; -} eci_prerev35_t; - -typedef struct eci_rev35 { - uint32 eci_outputlo; - uint32 eci_outputhi; - uint32 eci_controllo; - uint32 eci_controlhi; - uint32 eci_inputlo; - uint32 eci_inputhi; - uint32 eci_inputintpolaritylo; - uint32 eci_inputintpolarityhi; - uint32 eci_intmasklo; - uint32 eci_intmaskhi; - uint32 eci_eventlo; - uint32 eci_eventhi; - uint32 eci_eventmasklo; - uint32 eci_eventmaskhi; - uint32 eci_auxtx; - uint32 eci_auxrx; - uint32 eci_datatag; - uint32 eci_uartescvalue; - uint32 eci_autobaudctr; - uint32 eci_uartfifolevel; -} eci_rev35_t; - -typedef volatile struct { - uint32 chipid; - uint32 capabilities; - uint32 corecontrol; - uint32 bist; - - - uint32 otpstatus; - uint32 otpcontrol; - uint32 otpprog; - uint32 otplayout; - - - uint32 intstatus; - uint32 intmask; - - - uint32 chipcontrol; - uint32 chipstatus; - - - uint32 jtagcmd; - uint32 jtagir; - uint32 jtagdr; - uint32 jtagctrl; - - - uint32 flashcontrol; - uint32 flashaddress; - uint32 flashdata; - uint32 PAD[1]; - - - uint32 broadcastaddress; - uint32 broadcastdata; - - - uint32 gpiopullup; - uint32 gpiopulldown; - uint32 gpioin; - uint32 gpioout; - uint32 gpioouten; - uint32 gpiocontrol; - uint32 gpiointpolarity; - uint32 gpiointmask; - - - uint32 gpioevent; - uint32 gpioeventintmask; - - - uint32 watchdog; - - - uint32 gpioeventintpolarity; - - - uint32 gpiotimerval; - uint32 gpiotimeroutmask; - - - uint32 clockcontrol_n; - uint32 clockcontrol_sb; - uint32 clockcontrol_pci; - uint32 clockcontrol_m2; - uint32 clockcontrol_m3; - uint32 clkdiv; - uint32 gpiodebugsel; - uint32 capabilities_ext; - - - uint32 pll_on_delay; - uint32 fref_sel_delay; - uint32 slow_clk_ctl; - uint32 PAD; - - - uint32 system_clk_ctl; - uint32 clkstatestretch; - uint32 PAD[2]; - - - uint32 bp_addrlow; - uint32 bp_addrhigh; - uint32 bp_data; - uint32 PAD; - uint32 bp_indaccess; - - uint32 gsioctrl; - uint32 gsioaddress; - uint32 gsiodata; - - - uint32 clkdiv2; - uint32 PAD[2]; - - - uint32 eromptr; - - - uint32 pcmcia_config; - uint32 pcmcia_memwait; - uint32 pcmcia_attrwait; - uint32 pcmcia_iowait; - uint32 ide_config; - uint32 ide_memwait; - uint32 ide_attrwait; - uint32 ide_iowait; - uint32 prog_config; - uint32 prog_waitcount; - uint32 flash_config; - uint32 flash_waitcount; - uint32 SECI_config; - uint32 SECI_status; - uint32 SECI_statusmask; - uint32 SECI_rxnibchanged; - - uint32 PAD[20]; - - - uint32 sromcontrol; - uint32 sromaddress; - uint32 sromdata; - uint32 PAD[9]; - uint32 seci_uart_data; - uint32 seci_uart_bauddiv; - uint32 seci_uart_fcr; - uint32 seci_uart_lcr; - uint32 seci_uart_mcr; - uint32 seci_uart_lsr; - uint32 seci_uart_msr; - uint32 seci_uart_baudadj; - - uint32 clk_ctl_st; - uint32 hw_war; - uint32 PAD[70]; - - - uint8 uart0data; - uint8 uart0imr; - uint8 uart0fcr; - uint8 uart0lcr; - uint8 uart0mcr; - uint8 uart0lsr; - uint8 uart0msr; - uint8 uart0scratch; - uint8 PAD[248]; - - uint8 uart1data; - uint8 uart1imr; - uint8 uart1fcr; - uint8 uart1lcr; - uint8 uart1mcr; - uint8 uart1lsr; - uint8 uart1msr; - uint8 uart1scratch; - uint32 PAD[126]; - - - - uint32 pmucontrol; - uint32 pmucapabilities; - uint32 pmustatus; - uint32 res_state; - uint32 res_pending; - uint32 pmutimer; - uint32 min_res_mask; - uint32 max_res_mask; - uint32 res_table_sel; - uint32 res_dep_mask; - uint32 res_updn_timer; - uint32 res_timer; - uint32 clkstretch; - uint32 pmuwatchdog; - uint32 gpiosel; - uint32 gpioenable; - uint32 res_req_timer_sel; - uint32 res_req_timer; - uint32 res_req_mask; - uint32 PAD; - uint32 chipcontrol_addr; - uint32 chipcontrol_data; - uint32 regcontrol_addr; - uint32 regcontrol_data; - uint32 pllcontrol_addr; - uint32 pllcontrol_data; - uint32 pmustrapopt; - uint32 pmu_xtalfreq; - uint32 PAD[100]; - uint16 sromotp[768]; -} chipcregs_t; - -#endif - - -#define CC_CHIPID 0 -#define CC_CAPABILITIES 4 -#define CC_CHIPST 0x2c -#define CC_EROMPTR 0xfc - - -#define CC_OTPST 0x10 -#define CC_JTAGCMD 0x30 -#define CC_JTAGIR 0x34 -#define CC_JTAGDR 0x38 -#define CC_JTAGCTRL 0x3c -#define CC_GPIOPU 0x58 -#define CC_GPIOPD 0x5c -#define CC_GPIOIN 0x60 -#define CC_GPIOOUT 0x64 -#define CC_GPIOOUTEN 0x68 -#define CC_GPIOCTRL 0x6c -#define CC_GPIOPOL 0x70 -#define CC_GPIOINTM 0x74 -#define CC_WATCHDOG 0x80 -#define CC_CLKC_N 0x90 -#define CC_CLKC_M0 0x94 -#define CC_CLKC_M1 0x98 -#define CC_CLKC_M2 0x9c -#define CC_CLKC_M3 0xa0 -#define CC_CLKDIV 0xa4 -#define CC_SYS_CLK_CTL 0xc0 -#define CC_CLK_CTL_ST SI_CLK_CTL_ST -#define PMU_CTL 0x600 -#define PMU_CAP 0x604 -#define PMU_ST 0x608 -#define PMU_RES_STATE 0x60c -#define PMU_TIMER 0x614 -#define PMU_MIN_RES_MASK 0x618 -#define PMU_MAX_RES_MASK 0x61c -#define CC_CHIPCTL_ADDR 0x650 -#define CC_CHIPCTL_DATA 0x654 -#define PMU_REG_CONTROL_ADDR 0x658 -#define PMU_REG_CONTROL_DATA 0x65C -#define PMU_PLL_CONTROL_ADDR 0x660 -#define PMU_PLL_CONTROL_DATA 0x664 -#define CC_SROM_OTP 0x800 - - -#define CID_ID_MASK 0x0000ffff -#define CID_REV_MASK 0x000f0000 -#define CID_REV_SHIFT 16 -#define CID_PKG_MASK 0x00f00000 -#define CID_PKG_SHIFT 20 -#define CID_CC_MASK 0x0f000000 -#define CID_CC_SHIFT 24 -#define CID_TYPE_MASK 0xf0000000 -#define CID_TYPE_SHIFT 28 - - -#define CC_CAP_UARTS_MASK 0x00000003 -#define CC_CAP_MIPSEB 0x00000004 -#define CC_CAP_UCLKSEL 0x00000018 -#define CC_CAP_UINTCLK 0x00000008 -#define CC_CAP_UARTGPIO 0x00000020 -#define CC_CAP_EXTBUS_MASK 0x000000c0 -#define CC_CAP_EXTBUS_NONE 0x00000000 -#define CC_CAP_EXTBUS_FULL 0x00000040 -#define CC_CAP_EXTBUS_PROG 0x00000080 -#define CC_CAP_FLASH_MASK 0x00000700 -#define CC_CAP_PLL_MASK 0x00038000 -#define CC_CAP_PWR_CTL 0x00040000 -#define CC_CAP_OTPSIZE 0x00380000 -#define CC_CAP_OTPSIZE_SHIFT 19 -#define CC_CAP_OTPSIZE_BASE 5 -#define CC_CAP_JTAGP 0x00400000 -#define CC_CAP_ROM 0x00800000 -#define CC_CAP_BKPLN64 0x08000000 -#define CC_CAP_PMU 0x10000000 -#define CC_CAP_ECI 0x20000000 -#define CC_CAP_SROM 0x40000000 -#define CC_CAP_NFLASH 0x80000000 - -#define CC_CAP2_SECI 0x00000001 -#define CC_CAP2_GSIO 0x00000002 - - -#define CC_CAP_EXT_SECI_PRESENT 0x00000001 - - -#define PLL_NONE 0x00000000 -#define PLL_TYPE1 0x00010000 -#define PLL_TYPE2 0x00020000 -#define PLL_TYPE3 0x00030000 -#define PLL_TYPE4 0x00008000 -#define PLL_TYPE5 0x00018000 -#define PLL_TYPE6 0x00028000 -#define PLL_TYPE7 0x00038000 - - -#define ILP_CLOCK 32000 - - -#define ALP_CLOCK 20000000 - - -#define HT_CLOCK 80000000 - - -#define CC_UARTCLKO 0x00000001 -#define CC_SE 0x00000002 -#define CC_ASYNCGPIO 0x00000004 -#define CC_UARTCLKEN 0x00000008 - - -#define CHIPCTRL_4321A0_DEFAULT 0x3a4 -#define CHIPCTRL_4321A1_DEFAULT 0x0a4 -#define CHIPCTRL_4321_PLL_DOWN 0x800000 - - -#define OTPS_OL_MASK 0x000000ff -#define OTPS_OL_MFG 0x00000001 -#define OTPS_OL_OR1 0x00000002 -#define OTPS_OL_OR2 0x00000004 -#define OTPS_OL_GU 0x00000008 -#define OTPS_GUP_MASK 0x00000f00 -#define OTPS_GUP_SHIFT 8 -#define OTPS_GUP_HW 0x00000100 -#define OTPS_GUP_SW 0x00000200 -#define OTPS_GUP_CI 0x00000400 -#define OTPS_GUP_FUSE 0x00000800 -#define OTPS_READY 0x00001000 -#define OTPS_RV(x) (1 << (16 + (x))) -#define OTPS_RV_MASK 0x0fff0000 - - -#define OTPC_PROGSEL 0x00000001 -#define OTPC_PCOUNT_MASK 0x0000000e -#define OTPC_PCOUNT_SHIFT 1 -#define OTPC_VSEL_MASK 0x000000f0 -#define OTPC_VSEL_SHIFT 4 -#define OTPC_TMM_MASK 0x00000700 -#define OTPC_TMM_SHIFT 8 -#define OTPC_ODM 0x00000800 -#define OTPC_PROGEN 0x80000000 - - -#define OTPP_COL_MASK 0x000000ff -#define OTPP_COL_SHIFT 0 -#define OTPP_ROW_MASK 0x0000ff00 -#define OTPP_ROW_SHIFT 8 -#define OTPP_OC_MASK 0x0f000000 -#define OTPP_OC_SHIFT 24 -#define OTPP_READERR 0x10000000 -#define OTPP_VALUE_MASK 0x20000000 -#define OTPP_VALUE_SHIFT 29 -#define OTPP_START_BUSY 0x80000000 -#define OTPP_READ 0x40000000 - - -#define OTP_CISFORMAT_NEW 0x80000000 - - -#define OTPPOC_READ 0 -#define OTPPOC_BIT_PROG 1 -#define OTPPOC_VERIFY 3 -#define OTPPOC_INIT 4 -#define OTPPOC_SET 5 -#define OTPPOC_RESET 6 -#define OTPPOC_OCST 7 -#define OTPPOC_ROW_LOCK 8 -#define OTPPOC_PRESCN_TEST 9 - - - -#define JTAGM_CREV_OLD 10 -#define JTAGM_CREV_IRP 22 -#define JTAGM_CREV_RTI 28 - - -#define JCMD_START 0x80000000 -#define JCMD_BUSY 0x80000000 -#define JCMD_STATE_MASK 0x60000000 -#define JCMD_STATE_TLR 0x00000000 -#define JCMD_STATE_PIR 0x20000000 -#define JCMD_STATE_PDR 0x40000000 -#define JCMD_STATE_RTI 0x60000000 -#define JCMD0_ACC_MASK 0x0000f000 -#define JCMD0_ACC_IRDR 0x00000000 -#define JCMD0_ACC_DR 0x00001000 -#define JCMD0_ACC_IR 0x00002000 -#define JCMD0_ACC_RESET 0x00003000 -#define JCMD0_ACC_IRPDR 0x00004000 -#define JCMD0_ACC_PDR 0x00005000 -#define JCMD0_IRW_MASK 0x00000f00 -#define JCMD_ACC_MASK 0x000f0000 -#define JCMD_ACC_IRDR 0x00000000 -#define JCMD_ACC_DR 0x00010000 -#define JCMD_ACC_IR 0x00020000 -#define JCMD_ACC_RESET 0x00030000 -#define JCMD_ACC_IRPDR 0x00040000 -#define JCMD_ACC_PDR 0x00050000 -#define JCMD_ACC_PIR 0x00060000 -#define JCMD_ACC_IRDR_I 0x00070000 -#define JCMD_ACC_DR_I 0x00080000 -#define JCMD_IRW_MASK 0x00001f00 -#define JCMD_IRW_SHIFT 8 -#define JCMD_DRW_MASK 0x0000003f - - -#define JCTRL_FORCE_CLK 4 -#define JCTRL_EXT_EN 2 -#define JCTRL_EN 1 - - -#define CLKD_SFLASH 0x0f000000 -#define CLKD_SFLASH_SHIFT 24 -#define CLKD_OTP 0x000f0000 -#define CLKD_OTP_SHIFT 16 -#define CLKD_JTAG 0x00000f00 -#define CLKD_JTAG_SHIFT 8 -#define CLKD_UART 0x000000ff - -#define CLKD2_SROM 0x00000003 - - -#define CI_GPIO 0x00000001 -#define CI_EI 0x00000002 -#define CI_TEMP 0x00000004 -#define CI_SIRQ 0x00000008 -#define CI_ECI 0x00000010 -#define CI_PMU 0x00000020 -#define CI_UART 0x00000040 -#define CI_WDRESET 0x80000000 - - -#define SCC_SS_MASK 0x00000007 -#define SCC_SS_LPO 0x00000000 -#define SCC_SS_XTAL 0x00000001 -#define SCC_SS_PCI 0x00000002 -#define SCC_LF 0x00000200 -#define SCC_LP 0x00000400 -#define SCC_FS 0x00000800 -#define SCC_IP 0x00001000 -#define SCC_XC 0x00002000 -#define SCC_XP 0x00004000 -#define SCC_CD_MASK 0xffff0000 -#define SCC_CD_SHIFT 16 - - -#define SYCC_IE 0x00000001 -#define SYCC_AE 0x00000002 -#define SYCC_FP 0x00000004 -#define SYCC_AR 0x00000008 -#define SYCC_HR 0x00000010 -#define SYCC_CD_MASK 0xffff0000 -#define SYCC_CD_SHIFT 16 - - -#define BPIA_BYTEEN 0x0000000f -#define BPIA_SZ1 0x00000001 -#define BPIA_SZ2 0x00000003 -#define BPIA_SZ4 0x00000007 -#define BPIA_SZ8 0x0000000f -#define BPIA_WRITE 0x00000100 -#define BPIA_START 0x00000200 -#define BPIA_BUSY 0x00000200 -#define BPIA_ERROR 0x00000400 - - -#define CF_EN 0x00000001 -#define CF_EM_MASK 0x0000000e -#define CF_EM_SHIFT 1 -#define CF_EM_FLASH 0 -#define CF_EM_SYNC 2 -#define CF_EM_PCMCIA 4 -#define CF_DS 0x00000010 -#define CF_BS 0x00000020 -#define CF_CD_MASK 0x000000c0 -#define CF_CD_SHIFT 6 -#define CF_CD_DIV2 0x00000000 -#define CF_CD_DIV3 0x00000040 -#define CF_CD_DIV4 0x00000080 -#define CF_CE 0x00000100 -#define CF_SB 0x00000200 - - -#define PM_W0_MASK 0x0000003f -#define PM_W1_MASK 0x00001f00 -#define PM_W1_SHIFT 8 -#define PM_W2_MASK 0x001f0000 -#define PM_W2_SHIFT 16 -#define PM_W3_MASK 0x1f000000 -#define PM_W3_SHIFT 24 - - -#define PA_W0_MASK 0x0000003f -#define PA_W1_MASK 0x00001f00 -#define PA_W1_SHIFT 8 -#define PA_W2_MASK 0x001f0000 -#define PA_W2_SHIFT 16 -#define PA_W3_MASK 0x1f000000 -#define PA_W3_SHIFT 24 - - -#define PI_W0_MASK 0x0000003f -#define PI_W1_MASK 0x00001f00 -#define PI_W1_SHIFT 8 -#define PI_W2_MASK 0x001f0000 -#define PI_W2_SHIFT 16 -#define PI_W3_MASK 0x1f000000 -#define PI_W3_SHIFT 24 - - -#define PW_W0_MASK 0x0000001f -#define PW_W1_MASK 0x00001f00 -#define PW_W1_SHIFT 8 -#define PW_W2_MASK 0x001f0000 -#define PW_W2_SHIFT 16 -#define PW_W3_MASK 0x1f000000 -#define PW_W3_SHIFT 24 - -#define PW_W0 0x0000000c -#define PW_W1 0x00000a00 -#define PW_W2 0x00020000 -#define PW_W3 0x01000000 - - -#define FW_W0_MASK 0x0000003f -#define FW_W1_MASK 0x00001f00 -#define FW_W1_SHIFT 8 -#define FW_W2_MASK 0x001f0000 -#define FW_W2_SHIFT 16 -#define FW_W3_MASK 0x1f000000 -#define FW_W3_SHIFT 24 - - -#define SRC_START 0x80000000 -#define SRC_BUSY 0x80000000 -#define SRC_OPCODE 0x60000000 -#define SRC_OP_READ 0x00000000 -#define SRC_OP_WRITE 0x20000000 -#define SRC_OP_WRDIS 0x40000000 -#define SRC_OP_WREN 0x60000000 -#define SRC_OTPSEL 0x00000010 -#define SRC_LOCK 0x00000008 -#define SRC_SIZE_MASK 0x00000006 -#define SRC_SIZE_1K 0x00000000 -#define SRC_SIZE_4K 0x00000002 -#define SRC_SIZE_16K 0x00000004 -#define SRC_SIZE_SHIFT 1 -#define SRC_PRESENT 0x00000001 - - -#define PCTL_ILP_DIV_MASK 0xffff0000 -#define PCTL_ILP_DIV_SHIFT 16 -#define PCTL_PLL_PLLCTL_UPD 0x00000400 -#define PCTL_NOILP_ON_WAIT 0x00000200 -#define PCTL_HT_REQ_EN 0x00000100 -#define PCTL_ALP_REQ_EN 0x00000080 -#define PCTL_XTALFREQ_MASK 0x0000007c -#define PCTL_XTALFREQ_SHIFT 2 -#define PCTL_ILP_DIV_EN 0x00000002 -#define PCTL_LPO_SEL 0x00000001 - - -#define CSTRETCH_HT 0xffff0000 -#define CSTRETCH_ALP 0x0000ffff - - -#define GPIO_ONTIME_SHIFT 16 - - -#define CN_N1_MASK 0x3f -#define CN_N2_MASK 0x3f00 -#define CN_N2_SHIFT 8 -#define CN_PLLC_MASK 0xf0000 -#define CN_PLLC_SHIFT 16 - - -#define CC_M1_MASK 0x3f -#define CC_M2_MASK 0x3f00 -#define CC_M2_SHIFT 8 -#define CC_M3_MASK 0x3f0000 -#define CC_M3_SHIFT 16 -#define CC_MC_MASK 0x1f000000 -#define CC_MC_SHIFT 24 - - -#define CC_F6_2 0x02 -#define CC_F6_3 0x03 -#define CC_F6_4 0x05 -#define CC_F6_5 0x09 -#define CC_F6_6 0x11 -#define CC_F6_7 0x21 - -#define CC_F5_BIAS 5 - -#define CC_MC_BYPASS 0x08 -#define CC_MC_M1 0x04 -#define CC_MC_M1M2 0x02 -#define CC_MC_M1M2M3 0x01 -#define CC_MC_M1M3 0x11 - - -#define CC_T2_BIAS 2 -#define CC_T2M2_BIAS 3 - -#define CC_T2MC_M1BYP 1 -#define CC_T2MC_M2BYP 2 -#define CC_T2MC_M3BYP 4 - - -#define CC_T6_MMASK 1 -#define CC_T6_M0 120000000 -#define CC_T6_M1 100000000 -#define SB2MIPS_T6(sb) (2 * (sb)) - - -#define CC_CLOCK_BASE1 24000000 -#define CC_CLOCK_BASE2 12500000 - - -#define CLKC_5350_N 0x0311 -#define CLKC_5350_M 0x04020009 - - -#define FLASH_NONE 0x000 -#define SFLASH_ST 0x100 -#define SFLASH_AT 0x200 -#define PFLASH 0x700 - - -#define CC_CFG_EN 0x0001 -#define CC_CFG_EM_MASK 0x000e -#define CC_CFG_EM_ASYNC 0x0000 -#define CC_CFG_EM_SYNC 0x0002 -#define CC_CFG_EM_PCMCIA 0x0004 -#define CC_CFG_EM_IDE 0x0006 -#define CC_CFG_DS 0x0010 -#define CC_CFG_CD_MASK 0x00e0 -#define CC_CFG_CE 0x0100 -#define CC_CFG_SB 0x0200 -#define CC_CFG_IS 0x0400 - - -#define CC_EB_BASE 0x1a000000 -#define CC_EB_PCMCIA_MEM 0x1a000000 -#define CC_EB_PCMCIA_IO 0x1a200000 -#define CC_EB_PCMCIA_CFG 0x1a400000 -#define CC_EB_IDE 0x1a800000 -#define CC_EB_PCMCIA1_MEM 0x1a800000 -#define CC_EB_PCMCIA1_IO 0x1aa00000 -#define CC_EB_PCMCIA1_CFG 0x1ac00000 -#define CC_EB_PROGIF 0x1b000000 - - - -#define SFLASH_OPCODE 0x000000ff -#define SFLASH_ACTION 0x00000700 -#define SFLASH_CS_ACTIVE 0x00001000 -#define SFLASH_START 0x80000000 -#define SFLASH_BUSY SFLASH_START - - -#define SFLASH_ACT_OPONLY 0x0000 -#define SFLASH_ACT_OP1D 0x0100 -#define SFLASH_ACT_OP3A 0x0200 -#define SFLASH_ACT_OP3A1D 0x0300 -#define SFLASH_ACT_OP3A4D 0x0400 -#define SFLASH_ACT_OP3A4X4D 0x0500 -#define SFLASH_ACT_OP3A1X4D 0x0700 - - -#define SFLASH_ST_WREN 0x0006 -#define SFLASH_ST_WRDIS 0x0004 -#define SFLASH_ST_RDSR 0x0105 -#define SFLASH_ST_WRSR 0x0101 -#define SFLASH_ST_READ 0x0303 -#define SFLASH_ST_PP 0x0302 -#define SFLASH_ST_SE 0x02d8 -#define SFLASH_ST_BE 0x00c7 -#define SFLASH_ST_DP 0x00b9 -#define SFLASH_ST_RES 0x03ab -#define SFLASH_ST_CSA 0x1000 -#define SFLASH_ST_SSE 0x0220 - - -#define SFLASH_ST_WIP 0x01 -#define SFLASH_ST_WEL 0x02 -#define SFLASH_ST_BP_MASK 0x1c -#define SFLASH_ST_BP_SHIFT 2 -#define SFLASH_ST_SRWD 0x80 - - -#define SFLASH_AT_READ 0x07e8 -#define SFLASH_AT_PAGE_READ 0x07d2 -#define SFLASH_AT_BUF1_READ -#define SFLASH_AT_BUF2_READ -#define SFLASH_AT_STATUS 0x01d7 -#define SFLASH_AT_BUF1_WRITE 0x0384 -#define SFLASH_AT_BUF2_WRITE 0x0387 -#define SFLASH_AT_BUF1_ERASE_PROGRAM 0x0283 -#define SFLASH_AT_BUF2_ERASE_PROGRAM 0x0286 -#define SFLASH_AT_BUF1_PROGRAM 0x0288 -#define SFLASH_AT_BUF2_PROGRAM 0x0289 -#define SFLASH_AT_PAGE_ERASE 0x0281 -#define SFLASH_AT_BLOCK_ERASE 0x0250 -#define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382 -#define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385 -#define SFLASH_AT_BUF1_LOAD 0x0253 -#define SFLASH_AT_BUF2_LOAD 0x0255 -#define SFLASH_AT_BUF1_COMPARE 0x0260 -#define SFLASH_AT_BUF2_COMPARE 0x0261 -#define SFLASH_AT_BUF1_REPROGRAM 0x0258 -#define SFLASH_AT_BUF2_REPROGRAM 0x0259 - - -#define SFLASH_AT_READY 0x80 -#define SFLASH_AT_MISMATCH 0x40 -#define SFLASH_AT_ID_MASK 0x38 -#define SFLASH_AT_ID_SHIFT 3 - - -#define GSIO_START 0x80000000 -#define GSIO_BUSY GSIO_START - - - -#define UART_RX 0 -#define UART_TX 0 -#define UART_DLL 0 -#define UART_IER 1 -#define UART_DLM 1 -#define UART_IIR 2 -#define UART_FCR 2 -#define UART_LCR 3 -#define UART_MCR 4 -#define UART_LSR 5 -#define UART_MSR 6 -#define UART_SCR 7 -#define UART_LCR_DLAB 0x80 -#define UART_LCR_WLEN8 0x03 -#define UART_MCR_OUT2 0x08 -#define UART_MCR_LOOP 0x10 -#define UART_LSR_RX_FIFO 0x80 -#define UART_LSR_TDHR 0x40 -#define UART_LSR_THRE 0x20 -#define UART_LSR_BREAK 0x10 -#define UART_LSR_FRAMING 0x08 -#define UART_LSR_PARITY 0x04 -#define UART_LSR_OVERRUN 0x02 -#define UART_LSR_RXRDY 0x01 -#define UART_FCR_FIFO_ENABLE 1 - - -#define UART_IIR_FIFO_MASK 0xc0 -#define UART_IIR_INT_MASK 0xf -#define UART_IIR_MDM_CHG 0x0 -#define UART_IIR_NOINT 0x1 -#define UART_IIR_THRE 0x2 -#define UART_IIR_RCVD_DATA 0x4 -#define UART_IIR_RCVR_STATUS 0x6 -#define UART_IIR_CHAR_TIME 0xc - - -#define UART_IER_EDSSI 8 -#define UART_IER_ELSI 4 -#define UART_IER_ETBEI 2 -#define UART_IER_ERBFI 1 - - -#define PST_EXTLPOAVAIL 0x0100 -#define PST_WDRESET 0x0080 -#define PST_INTPEND 0x0040 -#define PST_SBCLKST 0x0030 -#define PST_SBCLKST_ILP 0x0010 -#define PST_SBCLKST_ALP 0x0020 -#define PST_SBCLKST_HT 0x0030 -#define PST_ALPAVAIL 0x0008 -#define PST_HTAVAIL 0x0004 -#define PST_RESINIT 0x0003 - - -#define PCAP_REV_MASK 0x000000ff -#define PCAP_RC_MASK 0x00001f00 -#define PCAP_RC_SHIFT 8 -#define PCAP_TC_MASK 0x0001e000 -#define PCAP_TC_SHIFT 13 -#define PCAP_PC_MASK 0x001e0000 -#define PCAP_PC_SHIFT 17 -#define PCAP_VC_MASK 0x01e00000 -#define PCAP_VC_SHIFT 21 -#define PCAP_CC_MASK 0x1e000000 -#define PCAP_CC_SHIFT 25 -#define PCAP5_PC_MASK 0x003e0000 -#define PCAP5_PC_SHIFT 17 -#define PCAP5_VC_MASK 0x07c00000 -#define PCAP5_VC_SHIFT 22 -#define PCAP5_CC_MASK 0xf8000000 -#define PCAP5_CC_SHIFT 27 - - - -#define PRRT_TIME_MASK 0x03ff -#define PRRT_INTEN 0x0400 -#define PRRT_REQ_ACTIVE 0x0800 -#define PRRT_ALP_REQ 0x1000 -#define PRRT_HT_REQ 0x2000 - - -#define PMURES_BIT(bit) (1 << (bit)) - - -#define PMURES_MAX_RESNUM 30 - - -#define PMU_CHIPCTL0 0 - - -#define PMU_CC1_CLKREQ_TYPE_SHIFT 19 -#define PMU_CC1_CLKREQ_TYPE_MASK (1 << PMU_CC1_CLKREQ_TYPE_SHIFT) - -#define CLKREQ_TYPE_CONFIG_OPENDRAIN 0 -#define CLKREQ_TYPE_CONFIG_PUSHPULL 1 - - -#define PMU_CHIPCTL1 1 -#define PMU_CC1_RXC_DLL_BYPASS 0x00010000 - -#define PMU_CC1_IF_TYPE_MASK 0x00000030 -#define PMU_CC1_IF_TYPE_RMII 0x00000000 -#define PMU_CC1_IF_TYPE_MII 0x00000010 -#define PMU_CC1_IF_TYPE_RGMII 0x00000020 - -#define PMU_CC1_SW_TYPE_MASK 0x000000c0 -#define PMU_CC1_SW_TYPE_EPHY 0x00000000 -#define PMU_CC1_SW_TYPE_EPHYMII 0x00000040 -#define PMU_CC1_SW_TYPE_EPHYRMII 0x00000080 -#define PMU_CC1_SW_TYPE_RGMII 0x000000c0 - - - - - -#define PMU0_PLL0_PLLCTL0 0 -#define PMU0_PLL0_PC0_PDIV_MASK 1 -#define PMU0_PLL0_PC0_PDIV_FREQ 25000 -#define PMU0_PLL0_PC0_DIV_ARM_MASK 0x00000038 -#define PMU0_PLL0_PC0_DIV_ARM_SHIFT 3 -#define PMU0_PLL0_PC0_DIV_ARM_BASE 8 - - -#define PMU0_PLL0_PC0_DIV_ARM_110MHZ 0 -#define PMU0_PLL0_PC0_DIV_ARM_97_7MHZ 1 -#define PMU0_PLL0_PC0_DIV_ARM_88MHZ 2 -#define PMU0_PLL0_PC0_DIV_ARM_80MHZ 3 -#define PMU0_PLL0_PC0_DIV_ARM_73_3MHZ 4 -#define PMU0_PLL0_PC0_DIV_ARM_67_7MHZ 5 -#define PMU0_PLL0_PC0_DIV_ARM_62_9MHZ 6 -#define PMU0_PLL0_PC0_DIV_ARM_58_6MHZ 7 - - -#define PMU0_PLL0_PLLCTL1 1 -#define PMU0_PLL0_PC1_WILD_INT_MASK 0xf0000000 -#define PMU0_PLL0_PC1_WILD_INT_SHIFT 28 -#define PMU0_PLL0_PC1_WILD_FRAC_MASK 0x0fffff00 -#define PMU0_PLL0_PC1_WILD_FRAC_SHIFT 8 -#define PMU0_PLL0_PC1_STOP_MOD 0x00000040 - - -#define PMU0_PLL0_PLLCTL2 2 -#define PMU0_PLL0_PC2_WILD_INT_MASK 0xf -#define PMU0_PLL0_PC2_WILD_INT_SHIFT 4 - - - -#define PMU1_PLL0_PLLCTL0 0 -#define PMU1_PLL0_PC0_P1DIV_MASK 0x00f00000 -#define PMU1_PLL0_PC0_P1DIV_SHIFT 20 -#define PMU1_PLL0_PC0_P2DIV_MASK 0x0f000000 -#define PMU1_PLL0_PC0_P2DIV_SHIFT 24 - - -#define PMU1_PLL0_PLLCTL1 1 -#define PMU1_PLL0_PC1_M1DIV_MASK 0x000000ff -#define PMU1_PLL0_PC1_M1DIV_SHIFT 0 -#define PMU1_PLL0_PC1_M2DIV_MASK 0x0000ff00 -#define PMU1_PLL0_PC1_M2DIV_SHIFT 8 -#define PMU1_PLL0_PC1_M3DIV_MASK 0x00ff0000 -#define PMU1_PLL0_PC1_M3DIV_SHIFT 16 -#define PMU1_PLL0_PC1_M4DIV_MASK 0xff000000 -#define PMU1_PLL0_PC1_M4DIV_SHIFT 24 -#define PMU1_PLL0_PC1_M4DIV_BY_9 9 -#define PMU1_PLL0_PC1_M4DIV_BY_18 0x12 -#define PMU1_PLL0_PC1_M4DIV_BY_36 0x24 - -#define DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT 8 -#define DOT11MAC_880MHZ_CLK_DIVISOR_MASK (0xFF << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT) -#define DOT11MAC_880MHZ_CLK_DIVISOR_VAL (0xE << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT) - - -#define PMU1_PLL0_PLLCTL2 2 -#define PMU1_PLL0_PC2_M5DIV_MASK 0x000000ff -#define PMU1_PLL0_PC2_M5DIV_SHIFT 0 -#define PMU1_PLL0_PC2_M5DIV_BY_12 0xc -#define PMU1_PLL0_PC2_M5DIV_BY_18 0x12 -#define PMU1_PLL0_PC2_M5DIV_BY_36 0x24 -#define PMU1_PLL0_PC2_M6DIV_MASK 0x0000ff00 -#define PMU1_PLL0_PC2_M6DIV_SHIFT 8 -#define PMU1_PLL0_PC2_M6DIV_BY_18 0x12 -#define PMU1_PLL0_PC2_M6DIV_BY_36 0x24 -#define PMU1_PLL0_PC2_NDIV_MODE_MASK 0x000e0000 -#define PMU1_PLL0_PC2_NDIV_MODE_SHIFT 17 -#define PMU1_PLL0_PC2_NDIV_MODE_MASH 1 -#define PMU1_PLL0_PC2_NDIV_MODE_MFB 2 -#define PMU1_PLL0_PC2_NDIV_INT_MASK 0x1ff00000 -#define PMU1_PLL0_PC2_NDIV_INT_SHIFT 20 - - -#define PMU1_PLL0_PLLCTL3 3 -#define PMU1_PLL0_PC3_NDIV_FRAC_MASK 0x00ffffff -#define PMU1_PLL0_PC3_NDIV_FRAC_SHIFT 0 - - -#define PMU1_PLL0_PLLCTL4 4 - - -#define PMU1_PLL0_PLLCTL5 5 -#define PMU1_PLL0_PC5_CLK_DRV_MASK 0xffffff00 -#define PMU1_PLL0_PC5_CLK_DRV_SHIFT 8 - - -#define PMU2_PHY_PLL_PLLCTL 4 -#define PMU2_SI_PLL_PLLCTL 10 - - - - -#define PMU2_PLL_PLLCTL0 0 -#define PMU2_PLL_PC0_P1DIV_MASK 0x00f00000 -#define PMU2_PLL_PC0_P1DIV_SHIFT 20 -#define PMU2_PLL_PC0_P2DIV_MASK 0x0f000000 -#define PMU2_PLL_PC0_P2DIV_SHIFT 24 - - -#define PMU2_PLL_PLLCTL1 1 -#define PMU2_PLL_PC1_M1DIV_MASK 0x000000ff -#define PMU2_PLL_PC1_M1DIV_SHIFT 0 -#define PMU2_PLL_PC1_M2DIV_MASK 0x0000ff00 -#define PMU2_PLL_PC1_M2DIV_SHIFT 8 -#define PMU2_PLL_PC1_M3DIV_MASK 0x00ff0000 -#define PMU2_PLL_PC1_M3DIV_SHIFT 16 -#define PMU2_PLL_PC1_M4DIV_MASK 0xff000000 -#define PMU2_PLL_PC1_M4DIV_SHIFT 24 - - -#define PMU2_PLL_PLLCTL2 2 -#define PMU2_PLL_PC2_M5DIV_MASK 0x000000ff -#define PMU2_PLL_PC2_M5DIV_SHIFT 0 -#define PMU2_PLL_PC2_M6DIV_MASK 0x0000ff00 -#define PMU2_PLL_PC2_M6DIV_SHIFT 8 -#define PMU2_PLL_PC2_NDIV_MODE_MASK 0x000e0000 -#define PMU2_PLL_PC2_NDIV_MODE_SHIFT 17 -#define PMU2_PLL_PC2_NDIV_INT_MASK 0x1ff00000 -#define PMU2_PLL_PC2_NDIV_INT_SHIFT 20 - - -#define PMU2_PLL_PLLCTL3 3 -#define PMU2_PLL_PC3_NDIV_FRAC_MASK 0x00ffffff -#define PMU2_PLL_PC3_NDIV_FRAC_SHIFT 0 - - -#define PMU2_PLL_PLLCTL4 4 - - -#define PMU2_PLL_PLLCTL5 5 -#define PMU2_PLL_PC5_CLKDRIVE_CH1_MASK 0x00000f00 -#define PMU2_PLL_PC5_CLKDRIVE_CH1_SHIFT 8 -#define PMU2_PLL_PC5_CLKDRIVE_CH2_MASK 0x0000f000 -#define PMU2_PLL_PC5_CLKDRIVE_CH2_SHIFT 12 -#define PMU2_PLL_PC5_CLKDRIVE_CH3_MASK 0x000f0000 -#define PMU2_PLL_PC5_CLKDRIVE_CH3_SHIFT 16 -#define PMU2_PLL_PC5_CLKDRIVE_CH4_MASK 0x00f00000 -#define PMU2_PLL_PC5_CLKDRIVE_CH4_SHIFT 20 -#define PMU2_PLL_PC5_CLKDRIVE_CH5_MASK 0x0f000000 -#define PMU2_PLL_PC5_CLKDRIVE_CH5_SHIFT 24 -#define PMU2_PLL_PC5_CLKDRIVE_CH6_MASK 0xf0000000 -#define PMU2_PLL_PC5_CLKDRIVE_CH6_SHIFT 28 - - -#define PMU5_PLL_P1P2_OFF 0 -#define PMU5_PLL_P1_MASK 0x0f000000 -#define PMU5_PLL_P1_SHIFT 24 -#define PMU5_PLL_P2_MASK 0x00f00000 -#define PMU5_PLL_P2_SHIFT 20 -#define PMU5_PLL_M14_OFF 1 -#define PMU5_PLL_MDIV_MASK 0x000000ff -#define PMU5_PLL_MDIV_WIDTH 8 -#define PMU5_PLL_NM5_OFF 2 -#define PMU5_PLL_NDIV_MASK 0xfff00000 -#define PMU5_PLL_NDIV_SHIFT 20 -#define PMU5_PLL_NDIV_MODE_MASK 0x000e0000 -#define PMU5_PLL_NDIV_MODE_SHIFT 17 -#define PMU5_PLL_FMAB_OFF 3 -#define PMU5_PLL_MRAT_MASK 0xf0000000 -#define PMU5_PLL_MRAT_SHIFT 28 -#define PMU5_PLL_ABRAT_MASK 0x08000000 -#define PMU5_PLL_ABRAT_SHIFT 27 -#define PMU5_PLL_FDIV_MASK 0x07ffffff -#define PMU5_PLL_PLLCTL_OFF 4 -#define PMU5_PLL_PCHI_OFF 5 -#define PMU5_PLL_PCHI_MASK 0x0000003f - - -#define PMU_XTALFREQ_REG_ILPCTR_MASK 0x00001FFF -#define PMU_XTALFREQ_REG_MEASURE_MASK 0x80000000 -#define PMU_XTALFREQ_REG_MEASURE_SHIFT 31 - - -#define PMU5_MAINPLL_CPU 1 -#define PMU5_MAINPLL_MEM 2 -#define PMU5_MAINPLL_SI 3 - -#define PMU7_PLL_PLLCTL7 7 -#define PMU7_PLL_CTL7_M4DIV_MASK 0xff000000 -#define PMU7_PLL_CTL7_M4DIV_SHIFT 24 -#define PMU7_PLL_CTL7_M4DIV_BY_6 6 -#define PMU7_PLL_CTL7_M4DIV_BY_12 0xc -#define PMU7_PLL_CTL7_M4DIV_BY_24 0x18 -#define PMU7_PLL_PLLCTL8 8 -#define PMU7_PLL_CTL8_M5DIV_MASK 0x000000ff -#define PMU7_PLL_CTL8_M5DIV_SHIFT 0 -#define PMU7_PLL_CTL8_M5DIV_BY_8 8 -#define PMU7_PLL_CTL8_M5DIV_BY_12 0xc -#define PMU7_PLL_CTL8_M5DIV_BY_24 0x18 -#define PMU7_PLL_CTL8_M6DIV_MASK 0x0000ff00 -#define PMU7_PLL_CTL8_M6DIV_SHIFT 8 -#define PMU7_PLL_CTL8_M6DIV_BY_12 0xc -#define PMU7_PLL_CTL8_M6DIV_BY_24 0x18 -#define PMU7_PLL_PLLCTL11 11 -#define PMU7_PLL_PLLCTL11_MASK 0xffffff00 -#define PMU7_PLL_PLLCTL11_VAL 0x22222200 - - -#define PMU4716_MAINPLL_PLL0 12 - - -#define PMU5356_MAINPLL_PLL0 0 -#define PMU5357_MAINPLL_PLL0 0 - - -#define RES4716_PROC_PLL_ON 0x00000040 -#define RES4716_PROC_HT_AVAIL 0x00000080 - - -#define CCTRL_471X_I2S_PINS_ENABLE 0x0080 - - - -#define CCTRL_5357_I2S_PINS_ENABLE 0x00040000 -#define CCTRL_5357_I2CSPI_PINS_ENABLE 0x00080000 - - -#define RES5354_EXT_SWITCHER_PWM 0 -#define RES5354_BB_SWITCHER_PWM 1 -#define RES5354_BB_SWITCHER_BURST 2 -#define RES5354_BB_EXT_SWITCHER_BURST 3 -#define RES5354_ILP_REQUEST 4 -#define RES5354_RADIO_SWITCHER_PWM 5 -#define RES5354_RADIO_SWITCHER_BURST 6 -#define RES5354_ROM_SWITCH 7 -#define RES5354_PA_REF_LDO 8 -#define RES5354_RADIO_LDO 9 -#define RES5354_AFE_LDO 10 -#define RES5354_PLL_LDO 11 -#define RES5354_BG_FILTBYP 12 -#define RES5354_TX_FILTBYP 13 -#define RES5354_RX_FILTBYP 14 -#define RES5354_XTAL_PU 15 -#define RES5354_XTAL_EN 16 -#define RES5354_BB_PLL_FILTBYP 17 -#define RES5354_RF_PLL_FILTBYP 18 -#define RES5354_BB_PLL_PU 19 - - -#define CCTRL5357_EXTPA (1<<14) -#define CCTRL5357_ANT_MUX_2o3 (1<<15) - - -#define RES4328_EXT_SWITCHER_PWM 0 -#define RES4328_BB_SWITCHER_PWM 1 -#define RES4328_BB_SWITCHER_BURST 2 -#define RES4328_BB_EXT_SWITCHER_BURST 3 -#define RES4328_ILP_REQUEST 4 -#define RES4328_RADIO_SWITCHER_PWM 5 -#define RES4328_RADIO_SWITCHER_BURST 6 -#define RES4328_ROM_SWITCH 7 -#define RES4328_PA_REF_LDO 8 -#define RES4328_RADIO_LDO 9 -#define RES4328_AFE_LDO 10 -#define RES4328_PLL_LDO 11 -#define RES4328_BG_FILTBYP 12 -#define RES4328_TX_FILTBYP 13 -#define RES4328_RX_FILTBYP 14 -#define RES4328_XTAL_PU 15 -#define RES4328_XTAL_EN 16 -#define RES4328_BB_PLL_FILTBYP 17 -#define RES4328_RF_PLL_FILTBYP 18 -#define RES4328_BB_PLL_PU 19 - - -#define RES4325_BUCK_BOOST_BURST 0 -#define RES4325_CBUCK_BURST 1 -#define RES4325_CBUCK_PWM 2 -#define RES4325_CLDO_CBUCK_BURST 3 -#define RES4325_CLDO_CBUCK_PWM 4 -#define RES4325_BUCK_BOOST_PWM 5 -#define RES4325_ILP_REQUEST 6 -#define RES4325_ABUCK_BURST 7 -#define RES4325_ABUCK_PWM 8 -#define RES4325_LNLDO1_PU 9 -#define RES4325_OTP_PU 10 -#define RES4325_LNLDO3_PU 11 -#define RES4325_LNLDO4_PU 12 -#define RES4325_XTAL_PU 13 -#define RES4325_ALP_AVAIL 14 -#define RES4325_RX_PWRSW_PU 15 -#define RES4325_TX_PWRSW_PU 16 -#define RES4325_RFPLL_PWRSW_PU 17 -#define RES4325_LOGEN_PWRSW_PU 18 -#define RES4325_AFE_PWRSW_PU 19 -#define RES4325_BBPLL_PWRSW_PU 20 -#define RES4325_HT_AVAIL 21 - - -#define RES4325B0_CBUCK_LPOM 1 -#define RES4325B0_CBUCK_BURST 2 -#define RES4325B0_CBUCK_PWM 3 -#define RES4325B0_CLDO_PU 4 - - -#define RES4325C1_LNLDO2_PU 12 - - -#define CST4325_SPROM_OTP_SEL_MASK 0x00000003 -#define CST4325_DEFCIS_SEL 0 -#define CST4325_SPROM_SEL 1 -#define CST4325_OTP_SEL 2 -#define CST4325_OTP_PWRDN 3 -#define CST4325_SDIO_USB_MODE_MASK 0x00000004 -#define CST4325_SDIO_USB_MODE_SHIFT 2 -#define CST4325_RCAL_VALID_MASK 0x00000008 -#define CST4325_RCAL_VALID_SHIFT 3 -#define CST4325_RCAL_VALUE_MASK 0x000001f0 -#define CST4325_RCAL_VALUE_SHIFT 4 -#define CST4325_PMUTOP_2B_MASK 0x00000200 -#define CST4325_PMUTOP_2B_SHIFT 9 - -#define RES4329_RESERVED0 0 -#define RES4329_CBUCK_LPOM 1 -#define RES4329_CBUCK_BURST 2 -#define RES4329_CBUCK_PWM 3 -#define RES4329_CLDO_PU 4 -#define RES4329_PALDO_PU 5 -#define RES4329_ILP_REQUEST 6 -#define RES4329_RESERVED7 7 -#define RES4329_RESERVED8 8 -#define RES4329_LNLDO1_PU 9 -#define RES4329_OTP_PU 10 -#define RES4329_RESERVED11 11 -#define RES4329_LNLDO2_PU 12 -#define RES4329_XTAL_PU 13 -#define RES4329_ALP_AVAIL 14 -#define RES4329_RX_PWRSW_PU 15 -#define RES4329_TX_PWRSW_PU 16 -#define RES4329_RFPLL_PWRSW_PU 17 -#define RES4329_LOGEN_PWRSW_PU 18 -#define RES4329_AFE_PWRSW_PU 19 -#define RES4329_BBPLL_PWRSW_PU 20 -#define RES4329_HT_AVAIL 21 - -#define CST4329_SPROM_OTP_SEL_MASK 0x00000003 -#define CST4329_DEFCIS_SEL 0 -#define CST4329_SPROM_SEL 1 -#define CST4329_OTP_SEL 2 -#define CST4329_OTP_PWRDN 3 -#define CST4329_SPI_SDIO_MODE_MASK 0x00000004 -#define CST4329_SPI_SDIO_MODE_SHIFT 2 - - -#define CST4312_SPROM_OTP_SEL_MASK 0x00000003 -#define CST4312_DEFCIS_SEL 0 -#define CST4312_SPROM_SEL 1 -#define CST4312_OTP_SEL 2 -#define CST4312_OTP_BAD 3 - - -#define RES4312_SWITCHER_BURST 0 -#define RES4312_SWITCHER_PWM 1 -#define RES4312_PA_REF_LDO 2 -#define RES4312_CORE_LDO_BURST 3 -#define RES4312_CORE_LDO_PWM 4 -#define RES4312_RADIO_LDO 5 -#define RES4312_ILP_REQUEST 6 -#define RES4312_BG_FILTBYP 7 -#define RES4312_TX_FILTBYP 8 -#define RES4312_RX_FILTBYP 9 -#define RES4312_XTAL_PU 10 -#define RES4312_ALP_AVAIL 11 -#define RES4312_BB_PLL_FILTBYP 12 -#define RES4312_RF_PLL_FILTBYP 13 -#define RES4312_HT_AVAIL 14 - - -#define RES4322_RF_LDO 0 -#define RES4322_ILP_REQUEST 1 -#define RES4322_XTAL_PU 2 -#define RES4322_ALP_AVAIL 3 -#define RES4322_SI_PLL_ON 4 -#define RES4322_HT_SI_AVAIL 5 -#define RES4322_PHY_PLL_ON 6 -#define RES4322_HT_PHY_AVAIL 7 -#define RES4322_OTP_PU 8 - - -#define CST4322_XTAL_FREQ_20_40MHZ 0x00000020 -#define CST4322_SPROM_OTP_SEL_MASK 0x000000c0 -#define CST4322_SPROM_OTP_SEL_SHIFT 6 -#define CST4322_NO_SPROM_OTP 0 -#define CST4322_SPROM_PRESENT 1 -#define CST4322_OTP_PRESENT 2 -#define CST4322_PCI_OR_USB 0x00000100 -#define CST4322_BOOT_MASK 0x00000600 -#define CST4322_BOOT_SHIFT 9 -#define CST4322_BOOT_FROM_SRAM 0 -#define CST4322_BOOT_FROM_ROM 1 -#define CST4322_BOOT_FROM_FLASH 2 -#define CST4322_BOOT_FROM_INVALID 3 -#define CST4322_ILP_DIV_EN 0x00000800 -#define CST4322_FLASH_TYPE_MASK 0x00001000 -#define CST4322_FLASH_TYPE_SHIFT 12 -#define CST4322_FLASH_TYPE_SHIFT_ST 0 -#define CST4322_FLASH_TYPE_SHIFT_ATMEL 1 -#define CST4322_ARM_TAP_SEL 0x00002000 -#define CST4322_RES_INIT_MODE_MASK 0x0000c000 -#define CST4322_RES_INIT_MODE_SHIFT 14 -#define CST4322_RES_INIT_MODE_ILPAVAIL 0 -#define CST4322_RES_INIT_MODE_ILPREQ 1 -#define CST4322_RES_INIT_MODE_ALPAVAIL 2 -#define CST4322_RES_INIT_MODE_HTAVAIL 3 -#define CST4322_PCIPLLCLK_GATING 0x00010000 -#define CST4322_CLK_SWITCH_PCI_TO_ALP 0x00020000 -#define CST4322_PCI_CARDBUS_MODE 0x00040000 - - -#define CCTRL43224_GPIO_TOGGLE 0x8000 -#define CCTRL_43224A0_12MA_LED_DRIVE 0x00F000F0 -#define CCTRL_43224B0_12MA_LED_DRIVE 0xF0 - - -#define RES43236_REGULATOR 0 -#define RES43236_ILP_REQUEST 1 -#define RES43236_XTAL_PU 2 -#define RES43236_ALP_AVAIL 3 -#define RES43236_SI_PLL_ON 4 -#define RES43236_HT_SI_AVAIL 5 - - -#define CCTRL43236_BT_COEXIST (1<<0) -#define CCTRL43236_SECI (1<<1) -#define CCTRL43236_EXT_LNA (1<<2) -#define CCTRL43236_ANT_MUX_2o3 (1<<3) -#define CCTRL43236_GSIO (1<<4) - - -#define CST43236_SFLASH_MASK 0x00000040 -#define CST43236_OTP_SEL_MASK 0x00000080 -#define CST43236_OTP_SEL_SHIFT 7 -#define CST43236_HSIC_MASK 0x00000100 -#define CST43236_BP_CLK 0x00000200 -#define CST43236_BOOT_MASK 0x00001800 -#define CST43236_BOOT_SHIFT 11 -#define CST43236_BOOT_FROM_SRAM 0 -#define CST43236_BOOT_FROM_ROM 1 -#define CST43236_BOOT_FROM_FLASH 2 -#define CST43236_BOOT_FROM_INVALID 3 - - -#define RES43237_REGULATOR 0 -#define RES43237_ILP_REQUEST 1 -#define RES43237_XTAL_PU 2 -#define RES43237_ALP_AVAIL 3 -#define RES43237_SI_PLL_ON 4 -#define RES43237_HT_SI_AVAIL 5 - - -#define CCTRL43237_BT_COEXIST (1<<0) -#define CCTRL43237_SECI (1<<1) -#define CCTRL43237_EXT_LNA (1<<2) -#define CCTRL43237_ANT_MUX_2o3 (1<<3) -#define CCTRL43237_GSIO (1<<4) - - -#define CST43237_SFLASH_MASK 0x00000040 -#define CST43237_OTP_SEL_MASK 0x00000080 -#define CST43237_OTP_SEL_SHIFT 7 -#define CST43237_HSIC_MASK 0x00000100 -#define CST43237_BP_CLK 0x00000200 -#define CST43237_BOOT_MASK 0x00001800 -#define CST43237_BOOT_SHIFT 11 -#define CST43237_BOOT_FROM_SRAM 0 -#define CST43237_BOOT_FROM_ROM 1 -#define CST43237_BOOT_FROM_FLASH 2 -#define CST43237_BOOT_FROM_INVALID 3 - - -#define RES43239_CBUCK_LPOM 0 -#define RES43239_CBUCK_BURST 1 -#define RES43239_CBUCK_LP_PWM 2 -#define RES43239_CBUCK_PWM 3 -#define RES43239_CLDO_PU 4 -#define RES43239_DIS_INT_RESET_PD 5 -#define RES43239_ILP_REQUEST 6 -#define RES43239_LNLDO_PU 7 -#define RES43239_LDO3P3_PU 8 -#define RES43239_OTP_PU 9 -#define RES43239_XTAL_PU 10 -#define RES43239_ALP_AVAIL 11 -#define RES43239_RADIO_PU 12 -#define RES43239_MACPHY_CLKAVAIL 23 -#define RES43239_HT_AVAIL 24 -#define RES43239_XOLDO_PU 25 -#define RES43239_WL_XTAL_CTL_SEL 26 -#define RES43239_SR_CLK_STABLE 27 -#define RES43239_SR_SAVE_RESTORE 28 -#define RES43239_SR_PHY_PIC 29 -#define RES43239_SR_PHY_PWR_SW 30 - - -#define CST43239_SPROM_MASK 0x00000002 -#define CST43239_SFLASH_MASK 0x00000004 -#define CST43239_RES_INIT_MODE_SHIFT 7 -#define CST43239_RES_INIT_MODE_MASK 0x000001f0 -#define CST43239_CHIPMODE_SDIOD(cs) ((cs) & (1 << 15)) -#define CST43239_CHIPMODE_USB20D(cs) (~(cs) & (1 << 15)) -#define CST43239_CHIPMODE_SDIO(cs) (((cs) & (1 << 0)) == 0) -#define CST43239_CHIPMODE_GSPI(cs) (((cs) & (1 << 0)) == (1 << 0)) - - -#define CCTRL43239_XTAL_STRENGTH(ctl) ((ctl & 0x3F) << 12) - - -#define RES4331_REGULATOR 0 -#define RES4331_ILP_REQUEST 1 -#define RES4331_XTAL_PU 2 -#define RES4331_ALP_AVAIL 3 -#define RES4331_SI_PLL_ON 4 -#define RES4331_HT_SI_AVAIL 5 - - -#define CCTRL4331_BT_COEXIST (1<<0) -#define CCTRL4331_SECI (1<<1) -#define CCTRL4331_EXT_LNA_G (1<<2) -#define CCTRL4331_SPROM_GPIO13_15 (1<<3) -#define CCTRL4331_EXTPA_EN (1<<4) -#define CCTRL4331_GPIOCLK_ON_SPROMCS (1<<5) -#define CCTRL4331_PCIE_MDIO_ON_SPROMCS (1<<6) -#define CCTRL4331_EXTPA_ON_GPIO2_5 (1<<7) -#define CCTRL4331_OVR_PIPEAUXCLKEN (1<<8) -#define CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9) -#define CCTRL4331_PCIE_AUXCLKEN (1<<10) -#define CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11) -#define CCTRL4331_EXTPA_EN2 (1<<12) -#define CCTRL4331_EXT_LNA_A (1<<13) -#define CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16) -#define CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17) -#define CCTRL4331_EXTPA_ANA_EN (1<<24) - - -#define CST4331_XTAL_FREQ 0x00000001 -#define CST4331_SPROM_OTP_SEL_MASK 0x00000006 -#define CST4331_SPROM_OTP_SEL_SHIFT 1 -#define CST4331_SPROM_PRESENT 0x00000002 -#define CST4331_OTP_PRESENT 0x00000004 -#define CST4331_LDO_RF 0x00000008 -#define CST4331_LDO_PAR 0x00000010 - - -#define RES4315_CBUCK_LPOM 1 -#define RES4315_CBUCK_BURST 2 -#define RES4315_CBUCK_PWM 3 -#define RES4315_CLDO_PU 4 -#define RES4315_PALDO_PU 5 -#define RES4315_ILP_REQUEST 6 -#define RES4315_LNLDO1_PU 9 -#define RES4315_OTP_PU 10 -#define RES4315_LNLDO2_PU 12 -#define RES4315_XTAL_PU 13 -#define RES4315_ALP_AVAIL 14 -#define RES4315_RX_PWRSW_PU 15 -#define RES4315_TX_PWRSW_PU 16 -#define RES4315_RFPLL_PWRSW_PU 17 -#define RES4315_LOGEN_PWRSW_PU 18 -#define RES4315_AFE_PWRSW_PU 19 -#define RES4315_BBPLL_PWRSW_PU 20 -#define RES4315_HT_AVAIL 21 - - -#define CST4315_SPROM_OTP_SEL_MASK 0x00000003 -#define CST4315_DEFCIS_SEL 0x00000000 -#define CST4315_SPROM_SEL 0x00000001 -#define CST4315_OTP_SEL 0x00000002 -#define CST4315_OTP_PWRDN 0x00000003 -#define CST4315_SDIO_MODE 0x00000004 -#define CST4315_RCAL_VALID 0x00000008 -#define CST4315_RCAL_VALUE_MASK 0x000001f0 -#define CST4315_RCAL_VALUE_SHIFT 4 -#define CST4315_PALDO_EXTPNP 0x00000200 -#define CST4315_CBUCK_MODE_MASK 0x00000c00 -#define CST4315_CBUCK_MODE_BURST 0x00000400 -#define CST4315_CBUCK_MODE_LPBURST 0x00000c00 - - -#define RES4319_CBUCK_LPOM 1 -#define RES4319_CBUCK_BURST 2 -#define RES4319_CBUCK_PWM 3 -#define RES4319_CLDO_PU 4 -#define RES4319_PALDO_PU 5 -#define RES4319_ILP_REQUEST 6 -#define RES4319_LNLDO1_PU 9 -#define RES4319_OTP_PU 10 -#define RES4319_LNLDO2_PU 12 -#define RES4319_XTAL_PU 13 -#define RES4319_ALP_AVAIL 14 -#define RES4319_RX_PWRSW_PU 15 -#define RES4319_TX_PWRSW_PU 16 -#define RES4319_RFPLL_PWRSW_PU 17 -#define RES4319_LOGEN_PWRSW_PU 18 -#define RES4319_AFE_PWRSW_PU 19 -#define RES4319_BBPLL_PWRSW_PU 20 -#define RES4319_HT_AVAIL 21 - - -#define CST4319_SPI_CPULESSUSB 0x00000001 -#define CST4319_SPI_CLK_POL 0x00000002 -#define CST4319_SPI_CLK_PH 0x00000008 -#define CST4319_SPROM_OTP_SEL_MASK 0x000000c0 -#define CST4319_SPROM_OTP_SEL_SHIFT 6 -#define CST4319_DEFCIS_SEL 0x00000000 -#define CST4319_SPROM_SEL 0x00000040 -#define CST4319_OTP_SEL 0x00000080 -#define CST4319_OTP_PWRDN 0x000000c0 -#define CST4319_SDIO_USB_MODE 0x00000100 -#define CST4319_REMAP_SEL_MASK 0x00000600 -#define CST4319_ILPDIV_EN 0x00000800 -#define CST4319_XTAL_PD_POL 0x00001000 -#define CST4319_LPO_SEL 0x00002000 -#define CST4319_RES_INIT_MODE 0x0000c000 -#define CST4319_PALDO_EXTPNP 0x00010000 -#define CST4319_CBUCK_MODE_MASK 0x00060000 -#define CST4319_CBUCK_MODE_BURST 0x00020000 -#define CST4319_CBUCK_MODE_LPBURST 0x00060000 -#define CST4319_RCAL_VALID 0x01000000 -#define CST4319_RCAL_VALUE_MASK 0x3e000000 -#define CST4319_RCAL_VALUE_SHIFT 25 - -#define PMU1_PLL0_CHIPCTL0 0 -#define PMU1_PLL0_CHIPCTL1 1 -#define PMU1_PLL0_CHIPCTL2 2 -#define CCTL_4319USB_XTAL_SEL_MASK 0x00180000 -#define CCTL_4319USB_XTAL_SEL_SHIFT 19 -#define CCTL_4319USB_48MHZ_PLL_SEL 1 -#define CCTL_4319USB_24MHZ_PLL_SEL 2 - - -#define RES4336_CBUCK_LPOM 0 -#define RES4336_CBUCK_BURST 1 -#define RES4336_CBUCK_LP_PWM 2 -#define RES4336_CBUCK_PWM 3 -#define RES4336_CLDO_PU 4 -#define RES4336_DIS_INT_RESET_PD 5 -#define RES4336_ILP_REQUEST 6 -#define RES4336_LNLDO_PU 7 -#define RES4336_LDO3P3_PU 8 -#define RES4336_OTP_PU 9 -#define RES4336_XTAL_PU 10 -#define RES4336_ALP_AVAIL 11 -#define RES4336_RADIO_PU 12 -#define RES4336_BG_PU 13 -#define RES4336_VREG1p4_PU_PU 14 -#define RES4336_AFE_PWRSW_PU 15 -#define RES4336_RX_PWRSW_PU 16 -#define RES4336_TX_PWRSW_PU 17 -#define RES4336_BB_PWRSW_PU 18 -#define RES4336_SYNTH_PWRSW_PU 19 -#define RES4336_MISC_PWRSW_PU 20 -#define RES4336_LOGEN_PWRSW_PU 21 -#define RES4336_BBPLL_PWRSW_PU 22 -#define RES4336_MACPHY_CLKAVAIL 23 -#define RES4336_HT_AVAIL 24 -#define RES4336_RSVD 25 - - -#define CST4336_SPI_MODE_MASK 0x00000001 -#define CST4336_SPROM_PRESENT 0x00000002 -#define CST4336_OTP_PRESENT 0x00000004 -#define CST4336_ARMREMAP_0 0x00000008 -#define CST4336_ILPDIV_EN_MASK 0x00000010 -#define CST4336_ILPDIV_EN_SHIFT 4 -#define CST4336_XTAL_PD_POL_MASK 0x00000020 -#define CST4336_XTAL_PD_POL_SHIFT 5 -#define CST4336_LPO_SEL_MASK 0x00000040 -#define CST4336_LPO_SEL_SHIFT 6 -#define CST4336_RES_INIT_MODE_MASK 0x00000180 -#define CST4336_RES_INIT_MODE_SHIFT 7 -#define CST4336_CBUCK_MODE_MASK 0x00000600 -#define CST4336_CBUCK_MODE_SHIFT 9 - - -#define PCTL_4336_SERIAL_ENAB (1 << 24) - - -#define RES4330_CBUCK_LPOM 0 -#define RES4330_CBUCK_BURST 1 -#define RES4330_CBUCK_LP_PWM 2 -#define RES4330_CBUCK_PWM 3 -#define RES4330_CLDO_PU 4 -#define RES4330_DIS_INT_RESET_PD 5 -#define RES4330_ILP_REQUEST 6 -#define RES4330_LNLDO_PU 7 -#define RES4330_LDO3P3_PU 8 -#define RES4330_OTP_PU 9 -#define RES4330_XTAL_PU 10 -#define RES4330_ALP_AVAIL 11 -#define RES4330_RADIO_PU 12 -#define RES4330_BG_PU 13 -#define RES4330_VREG1p4_PU_PU 14 -#define RES4330_AFE_PWRSW_PU 15 -#define RES4330_RX_PWRSW_PU 16 -#define RES4330_TX_PWRSW_PU 17 -#define RES4330_BB_PWRSW_PU 18 -#define RES4330_SYNTH_PWRSW_PU 19 -#define RES4330_MISC_PWRSW_PU 20 -#define RES4330_LOGEN_PWRSW_PU 21 -#define RES4330_BBPLL_PWRSW_PU 22 -#define RES4330_MACPHY_CLKAVAIL 23 -#define RES4330_HT_AVAIL 24 -#define RES4330_5gRX_PWRSW_PU 25 -#define RES4330_5gTX_PWRSW_PU 26 -#define RES4330_5g_LOGEN_PWRSW_PU 27 - - -#define CST4330_CHIPMODE_SDIOD(cs) (((cs) & 0x7) < 6) -#define CST4330_CHIPMODE_USB20D(cs) (((cs) & 0x7) >= 6) -#define CST4330_CHIPMODE_SDIO(cs) (((cs) & 0x4) == 0) -#define CST4330_CHIPMODE_GSPI(cs) (((cs) & 0x6) == 4) -#define CST4330_CHIPMODE_USB(cs) (((cs) & 0x7) == 6) -#define CST4330_CHIPMODE_USBDA(cs) (((cs) & 0x7) == 7) -#define CST4330_OTP_PRESENT 0x00000010 -#define CST4330_LPO_AUTODET_EN 0x00000020 -#define CST4330_ARMREMAP_0 0x00000040 -#define CST4330_SPROM_PRESENT 0x00000080 -#define CST4330_ILPDIV_EN 0x00000100 -#define CST4330_LPO_SEL 0x00000200 -#define CST4330_RES_INIT_MODE_SHIFT 10 -#define CST4330_RES_INIT_MODE_MASK 0x00000c00 -#define CST4330_CBUCK_MODE_SHIFT 12 -#define CST4330_CBUCK_MODE_MASK 0x00003000 -#define CST4330_CBUCK_POWER_OK 0x00004000 -#define CST4330_BB_PLL_LOCKED 0x00008000 -#define SOCDEVRAM_4330_BP_ADDR 0x1E000000 -#define SOCDEVRAM_4330_ARM_ADDR 0x00800000 - - -#define PCTL_4330_SERIAL_ENAB (1 << 24) - - -#define CCTRL_4330_GPIO_SEL 0x00000001 -#define CCTRL_4330_ERCX_SEL 0x00000002 -#define CCTRL_4330_SDIO_HOST_WAKE 0x00000004 -#define CCTRL_4330_JTAG_DISABLE 0x00000008 - - -#define CCTRL_43239_GPIO_SEL 0x00000002 -#define CCTRL_43239_SDIO_HOST_WAKE 0x00000004 - -#define RES4313_BB_PU_RSRC 0 -#define RES4313_ILP_REQ_RSRC 1 -#define RES4313_XTAL_PU_RSRC 2 -#define RES4313_ALP_AVAIL_RSRC 3 -#define RES4313_RADIO_PU_RSRC 4 -#define RES4313_BG_PU_RSRC 5 -#define RES4313_VREG1P4_PU_RSRC 6 -#define RES4313_AFE_PWRSW_RSRC 7 -#define RES4313_RX_PWRSW_RSRC 8 -#define RES4313_TX_PWRSW_RSRC 9 -#define RES4313_BB_PWRSW_RSRC 10 -#define RES4313_SYNTH_PWRSW_RSRC 11 -#define RES4313_MISC_PWRSW_RSRC 12 -#define RES4313_BB_PLL_PWRSW_RSRC 13 -#define RES4313_HT_AVAIL_RSRC 14 -#define RES4313_MACPHY_CLK_AVAIL_RSRC 15 - - -#define CST4313_SPROM_PRESENT 1 -#define CST4313_OTP_PRESENT 2 -#define CST4313_SPROM_OTP_SEL_MASK 0x00000002 -#define CST4313_SPROM_OTP_SEL_SHIFT 0 - - -#define CCTRL_4313_12MA_LED_DRIVE 0x00000007 - - -#define RES43228_NOT_USED 0 -#define RES43228_ILP_REQUEST 1 -#define RES43228_XTAL_PU 2 -#define RES43228_ALP_AVAIL 3 -#define RES43228_PLL_EN 4 -#define RES43228_HT_PHY_AVAIL 5 - - -#define CST43228_ILP_DIV_EN 0x1 -#define CST43228_OTP_PRESENT 0x2 -#define CST43228_SERDES_REFCLK_PADSEL 0x4 -#define CST43228_SDIO_MODE 0x8 -#define CST43228_SDIO_OTP_PRESENT 0x10 -#define CST43228_SDIO_RESET 0x20 - - -#define PMU_MAX_TRANSITION_DLY 15000 - - -#define PMURES_UP_TRANSITION 2 - - - -#define SECI_MODE_UART 0x0 -#define SECI_MODE_SECI 0x1 -#define SECI_MODE_LEGACY_3WIRE_BT 0x2 -#define SECI_MODE_LEGACY_3WIRE_WLAN 0x3 -#define SECI_MODE_HALF_SECI 0x4 - -#define SECI_RESET (1 << 0) -#define SECI_RESET_BAR_UART (1 << 1) -#define SECI_ENAB_SECI_ECI (1 << 2) -#define SECI_ENAB_SECIOUT_DIS (1 << 3) -#define SECI_MODE_MASK 0x7 -#define SECI_MODE_SHIFT 4 -#define SECI_UPD_SECI (1 << 7) - -#define SECI_SLIP_ESC_CHAR 0xDB -#define SECI_SIGNOFF_0 SECI_SLIP_ESC_CHAR -#define SECI_SIGNOFF_1 0 -#define SECI_REFRESH_REQ 0xDA - - -#define CLKCTL_STS_SECI_CLK_REQ (1 << 8) -#define CLKCTL_STS_SECI_CLK_AVAIL (1 << 24) - -#define SECI_UART_MSR_CTS_STATE (1 << 0) -#define SECI_UART_MSR_RTS_STATE (1 << 1) -#define SECI_UART_SECI_IN_STATE (1 << 2) -#define SECI_UART_SECI_IN2_STATE (1 << 3) - - -#define SECI_UART_LCR_STOP_BITS (1 << 0) -#define SECI_UART_LCR_PARITY_EN (1 << 1) -#define SECI_UART_LCR_PARITY (1 << 2) -#define SECI_UART_LCR_RX_EN (1 << 3) -#define SECI_UART_LCR_LBRK_CTRL (1 << 4) -#define SECI_UART_LCR_TXO_EN (1 << 5) -#define SECI_UART_LCR_RTSO_EN (1 << 6) -#define SECI_UART_LCR_SLIPMODE_EN (1 << 7) -#define SECI_UART_LCR_RXCRC_CHK (1 << 8) -#define SECI_UART_LCR_TXCRC_INV (1 << 9) -#define SECI_UART_LCR_TXCRC_LSBF (1 << 10) -#define SECI_UART_LCR_TXCRC_EN (1 << 11) - -#define SECI_UART_MCR_TX_EN (1 << 0) -#define SECI_UART_MCR_PRTS (1 << 1) -#define SECI_UART_MCR_SWFLCTRL_EN (1 << 2) -#define SECI_UART_MCR_HIGHRATE_EN (1 << 3) -#define SECI_UART_MCR_LOOPBK_EN (1 << 4) -#define SECI_UART_MCR_AUTO_RTS (1 << 5) -#define SECI_UART_MCR_AUTO_TX_DIS (1 << 6) -#define SECI_UART_MCR_BAUD_ADJ_EN (1 << 7) -#define SECI_UART_MCR_XONOFF_RPT (1 << 9) - - - - -#define ECI_BW_20 0x0 -#define ECI_BW_25 0x1 -#define ECI_BW_30 0x2 -#define ECI_BW_35 0x3 -#define ECI_BW_40 0x4 -#define ECI_BW_45 0x5 -#define ECI_BW_50 0x6 -#define ECI_BW_ALL 0x7 - - -#define WLAN_NUM_ANT1 TXANT_0 -#define WLAN_NUM_ANT2 TXANT_1 - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/sbconfig.h b/drivers/net/wireless/bcmdhd/include/sbconfig.h deleted file mode 100644 index f45351a586cb..000000000000 --- a/drivers/net/wireless/bcmdhd/include/sbconfig.h +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Broadcom SiliconBackplane hardware register definitions. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sbconfig.h 277737 2011-08-16 17:54:59Z $ - */ - - -#ifndef _SBCONFIG_H -#define _SBCONFIG_H - - -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif - - -#define SB_BUS_SIZE 0x10000 -#define SB_BUS_BASE(b) (SI_ENUM_BASE + (b) * SB_BUS_SIZE) -#define SB_BUS_MAXCORES (SB_BUS_SIZE / SI_CORE_SIZE) - - -#define SBCONFIGOFF 0xf00 -#define SBCONFIGSIZE 256 - -#define SBIPSFLAG 0x08 -#define SBTPSFLAG 0x18 -#define SBTMERRLOGA 0x48 -#define SBTMERRLOG 0x50 -#define SBADMATCH3 0x60 -#define SBADMATCH2 0x68 -#define SBADMATCH1 0x70 -#define SBIMSTATE 0x90 -#define SBINTVEC 0x94 -#define SBTMSTATELOW 0x98 -#define SBTMSTATEHIGH 0x9c -#define SBBWA0 0xa0 -#define SBIMCONFIGLOW 0xa8 -#define SBIMCONFIGHIGH 0xac -#define SBADMATCH0 0xb0 -#define SBTMCONFIGLOW 0xb8 -#define SBTMCONFIGHIGH 0xbc -#define SBBCONFIG 0xc0 -#define SBBSTATE 0xc8 -#define SBACTCNFG 0xd8 -#define SBFLAGST 0xe8 -#define SBIDLOW 0xf8 -#define SBIDHIGH 0xfc - - - -#define SBIMERRLOGA 0xea8 -#define SBIMERRLOG 0xeb0 -#define SBTMPORTCONNID0 0xed8 -#define SBTMPORTLOCK0 0xef8 - -#ifndef _LANGUAGE_ASSEMBLY - -typedef volatile struct _sbconfig { - uint32 PAD[2]; - uint32 sbipsflag; - uint32 PAD[3]; - uint32 sbtpsflag; - uint32 PAD[11]; - uint32 sbtmerrloga; - uint32 PAD; - uint32 sbtmerrlog; - uint32 PAD[3]; - uint32 sbadmatch3; - uint32 PAD; - uint32 sbadmatch2; - uint32 PAD; - uint32 sbadmatch1; - uint32 PAD[7]; - uint32 sbimstate; - uint32 sbintvec; - uint32 sbtmstatelow; - uint32 sbtmstatehigh; - uint32 sbbwa0; - uint32 PAD; - uint32 sbimconfiglow; - uint32 sbimconfighigh; - uint32 sbadmatch0; - uint32 PAD; - uint32 sbtmconfiglow; - uint32 sbtmconfighigh; - uint32 sbbconfig; - uint32 PAD; - uint32 sbbstate; - uint32 PAD[3]; - uint32 sbactcnfg; - uint32 PAD[3]; - uint32 sbflagst; - uint32 PAD[3]; - uint32 sbidlow; - uint32 sbidhigh; -} sbconfig_t; - -#endif - - -#define SBIPS_INT1_MASK 0x3f -#define SBIPS_INT1_SHIFT 0 -#define SBIPS_INT2_MASK 0x3f00 -#define SBIPS_INT2_SHIFT 8 -#define SBIPS_INT3_MASK 0x3f0000 -#define SBIPS_INT3_SHIFT 16 -#define SBIPS_INT4_MASK 0x3f000000 -#define SBIPS_INT4_SHIFT 24 - - -#define SBTPS_NUM0_MASK 0x3f -#define SBTPS_F0EN0 0x40 - - -#define SBTMEL_CM 0x00000007 -#define SBTMEL_CI 0x0000ff00 -#define SBTMEL_EC 0x0f000000 -#define SBTMEL_ME 0x80000000 - - -#define SBIM_PC 0xf -#define SBIM_AP_MASK 0x30 -#define SBIM_AP_BOTH 0x00 -#define SBIM_AP_TS 0x10 -#define SBIM_AP_TK 0x20 -#define SBIM_AP_RSV 0x30 -#define SBIM_IBE 0x20000 -#define SBIM_TO 0x40000 -#define SBIM_BY 0x01800000 -#define SBIM_RJ 0x02000000 - - -#define SBTML_RESET 0x0001 -#define SBTML_REJ_MASK 0x0006 -#define SBTML_REJ 0x0002 -#define SBTML_TMPREJ 0x0004 - -#define SBTML_SICF_SHIFT 16 - - -#define SBTMH_SERR 0x0001 -#define SBTMH_INT 0x0002 -#define SBTMH_BUSY 0x0004 -#define SBTMH_TO 0x0020 - -#define SBTMH_SISF_SHIFT 16 - - -#define SBBWA_TAB0_MASK 0xffff -#define SBBWA_TAB1_MASK 0xffff -#define SBBWA_TAB1_SHIFT 16 - - -#define SBIMCL_STO_MASK 0x7 -#define SBIMCL_RTO_MASK 0x70 -#define SBIMCL_RTO_SHIFT 4 -#define SBIMCL_CID_MASK 0xff0000 -#define SBIMCL_CID_SHIFT 16 - - -#define SBIMCH_IEM_MASK 0xc -#define SBIMCH_TEM_MASK 0x30 -#define SBIMCH_TEM_SHIFT 4 -#define SBIMCH_BEM_MASK 0xc0 -#define SBIMCH_BEM_SHIFT 6 - - -#define SBAM_TYPE_MASK 0x3 -#define SBAM_AD64 0x4 -#define SBAM_ADINT0_MASK 0xf8 -#define SBAM_ADINT0_SHIFT 3 -#define SBAM_ADINT1_MASK 0x1f8 -#define SBAM_ADINT1_SHIFT 3 -#define SBAM_ADINT2_MASK 0x1f8 -#define SBAM_ADINT2_SHIFT 3 -#define SBAM_ADEN 0x400 -#define SBAM_ADNEG 0x800 -#define SBAM_BASE0_MASK 0xffffff00 -#define SBAM_BASE0_SHIFT 8 -#define SBAM_BASE1_MASK 0xfffff000 -#define SBAM_BASE1_SHIFT 12 -#define SBAM_BASE2_MASK 0xffff0000 -#define SBAM_BASE2_SHIFT 16 - - -#define SBTMCL_CD_MASK 0xff -#define SBTMCL_CO_MASK 0xf800 -#define SBTMCL_CO_SHIFT 11 -#define SBTMCL_IF_MASK 0xfc0000 -#define SBTMCL_IF_SHIFT 18 -#define SBTMCL_IM_MASK 0x3000000 -#define SBTMCL_IM_SHIFT 24 - - -#define SBTMCH_BM_MASK 0x3 -#define SBTMCH_RM_MASK 0x3 -#define SBTMCH_RM_SHIFT 2 -#define SBTMCH_SM_MASK 0x30 -#define SBTMCH_SM_SHIFT 4 -#define SBTMCH_EM_MASK 0x300 -#define SBTMCH_EM_SHIFT 8 -#define SBTMCH_IM_MASK 0xc00 -#define SBTMCH_IM_SHIFT 10 - - -#define SBBC_LAT_MASK 0x3 -#define SBBC_MAX0_MASK 0xf0000 -#define SBBC_MAX0_SHIFT 16 -#define SBBC_MAX1_MASK 0xf00000 -#define SBBC_MAX1_SHIFT 20 - - -#define SBBS_SRD 0x1 -#define SBBS_HRD 0x2 - - -#define SBIDL_CS_MASK 0x3 -#define SBIDL_AR_MASK 0x38 -#define SBIDL_AR_SHIFT 3 -#define SBIDL_SYNCH 0x40 -#define SBIDL_INIT 0x80 -#define SBIDL_MINLAT_MASK 0xf00 -#define SBIDL_MINLAT_SHIFT 8 -#define SBIDL_MAXLAT 0xf000 -#define SBIDL_MAXLAT_SHIFT 12 -#define SBIDL_FIRST 0x10000 -#define SBIDL_CW_MASK 0xc0000 -#define SBIDL_CW_SHIFT 18 -#define SBIDL_TP_MASK 0xf00000 -#define SBIDL_TP_SHIFT 20 -#define SBIDL_IP_MASK 0xf000000 -#define SBIDL_IP_SHIFT 24 -#define SBIDL_RV_MASK 0xf0000000 -#define SBIDL_RV_SHIFT 28 -#define SBIDL_RV_2_2 0x00000000 -#define SBIDL_RV_2_3 0x10000000 - - -#define SBIDH_RC_MASK 0x000f -#define SBIDH_RCE_MASK 0x7000 -#define SBIDH_RCE_SHIFT 8 -#define SBCOREREV(sbidh) \ - ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK)) -#define SBIDH_CC_MASK 0x8ff0 -#define SBIDH_CC_SHIFT 4 -#define SBIDH_VC_MASK 0xffff0000 -#define SBIDH_VC_SHIFT 16 - -#define SB_COMMIT 0xfd8 - - -#define SB_VEND_BCM 0x4243 - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/sbhnddma.h b/drivers/net/wireless/bcmdhd/include/sbhnddma.h deleted file mode 100644 index 77c413f75f0d..000000000000 --- a/drivers/net/wireless/bcmdhd/include/sbhnddma.h +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Generic Broadcom Home Networking Division (HND) DMA engine HW interface - * This supports the following chips: BCM42xx, 44xx, 47xx . - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sbhnddma.h 278779 2011-08-19 22:07:18Z $ - */ - - -#ifndef _sbhnddma_h_ -#define _sbhnddma_h_ - - - - - - - -typedef volatile struct { - uint32 control; - uint32 addr; - uint32 ptr; - uint32 status; -} dma32regs_t; - -typedef volatile struct { - dma32regs_t xmt; - dma32regs_t rcv; -} dma32regp_t; - -typedef volatile struct { - uint32 fifoaddr; - uint32 fifodatalow; - uint32 fifodatahigh; - uint32 pad; -} dma32diag_t; - - -typedef volatile struct { - uint32 ctrl; - uint32 addr; -} dma32dd_t; - - -#define D32RINGALIGN_BITS 12 -#define D32MAXRINGSZ (1 << D32RINGALIGN_BITS) -#define D32RINGALIGN (1 << D32RINGALIGN_BITS) - -#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t)) - - -#define XC_XE ((uint32)1 << 0) -#define XC_SE ((uint32)1 << 1) -#define XC_LE ((uint32)1 << 2) -#define XC_FL ((uint32)1 << 4) -#define XC_PD ((uint32)1 << 11) -#define XC_AE ((uint32)3 << 16) -#define XC_AE_SHIFT 16 -#define XC_BL_MASK 0x001C0000 -#define XC_BL_SHIFT 18 - - -#define XP_LD_MASK 0xfff - - -#define XS_CD_MASK 0x0fff -#define XS_XS_MASK 0xf000 -#define XS_XS_SHIFT 12 -#define XS_XS_DISABLED 0x0000 -#define XS_XS_ACTIVE 0x1000 -#define XS_XS_IDLE 0x2000 -#define XS_XS_STOPPED 0x3000 -#define XS_XS_SUSP 0x4000 -#define XS_XE_MASK 0xf0000 -#define XS_XE_SHIFT 16 -#define XS_XE_NOERR 0x00000 -#define XS_XE_DPE 0x10000 -#define XS_XE_DFU 0x20000 -#define XS_XE_BEBR 0x30000 -#define XS_XE_BEDA 0x40000 -#define XS_AD_MASK 0xfff00000 -#define XS_AD_SHIFT 20 - - -#define RC_RE ((uint32)1 << 0) -#define RC_RO_MASK 0xfe -#define RC_RO_SHIFT 1 -#define RC_FM ((uint32)1 << 8) -#define RC_SH ((uint32)1 << 9) -#define RC_OC ((uint32)1 << 10) -#define RC_PD ((uint32)1 << 11) -#define RC_AE ((uint32)3 << 16) -#define RC_AE_SHIFT 16 -#define RC_BL_MASK 0x001C0000 -#define RC_BL_SHIFT 18 - - -#define RP_LD_MASK 0xfff - - -#define RS_CD_MASK 0x0fff -#define RS_RS_MASK 0xf000 -#define RS_RS_SHIFT 12 -#define RS_RS_DISABLED 0x0000 -#define RS_RS_ACTIVE 0x1000 -#define RS_RS_IDLE 0x2000 -#define RS_RS_STOPPED 0x3000 -#define RS_RE_MASK 0xf0000 -#define RS_RE_SHIFT 16 -#define RS_RE_NOERR 0x00000 -#define RS_RE_DPE 0x10000 -#define RS_RE_DFO 0x20000 -#define RS_RE_BEBW 0x30000 -#define RS_RE_BEDA 0x40000 -#define RS_AD_MASK 0xfff00000 -#define RS_AD_SHIFT 20 - - -#define FA_OFF_MASK 0xffff -#define FA_SEL_MASK 0xf0000 -#define FA_SEL_SHIFT 16 -#define FA_SEL_XDD 0x00000 -#define FA_SEL_XDP 0x10000 -#define FA_SEL_RDD 0x40000 -#define FA_SEL_RDP 0x50000 -#define FA_SEL_XFD 0x80000 -#define FA_SEL_XFP 0x90000 -#define FA_SEL_RFD 0xc0000 -#define FA_SEL_RFP 0xd0000 -#define FA_SEL_RSD 0xe0000 -#define FA_SEL_RSP 0xf0000 - - -#define CTRL_BC_MASK 0x00001fff -#define CTRL_AE ((uint32)3 << 16) -#define CTRL_AE_SHIFT 16 -#define CTRL_PARITY ((uint32)3 << 18) -#define CTRL_EOT ((uint32)1 << 28) -#define CTRL_IOC ((uint32)1 << 29) -#define CTRL_EOF ((uint32)1 << 30) -#define CTRL_SOF ((uint32)1 << 31) - - -#define CTRL_CORE_MASK 0x0ff00000 - - - - -typedef volatile struct { - uint32 control; - uint32 ptr; - uint32 addrlow; - uint32 addrhigh; - uint32 status0; - uint32 status1; -} dma64regs_t; - -typedef volatile struct { - dma64regs_t tx; - dma64regs_t rx; -} dma64regp_t; - -typedef volatile struct { - uint32 fifoaddr; - uint32 fifodatalow; - uint32 fifodatahigh; - uint32 pad; -} dma64diag_t; - - -typedef volatile struct { - uint32 ctrl1; - uint32 ctrl2; - uint32 addrlow; - uint32 addrhigh; -} dma64dd_t; - - -#define D64RINGALIGN_BITS 13 -#define D64MAXRINGSZ (1 << D64RINGALIGN_BITS) -#define D64RINGALIGN (1 << D64RINGALIGN_BITS) - -#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) - - -#define D64_DEF_USBBURSTLEN 2 -#define D64_DEF_SDIOBURSTLEN 1 - - -#define D64_XC_XE 0x00000001 -#define D64_XC_SE 0x00000002 -#define D64_XC_LE 0x00000004 -#define D64_XC_FL 0x00000010 -#define D64_XC_PD 0x00000800 -#define D64_XC_AE 0x00030000 -#define D64_XC_AE_SHIFT 16 -#define D64_XC_BL_MASK 0x001C0000 -#define D64_XC_BL_SHIFT 18 - - -#define D64_XP_LD_MASK 0x00001fff - - -#define D64_XS0_CD_MASK 0x00001fff -#define D64_XS0_XS_MASK 0xf0000000 -#define D64_XS0_XS_SHIFT 28 -#define D64_XS0_XS_DISABLED 0x00000000 -#define D64_XS0_XS_ACTIVE 0x10000000 -#define D64_XS0_XS_IDLE 0x20000000 -#define D64_XS0_XS_STOPPED 0x30000000 -#define D64_XS0_XS_SUSP 0x40000000 - -#define D64_XS1_AD_MASK 0x00001fff -#define D64_XS1_XE_MASK 0xf0000000 -#define D64_XS1_XE_SHIFT 28 -#define D64_XS1_XE_NOERR 0x00000000 -#define D64_XS1_XE_DPE 0x10000000 -#define D64_XS1_XE_DFU 0x20000000 -#define D64_XS1_XE_DTE 0x30000000 -#define D64_XS1_XE_DESRE 0x40000000 -#define D64_XS1_XE_COREE 0x50000000 - - -#define D64_RC_RE 0x00000001 -#define D64_RC_RO_MASK 0x000000fe -#define D64_RC_RO_SHIFT 1 -#define D64_RC_FM 0x00000100 -#define D64_RC_SH 0x00000200 -#define D64_RC_OC 0x00000400 -#define D64_RC_PD 0x00000800 -#define D64_RC_AE 0x00030000 -#define D64_RC_AE_SHIFT 16 -#define D64_RC_BL_MASK 0x001C0000 -#define D64_RC_BL_SHIFT 18 - - -#define DMA_CTRL_PEN (1 << 0) -#define DMA_CTRL_ROC (1 << 1) -#define DMA_CTRL_RXMULTI (1 << 2) -#define DMA_CTRL_UNFRAMED (1 << 3) -#define DMA_CTRL_USB_BOUNDRY4KB_WAR (1 << 4) - - -#define D64_RP_LD_MASK 0x00001fff - - -#define D64_RS0_CD_MASK 0x00001fff -#define D64_RS0_RS_MASK 0xf0000000 -#define D64_RS0_RS_SHIFT 28 -#define D64_RS0_RS_DISABLED 0x00000000 -#define D64_RS0_RS_ACTIVE 0x10000000 -#define D64_RS0_RS_IDLE 0x20000000 -#define D64_RS0_RS_STOPPED 0x30000000 -#define D64_RS0_RS_SUSP 0x40000000 - -#define D64_RS1_AD_MASK 0x0001ffff -#define D64_RS1_RE_MASK 0xf0000000 -#define D64_RS1_RE_SHIFT 28 -#define D64_RS1_RE_NOERR 0x00000000 -#define D64_RS1_RE_DPO 0x10000000 -#define D64_RS1_RE_DFU 0x20000000 -#define D64_RS1_RE_DTE 0x30000000 -#define D64_RS1_RE_DESRE 0x40000000 -#define D64_RS1_RE_COREE 0x50000000 - - -#define D64_FA_OFF_MASK 0xffff -#define D64_FA_SEL_MASK 0xf0000 -#define D64_FA_SEL_SHIFT 16 -#define D64_FA_SEL_XDD 0x00000 -#define D64_FA_SEL_XDP 0x10000 -#define D64_FA_SEL_RDD 0x40000 -#define D64_FA_SEL_RDP 0x50000 -#define D64_FA_SEL_XFD 0x80000 -#define D64_FA_SEL_XFP 0x90000 -#define D64_FA_SEL_RFD 0xc0000 -#define D64_FA_SEL_RFP 0xd0000 -#define D64_FA_SEL_RSD 0xe0000 -#define D64_FA_SEL_RSP 0xf0000 - - -#define D64_CTRL_COREFLAGS 0x0ff00000 -#define D64_CTRL1_EOT ((uint32)1 << 28) -#define D64_CTRL1_IOC ((uint32)1 << 29) -#define D64_CTRL1_EOF ((uint32)1 << 30) -#define D64_CTRL1_SOF ((uint32)1 << 31) - - -#define D64_CTRL2_BC_MASK 0x00007fff -#define D64_CTRL2_AE 0x00030000 -#define D64_CTRL2_AE_SHIFT 16 -#define D64_CTRL2_PARITY 0x00040000 - - -#define D64_CTRL_CORE_MASK 0x0ff00000 - -#define D64_RX_FRM_STS_LEN 0x0000ffff -#define D64_RX_FRM_STS_OVFL 0x00800000 -#define D64_RX_FRM_STS_DSCRCNT 0x0f000000 -#define D64_RX_FRM_STS_DATATYPE 0xf0000000 - - -typedef volatile struct { - uint16 len; - uint16 flags; -} dma_rxh_t; - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/sbpcmcia.h b/drivers/net/wireless/bcmdhd/include/sbpcmcia.h deleted file mode 100644 index d84f69ab5617..000000000000 --- a/drivers/net/wireless/bcmdhd/include/sbpcmcia.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sbpcmcia.h 277737 2011-08-16 17:54:59Z $ - */ - - -#ifndef _SBPCMCIA_H -#define _SBPCMCIA_H - - - - -#define PCMCIA_FCR (0x700 / 2) - -#define FCR0_OFF 0 -#define FCR1_OFF (0x40 / 2) -#define FCR2_OFF (0x80 / 2) -#define FCR3_OFF (0xc0 / 2) - -#define PCMCIA_FCR0 (0x700 / 2) -#define PCMCIA_FCR1 (0x740 / 2) -#define PCMCIA_FCR2 (0x780 / 2) -#define PCMCIA_FCR3 (0x7c0 / 2) - - - -#define PCMCIA_COR 0 - -#define COR_RST 0x80 -#define COR_LEV 0x40 -#define COR_IRQEN 0x04 -#define COR_BLREN 0x01 -#define COR_FUNEN 0x01 - - -#define PCICIA_FCSR (2 / 2) -#define PCICIA_PRR (4 / 2) -#define PCICIA_SCR (6 / 2) -#define PCICIA_ESR (8 / 2) - - -#define PCM_MEMOFF 0x0000 -#define F0_MEMOFF 0x1000 -#define F1_MEMOFF 0x2000 -#define F2_MEMOFF 0x3000 -#define F3_MEMOFF 0x4000 - - -#define MEM_ADDR0 (0x728 / 2) -#define MEM_ADDR1 (0x72a / 2) -#define MEM_ADDR2 (0x72c / 2) - - -#define PCMCIA_ADDR0 (0x072e / 2) -#define PCMCIA_ADDR1 (0x0730 / 2) -#define PCMCIA_ADDR2 (0x0732 / 2) - -#define MEM_SEG (0x0734 / 2) -#define SROM_CS (0x0736 / 2) -#define SROM_DATAL (0x0738 / 2) -#define SROM_DATAH (0x073a / 2) -#define SROM_ADDRL (0x073c / 2) -#define SROM_ADDRH (0x073e / 2) -#define SROM_INFO2 (0x0772 / 2) -#define SROM_INFO (0x07be / 2) - - -#define SROM_IDLE 0 -#define SROM_WRITE 1 -#define SROM_READ 2 -#define SROM_WEN 4 -#define SROM_WDS 7 -#define SROM_DONE 8 - - -#define SRI_SZ_MASK 0x03 -#define SRI_BLANK 0x04 -#define SRI_OTP 0x80 - - - -#define SBTML_INT_ACK 0x40000 -#define SBTML_INT_EN 0x20000 - - -#define SBTMH_INT_STATUS 0x40000 - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/sbsdio.h b/drivers/net/wireless/bcmdhd/include/sbsdio.h deleted file mode 100644 index 7aaeb73f0100..000000000000 --- a/drivers/net/wireless/bcmdhd/include/sbsdio.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * SDIO device core hardware definitions. - * sdio is a portion of the pcmcia core in core rev 3 - rev 8 - * - * SDIO core support 1bit, 4 bit SDIO mode as well as SPI mode. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sbsdio.h 277737 2011-08-16 17:54:59Z $ - */ - -#ifndef _SBSDIO_H -#define _SBSDIO_H - -#define SBSDIO_NUM_FUNCTION 3 /* as of sdiod rev 0, supports 3 functions */ - -/* function 1 miscellaneous registers */ -#define SBSDIO_SPROM_CS 0x10000 /* sprom command and status */ -#define SBSDIO_SPROM_INFO 0x10001 /* sprom info register */ -#define SBSDIO_SPROM_DATA_LOW 0x10002 /* sprom indirect access data byte 0 */ -#define SBSDIO_SPROM_DATA_HIGH 0x10003 /* sprom indirect access data byte 1 */ -#define SBSDIO_SPROM_ADDR_LOW 0x10004 /* sprom indirect access addr byte 0 */ -#define SBSDIO_SPROM_ADDR_HIGH 0x10005 /* sprom indirect access addr byte 0 */ -#define SBSDIO_CHIP_CTRL_DATA 0x10006 /* xtal_pu (gpio) output */ -#define SBSDIO_CHIP_CTRL_EN 0x10007 /* xtal_pu (gpio) enable */ -#define SBSDIO_WATERMARK 0x10008 /* rev < 7, watermark for sdio device */ -#define SBSDIO_DEVICE_CTL 0x10009 /* control busy signal generation */ - -/* registers introduced in rev 8, some content (mask/bits) defs in sbsdpcmdev.h */ -#define SBSDIO_FUNC1_SBADDRLOW 0x1000A /* SB Address Window Low (b15) */ -#define SBSDIO_FUNC1_SBADDRMID 0x1000B /* SB Address Window Mid (b23:b16) */ -#define SBSDIO_FUNC1_SBADDRHIGH 0x1000C /* SB Address Window High (b31:b24) */ -#define SBSDIO_FUNC1_FRAMECTRL 0x1000D /* Frame Control (frame term/abort) */ -#define SBSDIO_FUNC1_CHIPCLKCSR 0x1000E /* ChipClockCSR (ALP/HT ctl/status) */ -#define SBSDIO_FUNC1_SDIOPULLUP 0x1000F /* SdioPullUp (on cmd, d0-d2) */ -#define SBSDIO_FUNC1_WFRAMEBCLO 0x10019 /* Write Frame Byte Count Low */ -#define SBSDIO_FUNC1_WFRAMEBCHI 0x1001A /* Write Frame Byte Count High */ -#define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B /* Read Frame Byte Count Low */ -#define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C /* Read Frame Byte Count High */ - -#define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */ -#define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001C /* f1 misc register end */ - -/* SBSDIO_SPROM_CS */ -#define SBSDIO_SPROM_IDLE 0 -#define SBSDIO_SPROM_WRITE 1 -#define SBSDIO_SPROM_READ 2 -#define SBSDIO_SPROM_WEN 4 -#define SBSDIO_SPROM_WDS 7 -#define SBSDIO_SPROM_DONE 8 - -/* SBSDIO_SPROM_INFO */ -#define SROM_SZ_MASK 0x03 /* SROM size, 1: 4k, 2: 16k */ -#define SROM_BLANK 0x04 /* depreciated in corerev 6 */ -#define SROM_OTP 0x80 /* OTP present */ - -/* SBSDIO_CHIP_CTRL */ -#define SBSDIO_CHIP_CTRL_XTAL 0x01 /* or'd with onchip xtal_pu, - * 1: power on oscillator - * (for 4318 only) - */ -/* SBSDIO_WATERMARK */ -#define SBSDIO_WATERMARK_MASK 0x7f /* number of words - 1 for sd device - * to wait before sending data to host - */ - -/* SBSDIO_DEVICE_CTL */ -#define SBSDIO_DEVCTL_SETBUSY 0x01 /* 1: device will assert busy signal when - * receiving CMD53 - */ -#define SBSDIO_DEVCTL_SPI_INTR_SYNC 0x02 /* 1: assertion of sdio interrupt is - * synchronous to the sdio clock - */ -#define SBSDIO_DEVCTL_CA_INT_ONLY 0x04 /* 1: mask all interrupts to host - * except the chipActive (rev 8) - */ -#define SBSDIO_DEVCTL_PADS_ISO 0x08 /* 1: isolate internal sdio signals, put - * external pads in tri-state; requires - * sdio bus power cycle to clear (rev 9) - */ -#define SBSDIO_DEVCTL_SB_RST_CTL 0x30 /* Force SD->SB reset mapping (rev 11) */ -#define SBSDIO_DEVCTL_RST_CORECTL 0x00 /* Determined by CoreControl bit */ -#define SBSDIO_DEVCTL_RST_BPRESET 0x10 /* Force backplane reset */ -#define SBSDIO_DEVCTL_RST_NOBPRESET 0x20 /* Force no backplane reset */ - - -/* SBSDIO_FUNC1_CHIPCLKCSR */ -#define SBSDIO_FORCE_ALP 0x01 /* Force ALP request to backplane */ -#define SBSDIO_FORCE_HT 0x02 /* Force HT request to backplane */ -#define SBSDIO_FORCE_ILP 0x04 /* Force ILP request to backplane */ -#define SBSDIO_ALP_AVAIL_REQ 0x08 /* Make ALP ready (power up xtal) */ -#define SBSDIO_HT_AVAIL_REQ 0x10 /* Make HT ready (power up PLL) */ -#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20 /* Squelch clock requests from HW */ -#define SBSDIO_ALP_AVAIL 0x40 /* Status: ALP is ready */ -#define SBSDIO_HT_AVAIL 0x80 /* Status: HT is ready */ -/* In rev8, actual avail bits followed original docs */ -#define SBSDIO_Rev8_HT_AVAIL 0x40 -#define SBSDIO_Rev8_ALP_AVAIL 0x80 - -#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL) -#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS) -#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS) -#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval)) -#define SBSDIO_CLKAV(regval, alponly) (SBSDIO_ALPAV(regval) && \ - (alponly ? 1 : SBSDIO_HTAV(regval))) - -/* SBSDIO_FUNC1_SDIOPULLUP */ -#define SBSDIO_PULLUP_D0 0x01 /* Enable D0/MISO pullup */ -#define SBSDIO_PULLUP_D1 0x02 /* Enable D1/INT# pullup */ -#define SBSDIO_PULLUP_D2 0x04 /* Enable D2 pullup */ -#define SBSDIO_PULLUP_CMD 0x08 /* Enable CMD/MOSI pullup */ -#define SBSDIO_PULLUP_ALL 0x0f /* All valid bits */ - -/* function 1 OCP space */ -#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF /* sb offset addr is <= 15 bits, 32k */ -#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000 -#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 /* with b15, maps to 32-bit SB access */ - -/* some duplication with sbsdpcmdev.h here */ -/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */ -#define SBSDIO_SBADDRLOW_MASK 0x80 /* Valid bits in SBADDRLOW */ -#define SBSDIO_SBADDRMID_MASK 0xff /* Valid bits in SBADDRMID */ -#define SBSDIO_SBADDRHIGH_MASK 0xffU /* Valid bits in SBADDRHIGH */ -#define SBSDIO_SBWINDOW_MASK 0xffff8000 /* Address bits from SBADDR regs */ - -/* direct(mapped) cis space */ -#define SBSDIO_CIS_BASE_COMMON 0x1000 /* MAPPED common CIS address */ -#define SBSDIO_CIS_SIZE_LIMIT 0x200 /* maximum bytes in one CIS */ -#define SBSDIO_OTP_CIS_SIZE_LIMIT 0x078 /* maximum bytes OTP CIS */ - -#define SBSDIO_CIS_OFT_ADDR_MASK 0x1FFFF /* cis offset addr is < 17 bits */ - -#define SBSDIO_CIS_MANFID_TUPLE_LEN 6 /* manfid tuple length, include tuple, - * link bytes - */ - -/* indirect cis access (in sprom) */ -#define SBSDIO_SPROM_CIS_OFFSET 0x8 /* 8 control bytes first, CIS starts from - * 8th byte - */ - -#define SBSDIO_BYTEMODE_DATALEN_MAX 64 /* sdio byte mode: maximum length of one - * data comamnd - */ - -#define SBSDIO_CORE_ADDR_MASK 0x1FFFF /* sdio core function one address mask */ - -#endif /* _SBSDIO_H */ diff --git a/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h b/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h deleted file mode 100644 index e5176483e9a1..000000000000 --- a/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Broadcom SiliconBackplane SDIO/PCMCIA hardware-specific - * device core support - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sbsdpcmdev.h 282638 2011-09-08 21:18:10Z $ - */ - -#ifndef _sbsdpcmdev_h_ -#define _sbsdpcmdev_h_ - -/* cpp contortions to concatenate w/arg prescan */ -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif /* PAD */ - - -typedef volatile struct { - dma64regs_t xmt; /* dma tx */ - uint32 PAD[2]; - dma64regs_t rcv; /* dma rx */ - uint32 PAD[2]; -} dma64p_t; - -/* dma64 sdiod corerev >= 1 */ -typedef volatile struct { - dma64p_t dma64regs[2]; - dma64diag_t dmafifo; /* DMA Diagnostic Regs, 0x280-0x28c */ - uint32 PAD[92]; -} sdiodma64_t; - -/* dma32 sdiod corerev == 0 */ -typedef volatile struct { - dma32regp_t dma32regs[2]; /* dma tx & rx, 0x200-0x23c */ - dma32diag_t dmafifo; /* DMA Diagnostic Regs, 0x240-0x24c */ - uint32 PAD[108]; -} sdiodma32_t; - -/* dma32 regs for pcmcia core */ -typedef volatile struct { - dma32regp_t dmaregs; /* DMA Regs, 0x200-0x21c, rev8 */ - dma32diag_t dmafifo; /* DMA Diagnostic Regs, 0x220-0x22c */ - uint32 PAD[116]; -} pcmdma32_t; - -/* core registers */ -typedef volatile struct { - uint32 corecontrol; /* CoreControl, 0x000, rev8 */ - uint32 corestatus; /* CoreStatus, 0x004, rev8 */ - uint32 PAD[1]; - uint32 biststatus; /* BistStatus, 0x00c, rev8 */ - - /* PCMCIA access */ - uint16 pcmciamesportaladdr; /* PcmciaMesPortalAddr, 0x010, rev8 */ - uint16 PAD[1]; - uint16 pcmciamesportalmask; /* PcmciaMesPortalMask, 0x014, rev8 */ - uint16 PAD[1]; - uint16 pcmciawrframebc; /* PcmciaWrFrameBC, 0x018, rev8 */ - uint16 PAD[1]; - uint16 pcmciaunderflowtimer; /* PcmciaUnderflowTimer, 0x01c, rev8 */ - uint16 PAD[1]; - - /* interrupt */ - uint32 intstatus; /* IntStatus, 0x020, rev8 */ - uint32 hostintmask; /* IntHostMask, 0x024, rev8 */ - uint32 intmask; /* IntSbMask, 0x028, rev8 */ - uint32 sbintstatus; /* SBIntStatus, 0x02c, rev8 */ - uint32 sbintmask; /* SBIntMask, 0x030, rev8 */ - uint32 funcintmask; /* SDIO Function Interrupt Mask, SDIO rev4 */ - uint32 PAD[2]; - uint32 tosbmailbox; /* ToSBMailbox, 0x040, rev8 */ - uint32 tohostmailbox; /* ToHostMailbox, 0x044, rev8 */ - uint32 tosbmailboxdata; /* ToSbMailboxData, 0x048, rev8 */ - uint32 tohostmailboxdata; /* ToHostMailboxData, 0x04c, rev8 */ - - /* synchronized access to registers in SDIO clock domain */ - uint32 sdioaccess; /* SdioAccess, 0x050, rev8 */ - uint32 PAD[3]; - - /* PCMCIA frame control */ - uint8 pcmciaframectrl; /* pcmciaFrameCtrl, 0x060, rev8 */ - uint8 PAD[3]; - uint8 pcmciawatermark; /* pcmciaWaterMark, 0x064, rev8 */ - uint8 PAD[155]; - - /* interrupt batching control */ - uint32 intrcvlazy; /* IntRcvLazy, 0x100, rev8 */ - uint32 PAD[3]; - - /* counters */ - uint32 cmd52rd; /* Cmd52RdCount, 0x110, rev8, SDIO: cmd52 reads */ - uint32 cmd52wr; /* Cmd52WrCount, 0x114, rev8, SDIO: cmd52 writes */ - uint32 cmd53rd; /* Cmd53RdCount, 0x118, rev8, SDIO: cmd53 reads */ - uint32 cmd53wr; /* Cmd53WrCount, 0x11c, rev8, SDIO: cmd53 writes */ - uint32 abort; /* AbortCount, 0x120, rev8, SDIO: aborts */ - uint32 datacrcerror; /* DataCrcErrorCount, 0x124, rev8, SDIO: frames w/bad CRC */ - uint32 rdoutofsync; /* RdOutOfSyncCount, 0x128, rev8, SDIO/PCMCIA: Rd Frm OOS */ - uint32 wroutofsync; /* RdOutOfSyncCount, 0x12c, rev8, SDIO/PCMCIA: Wr Frm OOS */ - uint32 writebusy; /* WriteBusyCount, 0x130, rev8, SDIO: dev asserted "busy" */ - uint32 readwait; /* ReadWaitCount, 0x134, rev8, SDIO: read: no data avail */ - uint32 readterm; /* ReadTermCount, 0x138, rev8, SDIO: rd frm terminates */ - uint32 writeterm; /* WriteTermCount, 0x13c, rev8, SDIO: wr frm terminates */ - uint32 PAD[40]; - uint32 clockctlstatus; /* ClockCtlStatus, 0x1e0, rev8 */ - uint32 PAD[7]; - - /* DMA engines */ - volatile union { - pcmdma32_t pcm32; - sdiodma32_t sdiod32; - sdiodma64_t sdiod64; - } dma; - - /* SDIO/PCMCIA CIS region */ - char cis[512]; /* 512 byte CIS, 0x400-0x5ff, rev6 */ - - /* PCMCIA function control registers */ - char pcmciafcr[256]; /* PCMCIA FCR, 0x600-6ff, rev6 */ - uint16 PAD[55]; - - /* PCMCIA backplane access */ - uint16 backplanecsr; /* BackplaneCSR, 0x76E, rev6 */ - uint16 backplaneaddr0; /* BackplaneAddr0, 0x770, rev6 */ - uint16 backplaneaddr1; /* BackplaneAddr1, 0x772, rev6 */ - uint16 backplaneaddr2; /* BackplaneAddr2, 0x774, rev6 */ - uint16 backplaneaddr3; /* BackplaneAddr3, 0x776, rev6 */ - uint16 backplanedata0; /* BackplaneData0, 0x778, rev6 */ - uint16 backplanedata1; /* BackplaneData1, 0x77a, rev6 */ - uint16 backplanedata2; /* BackplaneData2, 0x77c, rev6 */ - uint16 backplanedata3; /* BackplaneData3, 0x77e, rev6 */ - uint16 PAD[31]; - - /* sprom "size" & "blank" info */ - uint16 spromstatus; /* SPROMStatus, 0x7BE, rev2 */ - uint32 PAD[464]; - - /* Sonics SiliconBackplane registers */ - sbconfig_t sbconfig; /* SbConfig Regs, 0xf00-0xfff, rev8 */ -} sdpcmd_regs_t; - -/* corecontrol */ -#define CC_CISRDY (1 << 0) /* CIS Ready */ -#define CC_BPRESEN (1 << 1) /* CCCR RES signal causes backplane reset */ -#define CC_F2RDY (1 << 2) /* set CCCR IOR2 bit */ -#define CC_CLRPADSISO (1 << 3) /* clear SDIO pads isolation bit (rev 11) */ -#define CC_XMTDATAAVAIL_MODE (1 << 4) /* data avail generates an interrupt */ -#define CC_XMTDATAAVAIL_CTRL (1 << 5) /* data avail interrupt ctrl */ - -/* corestatus */ -#define CS_PCMCIAMODE (1 << 0) /* Device Mode; 0=SDIO, 1=PCMCIA */ -#define CS_SMARTDEV (1 << 1) /* 1=smartDev enabled */ -#define CS_F2ENABLED (1 << 2) /* 1=host has enabled the device */ - -#define PCMCIA_MES_PA_MASK 0x7fff /* PCMCIA Message Portal Address Mask */ -#define PCMCIA_MES_PM_MASK 0x7fff /* PCMCIA Message Portal Mask Mask */ -#define PCMCIA_WFBC_MASK 0xffff /* PCMCIA Write Frame Byte Count Mask */ -#define PCMCIA_UT_MASK 0x07ff /* PCMCIA Underflow Timer Mask */ - -/* intstatus */ -#define I_SMB_SW0 (1 << 0) /* To SB Mail S/W interrupt 0 */ -#define I_SMB_SW1 (1 << 1) /* To SB Mail S/W interrupt 1 */ -#define I_SMB_SW2 (1 << 2) /* To SB Mail S/W interrupt 2 */ -#define I_SMB_SW3 (1 << 3) /* To SB Mail S/W interrupt 3 */ -#define I_SMB_SW_MASK 0x0000000f /* To SB Mail S/W interrupts mask */ -#define I_SMB_SW_SHIFT 0 /* To SB Mail S/W interrupts shift */ -#define I_HMB_SW0 (1 << 4) /* To Host Mail S/W interrupt 0 */ -#define I_HMB_SW1 (1 << 5) /* To Host Mail S/W interrupt 1 */ -#define I_HMB_SW2 (1 << 6) /* To Host Mail S/W interrupt 2 */ -#define I_HMB_SW3 (1 << 7) /* To Host Mail S/W interrupt 3 */ -#define I_HMB_SW_MASK 0x000000f0 /* To Host Mail S/W interrupts mask */ -#define I_HMB_SW_SHIFT 4 /* To Host Mail S/W interrupts shift */ -#define I_WR_OOSYNC (1 << 8) /* Write Frame Out Of Sync */ -#define I_RD_OOSYNC (1 << 9) /* Read Frame Out Of Sync */ -#define I_PC (1 << 10) /* descriptor error */ -#define I_PD (1 << 11) /* data error */ -#define I_DE (1 << 12) /* Descriptor protocol Error */ -#define I_RU (1 << 13) /* Receive descriptor Underflow */ -#define I_RO (1 << 14) /* Receive fifo Overflow */ -#define I_XU (1 << 15) /* Transmit fifo Underflow */ -#define I_RI (1 << 16) /* Receive Interrupt */ -#define I_BUSPWR (1 << 17) /* SDIO Bus Power Change (rev 9) */ -#define I_XMTDATA_AVAIL (1 << 23) /* bits in fifo */ -#define I_XI (1 << 24) /* Transmit Interrupt */ -#define I_RF_TERM (1 << 25) /* Read Frame Terminate */ -#define I_WF_TERM (1 << 26) /* Write Frame Terminate */ -#define I_PCMCIA_XU (1 << 27) /* PCMCIA Transmit FIFO Underflow */ -#define I_SBINT (1 << 28) /* sbintstatus Interrupt */ -#define I_CHIPACTIVE (1 << 29) /* chip transitioned from doze to active state */ -#define I_SRESET (1 << 30) /* CCCR RES interrupt */ -#define I_IOE2 (1U << 31) /* CCCR IOE2 Bit Changed */ -#define I_ERRORS (I_PC | I_PD | I_DE | I_RU | I_RO | I_XU) /* DMA Errors */ -#define I_DMA (I_RI | I_XI | I_ERRORS) - -/* sbintstatus */ -#define I_SB_SERR (1 << 8) /* Backplane SError (write) */ -#define I_SB_RESPERR (1 << 9) /* Backplane Response Error (read) */ -#define I_SB_SPROMERR (1 << 10) /* Error accessing the sprom */ - -/* sdioaccess */ -#define SDA_DATA_MASK 0x000000ff /* Read/Write Data Mask */ -#define SDA_ADDR_MASK 0x000fff00 /* Read/Write Address Mask */ -#define SDA_ADDR_SHIFT 8 /* Read/Write Address Shift */ -#define SDA_WRITE 0x01000000 /* Write bit */ -#define SDA_READ 0x00000000 /* Write bit cleared for Read */ -#define SDA_BUSY 0x80000000 /* Busy bit */ - -/* sdioaccess-accessible register address spaces */ -#define SDA_CCCR_SPACE 0x000 /* sdioAccess CCCR register space */ -#define SDA_F1_FBR_SPACE 0x100 /* sdioAccess F1 FBR register space */ -#define SDA_F2_FBR_SPACE 0x200 /* sdioAccess F2 FBR register space */ -#define SDA_F1_REG_SPACE 0x300 /* sdioAccess F1 core-specific register space */ - -/* SDA_F1_REG_SPACE sdioaccess-accessible F1 reg space register offsets */ -#define SDA_CHIPCONTROLDATA 0x006 /* ChipControlData */ -#define SDA_CHIPCONTROLENAB 0x007 /* ChipControlEnable */ -#define SDA_F2WATERMARK 0x008 /* Function 2 Watermark */ -#define SDA_DEVICECONTROL 0x009 /* DeviceControl */ -#define SDA_SBADDRLOW 0x00a /* SbAddrLow */ -#define SDA_SBADDRMID 0x00b /* SbAddrMid */ -#define SDA_SBADDRHIGH 0x00c /* SbAddrHigh */ -#define SDA_FRAMECTRL 0x00d /* FrameCtrl */ -#define SDA_CHIPCLOCKCSR 0x00e /* ChipClockCSR */ -#define SDA_SDIOPULLUP 0x00f /* SdioPullUp */ -#define SDA_SDIOWRFRAMEBCLOW 0x019 /* SdioWrFrameBCLow */ -#define SDA_SDIOWRFRAMEBCHIGH 0x01a /* SdioWrFrameBCHigh */ -#define SDA_SDIORDFRAMEBCLOW 0x01b /* SdioRdFrameBCLow */ -#define SDA_SDIORDFRAMEBCHIGH 0x01c /* SdioRdFrameBCHigh */ - -/* SDA_F2WATERMARK */ -#define SDA_F2WATERMARK_MASK 0x7f /* F2Watermark Mask */ - -/* SDA_SBADDRLOW */ -#define SDA_SBADDRLOW_MASK 0x80 /* SbAddrLow Mask */ - -/* SDA_SBADDRMID */ -#define SDA_SBADDRMID_MASK 0xff /* SbAddrMid Mask */ - -/* SDA_SBADDRHIGH */ -#define SDA_SBADDRHIGH_MASK 0xff /* SbAddrHigh Mask */ - -/* SDA_FRAMECTRL */ -#define SFC_RF_TERM (1 << 0) /* Read Frame Terminate */ -#define SFC_WF_TERM (1 << 1) /* Write Frame Terminate */ -#define SFC_CRC4WOOS (1 << 2) /* HW reports CRC error for write out of sync */ -#define SFC_ABORTALL (1 << 3) /* Abort cancels all in-progress frames */ - -/* pcmciaframectrl */ -#define PFC_RF_TERM (1 << 0) /* Read Frame Terminate */ -#define PFC_WF_TERM (1 << 1) /* Write Frame Terminate */ - -/* intrcvlazy */ -#define IRL_TO_MASK 0x00ffffff /* timeout */ -#define IRL_FC_MASK 0xff000000 /* frame count */ -#define IRL_FC_SHIFT 24 /* frame count */ - -/* rx header */ -typedef volatile struct { - uint16 len; - uint16 flags; -} sdpcmd_rxh_t; - -/* rx header flags */ -#define RXF_CRC 0x0001 /* CRC error detected */ -#define RXF_WOOS 0x0002 /* write frame out of sync */ -#define RXF_WF_TERM 0x0004 /* write frame terminated */ -#define RXF_ABORT 0x0008 /* write frame aborted */ -#define RXF_DISCARD (RXF_CRC | RXF_WOOS | RXF_WF_TERM | RXF_ABORT) /* bad frame */ - -/* HW frame tag */ -#define SDPCM_FRAMETAG_LEN 4 /* HW frametag: 2 bytes len, 2 bytes check val */ - -#endif /* _sbsdpcmdev_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/sbsocram.h b/drivers/net/wireless/bcmdhd/include/sbsocram.h deleted file mode 100644 index 45c4dc208bda..000000000000 --- a/drivers/net/wireless/bcmdhd/include/sbsocram.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * BCM47XX Sonics SiliconBackplane embedded ram core - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sbsocram.h 277737 2011-08-16 17:54:59Z $ - */ - - -#ifndef _SBSOCRAM_H -#define _SBSOCRAM_H - -#ifndef _LANGUAGE_ASSEMBLY - - -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif - - -typedef volatile struct sbsocramregs { - uint32 coreinfo; - uint32 bwalloc; - uint32 extracoreinfo; - uint32 biststat; - uint32 bankidx; - uint32 standbyctrl; - - uint32 errlogstatus; - uint32 errlogaddr; - - uint32 cambankidx; - uint32 cambankstandbyctrl; - uint32 cambankpatchctrl; - uint32 cambankpatchtblbaseaddr; - uint32 cambankcmdreg; - uint32 cambankdatareg; - uint32 cambankmaskreg; - uint32 PAD[1]; - uint32 bankinfo; - uint32 PAD[15]; - uint32 extmemconfig; - uint32 extmemparitycsr; - uint32 extmemparityerrdata; - uint32 extmemparityerrcnt; - uint32 extmemwrctrlandsize; - uint32 PAD[84]; - uint32 workaround; - uint32 pwrctl; - uint32 PAD[133]; - uint32 sr_control; - uint32 sr_status; - uint32 sr_address; - uint32 sr_data; -} sbsocramregs_t; - -#endif - - -#define SR_COREINFO 0x00 -#define SR_BWALLOC 0x04 -#define SR_BISTSTAT 0x0c -#define SR_BANKINDEX 0x10 -#define SR_BANKSTBYCTL 0x14 -#define SR_PWRCTL 0x1e8 - - -#define SRCI_PT_MASK 0x00070000 -#define SRCI_PT_SHIFT 16 - -#define SRCI_PT_OCP_OCP 0 -#define SRCI_PT_AXI_OCP 1 -#define SRCI_PT_ARM7AHB_OCP 2 -#define SRCI_PT_CM3AHB_OCP 3 -#define SRCI_PT_AXI_AXI 4 -#define SRCI_PT_AHB_AXI 5 - -#define SRCI_LSS_MASK 0x00f00000 -#define SRCI_LSS_SHIFT 20 -#define SRCI_LRS_MASK 0x0f000000 -#define SRCI_LRS_SHIFT 24 - - -#define SRCI_MS0_MASK 0xf -#define SR_MS0_BASE 16 - - -#define SRCI_ROMNB_MASK 0xf000 -#define SRCI_ROMNB_SHIFT 12 -#define SRCI_ROMBSZ_MASK 0xf00 -#define SRCI_ROMBSZ_SHIFT 8 -#define SRCI_SRNB_MASK 0xf0 -#define SRCI_SRNB_SHIFT 4 -#define SRCI_SRBSZ_MASK 0xf -#define SRCI_SRBSZ_SHIFT 0 - -#define SR_BSZ_BASE 14 - - -#define SRSC_SBYOVR_MASK 0x80000000 -#define SRSC_SBYOVR_SHIFT 31 -#define SRSC_SBYOVRVAL_MASK 0x60000000 -#define SRSC_SBYOVRVAL_SHIFT 29 -#define SRSC_SBYEN_MASK 0x01000000 -#define SRSC_SBYEN_SHIFT 24 - - -#define SRPC_PMU_STBYDIS_MASK 0x00000010 -#define SRPC_PMU_STBYDIS_SHIFT 4 -#define SRPC_STBYOVRVAL_MASK 0x00000008 -#define SRPC_STBYOVRVAL_SHIFT 3 -#define SRPC_STBYOVR_MASK 0x00000007 -#define SRPC_STBYOVR_SHIFT 0 - - -#define SRECC_NUM_BANKS_MASK 0x000000F0 -#define SRECC_NUM_BANKS_SHIFT 4 -#define SRECC_BANKSIZE_MASK 0x0000000F -#define SRECC_BANKSIZE_SHIFT 0 - -#define SRECC_BANKSIZE(value) (1 << (value)) - - -#define SRCBPC_PATCHENABLE 0x80000000 - -#define SRP_ADDRESS 0x0001FFFC -#define SRP_VALID 0x8000 - - -#define SRCMD_WRITE 0x00020000 -#define SRCMD_READ 0x00010000 -#define SRCMD_DONE 0x80000000 - -#define SRCMD_DONE_DLY 1000 - - -#define SOCRAM_BANKINFO_SZMASK 0x3f -#define SOCRAM_BANKIDX_ROM_MASK 0x100 - -#define SOCRAM_BANKIDX_MEMTYPE_SHIFT 8 - -#define SOCRAM_MEMTYPE_RAM 0 -#define SOCRAM_MEMTYPE_R0M 1 -#define SOCRAM_MEMTYPE_DEVRAM 2 - -#define SOCRAM_BANKINFO_REG 0x40 -#define SOCRAM_BANKIDX_REG 0x10 -#define SOCRAM_BANKINFO_STDBY_MASK 0x400 -#define SOCRAM_BANKINFO_STDBY_TIMER 0x800 - - -#define SOCRAM_BANKINFO_DEVRAMSEL_SHIFT 13 -#define SOCRAM_BANKINFO_DEVRAMSEL_MASK 0x2000 -#define SOCRAM_BANKINFO_DEVRAMPRO_SHIFT 14 -#define SOCRAM_BANKINFO_DEVRAMPRO_MASK 0x4000 - - -#define SOCRAM_DEVRAMBANK_MASK 0xF000 -#define SOCRAM_DEVRAMBANK_SHIFT 12 - - -#define SOCRAM_BANKINFO_SZBASE 8192 -#define SOCRAM_BANKSIZE_SHIFT 13 - - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/sdio.h b/drivers/net/wireless/bcmdhd/include/sdio.h deleted file mode 100644 index c8ac7b773fb9..000000000000 --- a/drivers/net/wireless/bcmdhd/include/sdio.h +++ /dev/null @@ -1,612 +0,0 @@ -/* - * SDIO spec header file - * Protocol and standard (common) device definitions - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sdio.h 277737 2011-08-16 17:54:59Z $ - */ - -#ifndef _SDIO_H -#define _SDIO_H - - -/* CCCR structure for function 0 */ -typedef volatile struct { - uint8 cccr_sdio_rev; /* RO, cccr and sdio revision */ - uint8 sd_rev; /* RO, sd spec revision */ - uint8 io_en; /* I/O enable */ - uint8 io_rdy; /* I/O ready reg */ - uint8 intr_ctl; /* Master and per function interrupt enable control */ - uint8 intr_status; /* RO, interrupt pending status */ - uint8 io_abort; /* read/write abort or reset all functions */ - uint8 bus_inter; /* bus interface control */ - uint8 capability; /* RO, card capability */ - - uint8 cis_base_low; /* 0x9 RO, common CIS base address, LSB */ - uint8 cis_base_mid; - uint8 cis_base_high; /* 0xB RO, common CIS base address, MSB */ - - /* suspend/resume registers */ - uint8 bus_suspend; /* 0xC */ - uint8 func_select; /* 0xD */ - uint8 exec_flag; /* 0xE */ - uint8 ready_flag; /* 0xF */ - - uint8 fn0_blk_size[2]; /* 0x10(LSB), 0x11(MSB) */ - - uint8 power_control; /* 0x12 (SDIO version 1.10) */ - - uint8 speed_control; /* 0x13 */ -} sdio_regs_t; - -/* SDIO Device CCCR offsets */ -#define SDIOD_CCCR_REV 0x00 -#define SDIOD_CCCR_SDREV 0x01 -#define SDIOD_CCCR_IOEN 0x02 -#define SDIOD_CCCR_IORDY 0x03 -#define SDIOD_CCCR_INTEN 0x04 -#define SDIOD_CCCR_INTPEND 0x05 -#define SDIOD_CCCR_IOABORT 0x06 -#define SDIOD_CCCR_BICTRL 0x07 -#define SDIOD_CCCR_CAPABLITIES 0x08 -#define SDIOD_CCCR_CISPTR_0 0x09 -#define SDIOD_CCCR_CISPTR_1 0x0A -#define SDIOD_CCCR_CISPTR_2 0x0B -#define SDIOD_CCCR_BUSSUSP 0x0C -#define SDIOD_CCCR_FUNCSEL 0x0D -#define SDIOD_CCCR_EXECFLAGS 0x0E -#define SDIOD_CCCR_RDYFLAGS 0x0F -#define SDIOD_CCCR_BLKSIZE_0 0x10 -#define SDIOD_CCCR_BLKSIZE_1 0x11 -#define SDIOD_CCCR_POWER_CONTROL 0x12 -#define SDIOD_CCCR_SPEED_CONTROL 0x13 -#define SDIOD_CCCR_UHSI_SUPPORT 0x14 -#define SDIOD_CCCR_DRIVER_STRENGTH 0x15 -#define SDIOD_CCCR_INTR_EXTN 0x16 - -/* Broadcom extensions (corerev >= 1) */ -#define SDIOD_CCCR_BRCM_SEPINT 0xf2 - -/* cccr_sdio_rev */ -#define SDIO_REV_SDIOID_MASK 0xf0 /* SDIO spec revision number */ -#define SDIO_REV_CCCRID_MASK 0x0f /* CCCR format version number */ - -/* sd_rev */ -#define SD_REV_PHY_MASK 0x0f /* SD format version number */ - -/* io_en */ -#define SDIO_FUNC_ENABLE_1 0x02 /* function 1 I/O enable */ -#define SDIO_FUNC_ENABLE_2 0x04 /* function 2 I/O enable */ - -/* io_rdys */ -#define SDIO_FUNC_READY_1 0x02 /* function 1 I/O ready */ -#define SDIO_FUNC_READY_2 0x04 /* function 2 I/O ready */ - -/* intr_ctl */ -#define INTR_CTL_MASTER_EN 0x1 /* interrupt enable master */ -#define INTR_CTL_FUNC1_EN 0x2 /* interrupt enable for function 1 */ -#define INTR_CTL_FUNC2_EN 0x4 /* interrupt enable for function 2 */ - -/* intr_status */ -#define INTR_STATUS_FUNC1 0x2 /* interrupt pending for function 1 */ -#define INTR_STATUS_FUNC2 0x4 /* interrupt pending for function 2 */ - -/* io_abort */ -#define IO_ABORT_RESET_ALL 0x08 /* I/O card reset */ -#define IO_ABORT_FUNC_MASK 0x07 /* abort selction: function x */ - -/* bus_inter */ -#define BUS_CARD_DETECT_DIS 0x80 /* Card Detect disable */ -#define BUS_SPI_CONT_INTR_CAP 0x40 /* support continuous SPI interrupt */ -#define BUS_SPI_CONT_INTR_EN 0x20 /* continuous SPI interrupt enable */ -#define BUS_SD_DATA_WIDTH_MASK 0x03 /* bus width mask */ -#define BUS_SD_DATA_WIDTH_4BIT 0x02 /* bus width 4-bit mode */ -#define BUS_SD_DATA_WIDTH_1BIT 0x00 /* bus width 1-bit mode */ - -/* capability */ -#define SDIO_CAP_4BLS 0x80 /* 4-bit support for low speed card */ -#define SDIO_CAP_LSC 0x40 /* low speed card */ -#define SDIO_CAP_E4MI 0x20 /* enable interrupt between block of data in 4-bit mode */ -#define SDIO_CAP_S4MI 0x10 /* support interrupt between block of data in 4-bit mode */ -#define SDIO_CAP_SBS 0x08 /* support suspend/resume */ -#define SDIO_CAP_SRW 0x04 /* support read wait */ -#define SDIO_CAP_SMB 0x02 /* support multi-block transfer */ -#define SDIO_CAP_SDC 0x01 /* Support Direct commands during multi-byte transfer */ - -/* power_control */ -#define SDIO_POWER_SMPC 0x01 /* supports master power control (RO) */ -#define SDIO_POWER_EMPC 0x02 /* enable master power control (allow > 200mA) (RW) */ - -/* speed_control (control device entry into high-speed clocking mode) */ -#define SDIO_SPEED_SHS 0x01 /* supports high-speed [clocking] mode (RO) */ -#define SDIO_SPEED_EHS 0x02 /* enable high-speed [clocking] mode (RW) */ - -/* for setting bus speed in card: 0x13h */ -#define SDIO_BUS_SPEED_UHSISEL_M BITFIELD_MASK(3) -#define SDIO_BUS_SPEED_UHSISEL_S 1 - -/* for getting bus speed cap in card: 0x14h */ -#define SDIO_BUS_SPEED_UHSICAP_M BITFIELD_MASK(3) -#define SDIO_BUS_SPEED_UHSICAP_S 0 - -/* for getting driver type CAP in card: 0x15h */ -#define SDIO_BUS_DRVR_TYPE_CAP_M BITFIELD_MASK(3) -#define SDIO_BUS_DRVR_TYPE_CAP_S 0 - -/* for setting driver type selection in card: 0x15h */ -#define SDIO_BUS_DRVR_TYPE_SEL_M BITFIELD_MASK(2) -#define SDIO_BUS_DRVR_TYPE_SEL_S 4 - -/* for getting async int support in card: 0x16h */ -#define SDIO_BUS_ASYNCINT_CAP_M BITFIELD_MASK(1) -#define SDIO_BUS_ASYNCINT_CAP_S 0 - -/* for setting async int selection in card: 0x16h */ -#define SDIO_BUS_ASYNCINT_SEL_M BITFIELD_MASK(1) -#define SDIO_BUS_ASYNCINT_SEL_S 1 - -/* brcm sepint */ -#define SDIO_SEPINT_MASK 0x01 /* route sdpcmdev intr onto separate pad (chip-specific) */ -#define SDIO_SEPINT_OE 0x02 /* 1 asserts output enable for above pad */ -#define SDIO_SEPINT_ACT_HI 0x04 /* use active high interrupt level instead of active low */ - -/* FBR structure for function 1-7, FBR addresses and register offsets */ -typedef volatile struct { - uint8 devctr; /* device interface, CSA control */ - uint8 ext_dev; /* extended standard I/O device type code */ - uint8 pwr_sel; /* power selection support */ - uint8 PAD[6]; /* reserved */ - - uint8 cis_low; /* CIS LSB */ - uint8 cis_mid; - uint8 cis_high; /* CIS MSB */ - uint8 csa_low; /* code storage area, LSB */ - uint8 csa_mid; - uint8 csa_high; /* code storage area, MSB */ - uint8 csa_dat_win; /* data access window to function */ - - uint8 fnx_blk_size[2]; /* block size, little endian */ -} sdio_fbr_t; - -/* Maximum number of I/O funcs */ -#define SDIOD_MAX_IOFUNCS 7 - -/* SDIO Device FBR Start Address */ -#define SDIOD_FBR_STARTADDR 0x100 - -/* SDIO Device FBR Size */ -#define SDIOD_FBR_SIZE 0x100 - -/* Macro to calculate FBR register base */ -#define SDIOD_FBR_BASE(n) ((n) * 0x100) - -/* Function register offsets */ -#define SDIOD_FBR_DEVCTR 0x00 /* basic info for function */ -#define SDIOD_FBR_EXT_DEV 0x01 /* extended I/O device code */ -#define SDIOD_FBR_PWR_SEL 0x02 /* power selection bits */ - -/* SDIO Function CIS ptr offset */ -#define SDIOD_FBR_CISPTR_0 0x09 -#define SDIOD_FBR_CISPTR_1 0x0A -#define SDIOD_FBR_CISPTR_2 0x0B - -/* Code Storage Area pointer */ -#define SDIOD_FBR_CSA_ADDR_0 0x0C -#define SDIOD_FBR_CSA_ADDR_1 0x0D -#define SDIOD_FBR_CSA_ADDR_2 0x0E -#define SDIOD_FBR_CSA_DATA 0x0F - -/* SDIO Function I/O Block Size */ -#define SDIOD_FBR_BLKSIZE_0 0x10 -#define SDIOD_FBR_BLKSIZE_1 0x11 - -/* devctr */ -#define SDIOD_FBR_DEVCTR_DIC 0x0f /* device interface code */ -#define SDIOD_FBR_DECVTR_CSA 0x40 /* CSA support flag */ -#define SDIOD_FBR_DEVCTR_CSA_EN 0x80 /* CSA enabled */ -/* interface codes */ -#define SDIOD_DIC_NONE 0 /* SDIO standard interface is not supported */ -#define SDIOD_DIC_UART 1 -#define SDIOD_DIC_BLUETOOTH_A 2 -#define SDIOD_DIC_BLUETOOTH_B 3 -#define SDIOD_DIC_GPS 4 -#define SDIOD_DIC_CAMERA 5 -#define SDIOD_DIC_PHS 6 -#define SDIOD_DIC_WLAN 7 -#define SDIOD_DIC_EXT 0xf /* extended device interface, read ext_dev register */ - -/* pwr_sel */ -#define SDIOD_PWR_SEL_SPS 0x01 /* supports power selection */ -#define SDIOD_PWR_SEL_EPS 0x02 /* enable power selection (low-current mode) */ - -/* misc defines */ -#define SDIO_FUNC_0 0 -#define SDIO_FUNC_1 1 -#define SDIO_FUNC_2 2 -#define SDIO_FUNC_3 3 -#define SDIO_FUNC_4 4 -#define SDIO_FUNC_5 5 -#define SDIO_FUNC_6 6 -#define SDIO_FUNC_7 7 - -#define SD_CARD_TYPE_UNKNOWN 0 /* bad type or unrecognized */ -#define SD_CARD_TYPE_IO 1 /* IO only card */ -#define SD_CARD_TYPE_MEMORY 2 /* memory only card */ -#define SD_CARD_TYPE_COMBO 3 /* IO and memory combo card */ - -#define SDIO_MAX_BLOCK_SIZE 2048 /* maximum block size for block mode operation */ -#define SDIO_MIN_BLOCK_SIZE 1 /* minimum block size for block mode operation */ - -/* Card registers: status bit position */ -#define CARDREG_STATUS_BIT_OUTOFRANGE 31 -#define CARDREG_STATUS_BIT_COMCRCERROR 23 -#define CARDREG_STATUS_BIT_ILLEGALCOMMAND 22 -#define CARDREG_STATUS_BIT_ERROR 19 -#define CARDREG_STATUS_BIT_IOCURRENTSTATE3 12 -#define CARDREG_STATUS_BIT_IOCURRENTSTATE2 11 -#define CARDREG_STATUS_BIT_IOCURRENTSTATE1 10 -#define CARDREG_STATUS_BIT_IOCURRENTSTATE0 9 -#define CARDREG_STATUS_BIT_FUN_NUM_ERROR 4 - - - -#define SD_CMD_GO_IDLE_STATE 0 /* mandatory for SDIO */ -#define SD_CMD_SEND_OPCOND 1 -#define SD_CMD_MMC_SET_RCA 3 -#define SD_CMD_IO_SEND_OP_COND 5 /* mandatory for SDIO */ -#define SD_CMD_SELECT_DESELECT_CARD 7 -#define SD_CMD_SEND_CSD 9 -#define SD_CMD_SEND_CID 10 -#define SD_CMD_STOP_TRANSMISSION 12 -#define SD_CMD_SEND_STATUS 13 -#define SD_CMD_GO_INACTIVE_STATE 15 -#define SD_CMD_SET_BLOCKLEN 16 -#define SD_CMD_READ_SINGLE_BLOCK 17 -#define SD_CMD_READ_MULTIPLE_BLOCK 18 -#define SD_CMD_WRITE_BLOCK 24 -#define SD_CMD_WRITE_MULTIPLE_BLOCK 25 -#define SD_CMD_PROGRAM_CSD 27 -#define SD_CMD_SET_WRITE_PROT 28 -#define SD_CMD_CLR_WRITE_PROT 29 -#define SD_CMD_SEND_WRITE_PROT 30 -#define SD_CMD_ERASE_WR_BLK_START 32 -#define SD_CMD_ERASE_WR_BLK_END 33 -#define SD_CMD_ERASE 38 -#define SD_CMD_LOCK_UNLOCK 42 -#define SD_CMD_IO_RW_DIRECT 52 /* mandatory for SDIO */ -#define SD_CMD_IO_RW_EXTENDED 53 /* mandatory for SDIO */ -#define SD_CMD_APP_CMD 55 -#define SD_CMD_GEN_CMD 56 -#define SD_CMD_READ_OCR 58 -#define SD_CMD_CRC_ON_OFF 59 /* mandatory for SDIO */ -#define SD_ACMD_SD_STATUS 13 -#define SD_ACMD_SEND_NUM_WR_BLOCKS 22 -#define SD_ACMD_SET_WR_BLOCK_ERASE_CNT 23 -#define SD_ACMD_SD_SEND_OP_COND 41 -#define SD_ACMD_SET_CLR_CARD_DETECT 42 -#define SD_ACMD_SEND_SCR 51 - -/* argument for SD_CMD_IO_RW_DIRECT and SD_CMD_IO_RW_EXTENDED */ -#define SD_IO_OP_READ 0 /* Read_Write: Read */ -#define SD_IO_OP_WRITE 1 /* Read_Write: Write */ -#define SD_IO_RW_NORMAL 0 /* no RAW */ -#define SD_IO_RW_RAW 1 /* RAW */ -#define SD_IO_BYTE_MODE 0 /* Byte Mode */ -#define SD_IO_BLOCK_MODE 1 /* BlockMode */ -#define SD_IO_FIXED_ADDRESS 0 /* fix Address */ -#define SD_IO_INCREMENT_ADDRESS 1 /* IncrementAddress */ - -/* build SD_CMD_IO_RW_DIRECT Argument */ -#define SDIO_IO_RW_DIRECT_ARG(rw, raw, func, addr, data) \ - ((((rw) & 1) << 31) | (((func) & 0x7) << 28) | (((raw) & 1) << 27) | \ - (((addr) & 0x1FFFF) << 9) | ((data) & 0xFF)) - -/* build SD_CMD_IO_RW_EXTENDED Argument */ -#define SDIO_IO_RW_EXTENDED_ARG(rw, blk, func, addr, inc_addr, count) \ - ((((rw) & 1) << 31) | (((func) & 0x7) << 28) | (((blk) & 1) << 27) | \ - (((inc_addr) & 1) << 26) | (((addr) & 0x1FFFF) << 9) | ((count) & 0x1FF)) - -/* SDIO response parameters */ -#define SD_RSP_NO_NONE 0 -#define SD_RSP_NO_1 1 -#define SD_RSP_NO_2 2 -#define SD_RSP_NO_3 3 -#define SD_RSP_NO_4 4 -#define SD_RSP_NO_5 5 -#define SD_RSP_NO_6 6 - - /* Modified R6 response (to CMD3) */ -#define SD_RSP_MR6_COM_CRC_ERROR 0x8000 -#define SD_RSP_MR6_ILLEGAL_COMMAND 0x4000 -#define SD_RSP_MR6_ERROR 0x2000 - - /* Modified R1 in R4 Response (to CMD5) */ -#define SD_RSP_MR1_SBIT 0x80 -#define SD_RSP_MR1_PARAMETER_ERROR 0x40 -#define SD_RSP_MR1_RFU5 0x20 -#define SD_RSP_MR1_FUNC_NUM_ERROR 0x10 -#define SD_RSP_MR1_COM_CRC_ERROR 0x08 -#define SD_RSP_MR1_ILLEGAL_COMMAND 0x04 -#define SD_RSP_MR1_RFU1 0x02 -#define SD_RSP_MR1_IDLE_STATE 0x01 - - /* R5 response (to CMD52 and CMD53) */ -#define SD_RSP_R5_COM_CRC_ERROR 0x80 -#define SD_RSP_R5_ILLEGAL_COMMAND 0x40 -#define SD_RSP_R5_IO_CURRENTSTATE1 0x20 -#define SD_RSP_R5_IO_CURRENTSTATE0 0x10 -#define SD_RSP_R5_ERROR 0x08 -#define SD_RSP_R5_RFU 0x04 -#define SD_RSP_R5_FUNC_NUM_ERROR 0x02 -#define SD_RSP_R5_OUT_OF_RANGE 0x01 - -#define SD_RSP_R5_ERRBITS 0xCB - - -/* ------------------------------------------------ - * SDIO Commands and responses - * - * I/O only commands are: - * CMD0, CMD3, CMD5, CMD7, CMD14, CMD15, CMD52, CMD53 - * ------------------------------------------------ - */ - -/* SDIO Commands */ -#define SDIOH_CMD_0 0 -#define SDIOH_CMD_3 3 -#define SDIOH_CMD_5 5 -#define SDIOH_CMD_7 7 -#define SDIOH_CMD_11 11 -#define SDIOH_CMD_14 14 -#define SDIOH_CMD_15 15 -#define SDIOH_CMD_19 19 -#define SDIOH_CMD_52 52 -#define SDIOH_CMD_53 53 -#define SDIOH_CMD_59 59 - -/* SDIO Command Responses */ -#define SDIOH_RSP_NONE 0 -#define SDIOH_RSP_R1 1 -#define SDIOH_RSP_R2 2 -#define SDIOH_RSP_R3 3 -#define SDIOH_RSP_R4 4 -#define SDIOH_RSP_R5 5 -#define SDIOH_RSP_R6 6 - -/* - * SDIO Response Error flags - */ -#define SDIOH_RSP5_ERROR_FLAGS 0xCB - -/* ------------------------------------------------ - * SDIO Command structures. I/O only commands are: - * - * CMD0, CMD3, CMD5, CMD7, CMD15, CMD52, CMD53 - * ------------------------------------------------ - */ - -#define CMD5_OCR_M BITFIELD_MASK(24) -#define CMD5_OCR_S 0 - -#define CMD5_S18R_M BITFIELD_MASK(1) -#define CMD5_S18R_S 24 - -#define CMD7_RCA_M BITFIELD_MASK(16) -#define CMD7_RCA_S 16 - -#define CMD14_RCA_M BITFIELD_MASK(16) -#define CMD14_RCA_S 16 -#define CMD14_SLEEP_M BITFIELD_MASK(1) -#define CMD14_SLEEP_S 15 - -#define CMD_15_RCA_M BITFIELD_MASK(16) -#define CMD_15_RCA_S 16 - -#define CMD52_DATA_M BITFIELD_MASK(8) /* Bits [7:0] - Write Data/Stuff bits of CMD52 - */ -#define CMD52_DATA_S 0 -#define CMD52_REG_ADDR_M BITFIELD_MASK(17) /* Bits [25:9] - register address */ -#define CMD52_REG_ADDR_S 9 -#define CMD52_RAW_M BITFIELD_MASK(1) /* Bit 27 - Read after Write flag */ -#define CMD52_RAW_S 27 -#define CMD52_FUNCTION_M BITFIELD_MASK(3) /* Bits [30:28] - Function number */ -#define CMD52_FUNCTION_S 28 -#define CMD52_RW_FLAG_M BITFIELD_MASK(1) /* Bit 31 - R/W flag */ -#define CMD52_RW_FLAG_S 31 - - -#define CMD53_BYTE_BLK_CNT_M BITFIELD_MASK(9) /* Bits [8:0] - Byte/Block Count of CMD53 */ -#define CMD53_BYTE_BLK_CNT_S 0 -#define CMD53_REG_ADDR_M BITFIELD_MASK(17) /* Bits [25:9] - register address */ -#define CMD53_REG_ADDR_S 9 -#define CMD53_OP_CODE_M BITFIELD_MASK(1) /* Bit 26 - R/W Operation Code */ -#define CMD53_OP_CODE_S 26 -#define CMD53_BLK_MODE_M BITFIELD_MASK(1) /* Bit 27 - Block Mode */ -#define CMD53_BLK_MODE_S 27 -#define CMD53_FUNCTION_M BITFIELD_MASK(3) /* Bits [30:28] - Function number */ -#define CMD53_FUNCTION_S 28 -#define CMD53_RW_FLAG_M BITFIELD_MASK(1) /* Bit 31 - R/W flag */ -#define CMD53_RW_FLAG_S 31 - -/* ------------------------------------------------------ - * SDIO Command Response structures for SD1 and SD4 modes - * ----------------------------------------------------- - */ -#define RSP4_IO_OCR_M BITFIELD_MASK(24) /* Bits [23:0] - Card's OCR Bits [23:0] */ -#define RSP4_IO_OCR_S 0 - -#define RSP4_S18A_M BITFIELD_MASK(1) /* Bits [23:0] - Card's OCR Bits [23:0] */ -#define RSP4_S18A_S 24 - -#define RSP4_STUFF_M BITFIELD_MASK(3) /* Bits [26:24] - Stuff bits */ -#define RSP4_STUFF_S 24 -#define RSP4_MEM_PRESENT_M BITFIELD_MASK(1) /* Bit 27 - Memory present */ -#define RSP4_MEM_PRESENT_S 27 -#define RSP4_NUM_FUNCS_M BITFIELD_MASK(3) /* Bits [30:28] - Number of I/O funcs */ -#define RSP4_NUM_FUNCS_S 28 -#define RSP4_CARD_READY_M BITFIELD_MASK(1) /* Bit 31 - SDIO card ready */ -#define RSP4_CARD_READY_S 31 - -#define RSP6_STATUS_M BITFIELD_MASK(16) /* Bits [15:0] - Card status bits [19,22,23,12:0] - */ -#define RSP6_STATUS_S 0 -#define RSP6_IO_RCA_M BITFIELD_MASK(16) /* Bits [31:16] - RCA bits[31-16] */ -#define RSP6_IO_RCA_S 16 - -#define RSP1_AKE_SEQ_ERROR_M BITFIELD_MASK(1) /* Bit 3 - Authentication seq error */ -#define RSP1_AKE_SEQ_ERROR_S 3 -#define RSP1_APP_CMD_M BITFIELD_MASK(1) /* Bit 5 - Card expects ACMD */ -#define RSP1_APP_CMD_S 5 -#define RSP1_READY_FOR_DATA_M BITFIELD_MASK(1) /* Bit 8 - Ready for data (buff empty) */ -#define RSP1_READY_FOR_DATA_S 8 -#define RSP1_CURR_STATE_M BITFIELD_MASK(4) /* Bits [12:9] - State of card - * when Cmd was received - */ -#define RSP1_CURR_STATE_S 9 -#define RSP1_EARSE_RESET_M BITFIELD_MASK(1) /* Bit 13 - Erase seq cleared */ -#define RSP1_EARSE_RESET_S 13 -#define RSP1_CARD_ECC_DISABLE_M BITFIELD_MASK(1) /* Bit 14 - Card ECC disabled */ -#define RSP1_CARD_ECC_DISABLE_S 14 -#define RSP1_WP_ERASE_SKIP_M BITFIELD_MASK(1) /* Bit 15 - Partial blocks erased due to W/P */ -#define RSP1_WP_ERASE_SKIP_S 15 -#define RSP1_CID_CSD_OVERW_M BITFIELD_MASK(1) /* Bit 16 - Illegal write to CID or R/O bits - * of CSD - */ -#define RSP1_CID_CSD_OVERW_S 16 -#define RSP1_ERROR_M BITFIELD_MASK(1) /* Bit 19 - General/Unknown error */ -#define RSP1_ERROR_S 19 -#define RSP1_CC_ERROR_M BITFIELD_MASK(1) /* Bit 20 - Internal Card Control error */ -#define RSP1_CC_ERROR_S 20 -#define RSP1_CARD_ECC_FAILED_M BITFIELD_MASK(1) /* Bit 21 - Card internal ECC failed - * to correct data - */ -#define RSP1_CARD_ECC_FAILED_S 21 -#define RSP1_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 22 - Cmd not legal for the card state */ -#define RSP1_ILLEGAL_CMD_S 22 -#define RSP1_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 23 - CRC check of previous command failed - */ -#define RSP1_COM_CRC_ERROR_S 23 -#define RSP1_LOCK_UNLOCK_FAIL_M BITFIELD_MASK(1) /* Bit 24 - Card lock-unlock Cmd Seq error */ -#define RSP1_LOCK_UNLOCK_FAIL_S 24 -#define RSP1_CARD_LOCKED_M BITFIELD_MASK(1) /* Bit 25 - Card locked by the host */ -#define RSP1_CARD_LOCKED_S 25 -#define RSP1_WP_VIOLATION_M BITFIELD_MASK(1) /* Bit 26 - Attempt to program - * write-protected blocks - */ -#define RSP1_WP_VIOLATION_S 26 -#define RSP1_ERASE_PARAM_M BITFIELD_MASK(1) /* Bit 27 - Invalid erase blocks */ -#define RSP1_ERASE_PARAM_S 27 -#define RSP1_ERASE_SEQ_ERR_M BITFIELD_MASK(1) /* Bit 28 - Erase Cmd seq error */ -#define RSP1_ERASE_SEQ_ERR_S 28 -#define RSP1_BLK_LEN_ERR_M BITFIELD_MASK(1) /* Bit 29 - Block length error */ -#define RSP1_BLK_LEN_ERR_S 29 -#define RSP1_ADDR_ERR_M BITFIELD_MASK(1) /* Bit 30 - Misaligned address */ -#define RSP1_ADDR_ERR_S 30 -#define RSP1_OUT_OF_RANGE_M BITFIELD_MASK(1) /* Bit 31 - Cmd arg was out of range */ -#define RSP1_OUT_OF_RANGE_S 31 - - -#define RSP5_DATA_M BITFIELD_MASK(8) /* Bits [0:7] - data */ -#define RSP5_DATA_S 0 -#define RSP5_FLAGS_M BITFIELD_MASK(8) /* Bit [15:8] - Rsp flags */ -#define RSP5_FLAGS_S 8 -#define RSP5_STUFF_M BITFIELD_MASK(16) /* Bits [31:16] - Stuff bits */ -#define RSP5_STUFF_S 16 - -/* ---------------------------------------------- - * SDIO Command Response structures for SPI mode - * ---------------------------------------------- - */ -#define SPIRSP4_IO_OCR_M BITFIELD_MASK(16) /* Bits [15:0] - Card's OCR Bits [23:8] */ -#define SPIRSP4_IO_OCR_S 0 -#define SPIRSP4_STUFF_M BITFIELD_MASK(3) /* Bits [18:16] - Stuff bits */ -#define SPIRSP4_STUFF_S 16 -#define SPIRSP4_MEM_PRESENT_M BITFIELD_MASK(1) /* Bit 19 - Memory present */ -#define SPIRSP4_MEM_PRESENT_S 19 -#define SPIRSP4_NUM_FUNCS_M BITFIELD_MASK(3) /* Bits [22:20] - Number of I/O funcs */ -#define SPIRSP4_NUM_FUNCS_S 20 -#define SPIRSP4_CARD_READY_M BITFIELD_MASK(1) /* Bit 23 - SDIO card ready */ -#define SPIRSP4_CARD_READY_S 23 -#define SPIRSP4_IDLE_STATE_M BITFIELD_MASK(1) /* Bit 24 - idle state */ -#define SPIRSP4_IDLE_STATE_S 24 -#define SPIRSP4_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 26 - Illegal Cmd error */ -#define SPIRSP4_ILLEGAL_CMD_S 26 -#define SPIRSP4_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 27 - COM CRC error */ -#define SPIRSP4_COM_CRC_ERROR_S 27 -#define SPIRSP4_FUNC_NUM_ERROR_M BITFIELD_MASK(1) /* Bit 28 - Function number error - */ -#define SPIRSP4_FUNC_NUM_ERROR_S 28 -#define SPIRSP4_PARAM_ERROR_M BITFIELD_MASK(1) /* Bit 30 - Parameter Error Bit */ -#define SPIRSP4_PARAM_ERROR_S 30 -#define SPIRSP4_START_BIT_M BITFIELD_MASK(1) /* Bit 31 - Start Bit */ -#define SPIRSP4_START_BIT_S 31 - -#define SPIRSP5_DATA_M BITFIELD_MASK(8) /* Bits [23:16] - R/W Data */ -#define SPIRSP5_DATA_S 16 -#define SPIRSP5_IDLE_STATE_M BITFIELD_MASK(1) /* Bit 24 - Idle state */ -#define SPIRSP5_IDLE_STATE_S 24 -#define SPIRSP5_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 26 - Illegal Cmd error */ -#define SPIRSP5_ILLEGAL_CMD_S 26 -#define SPIRSP5_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 27 - COM CRC error */ -#define SPIRSP5_COM_CRC_ERROR_S 27 -#define SPIRSP5_FUNC_NUM_ERROR_M BITFIELD_MASK(1) /* Bit 28 - Function number error - */ -#define SPIRSP5_FUNC_NUM_ERROR_S 28 -#define SPIRSP5_PARAM_ERROR_M BITFIELD_MASK(1) /* Bit 30 - Parameter Error Bit */ -#define SPIRSP5_PARAM_ERROR_S 30 -#define SPIRSP5_START_BIT_M BITFIELD_MASK(1) /* Bit 31 - Start Bit */ -#define SPIRSP5_START_BIT_S 31 - -/* RSP6 card status format; Pg 68 Physical Layer spec v 1.10 */ -#define RSP6STAT_AKE_SEQ_ERROR_M BITFIELD_MASK(1) /* Bit 3 - Authentication seq error - */ -#define RSP6STAT_AKE_SEQ_ERROR_S 3 -#define RSP6STAT_APP_CMD_M BITFIELD_MASK(1) /* Bit 5 - Card expects ACMD */ -#define RSP6STAT_APP_CMD_S 5 -#define RSP6STAT_READY_FOR_DATA_M BITFIELD_MASK(1) /* Bit 8 - Ready for data - * (buff empty) - */ -#define RSP6STAT_READY_FOR_DATA_S 8 -#define RSP6STAT_CURR_STATE_M BITFIELD_MASK(4) /* Bits [12:9] - Card state at - * Cmd reception - */ -#define RSP6STAT_CURR_STATE_S 9 -#define RSP6STAT_ERROR_M BITFIELD_MASK(1) /* Bit 13 - General/Unknown error Bit 19 - */ -#define RSP6STAT_ERROR_S 13 -#define RSP6STAT_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 14 - Illegal cmd for - * card state Bit 22 - */ -#define RSP6STAT_ILLEGAL_CMD_S 14 -#define RSP6STAT_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 15 - CRC previous command - * failed Bit 23 - */ -#define RSP6STAT_COM_CRC_ERROR_S 15 - -#define SDIOH_XFER_TYPE_READ SD_IO_OP_READ -#define SDIOH_XFER_TYPE_WRITE SD_IO_OP_WRITE - -/* command issue options */ -#define CMD_OPTION_DEFAULT 0 -#define CMD_OPTION_TUNING 1 - -#endif /* _SDIO_H */ diff --git a/drivers/net/wireless/bcmdhd/include/sdioh.h b/drivers/net/wireless/bcmdhd/include/sdioh.h deleted file mode 100644 index 1d820d1569e7..000000000000 --- a/drivers/net/wireless/bcmdhd/include/sdioh.h +++ /dev/null @@ -1,446 +0,0 @@ -/* - * SDIO Host Controller Spec header file - * Register map and definitions for the Standard Host Controller - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sdioh.h 345478 2012-07-18 06:45:15Z $ - */ - -#ifndef _SDIOH_H -#define _SDIOH_H - -#define SD_SysAddr 0x000 -#define SD_BlockSize 0x004 -#define SD_BlockCount 0x006 -#define SD_Arg0 0x008 -#define SD_Arg1 0x00A -#define SD_TransferMode 0x00C -#define SD_Command 0x00E -#define SD_Response0 0x010 -#define SD_Response1 0x012 -#define SD_Response2 0x014 -#define SD_Response3 0x016 -#define SD_Response4 0x018 -#define SD_Response5 0x01A -#define SD_Response6 0x01C -#define SD_Response7 0x01E -#define SD_BufferDataPort0 0x020 -#define SD_BufferDataPort1 0x022 -#define SD_PresentState 0x024 -#define SD_HostCntrl 0x028 -#define SD_PwrCntrl 0x029 -#define SD_BlockGapCntrl 0x02A -#define SD_WakeupCntrl 0x02B -#define SD_ClockCntrl 0x02C -#define SD_TimeoutCntrl 0x02E -#define SD_SoftwareReset 0x02F -#define SD_IntrStatus 0x030 -#define SD_ErrorIntrStatus 0x032 -#define SD_IntrStatusEnable 0x034 -#define SD_ErrorIntrStatusEnable 0x036 -#define SD_IntrSignalEnable 0x038 -#define SD_ErrorIntrSignalEnable 0x03A -#define SD_CMD12ErrorStatus 0x03C -#define SD_Capabilities 0x040 -#define SD_Capabilities3 0x044 -#define SD_MaxCurCap 0x048 -#define SD_MaxCurCap_Reserved 0x04C -#define SD_ADMA_ErrStatus 0x054 -#define SD_ADMA_SysAddr 0x58 -#define SD_SlotInterruptStatus 0x0FC -#define SD_HostControllerVersion 0x0FE -#define SD_GPIO_Reg 0x100 -#define SD_GPIO_OE 0x104 -#define SD_GPIO_Enable 0x108 - - -/* SD specific registers in PCI config space */ -#define SD_SlotInfo 0x40 - -/* HC 3.0 specific registers and offsets */ -#define SD3_HostCntrl2 0x03E -/* preset regsstart and count */ -#define SD3_PresetValStart 0x060 -#define SD3_PresetValCount 8 -/* preset-indiv regs */ -#define SD3_PresetVal_init 0x060 -#define SD3_PresetVal_default 0x062 -#define SD3_PresetVal_HS 0x064 -#define SD3_PresetVal_SDR12 0x066 -#define SD3_PresetVal_SDR25 0x068 -#define SD3_PresetVal_SDR50 0x06a -#define SD3_PresetVal_SDR104 0x06c -#define SD3_PresetVal_DDR50 0x06e -/* SDIO3.0 Revx specific Registers */ -#define SD3_Tuning_Info_Register 0x0EC -#define SD3_WL_BT_reset_register 0x0F0 - - -/* preset value indices */ -#define SD3_PRESETVAL_INITIAL_IX 0 -#define SD3_PRESETVAL_DESPEED_IX 1 -#define SD3_PRESETVAL_HISPEED_IX 2 -#define SD3_PRESETVAL_SDR12_IX 3 -#define SD3_PRESETVAL_SDR25_IX 4 -#define SD3_PRESETVAL_SDR50_IX 5 -#define SD3_PRESETVAL_SDR104_IX 6 -#define SD3_PRESETVAL_DDR50_IX 7 - -/* SD_Capabilities reg (0x040) */ -#define CAP_TO_CLKFREQ_M BITFIELD_MASK(6) -#define CAP_TO_CLKFREQ_S 0 -#define CAP_TO_CLKUNIT_M BITFIELD_MASK(1) -#define CAP_TO_CLKUNIT_S 7 -/* Note: for sdio-2.0 case, this mask has to be 6 bits, but msb 2 - bits are reserved. going ahead with 8 bits, as it is req for 3.0 -*/ -#define CAP_BASECLK_M BITFIELD_MASK(8) -#define CAP_BASECLK_S 8 -#define CAP_MAXBLOCK_M BITFIELD_MASK(2) -#define CAP_MAXBLOCK_S 16 -#define CAP_ADMA2_M BITFIELD_MASK(1) -#define CAP_ADMA2_S 19 -#define CAP_ADMA1_M BITFIELD_MASK(1) -#define CAP_ADMA1_S 20 -#define CAP_HIGHSPEED_M BITFIELD_MASK(1) -#define CAP_HIGHSPEED_S 21 -#define CAP_DMA_M BITFIELD_MASK(1) -#define CAP_DMA_S 22 -#define CAP_SUSPEND_M BITFIELD_MASK(1) -#define CAP_SUSPEND_S 23 -#define CAP_VOLT_3_3_M BITFIELD_MASK(1) -#define CAP_VOLT_3_3_S 24 -#define CAP_VOLT_3_0_M BITFIELD_MASK(1) -#define CAP_VOLT_3_0_S 25 -#define CAP_VOLT_1_8_M BITFIELD_MASK(1) -#define CAP_VOLT_1_8_S 26 -#define CAP_64BIT_HOST_M BITFIELD_MASK(1) -#define CAP_64BIT_HOST_S 28 - -#define SDIO_OCR_READ_FAIL (2) - - -#define CAP_ASYNCINT_SUP_M BITFIELD_MASK(1) -#define CAP_ASYNCINT_SUP_S 29 - -#define CAP_SLOTTYPE_M BITFIELD_MASK(2) -#define CAP_SLOTTYPE_S 30 - -#define CAP3_MSBits_OFFSET (32) -/* note: following are caps MSB32 bits. - So the bits start from 0, instead of 32. that is why - CAP3_MSBits_OFFSET is subtracted. -*/ -#define CAP3_SDR50_SUP_M BITFIELD_MASK(1) -#define CAP3_SDR50_SUP_S (32 - CAP3_MSBits_OFFSET) - -#define CAP3_SDR104_SUP_M BITFIELD_MASK(1) -#define CAP3_SDR104_SUP_S (33 - CAP3_MSBits_OFFSET) - -#define CAP3_DDR50_SUP_M BITFIELD_MASK(1) -#define CAP3_DDR50_SUP_S (34 - CAP3_MSBits_OFFSET) - -/* for knowing the clk caps in a single read */ -#define CAP3_30CLKCAP_M BITFIELD_MASK(3) -#define CAP3_30CLKCAP_S (32 - CAP3_MSBits_OFFSET) - -#define CAP3_DRIVTYPE_A_M BITFIELD_MASK(1) -#define CAP3_DRIVTYPE_A_S (36 - CAP3_MSBits_OFFSET) - -#define CAP3_DRIVTYPE_C_M BITFIELD_MASK(1) -#define CAP3_DRIVTYPE_C_S (37 - CAP3_MSBits_OFFSET) - -#define CAP3_DRIVTYPE_D_M BITFIELD_MASK(1) -#define CAP3_DRIVTYPE_D_S (38 - CAP3_MSBits_OFFSET) - -#define CAP3_RETUNING_TC_M BITFIELD_MASK(4) -#define CAP3_RETUNING_TC_S (40 - CAP3_MSBits_OFFSET) - -#define CAP3_TUNING_SDR50_M BITFIELD_MASK(1) -#define CAP3_TUNING_SDR50_S (45 - CAP3_MSBits_OFFSET) - -#define CAP3_RETUNING_MODES_M BITFIELD_MASK(2) -#define CAP3_RETUNING_MODES_S (46 - CAP3_MSBits_OFFSET) - -#define CAP3_CLK_MULT_M BITFIELD_MASK(8) -#define CAP3_CLK_MULT_S (48 - CAP3_MSBits_OFFSET) - -#define PRESET_DRIVR_SELECT_M BITFIELD_MASK(2) -#define PRESET_DRIVR_SELECT_S 14 - -#define PRESET_CLK_DIV_M BITFIELD_MASK(10) -#define PRESET_CLK_DIV_S 0 - -/* SD_MaxCurCap reg (0x048) */ -#define CAP_CURR_3_3_M BITFIELD_MASK(8) -#define CAP_CURR_3_3_S 0 -#define CAP_CURR_3_0_M BITFIELD_MASK(8) -#define CAP_CURR_3_0_S 8 -#define CAP_CURR_1_8_M BITFIELD_MASK(8) -#define CAP_CURR_1_8_S 16 - -/* SD_SysAddr: Offset 0x0000, Size 4 bytes */ - -/* SD_BlockSize: Offset 0x004, Size 2 bytes */ -#define BLKSZ_BLKSZ_M BITFIELD_MASK(12) -#define BLKSZ_BLKSZ_S 0 -#define BLKSZ_BNDRY_M BITFIELD_MASK(3) -#define BLKSZ_BNDRY_S 12 - -/* SD_BlockCount: Offset 0x006, size 2 bytes */ - -/* SD_Arg0: Offset 0x008, size = 4 bytes */ -/* SD_TransferMode Offset 0x00C, size = 2 bytes */ -#define XFER_DMA_ENABLE_M BITFIELD_MASK(1) -#define XFER_DMA_ENABLE_S 0 -#define XFER_BLK_COUNT_EN_M BITFIELD_MASK(1) -#define XFER_BLK_COUNT_EN_S 1 -#define XFER_CMD_12_EN_M BITFIELD_MASK(1) -#define XFER_CMD_12_EN_S 2 -#define XFER_DATA_DIRECTION_M BITFIELD_MASK(1) -#define XFER_DATA_DIRECTION_S 4 -#define XFER_MULTI_BLOCK_M BITFIELD_MASK(1) -#define XFER_MULTI_BLOCK_S 5 - -/* SD_Command: Offset 0x00E, size = 2 bytes */ -/* resp_type field */ -#define RESP_TYPE_NONE 0 -#define RESP_TYPE_136 1 -#define RESP_TYPE_48 2 -#define RESP_TYPE_48_BUSY 3 -/* type field */ -#define CMD_TYPE_NORMAL 0 -#define CMD_TYPE_SUSPEND 1 -#define CMD_TYPE_RESUME 2 -#define CMD_TYPE_ABORT 3 - -#define CMD_RESP_TYPE_M BITFIELD_MASK(2) /* Bits [0-1] - Response type */ -#define CMD_RESP_TYPE_S 0 -#define CMD_CRC_EN_M BITFIELD_MASK(1) /* Bit 3 - CRC enable */ -#define CMD_CRC_EN_S 3 -#define CMD_INDEX_EN_M BITFIELD_MASK(1) /* Bit 4 - Enable index checking */ -#define CMD_INDEX_EN_S 4 -#define CMD_DATA_EN_M BITFIELD_MASK(1) /* Bit 5 - Using DAT line */ -#define CMD_DATA_EN_S 5 -#define CMD_TYPE_M BITFIELD_MASK(2) /* Bit [6-7] - Normal, abort, resume, etc - */ -#define CMD_TYPE_S 6 -#define CMD_INDEX_M BITFIELD_MASK(6) /* Bits [8-13] - Command number */ -#define CMD_INDEX_S 8 - -/* SD_BufferDataPort0 : Offset 0x020, size = 2 or 4 bytes */ -/* SD_BufferDataPort1 : Offset 0x022, size = 2 bytes */ -/* SD_PresentState : Offset 0x024, size = 4 bytes */ -#define PRES_CMD_INHIBIT_M BITFIELD_MASK(1) /* Bit 0 May use CMD */ -#define PRES_CMD_INHIBIT_S 0 -#define PRES_DAT_INHIBIT_M BITFIELD_MASK(1) /* Bit 1 May use DAT */ -#define PRES_DAT_INHIBIT_S 1 -#define PRES_DAT_BUSY_M BITFIELD_MASK(1) /* Bit 2 DAT is busy */ -#define PRES_DAT_BUSY_S 2 -#define PRES_PRESENT_RSVD_M BITFIELD_MASK(5) /* Bit [3-7] rsvd */ -#define PRES_PRESENT_RSVD_S 3 -#define PRES_WRITE_ACTIVE_M BITFIELD_MASK(1) /* Bit 8 Write is active */ -#define PRES_WRITE_ACTIVE_S 8 -#define PRES_READ_ACTIVE_M BITFIELD_MASK(1) /* Bit 9 Read is active */ -#define PRES_READ_ACTIVE_S 9 -#define PRES_WRITE_DATA_RDY_M BITFIELD_MASK(1) /* Bit 10 Write buf is avail */ -#define PRES_WRITE_DATA_RDY_S 10 -#define PRES_READ_DATA_RDY_M BITFIELD_MASK(1) /* Bit 11 Read buf data avail */ -#define PRES_READ_DATA_RDY_S 11 -#define PRES_CARD_PRESENT_M BITFIELD_MASK(1) /* Bit 16 Card present - debounced */ -#define PRES_CARD_PRESENT_S 16 -#define PRES_CARD_STABLE_M BITFIELD_MASK(1) /* Bit 17 Debugging */ -#define PRES_CARD_STABLE_S 17 -#define PRES_CARD_PRESENT_RAW_M BITFIELD_MASK(1) /* Bit 18 Not debounced */ -#define PRES_CARD_PRESENT_RAW_S 18 -#define PRES_WRITE_ENABLED_M BITFIELD_MASK(1) /* Bit 19 Write protected? */ -#define PRES_WRITE_ENABLED_S 19 -#define PRES_DAT_SIGNAL_M BITFIELD_MASK(4) /* Bit [20-23] Debugging */ -#define PRES_DAT_SIGNAL_S 20 -#define PRES_CMD_SIGNAL_M BITFIELD_MASK(1) /* Bit 24 Debugging */ -#define PRES_CMD_SIGNAL_S 24 - -/* SD_HostCntrl: Offset 0x028, size = 1 bytes */ -#define HOST_LED_M BITFIELD_MASK(1) /* Bit 0 LED On/Off */ -#define HOST_LED_S 0 -#define HOST_DATA_WIDTH_M BITFIELD_MASK(1) /* Bit 1 4 bit enable */ -#define HOST_DATA_WIDTH_S 1 -#define HOST_HI_SPEED_EN_M BITFIELD_MASK(1) /* Bit 2 High speed vs low speed */ -#define HOST_DMA_SEL_S 3 -#define HOST_DMA_SEL_M BITFIELD_MASK(2) /* Bit 4:3 DMA Select */ -#define HOST_HI_SPEED_EN_S 2 - -/* Host Control2: */ -#define HOSTCtrl2_PRESVAL_EN_M BITFIELD_MASK(1) /* 1 bit */ -#define HOSTCtrl2_PRESVAL_EN_S 15 /* bit# */ - -#define HOSTCtrl2_ASYINT_EN_M BITFIELD_MASK(1) /* 1 bit */ -#define HOSTCtrl2_ASYINT_EN_S 14 /* bit# */ - -#define HOSTCtrl2_SAMPCLK_SEL_M BITFIELD_MASK(1) /* 1 bit */ -#define HOSTCtrl2_SAMPCLK_SEL_S 7 /* bit# */ - -#define HOSTCtrl2_EXEC_TUNING_M BITFIELD_MASK(1) /* 1 bit */ -#define HOSTCtrl2_EXEC_TUNING_S 6 /* bit# */ - -#define HOSTCtrl2_DRIVSTRENGTH_SEL_M BITFIELD_MASK(2) /* 2 bit */ -#define HOSTCtrl2_DRIVSTRENGTH_SEL_S 4 /* bit# */ - -#define HOSTCtrl2_1_8SIG_EN_M BITFIELD_MASK(1) /* 1 bit */ -#define HOSTCtrl2_1_8SIG_EN_S 3 /* bit# */ - -#define HOSTCtrl2_UHSMODE_SEL_M BITFIELD_MASK(3) /* 3 bit */ -#define HOSTCtrl2_UHSMODE_SEL_S 0 /* bit# */ - -#define HOST_CONTR_VER_2 (1) -#define HOST_CONTR_VER_3 (2) - -/* misc defines */ -#define SD1_MODE 0x1 /* SD Host Cntrlr Spec */ -#define SD4_MODE 0x2 /* SD Host Cntrlr Spec */ - -/* SD_PwrCntrl: Offset 0x029, size = 1 bytes */ -#define PWR_BUS_EN_M BITFIELD_MASK(1) /* Bit 0 Power the bus */ -#define PWR_BUS_EN_S 0 -#define PWR_VOLTS_M BITFIELD_MASK(3) /* Bit [1-3] Voltage Select */ -#define PWR_VOLTS_S 1 - -/* SD_SoftwareReset: Offset 0x02F, size = 1 byte */ -#define SW_RESET_ALL_M BITFIELD_MASK(1) /* Bit 0 Reset All */ -#define SW_RESET_ALL_S 0 -#define SW_RESET_CMD_M BITFIELD_MASK(1) /* Bit 1 CMD Line Reset */ -#define SW_RESET_CMD_S 1 -#define SW_RESET_DAT_M BITFIELD_MASK(1) /* Bit 2 DAT Line Reset */ -#define SW_RESET_DAT_S 2 - -/* SD_IntrStatus: Offset 0x030, size = 2 bytes */ -/* Defs also serve SD_IntrStatusEnable and SD_IntrSignalEnable */ -#define INTSTAT_CMD_COMPLETE_M BITFIELD_MASK(1) /* Bit 0 */ -#define INTSTAT_CMD_COMPLETE_S 0 -#define INTSTAT_XFER_COMPLETE_M BITFIELD_MASK(1) -#define INTSTAT_XFER_COMPLETE_S 1 -#define INTSTAT_BLOCK_GAP_EVENT_M BITFIELD_MASK(1) -#define INTSTAT_BLOCK_GAP_EVENT_S 2 -#define INTSTAT_DMA_INT_M BITFIELD_MASK(1) -#define INTSTAT_DMA_INT_S 3 -#define INTSTAT_BUF_WRITE_READY_M BITFIELD_MASK(1) -#define INTSTAT_BUF_WRITE_READY_S 4 -#define INTSTAT_BUF_READ_READY_M BITFIELD_MASK(1) -#define INTSTAT_BUF_READ_READY_S 5 -#define INTSTAT_CARD_INSERTION_M BITFIELD_MASK(1) -#define INTSTAT_CARD_INSERTION_S 6 -#define INTSTAT_CARD_REMOVAL_M BITFIELD_MASK(1) -#define INTSTAT_CARD_REMOVAL_S 7 -#define INTSTAT_CARD_INT_M BITFIELD_MASK(1) -#define INTSTAT_CARD_INT_S 8 -#define INTSTAT_RETUNING_INT_M BITFIELD_MASK(1) /* Bit 12 */ -#define INTSTAT_RETUNING_INT_S 12 -#define INTSTAT_ERROR_INT_M BITFIELD_MASK(1) /* Bit 15 */ -#define INTSTAT_ERROR_INT_S 15 - -/* SD_ErrorIntrStatus: Offset 0x032, size = 2 bytes */ -/* Defs also serve SD_ErrorIntrStatusEnable and SD_ErrorIntrSignalEnable */ -#define ERRINT_CMD_TIMEOUT_M BITFIELD_MASK(1) -#define ERRINT_CMD_TIMEOUT_S 0 -#define ERRINT_CMD_CRC_M BITFIELD_MASK(1) -#define ERRINT_CMD_CRC_S 1 -#define ERRINT_CMD_ENDBIT_M BITFIELD_MASK(1) -#define ERRINT_CMD_ENDBIT_S 2 -#define ERRINT_CMD_INDEX_M BITFIELD_MASK(1) -#define ERRINT_CMD_INDEX_S 3 -#define ERRINT_DATA_TIMEOUT_M BITFIELD_MASK(1) -#define ERRINT_DATA_TIMEOUT_S 4 -#define ERRINT_DATA_CRC_M BITFIELD_MASK(1) -#define ERRINT_DATA_CRC_S 5 -#define ERRINT_DATA_ENDBIT_M BITFIELD_MASK(1) -#define ERRINT_DATA_ENDBIT_S 6 -#define ERRINT_CURRENT_LIMIT_M BITFIELD_MASK(1) -#define ERRINT_CURRENT_LIMIT_S 7 -#define ERRINT_AUTO_CMD12_M BITFIELD_MASK(1) -#define ERRINT_AUTO_CMD12_S 8 -#define ERRINT_VENDOR_M BITFIELD_MASK(4) -#define ERRINT_VENDOR_S 12 -#define ERRINT_ADMA_M BITFIELD_MASK(1) -#define ERRINT_ADMA_S 9 - -/* Also provide definitions in "normal" form to allow combined masks */ -#define ERRINT_CMD_TIMEOUT_BIT 0x0001 -#define ERRINT_CMD_CRC_BIT 0x0002 -#define ERRINT_CMD_ENDBIT_BIT 0x0004 -#define ERRINT_CMD_INDEX_BIT 0x0008 -#define ERRINT_DATA_TIMEOUT_BIT 0x0010 -#define ERRINT_DATA_CRC_BIT 0x0020 -#define ERRINT_DATA_ENDBIT_BIT 0x0040 -#define ERRINT_CURRENT_LIMIT_BIT 0x0080 -#define ERRINT_AUTO_CMD12_BIT 0x0100 -#define ERRINT_ADMA_BIT 0x0200 - -/* Masks to select CMD vs. DATA errors */ -#define ERRINT_CMD_ERRS (ERRINT_CMD_TIMEOUT_BIT | ERRINT_CMD_CRC_BIT |\ - ERRINT_CMD_ENDBIT_BIT | ERRINT_CMD_INDEX_BIT) -#define ERRINT_DATA_ERRS (ERRINT_DATA_TIMEOUT_BIT | ERRINT_DATA_CRC_BIT |\ - ERRINT_DATA_ENDBIT_BIT | ERRINT_ADMA_BIT) -#define ERRINT_TRANSFER_ERRS (ERRINT_CMD_ERRS | ERRINT_DATA_ERRS) - -/* SD_WakeupCntr_BlockGapCntrl : Offset 0x02A , size = bytes */ -/* SD_ClockCntrl : Offset 0x02C , size = bytes */ -/* SD_SoftwareReset_TimeoutCntrl : Offset 0x02E , size = bytes */ -/* SD_IntrStatus : Offset 0x030 , size = bytes */ -/* SD_ErrorIntrStatus : Offset 0x032 , size = bytes */ -/* SD_IntrStatusEnable : Offset 0x034 , size = bytes */ -/* SD_ErrorIntrStatusEnable : Offset 0x036 , size = bytes */ -/* SD_IntrSignalEnable : Offset 0x038 , size = bytes */ -/* SD_ErrorIntrSignalEnable : Offset 0x03A , size = bytes */ -/* SD_CMD12ErrorStatus : Offset 0x03C , size = bytes */ -/* SD_Capabilities : Offset 0x040 , size = bytes */ -/* SD_MaxCurCap : Offset 0x048 , size = bytes */ -/* SD_MaxCurCap_Reserved: Offset 0x04C , size = bytes */ -/* SD_SlotInterruptStatus: Offset 0x0FC , size = bytes */ -/* SD_HostControllerVersion : Offset 0x0FE , size = bytes */ - -/* SDIO Host Control Register DMA Mode Definitions */ -#define SDIOH_SDMA_MODE 0 -#define SDIOH_ADMA1_MODE 1 -#define SDIOH_ADMA2_MODE 2 -#define SDIOH_ADMA2_64_MODE 3 - -#define ADMA2_ATTRIBUTE_VALID (1 << 0) /* ADMA Descriptor line valid */ -#define ADMA2_ATTRIBUTE_END (1 << 1) /* End of Descriptor */ -#define ADMA2_ATTRIBUTE_INT (1 << 2) /* Interrupt when line is done */ -#define ADMA2_ATTRIBUTE_ACT_NOP (0 << 4) /* Skip current line, go to next. */ -#define ADMA2_ATTRIBUTE_ACT_RSV (1 << 4) /* Same as NOP */ -#define ADMA1_ATTRIBUTE_ACT_SET (1 << 4) /* ADMA1 Only - set transfer length */ -#define ADMA2_ATTRIBUTE_ACT_TRAN (2 << 4) /* Transfer Data of one descriptor line. */ -#define ADMA2_ATTRIBUTE_ACT_LINK (3 << 4) /* Link Descriptor */ - -/* ADMA2 Descriptor Table Entry for 32-bit Address */ -typedef struct adma2_dscr_32b { - uint32 len_attr; - uint32 phys_addr; -} adma2_dscr_32b_t; - -/* ADMA1 Descriptor Table Entry */ -typedef struct adma1_dscr { - uint32 phys_addr_attr; -} adma1_dscr_t; - -#endif /* _SDIOH_H */ diff --git a/drivers/net/wireless/bcmdhd/include/sdiovar.h b/drivers/net/wireless/bcmdhd/include/sdiovar.h deleted file mode 100644 index 55a3d3490c30..000000000000 --- a/drivers/net/wireless/bcmdhd/include/sdiovar.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Structure used by apps whose drivers access SDIO drivers. - * Pulled out separately so dhdu and wlu can both use it. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sdiovar.h 277737 2011-08-16 17:54:59Z $ - */ - -#ifndef _sdiovar_h_ -#define _sdiovar_h_ - -#include - -/* require default structure packing */ -#define BWL_DEFAULT_PACKING -#include - -typedef struct sdreg { - int func; - int offset; - int value; -} sdreg_t; - -/* Common msglevel constants */ -#define SDH_ERROR_VAL 0x0001 /* Error */ -#define SDH_TRACE_VAL 0x0002 /* Trace */ -#define SDH_INFO_VAL 0x0004 /* Info */ -#define SDH_DEBUG_VAL 0x0008 /* Debug */ -#define SDH_DATA_VAL 0x0010 /* Data */ -#define SDH_CTRL_VAL 0x0020 /* Control Regs */ -#define SDH_LOG_VAL 0x0040 /* Enable bcmlog */ -#define SDH_DMA_VAL 0x0080 /* DMA */ - -#define NUM_PREV_TRANSACTIONS 16 - - -#include - -#endif /* _sdiovar_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/siutils.h b/drivers/net/wireless/bcmdhd/include/siutils.h deleted file mode 100644 index 4e7aeb71cb02..000000000000 --- a/drivers/net/wireless/bcmdhd/include/siutils.h +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Misc utility routines for accessing the SOC Interconnects - * of Broadcom HNBU chips. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: siutils.h 335486 2012-05-28 09:47:55Z $ - */ - - -#ifndef _siutils_h_ -#define _siutils_h_ - - -struct si_pub { - uint socitype; - - uint bustype; - uint buscoretype; - uint buscorerev; - uint buscoreidx; - int ccrev; - uint32 cccaps; - uint32 cccaps_ext; - int pmurev; - uint32 pmucaps; - uint boardtype; - uint boardvendor; - uint boardflags; - uint boardflags2; - uint chip; - uint chiprev; - uint chippkg; - uint32 chipst; - bool issim; - uint socirev; - bool pci_pr32414; - -}; - - -typedef const struct si_pub si_t; - - - -#define SI_OSH NULL - -#define BADIDX (SI_MAXCORES + 1) - - -#define XTAL 0x1 -#define PLL 0x2 - - -#define CLK_FAST 0 -#define CLK_DYNAMIC 2 - - -#define GPIO_DRV_PRIORITY 0 -#define GPIO_APP_PRIORITY 1 -#define GPIO_HI_PRIORITY 2 - - -#define GPIO_PULLUP 0 -#define GPIO_PULLDN 1 - - -#define GPIO_REGEVT 0 -#define GPIO_REGEVT_INTMSK 1 -#define GPIO_REGEVT_INTPOL 2 - - -#define SI_DEVPATH_BUFSZ 16 - - -#define SI_DOATTACH 1 -#define SI_PCIDOWN 2 -#define SI_PCIUP 3 - -#define ISSIM_ENAB(sih) 0 - - -#if defined(BCMPMUCTL) -#define PMUCTL_ENAB(sih) (BCMPMUCTL) -#else -#define PMUCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PMU) -#endif - - -#if defined(BCMPMUCTL) && BCMPMUCTL -#define CCCTL_ENAB(sih) (0) -#define CCPLL_ENAB(sih) (0) -#else -#define CCCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PWR_CTL) -#define CCPLL_ENAB(sih) ((sih)->cccaps & CC_CAP_PLL_MASK) -#endif - -typedef void (*gpio_handler_t)(uint32 stat, void *arg); - - - -extern si_t *si_attach(uint pcidev, osl_t *osh, void *regs, uint bustype, - void *sdh, char **vars, uint *varsz); -extern si_t *si_kattach(osl_t *osh); -extern void si_detach(si_t *sih); -extern bool si_pci_war16165(si_t *sih); - -extern uint si_corelist(si_t *sih, uint coreid[]); -extern uint si_coreid(si_t *sih); -extern uint si_flag(si_t *sih); -extern uint si_intflag(si_t *sih); -extern uint si_coreidx(si_t *sih); -extern uint si_coreunit(si_t *sih); -extern uint si_corevendor(si_t *sih); -extern uint si_corerev(si_t *sih); -extern void *si_osh(si_t *sih); -extern void si_setosh(si_t *sih, osl_t *osh); -extern uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); -extern void *si_coreregs(si_t *sih); -extern uint si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val); -extern uint32 si_core_cflags(si_t *sih, uint32 mask, uint32 val); -extern void si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val); -extern uint32 si_core_sflags(si_t *sih, uint32 mask, uint32 val); -extern bool si_iscoreup(si_t *sih); -extern uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit); -extern void *si_setcoreidx(si_t *sih, uint coreidx); -extern void *si_setcore(si_t *sih, uint coreid, uint coreunit); -extern void *si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val); -extern void si_restore_core(si_t *sih, uint coreid, uint intr_val); -extern int si_numaddrspaces(si_t *sih); -extern uint32 si_addrspace(si_t *sih, uint asidx); -extern uint32 si_addrspacesize(si_t *sih, uint asidx); -extern int si_corebist(si_t *sih); -extern void si_core_reset(si_t *sih, uint32 bits, uint32 resetbits); -extern void si_core_disable(si_t *sih, uint32 bits); -extern uint32 si_clock_rate(uint32 pll_type, uint32 n, uint32 m); -extern bool si_read_pmu_autopll(si_t *sih); -extern uint32 si_clock(si_t *sih); -extern uint32 si_alp_clock(si_t *sih); -extern uint32 si_ilp_clock(si_t *sih); -extern void si_pci_setup(si_t *sih, uint coremask); -extern void si_pcmcia_init(si_t *sih); -extern void si_setint(si_t *sih, int siflag); -extern bool si_backplane64(si_t *sih); -extern void si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn, - void *intrsenabled_fn, void *intr_arg); -extern void si_deregister_intr_callback(si_t *sih); -extern void si_clkctl_init(si_t *sih); -extern uint16 si_clkctl_fast_pwrup_delay(si_t *sih); -extern bool si_clkctl_cc(si_t *sih, uint mode); -extern int si_clkctl_xtal(si_t *sih, uint what, bool on); -extern uint32 si_gpiotimerval(si_t *sih, uint32 mask, uint32 val); -extern void si_btcgpiowar(si_t *sih); -extern bool si_deviceremoved(si_t *sih); -extern uint32 si_socram_size(si_t *sih); -extern uint32 si_socdevram_size(si_t *sih); -extern void si_socdevram(si_t *sih, bool set, uint8 *ennable, uint8 *protect); -extern bool si_socdevram_pkg(si_t *sih); - -extern void si_watchdog(si_t *sih, uint ticks); -extern void si_watchdog_ms(si_t *sih, uint32 ms); -extern void *si_gpiosetcore(si_t *sih); -extern uint32 si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority); -extern uint32 si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority); -extern uint32 si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority); -extern uint32 si_gpioin(si_t *sih); -extern uint32 si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority); -extern uint32 si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority); -extern uint32 si_gpioled(si_t *sih, uint32 mask, uint32 val); -extern uint32 si_gpioreserve(si_t *sih, uint32 gpio_num, uint8 priority); -extern uint32 si_gpiorelease(si_t *sih, uint32 gpio_num, uint8 priority); -extern uint32 si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val); -extern uint32 si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val); -extern uint32 si_gpio_int_enable(si_t *sih, bool enable); - - -extern void *si_gpio_handler_register(si_t *sih, uint32 e, bool lev, gpio_handler_t cb, void *arg); -extern void si_gpio_handler_unregister(si_t *sih, void* gpioh); -extern void si_gpio_handler_process(si_t *sih); - - -extern bool si_pci_pmecap(si_t *sih); -struct osl_info; -extern bool si_pci_fastpmecap(struct osl_info *osh); -extern bool si_pci_pmestat(si_t *sih); -extern void si_pci_pmeclr(si_t *sih); -extern void si_pci_pmeen(si_t *sih); -extern uint si_pcie_readreg(void *sih, uint addrtype, uint offset); - -extern void si_sdio_init(si_t *sih); - -extern uint16 si_d11_devid(si_t *sih); -extern int si_corepciid(si_t *sih, uint func, uint16 *pcivendor, uint16 *pcidevice, - uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif, uint8 *pciheader); - -#define si_eci(sih) 0 -#define si_eci_init(sih) (0) -#define si_eci_notify_bt(sih, type, val) (0) -#define si_seci(sih) 0 -static INLINE void * si_seci_init(si_t *sih, uint8 use_seci) {return NULL;} -#define si_seci_down(sih) do { } while (0) - - -extern bool si_is_otp_disabled(si_t *sih); -extern bool si_is_otp_powered(si_t *sih); -extern void si_otp_power(si_t *sih, bool on); -extern void si_set_otp_wr_volts(si_t *sih); -extern void si_set_otp_rd_volts(si_t *sih); - - -extern bool si_is_sprom_available(si_t *sih); -extern bool si_is_sprom_enabled(si_t *sih); -extern void si_sprom_enable(si_t *sih, bool enable); - - -extern int si_cis_source(si_t *sih); -#define CIS_DEFAULT 0 -#define CIS_SROM 1 -#define CIS_OTP 2 - - -#define DEFAULT_FAB 0x0 -#define CSM_FAB7 0x1 -#define TSMC_FAB12 0x2 -#define SMIC_FAB4 0x3 -extern int si_otp_fabid(si_t *sih, uint16 *fabid, bool rw); -extern uint16 si_fabid(si_t *sih); - - -extern int si_devpath(si_t *sih, char *path, int size); - -extern char *si_getdevpathvar(si_t *sih, const char *name); -extern int si_getdevpathintvar(si_t *sih, const char *name); - - -extern uint8 si_pcieclkreq(si_t *sih, uint32 mask, uint32 val); -extern uint32 si_pcielcreg(si_t *sih, uint32 mask, uint32 val); -extern void si_war42780_clkreq(si_t *sih, bool clkreq); -extern void si_pci_sleep(si_t *sih); -extern void si_pci_down(si_t *sih); -extern void si_pci_up(si_t *sih); -extern void si_pcie_war_ovr_update(si_t *sih, uint8 aspm); -extern void si_pcie_extendL1timer(si_t *sih, bool extend); -extern int si_pci_fixcfg(si_t *sih); -extern uint si_pll_reset(si_t *sih); - - - -extern bool si_taclear(si_t *sih, bool details); - - - -extern uint32 si_pciereg(si_t *sih, uint32 offset, uint32 mask, uint32 val, uint type); -extern uint32 si_pcieserdesreg(si_t *sih, uint32 mdioslave, uint32 offset, uint32 mask, uint32 val); - -char *si_getnvramflvar(si_t *sih, const char *name); - - -#endif diff --git a/drivers/net/wireless/bcmdhd/include/trxhdr.h b/drivers/net/wireless/bcmdhd/include/trxhdr.h deleted file mode 100644 index b52fb15ba5c0..000000000000 --- a/drivers/net/wireless/bcmdhd/include/trxhdr.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * TRX image file header format. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: trxhdr.h 286295 2011-09-27 06:39:43Z $ - */ - -#ifndef _TRX_HDR_H_ -#define _TRX_HDR_H_ - -#include - -#define TRX_MAGIC 0x30524448 /* "HDR0" */ -#define TRX_VERSION 1 /* Version 1 */ -#define TRX_MAX_LEN 0x3B0000 /* Max length */ -#define TRX_NO_HEADER 1 /* Do not write TRX header */ -#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */ -#define TRX_OVERLAYS 0x4 /* Contains an overlay header after the trx header */ -#define TRX_MAX_OFFSET 3 /* Max number of individual files */ -#define TRX_UNCOMP_IMAGE 0x20 /* Trx contains uncompressed rtecdc.bin image */ -#define TRX_ROMSIM_IMAGE 0x10 /* Trx contains ROM simulation image */ - -struct trx_header { - uint32 magic; /* "HDR0" */ - uint32 len; /* Length of file including header */ - uint32 crc32; /* 32-bit CRC from flag_version to end of file */ - uint32 flag_version; /* 0:15 flags, 16:31 version */ - uint32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ -}; - -/* Compatibility */ -typedef struct trx_header TRXHDR, *PTRXHDR; - -#endif /* _TRX_HDR_H_ */ diff --git a/drivers/net/wireless/bcmdhd/include/typedefs.h b/drivers/net/wireless/bcmdhd/include/typedefs.h deleted file mode 100644 index d0902fe80891..000000000000 --- a/drivers/net/wireless/bcmdhd/include/typedefs.h +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * $Id: typedefs.h 290055 2011-10-15 21:26:26Z $ - */ - - -#ifndef _TYPEDEFS_H_ -#define _TYPEDEFS_H_ - -#ifdef SITE_TYPEDEFS - - - -#include "site_typedefs.h" - -#else - - - -#ifdef __cplusplus - -#define TYPEDEF_BOOL -#ifndef FALSE -#define FALSE false -#endif -#ifndef TRUE -#define TRUE true -#endif - -#else - - -#endif - -#if defined(__x86_64__) -#define TYPEDEF_UINTPTR -typedef unsigned long long int uintptr; -#endif - - - - - -#if defined(_NEED_SIZE_T_) -typedef long unsigned int size_t; -#endif - - - - - -#if defined(__sparc__) -#define TYPEDEF_ULONG -#endif - - - -#if !defined(LINUX_HYBRID) || defined(LINUX_PORT) -#define TYPEDEF_UINT -#ifndef TARGETENV_android -#define TYPEDEF_USHORT -#define TYPEDEF_ULONG -#endif -#ifdef __KERNEL__ -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)) -#define TYPEDEF_BOOL -#endif - -#if (LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18)) -#include -#ifdef noinline_for_stack -#define TYPEDEF_BOOL -#endif -#endif -#endif -#endif - - - - - -#if defined(__GNUC__) && defined(__STRICT_ANSI__) -#define TYPEDEF_INT64 -#define TYPEDEF_UINT64 -#endif - - -#if defined(__ICL) - -#define TYPEDEF_INT64 - -#if defined(__STDC__) -#define TYPEDEF_UINT64 -#endif - -#endif - -#if !defined(__DJGPP__) - - -#if defined(__KERNEL__) - - -#if !defined(LINUX_HYBRID) || defined(LINUX_PORT) -#include -#endif - -#else - - -#include - -#endif - -#endif - - - - -#define USE_TYPEDEF_DEFAULTS - -#endif - - - - -#ifdef USE_TYPEDEF_DEFAULTS -#undef USE_TYPEDEF_DEFAULTS - -#ifndef TYPEDEF_BOOL -typedef unsigned char bool; -#endif - - - -#ifndef TYPEDEF_UCHAR -typedef unsigned char uchar; -#endif - -#ifndef TYPEDEF_USHORT -typedef unsigned short ushort; -#endif - -#ifndef TYPEDEF_UINT -typedef unsigned int uint; -#endif - -#ifndef TYPEDEF_ULONG -typedef unsigned long ulong; -#endif - - - -#ifndef TYPEDEF_UINT8 -typedef unsigned char uint8; -#endif - -#ifndef TYPEDEF_UINT16 -typedef unsigned short uint16; -#endif - -#ifndef TYPEDEF_UINT32 -typedef unsigned int uint32; -#endif - -#ifndef TYPEDEF_UINT64 -typedef unsigned long long uint64; -#endif - -#ifndef TYPEDEF_UINTPTR -typedef unsigned int uintptr; -#endif - -#ifndef TYPEDEF_INT8 -typedef signed char int8; -#endif - -#ifndef TYPEDEF_INT16 -typedef signed short int16; -#endif - -#ifndef TYPEDEF_INT32 -typedef signed int int32; -#endif - -#ifndef TYPEDEF_INT64 -typedef signed long long int64; -#endif - - - -#ifndef TYPEDEF_FLOAT32 -typedef float float32; -#endif - -#ifndef TYPEDEF_FLOAT64 -typedef double float64; -#endif - - - -#ifndef TYPEDEF_FLOAT_T - -#if defined(FLOAT32) -typedef float32 float_t; -#else -typedef float64 float_t; -#endif - -#endif - - - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef OFF -#define OFF 0 -#endif - -#ifndef ON -#define ON 1 -#endif - -#define AUTO (-1) - - - -#ifndef PTRSZ -#define PTRSZ sizeof(char*) -#endif - - - -#if defined(__GNUC__) - #define BWL_COMPILER_GNU -#elif defined(__CC_ARM) && __CC_ARM - #define BWL_COMPILER_ARMCC -#else - #error "Unknown compiler!" -#endif - - -#ifndef INLINE - #if defined(BWL_COMPILER_MICROSOFT) - #define INLINE __inline - #elif defined(BWL_COMPILER_GNU) - #define INLINE __inline__ - #elif defined(BWL_COMPILER_ARMCC) - #define INLINE __inline - #else - #define INLINE - #endif -#endif - -#undef TYPEDEF_BOOL -#undef TYPEDEF_UCHAR -#undef TYPEDEF_USHORT -#undef TYPEDEF_UINT -#undef TYPEDEF_ULONG -#undef TYPEDEF_UINT8 -#undef TYPEDEF_UINT16 -#undef TYPEDEF_UINT32 -#undef TYPEDEF_UINT64 -#undef TYPEDEF_UINTPTR -#undef TYPEDEF_INT8 -#undef TYPEDEF_INT16 -#undef TYPEDEF_INT32 -#undef TYPEDEF_INT64 -#undef TYPEDEF_FLOAT32 -#undef TYPEDEF_FLOAT64 -#undef TYPEDEF_FLOAT_T - -#endif - - -#define UNUSED_PARAMETER(x) (void)(x) - - -#define DISCARD_QUAL(ptr, type) ((type *)(uintptr)(ptr)) - - -#include -#endif diff --git a/drivers/net/wireless/bcmdhd/include/wlfc_proto.h b/drivers/net/wireless/bcmdhd/include/wlfc_proto.h deleted file mode 100644 index d37105165bab..000000000000 --- a/drivers/net/wireless/bcmdhd/include/wlfc_proto.h +++ /dev/null @@ -1,198 +0,0 @@ -/* -* Copyright (C) 1999-2011, Broadcom Corporation -* -* Unless you and Broadcom execute a separate written software license -* agreement governing use of this software, this software is licensed to you -* under the terms of the GNU General Public License version 2 (the "GPL"), -* available at http://www.broadcom.com/licenses/GPLv2.php, with the -* following added to such license: -* -* As a special exception, the copyright holders of this software give you -* permission to link this software with independent modules, and to copy and -* distribute the resulting executable under terms of your choice, provided that -* you also meet, for each linked independent module, the terms and conditions of -* the license of that module. An independent module is a module which is not -* derived from this software. The special exception does not apply to any -* modifications of the software. -* -* Notwithstanding the above, under no circumstances may you combine this -* software in any way with any other Broadcom software provided under a license -* other than the GPL, without Broadcom's express prior written consent. -* $Id: wlfc_proto.h 277737 2011-08-16 17:54:59Z $ -* -*/ -#ifndef __wlfc_proto_definitions_h__ -#define __wlfc_proto_definitions_h__ - - /* Use TLV to convey WLFC information. - --------------------------------------------------------------------------- - | Type | Len | value | Description - --------------------------------------------------------------------------- - | 1 | 1 | (handle) | MAC OPEN - --------------------------------------------------------------------------- - | 2 | 1 | (handle) | MAC CLOSE - --------------------------------------------------------------------------- - | 3 | 2 | (count, handle, prec_bmp)| Set the credit depth for a MAC dstn - --------------------------------------------------------------------------- - | 4 | 4 | see pkttag comments | TXSTATUS - --------------------------------------------------------------------------- - | 5 | 4 | see pkttag comments | PKKTTAG [host->firmware] - --------------------------------------------------------------------------- - | 6 | 8 | (handle, ifid, MAC) | MAC ADD - --------------------------------------------------------------------------- - | 7 | 8 | (handle, ifid, MAC) | MAC DEL - --------------------------------------------------------------------------- - | 8 | 1 | (rssi) | RSSI - RSSI value for the packet. - --------------------------------------------------------------------------- - | 9 | 1 | (interface ID) | Interface OPEN - --------------------------------------------------------------------------- - | 10 | 1 | (interface ID) | Interface CLOSE - --------------------------------------------------------------------------- - | 11 | 8 | fifo credit returns map | FIFO credits back to the host - | | | | - | | | | -------------------------------------- - | | | | | ac0 | ac1 | ac2 | ac3 | bcmc | atim | - | | | | -------------------------------------- - | | | | - --------------------------------------------------------------------------- - | 12 | 2 | MAC handle, | Host provides a bitmap of pending - | | | AC[0-3] traffic bitmap | unicast traffic for MAC-handle dstn. - | | | | [host->firmware] - --------------------------------------------------------------------------- - | 13 | 3 | (count, handle, prec_bmp)| One time request for packet to a specific - | | | | MAC destination. - --------------------------------------------------------------------------- - | 255 | N/A | N/A | FILLER - This is a special type - | | | | that has no length or value. - | | | | Typically used for padding. - --------------------------------------------------------------------------- - */ - -#define WLFC_CTL_TYPE_MAC_OPEN 1 -#define WLFC_CTL_TYPE_MAC_CLOSE 2 -#define WLFC_CTL_TYPE_MAC_REQUEST_CREDIT 3 -#define WLFC_CTL_TYPE_TXSTATUS 4 -#define WLFC_CTL_TYPE_PKTTAG 5 - -#define WLFC_CTL_TYPE_MACDESC_ADD 6 -#define WLFC_CTL_TYPE_MACDESC_DEL 7 -#define WLFC_CTL_TYPE_RSSI 8 - -#define WLFC_CTL_TYPE_INTERFACE_OPEN 9 -#define WLFC_CTL_TYPE_INTERFACE_CLOSE 10 - -#define WLFC_CTL_TYPE_FIFO_CREDITBACK 11 - -#define WLFC_CTL_TYPE_PENDING_TRAFFIC_BMP 12 -#define WLFC_CTL_TYPE_MAC_REQUEST_PACKET 13 - -#define WLFC_CTL_TYPE_FILLER 255 - -#define WLFC_CTL_VALUE_LEN_MACDESC 8 /* handle, interface, MAC */ - -#define WLFC_CTL_VALUE_LEN_MAC 1 /* MAC-handle */ -#define WLFC_CTL_VALUE_LEN_RSSI 1 - -#define WLFC_CTL_VALUE_LEN_INTERFACE 1 -#define WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP 2 - -#define WLFC_CTL_VALUE_LEN_TXSTATUS 4 -#define WLFC_CTL_VALUE_LEN_PKTTAG 4 - -/* enough space to host all 4 ACs, bc/mc and atim fifo credit */ -#define WLFC_CTL_VALUE_LEN_FIFO_CREDITBACK 6 - -#define WLFC_CTL_VALUE_LEN_REQUEST_CREDIT 3 /* credit, MAC-handle, prec_bitmap */ -#define WLFC_CTL_VALUE_LEN_REQUEST_PACKET 3 /* credit, MAC-handle, prec_bitmap */ - - - -#define WLFC_PKTID_GEN_MASK 0x80000000 -#define WLFC_PKTID_GEN_SHIFT 31 - -#define WLFC_PKTID_GEN(x) (((x) & WLFC_PKTID_GEN_MASK) >> WLFC_PKTID_GEN_SHIFT) -#define WLFC_PKTID_SETGEN(x, gen) (x) = ((x) & ~WLFC_PKTID_GEN_MASK) | \ - (((gen) << WLFC_PKTID_GEN_SHIFT) & WLFC_PKTID_GEN_MASK) - -#define WLFC_PKTFLAG_PKTFROMHOST 0x01 -#define WLFC_PKTFLAG_PKT_REQUESTED 0x02 - -#define WL_TXSTATUS_FLAGS_MASK 0xf /* allow 4 bits only */ -#define WL_TXSTATUS_FLAGS_SHIFT 27 - -#define WL_TXSTATUS_SET_FLAGS(x, flags) ((x) = \ - ((x) & ~(WL_TXSTATUS_FLAGS_MASK << WL_TXSTATUS_FLAGS_SHIFT)) | \ - (((flags) & WL_TXSTATUS_FLAGS_MASK) << WL_TXSTATUS_FLAGS_SHIFT)) -#define WL_TXSTATUS_GET_FLAGS(x) (((x) >> WL_TXSTATUS_FLAGS_SHIFT) & \ - WL_TXSTATUS_FLAGS_MASK) - -#define WL_TXSTATUS_FIFO_MASK 0x7 /* allow 3 bits for FIFO ID */ -#define WL_TXSTATUS_FIFO_SHIFT 24 - -#define WL_TXSTATUS_SET_FIFO(x, flags) ((x) = \ - ((x) & ~(WL_TXSTATUS_FIFO_MASK << WL_TXSTATUS_FIFO_SHIFT)) | \ - (((flags) & WL_TXSTATUS_FIFO_MASK) << WL_TXSTATUS_FIFO_SHIFT)) -#define WL_TXSTATUS_GET_FIFO(x) (((x) >> WL_TXSTATUS_FIFO_SHIFT) & WL_TXSTATUS_FIFO_MASK) - -#define WL_TXSTATUS_PKTID_MASK 0xffffff /* allow 24 bits */ -#define WL_TXSTATUS_SET_PKTID(x, num) ((x) = \ - ((x) & ~WL_TXSTATUS_PKTID_MASK) | (num)) -#define WL_TXSTATUS_GET_PKTID(x) ((x) & WL_TXSTATUS_PKTID_MASK) - -/* 32 STA should be enough??, 6 bits; Must be power of 2 */ -#define WLFC_MAC_DESC_TABLE_SIZE 32 -#define WLFC_MAX_IFNUM 16 -#define WLFC_MAC_DESC_ID_INVALID 0xff - -/* b[7:5] -reuse guard, b[4:0] -value */ -#define WLFC_MAC_DESC_GET_LOOKUP_INDEX(x) ((x) & 0x1f) - -#define WLFC_PKTFLAG_SET_PKTREQUESTED(x) (x) |= \ - (WLFC_PKTFLAG_PKT_REQUESTED << WL_TXSTATUS_FLAGS_SHIFT) - -#define WLFC_PKTFLAG_CLR_PKTREQUESTED(x) (x) &= \ - ~(WLFC_PKTFLAG_PKT_REQUESTED << WL_TXSTATUS_FLAGS_SHIFT) - -#define WL_TXSTATUS_GENERATION_MASK 1 -#define WL_TXSTATUS_GENERATION_SHIFT 31 - -#define WLFC_PKTFLAG_SET_GENERATION(x, gen) ((x) = \ - ((x) & ~(WL_TXSTATUS_GENERATION_MASK << WL_TXSTATUS_GENERATION_SHIFT)) | \ - (((gen) & WL_TXSTATUS_GENERATION_MASK) << WL_TXSTATUS_GENERATION_SHIFT)) - -#define WLFC_PKTFLAG_GENERATION(x) (((x) >> WL_TXSTATUS_GENERATION_SHIFT) & \ - WL_TXSTATUS_GENERATION_MASK) - -#define WLFC_MAX_PENDING_DATALEN 120 - -/* host is free to discard the packet */ -#define WLFC_CTL_PKTFLAG_DISCARD 0 -/* D11 suppressed a packet */ -#define WLFC_CTL_PKTFLAG_D11SUPPRESS 1 -/* WL firmware suppressed a packet because MAC is - already in PSMode (short time window) -*/ -#define WLFC_CTL_PKTFLAG_WLSUPPRESS 2 -/* Firmware tossed this packet */ -#define WLFC_CTL_PKTFLAG_TOSSED_BYWLC 3 - -#define WLFC_D11_STATUS_INTERPRET(txs) ((((txs)->status & TX_STATUS_SUPR_MASK) >> \ - TX_STATUS_SUPR_SHIFT)) ? WLFC_CTL_PKTFLAG_D11SUPPRESS : WLFC_CTL_PKTFLAG_DISCARD - -#ifdef PROP_TXSTATUS_DEBUG -#define WLFC_DBGMESG(x) printf x -/* wlfc-breadcrumb */ -#define WLFC_BREADCRUMB(x) do {if ((x) == NULL) \ - {printf("WLFC: %s():%d:caller:%p\n", \ - __FUNCTION__, __LINE__, __builtin_return_address(0));}} while (0) -#define WLFC_PRINTMAC(banner, ea) do {printf("%s MAC: [%02x:%02x:%02x:%02x:%02x:%02x]\n", \ - banner, ea[0], ea[1], ea[2], ea[3], ea[4], ea[5]); } while (0) -#define WLFC_WHEREIS(s) printf("WLFC: at %s():%d, %s\n", __FUNCTION__, __LINE__, (s)) -#else -#define WLFC_DBGMESG(x) -#define WLFC_BREADCRUMB(x) -#define WLFC_PRINTMAC(banner, ea) -#define WLFC_WHEREIS(s) -#endif - -#endif /* __wlfc_proto_definitions_h__ */ diff --git a/drivers/net/wireless/bcmdhd/include/wlioctl.h b/drivers/net/wireless/bcmdhd/include/wlioctl.h deleted file mode 100644 index 2038e202a46b..000000000000 --- a/drivers/net/wireless/bcmdhd/include/wlioctl.h +++ /dev/null @@ -1,2763 +0,0 @@ -/* - * Custom OID/ioctl definitions for - * Broadcom 802.11abg Networking Device Driver - * - * Definitions subject to change without notice. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wlioctl.h 353331 2012-08-27 06:04:47Z $ - */ - - -#ifndef _wlioctl_h_ -#define _wlioctl_h_ - -#include -#include -#include -#include -#include -#include - -#include - -#ifndef INTF_NAME_SIZ -#define INTF_NAME_SIZ 16 -#endif - - -typedef struct remote_ioctl { - cdc_ioctl_t msg; - uint data_len; - char intf_name[INTF_NAME_SIZ]; -} rem_ioctl_t; -#define REMOTE_SIZE sizeof(rem_ioctl_t) - -#define ACTION_FRAME_SIZE 1040 - -typedef struct wl_action_frame { - struct ether_addr da; - uint16 len; - uint32 packetId; - uint8 data[ACTION_FRAME_SIZE]; -} wl_action_frame_t; - -#define WL_WIFI_ACTION_FRAME_SIZE sizeof(struct wl_action_frame) - -typedef struct ssid_info -{ - uint8 ssid_len; - uint8 ssid[32]; -} ssid_info_t; - -typedef struct wl_af_params { - uint32 channel; - int32 dwell_time; - struct ether_addr BSSID; - wl_action_frame_t action_frame; -} wl_af_params_t; - -#define WL_WIFI_AF_PARAMS_SIZE sizeof(struct wl_af_params) - - -#define BWL_DEFAULT_PACKING -#include - - -#define WL_BSS_INFO_VERSION 109 - - -typedef struct wl_bss_info { - uint32 version; - uint32 length; - struct ether_addr BSSID; - uint16 beacon_period; - uint16 capability; - uint8 SSID_len; - uint8 SSID[32]; - struct { - uint count; - uint8 rates[16]; - } rateset; - chanspec_t chanspec; - uint16 atim_window; - uint8 dtim_period; - int16 RSSI; - int8 phy_noise; - - uint8 n_cap; - uint32 nbss_cap; - uint8 ctl_ch; - uint32 reserved32[1]; - uint8 flags; - uint8 reserved[3]; - uint8 basic_mcs[MCSSET_LEN]; - - uint16 ie_offset; - uint32 ie_length; - int16 SNR; - - -} wl_bss_info_t; - - -#define WL_BSS_FLAGS_FROM_BEACON 0x01 -#define WL_BSS_FLAGS_FROM_CACHE 0x02 -#define WL_BSS_FLAGS_RSSI_ONCHANNEL 0x04 - - -#define VHT_BI_SGI_80MHZ 0x00000100 - -typedef struct wlc_ssid { - uint32 SSID_len; - uchar SSID[32]; -} wlc_ssid_t; - - -#define WL_BSSTYPE_INFRA 1 -#define WL_BSSTYPE_INDEP 0 -#define WL_BSSTYPE_ANY 2 - - -#define WL_SCANFLAGS_PASSIVE 0x01 -#define WL_SCANFLAGS_RESERVED 0x02 -#define WL_SCANFLAGS_PROHIBITED 0x04 - -#define WL_SCAN_PARAMS_SSID_MAX 10 - -typedef struct wl_scan_params { - wlc_ssid_t ssid; - struct ether_addr bssid; - int8 bss_type; - uint8 scan_type; - int32 nprobes; - int32 active_time; - int32 passive_time; - int32 home_time; - int32 channel_num; - uint16 channel_list[1]; -} wl_scan_params_t; - - -#define WL_SCAN_PARAMS_FIXED_SIZE 64 - - -#define WL_SCAN_PARAMS_COUNT_MASK 0x0000ffff -#define WL_SCAN_PARAMS_NSSID_SHIFT 16 - -#define WL_SCAN_ACTION_START 1 -#define WL_SCAN_ACTION_CONTINUE 2 -#define WL_SCAN_ACTION_ABORT 3 - -#define ISCAN_REQ_VERSION 1 - - -typedef struct wl_iscan_params { - uint32 version; - uint16 action; - uint16 scan_duration; - wl_scan_params_t params; -} wl_iscan_params_t; - - -#define WL_ISCAN_PARAMS_FIXED_SIZE (OFFSETOF(wl_iscan_params_t, params) + sizeof(wlc_ssid_t)) - -typedef struct wl_scan_results { - uint32 buflen; - uint32 version; - uint32 count; - wl_bss_info_t bss_info[1]; -} wl_scan_results_t; - - -#define WL_SCAN_RESULTS_FIXED_SIZE (sizeof(wl_scan_results_t) - sizeof(wl_bss_info_t)) - - -#define WL_SCAN_RESULTS_SUCCESS 0 -#define WL_SCAN_RESULTS_PARTIAL 1 -#define WL_SCAN_RESULTS_PENDING 2 -#define WL_SCAN_RESULTS_ABORTED 3 -#define WL_SCAN_RESULTS_NO_MEM 4 - - -#define DNGL_RXCTXT_SIZE 45 - -#if defined(SIMPLE_ISCAN) -#define ISCAN_RETRY_CNT 5 -#define ISCAN_STATE_IDLE 0 -#define ISCAN_STATE_SCANING 1 -#define ISCAN_STATE_PENDING 2 - - -#define WLC_IW_ISCAN_MAXLEN 2048 -typedef struct iscan_buf { - struct iscan_buf * next; - char iscan_buf[WLC_IW_ISCAN_MAXLEN]; -} iscan_buf_t; -#endif - -#define ESCAN_REQ_VERSION 1 - -typedef struct wl_escan_params { - uint32 version; - uint16 action; - uint16 sync_id; - wl_scan_params_t params; -} wl_escan_params_t; - -#define WL_ESCAN_PARAMS_FIXED_SIZE (OFFSETOF(wl_escan_params_t, params) + sizeof(wlc_ssid_t)) - -typedef struct wl_escan_result { - uint32 buflen; - uint32 version; - uint16 sync_id; - uint16 bss_count; - wl_bss_info_t bss_info[1]; -} wl_escan_result_t; - -#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(wl_escan_result_t) - sizeof(wl_bss_info_t)) - - -typedef struct wl_iscan_results { - uint32 status; - wl_scan_results_t results; -} wl_iscan_results_t; - - -#define WL_ISCAN_RESULTS_FIXED_SIZE \ - (WL_SCAN_RESULTS_FIXED_SIZE + OFFSETOF(wl_iscan_results_t, results)) - -typedef struct wl_probe_params { - wlc_ssid_t ssid; - struct ether_addr bssid; - struct ether_addr mac; -} wl_probe_params_t; - -#define WL_NUMRATES 16 -typedef struct wl_rateset { - uint32 count; - uint8 rates[WL_NUMRATES]; -} wl_rateset_t; - -typedef struct wl_rateset_args { - uint32 count; - uint8 rates[WL_NUMRATES]; - uint8 mcs[MCSSET_LEN]; -} wl_rateset_args_t; - - -typedef struct wl_uint32_list { - - uint32 count; - - uint32 element[1]; -} wl_uint32_list_t; - - -typedef struct wl_assoc_params { - struct ether_addr bssid; - uint16 bssid_cnt; - int32 chanspec_num; - chanspec_t chanspec_list[1]; -} wl_assoc_params_t; -#define WL_ASSOC_PARAMS_FIXED_SIZE (sizeof(wl_assoc_params_t) - sizeof(chanspec_t)) - - -typedef wl_assoc_params_t wl_reassoc_params_t; -#define WL_REASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE - - -typedef wl_assoc_params_t wl_join_assoc_params_t; -#define WL_JOIN_ASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE - - -typedef struct wl_join_params { - wlc_ssid_t ssid; - wl_assoc_params_t params; -} wl_join_params_t; -#define WL_JOIN_PARAMS_FIXED_SIZE (sizeof(wl_join_params_t) - sizeof(chanspec_t)) - - -typedef struct wl_join_scan_params { - uint8 scan_type; - int32 nprobes; - int32 active_time; - int32 passive_time; - int32 home_time; -} wl_join_scan_params_t; - - -typedef struct wl_extjoin_params { - wlc_ssid_t ssid; - wl_join_scan_params_t scan; - wl_join_assoc_params_t assoc; -} wl_extjoin_params_t; -#define WL_EXTJOIN_PARAMS_FIXED_SIZE (sizeof(wl_extjoin_params_t) - sizeof(chanspec_t)) - -typedef struct { - uint32 num; - chanspec_t list[1]; -} chanspec_list_t; - - -#define NRATE_MCS_INUSE 0x00000080 -#define NRATE_RATE_MASK 0x0000007f -#define NRATE_STF_MASK 0x0000ff00 -#define NRATE_STF_SHIFT 8 -#define NRATE_OVERRIDE 0x80000000 -#define NRATE_OVERRIDE_MCS_ONLY 0x40000000 -#define NRATE_SGI_MASK 0x00800000 -#define NRATE_SGI_SHIFT 23 -#define NRATE_LDPC_CODING 0x00400000 -#define NRATE_LDPC_SHIFT 22 -#define NRATE_BCMC_OVERRIDE 0x00200000 -#define NRATE_BCMC_SHIFT 21 - -#define NRATE_STF_SISO 0 -#define NRATE_STF_CDD 1 -#define NRATE_STF_STBC 2 -#define NRATE_STF_SDM 3 - -#define ANTENNA_NUM_1 1 -#define ANTENNA_NUM_2 2 -#define ANTENNA_NUM_3 3 -#define ANTENNA_NUM_4 4 - -#define ANT_SELCFG_AUTO 0x80 -#define ANT_SELCFG_MASK 0x33 -#define ANT_SELCFG_MAX 4 -#define ANT_SELCFG_TX_UNICAST 0 -#define ANT_SELCFG_RX_UNICAST 1 -#define ANT_SELCFG_TX_DEF 2 -#define ANT_SELCFG_RX_DEF 3 - -#define MAX_STREAMS_SUPPORTED 4 - -typedef struct { - uint8 ant_config[ANT_SELCFG_MAX]; - uint8 num_antcfg; -} wlc_antselcfg_t; - -#define HIGHEST_SINGLE_STREAM_MCS 7 - -#define MAX_CCA_CHANNELS 38 -#define MAX_CCA_SECS 60 - -#define IBSS_MED 15 -#define IBSS_HI 25 -#define OBSS_MED 12 -#define OBSS_HI 25 -#define INTERFER_MED 5 -#define INTERFER_HI 10 - -#define CCA_FLAG_2G_ONLY 0x01 -#define CCA_FLAG_5G_ONLY 0x02 -#define CCA_FLAG_IGNORE_DURATION 0x04 -#define CCA_FLAGS_PREFER_1_6_11 0x10 -#define CCA_FLAG_IGNORE_INTERFER 0x20 - -#define CCA_ERRNO_BAND 1 -#define CCA_ERRNO_DURATION 2 -#define CCA_ERRNO_PREF_CHAN 3 -#define CCA_ERRNO_INTERFER 4 -#define CCA_ERRNO_TOO_FEW 5 - -typedef struct { - uint32 duration; - uint32 congest_ibss; - - uint32 congest_obss; - uint32 interference; - uint32 timestamp; -} cca_congest_t; - -typedef struct { - chanspec_t chanspec; - uint8 num_secs; - cca_congest_t secs[1]; -} cca_congest_channel_req_t; - -#define WLC_CNTRY_BUF_SZ 4 - -typedef struct wl_country { - char country_abbrev[WLC_CNTRY_BUF_SZ]; - int32 rev; - char ccode[WLC_CNTRY_BUF_SZ]; -} wl_country_t; - -typedef struct wl_channels_in_country { - uint32 buflen; - uint32 band; - char country_abbrev[WLC_CNTRY_BUF_SZ]; - uint32 count; - uint32 channel[1]; -} wl_channels_in_country_t; - -typedef struct wl_country_list { - uint32 buflen; - uint32 band_set; - uint32 band; - uint32 count; - char country_abbrev[1]; -} wl_country_list_t; - -#define WL_NUM_RPI_BINS 8 -#define WL_RM_TYPE_BASIC 1 -#define WL_RM_TYPE_CCA 2 -#define WL_RM_TYPE_RPI 3 - -#define WL_RM_FLAG_PARALLEL (1<<0) - -#define WL_RM_FLAG_LATE (1<<1) -#define WL_RM_FLAG_INCAPABLE (1<<2) -#define WL_RM_FLAG_REFUSED (1<<3) - -typedef struct wl_rm_req_elt { - int8 type; - int8 flags; - chanspec_t chanspec; - uint32 token; - uint32 tsf_h; - uint32 tsf_l; - uint32 dur; -} wl_rm_req_elt_t; - -typedef struct wl_rm_req { - uint32 token; - uint32 count; - void *cb; - void *cb_arg; - wl_rm_req_elt_t req[1]; -} wl_rm_req_t; -#define WL_RM_REQ_FIXED_LEN OFFSETOF(wl_rm_req_t, req) - -typedef struct wl_rm_rep_elt { - int8 type; - int8 flags; - chanspec_t chanspec; - uint32 token; - uint32 tsf_h; - uint32 tsf_l; - uint32 dur; - uint32 len; - uint8 data[1]; -} wl_rm_rep_elt_t; -#define WL_RM_REP_ELT_FIXED_LEN 24 - -#define WL_RPI_REP_BIN_NUM 8 -typedef struct wl_rm_rpi_rep { - uint8 rpi[WL_RPI_REP_BIN_NUM]; - int8 rpi_max[WL_RPI_REP_BIN_NUM]; -} wl_rm_rpi_rep_t; - -typedef struct wl_rm_rep { - uint32 token; - uint32 len; - wl_rm_rep_elt_t rep[1]; -} wl_rm_rep_t; -#define WL_RM_REP_FIXED_LEN 8 - - -typedef enum sup_auth_status { - - WLC_SUP_DISCONNECTED = 0, - WLC_SUP_CONNECTING, - WLC_SUP_IDREQUIRED, - WLC_SUP_AUTHENTICATING, - WLC_SUP_AUTHENTICATED, - WLC_SUP_KEYXCHANGE, - WLC_SUP_KEYED, - WLC_SUP_TIMEOUT, - WLC_SUP_LAST_BASIC_STATE, - - - - WLC_SUP_KEYXCHANGE_WAIT_M1 = WLC_SUP_AUTHENTICATED, - - WLC_SUP_KEYXCHANGE_PREP_M2 = WLC_SUP_KEYXCHANGE, - - WLC_SUP_KEYXCHANGE_WAIT_M3 = WLC_SUP_LAST_BASIC_STATE, - WLC_SUP_KEYXCHANGE_PREP_M4, - WLC_SUP_KEYXCHANGE_WAIT_G1, - WLC_SUP_KEYXCHANGE_PREP_G2 -} sup_auth_status_t; - - -#define CRYPTO_ALGO_OFF 0 -#define CRYPTO_ALGO_WEP1 1 -#define CRYPTO_ALGO_TKIP 2 -#define CRYPTO_ALGO_WEP128 3 -#define CRYPTO_ALGO_AES_CCM 4 -#define CRYPTO_ALGO_AES_OCB_MSDU 5 -#define CRYPTO_ALGO_AES_OCB_MPDU 6 -#define CRYPTO_ALGO_NALG 7 -#define CRYPTO_ALGO_PMK 12 - -#define WSEC_GEN_MIC_ERROR 0x0001 -#define WSEC_GEN_REPLAY 0x0002 -#define WSEC_GEN_ICV_ERROR 0x0004 - -#define WL_SOFT_KEY (1 << 0) -#define WL_PRIMARY_KEY (1 << 1) -#define WL_KF_RES_4 (1 << 4) -#define WL_KF_RES_5 (1 << 5) -#define WL_IBSS_PEER_GROUP_KEY (1 << 6) - -typedef struct wl_wsec_key { - uint32 index; - uint32 len; - uint8 data[DOT11_MAX_KEY_SIZE]; - uint32 pad_1[18]; - uint32 algo; - uint32 flags; - uint32 pad_2[2]; - int pad_3; - int iv_initialized; - int pad_4; - - struct { - uint32 hi; - uint16 lo; - } rxiv; - uint32 pad_5[2]; - struct ether_addr ea; -} wl_wsec_key_t; - -#define WSEC_MIN_PSK_LEN 8 -#define WSEC_MAX_PSK_LEN 64 - - -#define WSEC_PASSPHRASE (1<<0) - - -typedef struct { - ushort key_len; - ushort flags; - uint8 key[WSEC_MAX_PSK_LEN]; -} wsec_pmk_t; - - -#define WEP_ENABLED 0x0001 -#define TKIP_ENABLED 0x0002 -#define AES_ENABLED 0x0004 -#define WSEC_SWFLAG 0x0008 -#define SES_OW_ENABLED 0x0040 - - -#define WPA_AUTH_DISABLED 0x0000 -#define WPA_AUTH_NONE 0x0001 -#define WPA_AUTH_UNSPECIFIED 0x0002 -#define WPA_AUTH_PSK 0x0004 - -#define WPA2_AUTH_UNSPECIFIED 0x0040 -#define WPA2_AUTH_PSK 0x0080 -#define BRCM_AUTH_PSK 0x0100 -#define BRCM_AUTH_DPT 0x0200 -#define WPA2_AUTH_MFP 0x1000 -#define WPA2_AUTH_TPK 0x2000 -#define WPA2_AUTH_FT 0x4000 - - -#define MAXPMKID 16 - -typedef struct _pmkid { - struct ether_addr BSSID; - uint8 PMKID[WPA2_PMKID_LEN]; -} pmkid_t; - -typedef struct _pmkid_list { - uint32 npmkid; - pmkid_t pmkid[1]; -} pmkid_list_t; - -typedef struct _pmkid_cand { - struct ether_addr BSSID; - uint8 preauth; -} pmkid_cand_t; - -typedef struct _pmkid_cand_list { - uint32 npmkid_cand; - pmkid_cand_t pmkid_cand[1]; -} pmkid_cand_list_t; - -typedef struct wl_assoc_info { - uint32 req_len; - uint32 resp_len; - uint32 flags; - struct dot11_assoc_req req; - struct ether_addr reassoc_bssid; - struct dot11_assoc_resp resp; -} wl_assoc_info_t; - - -#define WLC_ASSOC_REQ_IS_REASSOC 0x01 - - -typedef struct { - uint16 ver; - uint16 len; - uint16 cap; - uint32 flags; - uint32 idle; - struct ether_addr ea; - wl_rateset_t rateset; - uint32 in; - uint32 listen_interval_inms; - uint32 tx_pkts; - uint32 tx_failures; - uint32 rx_ucast_pkts; - uint32 rx_mcast_pkts; - uint32 tx_rate; - uint32 rx_rate; - uint32 rx_decrypt_succeeds; - uint32 rx_decrypt_failures; -} sta_info_t; - -#define WL_OLD_STAINFO_SIZE OFFSETOF(sta_info_t, tx_pkts) - -#define WL_STA_VER 3 - - -#define WL_STA_BRCM 0x1 -#define WL_STA_WME 0x2 -#define WL_STA_ABCAP 0x4 -#define WL_STA_AUTHE 0x8 -#define WL_STA_ASSOC 0x10 -#define WL_STA_AUTHO 0x20 -#define WL_STA_WDS 0x40 -#define WL_STA_WDS_LINKUP 0x80 -#define WL_STA_PS 0x100 -#define WL_STA_APSD_BE 0x200 -#define WL_STA_APSD_BK 0x400 -#define WL_STA_APSD_VI 0x800 -#define WL_STA_APSD_VO 0x1000 -#define WL_STA_N_CAP 0x2000 -#define WL_STA_SCBSTATS 0x4000 - -#define WL_WDS_LINKUP WL_STA_WDS_LINKUP - - -#define WLC_TXFILTER_OVERRIDE_DISABLED 0 -#define WLC_TXFILTER_OVERRIDE_ENABLED 1 - - -typedef struct { - uint32 val; - struct ether_addr ea; -} scb_val_t; - - -typedef struct { - uint32 code; - scb_val_t ioctl_args; -} authops_t; - - -typedef struct channel_info { - int hw_channel; - int target_channel; - int scan_channel; -} channel_info_t; - - -struct maclist { - uint count; - struct ether_addr ea[1]; -}; - - -typedef struct get_pktcnt { - uint rx_good_pkt; - uint rx_bad_pkt; - uint tx_good_pkt; - uint tx_bad_pkt; - uint rx_ocast_good_pkt; -} get_pktcnt_t; - -#define WL_IOCTL_ACTION_GET 0x0 -#define WL_IOCTL_ACTION_SET 0x1 -#define WL_IOCTL_ACTION_OVL_IDX_MASK 0x1e -#define WL_IOCTL_ACTION_OVL_RSV 0x20 -#define WL_IOCTL_ACTION_OVL 0x40 -#define WL_IOCTL_ACTION_MASK 0x7e -#define WL_IOCTL_ACTION_OVL_SHIFT 1 - - -typedef struct wl_ioctl { - uint cmd; - void *buf; - uint len; - uint8 set; - uint used; - uint needed; -} wl_ioctl_t; - - -#define ioctl_subtype set -#define ioctl_pid used -#define ioctl_status needed - - -typedef struct wlc_rev_info { - uint vendorid; - uint deviceid; - uint radiorev; - uint chiprev; - uint corerev; - uint boardid; - uint boardvendor; - uint boardrev; - uint driverrev; - uint ucoderev; - uint bus; - uint chipnum; - uint phytype; - uint phyrev; - uint anarev; - uint chippkg; -} wlc_rev_info_t; - -#define WL_REV_INFO_LEGACY_LENGTH 48 - -#define WL_BRAND_MAX 10 -typedef struct wl_instance_info { - uint instance; - char brand[WL_BRAND_MAX]; -} wl_instance_info_t; - - -typedef struct wl_txfifo_sz { - uint16 magic; - uint16 fifo; - uint16 size; -} wl_txfifo_sz_t; - -#define WL_TXFIFO_SZ_MAGIC 0xa5a5 - - - -#define WLC_IOV_NAME_LEN 30 -typedef struct wlc_iov_trx_s { - uint8 module; - uint8 type; - char name[WLC_IOV_NAME_LEN]; -} wlc_iov_trx_t; - - -#define WLC_IOCTL_MAGIC 0x14e46c77 - - -#define WLC_IOCTL_VERSION 1 - -#define WLC_IOCTL_MAXLEN 8192 -#define WLC_IOCTL_SMLEN 256 -#define WLC_IOCTL_MEDLEN 1536 -#ifdef WLC_HIGH_ONLY -#define WLC_SAMPLECOLLECT_MAXLEN 1024 -#define WLC_SAMPLECOLLECT_MAXLEN_LCN40 1024 -#else -#if defined(LCNCONF) || defined(LCN40CONF) -#define WLC_SAMPLECOLLECT_MAXLEN 8192 -#else -#define WLC_SAMPLECOLLECT_MAXLEN 10240 -#endif -#define WLC_SAMPLECOLLECT_MAXLEN_LCN40 8192 -#endif - - -#define WLC_GET_MAGIC 0 -#define WLC_GET_VERSION 1 -#define WLC_UP 2 -#define WLC_DOWN 3 -#define WLC_GET_LOOP 4 -#define WLC_SET_LOOP 5 -#define WLC_DUMP 6 -#define WLC_GET_MSGLEVEL 7 -#define WLC_SET_MSGLEVEL 8 -#define WLC_GET_PROMISC 9 -#define WLC_SET_PROMISC 10 -#define WLC_OVERLAY_IOCTL 11 -#define WLC_GET_RATE 12 - -#define WLC_GET_INSTANCE 14 - - - - -#define WLC_GET_INFRA 19 -#define WLC_SET_INFRA 20 -#define WLC_GET_AUTH 21 -#define WLC_SET_AUTH 22 -#define WLC_GET_BSSID 23 -#define WLC_SET_BSSID 24 -#define WLC_GET_SSID 25 -#define WLC_SET_SSID 26 -#define WLC_RESTART 27 -#define WLC_TERMINATED 28 - -#define WLC_GET_CHANNEL 29 -#define WLC_SET_CHANNEL 30 -#define WLC_GET_SRL 31 -#define WLC_SET_SRL 32 -#define WLC_GET_LRL 33 -#define WLC_SET_LRL 34 -#define WLC_GET_PLCPHDR 35 -#define WLC_SET_PLCPHDR 36 -#define WLC_GET_RADIO 37 -#define WLC_SET_RADIO 38 -#define WLC_GET_PHYTYPE 39 -#define WLC_DUMP_RATE 40 -#define WLC_SET_RATE_PARAMS 41 -#define WLC_GET_FIXRATE 42 -#define WLC_SET_FIXRATE 43 - - -#define WLC_GET_KEY 44 -#define WLC_SET_KEY 45 -#define WLC_GET_REGULATORY 46 -#define WLC_SET_REGULATORY 47 -#define WLC_GET_PASSIVE_SCAN 48 -#define WLC_SET_PASSIVE_SCAN 49 -#define WLC_SCAN 50 -#define WLC_SCAN_RESULTS 51 -#define WLC_DISASSOC 52 -#define WLC_REASSOC 53 -#define WLC_GET_ROAM_TRIGGER 54 -#define WLC_SET_ROAM_TRIGGER 55 -#define WLC_GET_ROAM_DELTA 56 -#define WLC_SET_ROAM_DELTA 57 -#define WLC_GET_ROAM_SCAN_PERIOD 58 -#define WLC_SET_ROAM_SCAN_PERIOD 59 -#define WLC_EVM 60 -#define WLC_GET_TXANT 61 -#define WLC_SET_TXANT 62 -#define WLC_GET_ANTDIV 63 -#define WLC_SET_ANTDIV 64 - - -#define WLC_GET_CLOSED 67 -#define WLC_SET_CLOSED 68 -#define WLC_GET_MACLIST 69 -#define WLC_SET_MACLIST 70 -#define WLC_GET_RATESET 71 -#define WLC_SET_RATESET 72 - -#define WLC_LONGTRAIN 74 -#define WLC_GET_BCNPRD 75 -#define WLC_SET_BCNPRD 76 -#define WLC_GET_DTIMPRD 77 -#define WLC_SET_DTIMPRD 78 -#define WLC_GET_SROM 79 -#define WLC_SET_SROM 80 -#define WLC_GET_WEP_RESTRICT 81 -#define WLC_SET_WEP_RESTRICT 82 -#define WLC_GET_COUNTRY 83 -#define WLC_SET_COUNTRY 84 -#define WLC_GET_PM 85 -#define WLC_SET_PM 86 -#define WLC_GET_WAKE 87 -#define WLC_SET_WAKE 88 - -#define WLC_GET_FORCELINK 90 -#define WLC_SET_FORCELINK 91 -#define WLC_FREQ_ACCURACY 92 -#define WLC_CARRIER_SUPPRESS 93 -#define WLC_GET_PHYREG 94 -#define WLC_SET_PHYREG 95 -#define WLC_GET_RADIOREG 96 -#define WLC_SET_RADIOREG 97 -#define WLC_GET_REVINFO 98 -#define WLC_GET_UCANTDIV 99 -#define WLC_SET_UCANTDIV 100 -#define WLC_R_REG 101 -#define WLC_W_REG 102 - - -#define WLC_GET_MACMODE 105 -#define WLC_SET_MACMODE 106 -#define WLC_GET_MONITOR 107 -#define WLC_SET_MONITOR 108 -#define WLC_GET_GMODE 109 -#define WLC_SET_GMODE 110 -#define WLC_GET_LEGACY_ERP 111 -#define WLC_SET_LEGACY_ERP 112 -#define WLC_GET_RX_ANT 113 -#define WLC_GET_CURR_RATESET 114 -#define WLC_GET_SCANSUPPRESS 115 -#define WLC_SET_SCANSUPPRESS 116 -#define WLC_GET_AP 117 -#define WLC_SET_AP 118 -#define WLC_GET_EAP_RESTRICT 119 -#define WLC_SET_EAP_RESTRICT 120 -#define WLC_SCB_AUTHORIZE 121 -#define WLC_SCB_DEAUTHORIZE 122 -#define WLC_GET_WDSLIST 123 -#define WLC_SET_WDSLIST 124 -#define WLC_GET_ATIM 125 -#define WLC_SET_ATIM 126 -#define WLC_GET_RSSI 127 -#define WLC_GET_PHYANTDIV 128 -#define WLC_SET_PHYANTDIV 129 -#define WLC_AP_RX_ONLY 130 -#define WLC_GET_TX_PATH_PWR 131 -#define WLC_SET_TX_PATH_PWR 132 -#define WLC_GET_WSEC 133 -#define WLC_SET_WSEC 134 -#define WLC_GET_PHY_NOISE 135 -#define WLC_GET_BSS_INFO 136 -#define WLC_GET_PKTCNTS 137 -#define WLC_GET_LAZYWDS 138 -#define WLC_SET_LAZYWDS 139 -#define WLC_GET_BANDLIST 140 -#define WLC_GET_BAND 141 -#define WLC_SET_BAND 142 -#define WLC_SCB_DEAUTHENTICATE 143 -#define WLC_GET_SHORTSLOT 144 -#define WLC_GET_SHORTSLOT_OVERRIDE 145 -#define WLC_SET_SHORTSLOT_OVERRIDE 146 -#define WLC_GET_SHORTSLOT_RESTRICT 147 -#define WLC_SET_SHORTSLOT_RESTRICT 148 -#define WLC_GET_GMODE_PROTECTION 149 -#define WLC_GET_GMODE_PROTECTION_OVERRIDE 150 -#define WLC_SET_GMODE_PROTECTION_OVERRIDE 151 -#define WLC_UPGRADE 152 - - -#define WLC_GET_IGNORE_BCNS 155 -#define WLC_SET_IGNORE_BCNS 156 -#define WLC_GET_SCB_TIMEOUT 157 -#define WLC_SET_SCB_TIMEOUT 158 -#define WLC_GET_ASSOCLIST 159 -#define WLC_GET_CLK 160 -#define WLC_SET_CLK 161 -#define WLC_GET_UP 162 -#define WLC_OUT 163 -#define WLC_GET_WPA_AUTH 164 -#define WLC_SET_WPA_AUTH 165 -#define WLC_GET_UCFLAGS 166 -#define WLC_SET_UCFLAGS 167 -#define WLC_GET_PWRIDX 168 -#define WLC_SET_PWRIDX 169 -#define WLC_GET_TSSI 170 -#define WLC_GET_SUP_RATESET_OVERRIDE 171 -#define WLC_SET_SUP_RATESET_OVERRIDE 172 - - - - - -#define WLC_GET_PROTECTION_CONTROL 178 -#define WLC_SET_PROTECTION_CONTROL 179 -#define WLC_GET_PHYLIST 180 -#define WLC_ENCRYPT_STRENGTH 181 -#define WLC_DECRYPT_STATUS 182 -#define WLC_GET_KEY_SEQ 183 -#define WLC_GET_SCAN_CHANNEL_TIME 184 -#define WLC_SET_SCAN_CHANNEL_TIME 185 -#define WLC_GET_SCAN_UNASSOC_TIME 186 -#define WLC_SET_SCAN_UNASSOC_TIME 187 -#define WLC_GET_SCAN_HOME_TIME 188 -#define WLC_SET_SCAN_HOME_TIME 189 -#define WLC_GET_SCAN_NPROBES 190 -#define WLC_SET_SCAN_NPROBES 191 -#define WLC_GET_PRB_RESP_TIMEOUT 192 -#define WLC_SET_PRB_RESP_TIMEOUT 193 -#define WLC_GET_ATTEN 194 -#define WLC_SET_ATTEN 195 -#define WLC_GET_SHMEM 196 -#define WLC_SET_SHMEM 197 - - -#define WLC_SET_WSEC_TEST 200 -#define WLC_SCB_DEAUTHENTICATE_FOR_REASON 201 -#define WLC_TKIP_COUNTERMEASURES 202 -#define WLC_GET_PIOMODE 203 -#define WLC_SET_PIOMODE 204 -#define WLC_SET_ASSOC_PREFER 205 -#define WLC_GET_ASSOC_PREFER 206 -#define WLC_SET_ROAM_PREFER 207 -#define WLC_GET_ROAM_PREFER 208 -#define WLC_SET_LED 209 -#define WLC_GET_LED 210 -#define WLC_GET_INTERFERENCE_MODE 211 -#define WLC_SET_INTERFERENCE_MODE 212 -#define WLC_GET_CHANNEL_QA 213 -#define WLC_START_CHANNEL_QA 214 -#define WLC_GET_CHANNEL_SEL 215 -#define WLC_START_CHANNEL_SEL 216 -#define WLC_GET_VALID_CHANNELS 217 -#define WLC_GET_FAKEFRAG 218 -#define WLC_SET_FAKEFRAG 219 -#define WLC_GET_PWROUT_PERCENTAGE 220 -#define WLC_SET_PWROUT_PERCENTAGE 221 -#define WLC_SET_BAD_FRAME_PREEMPT 222 -#define WLC_GET_BAD_FRAME_PREEMPT 223 -#define WLC_SET_LEAP_LIST 224 -#define WLC_GET_LEAP_LIST 225 -#define WLC_GET_CWMIN 226 -#define WLC_SET_CWMIN 227 -#define WLC_GET_CWMAX 228 -#define WLC_SET_CWMAX 229 -#define WLC_GET_WET 230 -#define WLC_SET_WET 231 -#define WLC_GET_PUB 232 - - -#define WLC_GET_KEY_PRIMARY 235 -#define WLC_SET_KEY_PRIMARY 236 - -#define WLC_GET_ACI_ARGS 238 -#define WLC_SET_ACI_ARGS 239 -#define WLC_UNSET_CALLBACK 240 -#define WLC_SET_CALLBACK 241 -#define WLC_GET_RADAR 242 -#define WLC_SET_RADAR 243 -#define WLC_SET_SPECT_MANAGMENT 244 -#define WLC_GET_SPECT_MANAGMENT 245 -#define WLC_WDS_GET_REMOTE_HWADDR 246 -#define WLC_WDS_GET_WPA_SUP 247 -#define WLC_SET_CS_SCAN_TIMER 248 -#define WLC_GET_CS_SCAN_TIMER 249 -#define WLC_MEASURE_REQUEST 250 -#define WLC_INIT 251 -#define WLC_SEND_QUIET 252 -#define WLC_KEEPALIVE 253 -#define WLC_SEND_PWR_CONSTRAINT 254 -#define WLC_UPGRADE_STATUS 255 -#define WLC_CURRENT_PWR 256 -#define WLC_GET_SCAN_PASSIVE_TIME 257 -#define WLC_SET_SCAN_PASSIVE_TIME 258 -#define WLC_LEGACY_LINK_BEHAVIOR 259 -#define WLC_GET_CHANNELS_IN_COUNTRY 260 -#define WLC_GET_COUNTRY_LIST 261 -#define WLC_GET_VAR 262 -#define WLC_SET_VAR 263 -#define WLC_NVRAM_GET 264 -#define WLC_NVRAM_SET 265 -#define WLC_NVRAM_DUMP 266 -#define WLC_REBOOT 267 -#define WLC_SET_WSEC_PMK 268 -#define WLC_GET_AUTH_MODE 269 -#define WLC_SET_AUTH_MODE 270 -#define WLC_GET_WAKEENTRY 271 -#define WLC_SET_WAKEENTRY 272 -#define WLC_NDCONFIG_ITEM 273 -#define WLC_NVOTPW 274 -#define WLC_OTPW 275 -#define WLC_IOV_BLOCK_GET 276 -#define WLC_IOV_MODULES_GET 277 -#define WLC_SOFT_RESET 278 -#define WLC_GET_ALLOW_MODE 279 -#define WLC_SET_ALLOW_MODE 280 -#define WLC_GET_DESIRED_BSSID 281 -#define WLC_SET_DESIRED_BSSID 282 -#define WLC_DISASSOC_MYAP 283 -#define WLC_GET_NBANDS 284 -#define WLC_GET_BANDSTATES 285 -#define WLC_GET_WLC_BSS_INFO 286 -#define WLC_GET_ASSOC_INFO 287 -#define WLC_GET_OID_PHY 288 -#define WLC_SET_OID_PHY 289 -#define WLC_SET_ASSOC_TIME 290 -#define WLC_GET_DESIRED_SSID 291 -#define WLC_GET_CHANSPEC 292 -#define WLC_GET_ASSOC_STATE 293 -#define WLC_SET_PHY_STATE 294 -#define WLC_GET_SCAN_PENDING 295 -#define WLC_GET_SCANREQ_PENDING 296 -#define WLC_GET_PREV_ROAM_REASON 297 -#define WLC_SET_PREV_ROAM_REASON 298 -#define WLC_GET_BANDSTATES_PI 299 -#define WLC_GET_PHY_STATE 300 -#define WLC_GET_BSS_WPA_RSN 301 -#define WLC_GET_BSS_WPA2_RSN 302 -#define WLC_GET_BSS_BCN_TS 303 -#define WLC_GET_INT_DISASSOC 304 -#define WLC_SET_NUM_PEERS 305 -#define WLC_GET_NUM_BSS 306 -#define WLC_NPHY_SAMPLE_COLLECT 307 -#define WLC_UM_PRIV 308 -#define WLC_GET_CMD 309 - -#define WLC_SET_INTERFERENCE_OVERRIDE_MODE 311 -#define WLC_GET_INTERFERENCE_OVERRIDE_MODE 312 -#define WLC_GET_WAI_RESTRICT 313 -#define WLC_SET_WAI_RESTRICT 314 -#define WLC_SET_WAI_REKEY 315 -#define WLC_SET_PEAKRATE 316 -#define WLC_GET_PEAKRATE 317 -#define WLC_LAST 318 - -#ifndef EPICTRL_COOKIE -#define EPICTRL_COOKIE 0xABADCEDE -#endif - - -#define CMN_IOCTL_OFF 0x180 - - - - -#define WL_OID_BASE 0xFFE41420 - - -#define OID_WL_GETINSTANCE (WL_OID_BASE + WLC_GET_INSTANCE) -#define OID_WL_GET_FORCELINK (WL_OID_BASE + WLC_GET_FORCELINK) -#define OID_WL_SET_FORCELINK (WL_OID_BASE + WLC_SET_FORCELINK) -#define OID_WL_ENCRYPT_STRENGTH (WL_OID_BASE + WLC_ENCRYPT_STRENGTH) -#define OID_WL_DECRYPT_STATUS (WL_OID_BASE + WLC_DECRYPT_STATUS) -#define OID_LEGACY_LINK_BEHAVIOR (WL_OID_BASE + WLC_LEGACY_LINK_BEHAVIOR) -#define OID_WL_NDCONFIG_ITEM (WL_OID_BASE + WLC_NDCONFIG_ITEM) - - -#define OID_STA_CHANSPEC (WL_OID_BASE + WLC_GET_CHANSPEC) -#define OID_STA_NBANDS (WL_OID_BASE + WLC_GET_NBANDS) -#define OID_STA_GET_PHY (WL_OID_BASE + WLC_GET_OID_PHY) -#define OID_STA_SET_PHY (WL_OID_BASE + WLC_SET_OID_PHY) -#define OID_STA_ASSOC_TIME (WL_OID_BASE + WLC_SET_ASSOC_TIME) -#define OID_STA_DESIRED_SSID (WL_OID_BASE + WLC_GET_DESIRED_SSID) -#define OID_STA_SET_PHY_STATE (WL_OID_BASE + WLC_SET_PHY_STATE) -#define OID_STA_SCAN_PENDING (WL_OID_BASE + WLC_GET_SCAN_PENDING) -#define OID_STA_SCANREQ_PENDING (WL_OID_BASE + WLC_GET_SCANREQ_PENDING) -#define OID_STA_GET_ROAM_REASON (WL_OID_BASE + WLC_GET_PREV_ROAM_REASON) -#define OID_STA_SET_ROAM_REASON (WL_OID_BASE + WLC_SET_PREV_ROAM_REASON) -#define OID_STA_GET_PHY_STATE (WL_OID_BASE + WLC_GET_PHY_STATE) -#define OID_STA_INT_DISASSOC (WL_OID_BASE + WLC_GET_INT_DISASSOC) -#define OID_STA_SET_NUM_PEERS (WL_OID_BASE + WLC_SET_NUM_PEERS) -#define OID_STA_GET_NUM_BSS (WL_OID_BASE + WLC_GET_NUM_BSS) - -#define WL_DECRYPT_STATUS_SUCCESS 1 -#define WL_DECRYPT_STATUS_FAILURE 2 -#define WL_DECRYPT_STATUS_UNKNOWN 3 - - -#define WLC_UPGRADE_SUCCESS 0 -#define WLC_UPGRADE_PENDING 1 - -#ifdef CONFIG_USBRNDIS_RETAIL - -typedef struct { - char *name; - void *param; -} ndconfig_item_t; -#endif - - - -#define WL_AUTH_OPEN_SYSTEM 0 -#define WL_AUTH_SHARED_KEY 1 -#define WL_AUTH_OPEN_SHARED 2 - - -#define WL_RADIO_SW_DISABLE (1<<0) -#define WL_RADIO_HW_DISABLE (1<<1) -#define WL_RADIO_MPC_DISABLE (1<<2) -#define WL_RADIO_COUNTRY_DISABLE (1<<3) - -#define WL_SPURAVOID_OFF 0 -#define WL_SPURAVOID_ON1 1 -#define WL_SPURAVOID_ON2 2 - - -#define WL_TXPWR_OVERRIDE (1U<<31) -#define WL_TXPWR_NEG (1U<<30) - -#define WL_PHY_PAVARS_LEN 6 - -#define WL_PHY_PAVARS2_NUM 3 -#define WL_PHY_PAVAR_VER 1 -typedef struct wl_pavars2 { - uint16 ver; - uint16 len; - uint16 inuse; - uint16 phy_type; - uint16 bandrange; - uint16 chain; - uint16 inpa[WL_PHY_PAVARS2_NUM]; -} wl_pavars2_t; - -typedef struct wl_po { - uint16 phy_type; - uint16 band; - uint16 cckpo; - uint32 ofdmpo; - uint16 mcspo[8]; -} wl_po_t; - - -#define WLC_TXPWR_MAX (127) - - -#define WL_DIAG_INTERRUPT 1 -#define WL_DIAG_LOOPBACK 2 -#define WL_DIAG_MEMORY 3 -#define WL_DIAG_LED 4 -#define WL_DIAG_REG 5 -#define WL_DIAG_SROM 6 -#define WL_DIAG_DMA 7 - -#define WL_DIAGERR_SUCCESS 0 -#define WL_DIAGERR_FAIL_TO_RUN 1 -#define WL_DIAGERR_NOT_SUPPORTED 2 -#define WL_DIAGERR_INTERRUPT_FAIL 3 -#define WL_DIAGERR_LOOPBACK_FAIL 4 -#define WL_DIAGERR_SROM_FAIL 5 -#define WL_DIAGERR_SROM_BADCRC 6 -#define WL_DIAGERR_REG_FAIL 7 -#define WL_DIAGERR_MEMORY_FAIL 8 -#define WL_DIAGERR_NOMEM 9 -#define WL_DIAGERR_DMA_FAIL 10 - -#define WL_DIAGERR_MEMORY_TIMEOUT 11 -#define WL_DIAGERR_MEMORY_BADPATTERN 12 - - -#define WLC_BAND_AUTO 0 -#define WLC_BAND_5G 1 -#define WLC_BAND_2G 2 -#define WLC_BAND_ALL 3 - - -#define WL_CHAN_FREQ_RANGE_2G 0 -#define WL_CHAN_FREQ_RANGE_5GL 1 -#define WL_CHAN_FREQ_RANGE_5GM 2 -#define WL_CHAN_FREQ_RANGE_5GH 3 - -#define WL_CHAN_FREQ_RANGE_5GLL_5BAND 4 -#define WL_CHAN_FREQ_RANGE_5GLH_5BAND 5 -#define WL_CHAN_FREQ_RANGE_5GML_5BAND 6 -#define WL_CHAN_FREQ_RANGE_5GMH_5BAND 7 -#define WL_CHAN_FREQ_RANGE_5GH_5BAND 8 - -#define WL_CHAN_FREQ_RANGE_5G_BAND0 1 -#define WL_CHAN_FREQ_RANGE_5G_BAND1 2 -#define WL_CHAN_FREQ_RANGE_5G_BAND2 3 -#define WL_CHAN_FREQ_RANGE_5G_BAND3 4 - - -#define WLC_PHY_TYPE_A 0 -#define WLC_PHY_TYPE_B 1 -#define WLC_PHY_TYPE_G 2 -#define WLC_PHY_TYPE_N 4 -#define WLC_PHY_TYPE_LP 5 -#define WLC_PHY_TYPE_SSN 6 -#define WLC_PHY_TYPE_HT 7 -#define WLC_PHY_TYPE_LCN 8 -#define WLC_PHY_TYPE_NULL 0xf - - -#define WLC_MACMODE_DISABLED 0 -#define WLC_MACMODE_DENY 1 -#define WLC_MACMODE_ALLOW 2 - - -#define GMODE_LEGACY_B 0 -#define GMODE_AUTO 1 -#define GMODE_ONLY 2 -#define GMODE_B_DEFERRED 3 -#define GMODE_PERFORMANCE 4 -#define GMODE_LRS 5 -#define GMODE_MAX 6 - - -#define WLC_PLCP_AUTO -1 -#define WLC_PLCP_SHORT 0 -#define WLC_PLCP_LONG 1 - - -#define WLC_PROTECTION_AUTO -1 -#define WLC_PROTECTION_OFF 0 -#define WLC_PROTECTION_ON 1 -#define WLC_PROTECTION_MMHDR_ONLY 2 -#define WLC_PROTECTION_CTS_ONLY 3 - - -#define WLC_PROTECTION_CTL_OFF 0 -#define WLC_PROTECTION_CTL_LOCAL 1 -#define WLC_PROTECTION_CTL_OVERLAP 2 - - -#define WLC_N_PROTECTION_OFF 0 -#define WLC_N_PROTECTION_OPTIONAL 1 -#define WLC_N_PROTECTION_20IN40 2 -#define WLC_N_PROTECTION_MIXEDMODE 3 - - -#define WLC_N_PREAMBLE_MIXEDMODE 0 -#define WLC_N_PREAMBLE_GF 1 -#define WLC_N_PREAMBLE_GF_BRCM 2 - - -#define WLC_N_BW_20ALL 0 -#define WLC_N_BW_40ALL 1 -#define WLC_N_BW_20IN2G_40IN5G 2 - - -#define WLC_N_TXRX_CHAIN0 0 -#define WLC_N_TXRX_CHAIN1 1 - - -#define WLC_N_SGI_20 0x01 -#define WLC_N_SGI_40 0x02 - - -#define PM_OFF 0 -#define PM_MAX 1 -#define PM_FAST 2 - -#define LISTEN_INTERVAL 10 - -#define INTERFERE_OVRRIDE_OFF -1 -#define INTERFERE_NONE 0 -#define NON_WLAN 1 -#define WLAN_MANUAL 2 -#define WLAN_AUTO 3 -#define WLAN_AUTO_W_NOISE 4 -#define AUTO_ACTIVE (1 << 7) - -typedef struct wl_aci_args { - int enter_aci_thresh; - int exit_aci_thresh; - int usec_spin; - int glitch_delay; - uint16 nphy_adcpwr_enter_thresh; - uint16 nphy_adcpwr_exit_thresh; - uint16 nphy_repeat_ctr; - uint16 nphy_num_samples; - uint16 nphy_undetect_window_sz; - uint16 nphy_b_energy_lo_aci; - uint16 nphy_b_energy_md_aci; - uint16 nphy_b_energy_hi_aci; - uint16 nphy_noise_noassoc_glitch_th_up; - uint16 nphy_noise_noassoc_glitch_th_dn; - uint16 nphy_noise_assoc_glitch_th_up; - uint16 nphy_noise_assoc_glitch_th_dn; - uint16 nphy_noise_assoc_aci_glitch_th_up; - uint16 nphy_noise_assoc_aci_glitch_th_dn; - uint16 nphy_noise_assoc_enter_th; - uint16 nphy_noise_noassoc_enter_th; - uint16 nphy_noise_assoc_rx_glitch_badplcp_enter_th; - uint16 nphy_noise_noassoc_crsidx_incr; - uint16 nphy_noise_assoc_crsidx_incr; - uint16 nphy_noise_crsidx_decr; -} wl_aci_args_t; - -#define TRIGGER_NOW 0 -#define TRIGGER_CRS 0x01 -#define TRIGGER_CRSDEASSERT 0x02 -#define TRIGGER_GOODFCS 0x04 -#define TRIGGER_BADFCS 0x08 -#define TRIGGER_BADPLCP 0x10 -#define TRIGGER_CRSGLITCH 0x20 -#define WL_ACI_ARGS_LEGACY_LENGTH 16 -#define WL_SAMPLECOLLECT_T_VERSION 2 -typedef struct wl_samplecollect_args { - - uint8 coll_us; - int cores; - - uint16 version; - uint16 length; - int8 trigger; - uint16 timeout; - uint16 mode; - uint32 pre_dur; - uint32 post_dur; - uint8 gpio_sel; - bool downsamp; - bool be_deaf; - bool agc; - bool filter; - - uint8 trigger_state; - uint8 module_sel1; - uint8 module_sel2; - uint16 nsamps; -} wl_samplecollect_args_t; - -#define WL_SAMPLEDATA_HEADER_TYPE 1 -#define WL_SAMPLEDATA_HEADER_SIZE 80 -#define WL_SAMPLEDATA_TYPE 2 -#define WL_SAMPLEDATA_SEQ 0xff -#define WL_SAMPLEDATA_MORE_DATA 0x100 -#define WL_SAMPLEDATA_T_VERSION 1 - -#define WL_SAMPLEDATA_T_VERSION_SPEC_AN 2 - -typedef struct wl_sampledata { - uint16 version; - uint16 size; - uint16 tag; - uint16 length; - uint32 flag; -} wl_sampledata_t; - - -#define WL_CHAN_VALID_HW (1 << 0) -#define WL_CHAN_VALID_SW (1 << 1) -#define WL_CHAN_BAND_5G (1 << 2) -#define WL_CHAN_RADAR (1 << 3) -#define WL_CHAN_INACTIVE (1 << 4) -#define WL_CHAN_PASSIVE (1 << 5) -#define WL_CHAN_RESTRICTED (1 << 6) - - -#define WL_ERROR_VAL 0x00000001 -#define WL_TRACE_VAL 0x00000002 -#define WL_PRHDRS_VAL 0x00000004 -#define WL_PRPKT_VAL 0x00000008 -#define WL_INFORM_VAL 0x00000010 -#define WL_TMP_VAL 0x00000020 -#define WL_OID_VAL 0x00000040 -#define WL_RATE_VAL 0x00000080 -#define WL_ASSOC_VAL 0x00000100 -#define WL_PRUSR_VAL 0x00000200 -#define WL_PS_VAL 0x00000400 -#define WL_TXPWR_VAL 0x00000800 -#define WL_PORT_VAL 0x00001000 -#define WL_DUAL_VAL 0x00002000 -#define WL_WSEC_VAL 0x00004000 -#define WL_WSEC_DUMP_VAL 0x00008000 -#define WL_LOG_VAL 0x00010000 -#define WL_NRSSI_VAL 0x00020000 -#define WL_LOFT_VAL 0x00040000 -#define WL_REGULATORY_VAL 0x00080000 -#define WL_PHYCAL_VAL 0x00100000 -#define WL_RADAR_VAL 0x00200000 -#define WL_MPC_VAL 0x00400000 -#define WL_APSTA_VAL 0x00800000 -#define WL_DFS_VAL 0x01000000 -#define WL_BA_VAL 0x02000000 -#define WL_ACI_VAL 0x04000000 -#define WL_MBSS_VAL 0x04000000 -#define WL_CAC_VAL 0x08000000 -#define WL_AMSDU_VAL 0x10000000 -#define WL_AMPDU_VAL 0x20000000 -#define WL_FFPLD_VAL 0x40000000 - - -#define WL_DPT_VAL 0x00000001 -#define WL_SCAN_VAL 0x00000002 -#define WL_WOWL_VAL 0x00000004 -#define WL_COEX_VAL 0x00000008 -#define WL_RTDC_VAL 0x00000010 -#define WL_PROTO_VAL 0x00000020 -#define WL_BTA_VAL 0x00000040 -#define WL_CHANINT_VAL 0x00000080 -#define WL_THERMAL_VAL 0x00000100 -#define WL_P2P_VAL 0x00000200 -#define WL_TXRX_VAL 0x00000400 -#define WL_MCHAN_VAL 0x00000800 -#define WL_TDLS_VAL 0x00001000 - - -#define WL_LED_NUMGPIO 16 - - -#define WL_LED_OFF 0 -#define WL_LED_ON 1 -#define WL_LED_ACTIVITY 2 -#define WL_LED_RADIO 3 -#define WL_LED_ARADIO 4 -#define WL_LED_BRADIO 5 -#define WL_LED_BGMODE 6 -#define WL_LED_WI1 7 -#define WL_LED_WI2 8 -#define WL_LED_WI3 9 -#define WL_LED_ASSOC 10 -#define WL_LED_INACTIVE 11 -#define WL_LED_ASSOCACT 12 -#define WL_LED_WI4 13 -#define WL_LED_WI5 14 -#define WL_LED_BLINKSLOW 15 -#define WL_LED_BLINKMED 16 -#define WL_LED_BLINKFAST 17 -#define WL_LED_BLINKCUSTOM 18 -#define WL_LED_BLINKPERIODIC 19 -#define WL_LED_ASSOC_WITH_SEC 20 - -#define WL_LED_START_OFF 21 -#define WL_LED_NUMBEHAVIOR 22 - - -#define WL_LED_BEH_MASK 0x7f -#define WL_LED_AL_MASK 0x80 - - -#define WL_NUMCHANNELS 64 -#define WL_NUMCHANSPECS 100 - - -#define WL_WDS_WPA_ROLE_AUTH 0 -#define WL_WDS_WPA_ROLE_SUP 1 -#define WL_WDS_WPA_ROLE_AUTO 255 - - -#define WL_EVENTING_MASK_LEN 16 - - - - -#define WL_JOIN_PREF_RSSI 1 -#define WL_JOIN_PREF_WPA 2 -#define WL_JOIN_PREF_BAND 3 -#define WL_JOIN_PREF_RSSI_DELTA 4 -#define WL_JOIN_PREF_TRANS_PREF 5 - - -#define WLJP_BAND_ASSOC_PREF 255 - - -#define WL_WPA_ACP_MCS_ANY "\x00\x00\x00\x00" - -struct tsinfo_arg { - uint8 octets[3]; -}; - -#define NFIFO 6 - -#define WL_CNT_T_VERSION 6 - -typedef struct { - uint16 version; - uint16 length; - - - uint32 txframe; - uint32 txbyte; - uint32 txretrans; - uint32 txerror; - uint32 txctl; - uint32 txprshort; - uint32 txserr; - uint32 txnobuf; - uint32 txnoassoc; - uint32 txrunt; - uint32 txchit; - uint32 txcmiss; - - - uint32 txuflo; - uint32 txphyerr; - uint32 txphycrs; - - - uint32 rxframe; - uint32 rxbyte; - uint32 rxerror; - uint32 rxctl; - uint32 rxnobuf; - uint32 rxnondata; - uint32 rxbadds; - uint32 rxbadcm; - uint32 rxfragerr; - uint32 rxrunt; - uint32 rxgiant; - uint32 rxnoscb; - uint32 rxbadproto; - uint32 rxbadsrcmac; - uint32 rxbadda; - uint32 rxfilter; - - - uint32 rxoflo; - uint32 rxuflo[NFIFO]; - - uint32 d11cnt_txrts_off; - uint32 d11cnt_rxcrc_off; - uint32 d11cnt_txnocts_off; - - - uint32 dmade; - uint32 dmada; - uint32 dmape; - uint32 reset; - uint32 tbtt; - uint32 txdmawar; - uint32 pkt_callback_reg_fail; - - - uint32 txallfrm; - uint32 txrtsfrm; - uint32 txctsfrm; - uint32 txackfrm; - uint32 txdnlfrm; - uint32 txbcnfrm; - uint32 txfunfl[8]; - uint32 txtplunfl; - uint32 txphyerror; - uint32 rxfrmtoolong; - uint32 rxfrmtooshrt; - uint32 rxinvmachdr; - uint32 rxbadfcs; - uint32 rxbadplcp; - uint32 rxcrsglitch; - uint32 rxstrt; - uint32 rxdfrmucastmbss; - uint32 rxmfrmucastmbss; - uint32 rxcfrmucast; - uint32 rxrtsucast; - uint32 rxctsucast; - uint32 rxackucast; - uint32 rxdfrmocast; - uint32 rxmfrmocast; - uint32 rxcfrmocast; - uint32 rxrtsocast; - uint32 rxctsocast; - uint32 rxdfrmmcast; - uint32 rxmfrmmcast; - uint32 rxcfrmmcast; - uint32 rxbeaconmbss; - uint32 rxdfrmucastobss; - uint32 rxbeaconobss; - uint32 rxrsptmout; - uint32 bcntxcancl; - uint32 rxf0ovfl; - uint32 rxf1ovfl; - uint32 rxf2ovfl; - uint32 txsfovfl; - uint32 pmqovfl; - uint32 rxcgprqfrm; - uint32 rxcgprsqovfl; - uint32 txcgprsfail; - uint32 txcgprssuc; - uint32 prs_timeout; - uint32 rxnack; - uint32 frmscons; - uint32 txnack; - uint32 txglitch_nack; - uint32 txburst; - - - uint32 txfrag; - uint32 txmulti; - uint32 txfail; - uint32 txretry; - uint32 txretrie; - uint32 rxdup; - uint32 txrts; - uint32 txnocts; - uint32 txnoack; - uint32 rxfrag; - uint32 rxmulti; - uint32 rxcrc; - uint32 txfrmsnt; - uint32 rxundec; - - - uint32 tkipmicfaill; - uint32 tkipcntrmsr; - uint32 tkipreplay; - uint32 ccmpfmterr; - uint32 ccmpreplay; - uint32 ccmpundec; - uint32 fourwayfail; - uint32 wepundec; - uint32 wepicverr; - uint32 decsuccess; - uint32 tkipicverr; - uint32 wepexcluded; - - uint32 rxundec_mcst; - - - uint32 tkipmicfaill_mcst; - uint32 tkipcntrmsr_mcst; - uint32 tkipreplay_mcst; - uint32 ccmpfmterr_mcst; - uint32 ccmpreplay_mcst; - uint32 ccmpundec_mcst; - uint32 fourwayfail_mcst; - uint32 wepundec_mcst; - uint32 wepicverr_mcst; - uint32 decsuccess_mcst; - uint32 tkipicverr_mcst; - uint32 wepexcluded_mcst; - - uint32 txchanrej; - uint32 txexptime; - uint32 psmwds; - uint32 phywatchdog; - - - uint32 prq_entries_handled; - uint32 prq_undirected_entries; - uint32 prq_bad_entries; - uint32 atim_suppress_count; - uint32 bcn_template_not_ready; - uint32 bcn_template_not_ready_done; - uint32 late_tbtt_dpc; - - - uint32 rx1mbps; - uint32 rx2mbps; - uint32 rx5mbps5; - uint32 rx6mbps; - uint32 rx9mbps; - uint32 rx11mbps; - uint32 rx12mbps; - uint32 rx18mbps; - uint32 rx24mbps; - uint32 rx36mbps; - uint32 rx48mbps; - uint32 rx54mbps; - uint32 rx108mbps; - uint32 rx162mbps; - uint32 rx216mbps; - uint32 rx270mbps; - uint32 rx324mbps; - uint32 rx378mbps; - uint32 rx432mbps; - uint32 rx486mbps; - uint32 rx540mbps; - - - uint32 pktengrxducast; - uint32 pktengrxdmcast; - - uint32 rfdisable; - uint32 bphy_rxcrsglitch; - - uint32 txmpdu_sgi; - uint32 rxmpdu_sgi; - uint32 txmpdu_stbc; - uint32 rxmpdu_stbc; -} wl_cnt_t; - - -#define WL_WME_CNT_VERSION 1 - -typedef struct { - uint32 packets; - uint32 bytes; -} wl_traffic_stats_t; - -typedef struct { - uint16 version; - uint16 length; - - wl_traffic_stats_t tx[AC_COUNT]; - wl_traffic_stats_t tx_failed[AC_COUNT]; - wl_traffic_stats_t rx[AC_COUNT]; - wl_traffic_stats_t rx_failed[AC_COUNT]; - - wl_traffic_stats_t forward[AC_COUNT]; - - wl_traffic_stats_t tx_expired[AC_COUNT]; - -} wl_wme_cnt_t; - -struct wl_msglevel2 { - uint32 low; - uint32 high; -}; - -typedef struct wl_mkeep_alive_pkt { - uint16 version; - uint16 length; - uint32 period_msec; - uint16 len_bytes; - uint8 keep_alive_id; - uint8 data[1]; -} wl_mkeep_alive_pkt_t; - -#define WL_MKEEP_ALIVE_VERSION 1 -#define WL_MKEEP_ALIVE_FIXED_LEN OFFSETOF(wl_mkeep_alive_pkt_t, data) -#define WL_MKEEP_ALIVE_PRECISION 500 - - - -#define WLC_ROAM_TRIGGER_DEFAULT 0 -#define WLC_ROAM_TRIGGER_BANDWIDTH 1 -#define WLC_ROAM_TRIGGER_DISTANCE 2 -#define WLC_ROAM_TRIGGER_AUTO 3 -#define WLC_ROAM_TRIGGER_MAX_VALUE 3 - - -#define WPA_AUTH_PFN_ANY 0xffffffff - -enum { - PFN_LIST_ORDER, - PFN_RSSI -}; - -enum { - DISABLE, - ENABLE -}; - -enum { - OFF_ADAPT, - SMART_ADAPT, - STRICT_ADAPT, - SLOW_ADAPT -}; - -#define SORT_CRITERIA_BIT 0 -#define AUTO_NET_SWITCH_BIT 1 -#define ENABLE_BKGRD_SCAN_BIT 2 -#define IMMEDIATE_SCAN_BIT 3 -#define AUTO_CONNECT_BIT 4 -#define ENABLE_BD_SCAN_BIT 5 -#define ENABLE_ADAPTSCAN_BIT 6 -#define IMMEDIATE_EVENT_BIT 8 - -#define SORT_CRITERIA_MASK 0x0001 -#define AUTO_NET_SWITCH_MASK 0x0002 -#define ENABLE_BKGRD_SCAN_MASK 0x0004 -#define IMMEDIATE_SCAN_MASK 0x0008 -#define AUTO_CONNECT_MASK 0x0010 -#define ENABLE_BD_SCAN_MASK 0x0020 -#define ENABLE_ADAPTSCAN_MASK 0x00c0 -#define IMMEDIATE_EVENT_MASK 0x0100 - -#define PFN_VERSION 2 -#define PFN_SCANRESULT_VERSION 1 -#define MAX_PFN_LIST_COUNT 16 - -#define PFN_COMPLETE 1 -#define PFN_INCOMPLETE 0 - -#define DEFAULT_BESTN 2 -#define DEFAULT_MSCAN 0 -#define DEFAULT_REPEAT 10 -#define DEFAULT_EXP 2 - - -typedef struct wl_pfn_subnet_info { - struct ether_addr BSSID; - uint8 channel; - uint8 SSID_len; - uint8 SSID[32]; -} wl_pfn_subnet_info_t; - -typedef struct wl_pfn_net_info { - wl_pfn_subnet_info_t pfnsubnet; - int16 RSSI; - uint16 timestamp; -} wl_pfn_net_info_t; - -typedef struct wl_pfn_scanresults { - uint32 version; - uint32 status; - uint32 count; - wl_pfn_net_info_t netinfo[1]; -} wl_pfn_scanresults_t; - - -typedef struct wl_pfn_param { - int32 version; - int32 scan_freq; - int32 lost_network_timeout; - int16 flags; - int16 rssi_margin; - uint8 bestn; - uint8 mscan; - uint8 repeat; - uint8 exp; - int32 slow_freq; -} wl_pfn_param_t; - -typedef struct wl_pfn_bssid { - struct ether_addr macaddr; - - uint16 flags; -} wl_pfn_bssid_t; -#define WL_PFN_SUPPRESSFOUND_MASK 0x08 -#define WL_PFN_SUPPRESSLOST_MASK 0x10 - -typedef struct wl_pfn_cfg { - uint32 reporttype; - int32 channel_num; - uint16 channel_list[WL_NUMCHANNELS]; -} wl_pfn_cfg_t; -#define WL_PFN_REPORT_ALLNET 0 -#define WL_PFN_REPORT_SSIDNET 1 -#define WL_PFN_REPORT_BSSIDNET 2 - -typedef struct wl_pfn { - wlc_ssid_t ssid; - int32 flags; - int32 infra; - int32 auth; - int32 wpa_auth; - int32 wsec; -} wl_pfn_t; -#define WL_PFN_HIDDEN_BIT 2 -#define PNO_SCAN_MAX_FW 508*1000 -#define PNO_SCAN_MAX_FW_SEC PNO_SCAN_MAX_FW/1000 -#define PNO_SCAN_MIN_FW_SEC 10 -#define WL_PFN_HIDDEN_MASK 0x4 - - -#define TOE_TX_CSUM_OL 0x00000001 -#define TOE_RX_CSUM_OL 0x00000002 - - -#define TOE_ERRTEST_TX_CSUM 0x00000001 -#define TOE_ERRTEST_RX_CSUM 0x00000002 -#define TOE_ERRTEST_RX_CSUM2 0x00000004 - -struct toe_ol_stats_t { - - uint32 tx_summed; - - - uint32 tx_iph_fill; - uint32 tx_tcp_fill; - uint32 tx_udp_fill; - uint32 tx_icmp_fill; - - - uint32 rx_iph_good; - uint32 rx_iph_bad; - uint32 rx_tcp_good; - uint32 rx_tcp_bad; - uint32 rx_udp_good; - uint32 rx_udp_bad; - uint32 rx_icmp_good; - uint32 rx_icmp_bad; - - - uint32 tx_tcp_errinj; - uint32 tx_udp_errinj; - uint32 tx_icmp_errinj; - - - uint32 rx_tcp_errinj; - uint32 rx_udp_errinj; - uint32 rx_icmp_errinj; -}; - - -#define ARP_OL_AGENT 0x00000001 -#define ARP_OL_SNOOP 0x00000002 -#define ARP_OL_HOST_AUTO_REPLY 0x00000004 -#define ARP_OL_PEER_AUTO_REPLY 0x00000008 - - -#define ARP_ERRTEST_REPLY_PEER 0x1 -#define ARP_ERRTEST_REPLY_HOST 0x2 - -#define ARP_MULTIHOMING_MAX 8 - - -struct arp_ol_stats_t { - uint32 host_ip_entries; - uint32 host_ip_overflow; - - uint32 arp_table_entries; - uint32 arp_table_overflow; - - uint32 host_request; - uint32 host_reply; - uint32 host_service; - - uint32 peer_request; - uint32 peer_request_drop; - uint32 peer_reply; - uint32 peer_reply_drop; - uint32 peer_service; -}; - - - - -typedef struct wl_keep_alive_pkt { - uint32 period_msec; - uint16 len_bytes; - uint8 data[1]; -} wl_keep_alive_pkt_t; - -#define WL_KEEP_ALIVE_FIXED_LEN OFFSETOF(wl_keep_alive_pkt_t, data) - - - - -#define MAX_WAKE_PACKET_BYTES 128 - - -typedef struct pm_wake_packet { - uint32 status; - uint32 pattern_id; - uint32 original_packet_size; - uint32 saved_packet_size; - uchar packet[MAX_WAKE_PACKET_BYTES]; -} pm_wake_packet_t; - - - -#define PKT_FILTER_MODE_FORWARD_ON_MATCH 1 - -#define PKT_FILTER_MODE_DISABLE 2 - -#define PKT_FILTER_MODE_PKT_CACHE_ON_MATCH 4 - -#define PKT_FILTER_MODE_PKT_FORWARD_OFF_DEFAULT 8 - - -typedef enum wl_pkt_filter_type { - WL_PKT_FILTER_TYPE_PATTERN_MATCH, - WL_PKT_FILTER_TYPE_MAGIC_PATTERN_MATCH -} wl_pkt_filter_type_t; - -#define WL_PKT_FILTER_TYPE wl_pkt_filter_type_t - - -typedef struct wl_pkt_filter_pattern { - uint32 offset; - uint32 size_bytes; - uint8 mask_and_pattern[1]; -} wl_pkt_filter_pattern_t; - - -typedef struct wl_pkt_filter { - uint32 id; - uint32 type; - uint32 negate_match; - union { - wl_pkt_filter_pattern_t pattern; - } u; -} wl_pkt_filter_t; - -#define WL_PKT_FILTER_FIXED_LEN OFFSETOF(wl_pkt_filter_t, u) -#define WL_PKT_FILTER_PATTERN_FIXED_LEN OFFSETOF(wl_pkt_filter_pattern_t, mask_and_pattern) - - -typedef struct wl_pkt_filter_enable { - uint32 id; - uint32 enable; -} wl_pkt_filter_enable_t; - - -typedef struct wl_pkt_filter_list { - uint32 num; - wl_pkt_filter_t filter[1]; -} wl_pkt_filter_list_t; - -#define WL_PKT_FILTER_LIST_FIXED_LEN OFFSETOF(wl_pkt_filter_list_t, filter) - - -typedef struct wl_pkt_filter_stats { - uint32 num_pkts_matched; - uint32 num_pkts_forwarded; - uint32 num_pkts_discarded; -} wl_pkt_filter_stats_t; - - -typedef struct wl_seq_cmd_ioctl { - uint32 cmd; - uint32 len; -} wl_seq_cmd_ioctl_t; - -#define WL_SEQ_CMD_ALIGN_BYTES 4 - - -#define WL_SEQ_CMDS_GET_IOCTL_FILTER(cmd) \ - (((cmd) == WLC_GET_MAGIC) || \ - ((cmd) == WLC_GET_VERSION) || \ - ((cmd) == WLC_GET_AP) || \ - ((cmd) == WLC_GET_INSTANCE)) - - - -#define WL_PKTENG_PER_TX_START 0x01 -#define WL_PKTENG_PER_TX_STOP 0x02 -#define WL_PKTENG_PER_RX_START 0x04 -#define WL_PKTENG_PER_RX_WITH_ACK_START 0x05 -#define WL_PKTENG_PER_TX_WITH_ACK_START 0x06 -#define WL_PKTENG_PER_RX_STOP 0x08 -#define WL_PKTENG_PER_MASK 0xff - -#define WL_PKTENG_SYNCHRONOUS 0x100 - -typedef struct wl_pkteng { - uint32 flags; - uint32 delay; - uint32 nframes; - uint32 length; - uint8 seqno; - struct ether_addr dest; - struct ether_addr src; -} wl_pkteng_t; - -#define NUM_80211b_RATES 4 -#define NUM_80211ag_RATES 8 -#define NUM_80211n_RATES 32 -#define NUM_80211_RATES (NUM_80211b_RATES+NUM_80211ag_RATES+NUM_80211n_RATES) -typedef struct wl_pkteng_stats { - uint32 lostfrmcnt; - int32 rssi; - int32 snr; - uint16 rxpktcnt[NUM_80211_RATES+1]; -} wl_pkteng_stats_t; - - -#define WL_WOWL_MAGIC (1 << 0) -#define WL_WOWL_NET (1 << 1) -#define WL_WOWL_DIS (1 << 2) -#define WL_WOWL_RETR (1 << 3) -#define WL_WOWL_BCN (1 << 4) -#define WL_WOWL_TST (1 << 5) -#define WL_WOWL_M1 (1 << 6) -#define WL_WOWL_EAPID (1 << 7) -#define WL_WOWL_KEYROT (1 << 14) -#define WL_WOWL_BCAST (1 << 15) - -#define MAGIC_PKT_MINLEN 102 - -typedef struct { - uint masksize; - uint offset; - uint patternoffset; - uint patternsize; - ulong id; - - -} wl_wowl_pattern_t; - -typedef struct { - uint count; - wl_wowl_pattern_t pattern[1]; -} wl_wowl_pattern_list_t; - -typedef struct { - uint8 pci_wakeind; - uint16 ucode_wakeind; -} wl_wowl_wakeind_t; - - -typedef struct wl_txrate_class { - uint8 init_rate; - uint8 min_rate; - uint8 max_rate; -} wl_txrate_class_t; - - - - -#define WLC_OBSS_SCAN_PASSIVE_DWELL_DEFAULT 20 -#define WLC_OBSS_SCAN_PASSIVE_DWELL_MIN 5 -#define WLC_OBSS_SCAN_PASSIVE_DWELL_MAX 1000 -#define WLC_OBSS_SCAN_ACTIVE_DWELL_DEFAULT 10 -#define WLC_OBSS_SCAN_ACTIVE_DWELL_MIN 10 -#define WLC_OBSS_SCAN_ACTIVE_DWELL_MAX 1000 -#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_DEFAULT 300 -#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MIN 10 -#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MAX 900 -#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_DEFAULT 5 -#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MIN 5 -#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MAX 100 -#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_DEFAULT 200 -#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MIN 200 -#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MAX 10000 -#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_DEFAULT 20 -#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MIN 20 -#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MAX 10000 -#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_DEFAULT 25 -#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MIN 0 -#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MAX 100 - - -typedef struct wl_obss_scan_arg { - int16 passive_dwell; - int16 active_dwell; - int16 bss_widthscan_interval; - int16 passive_total; - int16 active_total; - int16 chanwidth_transition_delay; - int16 activity_threshold; -} wl_obss_scan_arg_t; - -#define WL_OBSS_SCAN_PARAM_LEN sizeof(wl_obss_scan_arg_t) -#define WL_MIN_NUM_OBSS_SCAN_ARG 7 - -#define WL_COEX_INFO_MASK 0x07 -#define WL_COEX_INFO_REQ 0x01 -#define WL_COEX_40MHZ_INTOLERANT 0x02 -#define WL_COEX_WIDTH20 0x04 - -#define WLC_RSSI_INVALID 0 - -#define MAX_RSSI_LEVELS 8 - - -typedef struct wl_rssi_event { - uint32 rate_limit_msec; - uint8 num_rssi_levels; - int8 rssi_levels[MAX_RSSI_LEVELS]; -} wl_rssi_event_t; - -typedef struct wl_action_obss_coex_req { - uint8 info; - uint8 num; - uint8 ch_list[1]; -} wl_action_obss_coex_req_t; - - -#define EXTLOG_CUR_VER 0x0100 - -#define MAX_ARGSTR_LEN 18 - - -#define LOG_MODULE_COMMON 0x0001 -#define LOG_MODULE_ASSOC 0x0002 -#define LOG_MODULE_EVENT 0x0004 -#define LOG_MODULE_MAX 3 - - -#define WL_LOG_LEVEL_DISABLE 0 -#define WL_LOG_LEVEL_ERR 1 -#define WL_LOG_LEVEL_WARN 2 -#define WL_LOG_LEVEL_INFO 3 -#define WL_LOG_LEVEL_MAX WL_LOG_LEVEL_INFO - - -#define LOG_FLAG_EVENT 1 - - -#define LOG_ARGTYPE_NULL 0 -#define LOG_ARGTYPE_STR 1 -#define LOG_ARGTYPE_INT 2 -#define LOG_ARGTYPE_INT_STR 3 -#define LOG_ARGTYPE_STR_INT 4 - -typedef struct wlc_extlog_cfg { - int max_number; - uint16 module; - uint8 level; - uint8 flag; - uint16 version; -} wlc_extlog_cfg_t; - -typedef struct log_record { - uint32 time; - uint16 module; - uint16 id; - uint8 level; - uint8 sub_unit; - uint8 seq_num; - int32 arg; - char str[MAX_ARGSTR_LEN]; -} log_record_t; - -typedef struct wlc_extlog_req { - uint32 from_last; - uint32 num; -} wlc_extlog_req_t; - -typedef struct wlc_extlog_results { - uint16 version; - uint16 record_len; - uint32 num; - log_record_t logs[1]; -} wlc_extlog_results_t; - -typedef struct log_idstr { - uint16 id; - uint16 flag; - uint8 arg_type; - const char *fmt_str; -} log_idstr_t; - -#define FMTSTRF_USER 1 - - -typedef enum { - FMTSTR_DRIVER_UP_ID = 0, - FMTSTR_DRIVER_DOWN_ID = 1, - FMTSTR_SUSPEND_MAC_FAIL_ID = 2, - FMTSTR_NO_PROGRESS_ID = 3, - FMTSTR_RFDISABLE_ID = 4, - FMTSTR_REG_PRINT_ID = 5, - FMTSTR_EXPTIME_ID = 6, - FMTSTR_JOIN_START_ID = 7, - FMTSTR_JOIN_COMPLETE_ID = 8, - FMTSTR_NO_NETWORKS_ID = 9, - FMTSTR_SECURITY_MISMATCH_ID = 10, - FMTSTR_RATE_MISMATCH_ID = 11, - FMTSTR_AP_PRUNED_ID = 12, - FMTSTR_KEY_INSERTED_ID = 13, - FMTSTR_DEAUTH_ID = 14, - FMTSTR_DISASSOC_ID = 15, - FMTSTR_LINK_UP_ID = 16, - FMTSTR_LINK_DOWN_ID = 17, - FMTSTR_RADIO_HW_OFF_ID = 18, - FMTSTR_RADIO_HW_ON_ID = 19, - FMTSTR_EVENT_DESC_ID = 20, - FMTSTR_PNP_SET_POWER_ID = 21, - FMTSTR_RADIO_SW_OFF_ID = 22, - FMTSTR_RADIO_SW_ON_ID = 23, - FMTSTR_PWD_MISMATCH_ID = 24, - FMTSTR_FATAL_ERROR_ID = 25, - FMTSTR_AUTH_FAIL_ID = 26, - FMTSTR_ASSOC_FAIL_ID = 27, - FMTSTR_IBSS_FAIL_ID = 28, - FMTSTR_EXTAP_FAIL_ID = 29, - FMTSTR_MAX_ID -} log_fmtstr_id_t; - -#ifdef DONGLEOVERLAYS -typedef struct { - uint32 flags_idx; - uint32 offset; - uint32 len; - -} wl_ioctl_overlay_t; - -#define OVERLAY_IDX_MASK 0x000000ff -#define OVERLAY_IDX_SHIFT 0 -#define OVERLAY_FLAGS_MASK 0xffffff00 -#define OVERLAY_FLAGS_SHIFT 8 - -#define OVERLAY_FLAG_POSTLOAD 0x100 - -#define OVERLAY_FLAG_DEFER_DL 0x200 - -#define OVERLAY_FLAG_PRESLEEP 0x400 - -#define OVERLAY_DOWNLOAD_CHUNKSIZE 1024 -#endif - - -#include - - -#include - -#define VNDR_IE_CMD_LEN 4 - - -#define VNDR_IE_BEACON_FLAG 0x1 -#define VNDR_IE_PRBRSP_FLAG 0x2 -#define VNDR_IE_ASSOCRSP_FLAG 0x4 -#define VNDR_IE_AUTHRSP_FLAG 0x8 -#define VNDR_IE_PRBREQ_FLAG 0x10 -#define VNDR_IE_ASSOCREQ_FLAG 0x20 -#define VNDR_IE_CUSTOM_FLAG 0x100 - -#define VNDR_IE_INFO_HDR_LEN (sizeof(uint32)) - -typedef BWL_PRE_PACKED_STRUCT struct { - uint32 pktflag; - vndr_ie_t vndr_ie_data; -} BWL_POST_PACKED_STRUCT vndr_ie_info_t; - -typedef BWL_PRE_PACKED_STRUCT struct { - int iecount; - vndr_ie_info_t vndr_ie_list[1]; -} BWL_POST_PACKED_STRUCT vndr_ie_buf_t; - -typedef BWL_PRE_PACKED_STRUCT struct { - char cmd[VNDR_IE_CMD_LEN]; - vndr_ie_buf_t vndr_ie_buffer; -} BWL_POST_PACKED_STRUCT vndr_ie_setbuf_t; - - - -typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_hdr { - struct ether_addr staAddr; - uint16 ieLen; -} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_hdr_t; - -typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_data { - sta_prbreq_wps_ie_hdr_t hdr; - uint8 ieData[1]; -} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_data_t; - -typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_list { - uint32 totLen; - uint8 ieDataList[1]; -} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_list_t; - - -#ifdef WLMEDIA_TXFAILEVENT -typedef BWL_PRE_PACKED_STRUCT struct { - char dest[ETHER_ADDR_LEN]; - uint8 prio; - uint8 flags; - uint32 tsf_l; - uint32 tsf_h; - uint16 rates; - uint16 txstatus; -} BWL_POST_PACKED_STRUCT txfailinfo_t; -#endif - -#include - - -#define ASSERTLOG_CUR_VER 0x0100 -#define MAX_ASSRTSTR_LEN 64 - -typedef struct assert_record { - uint32 time; - uint8 seq_num; - char str[MAX_ASSRTSTR_LEN]; -} assert_record_t; - -typedef struct assertlog_results { - uint16 version; - uint16 record_len; - uint32 num; - assert_record_t logs[1]; -} assertlog_results_t; - -#define LOGRRC_FIX_LEN 8 -#define IOBUF_ALLOWED_NUM_OF_LOGREC(type, len) ((len - LOGRRC_FIX_LEN)/sizeof(type)) - - - - - -#define CHANIM_DISABLE 0 -#define CHANIM_DETECT 1 -#define CHANIM_ACT 2 -#define CHANIM_MODE_MAX 2 - - -#define APCS_IOCTL 1 -#define APCS_CHANIM 2 -#define APCS_CSTIMER 3 -#define APCS_BTA 4 - - -#define CHANIM_ACS_RECORD 10 - - -typedef struct { - bool valid; - uint8 trigger; - chanspec_t selected_chspc; - uint32 glitch_cnt; - uint8 ccastats; - uint timestamp; -} chanim_acs_record_t; - -typedef struct { - chanim_acs_record_t acs_record[CHANIM_ACS_RECORD]; - uint8 count; - uint timestamp; -} wl_acs_record_t; - - - -#define SMFS_VERSION 1 - -typedef struct wl_smfs_elem { - uint32 count; - uint16 code; -} wl_smfs_elem_t; - -typedef struct wl_smf_stats { - uint32 version; - uint16 length; - uint8 type; - uint8 codetype; - uint32 ignored_cnt; - uint32 malformed_cnt; - uint32 count_total; - wl_smfs_elem_t elem[1]; -} wl_smf_stats_t; - -#define WL_SMFSTATS_FIXED_LEN OFFSETOF(wl_smf_stats_t, elem); - -enum { - SMFS_CODETYPE_SC, - SMFS_CODETYPE_RC -}; - - -#define SMFS_CODE_MALFORMED 0xFFFE -#define SMFS_CODE_IGNORED 0xFFFD - -typedef enum smfs_type { - SMFS_TYPE_AUTH, - SMFS_TYPE_ASSOC, - SMFS_TYPE_REASSOC, - SMFS_TYPE_DISASSOC_TX, - SMFS_TYPE_DISASSOC_RX, - SMFS_TYPE_DEAUTH_TX, - SMFS_TYPE_DEAUTH_RX, - SMFS_TYPE_MAX -} smfs_type_t; - -#ifdef PHYMON - -#define PHYMON_VERSION 1 - -typedef struct wl_phycal_core_state { - - int16 tx_iqlocal_a; - int16 tx_iqlocal_b; - int8 tx_iqlocal_ci; - int8 tx_iqlocal_cq; - int8 tx_iqlocal_di; - int8 tx_iqlocal_dq; - int8 tx_iqlocal_ei; - int8 tx_iqlocal_eq; - int8 tx_iqlocal_fi; - int8 tx_iqlocal_fq; - - - int16 rx_iqcal_a; - int16 rx_iqcal_b; - - uint8 tx_iqlocal_pwridx; - uint32 papd_epsilon_table[64]; - int16 papd_epsilon_offset; - uint8 curr_tx_pwrindex; - int8 idle_tssi; - int8 est_tx_pwr; - int8 est_rx_pwr; - uint16 rx_gaininfo; - uint16 init_gaincode; - int8 estirr_tx; - int8 estirr_rx; - -} wl_phycal_core_state_t; - -typedef struct wl_phycal_state { - int version; - int8 num_phy_cores; - int8 curr_temperature; - chanspec_t chspec; - bool aci_state; - uint16 crsminpower; - uint16 crsminpowerl; - uint16 crsminpoweru; - wl_phycal_core_state_t phycal_core[1]; -} wl_phycal_state_t; - -#define WL_PHYCAL_STAT_FIXED_LEN OFFSETOF(wl_phycal_state_t, phycal_core) -#endif - -#ifdef WLDSTA -typedef struct wl_dsta_if { - struct ether_addr addr; -} wl_dsta_if_t; -#endif - -#ifdef WLP2P - -typedef struct wl_p2p_disc_st { - uint8 state; - chanspec_t chspec; - uint16 dwell; -} wl_p2p_disc_st_t; - - -#define WL_P2P_DISC_ST_SCAN 0 -#define WL_P2P_DISC_ST_LISTEN 1 -#define WL_P2P_DISC_ST_SEARCH 2 - - -typedef struct wl_p2p_scan { - uint8 type; - uint8 reserved[3]; - -} wl_p2p_scan_t; - - -typedef struct wl_p2p_if { - struct ether_addr addr; - uint8 type; - chanspec_t chspec; -} wl_p2p_if_t; - - -#define WL_P2P_IF_CLIENT 0 -#define WL_P2P_IF_GO 1 -#define WL_P2P_IF_DYNBCN_GO 2 -#define WL_P2P_IF_DEV 3 - - -typedef struct wl_p2p_ifq { - uint bsscfgidx; - char ifname[BCM_MSG_IFNAME_MAX]; -} wl_p2p_ifq_t; - - -typedef struct wl_p2p_ops { - uint8 ops; - uint8 ctw; -} wl_p2p_ops_t; - - -typedef struct wl_p2p_sched_desc { - uint32 start; - uint32 interval; - uint32 duration; - uint32 count; -} wl_p2p_sched_desc_t; - - -#define WL_P2P_SCHED_RSVD 0 -#define WL_P2P_SCHED_REPEAT 255 - -typedef struct wl_p2p_sched { - uint8 type; - uint8 action; - uint8 option; - wl_p2p_sched_desc_t desc[1]; -} wl_p2p_sched_t; -#define WL_P2P_SCHED_FIXED_LEN 3 - - -#define WL_P2P_SCHED_TYPE_ABS 0 -#define WL_P2P_SCHED_TYPE_REQ_ABS 1 - - -#define WL_P2P_SCHED_ACTION_NONE 0 -#define WL_P2P_SCHED_ACTION_DOZE 1 - -#define WL_P2P_SCHED_ACTION_GOOFF 2 - -#define WL_P2P_SCHED_ACTION_RESET 255 - - -#define WL_P2P_SCHED_OPTION_NORMAL 0 -#define WL_P2P_SCHED_OPTION_BCNPCT 1 - -#define WL_P2P_SCHED_OPTION_TSFOFS 2 - - -#define WL_P2P_FEAT_GO_CSA (1 << 0) -#define WL_P2P_FEAT_GO_NOLEGACY (1 << 1) -#define WL_P2P_FEAT_RESTRICT_DEV_RESP (1 << 2) -#endif - - -#define BCM_ACTION_RFAWARE 0x77 -#define BCM_ACTION_RFAWARE_DCS 0x01 - - - -#define WL_11N_2x2 1 -#define WL_11N_3x3 3 -#define WL_11N_4x4 4 - - -#define WLFEATURE_DISABLE_11N 0x00000001 -#define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002 -#define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004 -#define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008 -#define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010 -#define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020 -#define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040 -#define WLFEATURE_DISABLE_11N_GF 0x00000080 - - -#define LQ_IDX_LAST 3 -#define MCS_INDEX_SIZE 33 - -#define LQ_IDX_MIN 0 -#define LQ_IDX_MAX 1 -#define LQ_IDX_AVG 2 -#define LQ_IDX_SUM 2 -#define LQ_IDX_LAST 3 -#define LQ_STOP_MONITOR 0 -#define LQ_START_MONITOR 1 - -#define LINKQUAL_V1 0x01 - -struct wl_lq { - int32 enable; - int32 rssi[LQ_IDX_LAST]; - int32 rssicnt; - int32 snr[LQ_IDX_LAST]; - uint32 nsamples; - uint8 isvalid; - uint8 version; -}; - -typedef struct wl_lq wl_lq_t; -typedef struct wl_lq wl_lq_stats_t; - -typedef struct { - struct ether_addr ea; - uint8 ac_cat; - uint8 num_pkts; -} wl_mac_ratehisto_cmd_t; - - -typedef struct { - uint32 rate[WLC_MAXRATE + 1]; - uint32 mcs_index[MCS_INDEX_SIZE]; - uint32 tsf_timer[2][2]; -} wl_mac_ratehisto_res_t; - -#ifdef PROP_TXSTATUS - - -#define WLFC_FLAGS_RSSI_SIGNALS 1 - - -#define WLFC_FLAGS_XONXOFF_SIGNALS 2 - - -#define WLFC_FLAGS_CREDIT_STATUS_SIGNALS 4 - -#define WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE 8 -#define WLFC_FLAGS_PSQ_GENERATIONFSM_ENABLE 16 -#define WLFC_FLAGS_PSQ_ZERO_BUFFER_ENABLE 32 -#endif - -#define BTA_STATE_LOG_SZ 64 - - -enum { - HCIReset = 1, - HCIReadLocalAMPInfo, - HCIReadLocalAMPASSOC, - HCIWriteRemoteAMPASSOC, - HCICreatePhysicalLink, - HCIAcceptPhysicalLinkRequest, - HCIDisconnectPhysicalLink, - HCICreateLogicalLink, - HCIAcceptLogicalLink, - HCIDisconnectLogicalLink, - HCILogicalLinkCancel, - HCIAmpStateChange, - HCIWriteLogicalLinkAcceptTimeout -}; - -typedef struct flush_txfifo { - uint32 txfifobmp; - uint32 hwtxfifoflush; - struct ether_addr ea; -} flush_txfifo_t; - -#define CHANNEL_5G_LOW_START 36 -#define CHANNEL_5G_MID_START 52 -#define CHANNEL_5G_HIGH_START 100 -#define CHANNEL_5G_UPPER_START 149 - -enum { - SPATIAL_MODE_2G_IDX = 0, - SPATIAL_MODE_5G_LOW_IDX, - SPATIAL_MODE_5G_MID_IDX, - SPATIAL_MODE_5G_HIGH_IDX, - SPATIAL_MODE_5G_UPPER_IDX, - SPATIAL_MODE_MAX_IDX -}; - -#endif diff --git a/drivers/net/wireless/bcmdhd/linux_osl.c b/drivers/net/wireless/bcmdhd/linux_osl.c deleted file mode 100644 index 4ef7bf7b24dc..000000000000 --- a/drivers/net/wireless/bcmdhd/linux_osl.c +++ /dev/null @@ -1,924 +0,0 @@ -/* - * Linux OS Independent Layer - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: linux_osl.c,v 1.168.2.7 2011-01-27 17:01:13 $ - */ - - -#define LINUX_PORT - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef BCMASSERT_LOG -#include -#endif - -#include - -#define PCI_CFG_RETRY 10 - -#define OS_HANDLE_MAGIC 0x1234abcd -#define BCM_MEM_FILENAME_LEN 24 - -#ifdef CONFIG_DHD_USE_STATIC_BUF -#define STATIC_BUF_MAX_NUM 16 -#define STATIC_BUF_SIZE (PAGE_SIZE * 2) -#define STATIC_BUF_TOTAL_LEN (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE) - -typedef struct bcm_static_buf { - struct semaphore static_sem; - unsigned char *buf_ptr; - unsigned char buf_use[STATIC_BUF_MAX_NUM]; -} bcm_static_buf_t; - -static bcm_static_buf_t *bcm_static_buf = 0; - -#define STATIC_PKT_MAX_NUM 8 - -typedef struct bcm_static_pkt { - struct sk_buff *skb_4k[STATIC_PKT_MAX_NUM]; - struct sk_buff *skb_8k[STATIC_PKT_MAX_NUM]; - struct semaphore osl_pkt_sem; - unsigned char pkt_use[STATIC_PKT_MAX_NUM * 2]; -} bcm_static_pkt_t; - -static bcm_static_pkt_t *bcm_static_skb = 0; -#endif - -typedef struct bcm_mem_link { - struct bcm_mem_link *prev; - struct bcm_mem_link *next; - uint size; - int line; - char file[BCM_MEM_FILENAME_LEN]; -} bcm_mem_link_t; - -struct osl_info { - osl_pubinfo_t pub; -#ifdef CTFPOOL - ctfpool_t *ctfpool; -#endif - uint magic; - void *pdev; - atomic_t malloced; - uint failed; - uint bustype; - bcm_mem_link_t *dbgmem_list; -}; - - - - -uint32 g_assert_type = FALSE; - -static int16 linuxbcmerrormap[] = -{ 0, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -E2BIG, - -E2BIG, - -EBUSY, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EFAULT, - -ENOMEM, - -EOPNOTSUPP, - -EMSGSIZE, - -EINVAL, - -EPERM, - -ENOMEM, - -EINVAL, - -ERANGE, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EIO, - -ENODEV, - -EINVAL, - -EIO, - -EIO, - -ENODEV, - -EINVAL, - -ENODATA, - - - -#if BCME_LAST != -42 -#error "You need to add a OS error translation in the linuxbcmerrormap \ - for new error code defined in bcmutils.h" -#endif -}; - - -int -osl_error(int bcmerror) -{ - if (bcmerror > 0) - bcmerror = 0; - else if (bcmerror < BCME_LAST) - bcmerror = BCME_ERROR; - - - return linuxbcmerrormap[-bcmerror]; -} - -extern uint8* dhd_os_prealloc(void *osh, int section, int size); - -osl_t * -osl_attach(void *pdev, uint bustype, bool pkttag) -{ - osl_t *osh; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - gfp_t flags; - - flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; - osh = kmalloc(sizeof(osl_t), flags); -#else - osh = kmalloc(sizeof(osl_t), GFP_ATOMIC); -#endif - ASSERT(osh); - - bzero(osh, sizeof(osl_t)); - - - ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1)); - - osh->magic = OS_HANDLE_MAGIC; - atomic_set(&osh->malloced, 0); - osh->failed = 0; - osh->dbgmem_list = NULL; - osh->pdev = pdev; - osh->pub.pkttag = pkttag; - osh->bustype = bustype; - - switch (bustype) { - case PCI_BUS: - case SI_BUS: - case PCMCIA_BUS: - osh->pub.mmbus = TRUE; - break; - case JTAG_BUS: - case SDIO_BUS: - case USB_BUS: - case SPI_BUS: - case RPC_BUS: - osh->pub.mmbus = FALSE; - break; - default: - ASSERT(FALSE); - break; - } - -#if defined(CONFIG_DHD_USE_STATIC_BUF) - if (!bcm_static_buf) { - if (!(bcm_static_buf = (bcm_static_buf_t *)dhd_os_prealloc(osh, 3, STATIC_BUF_SIZE+ - STATIC_BUF_TOTAL_LEN))) { - printk("can not alloc static buf!\n"); - } - else - printk("alloc static buf at %x!\n", (unsigned int)bcm_static_buf); - - sema_init(&bcm_static_buf->static_sem, 1); - - bcm_static_buf->buf_ptr = (unsigned char *)bcm_static_buf + STATIC_BUF_SIZE; - } - - if (!bcm_static_skb) { - int i; - void *skb_buff_ptr = 0; - bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048); - skb_buff_ptr = dhd_os_prealloc(osh, 4, 0); - - bcopy(skb_buff_ptr, bcm_static_skb, sizeof(struct sk_buff *) * 16); - for (i = 0; i < STATIC_PKT_MAX_NUM * 2; i++) - bcm_static_skb->pkt_use[i] = 0; - - sema_init(&bcm_static_skb->osl_pkt_sem, 1); - } -#endif - - return osh; -} - -void -osl_detach(osl_t *osh) -{ - if (osh == NULL) - return; - - ASSERT(osh->magic == OS_HANDLE_MAGIC); - kfree(osh); -} - -static struct sk_buff *osl_alloc_skb(unsigned int len) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) - gfp_t flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; - - return __dev_alloc_skb(len, flags); -#else - return dev_alloc_skb(len); -#endif -} - -#ifdef CTFPOOL - -void * -osl_ctfpool_add(osl_t *osh) -{ - struct sk_buff *skb; - - if ((osh == NULL) || (osh->ctfpool == NULL)) - return NULL; - - spin_lock_bh(&osh->ctfpool->lock); - ASSERT(osh->ctfpool->curr_obj <= osh->ctfpool->max_obj); - - - if (osh->ctfpool->curr_obj == osh->ctfpool->max_obj) { - spin_unlock_bh(&osh->ctfpool->lock); - return NULL; - } - - - skb = osl_alloc_skb(osh->ctfpool->obj_size); - if (skb == NULL) { - printf("%s: skb alloc of len %d failed\n", __FUNCTION__, - osh->ctfpool->obj_size); - spin_unlock_bh(&osh->ctfpool->lock); - return NULL; - } - - - skb->next = (struct sk_buff *)osh->ctfpool->head; - osh->ctfpool->head = skb; - osh->ctfpool->fast_frees++; - osh->ctfpool->curr_obj++; - - - CTFPOOLPTR(osh, skb) = (void *)osh->ctfpool; - - - PKTFAST(osh, skb) = FASTBUF; - - spin_unlock_bh(&osh->ctfpool->lock); - - return skb; -} - - -void -osl_ctfpool_replenish(osl_t *osh, uint thresh) -{ - if ((osh == NULL) || (osh->ctfpool == NULL)) - return; - - - while ((osh->ctfpool->refills > 0) && (thresh--)) { - osl_ctfpool_add(osh); - osh->ctfpool->refills--; - } -} - - -int32 -osl_ctfpool_init(osl_t *osh, uint numobj, uint size) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - gfp_t flags; - - flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; - osh->ctfpool = kmalloc(sizeof(ctfpool_t), flags); -#else - osh->ctfpool = kmalloc(sizeof(ctfpool_t), GFP_ATOMIC); -#endif - ASSERT(osh->ctfpool); - bzero(osh->ctfpool, sizeof(ctfpool_t)); - - osh->ctfpool->max_obj = numobj; - osh->ctfpool->obj_size = size; - - spin_lock_init(&osh->ctfpool->lock); - - while (numobj--) { - if (!osl_ctfpool_add(osh)) - return -1; - osh->ctfpool->fast_frees--; - } - - return 0; -} - - -void -osl_ctfpool_cleanup(osl_t *osh) -{ - struct sk_buff *skb, *nskb; - - if ((osh == NULL) || (osh->ctfpool == NULL)) - return; - - spin_lock_bh(&osh->ctfpool->lock); - - skb = osh->ctfpool->head; - - while (skb != NULL) { - nskb = skb->next; - dev_kfree_skb(skb); - skb = nskb; - osh->ctfpool->curr_obj--; - } - - ASSERT(osh->ctfpool->curr_obj == 0); - osh->ctfpool->head = NULL; - spin_unlock_bh(&osh->ctfpool->lock); - - kfree(osh->ctfpool); - osh->ctfpool = NULL; -} - -void -osl_ctfpool_stats(osl_t *osh, void *b) -{ - struct bcmstrbuf *bb; - - if ((osh == NULL) || (osh->ctfpool == NULL)) - return; - -#ifdef CONFIG_DHD_USE_STATIC_BUF - if (bcm_static_buf) { - bcm_static_buf = 0; - } - if (bcm_static_skb) { - bcm_static_skb = 0; - } -#endif - - bb = b; - - ASSERT((osh != NULL) && (bb != NULL)); - - bcm_bprintf(bb, "max_obj %d obj_size %d curr_obj %d refills %d\n", - osh->ctfpool->max_obj, osh->ctfpool->obj_size, - osh->ctfpool->curr_obj, osh->ctfpool->refills); - bcm_bprintf(bb, "fast_allocs %d fast_frees %d slow_allocs %d\n", - osh->ctfpool->fast_allocs, osh->ctfpool->fast_frees, - osh->ctfpool->slow_allocs); -} - -static inline struct sk_buff * -osl_pktfastget(osl_t *osh, uint len) -{ - struct sk_buff *skb; - - - if (osh->ctfpool == NULL) - return NULL; - - spin_lock_bh(&osh->ctfpool->lock); - if (osh->ctfpool->head == NULL) { - ASSERT(osh->ctfpool->curr_obj == 0); - osh->ctfpool->slow_allocs++; - spin_unlock_bh(&osh->ctfpool->lock); - return NULL; - } - - ASSERT(len <= osh->ctfpool->obj_size); - - - skb = (struct sk_buff *)osh->ctfpool->head; - osh->ctfpool->head = (void *)skb->next; - - osh->ctfpool->fast_allocs++; - osh->ctfpool->curr_obj--; - ASSERT(CTFPOOLHEAD(osh, skb) == (struct sock *)osh->ctfpool->head); - spin_unlock_bh(&osh->ctfpool->lock); - - - skb->next = skb->prev = NULL; - skb->data = skb->head + 16; - skb->tail = skb->head + 16; - - skb->len = 0; - skb->cloned = 0; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14) - skb->list = NULL; -#endif - atomic_set(&skb->users, 1); - - return skb; -} -#endif - - -void * BCMFASTPATH -osl_pktget(osl_t *osh, uint len) -{ - struct sk_buff *skb; - -#ifdef CTFPOOL - skb = osl_pktfastget(osh, len); - if ((skb != NULL) || ((skb = osl_alloc_skb(len)) != NULL)) { -#else - if ((skb = osl_alloc_skb(len))) { -#endif - skb_put(skb, len); - skb->priority = 0; - - osh->pub.pktalloced++; - } - - return ((void*) skb); -} - -#ifdef CTFPOOL -static inline void -osl_pktfastfree(osl_t *osh, struct sk_buff *skb) -{ - ctfpool_t *ctfpool; - - ctfpool = (ctfpool_t *)CTFPOOLPTR(osh, skb); - ASSERT(ctfpool != NULL); - - - spin_lock_bh(&ctfpool->lock); - skb->next = (struct sk_buff *)ctfpool->head; - ctfpool->head = (void *)skb; - - ctfpool->fast_frees++; - ctfpool->curr_obj++; - - ASSERT(ctfpool->curr_obj <= ctfpool->max_obj); - spin_unlock_bh(&ctfpool->lock); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) - skb->tstamp.tv.sec = 0; -#else - skb->stamp.tv_sec = 0; -#endif - - - skb->dev = NULL; - skb->dst = NULL; - memset(skb->cb, 0, sizeof(skb->cb)); - skb->ip_summed = 0; - skb->destructor = NULL; -} -#endif - - -void BCMFASTPATH -osl_pktfree(osl_t *osh, void *p, bool send) -{ - struct sk_buff *skb, *nskb; - - skb = (struct sk_buff*) p; - - if (send && osh->pub.tx_fn) - osh->pub.tx_fn(osh->pub.tx_ctx, p, 0); - - - while (skb) { - nskb = skb->next; - skb->next = NULL; - - -#ifdef CTFPOOL - if (PKTISFAST(osh, skb)) - osl_pktfastfree(osh, skb); - else { -#else - { -#endif - - if (skb->destructor) - - dev_kfree_skb_any(skb); - else - - dev_kfree_skb(skb); - } - - osh->pub.pktalloced--; - - skb = nskb; - } -} - -#ifdef CONFIG_DHD_USE_STATIC_BUF -void * -osl_pktget_static(osl_t *osh, uint len) -{ - int i; - struct sk_buff *skb; - - if (!bcm_static_skb || (len > (PAGE_SIZE * 2))) { - printk("%s: attempt to allocate huge packet (0x%x)\n", __FUNCTION__, len); - return osl_pktget(osh, len); - } - - down(&bcm_static_skb->osl_pkt_sem); - - if (len <= PAGE_SIZE) { - for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { - if (bcm_static_skb->pkt_use[i] == 0) - break; - } - - if (i != STATIC_PKT_MAX_NUM) { - bcm_static_skb->pkt_use[i] = 1; - skb = bcm_static_skb->skb_4k[i]; - skb->tail = skb->data + len; - skb->len = len; - up(&bcm_static_skb->osl_pkt_sem); - return skb; - } - } - - - for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { - if (bcm_static_skb->pkt_use[i+STATIC_PKT_MAX_NUM] == 0) - break; - } - - if (i != STATIC_PKT_MAX_NUM) { - bcm_static_skb->pkt_use[i+STATIC_PKT_MAX_NUM] = 1; - skb = bcm_static_skb->skb_8k[i]; - skb->tail = skb->data + len; - skb->len = len; - up(&bcm_static_skb->osl_pkt_sem); - return skb; - } - - up(&bcm_static_skb->osl_pkt_sem); - printk("%s: all static pkt in use!\n", __FUNCTION__); - return osl_pktget(osh, len); -} - -void -osl_pktfree_static(osl_t *osh, void *p, bool send) -{ - int i; - - if (!bcm_static_skb) { - osl_pktfree(osh, p, send); - return; - } - - down(&bcm_static_skb->osl_pkt_sem); - for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { - if (p == bcm_static_skb->skb_4k[i]) { - bcm_static_skb->pkt_use[i] = 0; - up(&bcm_static_skb->osl_pkt_sem); - return; - } - } - - for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { - if (p == bcm_static_skb->skb_8k[i]) { - bcm_static_skb->pkt_use[i + STATIC_PKT_MAX_NUM] = 0; - up(&bcm_static_skb->osl_pkt_sem); - return; - } - } - up(&bcm_static_skb->osl_pkt_sem); - - osl_pktfree(osh, p, send); - return; -} -#endif - -uint32 -osl_pci_read_config(osl_t *osh, uint offset, uint size) -{ - uint val = 0; - uint retry = PCI_CFG_RETRY; - - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - - - ASSERT(size == 4); - - do { - pci_read_config_dword(osh->pdev, offset, &val); - if (val != 0xffffffff) - break; - } while (retry--); - - - return (val); -} - -void -osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) -{ - uint retry = PCI_CFG_RETRY; - - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - - - ASSERT(size == 4); - - do { - pci_write_config_dword(osh->pdev, offset, val); - if (offset != PCI_BAR0_WIN) - break; - if (osl_pci_read_config(osh, offset, size) == val) - break; - } while (retry--); - -} - - -uint -osl_pci_bus(osl_t *osh) -{ - ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); - - return ((struct pci_dev *)osh->pdev)->bus->number; -} - - -uint -osl_pci_slot(osl_t *osh) -{ - ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); - - return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); -} - -static void -osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write) -{ -} - -void -osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size) -{ - osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE); -} - -void -osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size) -{ - osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE); -} - -void * -osl_malloc(osl_t *osh, uint size) -{ - void *addr; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - gfp_t flags; - - - if (osh) - ASSERT(osh->magic == OS_HANDLE_MAGIC); - - flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; - if ((addr = kmalloc(size, flags)) == NULL) { -#else - if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) { -#endif - if (osh) - osh->failed++; - return (NULL); - } - if (osh) - atomic_add(size, &osh->malloced); - - return (addr); -} - -void -osl_mfree(osl_t *osh, void *addr, uint size) -{ - if (osh) { - ASSERT(osh->magic == OS_HANDLE_MAGIC); - atomic_sub(size, &osh->malloced); - } - kfree(addr); -} - -uint -osl_malloced(osl_t *osh) -{ - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - return (atomic_read(&osh->malloced)); -} - -uint -osl_malloc_failed(osl_t *osh) -{ - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - return (osh->failed); -} - - - -uint -osl_dma_consistent_align(void) -{ - return (PAGE_SIZE); -} - -void* -osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align_bits, uint *alloced, ulong *pap) -{ - uint16 align = (1 << align_bits); - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - - if (!ISALIGNED(DMA_CONSISTENT_ALIGN, align)) - size += align; - *alloced = size; - - return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap)); -} - -void -osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa) -{ - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - - pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa); -} - -uint BCMFASTPATH -osl_dma_map(osl_t *osh, void *va, uint size, int direction) -{ - int dir; - - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; - return (pci_map_single(osh->pdev, va, size, dir)); -} - -void BCMFASTPATH -osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction) -{ - int dir; - - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; - pci_unmap_single(osh->pdev, (uint32)pa, size, dir); -} - -#if defined(BCMASSERT_LOG) -void -osl_assert(char *exp, char *file, int line) -{ - char tempbuf[256]; - char *basename; - - basename = strrchr(file, '/'); - - if (basename) - basename++; - - if (!basename) - basename = file; - -#ifdef BCMASSERT_LOG - snprintf(tempbuf, 64, "\"%s\": file \"%s\", line %d\n", - exp, basename, line); - - bcm_assert_log(tempbuf); -#endif - - -} -#endif - -void -osl_delay(uint usec) -{ - uint d; - - while (usec > 0) { - d = MIN(usec, 1000); - udelay(d); - usec -= d; - } -} - - - -void * -osl_pktdup(osl_t *osh, void *skb) -{ - void * p; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - gfp_t flags; - - flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; - if ((p = skb_clone((struct sk_buff *)skb, flags)) == NULL) -#else - if ((p = skb_clone((struct sk_buff*)skb, GFP_ATOMIC)) == NULL) -#endif - return NULL; - -#ifdef CTFPOOL - if (PKTISFAST(osh, skb)) { - ctfpool_t *ctfpool; - - - ctfpool = (ctfpool_t *)CTFPOOLPTR(osh, skb); - ASSERT(ctfpool != NULL); - PKTCLRFAST(osh, p); - PKTCLRFAST(osh, skb); - ctfpool->refills++; - } -#endif - - - if (osh->pub.pkttag) - bzero((void*)((struct sk_buff *)p)->cb, OSL_PKTTAG_SZ); - - - osh->pub.pktalloced++; - return (p); -} - - - - - - - -void * -osl_os_open_image(char *filename) -{ - struct file *fp; - - fp = filp_open(filename, O_RDONLY, 0); - - if (IS_ERR(fp)) - fp = NULL; - - return fp; -} - -int -osl_os_get_image_block(char *buf, int len, void *image) -{ - struct file *fp = (struct file *)image; - int rdlen; - - if (!image) - return 0; - - rdlen = kernel_read(fp, fp->f_pos, buf, len); - if (rdlen > 0) - fp->f_pos += rdlen; - - return rdlen; -} - -void -osl_os_close_image(void *image) -{ - if (image) - filp_close((struct file *)image, NULL); -} diff --git a/drivers/net/wireless/bcmdhd/sbutils.c b/drivers/net/wireless/bcmdhd/sbutils.c deleted file mode 100644 index 02d1bc0a79d1..000000000000 --- a/drivers/net/wireless/bcmdhd/sbutils.c +++ /dev/null @@ -1,992 +0,0 @@ -/* - * Misc utility routines for accessing chip-specific features - * of the SiliconBackplane-based Broadcom chips. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: sbutils.c,v 1.687.2.1 2010-11-29 20:21:56 Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "siutils_priv.h" - - -/* local prototypes */ -static uint _sb_coreidx(si_info_t *sii, uint32 sba); -static uint _sb_scan(si_info_t *sii, uint32 sba, void *regs, uint bus, uint32 sbba, - uint ncores); -static uint32 _sb_coresba(si_info_t *sii); -static void *_sb_setcoreidx(si_info_t *sii, uint coreidx); - -#define SET_SBREG(sii, r, mask, val) \ - W_SBREG((sii), (r), ((R_SBREG((sii), (r)) & ~(mask)) | (val))) -#define REGS2SB(va) (sbconfig_t*) ((int8*)(va) + SBCONFIGOFF) - -/* sonicsrev */ -#define SONICS_2_2 (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT) -#define SONICS_2_3 (SBIDL_RV_2_3 >> SBIDL_RV_SHIFT) - -#define R_SBREG(sii, sbr) sb_read_sbreg((sii), (sbr)) -#define W_SBREG(sii, sbr, v) sb_write_sbreg((sii), (sbr), (v)) -#define AND_SBREG(sii, sbr, v) W_SBREG((sii), (sbr), (R_SBREG((sii), (sbr)) & (v))) -#define OR_SBREG(sii, sbr, v) W_SBREG((sii), (sbr), (R_SBREG((sii), (sbr)) | (v))) - -static uint32 -sb_read_sbreg(si_info_t *sii, volatile uint32 *sbr) -{ - uint8 tmp; - uint32 val, intr_val = 0; - - - /* - * compact flash only has 11 bits address, while we needs 12 bits address. - * MEM_SEG will be OR'd with other 11 bits address in hardware, - * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). - * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special - */ - if (PCMCIA(sii)) { - INTR_OFF(sii, intr_val); - tmp = 1; - OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1); - sbr = (volatile uint32 *)((uintptr)sbr & ~(1 << 11)); /* mask out bit 11 */ - } - - val = R_REG(sii->osh, sbr); - - if (PCMCIA(sii)) { - tmp = 0; - OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1); - INTR_RESTORE(sii, intr_val); - } - - return (val); -} - -static void -sb_write_sbreg(si_info_t *sii, volatile uint32 *sbr, uint32 v) -{ - uint8 tmp; - volatile uint32 dummy; - uint32 intr_val = 0; - - - /* - * compact flash only has 11 bits address, while we needs 12 bits address. - * MEM_SEG will be OR'd with other 11 bits address in hardware, - * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). - * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special - */ - if (PCMCIA(sii)) { - INTR_OFF(sii, intr_val); - tmp = 1; - OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1); - sbr = (volatile uint32 *)((uintptr)sbr & ~(1 << 11)); /* mask out bit 11 */ - } - - if (BUSTYPE(sii->pub.bustype) == PCMCIA_BUS) { - dummy = R_REG(sii->osh, sbr); - W_REG(sii->osh, (volatile uint16 *)sbr, (uint16)(v & 0xffff)); - dummy = R_REG(sii->osh, sbr); - W_REG(sii->osh, ((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); - } else - W_REG(sii->osh, sbr, v); - - if (PCMCIA(sii)) { - tmp = 0; - OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1); - INTR_RESTORE(sii, intr_val); - } -} - -uint -sb_coreid(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - return ((R_SBREG(sii, &sb->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT); -} - -uint -sb_intflag(si_t *sih) -{ - si_info_t *sii; - void *corereg; - sbconfig_t *sb; - uint origidx, intflag, intr_val = 0; - - sii = SI_INFO(sih); - - INTR_OFF(sii, intr_val); - origidx = si_coreidx(sih); - corereg = si_setcore(sih, CC_CORE_ID, 0); - ASSERT(corereg != NULL); - sb = REGS2SB(corereg); - intflag = R_SBREG(sii, &sb->sbflagst); - sb_setcoreidx(sih, origidx); - INTR_RESTORE(sii, intr_val); - - return intflag; -} - -uint -sb_flag(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - return R_SBREG(sii, &sb->sbtpsflag) & SBTPS_NUM0_MASK; -} - -void -sb_setint(si_t *sih, int siflag) -{ - si_info_t *sii; - sbconfig_t *sb; - uint32 vec; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - if (siflag == -1) - vec = 0; - else - vec = 1 << siflag; - W_SBREG(sii, &sb->sbintvec, vec); -} - -/* return core index of the core with address 'sba' */ -static uint -_sb_coreidx(si_info_t *sii, uint32 sba) -{ - uint i; - - for (i = 0; i < sii->numcores; i ++) - if (sba == sii->coresba[i]) - return i; - return BADIDX; -} - -/* return core address of the current core */ -static uint32 -_sb_coresba(si_info_t *sii) -{ - uint32 sbaddr; - - - switch (BUSTYPE(sii->pub.bustype)) { - case SI_BUS: { - sbconfig_t *sb = REGS2SB(sii->curmap); - sbaddr = sb_base(R_SBREG(sii, &sb->sbadmatch0)); - break; - } - - case PCI_BUS: - sbaddr = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32)); - break; - - case PCMCIA_BUS: { - uint8 tmp = 0; - OSL_PCMCIA_READ_ATTR(sii->osh, PCMCIA_ADDR0, &tmp, 1); - sbaddr = (uint32)tmp << 12; - OSL_PCMCIA_READ_ATTR(sii->osh, PCMCIA_ADDR1, &tmp, 1); - sbaddr |= (uint32)tmp << 16; - OSL_PCMCIA_READ_ATTR(sii->osh, PCMCIA_ADDR2, &tmp, 1); - sbaddr |= (uint32)tmp << 24; - break; - } - - case SPI_BUS: - case SDIO_BUS: - sbaddr = (uint32)(uintptr)sii->curmap; - break; - - - default: - sbaddr = BADCOREADDR; - break; - } - - return sbaddr; -} - -uint -sb_corevendor(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - return ((R_SBREG(sii, &sb->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT); -} - -uint -sb_corerev(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - uint sbidh; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - sbidh = R_SBREG(sii, &sb->sbidhigh); - - return (SBCOREREV(sbidh)); -} - -/* set core-specific control flags */ -void -sb_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - sbconfig_t *sb; - uint32 w; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - ASSERT((val & ~mask) == 0); - - /* mask and set */ - w = (R_SBREG(sii, &sb->sbtmstatelow) & ~(mask << SBTML_SICF_SHIFT)) | - (val << SBTML_SICF_SHIFT); - W_SBREG(sii, &sb->sbtmstatelow, w); -} - -/* set/clear core-specific control flags */ -uint32 -sb_core_cflags(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - sbconfig_t *sb; - uint32 w; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - ASSERT((val & ~mask) == 0); - - /* mask and set */ - if (mask || val) { - w = (R_SBREG(sii, &sb->sbtmstatelow) & ~(mask << SBTML_SICF_SHIFT)) | - (val << SBTML_SICF_SHIFT); - W_SBREG(sii, &sb->sbtmstatelow, w); - } - - /* return the new value - * for write operation, the following readback ensures the completion of write opration. - */ - return (R_SBREG(sii, &sb->sbtmstatelow) >> SBTML_SICF_SHIFT); -} - -/* set/clear core-specific status flags */ -uint32 -sb_core_sflags(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - sbconfig_t *sb; - uint32 w; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - ASSERT((val & ~mask) == 0); - ASSERT((mask & ~SISF_CORE_BITS) == 0); - - /* mask and set */ - if (mask || val) { - w = (R_SBREG(sii, &sb->sbtmstatehigh) & ~(mask << SBTMH_SISF_SHIFT)) | - (val << SBTMH_SISF_SHIFT); - W_SBREG(sii, &sb->sbtmstatehigh, w); - } - - /* return the new value */ - return (R_SBREG(sii, &sb->sbtmstatehigh) >> SBTMH_SISF_SHIFT); -} - -bool -sb_iscoreup(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - return ((R_SBREG(sii, &sb->sbtmstatelow) & - (SBTML_RESET | SBTML_REJ_MASK | (SICF_CLOCK_EN << SBTML_SICF_SHIFT))) == - (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); -} - -/* - * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, - * switch back to the original core, and return the new value. - * - * When using the silicon backplane, no fidleing with interrupts or core switches are needed. - * - * Also, when using pci/pcie, we can optimize away the core switching for pci registers - * and (on newer pci cores) chipcommon registers. - */ -uint -sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) -{ - uint origidx = 0; - uint32 *r = NULL; - uint w; - uint intr_val = 0; - bool fast = FALSE; - si_info_t *sii; - - sii = SI_INFO(sih); - - ASSERT(GOODIDX(coreidx)); - ASSERT(regoff < SI_CORE_SIZE); - ASSERT((val & ~mask) == 0); - - if (coreidx >= SI_MAXCORES) - return 0; - - if (BUSTYPE(sii->pub.bustype) == SI_BUS) { - /* If internal bus, we can always get at everything */ - fast = TRUE; - /* map if does not exist */ - if (!sii->regs[coreidx]) { - sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx], - SI_CORE_SIZE); - ASSERT(GOODREGS(sii->regs[coreidx])); - } - r = (uint32 *)((uchar *)sii->regs[coreidx] + regoff); - } else if (BUSTYPE(sii->pub.bustype) == PCI_BUS) { - /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */ - - if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) { - /* Chipc registers are mapped at 12KB */ - - fast = TRUE; - r = (uint32 *)((char *)sii->curmap + PCI_16KB0_CCREGS_OFFSET + regoff); - } else if (sii->pub.buscoreidx == coreidx) { - /* pci registers are at either in the last 2KB of an 8KB window - * or, in pcie and pci rev 13 at 8KB - */ - fast = TRUE; - if (SI_FAST(sii)) - r = (uint32 *)((char *)sii->curmap + - PCI_16KB0_PCIREGS_OFFSET + regoff); - else - r = (uint32 *)((char *)sii->curmap + - ((regoff >= SBCONFIGOFF) ? - PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) + - regoff); - } - } - - if (!fast) { - INTR_OFF(sii, intr_val); - - /* save current core index */ - origidx = si_coreidx(&sii->pub); - - /* switch core */ - r = (uint32*) ((uchar*)sb_setcoreidx(&sii->pub, coreidx) + regoff); - } - ASSERT(r != NULL); - - /* mask and set */ - if (mask || val) { - if (regoff >= SBCONFIGOFF) { - w = (R_SBREG(sii, r) & ~mask) | val; - W_SBREG(sii, r, w); - } else { - w = (R_REG(sii->osh, r) & ~mask) | val; - W_REG(sii->osh, r, w); - } - } - - /* readback */ - if (regoff >= SBCONFIGOFF) - w = R_SBREG(sii, r); - else { - if ((CHIPID(sii->pub.chip) == BCM5354_CHIP_ID) && - (coreidx == SI_CC_IDX) && - (regoff == OFFSETOF(chipcregs_t, watchdog))) { - w = val; - } else - w = R_REG(sii->osh, r); - } - - if (!fast) { - /* restore core index */ - if (origidx != coreidx) - sb_setcoreidx(&sii->pub, origidx); - - INTR_RESTORE(sii, intr_val); - } - - return (w); -} - -/* Scan the enumeration space to find all cores starting from the given - * bus 'sbba'. Append coreid and other info to the lists in 'si'. 'sba' - * is the default core address at chip POR time and 'regs' is the virtual - * address that the default core is mapped at. 'ncores' is the number of - * cores expected on bus 'sbba'. It returns the total number of cores - * starting from bus 'sbba', inclusive. - */ -#define SB_MAXBUSES 2 -static uint -_sb_scan(si_info_t *sii, uint32 sba, void *regs, uint bus, uint32 sbba, uint numcores) -{ - uint next; - uint ncc = 0; - uint i; - - if (bus >= SB_MAXBUSES) { - SI_ERROR(("_sb_scan: bus 0x%08x at level %d is too deep to scan\n", sbba, bus)); - return 0; - } - SI_MSG(("_sb_scan: scan bus 0x%08x assume %u cores\n", sbba, numcores)); - - /* Scan all cores on the bus starting from core 0. - * Core addresses must be contiguous on each bus. - */ - for (i = 0, next = sii->numcores; i < numcores && next < SB_BUS_MAXCORES; i++, next++) { - sii->coresba[next] = sbba + (i * SI_CORE_SIZE); - - /* keep and reuse the initial register mapping */ - if ((BUSTYPE(sii->pub.bustype) == SI_BUS) && (sii->coresba[next] == sba)) { - SI_VMSG(("_sb_scan: reuse mapped regs %p for core %u\n", regs, next)); - sii->regs[next] = regs; - } - - /* change core to 'next' and read its coreid */ - sii->curmap = _sb_setcoreidx(sii, next); - sii->curidx = next; - - sii->coreid[next] = sb_coreid(&sii->pub); - - /* core specific processing... */ - /* chipc provides # cores */ - if (sii->coreid[next] == CC_CORE_ID) { - chipcregs_t *cc = (chipcregs_t *)sii->curmap; - uint32 ccrev = sb_corerev(&sii->pub); - - /* determine numcores - this is the total # cores in the chip */ - if (((ccrev == 4) || (ccrev >= 6))) - numcores = (R_REG(sii->osh, &cc->chipid) & CID_CC_MASK) >> - CID_CC_SHIFT; - else { - /* Older chips */ - uint chip = CHIPID(sii->pub.chip); - - if (chip == BCM4306_CHIP_ID) /* < 4306c0 */ - numcores = 6; - else if (chip == BCM4704_CHIP_ID) - numcores = 9; - else if (chip == BCM5365_CHIP_ID) - numcores = 7; - else { - SI_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", - chip)); - ASSERT(0); - numcores = 1; - } - } - SI_VMSG(("_sb_scan: there are %u cores in the chip %s\n", numcores, - sii->pub.issim ? "QT" : "")); - } - /* scan bridged SB(s) and add results to the end of the list */ - else if (sii->coreid[next] == OCP_CORE_ID) { - sbconfig_t *sb = REGS2SB(sii->curmap); - uint32 nsbba = R_SBREG(sii, &sb->sbadmatch1); - uint nsbcc; - - sii->numcores = next + 1; - - if ((nsbba & 0xfff00000) != SI_ENUM_BASE) - continue; - nsbba &= 0xfffff000; - if (_sb_coreidx(sii, nsbba) != BADIDX) - continue; - - nsbcc = (R_SBREG(sii, &sb->sbtmstatehigh) & 0x000f0000) >> 16; - nsbcc = _sb_scan(sii, sba, regs, bus + 1, nsbba, nsbcc); - if (sbba == SI_ENUM_BASE) - numcores -= nsbcc; - ncc += nsbcc; - } - } - - SI_MSG(("_sb_scan: found %u cores on bus 0x%08x\n", i, sbba)); - - sii->numcores = i + ncc; - return sii->numcores; -} - -/* scan the sb enumerated space to identify all cores */ -void -sb_scan(si_t *sih, void *regs, uint devid) -{ - si_info_t *sii; - uint32 origsba; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - sii->pub.socirev = (R_SBREG(sii, &sb->sbidlow) & SBIDL_RV_MASK) >> SBIDL_RV_SHIFT; - - /* Save the current core info and validate it later till we know - * for sure what is good and what is bad. - */ - origsba = _sb_coresba(sii); - - /* scan all SB(s) starting from SI_ENUM_BASE */ - sii->numcores = _sb_scan(sii, origsba, regs, 0, SI_ENUM_BASE, 1); -} - -/* - * This function changes logical "focus" to the indicated core; - * must be called with interrupts off. - * Moreover, callers should keep interrupts off during switching out of and back to d11 core - */ -void * -sb_setcoreidx(si_t *sih, uint coreidx) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - if (coreidx >= sii->numcores) - return (NULL); - - /* - * If the user has provided an interrupt mask enabled function, - * then assert interrupts are disabled before switching the core. - */ - ASSERT((sii->intrsenabled_fn == NULL) || !(*(sii)->intrsenabled_fn)((sii)->intr_arg)); - - sii->curmap = _sb_setcoreidx(sii, coreidx); - sii->curidx = coreidx; - - return (sii->curmap); -} - -/* This function changes the logical "focus" to the indicated core. - * Return the current core's virtual address. - */ -static void * -_sb_setcoreidx(si_info_t *sii, uint coreidx) -{ - uint32 sbaddr = sii->coresba[coreidx]; - void *regs; - - switch (BUSTYPE(sii->pub.bustype)) { - case SI_BUS: - /* map new one */ - if (!sii->regs[coreidx]) { - sii->regs[coreidx] = REG_MAP(sbaddr, SI_CORE_SIZE); - ASSERT(GOODREGS(sii->regs[coreidx])); - } - regs = sii->regs[coreidx]; - break; - - case PCI_BUS: - /* point bar0 window */ - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, sbaddr); - regs = sii->curmap; - break; - - case PCMCIA_BUS: { - uint8 tmp = (sbaddr >> 12) & 0x0f; - OSL_PCMCIA_WRITE_ATTR(sii->osh, PCMCIA_ADDR0, &tmp, 1); - tmp = (sbaddr >> 16) & 0xff; - OSL_PCMCIA_WRITE_ATTR(sii->osh, PCMCIA_ADDR1, &tmp, 1); - tmp = (sbaddr >> 24) & 0xff; - OSL_PCMCIA_WRITE_ATTR(sii->osh, PCMCIA_ADDR2, &tmp, 1); - regs = sii->curmap; - break; - } - case SPI_BUS: - case SDIO_BUS: - /* map new one */ - if (!sii->regs[coreidx]) { - sii->regs[coreidx] = (void *)(uintptr)sbaddr; - ASSERT(GOODREGS(sii->regs[coreidx])); - } - regs = sii->regs[coreidx]; - break; - - - default: - ASSERT(0); - regs = NULL; - break; - } - - return regs; -} - -/* Return the address of sbadmatch0/1/2/3 register */ -static volatile uint32 * -sb_admatch(si_info_t *sii, uint asidx) -{ - sbconfig_t *sb; - volatile uint32 *addrm; - - sb = REGS2SB(sii->curmap); - - switch (asidx) { - case 0: - addrm = &sb->sbadmatch0; - break; - - case 1: - addrm = &sb->sbadmatch1; - break; - - case 2: - addrm = &sb->sbadmatch2; - break; - - case 3: - addrm = &sb->sbadmatch3; - break; - - default: - SI_ERROR(("%s: Address space index (%d) out of range\n", __FUNCTION__, asidx)); - return 0; - } - - return (addrm); -} - -/* Return the number of address spaces in current core */ -int -sb_numaddrspaces(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - /* + 1 because of enumeration space */ - return ((R_SBREG(sii, &sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT) + 1; -} - -/* Return the address of the nth address space in the current core */ -uint32 -sb_addrspace(si_t *sih, uint asidx) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - return (sb_base(R_SBREG(sii, sb_admatch(sii, asidx)))); -} - -/* Return the size of the nth address space in the current core */ -uint32 -sb_addrspacesize(si_t *sih, uint asidx) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - return (sb_size(R_SBREG(sii, sb_admatch(sii, asidx)))); -} - - -/* do buffered registers update */ -void -sb_commit(si_t *sih) -{ - si_info_t *sii; - uint origidx; - uint intr_val = 0; - - sii = SI_INFO(sih); - - origidx = sii->curidx; - ASSERT(GOODIDX(origidx)); - - INTR_OFF(sii, intr_val); - - /* switch over to chipcommon core if there is one, else use pci */ - if (sii->pub.ccrev != NOREV) { - chipcregs_t *ccregs = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); - ASSERT(ccregs != NULL); - - /* do the buffer registers update */ - W_REG(sii->osh, &ccregs->broadcastaddress, SB_COMMIT); - W_REG(sii->osh, &ccregs->broadcastdata, 0x0); - } else - ASSERT(0); - - /* restore core index */ - sb_setcoreidx(sih, origidx); - INTR_RESTORE(sii, intr_val); -} - -void -sb_core_disable(si_t *sih, uint32 bits) -{ - si_info_t *sii; - volatile uint32 dummy; - sbconfig_t *sb; - - sii = SI_INFO(sih); - - ASSERT(GOODREGS(sii->curmap)); - sb = REGS2SB(sii->curmap); - - /* if core is already in reset, just return */ - if (R_SBREG(sii, &sb->sbtmstatelow) & SBTML_RESET) - return; - - /* if clocks are not enabled, put into reset and return */ - if ((R_SBREG(sii, &sb->sbtmstatelow) & (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) == 0) - goto disable; - - /* set target reject and spin until busy is clear (preserve core-specific bits) */ - OR_SBREG(sii, &sb->sbtmstatelow, SBTML_REJ); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - OSL_DELAY(1); - SPINWAIT((R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000); - if (R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_BUSY) - SI_ERROR(("%s: target state still busy\n", __FUNCTION__)); - - if (R_SBREG(sii, &sb->sbidlow) & SBIDL_INIT) { - OR_SBREG(sii, &sb->sbimstate, SBIM_RJ); - dummy = R_SBREG(sii, &sb->sbimstate); - OSL_DELAY(1); - SPINWAIT((R_SBREG(sii, &sb->sbimstate) & SBIM_BY), 100000); - } - - /* set reset and reject while enabling the clocks */ - W_SBREG(sii, &sb->sbtmstatelow, - (((bits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | - SBTML_REJ | SBTML_RESET)); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - OSL_DELAY(10); - - /* don't forget to clear the initiator reject bit */ - if (R_SBREG(sii, &sb->sbidlow) & SBIDL_INIT) - AND_SBREG(sii, &sb->sbimstate, ~SBIM_RJ); - -disable: - /* leave reset and reject asserted */ - W_SBREG(sii, &sb->sbtmstatelow, ((bits << SBTML_SICF_SHIFT) | SBTML_REJ | SBTML_RESET)); - OSL_DELAY(1); -} - -/* reset and re-enable a core - * inputs: - * bits - core specific bits that are set during and after reset sequence - * resetbits - core specific bits that are set only during reset sequence - */ -void -sb_core_reset(si_t *sih, uint32 bits, uint32 resetbits) -{ - si_info_t *sii; - sbconfig_t *sb; - volatile uint32 dummy; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curmap)); - sb = REGS2SB(sii->curmap); - - /* - * Must do the disable sequence first to work for arbitrary current core state. - */ - sb_core_disable(sih, (bits | resetbits)); - - /* - * Now do the initialization sequence. - */ - - /* set reset while enabling the clock and forcing them on throughout the core */ - W_SBREG(sii, &sb->sbtmstatelow, - (((bits | resetbits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | - SBTML_RESET)); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - OSL_DELAY(1); - - if (R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_SERR) { - W_SBREG(sii, &sb->sbtmstatehigh, 0); - } - if ((dummy = R_SBREG(sii, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) { - AND_SBREG(sii, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO)); - } - - /* clear reset and allow it to propagate throughout the core */ - W_SBREG(sii, &sb->sbtmstatelow, - ((bits | resetbits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT)); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - OSL_DELAY(1); - - /* leave clock enabled */ - W_SBREG(sii, &sb->sbtmstatelow, ((bits | SICF_CLOCK_EN) << SBTML_SICF_SHIFT)); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - OSL_DELAY(1); -} - -/* - * Set the initiator timeout for the "master core". - * The master core is defined to be the core in control - * of the chip and so it issues accesses to non-memory - * locations (Because of dma *any* core can access memeory). - * - * The routine uses the bus to decide who is the master: - * SI_BUS => mips - * JTAG_BUS => chipc - * PCI_BUS => pci or pcie - * PCMCIA_BUS => pcmcia - * SDIO_BUS => pcmcia - * - * This routine exists so callers can disable initiator - * timeouts so accesses to very slow devices like otp - * won't cause an abort. The routine allows arbitrary - * settings of the service and request timeouts, though. - * - * Returns the timeout state before changing it or -1 - * on error. - */ - -#define TO_MASK (SBIMCL_RTO_MASK | SBIMCL_STO_MASK) - -uint32 -sb_set_initiator_to(si_t *sih, uint32 to, uint idx) -{ - si_info_t *sii; - uint origidx; - uint intr_val = 0; - uint32 tmp, ret = 0xffffffff; - sbconfig_t *sb; - - sii = SI_INFO(sih); - - if ((to & ~TO_MASK) != 0) - return ret; - - /* Figure out the master core */ - if (idx == BADIDX) { - switch (BUSTYPE(sii->pub.bustype)) { - case PCI_BUS: - idx = sii->pub.buscoreidx; - break; - case JTAG_BUS: - idx = SI_CC_IDX; - break; - case PCMCIA_BUS: - case SDIO_BUS: - idx = si_findcoreidx(sih, PCMCIA_CORE_ID, 0); - break; - case SI_BUS: - idx = si_findcoreidx(sih, MIPS33_CORE_ID, 0); - break; - default: - ASSERT(0); - } - if (idx == BADIDX) - return ret; - } - - INTR_OFF(sii, intr_val); - origidx = si_coreidx(sih); - - sb = REGS2SB(sb_setcoreidx(sih, idx)); - - tmp = R_SBREG(sii, &sb->sbimconfiglow); - ret = tmp & TO_MASK; - W_SBREG(sii, &sb->sbimconfiglow, (tmp & ~TO_MASK) | to); - - sb_commit(sih); - sb_setcoreidx(sih, origidx); - INTR_RESTORE(sii, intr_val); - return ret; -} - -uint32 -sb_base(uint32 admatch) -{ - uint32 base; - uint type; - - type = admatch & SBAM_TYPE_MASK; - ASSERT(type < 3); - - base = 0; - - if (type == 0) { - base = admatch & SBAM_BASE0_MASK; - } else if (type == 1) { - ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ - base = admatch & SBAM_BASE1_MASK; - } else if (type == 2) { - ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ - base = admatch & SBAM_BASE2_MASK; - } - - return (base); -} - -uint32 -sb_size(uint32 admatch) -{ - uint32 size; - uint type; - - type = admatch & SBAM_TYPE_MASK; - ASSERT(type < 3); - - size = 0; - - if (type == 0) { - size = 1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) + 1); - } else if (type == 1) { - ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ - size = 1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) + 1); - } else if (type == 2) { - ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ - size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1); - } - - return (size); -} diff --git a/drivers/net/wireless/bcmdhd/siutils.c b/drivers/net/wireless/bcmdhd/siutils.c deleted file mode 100644 index a655ac4ef141..000000000000 --- a/drivers/net/wireless/bcmdhd/siutils.c +++ /dev/null @@ -1,1915 +0,0 @@ -/* - * Misc utility routines for accessing chip-specific features - * of the SiliconBackplane-based Broadcom chips. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: siutils.c,v 1.813.2.36 2011-02-10 23:43:55 $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "siutils_priv.h" - -/* local prototypes */ -static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs, - uint bustype, void *sdh, char **vars, uint *varsz); -static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh); -static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin, - uint *origidx, void *regs); - - -/* global variable to indicate reservation/release of gpio's */ -static uint32 si_gpioreservation = 0; - -/* global flag to prevent shared resources from being initialized multiple times in si_attach() */ - -/* - * Allocate a si handle. - * devid - pci device id (used to determine chip#) - * osh - opaque OS handle - * regs - virtual address of initial core registers - * bustype - pci/pcmcia/sb/sdio/etc - * vars - pointer to a pointer area for "environment" variables - * varsz - pointer to int to return the size of the vars - */ -si_t * -si_attach(uint devid, osl_t *osh, void *regs, - uint bustype, void *sdh, char **vars, uint *varsz) -{ - si_info_t *sii; - - /* alloc si_info_t */ - if ((sii = MALLOC(osh, sizeof (si_info_t))) == NULL) { - SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh))); - return (NULL); - } - - if (si_doattach(sii, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) { - MFREE(osh, sii, sizeof(si_info_t)); - return (NULL); - } - sii->vars = vars ? *vars : NULL; - sii->varsz = varsz ? *varsz : 0; - - return (si_t *)sii; -} - -/* global kernel resource */ -static si_info_t ksii; - -static uint32 wd_msticks; /* watchdog timer ticks normalized to ms */ - -/* generic kernel variant of si_attach() */ -si_t * -si_kattach(osl_t *osh) -{ - static bool ksii_attached = FALSE; - - if (!ksii_attached) { - void *regs; - regs = REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE); - - if (si_doattach(&ksii, BCM4710_DEVICE_ID, osh, regs, - SI_BUS, NULL, - osh != SI_OSH ? &ksii.vars : NULL, - osh != SI_OSH ? &ksii.varsz : NULL) == NULL) { - SI_ERROR(("si_kattach: si_doattach failed\n")); - REG_UNMAP(regs); - return NULL; - } - REG_UNMAP(regs); - - /* save ticks normalized to ms for si_watchdog_ms() */ - if (PMUCTL_ENAB(&ksii.pub)) { - /* based on 32KHz ILP clock */ - wd_msticks = 32; - } else { - wd_msticks = ALP_CLOCK / 1000; - } - - ksii_attached = TRUE; - SI_MSG(("si_kattach done. ccrev = %d, wd_msticks = %d\n", - ksii.pub.ccrev, wd_msticks)); - } - - return &ksii.pub; -} - - -static bool -si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh) -{ - /* need to set memseg flag for CF card first before any sb registers access */ - if (BUSTYPE(bustype) == PCMCIA_BUS) - sii->memseg = TRUE; - - - if (BUSTYPE(bustype) == SDIO_BUS) { - int err; - uint8 clkset; - - /* Try forcing SDIO core to do ALPAvail request only */ - clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); - if (!err) { - uint8 clkval; - - /* If register supported, wait for ALPAvail and then force ALP */ - clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, NULL); - if ((clkval & ~SBSDIO_AVBITS) == clkset) { - SPINWAIT(((clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_CHIPCLKCSR, NULL)), !SBSDIO_ALPAV(clkval)), - PMU_MAX_TRANSITION_DLY); - if (!SBSDIO_ALPAV(clkval)) { - SI_ERROR(("timeout on ALPAV wait, clkval 0x%02x\n", - clkval)); - return FALSE; - } - clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - clkset, &err); - OSL_DELAY(65); - } - } - - /* Also, disable the extra SDIO pull-ups */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); - } - - - return TRUE; -} - -static bool -si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin, - uint *origidx, void *regs) -{ - bool pci, pcie; - uint i; - uint pciidx, pcieidx, pcirev, pcierev; - - cc = si_setcoreidx(&sii->pub, SI_CC_IDX); - ASSERT((uintptr)cc); - - /* get chipcommon rev */ - sii->pub.ccrev = (int)si_corerev(&sii->pub); - - /* get chipcommon chipstatus */ - if (sii->pub.ccrev >= 11) - sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus); - - /* get chipcommon capabilites */ - sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities); - /* get chipcommon extended capabilities */ - - if (sii->pub.ccrev >= 35) - sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext); - - /* get pmu rev and caps */ - if (sii->pub.cccaps & CC_CAP_PMU) { - sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities); - sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK; - } - - SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n", - sii->pub.ccrev, sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev, - sii->pub.pmucaps)); - - /* figure out bus/orignal core idx */ - sii->pub.buscoretype = NODEV_CORE_ID; - sii->pub.buscorerev = (uint)NOREV; - sii->pub.buscoreidx = BADIDX; - - pci = pcie = FALSE; - pcirev = pcierev = (uint)NOREV; - pciidx = pcieidx = BADIDX; - - for (i = 0; i < sii->numcores; i++) { - uint cid, crev; - - si_setcoreidx(&sii->pub, i); - cid = si_coreid(&sii->pub); - crev = si_corerev(&sii->pub); - - /* Display cores found */ - SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n", - i, cid, crev, sii->coresba[i], sii->regs[i])); - - if (BUSTYPE(bustype) == PCI_BUS) { - if (cid == PCI_CORE_ID) { - pciidx = i; - pcirev = crev; - pci = TRUE; - } else if (cid == PCIE_CORE_ID) { - pcieidx = i; - pcierev = crev; - pcie = TRUE; - } - } else if ((BUSTYPE(bustype) == PCMCIA_BUS) && - (cid == PCMCIA_CORE_ID)) { - sii->pub.buscorerev = crev; - sii->pub.buscoretype = cid; - sii->pub.buscoreidx = i; - } - else if (((BUSTYPE(bustype) == SDIO_BUS) || - (BUSTYPE(bustype) == SPI_BUS)) && - ((cid == PCMCIA_CORE_ID) || - (cid == SDIOD_CORE_ID))) { - sii->pub.buscorerev = crev; - sii->pub.buscoretype = cid; - sii->pub.buscoreidx = i; - } - - /* find the core idx before entering this func. */ - if ((savewin && (savewin == sii->coresba[i])) || - (regs == sii->regs[i])) - *origidx = i; - } - - if (pci) { - sii->pub.buscoretype = PCI_CORE_ID; - sii->pub.buscorerev = pcirev; - sii->pub.buscoreidx = pciidx; - } else if (pcie) { - sii->pub.buscoretype = PCIE_CORE_ID; - sii->pub.buscorerev = pcierev; - sii->pub.buscoreidx = pcieidx; - } - - SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, sii->pub.buscoretype, - sii->pub.buscorerev)); - - if (BUSTYPE(sii->pub.bustype) == SI_BUS && (CHIPID(sii->pub.chip) == BCM4712_CHIP_ID) && - (sii->pub.chippkg != BCM4712LARGE_PKG_ID) && (CHIPREV(sii->pub.chiprev) <= 3)) - OR_REG(sii->osh, &cc->slow_clk_ctl, SCC_SS_XTAL); - - - /* Make sure any on-chip ARM is off (in case strapping is wrong), or downloaded code was - * already running. - */ - if ((BUSTYPE(bustype) == SDIO_BUS) || (BUSTYPE(bustype) == SPI_BUS)) { - if (si_setcore(&sii->pub, ARM7S_CORE_ID, 0) || - si_setcore(&sii->pub, ARMCM3_CORE_ID, 0)) - si_core_disable(&sii->pub, 0); - } - - /* return to the original core */ - si_setcoreidx(&sii->pub, *origidx); - - return TRUE; -} - - - -static si_info_t * -si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs, - uint bustype, void *sdh, char **vars, uint *varsz) -{ - struct si_pub *sih = &sii->pub; - uint32 w, savewin; - chipcregs_t *cc; - char *pvars = NULL; - uint origidx; - - ASSERT(GOODREGS(regs)); - - bzero((uchar*)sii, sizeof(si_info_t)); - - savewin = 0; - - sih->buscoreidx = BADIDX; - - sii->curmap = regs; - sii->sdh = sdh; - sii->osh = osh; - - - - /* find Chipcommon address */ - if (bustype == PCI_BUS) { - savewin = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32)); - if (!GOODCOREADDR(savewin, SI_ENUM_BASE)) - savewin = SI_ENUM_BASE; - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE); - cc = (chipcregs_t *)regs; - } else if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) { - cc = (chipcregs_t *)sii->curmap; - } else { - cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE); - } - - sih->bustype = bustype; - if (bustype != BUSTYPE(bustype)) { - SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n", - bustype, BUSTYPE(bustype))); - return NULL; - } - - /* bus/core/clk setup for register access */ - if (!si_buscore_prep(sii, bustype, devid, sdh)) { - SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", bustype)); - return NULL; - } - - /* ChipID recognition. - * We assume we can read chipid at offset 0 from the regs arg. - * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon), - * some way of recognizing them needs to be added here. - */ - w = R_REG(osh, &cc->chipid); - sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT; - /* Might as wll fill in chip id rev & pkg */ - sih->chip = w & CID_ID_MASK; - sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT; - sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT; - if (CHIPID(sih->chip) == BCM4322_CHIP_ID && (((sih->chipst & CST4322_SPROM_OTP_SEL_MASK) - >> CST4322_SPROM_OTP_SEL_SHIFT) == (CST4322_OTP_PRESENT | - CST4322_SPROM_PRESENT))) { - SI_ERROR(("%s: Invalid setting: both SPROM and OTP strapped.\n", __FUNCTION__)); - return NULL; - } - -#if defined(HW_OOB) - if (CHIPID(sih->chip) == BCM43362_CHIP_ID) { - uint32 gpiocontrol, addr; - addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, gpiocontrol); - gpiocontrol = bcmsdh_reg_read(sdh, addr, 4); - gpiocontrol |= 0x2; - bcmsdh_reg_write(sdh, addr, 4, gpiocontrol); - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10005, 0xf, NULL); - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10006, 0x0, NULL); - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10007, 0x2, NULL); - } -#endif - - if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chiprev == 0) && - (sih->chippkg != BCM4329_289PIN_PKG_ID)) { - sih->chippkg = BCM4329_182PIN_PKG_ID; - } - - sih->issim = IS_SIM(sih->chippkg); - - /* scan for cores */ - if (CHIPTYPE(sii->pub.socitype) == SOCI_SB) { - SI_MSG(("Found chip type SB (0x%08x)\n", w)); - sb_scan(&sii->pub, regs, devid); - } else if (CHIPTYPE(sii->pub.socitype) == SOCI_AI) { - SI_MSG(("Found chip type AI (0x%08x)\n", w)); - /* pass chipc address instead of original core base */ - ai_scan(&sii->pub, (void *)(uintptr)cc, devid); - } else if (CHIPTYPE(sii->pub.socitype) == SOCI_UBUS) { - SI_MSG(("Found chip type UBUS (0x%08x), chip id = 0x%4x\n", w, sih->chip)); - /* pass chipc address instead of original core base */ - ub_scan(&sii->pub, (void *)(uintptr)cc, devid); - } else { - SI_ERROR(("Found chip of unknown type (0x%08x)\n", w)); - return NULL; - } - /* no cores found, bail out */ - if (sii->numcores == 0) { - SI_ERROR(("si_doattach: could not find any cores\n")); - return NULL; - } - /* bus/core/clk setup */ - origidx = SI_CC_IDX; - if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) { - SI_ERROR(("si_doattach: si_buscore_setup failed\n")); - goto exit; - } - - /* assume current core is CC */ - if ((sii->pub.ccrev == 0x25) && ((CHIPID(sih->chip) == BCM43234_CHIP_ID || - CHIPID(sih->chip) == BCM43235_CHIP_ID || - CHIPID(sih->chip) == BCM43236_CHIP_ID || - CHIPID(sih->chip) == BCM43238_CHIP_ID) && - (CHIPREV(sii->pub.chiprev) == 0))) { - - if ((cc->chipstatus & CST43236_BP_CLK) != 0) { - uint clkdiv; - clkdiv = R_REG(osh, &cc->clkdiv); - /* otp_clk_div is even number, 120/14 < 9mhz */ - clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT); - W_REG(osh, &cc->clkdiv, clkdiv); - SI_ERROR(("%s: set clkdiv to %x\n", __FUNCTION__, clkdiv)); - } - OSL_DELAY(10); - } - - - pvars = NULL; - - - - if (sii->pub.ccrev >= 20) { - cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); - ASSERT(cc != NULL); - W_REG(osh, &cc->gpiopullup, 0); - W_REG(osh, &cc->gpiopulldown, 0); - si_setcoreidx(sih, origidx); - } - - - - - return (sii); - -exit: - - return NULL; -} - -/* may be called with core in reset */ -void -si_detach(si_t *sih) -{ - si_info_t *sii; - uint idx; - - - sii = SI_INFO(sih); - - if (sii == NULL) - return; - - if (BUSTYPE(sih->bustype) == SI_BUS) - for (idx = 0; idx < SI_MAXCORES; idx++) - if (sii->regs[idx]) { - REG_UNMAP(sii->regs[idx]); - sii->regs[idx] = NULL; - } - - - -#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS) - if (sii != &ksii) -#endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */ - MFREE(sii->osh, sii, sizeof(si_info_t)); -} - -void * -si_osh(si_t *sih) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - return sii->osh; -} - -void -si_setosh(si_t *sih, osl_t *osh) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - if (sii->osh != NULL) { - SI_ERROR(("osh is already set....\n")); - ASSERT(!sii->osh); - } - sii->osh = osh; -} - -/* register driver interrupt disabling and restoring callback functions */ -void -si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn, - void *intrsenabled_fn, void *intr_arg) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - sii->intr_arg = intr_arg; - sii->intrsoff_fn = (si_intrsoff_t)intrsoff_fn; - sii->intrsrestore_fn = (si_intrsrestore_t)intrsrestore_fn; - sii->intrsenabled_fn = (si_intrsenabled_t)intrsenabled_fn; - /* save current core id. when this function called, the current core - * must be the core which provides driver functions(il, et, wl, etc.) - */ - sii->dev_coreid = sii->coreid[sii->curidx]; -} - -void -si_deregister_intr_callback(si_t *sih) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - sii->intrsoff_fn = NULL; -} - -uint -si_intflag(si_t *sih) -{ - si_info_t *sii = SI_INFO(sih); - - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_intflag(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return R_REG(sii->osh, ((uint32 *)(uintptr) - (sii->oob_router + OOB_STATUSA))); - else { - ASSERT(0); - return 0; - } -} - -uint -si_flag(si_t *sih) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_flag(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_flag(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) - return ub_flag(sih); - else { - ASSERT(0); - return 0; - } -} - -void -si_setint(si_t *sih, int siflag) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - sb_setint(sih, siflag); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - ai_setint(sih, siflag); - else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) - ub_setint(sih, siflag); - else - ASSERT(0); -} - -uint -si_coreid(si_t *sih) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - return sii->coreid[sii->curidx]; -} - -uint -si_coreidx(si_t *sih) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - return sii->curidx; -} - -/* return the core-type instantiation # of the current core */ -uint -si_coreunit(si_t *sih) -{ - si_info_t *sii; - uint idx; - uint coreid; - uint coreunit; - uint i; - - sii = SI_INFO(sih); - coreunit = 0; - - idx = sii->curidx; - - ASSERT(GOODREGS(sii->curmap)); - coreid = si_coreid(sih); - - /* count the cores of our type */ - for (i = 0; i < idx; i++) - if (sii->coreid[i] == coreid) - coreunit++; - - return (coreunit); -} - -uint -si_corevendor(si_t *sih) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_corevendor(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_corevendor(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) - return ub_corevendor(sih); - else { - ASSERT(0); - return 0; - } -} - -bool -si_backplane64(si_t *sih) -{ - return ((sih->cccaps & CC_CAP_BKPLN64) != 0); -} - -uint -si_corerev(si_t *sih) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_corerev(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_corerev(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) - return ub_corerev(sih); - else { - ASSERT(0); - return 0; - } -} - -/* return index of coreid or BADIDX if not found */ -uint -si_findcoreidx(si_t *sih, uint coreid, uint coreunit) -{ - si_info_t *sii; - uint found; - uint i; - - sii = SI_INFO(sih); - - found = 0; - - for (i = 0; i < sii->numcores; i++) - if (sii->coreid[i] == coreid) { - if (found == coreunit) - return (i); - found++; - } - - return (BADIDX); -} - -/* return list of found cores */ -uint -si_corelist(si_t *sih, uint coreid[]) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - bcopy((uchar*)sii->coreid, (uchar*)coreid, (sii->numcores * sizeof(uint))); - return (sii->numcores); -} - -/* return current register mapping */ -void * -si_coreregs(si_t *sih) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curmap)); - - return (sii->curmap); -} - -/* - * This function changes logical "focus" to the indicated core; - * must be called with interrupts off. - * Moreover, callers should keep interrupts off during switching out of and back to d11 core - */ -void * -si_setcore(si_t *sih, uint coreid, uint coreunit) -{ - uint idx; - - idx = si_findcoreidx(sih, coreid, coreunit); - if (!GOODIDX(idx)) - return (NULL); - - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_setcoreidx(sih, idx); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_setcoreidx(sih, idx); - else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) - return ub_setcoreidx(sih, idx); - else { - ASSERT(0); - return NULL; - } -} - -void * -si_setcoreidx(si_t *sih, uint coreidx) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_setcoreidx(sih, coreidx); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_setcoreidx(sih, coreidx); - else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) - return ub_setcoreidx(sih, coreidx); - else { - ASSERT(0); - return NULL; - } -} - -/* Turn off interrupt as required by sb_setcore, before switch core */ -void * -si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val) -{ - void *cc; - si_info_t *sii; - - sii = SI_INFO(sih); - - if (SI_FAST(sii)) { - /* Overloading the origidx variable to remember the coreid, - * this works because the core ids cannot be confused with - * core indices. - */ - *origidx = coreid; - if (coreid == CC_CORE_ID) - return (void *)CCREGS_FAST(sii); - else if (coreid == sih->buscoretype) - return (void *)PCIEREGS(sii); - } - INTR_OFF(sii, *intr_val); - *origidx = sii->curidx; - cc = si_setcore(sih, coreid, 0); - ASSERT(cc != NULL); - - return cc; -} - -/* restore coreidx and restore interrupt */ -void -si_restore_core(si_t *sih, uint coreid, uint intr_val) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - if (SI_FAST(sii) && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype))) - return; - - si_setcoreidx(sih, coreid); - INTR_RESTORE(sii, intr_val); -} - -int -si_numaddrspaces(si_t *sih) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_numaddrspaces(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_numaddrspaces(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) - return ub_numaddrspaces(sih); - else { - ASSERT(0); - return 0; - } -} - -uint32 -si_addrspace(si_t *sih, uint asidx) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_addrspace(sih, asidx); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_addrspace(sih, asidx); - else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) - return ub_addrspace(sih, asidx); - else { - ASSERT(0); - return 0; - } -} - -uint32 -si_addrspacesize(si_t *sih, uint asidx) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_addrspacesize(sih, asidx); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_addrspacesize(sih, asidx); - else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) - return ub_addrspacesize(sih, asidx); - else { - ASSERT(0); - return 0; - } -} - -uint32 -si_core_cflags(si_t *sih, uint32 mask, uint32 val) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_core_cflags(sih, mask, val); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_core_cflags(sih, mask, val); - else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) - return ub_core_cflags(sih, mask, val); - else { - ASSERT(0); - return 0; - } -} - -void -si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - sb_core_cflags_wo(sih, mask, val); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - ai_core_cflags_wo(sih, mask, val); - else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) - ub_core_cflags_wo(sih, mask, val); - else - ASSERT(0); -} - -uint32 -si_core_sflags(si_t *sih, uint32 mask, uint32 val) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_core_sflags(sih, mask, val); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_core_sflags(sih, mask, val); - else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) - return ub_core_sflags(sih, mask, val); - else { - ASSERT(0); - return 0; - } -} - -bool -si_iscoreup(si_t *sih) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_iscoreup(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_iscoreup(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) - return ub_iscoreup(sih); - else { - ASSERT(0); - return FALSE; - } -} - -uint -si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val) -{ - /* only for AI back plane chips */ - if (CHIPTYPE(sih->socitype) == SOCI_AI) - return (ai_wrap_reg(sih, offset, mask, val)); - return 0; -} - -uint -si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_corereg(sih, coreidx, regoff, mask, val); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_corereg(sih, coreidx, regoff, mask, val); - else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) - return ub_corereg(sih, coreidx, regoff, mask, val); - else { - ASSERT(0); - return 0; - } -} - -void -si_core_disable(si_t *sih, uint32 bits) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - sb_core_disable(sih, bits); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - ai_core_disable(sih, bits); - else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) - ub_core_disable(sih, bits); -} - -void -si_core_reset(si_t *sih, uint32 bits, uint32 resetbits) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - sb_core_reset(sih, bits, resetbits); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - ai_core_reset(sih, bits, resetbits); - else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) - ub_core_reset(sih, bits, resetbits); -} - -/* Run bist on current core. Caller needs to take care of core-specific bist hazards */ -int -si_corebist(si_t *sih) -{ - uint32 cflags; - int result = 0; - - /* Read core control flags */ - cflags = si_core_cflags(sih, 0, 0); - - /* Set bist & fgc */ - si_core_cflags(sih, ~0, (SICF_BIST_EN | SICF_FGC)); - - /* Wait for bist done */ - SPINWAIT(((si_core_sflags(sih, 0, 0) & SISF_BIST_DONE) == 0), 100000); - - if (si_core_sflags(sih, 0, 0) & SISF_BIST_ERROR) - result = BCME_ERROR; - - /* Reset core control flags */ - si_core_cflags(sih, 0xffff, cflags); - - return result; -} - -static uint32 -factor6(uint32 x) -{ - switch (x) { - case CC_F6_2: return 2; - case CC_F6_3: return 3; - case CC_F6_4: return 4; - case CC_F6_5: return 5; - case CC_F6_6: return 6; - case CC_F6_7: return 7; - default: return 0; - } -} - -/* calculate the speed the SI would run at given a set of clockcontrol values */ -uint32 -si_clock_rate(uint32 pll_type, uint32 n, uint32 m) -{ - uint32 n1, n2, clock, m1, m2, m3, mc; - - n1 = n & CN_N1_MASK; - n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT; - - if (pll_type == PLL_TYPE6) { - if (m & CC_T6_MMASK) - return CC_T6_M1; - else - return CC_T6_M0; - } else if ((pll_type == PLL_TYPE1) || - (pll_type == PLL_TYPE3) || - (pll_type == PLL_TYPE4) || - (pll_type == PLL_TYPE7)) { - n1 = factor6(n1); - n2 += CC_F5_BIAS; - } else if (pll_type == PLL_TYPE2) { - n1 += CC_T2_BIAS; - n2 += CC_T2_BIAS; - ASSERT((n1 >= 2) && (n1 <= 7)); - ASSERT((n2 >= 5) && (n2 <= 23)); - } else if (pll_type == PLL_TYPE5) { - return (100000000); - } else - ASSERT(0); - /* PLL types 3 and 7 use BASE2 (25Mhz) */ - if ((pll_type == PLL_TYPE3) || - (pll_type == PLL_TYPE7)) { - clock = CC_CLOCK_BASE2 * n1 * n2; - } else - clock = CC_CLOCK_BASE1 * n1 * n2; - - if (clock == 0) - return 0; - - m1 = m & CC_M1_MASK; - m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT; - m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT; - mc = (m & CC_MC_MASK) >> CC_MC_SHIFT; - - if ((pll_type == PLL_TYPE1) || - (pll_type == PLL_TYPE3) || - (pll_type == PLL_TYPE4) || - (pll_type == PLL_TYPE7)) { - m1 = factor6(m1); - if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3)) - m2 += CC_F5_BIAS; - else - m2 = factor6(m2); - m3 = factor6(m3); - - switch (mc) { - case CC_MC_BYPASS: return (clock); - case CC_MC_M1: return (clock / m1); - case CC_MC_M1M2: return (clock / (m1 * m2)); - case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3)); - case CC_MC_M1M3: return (clock / (m1 * m3)); - default: return (0); - } - } else { - ASSERT(pll_type == PLL_TYPE2); - - m1 += CC_T2_BIAS; - m2 += CC_T2M2_BIAS; - m3 += CC_T2_BIAS; - ASSERT((m1 >= 2) && (m1 <= 7)); - ASSERT((m2 >= 3) && (m2 <= 10)); - ASSERT((m3 >= 2) && (m3 <= 7)); - - if ((mc & CC_T2MC_M1BYP) == 0) - clock /= m1; - if ((mc & CC_T2MC_M2BYP) == 0) - clock /= m2; - if ((mc & CC_T2MC_M3BYP) == 0) - clock /= m3; - - return (clock); - } -} - - -/* set chip watchdog reset timer to fire in 'ticks' */ -void -si_watchdog(si_t *sih, uint ticks) -{ - uint nb, maxt; - - if (PMUCTL_ENAB(sih)) { - - if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) && - (CHIPREV(sih->chiprev) == 0) && (ticks != 0)) { - si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), ~0, 0x2); - si_setcore(sih, USB20D_CORE_ID, 0); - si_core_disable(sih, 1); - si_setcore(sih, CC_CORE_ID, 0); - } - - nb = (sih->ccrev < 26) ? 16 : ((sih->ccrev >= 37) ? 32 : 24); - /* The mips compiler uses the sllv instruction, - * so we specially handle the 32-bit case. - */ - if (nb == 32) - maxt = 0xffffffff; - else - maxt = ((1 << nb) - 1); - - if (ticks == 1) - ticks = 2; - else if (ticks > maxt) - ticks = maxt; - - si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pmuwatchdog), ~0, ticks); - } else { - maxt = (1 << 28) - 1; - if (ticks > maxt) - ticks = maxt; - - si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0, ticks); - } -} - -/* trigger watchdog reset after ms milliseconds */ -void -si_watchdog_ms(si_t *sih, uint32 ms) -{ - si_watchdog(sih, wd_msticks * ms); -} - - - - -/* return the slow clock source - LPO, XTAL, or PCI */ -static uint -si_slowclk_src(si_info_t *sii) -{ - chipcregs_t *cc; - - ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID); - - if (sii->pub.ccrev < 6) { - if ((BUSTYPE(sii->pub.bustype) == PCI_BUS) && - (OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32)) & - PCI_CFG_GPIO_SCS)) - return (SCC_SS_PCI); - else - return (SCC_SS_XTAL); - } else if (sii->pub.ccrev < 10) { - cc = (chipcregs_t *)si_setcoreidx(&sii->pub, sii->curidx); - return (R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK); - } else /* Insta-clock */ - return (SCC_SS_XTAL); -} - -/* return the ILP (slowclock) min or max frequency */ -static uint -si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc) -{ - uint32 slowclk; - uint div; - - ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID); - - /* shouldn't be here unless we've established the chip has dynamic clk control */ - ASSERT(R_REG(sii->osh, &cc->capabilities) & CC_CAP_PWR_CTL); - - slowclk = si_slowclk_src(sii); - if (sii->pub.ccrev < 6) { - if (slowclk == SCC_SS_PCI) - return (max_freq ? (PCIMAXFREQ / 64) : (PCIMINFREQ / 64)); - else - return (max_freq ? (XTALMAXFREQ / 32) : (XTALMINFREQ / 32)); - } else if (sii->pub.ccrev < 10) { - div = 4 * - (((R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); - if (slowclk == SCC_SS_LPO) - return (max_freq ? LPOMAXFREQ : LPOMINFREQ); - else if (slowclk == SCC_SS_XTAL) - return (max_freq ? (XTALMAXFREQ / div) : (XTALMINFREQ / div)); - else if (slowclk == SCC_SS_PCI) - return (max_freq ? (PCIMAXFREQ / div) : (PCIMINFREQ / div)); - else - ASSERT(0); - } else { - /* Chipc rev 10 is InstaClock */ - div = R_REG(sii->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT; - div = 4 * (div + 1); - return (max_freq ? XTALMAXFREQ : (XTALMINFREQ / div)); - } - return (0); -} - -static void -si_clkctl_setdelay(si_info_t *sii, void *chipcregs) -{ - chipcregs_t *cc = (chipcregs_t *)chipcregs; - uint slowmaxfreq, pll_delay, slowclk; - uint pll_on_delay, fref_sel_delay; - - pll_delay = PLL_DELAY; - - /* If the slow clock is not sourced by the xtal then add the xtal_on_delay - * since the xtal will also be powered down by dynamic clk control logic. - */ - - slowclk = si_slowclk_src(sii); - if (slowclk != SCC_SS_XTAL) - pll_delay += XTAL_ON_DELAY; - - /* Starting with 4318 it is ILP that is used for the delays */ - slowmaxfreq = si_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? FALSE : TRUE, cc); - - pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; - fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; - - W_REG(sii->osh, &cc->pll_on_delay, pll_on_delay); - W_REG(sii->osh, &cc->fref_sel_delay, fref_sel_delay); -} - -/* initialize power control delay registers */ -void -si_clkctl_init(si_t *sih) -{ - si_info_t *sii; - uint origidx = 0; - chipcregs_t *cc; - bool fast; - - if (!CCCTL_ENAB(sih)) - return; - - sii = SI_INFO(sih); - fast = SI_FAST(sii); - if (!fast) { - origidx = sii->curidx; - if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) - return; - } else if ((cc = (chipcregs_t *)CCREGS_FAST(sii)) == NULL) - return; - ASSERT(cc != NULL); - - /* set all Instaclk chip ILP to 1 MHz */ - if (sih->ccrev >= 10) - SET_REG(sii->osh, &cc->system_clk_ctl, SYCC_CD_MASK, - (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); - - si_clkctl_setdelay(sii, (void *)(uintptr)cc); - - if (!fast) - si_setcoreidx(sih, origidx); -} - -/* change logical "focus" to the gpio core for optimized access */ -void * -si_gpiosetcore(si_t *sih) -{ - return (si_setcoreidx(sih, SI_CC_IDX)); -} - -/* mask&set gpiocontrol bits */ -uint32 -si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority) -{ - uint regoff; - - regoff = 0; - - /* gpios could be shared on router platforms - * ignore reservation if it's high priority (e.g., test apps) - */ - if ((priority != GPIO_HI_PRIORITY) && - (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { - mask = priority ? (si_gpioreservation & mask) : - ((si_gpioreservation | mask) & ~(si_gpioreservation)); - val &= mask; - } - - regoff = OFFSETOF(chipcregs_t, gpiocontrol); - return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -} - -/* mask&set gpio output enable bits */ -uint32 -si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority) -{ - uint regoff; - - regoff = 0; - - /* gpios could be shared on router platforms - * ignore reservation if it's high priority (e.g., test apps) - */ - if ((priority != GPIO_HI_PRIORITY) && - (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { - mask = priority ? (si_gpioreservation & mask) : - ((si_gpioreservation | mask) & ~(si_gpioreservation)); - val &= mask; - } - - regoff = OFFSETOF(chipcregs_t, gpioouten); - return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -} - -/* mask&set gpio output bits */ -uint32 -si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority) -{ - uint regoff; - - regoff = 0; - - /* gpios could be shared on router platforms - * ignore reservation if it's high priority (e.g., test apps) - */ - if ((priority != GPIO_HI_PRIORITY) && - (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { - mask = priority ? (si_gpioreservation & mask) : - ((si_gpioreservation | mask) & ~(si_gpioreservation)); - val &= mask; - } - - regoff = OFFSETOF(chipcregs_t, gpioout); - return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -} - -/* reserve one gpio */ -uint32 -si_gpioreserve(si_t *sih, uint32 gpio_bitmask, uint8 priority) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - /* only cores on SI_BUS share GPIO's and only applcation users need to - * reserve/release GPIO - */ - if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) { - ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority)); - return 0xffffffff; - } - /* make sure only one bit is set */ - if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { - ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); - return 0xffffffff; - } - - /* already reserved */ - if (si_gpioreservation & gpio_bitmask) - return 0xffffffff; - /* set reservation */ - si_gpioreservation |= gpio_bitmask; - - return si_gpioreservation; -} - -/* release one gpio */ -/* - * releasing the gpio doesn't change the current value on the GPIO last write value - * persists till some one overwrites it - */ - -uint32 -si_gpiorelease(si_t *sih, uint32 gpio_bitmask, uint8 priority) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - /* only cores on SI_BUS share GPIO's and only applcation users need to - * reserve/release GPIO - */ - if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) { - ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority)); - return 0xffffffff; - } - /* make sure only one bit is set */ - if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { - ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); - return 0xffffffff; - } - - /* already released */ - if (!(si_gpioreservation & gpio_bitmask)) - return 0xffffffff; - - /* clear reservation */ - si_gpioreservation &= ~gpio_bitmask; - - return si_gpioreservation; -} - -/* return the current gpioin register value */ -uint32 -si_gpioin(si_t *sih) -{ - si_info_t *sii; - uint regoff; - - sii = SI_INFO(sih); - regoff = 0; - - regoff = OFFSETOF(chipcregs_t, gpioin); - return (si_corereg(sih, SI_CC_IDX, regoff, 0, 0)); -} - -/* mask&set gpio interrupt polarity bits */ -uint32 -si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority) -{ - si_info_t *sii; - uint regoff; - - sii = SI_INFO(sih); - regoff = 0; - - /* gpios could be shared on router platforms */ - if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { - mask = priority ? (si_gpioreservation & mask) : - ((si_gpioreservation | mask) & ~(si_gpioreservation)); - val &= mask; - } - - regoff = OFFSETOF(chipcregs_t, gpiointpolarity); - return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -} - -/* mask&set gpio interrupt mask bits */ -uint32 -si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority) -{ - si_info_t *sii; - uint regoff; - - sii = SI_INFO(sih); - regoff = 0; - - /* gpios could be shared on router platforms */ - if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { - mask = priority ? (si_gpioreservation & mask) : - ((si_gpioreservation | mask) & ~(si_gpioreservation)); - val &= mask; - } - - regoff = OFFSETOF(chipcregs_t, gpiointmask); - return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -} - -/* assign the gpio to an led */ -uint32 -si_gpioled(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - if (sih->ccrev < 16) - return 0xffffffff; - - /* gpio led powersave reg */ - return (si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val)); -} - -/* mask&set gpio timer val */ -uint32 -si_gpiotimerval(si_t *sih, uint32 mask, uint32 gpiotimerval) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - if (sih->ccrev < 16) - return 0xffffffff; - - return (si_corereg(sih, SI_CC_IDX, - OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval)); -} - -uint32 -si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val) -{ - si_info_t *sii; - uint offs; - - sii = SI_INFO(sih); - if (sih->ccrev < 20) - return 0xffffffff; - - offs = (updown ? OFFSETOF(chipcregs_t, gpiopulldown) : OFFSETOF(chipcregs_t, gpiopullup)); - return (si_corereg(sih, SI_CC_IDX, offs, mask, val)); -} - -uint32 -si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val) -{ - si_info_t *sii; - uint offs; - - sii = SI_INFO(sih); - if (sih->ccrev < 11) - return 0xffffffff; - - if (regtype == GPIO_REGEVT) - offs = OFFSETOF(chipcregs_t, gpioevent); - else if (regtype == GPIO_REGEVT_INTMSK) - offs = OFFSETOF(chipcregs_t, gpioeventintmask); - else if (regtype == GPIO_REGEVT_INTPOL) - offs = OFFSETOF(chipcregs_t, gpioeventintpolarity); - else - return 0xffffffff; - - return (si_corereg(sih, SI_CC_IDX, offs, mask, val)); -} - -void * -si_gpio_handler_register(si_t *sih, uint32 event, - bool level, gpio_handler_t cb, void *arg) -{ - si_info_t *sii; - gpioh_item_t *gi; - - ASSERT(event); - ASSERT(cb != NULL); - - sii = SI_INFO(sih); - if (sih->ccrev < 11) - return NULL; - - if ((gi = MALLOC(sii->osh, sizeof(gpioh_item_t))) == NULL) - return NULL; - - bzero(gi, sizeof(gpioh_item_t)); - gi->event = event; - gi->handler = cb; - gi->arg = arg; - gi->level = level; - - gi->next = sii->gpioh_head; - sii->gpioh_head = gi; - - return (void *)(gi); -} - -void -si_gpio_handler_unregister(si_t *sih, void *gpioh) -{ - si_info_t *sii; - gpioh_item_t *p, *n; - - sii = SI_INFO(sih); - if (sih->ccrev < 11) - return; - - ASSERT(sii->gpioh_head != NULL); - if ((void*)sii->gpioh_head == gpioh) { - sii->gpioh_head = sii->gpioh_head->next; - MFREE(sii->osh, gpioh, sizeof(gpioh_item_t)); - return; - } else { - p = sii->gpioh_head; - n = p->next; - while (n) { - if ((void*)n == gpioh) { - p->next = n->next; - MFREE(sii->osh, gpioh, sizeof(gpioh_item_t)); - return; - } - p = n; - n = n->next; - } - } - - ASSERT(0); /* Not found in list */ -} - -void -si_gpio_handler_process(si_t *sih) -{ - si_info_t *sii; - gpioh_item_t *h; - uint32 level = si_gpioin(sih); - uint32 levelp = si_gpiointpolarity(sih, 0, 0, 0); - uint32 edge = si_gpioevent(sih, GPIO_REGEVT, 0, 0); - uint32 edgep = si_gpioevent(sih, GPIO_REGEVT_INTPOL, 0, 0); - - sii = SI_INFO(sih); - for (h = sii->gpioh_head; h != NULL; h = h->next) { - if (h->handler) { - uint32 status = (h->level ? level : edge) & h->event; - uint32 polarity = (h->level ? levelp : edgep) & h->event; - - /* polarity bitval is opposite of status bitval */ - if (status ^ polarity) - h->handler(status, h->arg); - } - } - - si_gpioevent(sih, GPIO_REGEVT, edge, edge); /* clear edge-trigger status */ -} - -uint32 -si_gpio_int_enable(si_t *sih, bool enable) -{ - si_info_t *sii; - uint offs; - - sii = SI_INFO(sih); - if (sih->ccrev < 11) - return 0xffffffff; - - offs = OFFSETOF(chipcregs_t, intmask); - return (si_corereg(sih, SI_CC_IDX, offs, CI_GPIO, (enable ? CI_GPIO : 0))); -} - - -/* Return the size of the specified SOCRAM bank */ -static uint -socram_banksize(si_info_t *sii, sbsocramregs_t *regs, uint8 index, uint8 mem_type) -{ - uint banksize, bankinfo; - uint bankidx = index | (mem_type << SOCRAM_BANKIDX_MEMTYPE_SHIFT); - - ASSERT(mem_type <= SOCRAM_MEMTYPE_DEVRAM); - - W_REG(sii->osh, ®s->bankidx, bankidx); - bankinfo = R_REG(sii->osh, ®s->bankinfo); - banksize = SOCRAM_BANKINFO_SZBASE * ((bankinfo & SOCRAM_BANKINFO_SZMASK) + 1); - return banksize; -} - -void -si_socdevram(si_t *sih, bool set, uint8 *enable, uint8 *protect) -{ - si_info_t *sii; - uint origidx; - uint intr_val = 0; - sbsocramregs_t *regs; - bool wasup; - uint corerev; - - sii = SI_INFO(sih); - - /* Block ints and save current core */ - INTR_OFF(sii, intr_val); - origidx = si_coreidx(sih); - - if (!set) - *enable = *protect = 0; - - /* Switch to SOCRAM core */ - if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) - goto done; - - /* Get info for determining size */ - if (!(wasup = si_iscoreup(sih))) - si_core_reset(sih, 0, 0); - - corerev = si_corerev(sih); - if (corerev >= 10) { - uint32 extcinfo; - uint8 nb; - uint8 i; - uint32 bankidx, bankinfo; - - extcinfo = R_REG(sii->osh, ®s->extracoreinfo); - nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT); - for (i = 0; i < nb; i++) { - bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT); - W_REG(sii->osh, ®s->bankidx, bankidx); - bankinfo = R_REG(sii->osh, ®s->bankinfo); - if (set) { - bankinfo &= ~SOCRAM_BANKINFO_DEVRAMSEL_MASK; - bankinfo &= ~SOCRAM_BANKINFO_DEVRAMPRO_MASK; - if (*enable) { - bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMSEL_SHIFT); - if (*protect) - bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMPRO_SHIFT); - } - W_REG(sii->osh, ®s->bankinfo, bankinfo); - } - else if (i == 0) { - if (bankinfo & SOCRAM_BANKINFO_DEVRAMSEL_MASK) { - *enable = 1; - if (bankinfo & SOCRAM_BANKINFO_DEVRAMPRO_MASK) - *protect = 1; - } - } - } - } - - /* Return to previous state and core */ - if (!wasup) - si_core_disable(sih, 0); - si_setcoreidx(sih, origidx); - -done: - INTR_RESTORE(sii, intr_val); -} - -bool -si_socdevram_pkg(si_t *sih) -{ - if (si_socdevram_size(sih) > 0) - return TRUE; - else - return FALSE; -} - -uint32 -si_socdevram_size(si_t *sih) -{ - si_info_t *sii; - uint origidx; - uint intr_val = 0; - uint32 memsize = 0; - sbsocramregs_t *regs; - bool wasup; - uint corerev; - - sii = SI_INFO(sih); - - /* Block ints and save current core */ - INTR_OFF(sii, intr_val); - origidx = si_coreidx(sih); - - /* Switch to SOCRAM core */ - if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) - goto done; - - /* Get info for determining size */ - if (!(wasup = si_iscoreup(sih))) - si_core_reset(sih, 0, 0); - - corerev = si_corerev(sih); - if (corerev >= 10) { - uint32 extcinfo; - uint8 nb; - uint8 i; - - extcinfo = R_REG(sii->osh, ®s->extracoreinfo); - nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT)); - for (i = 0; i < nb; i++) - memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_DEVRAM); - } - - /* Return to previous state and core */ - if (!wasup) - si_core_disable(sih, 0); - si_setcoreidx(sih, origidx); - -done: - INTR_RESTORE(sii, intr_val); - - return memsize; -} - -/* Return the RAM size of the SOCRAM core */ -uint32 -si_socram_size(si_t *sih) -{ - si_info_t *sii; - uint origidx; - uint intr_val = 0; - - sbsocramregs_t *regs; - bool wasup; - uint corerev; - uint32 coreinfo; - uint memsize = 0; - - sii = SI_INFO(sih); - - /* Block ints and save current core */ - INTR_OFF(sii, intr_val); - origidx = si_coreidx(sih); - - /* Switch to SOCRAM core */ - if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) - goto done; - - /* Get info for determining size */ - if (!(wasup = si_iscoreup(sih))) - si_core_reset(sih, 0, 0); - corerev = si_corerev(sih); - coreinfo = R_REG(sii->osh, ®s->coreinfo); - - /* Calculate size from coreinfo based on rev */ - if (corerev == 0) - memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK)); - else if (corerev < 3) { - memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK)); - memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; - } else if ((corerev <= 7) || (corerev == 12)) { - uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; - uint bsz = (coreinfo & SRCI_SRBSZ_MASK); - uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT; - if (lss != 0) - nb --; - memsize = nb * (1 << (bsz + SR_BSZ_BASE)); - if (lss != 0) - memsize += (1 << ((lss - 1) + SR_BSZ_BASE)); - } else { - uint8 i; - uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; - for (i = 0; i < nb; i++) - memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM); - } - - /* Return to previous state and core */ - if (!wasup) - si_core_disable(sih, 0); - si_setcoreidx(sih, origidx); - -done: - INTR_RESTORE(sii, intr_val); - - return memsize; -} - - -void -si_btcgpiowar(si_t *sih) -{ - si_info_t *sii; - uint origidx; - uint intr_val = 0; - chipcregs_t *cc; - - sii = SI_INFO(sih); - - /* Make sure that there is ChipCommon core present && - * UART_TX is strapped to 1 - */ - if (!(sih->cccaps & CC_CAP_UARTGPIO)) - return; - - /* si_corereg cannot be used as we have to guarantee 8-bit read/writes */ - INTR_OFF(sii, intr_val); - - origidx = si_coreidx(sih); - - cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); - ASSERT(cc != NULL); - - W_REG(sii->osh, &cc->uart0mcr, R_REG(sii->osh, &cc->uart0mcr) | 0x04); - - /* restore the original index */ - si_setcoreidx(sih, origidx); - - INTR_RESTORE(sii, intr_val); -} - -uint -si_pll_reset(si_t *sih) -{ - uint err = 0; - - return (err); -} - -/* check if the device is removed */ -bool -si_deviceremoved(si_t *sih) -{ - uint32 w; - si_info_t *sii; - - sii = SI_INFO(sih); - - switch (BUSTYPE(sih->bustype)) { - case PCI_BUS: - ASSERT(sii->osh != NULL); - w = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_VID, sizeof(uint32)); - if ((w & 0xFFFF) != VENDOR_BROADCOM) - return TRUE; - break; - } - return FALSE; -} - -bool -si_is_sprom_available(si_t *sih) -{ - if (sih->ccrev >= 31) { - si_info_t *sii; - uint origidx; - chipcregs_t *cc; - uint32 sromctrl; - - if ((sih->cccaps & CC_CAP_SROM) == 0) - return FALSE; - - sii = SI_INFO(sih); - origidx = sii->curidx; - cc = si_setcoreidx(sih, SI_CC_IDX); - sromctrl = R_REG(sii->osh, &cc->sromcontrol); - si_setcoreidx(sih, origidx); - return (sromctrl & SRC_PRESENT); - } - - switch (CHIPID(sih->chip)) { - case BCM4312_CHIP_ID: - return ((sih->chipst & CST4312_SPROM_OTP_SEL_MASK) != CST4312_OTP_SEL); - case BCM4325_CHIP_ID: - return (sih->chipst & CST4325_SPROM_SEL) != 0; - case BCM4322_CHIP_ID: - case BCM43221_CHIP_ID: - case BCM43231_CHIP_ID: - case BCM43222_CHIP_ID: - case BCM43111_CHIP_ID: - case BCM43112_CHIP_ID: - case BCM4342_CHIP_ID: - { - uint32 spromotp; - spromotp = (sih->chipst & CST4322_SPROM_OTP_SEL_MASK) >> - CST4322_SPROM_OTP_SEL_SHIFT; - return (spromotp & CST4322_SPROM_PRESENT) != 0; - } - case BCM4329_CHIP_ID: - return (sih->chipst & CST4329_SPROM_SEL) != 0; - case BCM4315_CHIP_ID: - return (sih->chipst & CST4315_SPROM_SEL) != 0; - case BCM4319_CHIP_ID: - return (sih->chipst & CST4319_SPROM_SEL) != 0; - - case BCM4336_CHIP_ID: - case BCM43362_CHIP_ID: - return (sih->chipst & CST4336_SPROM_PRESENT) != 0; - - case BCM4330_CHIP_ID: - return (sih->chipst & CST4330_SPROM_PRESENT) != 0; - case BCM4313_CHIP_ID: - return (sih->chipst & CST4313_SPROM_PRESENT) != 0; - case BCM43239_CHIP_ID: - return ((sih->chipst & CST43239_SPROM_MASK) && - !(sih->chipst & CST43239_SFLASH_MASK)); - default: - return TRUE; - } -} diff --git a/drivers/net/wireless/bcmdhd/siutils_priv.h b/drivers/net/wireless/bcmdhd/siutils_priv.h deleted file mode 100644 index d80246e01d1b..000000000000 --- a/drivers/net/wireless/bcmdhd/siutils_priv.h +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Include file private to the SOC Interconnect support files. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: siutils_priv.h,v 1.17.4.3 2010-10-25 16:56:56 Exp $ - */ - -#ifndef _siutils_priv_h_ -#define _siutils_priv_h_ - -#define SI_ERROR(args) - -#define SI_MSG(args) - -/* Define SI_VMSG to printf for verbose debugging, but don't check it in */ -#define SI_VMSG(args) - -#define IS_SIM(chippkg) ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID)) - -typedef uint32 (*si_intrsoff_t)(void *intr_arg); -typedef void (*si_intrsrestore_t)(void *intr_arg, uint32 arg); -typedef bool (*si_intrsenabled_t)(void *intr_arg); - -typedef struct gpioh_item { - void *arg; - bool level; - gpio_handler_t handler; - uint32 event; - struct gpioh_item *next; -} gpioh_item_t; - -/* misc si info needed by some of the routines */ -typedef struct si_info { - struct si_pub pub; /* back plane public state (must be first field) */ - - void *osh; /* osl os handle */ - void *sdh; /* bcmsdh handle */ - - uint dev_coreid; /* the core provides driver functions */ - void *intr_arg; /* interrupt callback function arg */ - si_intrsoff_t intrsoff_fn; /* turns chip interrupts off */ - si_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */ - si_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */ - - void *pch; /* PCI/E core handle */ - - gpioh_item_t *gpioh_head; /* GPIO event handlers list */ - - bool memseg; /* flag to toggle MEM_SEG register */ - - char *vars; - uint varsz; - - void *curmap; /* current regs va */ - void *regs[SI_MAXCORES]; /* other regs va */ - - uint curidx; /* current core index */ - uint numcores; /* # discovered cores */ - uint coreid[SI_MAXCORES]; /* id of each core */ - uint32 coresba[SI_MAXCORES]; /* backplane address of each core */ - void *regs2[SI_MAXCORES]; /* va of each core second register set (usbh20) */ - uint32 coresba2[SI_MAXCORES]; /* address of each core second register set (usbh20) */ - uint32 coresba_size[SI_MAXCORES]; /* backplane address space size */ - uint32 coresba2_size[SI_MAXCORES]; /* second address space size */ - - void *curwrap; /* current wrapper va */ - void *wrappers[SI_MAXCORES]; /* other cores wrapper va */ - uint32 wrapba[SI_MAXCORES]; /* address of controlling wrapper */ - - uint32 cia[SI_MAXCORES]; /* erom cia entry for each core */ - uint32 cib[SI_MAXCORES]; /* erom cia entry for each core */ - uint32 oob_router; /* oob router registers for axi */ -} si_info_t; - -#define SI_INFO(sih) (si_info_t *)(uintptr)sih - -#define GOODCOREADDR(x, b) (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ - ISALIGNED((x), SI_CORE_SIZE)) -#define GOODREGS(regs) ((regs) != NULL && ISALIGNED((uintptr)(regs), SI_CORE_SIZE)) -#define BADCOREADDR 0 -#define GOODIDX(idx) (((uint)idx) < SI_MAXCORES) -#define NOREV -1 /* Invalid rev */ - -#define PCI(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ - ((si)->pub.buscoretype == PCI_CORE_ID)) -#define PCIE(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ - ((si)->pub.buscoretype == PCIE_CORE_ID)) -#define PCMCIA(si) ((BUSTYPE((si)->pub.bustype) == PCMCIA_BUS) && ((si)->memseg == TRUE)) - -/* Newer chips can access PCI/PCIE and CC core without requiring to change - * PCI BAR0 WIN - */ -#define SI_FAST(si) (((si)->pub.buscoretype == PCIE_CORE_ID) || \ - (((si)->pub.buscoretype == PCI_CORE_ID) && (si)->pub.buscorerev >= 13)) - -#define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET)) -#define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET)) - -/* - * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/ - * after core switching to avoid invalid register accesss inside ISR. - */ -#define INTR_OFF(si, intr_val) \ - if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ - intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); } -#define INTR_RESTORE(si, intr_val) \ - if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ - (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } - -/* dynamic clock control defines */ -#define LPOMINFREQ 25000 /* low power oscillator min */ -#define LPOMAXFREQ 43000 /* low power oscillator max */ -#define XTALMINFREQ 19800000 /* 20 MHz - 1% */ -#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */ -#define PCIMINFREQ 25000000 /* 25 MHz */ -#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */ - -#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ -#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ - -#define PCI_FORCEHT(si) \ - (((PCIE(si)) && (si->pub.chip == BCM4311_CHIP_ID) && ((si->pub.chiprev <= 1))) || \ - ((PCI(si) || PCIE(si)) && (si->pub.chip == BCM4321_CHIP_ID)) || \ - (PCIE(si) && (si->pub.chip == BCM4716_CHIP_ID))) - -/* GPIO Based LED powersave defines */ -#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */ -#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */ - -#ifndef DEFAULT_GPIOTIMERVAL -#define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) -#endif - -/* Silicon Backplane externs */ -extern void sb_scan(si_t *sih, void *regs, uint devid); -extern uint sb_coreid(si_t *sih); -extern uint sb_intflag(si_t *sih); -extern uint sb_flag(si_t *sih); -extern void sb_setint(si_t *sih, int siflag); -extern uint sb_corevendor(si_t *sih); -extern uint sb_corerev(si_t *sih); -extern uint sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); -extern bool sb_iscoreup(si_t *sih); -extern void *sb_setcoreidx(si_t *sih, uint coreidx); -extern uint32 sb_core_cflags(si_t *sih, uint32 mask, uint32 val); -extern void sb_core_cflags_wo(si_t *sih, uint32 mask, uint32 val); -extern uint32 sb_core_sflags(si_t *sih, uint32 mask, uint32 val); -extern void sb_commit(si_t *sih); -extern uint32 sb_base(uint32 admatch); -extern uint32 sb_size(uint32 admatch); -extern void sb_core_reset(si_t *sih, uint32 bits, uint32 resetbits); -extern void sb_core_disable(si_t *sih, uint32 bits); -extern uint32 sb_addrspace(si_t *sih, uint asidx); -extern uint32 sb_addrspacesize(si_t *sih, uint asidx); -extern int sb_numaddrspaces(si_t *sih); - -extern uint32 sb_set_initiator_to(si_t *sih, uint32 to, uint idx); - -extern bool sb_taclear(si_t *sih, bool details); - - -/* Wake-on-wireless-LAN (WOWL) */ -extern bool sb_pci_pmecap(si_t *sih); -struct osl_info; -extern bool sb_pci_fastpmecap(struct osl_info *osh); -extern bool sb_pci_pmeclr(si_t *sih); -extern void sb_pci_pmeen(si_t *sih); -extern uint sb_pcie_readreg(void *sih, uint addrtype, uint offset); - -/* AMBA Interconnect exported externs */ -extern si_t *ai_attach(uint pcidev, osl_t *osh, void *regs, uint bustype, - void *sdh, char **vars, uint *varsz); -extern si_t *ai_kattach(osl_t *osh); -extern void ai_scan(si_t *sih, void *regs, uint devid); - -extern uint ai_flag(si_t *sih); -extern void ai_setint(si_t *sih, int siflag); -extern uint ai_coreidx(si_t *sih); -extern uint ai_corevendor(si_t *sih); -extern uint ai_corerev(si_t *sih); -extern bool ai_iscoreup(si_t *sih); -extern void *ai_setcoreidx(si_t *sih, uint coreidx); -extern uint32 ai_core_cflags(si_t *sih, uint32 mask, uint32 val); -extern void ai_core_cflags_wo(si_t *sih, uint32 mask, uint32 val); -extern uint32 ai_core_sflags(si_t *sih, uint32 mask, uint32 val); -extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); -extern void ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits); -extern void ai_core_disable(si_t *sih, uint32 bits); -extern int ai_numaddrspaces(si_t *sih); -extern uint32 ai_addrspace(si_t *sih, uint asidx); -extern uint32 ai_addrspacesize(si_t *sih, uint asidx); -extern uint ai_wrap_reg(si_t *sih, uint32 offset, uint32 mask, uint32 val); - - - -#define ub_scan(a, b, c) do {} while (0) -#define ub_flag(a) (0) -#define ub_setint(a, b) do {} while (0) -#define ub_coreidx(a) (0) -#define ub_corevendor(a) (0) -#define ub_corerev(a) (0) -#define ub_iscoreup(a) (0) -#define ub_setcoreidx(a, b) (0) -#define ub_core_cflags(a, b, c) (0) -#define ub_core_cflags_wo(a, b, c) do {} while (0) -#define ub_core_sflags(a, b, c) (0) -#define ub_corereg(a, b, c, d, e) (0) -#define ub_core_reset(a, b, c) do {} while (0) -#define ub_core_disable(a, b) do {} while (0) -#define ub_numaddrspaces(a) (0) -#define ub_addrspace(a, b) (0) -#define ub_addrspacesize(a, b) (0) -#define ub_view(a, b) do {} while (0) -#define ub_dumpregs(a, b) do {} while (0) - -#endif /* _siutils_priv_h_ */ diff --git a/drivers/net/wireless/bcmdhd/uamp_api.h b/drivers/net/wireless/bcmdhd/uamp_api.h deleted file mode 100644 index c51c68cd0eed..000000000000 --- a/drivers/net/wireless/bcmdhd/uamp_api.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Name: uamp_api.h - * - * Description: Universal AMP API - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: uamp_api.h,v 1.2.8.1 2011-02-05 00:16:14 Exp $ - * - */ -#ifndef UAMP_API_H -#define UAMP_API_H - - -#include "typedefs.h" - - -/***************************************************************************** -** Constant and Type Definitions -****************************************************************************** -*/ - -#define BT_API - -/* Types. */ -typedef bool BOOLEAN; -typedef uint8 UINT8; -typedef uint16 UINT16; - - -/* UAMP identifiers */ -#define UAMP_ID_1 1 -#define UAMP_ID_2 2 -typedef UINT8 tUAMP_ID; - -/* UAMP event ids (used by UAMP_CBACK) */ -#define UAMP_EVT_RX_READY 0 /* Data from AMP controller is ready to be read */ -#define UAMP_EVT_CTLR_REMOVED 1 /* Controller removed */ -#define UAMP_EVT_CTLR_READY 2 /* Controller added/ready */ -typedef UINT8 tUAMP_EVT; - - -/* UAMP Channels */ -#define UAMP_CH_HCI_CMD 0 /* HCI Command channel */ -#define UAMP_CH_HCI_EVT 1 /* HCI Event channel */ -#define UAMP_CH_HCI_DATA 2 /* HCI ACL Data channel */ -typedef UINT8 tUAMP_CH; - -/* tUAMP_EVT_DATA: union for event-specific data, used by UAMP_CBACK */ -typedef union { - tUAMP_CH channel; /* UAMP_EVT_RX_READY: channel for which rx occured */ -} tUAMP_EVT_DATA; - - -/***************************************************************************** -** -** Function: UAMP_CBACK -** -** Description: Callback for events. Register callback using UAMP_Init. -** -** Parameters amp_id: AMP device identifier that generated the event -** amp_evt: event id -** p_amp_evt_data: pointer to event-specific data -** -****************************************************************************** -*/ -typedef void (*tUAMP_CBACK)(tUAMP_ID amp_id, tUAMP_EVT amp_evt, tUAMP_EVT_DATA *p_amp_evt_data); - -/***************************************************************************** -** external function declarations -****************************************************************************** -*/ -#ifdef __cplusplus -extern "C" -{ -#endif - -/***************************************************************************** -** -** Function: UAMP_Init -** -** Description: Initialize UAMP driver -** -** Parameters p_cback: Callback function for UAMP event notification -** -****************************************************************************** -*/ -BT_API BOOLEAN UAMP_Init(tUAMP_CBACK p_cback); - - -/***************************************************************************** -** -** Function: UAMP_Open -** -** Description: Open connection to local AMP device. -** -** Parameters app_id: Application specific AMP identifer. This value -** will be included in AMP messages sent to the -** BTU task, to identify source of the message -** -****************************************************************************** -*/ -BT_API BOOLEAN UAMP_Open(tUAMP_ID amp_id); - -/***************************************************************************** -** -** Function: UAMP_Close -** -** Description: Close connection to local AMP device. -** -** Parameters app_id: Application specific AMP identifer. -** -****************************************************************************** -*/ -BT_API void UAMP_Close(tUAMP_ID amp_id); - - -/***************************************************************************** -** -** Function: UAMP_Write -** -** Description: Send buffer to AMP device. Frees GKI buffer when done. -** -** -** Parameters: app_id: AMP identifer. -** p_buf: pointer to buffer to write -** num_bytes: number of bytes to write -** channel: UAMP_CH_HCI_ACL, or UAMP_CH_HCI_CMD -** -** Returns: number of bytes written -** -****************************************************************************** -*/ -BT_API UINT16 UAMP_Write(tUAMP_ID amp_id, UINT8 *p_buf, UINT16 num_bytes, tUAMP_CH channel); - -/***************************************************************************** -** -** Function: UAMP_Read -** -** Description: Read incoming data from AMP. Call after receiving a -** UAMP_EVT_RX_READY callback event. -** -** Parameters: app_id: AMP identifer. -** p_buf: pointer to buffer for holding incoming AMP data -** buf_size: size of p_buf -** channel: UAMP_CH_HCI_ACL, or UAMP_CH_HCI_EVT -** -** Returns: number of bytes read -** -****************************************************************************** -*/ -BT_API UINT16 UAMP_Read(tUAMP_ID amp_id, UINT8 *p_buf, UINT16 buf_size, tUAMP_CH channel); - -#ifdef __cplusplus -} -#endif - -#endif /* UAMP_API_H */ diff --git a/drivers/net/wireless/bcmdhd/wl_android.c b/drivers/net/wireless/bcmdhd/wl_android.c deleted file mode 100644 index ce74f0f94619..000000000000 --- a/drivers/net/wireless/bcmdhd/wl_android.c +++ /dev/null @@ -1,858 +0,0 @@ -/* - * Linux cfg80211 driver - Android related functions - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wl_android.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $ - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef WL_CFG80211 -#include -#endif -#if defined(CONFIG_WIFI_CONTROL_FUNC) -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) -#include -#else -#include -#endif -#endif /* CONFIG_WIFI_CONTROL_FUNC */ - -/* - * Android private command strings, PLEASE define new private commands here - * so they can be updated easily in the future (if needed) - */ - -#define CMD_START "START" -#define CMD_STOP "STOP" -#define CMD_SCAN_ACTIVE "SCAN-ACTIVE" -#define CMD_SCAN_PASSIVE "SCAN-PASSIVE" -#define CMD_RSSI "RSSI" -#define CMD_LINKSPEED "LINKSPEED" -#define CMD_RXFILTER_START "RXFILTER-START" -#define CMD_RXFILTER_STOP "RXFILTER-STOP" -#define CMD_RXFILTER_ADD "RXFILTER-ADD" -#define CMD_RXFILTER_REMOVE "RXFILTER-REMOVE" -#define CMD_BTCOEXSCAN_START "BTCOEXSCAN-START" -#define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP" -#define CMD_BTCOEXMODE "BTCOEXMODE" -#define CMD_SETSUSPENDOPT "SETSUSPENDOPT" -#define CMD_SETSUSPENDMODE "SETSUSPENDMODE" -#define CMD_P2P_DEV_ADDR "P2P_DEV_ADDR" -#define CMD_SETFWPATH "SETFWPATH" -#define CMD_SETBAND "SETBAND" -#define CMD_GETBAND "GETBAND" -#define CMD_COUNTRY "COUNTRY" -#define CMD_P2P_SET_NOA "P2P_SET_NOA" -#if !defined WL_ENABLE_P2P_IF -#define CMD_P2P_GET_NOA "P2P_GET_NOA" -#endif -#define CMD_P2P_SET_PS "P2P_SET_PS" -#define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE" - - -#ifdef PNO_SUPPORT -#define CMD_PNOSSIDCLR_SET "PNOSSIDCLR" -#define CMD_PNOSETUP_SET "PNOSETUP " -#define CMD_PNOENABLE_SET "PNOFORCE" -#define CMD_PNODEBUG_SET "PNODEBUG" - -#define PNO_TLV_PREFIX 'S' -#define PNO_TLV_VERSION '1' -#define PNO_TLV_SUBVERSION '2' -#define PNO_TLV_RESERVED '0' -#define PNO_TLV_TYPE_SSID_IE 'S' -#define PNO_TLV_TYPE_TIME 'T' -#define PNO_TLV_FREQ_REPEAT 'R' -#define PNO_TLV_FREQ_EXPO_MAX 'M' - -typedef struct cmd_tlv { - char prefix; - char version; - char subver; - char reserved; -} cmd_tlv_t; -#endif /* PNO_SUPPORT */ - -typedef struct android_wifi_priv_cmd { - char *buf; - int used_len; - int total_len; -} android_wifi_priv_cmd; - -/** - * Extern function declarations (TODO: move them to dhd_linux.h) - */ -void dhd_customer_gpio_wlan_ctrl(int onoff); -uint dhd_dev_reset(struct net_device *dev, uint8 flag); -int dhd_dev_init_ioctl(struct net_device *dev); -#ifdef WL_CFG80211 -int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr); -int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command); -#else -int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr) -{ return 0; } -int wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len) -{ return 0; } -int wl_cfg80211_get_p2p_noa(struct net_device *net, char* buf, int len) -{ return 0; } -int wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len) -{ return 0; } -#endif -extern int dhd_os_check_if_up(void *dhdp); -extern void *bcmsdh_get_drvdata(void); - -extern bool ap_fw_loaded; -#ifdef CUSTOMER_HW2 -extern char iface_name[IFNAMSIZ]; -#endif - -/** - * Local (static) functions and variables - */ - -/* Initialize g_wifi_on to 1 so dhd_bus_start will be called for the first - * time (only) in dhd_open, subsequential wifi on will be handled by - * wl_android_wifi_on - */ -static int g_wifi_on = TRUE; - -/** - * Local (static) function definitions - */ -static int wl_android_get_link_speed(struct net_device *net, char *command, int total_len) -{ - int link_speed; - int bytes_written; - int error; - - error = wldev_get_link_speed(net, &link_speed); - if (error) - return -1; - - /* Convert Kbps to Android Mbps */ - link_speed = link_speed / 1000; - bytes_written = snprintf(command, total_len, "LinkSpeed %d", link_speed); - DHD_INFO(("%s: command result is %s\n", __FUNCTION__, command)); - return bytes_written; -} - -static int wl_android_get_rssi(struct net_device *net, char *command, int total_len) -{ - wlc_ssid_t ssid = {0}; - int rssi; - int bytes_written = 0; - int error; - - error = wldev_get_rssi(net, &rssi); - if (error) - return -1; - - error = wldev_get_ssid(net, &ssid); - if (error) - return -1; - if ((ssid.SSID_len == 0) || (ssid.SSID_len > DOT11_MAX_SSID_LEN)) { - DHD_ERROR(("%s: wldev_get_ssid failed\n", __FUNCTION__)); - } else { - memcpy(command, ssid.SSID, ssid.SSID_len); - bytes_written = ssid.SSID_len; - } - bytes_written += snprintf(&command[bytes_written], total_len, " rssi %d", rssi); - DHD_INFO(("%s: command result is %s (%d)\n", __FUNCTION__, command, bytes_written)); - return bytes_written; -} - -static int wl_android_set_suspendopt(struct net_device *dev, char *command, int total_len) -{ - int suspend_flag; - int ret_now; - int ret = 0; - - suspend_flag = *(command + strlen(CMD_SETSUSPENDOPT) + 1) - '0'; - - if (suspend_flag != 0) - suspend_flag = 1; - ret_now = net_os_set_suspend_disable(dev, suspend_flag); - - if (ret_now != suspend_flag) { - if (!(ret = net_os_set_suspend(dev, ret_now, 1))) - DHD_INFO(("%s: Suspend Flag %d -> %d\n", - __FUNCTION__, ret_now, suspend_flag)); - else - DHD_ERROR(("%s: failed %d\n", __FUNCTION__, ret)); - } - return ret; -} - -static int wl_android_set_suspendmode(struct net_device *dev, char *command, int total_len) -{ - int ret = 0; - -#if !defined(CONFIG_HAS_EARLYSUSPEND) || !defined(DHD_USE_EARLYSUSPEND) - int suspend_flag; - - suspend_flag = *(command + strlen(CMD_SETSUSPENDMODE) + 1) - '0'; - - if (suspend_flag != 0) - suspend_flag = 1; - - if (!(ret = net_os_set_suspend(dev, suspend_flag, 0))) - DHD_INFO(("%s: Suspend Mode %d\n",__FUNCTION__,suspend_flag)); - else - DHD_ERROR(("%s: failed %d\n",__FUNCTION__,ret)); -#endif - return ret; -} - -static int wl_android_get_band(struct net_device *dev, char *command, int total_len) -{ - uint band; - int bytes_written; - int error; - - error = wldev_get_band(dev, &band); - if (error) - return -1; - bytes_written = snprintf(command, total_len, "Band %d", band); - return bytes_written; -} - -#if defined(PNO_SUPPORT) && !defined(WL_SCHED_SCAN) -static int wl_android_set_pno_setup(struct net_device *dev, char *command, int total_len) -{ - wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT]; - int res = -1; - int nssid = 0; - cmd_tlv_t *cmd_tlv_temp; - char *str_ptr; - int tlv_size_left; - int pno_time = 0; - int pno_repeat = 0; - int pno_freq_expo_max = 0; - -#ifdef PNO_SET_DEBUG - int i; - char pno_in_example[] = { - 'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ', - 'S', '1', '2', '0', - 'S', - 0x05, - 'd', 'l', 'i', 'n', 'k', - 'S', - 0x04, - 'G', 'O', 'O', 'G', - 'T', - '0', 'B', - 'R', - '2', - 'M', - '2', - 0x00 - }; -#endif /* PNO_SET_DEBUG */ - - DHD_INFO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len)); - - if (total_len < (strlen(CMD_PNOSETUP_SET) + sizeof(cmd_tlv_t))) { - DHD_ERROR(("%s argument=%d less min size\n", __FUNCTION__, total_len)); - goto exit_proc; - } - -#ifdef PNO_SET_DEBUG - memcpy(command, pno_in_example, sizeof(pno_in_example)); - for (i = 0; i < sizeof(pno_in_example); i++) - printf("%02X ", command[i]); - printf("\n"); - total_len = sizeof(pno_in_example); -#endif - - str_ptr = command + strlen(CMD_PNOSETUP_SET); - tlv_size_left = total_len - strlen(CMD_PNOSETUP_SET); - - cmd_tlv_temp = (cmd_tlv_t *)str_ptr; - memset(ssids_local, 0, sizeof(ssids_local)); - - if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) && - (cmd_tlv_temp->version == PNO_TLV_VERSION) && - (cmd_tlv_temp->subver == PNO_TLV_SUBVERSION)) { - - str_ptr += sizeof(cmd_tlv_t); - tlv_size_left -= sizeof(cmd_tlv_t); - - if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local, - MAX_PFN_LIST_COUNT, &tlv_size_left)) <= 0) { - DHD_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid)); - goto exit_proc; - } else { - if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) { - DHD_ERROR(("%s scan duration corrupted field size %d\n", - __FUNCTION__, tlv_size_left)); - goto exit_proc; - } - str_ptr++; - pno_time = simple_strtoul(str_ptr, &str_ptr, 16); - DHD_INFO(("%s: pno_time=%d\n", __FUNCTION__, pno_time)); - - if (str_ptr[0] != 0) { - if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) { - DHD_ERROR(("%s pno repeat : corrupted field\n", - __FUNCTION__)); - goto exit_proc; - } - str_ptr++; - pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16); - DHD_INFO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat)); - if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) { - DHD_ERROR(("%s FREQ_EXPO_MAX corrupted field size\n", - __FUNCTION__)); - goto exit_proc; - } - str_ptr++; - pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16); - DHD_INFO(("%s: pno_freq_expo_max=%d\n", - __FUNCTION__, pno_freq_expo_max)); - } - } - } else { - DHD_ERROR(("%s get wrong TLV command\n", __FUNCTION__)); - goto exit_proc; - } - - res = dhd_dev_pno_set(dev, ssids_local, nssid, pno_time, pno_repeat, pno_freq_expo_max); - -exit_proc: - return res; -} -#endif /* PNO_SUPPORT && !WL_SCHED_SCAN */ - -static int wl_android_get_p2p_dev_addr(struct net_device *ndev, char *command, int total_len) -{ - int ret; - int bytes_written = 0; - - ret = wl_cfg80211_get_p2p_dev_addr(ndev, (struct ether_addr*)command); - if (ret) - return 0; - bytes_written = sizeof(struct ether_addr); - return bytes_written; -} - -/** - * Global function definitions (declared in wl_android.h) - */ - -int wl_android_wifi_on(struct net_device *dev) -{ - int ret = 0; - - printk("%s in\n", __FUNCTION__); - if (!dev) { - DHD_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -EINVAL; - } - - dhd_net_if_lock(dev); - if (!g_wifi_on) { - dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON); - sdioh_start(NULL, 0); - ret = dhd_dev_reset(dev, FALSE); - sdioh_start(NULL, 1); - if (!ret) { - if (dhd_dev_init_ioctl(dev) < 0) - ret = -EFAULT; - } - g_wifi_on = 1; - } - dhd_net_if_unlock(dev); - - return ret; -} - -int wl_android_wifi_off(struct net_device *dev) -{ - int ret = 0; - - printk("%s in\n", __FUNCTION__); - if (!dev) { - DHD_TRACE(("%s: dev is null\n", __FUNCTION__)); - return -EINVAL; - } - - dhd_net_if_lock(dev); - if (g_wifi_on) { - ret = dhd_dev_reset(dev, TRUE); - sdioh_stop(NULL); - dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); - g_wifi_on = 0; - } - dhd_net_if_unlock(dev); - - return ret; -} - -static int wl_android_set_fwpath(struct net_device *net, char *command, int total_len) -{ - if ((strlen(command) - strlen(CMD_SETFWPATH)) > MOD_PARAM_PATHLEN) - return -1; - bcm_strncpy_s(fw_path, sizeof(fw_path), - command + strlen(CMD_SETFWPATH) + 1, MOD_PARAM_PATHLEN - 1); - if (strstr(fw_path, "apsta") != NULL) { - DHD_INFO(("GOT APSTA FIRMWARE\n")); - ap_fw_loaded = TRUE; - } else { - DHD_INFO(("GOT STA FIRMWARE\n")); - ap_fw_loaded = FALSE; - } - return 0; -} - -int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) -{ - int ret = 0; - char *command = NULL; - int bytes_written = 0; - android_wifi_priv_cmd priv_cmd; - - net_os_wake_lock(net); - - if (!ifr->ifr_data) { - ret = -EINVAL; - goto exit; - } - if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(android_wifi_priv_cmd))) { - ret = -EFAULT; - goto exit; - } - command = kmalloc(priv_cmd.total_len, GFP_KERNEL); - if (!command) - { - DHD_ERROR(("%s: failed to allocate memory\n", __FUNCTION__)); - ret = -ENOMEM; - goto exit; - } - if (copy_from_user(command, priv_cmd.buf, priv_cmd.total_len)) { - ret = -EFAULT; - goto exit; - } - - DHD_INFO(("%s: Android private cmd \"%s\" on %s\n", __FUNCTION__, command, ifr->ifr_name)); - - if (strnicmp(command, CMD_START, strlen(CMD_START)) == 0) { - DHD_INFO(("%s, Received regular START command\n", __FUNCTION__)); - bytes_written = wl_android_wifi_on(net); - } - else if (strnicmp(command, CMD_SETFWPATH, strlen(CMD_SETFWPATH)) == 0) { - bytes_written = wl_android_set_fwpath(net, command, priv_cmd.total_len); - } - - if (!g_wifi_on) { - DHD_ERROR(("%s: Ignore private cmd \"%s\" - iface %s is down\n", - __FUNCTION__, command, ifr->ifr_name)); - ret = 0; - goto exit; - } - - if (strnicmp(command, CMD_STOP, strlen(CMD_STOP)) == 0) { - bytes_written = wl_android_wifi_off(net); - } - else if (strnicmp(command, CMD_SCAN_ACTIVE, strlen(CMD_SCAN_ACTIVE)) == 0) { - /* TBD: SCAN-ACTIVE */ - } - else if (strnicmp(command, CMD_SCAN_PASSIVE, strlen(CMD_SCAN_PASSIVE)) == 0) { - /* TBD: SCAN-PASSIVE */ - } - else if (strnicmp(command, CMD_RSSI, strlen(CMD_RSSI)) == 0) { - bytes_written = wl_android_get_rssi(net, command, priv_cmd.total_len); - } - else if (strnicmp(command, CMD_LINKSPEED, strlen(CMD_LINKSPEED)) == 0) { - bytes_written = wl_android_get_link_speed(net, command, priv_cmd.total_len); - } - else if (strnicmp(command, CMD_RXFILTER_START, strlen(CMD_RXFILTER_START)) == 0) { - bytes_written = net_os_set_packet_filter(net, 1); - } - else if (strnicmp(command, CMD_RXFILTER_STOP, strlen(CMD_RXFILTER_STOP)) == 0) { - bytes_written = net_os_set_packet_filter(net, 0); - } - else if (strnicmp(command, CMD_RXFILTER_ADD, strlen(CMD_RXFILTER_ADD)) == 0) { - int filter_num = *(command + strlen(CMD_RXFILTER_ADD) + 1) - '0'; - bytes_written = net_os_rxfilter_add_remove(net, TRUE, filter_num); - } - else if (strnicmp(command, CMD_RXFILTER_REMOVE, strlen(CMD_RXFILTER_REMOVE)) == 0) { - int filter_num = *(command + strlen(CMD_RXFILTER_REMOVE) + 1) - '0'; - bytes_written = net_os_rxfilter_add_remove(net, FALSE, filter_num); - } - else if (strnicmp(command, CMD_BTCOEXSCAN_START, strlen(CMD_BTCOEXSCAN_START)) == 0) { - /* TBD: BTCOEXSCAN-START */ - } - else if (strnicmp(command, CMD_BTCOEXSCAN_STOP, strlen(CMD_BTCOEXSCAN_STOP)) == 0) { - /* TBD: BTCOEXSCAN-STOP */ - } - else if (strnicmp(command, CMD_BTCOEXMODE, strlen(CMD_BTCOEXMODE)) == 0) { - uint mode = *(command + strlen(CMD_BTCOEXMODE) + 1) - '0'; - - if (mode == 1) - net_os_set_packet_filter(net, 0); /* DHCP starts */ - else - net_os_set_packet_filter(net, 1); /* DHCP ends */ -#ifdef WL_CFG80211 - bytes_written = wl_cfg80211_set_btcoex_dhcp(net, command); -#endif - } - else if (strnicmp(command, CMD_SETSUSPENDOPT, strlen(CMD_SETSUSPENDOPT)) == 0) { - bytes_written = wl_android_set_suspendopt(net, command, priv_cmd.total_len); - } - else if (strnicmp(command, CMD_SETSUSPENDMODE, strlen(CMD_SETSUSPENDMODE)) == 0) { - bytes_written = wl_android_set_suspendmode(net, command, priv_cmd.total_len); - } - else if (strnicmp(command, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) { - uint band = *(command + strlen(CMD_SETBAND) + 1) - '0'; - bytes_written = wldev_set_band(net, band); - } - else if (strnicmp(command, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) { - bytes_written = wl_android_get_band(net, command, priv_cmd.total_len); - } - else if (strnicmp(command, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) { - char *country_code = command + strlen(CMD_COUNTRY) + 1; - bytes_written = wldev_set_country(net, country_code); - } -#if defined(PNO_SUPPORT) && !defined(WL_SCHED_SCAN) - else if (strnicmp(command, CMD_PNOSSIDCLR_SET, strlen(CMD_PNOSSIDCLR_SET)) == 0) { - bytes_written = dhd_dev_pno_reset(net); - } - else if (strnicmp(command, CMD_PNOSETUP_SET, strlen(CMD_PNOSETUP_SET)) == 0) { - bytes_written = wl_android_set_pno_setup(net, command, priv_cmd.total_len); - } - else if (strnicmp(command, CMD_PNOENABLE_SET, strlen(CMD_PNOENABLE_SET)) == 0) { - uint pfn_enabled = *(command + strlen(CMD_PNOENABLE_SET) + 1) - '0'; - bytes_written = dhd_dev_pno_enable(net, pfn_enabled); - } -#endif - else if (strnicmp(command, CMD_P2P_DEV_ADDR, strlen(CMD_P2P_DEV_ADDR)) == 0) { - bytes_written = wl_android_get_p2p_dev_addr(net, command, priv_cmd.total_len); - } - else if (strnicmp(command, CMD_P2P_SET_NOA, strlen(CMD_P2P_SET_NOA)) == 0) { - int skip = strlen(CMD_P2P_SET_NOA) + 1; - bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip, - priv_cmd.total_len - skip); - } -#if !defined WL_ENABLE_P2P_IF - else if (strnicmp(command, CMD_P2P_GET_NOA, strlen(CMD_P2P_GET_NOA)) == 0) { - bytes_written = wl_cfg80211_get_p2p_noa(net, command, priv_cmd.total_len); - } -#endif - else if (strnicmp(command, CMD_P2P_SET_PS, strlen(CMD_P2P_SET_PS)) == 0) { - int skip = strlen(CMD_P2P_SET_PS) + 1; - bytes_written = wl_cfg80211_set_p2p_ps(net, command + skip, - priv_cmd.total_len - skip); - } -#ifdef WL_CFG80211 - else if (strnicmp(command, CMD_SET_AP_WPS_P2P_IE, - strlen(CMD_SET_AP_WPS_P2P_IE)) == 0) { - int skip = strlen(CMD_SET_AP_WPS_P2P_IE) + 3; - bytes_written = wl_cfg80211_set_wps_p2p_ie(net, command + skip, - priv_cmd.total_len - skip, *(command + skip - 2) - '0'); - } -#endif /* WL_CFG80211 */ - else { - DHD_ERROR(("Unknown PRIVATE command %s - ignored\n", command)); - snprintf(command, 3, "OK"); - bytes_written = strlen("OK"); - } - - if (bytes_written >= 0) { - if ((bytes_written == 0) && (priv_cmd.total_len > 0)) - command[0] = '\0'; - if (bytes_written >= priv_cmd.total_len) { - DHD_ERROR(("%s: bytes_written = %d\n", __FUNCTION__, bytes_written)); - bytes_written = priv_cmd.total_len; - } else { - bytes_written++; - } - priv_cmd.used_len = bytes_written; - if (copy_to_user(priv_cmd.buf, command, bytes_written)) { - DHD_ERROR(("%s: failed to copy data to user buffer\n", __FUNCTION__)); - ret = -EFAULT; - } - } - else { - ret = bytes_written; - } - -exit: - net_os_wake_unlock(net); - if (command) { - kfree(command); - } - - return ret; -} - -int wl_android_init(void) -{ - int ret = 0; - - dhd_msg_level |= DHD_ERROR_VAL; -#ifdef ENABLE_INSMOD_NO_FW_LOAD - dhd_download_fw_on_driverload = FALSE; -#endif /* ENABLE_INSMOD_NO_FW_LOAD */ -#ifdef CUSTOMER_HW2 - if (!iface_name[0]) { - memset(iface_name, 0, IFNAMSIZ); - bcm_strncpy_s(iface_name, IFNAMSIZ, "wlan", IFNAMSIZ); - } -#endif /* CUSTOMER_HW2 */ - return ret; -} - -int wl_android_exit(void) -{ - int ret = 0; - - return ret; -} - -void wl_android_post_init(void) -{ - if (!dhd_download_fw_on_driverload) { - /* Call customer gpio to turn off power with WL_REG_ON signal */ - dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); - g_wifi_on = 0; - } -} -/** - * Functions for Android WiFi card detection - */ -#if defined(CONFIG_WIFI_CONTROL_FUNC) - -static int g_wifidev_registered = 0; -static struct semaphore wifi_control_sem; -static struct wifi_platform_data *wifi_control_data = NULL; -static struct resource *wifi_irqres = NULL; - -static int wifi_add_dev(void); -static void wifi_del_dev(void); - -int wl_android_wifictrl_func_add(void) -{ - int ret = 0; - sema_init(&wifi_control_sem, 0); - - ret = wifi_add_dev(); - if (ret) { - DHD_ERROR(("%s: platform_driver_register failed\n", __FUNCTION__)); - return ret; - } - g_wifidev_registered = 1; - - /* Waiting callback after platform_driver_register is done or exit with error */ - if (down_timeout(&wifi_control_sem, msecs_to_jiffies(1000)) != 0) { - ret = -EINVAL; - DHD_ERROR(("%s: platform_driver_register timeout\n", __FUNCTION__)); - } - - return ret; -} - -void wl_android_wifictrl_func_del(void) -{ - if (g_wifidev_registered) - { - wifi_del_dev(); - g_wifidev_registered = 0; - } -} - -void* wl_android_prealloc(int section, unsigned long size) -{ - void *alloc_ptr = NULL; - if (wifi_control_data && wifi_control_data->mem_prealloc) { - alloc_ptr = wifi_control_data->mem_prealloc(section, size); - if (alloc_ptr) { - DHD_INFO(("success alloc section %d\n", section)); - if (size != 0L) - bzero(alloc_ptr, size); - return alloc_ptr; - } - } - - DHD_ERROR(("can't alloc section %d\n", section)); - return NULL; -} - -int wifi_get_irq_number(unsigned long *irq_flags_ptr) -{ - if (wifi_irqres) { - *irq_flags_ptr = wifi_irqres->flags & IRQF_TRIGGER_MASK; - return (int)wifi_irqres->start; - } -#ifdef CUSTOM_OOB_GPIO_NUM - return CUSTOM_OOB_GPIO_NUM; -#else - return -1; -#endif -} - -int wifi_set_power(int on, unsigned long msec) -{ - DHD_ERROR(("%s = %d\n", __FUNCTION__, on)); - if (wifi_control_data && wifi_control_data->set_power) { - wifi_control_data->set_power(on); - } - if (msec) - msleep(msec); - return 0; -} - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) -int wifi_get_mac_addr(unsigned char *buf) -{ - DHD_TRACE(("%s\n", __FUNCTION__)); - if (!buf) - return -EINVAL; - if (wifi_control_data && wifi_control_data->get_mac_addr) { - return wifi_control_data->get_mac_addr(buf); - } - return -EOPNOTSUPP; -} -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) -void *wifi_get_country_code(char *ccode) -{ - DHD_TRACE(("%s\n", __FUNCTION__)); - if (!ccode) - return NULL; - if (wifi_control_data && wifi_control_data->get_country_code) { - return wifi_control_data->get_country_code(ccode); - } - return NULL; -} -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) */ - -static int wifi_set_carddetect(int on) -{ - DHD_ERROR(("%s = %d\n", __FUNCTION__, on)); - if (wifi_control_data && wifi_control_data->set_carddetect) { - wifi_control_data->set_carddetect(on); - } - return 0; -} - -static int wifi_probe(struct platform_device *pdev) -{ - struct wifi_platform_data *wifi_ctrl = - (struct wifi_platform_data *)(pdev->dev.platform_data); - - DHD_ERROR(("## %s\n", __FUNCTION__)); - wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcmdhd_wlan_irq"); - if (wifi_irqres == NULL) - wifi_irqres = platform_get_resource_byname(pdev, - IORESOURCE_IRQ, "bcm4329_wlan_irq"); - wifi_control_data = wifi_ctrl; - - wifi_set_power(1, 0); /* Power On */ - wifi_set_carddetect(1); /* CardDetect (0->1) */ - - up(&wifi_control_sem); - return 0; -} - -static int wifi_remove(struct platform_device *pdev) -{ - struct wifi_platform_data *wifi_ctrl = - (struct wifi_platform_data *)(pdev->dev.platform_data); - - DHD_ERROR(("## %s\n", __FUNCTION__)); - wifi_control_data = wifi_ctrl; - - wifi_set_power(0, 0); /* Power Off */ - wifi_set_carddetect(0); /* CardDetect (1->0) */ - - up(&wifi_control_sem); - return 0; -} - -static int wifi_suspend(struct platform_device *pdev, pm_message_t state) -{ - DHD_TRACE(("##> %s\n", __FUNCTION__)); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) - bcmsdh_oob_intr_set(0); -#endif - return 0; -} - -static int wifi_resume(struct platform_device *pdev) -{ - DHD_TRACE(("##> %s\n", __FUNCTION__)); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) - if (dhd_os_check_if_up(bcmsdh_get_drvdata())) - bcmsdh_oob_intr_set(1); -#endif - return 0; -} - -static struct platform_driver wifi_device = { - .probe = wifi_probe, - .remove = wifi_remove, - .suspend = wifi_suspend, - .resume = wifi_resume, - .driver = { - .name = "bcmdhd_wlan", - } -}; - -static struct platform_driver wifi_device_legacy = { - .probe = wifi_probe, - .remove = wifi_remove, - .suspend = wifi_suspend, - .resume = wifi_resume, - .driver = { - .name = "bcm4329_wlan", - } -}; - -static int wifi_add_dev(void) -{ - DHD_TRACE(("## Calling platform_driver_register\n")); - platform_driver_register(&wifi_device); - platform_driver_register(&wifi_device_legacy); - return 0; -} - -static void wifi_del_dev(void) -{ - DHD_TRACE(("## Unregister platform_driver_register\n")); - platform_driver_unregister(&wifi_device); - platform_driver_unregister(&wifi_device_legacy); -} -#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */ diff --git a/drivers/net/wireless/bcmdhd/wl_android.h b/drivers/net/wireless/bcmdhd/wl_android.h deleted file mode 100644 index 3983306cfe38..000000000000 --- a/drivers/net/wireless/bcmdhd/wl_android.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Linux cfg80211 driver - Android related functions - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wl_android.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $ - */ - -#include -#include -#include - -/** - * Android platform dependent functions, feel free to add Android specific functions here - * (save the macros in dhd). Please do NOT declare functions that are NOT exposed to dhd - * or cfg, define them as static in wl_android.c - */ - -/** - * wl_android_init will be called from module init function (dhd_module_init now), similarly - * wl_android_exit will be called from module exit function (dhd_module_cleanup now) - */ -int wl_android_init(void); -int wl_android_exit(void); -void wl_android_post_init(void); -int wl_android_wifi_on(struct net_device *dev); -int wl_android_wifi_off(struct net_device *dev); -int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd); - -#if defined(CONFIG_WIFI_CONTROL_FUNC) -int wl_android_wifictrl_func_add(void); -void wl_android_wifictrl_func_del(void); -void* wl_android_prealloc(int section, unsigned long size); - -int wifi_get_irq_number(unsigned long *irq_flags_ptr); -int wifi_set_power(int on, unsigned long msec); -int wifi_get_mac_addr(unsigned char *buf); -void *wifi_get_country_code(char *ccode); -#endif /* CONFIG_WIFI_CONTROL_FUNC */ diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c deleted file mode 100644 index 90c947e8e8c1..000000000000 --- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c +++ /dev/null @@ -1,7885 +0,0 @@ -/* - * Linux cfg80211 driver - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wl_cfg80211.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $ - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static struct device *cfg80211_parent_dev = NULL; -static int vsdb_supported = 0; -struct wl_priv *wlcfg_drv_priv = NULL; - -u32 wl_dbg_level = WL_DBG_ERR; - -#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] -#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" -#define MAX_WAIT_TIME 1500 -#define WL_SCAN_ACTIVE_TIME 40 -#define WL_SCAN_PASSIVE_TIME 130 -#define WL_FRAME_LEN 300 -#define WL_SCAN_BUSY_MAX 8 - -#define DNGL_FUNC(func, parameters) func parameters; -#define COEX_DHCP - - -/* This is to override regulatory domains defined in cfg80211 module (reg.c) - * By default world regulatory domain defined in reg.c puts the flags NL80211_RRF_PASSIVE_SCAN - * and NL80211_RRF_NO_IBSS for 5GHz channels (for 36..48 and 149..165). - * With respect to these flags, wpa_supplicant doesn't start p2p operations on 5GHz channels. - * All the chnages in world regulatory domain are to be done here. - */ -static const struct ieee80211_regdomain brcm_regdom = { - .n_reg_rules = 4, - .alpha2 = "99", - .reg_rules = { - /* IEEE 802.11b/g, channels 1..11 */ - REG_RULE(2412-10, 2472+10, 40, 6, 20, 0), - /* IEEE 802.11b/g, channels 12..13. No HT40 - * channel fits here. - */ - /* If any */ - /* - * IEEE 802.11 channel 14 - is for JP only, - * we need cfg80211 to allow it (reg_flags = 0); so that - * hostapd could request auto channel by sending down ch 14 - */ - REG_RULE(2484-10, 2484+10, 20, 6, 20, - NL80211_RRF_PASSIVE_SCAN | - NL80211_RRF_NO_IBSS | - NL80211_RRF_NO_OFDM), - /* IEEE 802.11a, channel 36..64 */ - REG_RULE(5150-10, 5350+10, 40, 6, 20, 0), - /* IEEE 802.11a, channel 100..165 */ - REG_RULE(5470-10, 5850+10, 40, 6, 20, 0), } -}; - - -/* Data Element Definitions */ -#define WPS_ID_CONFIG_METHODS 0x1008 -#define WPS_ID_REQ_TYPE 0x103A -#define WPS_ID_DEVICE_NAME 0x1011 -#define WPS_ID_VERSION 0x104A -#define WPS_ID_DEVICE_PWD_ID 0x1012 -#define WPS_ID_REQ_DEV_TYPE 0x106A -#define WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS 0x1053 -#define WPS_ID_PRIM_DEV_TYPE 0x1054 - -/* Device Password ID */ -#define DEV_PW_DEFAULT 0x0000 -#define DEV_PW_USER_SPECIFIED 0x0001, -#define DEV_PW_MACHINE_SPECIFIED 0x0002 -#define DEV_PW_REKEY 0x0003 -#define DEV_PW_PUSHBUTTON 0x0004 -#define DEV_PW_REGISTRAR_SPECIFIED 0x0005 - -/* Config Methods */ -#define WPS_CONFIG_USBA 0x0001 -#define WPS_CONFIG_ETHERNET 0x0002 -#define WPS_CONFIG_LABEL 0x0004 -#define WPS_CONFIG_DISPLAY 0x0008 -#define WPS_CONFIG_EXT_NFC_TOKEN 0x0010 -#define WPS_CONFIG_INT_NFC_TOKEN 0x0020 -#define WPS_CONFIG_NFC_INTERFACE 0x0040 -#define WPS_CONFIG_PUSHBUTTON 0x0080 -#define WPS_CONFIG_KEYPAD 0x0100 -#define WPS_CONFIG_VIRT_PUSHBUTTON 0x0280 -#define WPS_CONFIG_PHY_PUSHBUTTON 0x0480 -#define WPS_CONFIG_VIRT_DISPLAY 0x2008 -#define WPS_CONFIG_PHY_DISPLAY 0x4008 - -/* - * cfg80211_ops api/callback list - */ -static s32 wl_frame_get_mgmt(u16 fc, const struct ether_addr *da, - const struct ether_addr *sa, const struct ether_addr *bssid, - u8 **pheader, u32 *body_len, u8 *pbody); -static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, - struct cfg80211_scan_request *request, - struct cfg80211_ssid *this_ssid); -static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, - struct cfg80211_scan_request *request); -static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed); -static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, - struct cfg80211_ibss_params *params); -static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, - struct net_device *dev); -static s32 wl_cfg80211_get_station(struct wiphy *wiphy, - struct net_device *dev, u8 *mac, - struct station_info *sinfo); -static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, - struct net_device *dev, bool enabled, - s32 timeout); -static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, - struct cfg80211_connect_params *sme); -static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, - u16 reason_code); -static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy, - enum nl80211_tx_power_setting type, - s32 dbm); -static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm); -static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy, - struct net_device *dev, - u8 key_idx, bool unicast, bool multicast); -static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool pairwise, const u8 *mac_addr, - struct key_params *params); -static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool pairwise, const u8 *mac_addr); -static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool pairwise, const u8 *mac_addr, - void *cookie, void (*callback) (void *cookie, - struct key_params *params)); -static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, - struct net_device *dev, u8 key_idx); -static s32 wl_cfg80211_resume(struct wiphy *wiphy); -static s32 wl_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, - struct net_device *dev, u64 cookie); -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) -static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow); -#else -static s32 wl_cfg80211_suspend(struct wiphy *wiphy); -#endif -static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, - struct cfg80211_pmksa *pmksa); -static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, - struct cfg80211_pmksa *pmksa); -static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, - struct net_device *dev); -static s32 wl_notify_escan_complete(struct wl_priv *wl, - struct net_device *ndev, bool aborted, bool fw_abort); -/* - * event & event Q handlers for cfg80211 interfaces - */ -static s32 wl_create_event_handler(struct wl_priv *wl); -static void wl_destroy_event_handler(struct wl_priv *wl); -static s32 wl_event_handler(void *data); -static void wl_init_eq(struct wl_priv *wl); -static void wl_flush_eq(struct wl_priv *wl); -static unsigned long wl_lock_eq(struct wl_priv *wl); -static void wl_unlock_eq(struct wl_priv *wl, unsigned long flags); -static void wl_init_eq_lock(struct wl_priv *wl); -static void wl_init_event_handler(struct wl_priv *wl); -static struct wl_event_q *wl_deq_event(struct wl_priv *wl); -static s32 wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 type, - const wl_event_msg_t *msg, void *data); -static void wl_put_event(struct wl_event_q *e); -static void wl_wakeup_event(struct wl_priv *wl); -static s32 wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data); -static s32 wl_notify_connect_status(struct wl_priv *wl, - struct net_device *ndev, - const wl_event_msg_t *e, void *data); -static s32 wl_notify_roaming_status(struct wl_priv *wl, - struct net_device *ndev, - const wl_event_msg_t *e, void *data); -static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data); -static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data, bool completed); -static s32 wl_ibss_join_done(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data, bool completed); -static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data); -static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data); -#ifdef WL_SCHED_SCAN -static s32 -wl_notify_sched_scan_results(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data); -#endif /* WL_SCHED_SCAN */ -#ifdef PNO_SUPPORT -static s32 wl_notify_pfn_status(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data); -#endif /* PNO_SUPPORT */ -/* - * register/deregister parent device - */ -static void wl_cfg80211_clear_parent_dev(void); - -/* - * cfg80211 set_wiphy_params utilities - */ -static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold); -static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold); -static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l); - -/* - * wl profile utilities - */ -static s32 wl_update_prof(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data, s32 item); -static void *wl_read_prof(struct wl_priv *wl, struct net_device *ndev, s32 item); -static void wl_init_prof(struct wl_priv *wl, struct net_device *ndev); - -/* - * cfg80211 connect utilites - */ -static s32 wl_set_wpa_version(struct net_device *dev, - struct cfg80211_connect_params *sme); -static s32 wl_set_auth_type(struct net_device *dev, - struct cfg80211_connect_params *sme); -static s32 wl_set_set_cipher(struct net_device *dev, - struct cfg80211_connect_params *sme); -static s32 wl_set_key_mgmt(struct net_device *dev, - struct cfg80211_connect_params *sme); -static s32 wl_set_set_sharedkey(struct net_device *dev, - struct cfg80211_connect_params *sme); -static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev); -static void wl_ch_to_chanspec(int ch, - struct wl_join_params *join_params, size_t *join_params_size); - -/* - * information element utilities - */ -static void wl_rst_ie(struct wl_priv *wl); -static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v); -static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size); -static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size); -static u32 wl_get_ielen(struct wl_priv *wl); - - -static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *dev); -static void wl_free_wdev(struct wl_priv *wl); - -static s32 wl_inform_bss(struct wl_priv *wl); -static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi); -static s32 wl_inform_ibss(struct wl_priv *wl, const u8 *bssid); -static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev); -static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy); - -static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, const u8 *mac_addr, - struct key_params *params); -/* - * key indianess swap utilities - */ -static void swap_key_from_BE(struct wl_wsec_key *key); -static void swap_key_to_BE(struct wl_wsec_key *key); - -/* - * wl_priv memory init/deinit utilities - */ -static s32 wl_init_priv_mem(struct wl_priv *wl); -static void wl_deinit_priv_mem(struct wl_priv *wl); - -static void wl_delay(u32 ms); - -/* - * ibss mode utilities - */ -static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev); -static __used bool wl_is_ibssstarter(struct wl_priv *wl); - -/* - * link up/down , default configuration utilities - */ -static s32 __wl_cfg80211_up(struct wl_priv *wl); -static s32 __wl_cfg80211_down(struct wl_priv *wl); -static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e); -static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev); -static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e); -static void wl_link_up(struct wl_priv *wl); -static void wl_link_down(struct wl_priv *wl); -static s32 wl_config_ifmode(struct wl_priv *wl, struct net_device *ndev, s32 iftype); -static void wl_init_conf(struct wl_conf *conf); - -/* - * iscan handler - */ -static void wl_iscan_timer(unsigned long data); -static void wl_term_iscan(struct wl_priv *wl); -static s32 wl_init_scan(struct wl_priv *wl); -static s32 wl_iscan_thread(void *data); -static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request, - u16 action); -static s32 wl_do_iscan(struct wl_priv *wl, struct cfg80211_scan_request *request); -static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan); -static s32 wl_invoke_iscan(struct wl_priv *wl); -static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status, - struct wl_scan_results **bss_list); -static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted); -static void wl_init_iscan_handler(struct wl_iscan_ctrl *iscan); -static s32 wl_iscan_done(struct wl_priv *wl); -static s32 wl_iscan_pending(struct wl_priv *wl); -static s32 wl_iscan_inprogress(struct wl_priv *wl); -static s32 wl_iscan_aborted(struct wl_priv *wl); -static void wl_scan_timeout_process(struct work_struct *work); - -/* - * find most significant bit set - */ -static __used u32 wl_find_msb(u16 bit16); - -/* - * rfkill support - */ -static int wl_setup_rfkill(struct wl_priv *wl, bool setup); -static int wl_rfkill_set(void *data, bool blocked); - -static wl_scan_params_t *wl_cfg80211_scan_alloc_params(int channel, - int nprobes, int *out_params_size); -static void get_primary_mac(struct wl_priv *wl, struct ether_addr *mac); - -/* - * Some external functions, TODO: move them to dhd_linux.h - */ -int dhd_add_monitor(char *name, struct net_device **new_ndev); -int dhd_del_monitor(struct net_device *ndev); -int dhd_monitor_init(void *dhd_pub); -int dhd_monitor_uninit(void); -int dhd_start_xmit(struct sk_buff *skb, struct net_device *net); - -#define CHECK_SYS_UP(wlpriv) \ -do { \ - struct net_device *ndev = wl_to_prmry_ndev(wlpriv); \ - if (unlikely(!wl_get_drv_status(wlpriv, READY, ndev))) { \ - WL_INFO(("device is not ready\n")); \ - return -EIO; \ - } \ -} while (0) - - -#define IS_WPA_AKM(akm) ((akm) == RSN_AKM_NONE || \ - (akm) == RSN_AKM_UNSPECIFIED || \ - (akm) == RSN_AKM_PSK) - - -extern int dhd_wait_pend8021x(struct net_device *dev); - -#if (WL_DBG_LEVEL > 0) -#define WL_DBG_ESTR_MAX 50 -static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = { - "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND", - "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC", - "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END", - "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM", - "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH", - "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND", - "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND", - "PFN_NET_LOST", - "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START", - "IBSS_ASSOC", - "RADIO", "PSM_WATCHDOG", "WLC_E_CCX_ASSOC_START", "WLC_E_CCX_ASSOC_ABORT", - "PROBREQ_MSG", - "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED", - "EXCEEDED_MEDIUM_TIME", "ICV_ERROR", - "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE", - "WLC_E_BTA_HCI_EVENT", "IF", "WLC_E_P2P_DISC_LISTEN_COMPLETE", - "RSSI", "PFN_SCAN_COMPLETE", "WLC_E_EXTLOG_MSG", - "ACTION_FRAME", "ACTION_FRAME_COMPLETE", "WLC_E_PRE_ASSOC_IND", - "WLC_E_PRE_REASSOC_IND", "WLC_E_CHANNEL_ADOPTED", "WLC_E_AP_STARTED", - "WLC_E_DFS_AP_STOP", "WLC_E_DFS_AP_RESUME", "WLC_E_WAI_STA_EVENT", - "WLC_E_WAI_MSG", "WLC_E_ESCAN_RESULT", "WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE", - "WLC_E_PROBRESP_MSG", "WLC_E_P2P_PROBREQ_MSG", "WLC_E_DCS_REQUEST", "WLC_E_FIFO_CREDIT_MAP", - "WLC_E_ACTION_FRAME_RX", "WLC_E_WAKE_EVENT", "WLC_E_RM_COMPLETE" -}; -#endif /* WL_DBG_LEVEL */ - -#define CHAN2G(_channel, _freq, _flags) { \ - .band = IEEE80211_BAND_2GHZ, \ - .center_freq = (_freq), \ - .hw_value = (_channel), \ - .flags = (_flags), \ - .max_antenna_gain = 0, \ - .max_power = 30, \ -} - -#define CHAN5G(_channel, _flags) { \ - .band = IEEE80211_BAND_5GHZ, \ - .center_freq = 5000 + (5 * (_channel)), \ - .hw_value = (_channel), \ - .flags = (_flags), \ - .max_antenna_gain = 0, \ - .max_power = 30, \ -} - -#define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2) -#define RATETAB_ENT(_rateid, _flags) \ - { \ - .bitrate = RATE_TO_BASE100KBPS(_rateid), \ - .hw_value = (_rateid), \ - .flags = (_flags), \ - } - -static struct ieee80211_rate __wl_rates[] = { - RATETAB_ENT(WLC_RATE_1M, 0), - RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE), - RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE), - RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE), - RATETAB_ENT(WLC_RATE_6M, 0), - RATETAB_ENT(WLC_RATE_9M, 0), - RATETAB_ENT(WLC_RATE_12M, 0), - RATETAB_ENT(WLC_RATE_18M, 0), - RATETAB_ENT(WLC_RATE_24M, 0), - RATETAB_ENT(WLC_RATE_36M, 0), - RATETAB_ENT(WLC_RATE_48M, 0), - RATETAB_ENT(WLC_RATE_54M, 0) -}; - -#define wl_a_rates (__wl_rates + 4) -#define wl_a_rates_size 8 -#define wl_g_rates (__wl_rates + 0) -#define wl_g_rates_size 12 - -static struct ieee80211_channel __wl_2ghz_channels[] = { - CHAN2G(1, 2412, 0), - CHAN2G(2, 2417, 0), - CHAN2G(3, 2422, 0), - CHAN2G(4, 2427, 0), - CHAN2G(5, 2432, 0), - CHAN2G(6, 2437, 0), - CHAN2G(7, 2442, 0), - CHAN2G(8, 2447, 0), - CHAN2G(9, 2452, 0), - CHAN2G(10, 2457, 0), - CHAN2G(11, 2462, 0), - CHAN2G(12, 2467, 0), - CHAN2G(13, 2472, 0), - CHAN2G(14, 2484, 0) -}; - -static struct ieee80211_channel __wl_5ghz_a_channels[] = { - CHAN5G(34, 0), CHAN5G(36, 0), - CHAN5G(38, 0), CHAN5G(40, 0), - CHAN5G(42, 0), CHAN5G(44, 0), - CHAN5G(46, 0), CHAN5G(48, 0), - CHAN5G(52, 0), CHAN5G(56, 0), - CHAN5G(60, 0), CHAN5G(64, 0), - CHAN5G(100, 0), CHAN5G(104, 0), - CHAN5G(108, 0), CHAN5G(112, 0), - CHAN5G(116, 0), CHAN5G(120, 0), - CHAN5G(124, 0), CHAN5G(128, 0), - CHAN5G(132, 0), CHAN5G(136, 0), - CHAN5G(140, 0), CHAN5G(149, 0), - CHAN5G(153, 0), CHAN5G(157, 0), - CHAN5G(161, 0), CHAN5G(165, 0) -}; - -static struct ieee80211_supported_band __wl_band_2ghz = { - .band = IEEE80211_BAND_2GHZ, - .channels = __wl_2ghz_channels, - .n_channels = ARRAY_SIZE(__wl_2ghz_channels), - .bitrates = wl_g_rates, - .n_bitrates = wl_g_rates_size -}; - -static struct ieee80211_supported_band __wl_band_5ghz_a = { - .band = IEEE80211_BAND_5GHZ, - .channels = __wl_5ghz_a_channels, - .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels), - .bitrates = wl_a_rates, - .n_bitrates = wl_a_rates_size -}; - -static const u32 __wl_cipher_suites[] = { - WLAN_CIPHER_SUITE_WEP40, - WLAN_CIPHER_SUITE_WEP104, - WLAN_CIPHER_SUITE_TKIP, - WLAN_CIPHER_SUITE_CCMP, - WLAN_CIPHER_SUITE_AES_CMAC, -}; - -/* There isn't a lot of sense in it, but you can transmit anything you like */ -static const struct ieee80211_txrx_stypes -wl_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { - [NL80211_IFTYPE_ADHOC] = { - .tx = 0xffff, - .rx = BIT(IEEE80211_STYPE_ACTION >> 4) - }, - [NL80211_IFTYPE_STATION] = { - .tx = 0xffff, - .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4) - }, - [NL80211_IFTYPE_AP] = { - .tx = 0xffff, - .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | - BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | - BIT(IEEE80211_STYPE_DISASSOC >> 4) | - BIT(IEEE80211_STYPE_AUTH >> 4) | - BIT(IEEE80211_STYPE_DEAUTH >> 4) | - BIT(IEEE80211_STYPE_ACTION >> 4) - }, - [NL80211_IFTYPE_AP_VLAN] = { - /* copy AP */ - .tx = 0xffff, - .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | - BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | - BIT(IEEE80211_STYPE_DISASSOC >> 4) | - BIT(IEEE80211_STYPE_AUTH >> 4) | - BIT(IEEE80211_STYPE_DEAUTH >> 4) | - BIT(IEEE80211_STYPE_ACTION >> 4) - }, - [NL80211_IFTYPE_P2P_CLIENT] = { - .tx = 0xffff, - .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4) - }, - [NL80211_IFTYPE_P2P_GO] = { - .tx = 0xffff, - .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | - BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | - BIT(IEEE80211_STYPE_DISASSOC >> 4) | - BIT(IEEE80211_STYPE_AUTH >> 4) | - BIT(IEEE80211_STYPE_DEAUTH >> 4) | - BIT(IEEE80211_STYPE_ACTION >> 4) - } -}; - -static void swap_key_from_BE(struct wl_wsec_key *key) -{ - key->index = htod32(key->index); - key->len = htod32(key->len); - key->algo = htod32(key->algo); - key->flags = htod32(key->flags); - key->rxiv.hi = htod32(key->rxiv.hi); - key->rxiv.lo = htod16(key->rxiv.lo); - key->iv_initialized = htod32(key->iv_initialized); -} - -static void swap_key_to_BE(struct wl_wsec_key *key) -{ - key->index = dtoh32(key->index); - key->len = dtoh32(key->len); - key->algo = dtoh32(key->algo); - key->flags = dtoh32(key->flags); - key->rxiv.hi = dtoh32(key->rxiv.hi); - key->rxiv.lo = dtoh16(key->rxiv.lo); - key->iv_initialized = dtoh32(key->iv_initialized); -} - -/* For debug: Dump the contents of the encoded wps ie buffe */ -static void -wl_validate_wps_ie(char *wps_ie, bool *pbc) -{ - #define WPS_IE_FIXED_LEN 6 - u16 len = (u16) wps_ie[TLV_LEN_OFF]; - u8 *subel = wps_ie+ WPS_IE_FIXED_LEN; - u16 subelt_id; - u16 subelt_len; - u16 val; - u8 *valptr = (uint8*) &val; - - WL_DBG(("wps_ie len=%d\n", len)); - - len -= 4; /* for the WPS IE's OUI, oui_type fields */ - - while (len >= 4) { /* must have attr id, attr len fields */ - valptr[0] = *subel++; - valptr[1] = *subel++; - subelt_id = HTON16(val); - - valptr[0] = *subel++; - valptr[1] = *subel++; - subelt_len = HTON16(val); - - len -= 4; /* for the attr id, attr len fields */ - len -= subelt_len; /* for the remaining fields in this attribute */ - WL_DBG((" subel=%p, subelt_id=0x%x subelt_len=%u\n", - subel, subelt_id, subelt_len)); - - if (subelt_id == WPS_ID_VERSION) { - WL_DBG((" attr WPS_ID_VERSION: %u\n", *subel)); - } else if (subelt_id == WPS_ID_REQ_TYPE) { - WL_DBG((" attr WPS_ID_REQ_TYPE: %u\n", *subel)); - } else if (subelt_id == WPS_ID_CONFIG_METHODS) { - valptr[0] = *subel; - valptr[1] = *(subel + 1); - WL_DBG((" attr WPS_ID_CONFIG_METHODS: %x\n", HTON16(val))); - } else if (subelt_id == WPS_ID_DEVICE_NAME) { - char devname[100]; - memcpy(devname, subel, subelt_len); - devname[subelt_len] = '\0'; - WL_DBG((" attr WPS_ID_DEVICE_NAME: %s (len %u)\n", - devname, subelt_len)); - } else if (subelt_id == WPS_ID_DEVICE_PWD_ID) { - valptr[0] = *subel; - valptr[1] = *(subel + 1); - WL_DBG((" attr WPS_ID_DEVICE_PWD_ID: %u\n", HTON16(val))); - *pbc = (HTON16(val) == DEV_PW_PUSHBUTTON) ? true : false; - } else if (subelt_id == WPS_ID_PRIM_DEV_TYPE) { - valptr[0] = *subel; - valptr[1] = *(subel + 1); - WL_DBG((" attr WPS_ID_PRIM_DEV_TYPE: cat=%u \n", HTON16(val))); - valptr[0] = *(subel + 6); - valptr[1] = *(subel + 7); - WL_DBG((" attr WPS_ID_PRIM_DEV_TYPE: subcat=%u\n", HTON16(val))); - } else if (subelt_id == WPS_ID_REQ_DEV_TYPE) { - valptr[0] = *subel; - valptr[1] = *(subel + 1); - WL_DBG((" attr WPS_ID_REQ_DEV_TYPE: cat=%u\n", HTON16(val))); - valptr[0] = *(subel + 6); - valptr[1] = *(subel + 7); - WL_DBG((" attr WPS_ID_REQ_DEV_TYPE: subcat=%u\n", HTON16(val))); - } else if (subelt_id == WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS) { - valptr[0] = *subel; - valptr[1] = *(subel + 1); - WL_DBG((" attr WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS" - ": cat=%u\n", HTON16(val))); - } else { - WL_DBG((" unknown attr 0x%x\n", subelt_id)); - } - - subel += subelt_len; - } -} - -static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy) -{ - if (vsdb_supported) { - return wf_chspec_aton(WL_P2P_TEMP_CHAN); - } - else { - chanspec_t chspec; - int err = 0; - struct wl_priv *wl = wiphy_priv(wiphy); - struct net_device *dev = wl_to_prmry_ndev(wl); - struct ether_addr bssid; - struct wl_bss_info *bss = NULL; - if ((err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), false))) { - /* STA interface is not associated. So start the new interface on a temp - * channel . Later proper channel will be applied by the above framework - * via set_channel (cfg80211 API). - */ - WL_DBG(("Not associated. Return a temp channel. \n")); - return wf_chspec_aton(WL_P2P_TEMP_CHAN); - } - - - *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX); - if ((err = wldev_ioctl(dev, WLC_GET_BSS_INFO, wl->extra_buf, - WL_EXTRA_BUF_MAX, false))) { - WL_ERR(("Failed to get associated bss info, use temp channel \n")); - chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN); - } - else { - bss = (struct wl_bss_info *) (wl->extra_buf + 4); - chspec = bss->chanspec; - WL_DBG(("Valid BSS Found. chanspec:%d \n", bss->chanspec)); - } - return chspec; - } -} - -static struct net_device* wl_cfg80211_add_monitor_if(char *name) -{ - int ret = 0; - struct net_device* ndev = NULL; - - ret = dhd_add_monitor(name, &ndev); - WL_INFO(("wl_cfg80211_add_monitor_if net device returned: 0x%p\n", ndev)); - return ndev; -} - -static struct net_device * -wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name, - enum nl80211_iftype type, u32 *flags, - struct vif_params *params) -{ - s32 err; - s32 timeout = -1; - s32 wlif_type = -1; - s32 mode = 0; -#if defined(WL_ENABLE_P2P_IF) - s32 dhd_mode = 0; -#endif /* (WL_ENABLE_P2P_IF) */ - chanspec_t chspec; - struct wl_priv *wl = wiphy_priv(wiphy); - struct net_device *_ndev; - struct ether_addr primary_mac; - int (*net_attach)(void *dhdp, int ifidx); - bool rollback_lock = false; - - /* Use primary I/F for sending cmds down to firmware */ - _ndev = wl_to_prmry_ndev(wl); - - WL_DBG(("if name: %s, type: %d\n", name, type)); - switch (type) { - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_AP_VLAN: - case NL80211_IFTYPE_WDS: - case NL80211_IFTYPE_MESH_POINT: - WL_ERR(("Unsupported interface type\n")); - mode = WL_MODE_IBSS; - return NULL; - case NL80211_IFTYPE_MONITOR: - return wl_cfg80211_add_monitor_if(name); - case NL80211_IFTYPE_P2P_CLIENT: - case NL80211_IFTYPE_STATION: - wlif_type = WL_P2P_IF_CLIENT; - mode = WL_MODE_BSS; - break; - case NL80211_IFTYPE_P2P_GO: - case NL80211_IFTYPE_AP: - wlif_type = WL_P2P_IF_GO; - mode = WL_MODE_AP; - break; - default: - WL_ERR(("Unsupported interface type\n")); - return NULL; - break; - } - - if (!name) { - WL_ERR(("name is NULL\n")); - return NULL; - } - if (wl->p2p_supported && (wlif_type != -1)) { - if (wl_get_p2p_status(wl, IF_DELETING)) { - /* wait till IF_DEL is complete - * release the lock for the unregister to proceed - */ - if (rtnl_is_locked()) { - rtnl_unlock(); - rollback_lock = true; - } - WL_INFO(("%s: Released the lock and wait till IF_DEL is complete\n", - __func__)); - timeout = wait_event_interruptible_timeout(wl->netif_change_event, - (wl_get_p2p_status(wl, IF_DELETING) == false), - msecs_to_jiffies(MAX_WAIT_TIME)); - - /* put back the rtnl_lock again */ - if (rollback_lock) { - rtnl_lock(); - rollback_lock = false; - } - if (timeout > 0) { - WL_ERR(("IF DEL is Success\n")); - - } else { - WL_ERR(("timeount < 0, return -EAGAIN\n")); - return ERR_PTR(-EAGAIN); - } - /* It should be now be safe to put this check here since we are sure - * by now netdev_notifier (unregister) would have been called */ - if (wl->iface_cnt == IFACE_MAX_CNT) - return ERR_PTR(-ENOMEM); - } - if (wl->p2p && !wl->p2p->on && strstr(name, WL_P2P_INTERFACE_PREFIX)) { - p2p_on(wl) = true; - wl_cfgp2p_set_firm_p2p(wl); - wl_cfgp2p_init_discovery(wl); - get_primary_mac(wl, &primary_mac); - wl_cfgp2p_generate_bss_mac(&primary_mac, - &wl->p2p->dev_addr, &wl->p2p->int_addr); - } - - memset(wl->p2p->vir_ifname, 0, IFNAMSIZ); - strncpy(wl->p2p->vir_ifname, name, IFNAMSIZ - 1); - - wldev_iovar_setint(_ndev, "mpc", 0); - wl_notify_escan_complete(wl, _ndev, true, true); - /* In concurrency case, STA may be already associated in a particular channel. - * so retrieve the current channel of primary interface and then start the virtual - * interface on that. - */ - chspec = wl_cfg80211_get_shared_freq(wiphy); - - /* For P2P mode, use P2P-specific driver features to create the - * bss: "wl p2p_ifadd" - */ - wl_set_p2p_status(wl, IF_ADD); - err = wl_cfgp2p_ifadd(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec); - - if (unlikely(err)) { - WL_ERR((" virtual iface add failed (%d) \n", err)); - return ERR_PTR(-ENOMEM); - } - - timeout = wait_event_interruptible_timeout(wl->netif_change_event, - (wl_get_p2p_status(wl, IF_ADD) == false), - msecs_to_jiffies(MAX_WAIT_TIME)); - if (timeout > 0 && (!wl_get_p2p_status(wl, IF_ADD))) { - - struct wireless_dev *vwdev; - vwdev = kzalloc(sizeof(*vwdev), GFP_KERNEL); - if (unlikely(!vwdev)) { - WL_ERR(("Could not allocate wireless device\n")); - return ERR_PTR(-ENOMEM); - } - vwdev->wiphy = wl->wdev->wiphy; - WL_INFO((" virtual interface(%s) is created memalloc done \n", - wl->p2p->vir_ifname)); - vwdev->iftype = type; - _ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION); - _ndev->ieee80211_ptr = vwdev; - SET_NETDEV_DEV(_ndev, wiphy_dev(vwdev->wiphy)); - vwdev->netdev = _ndev; - wl_set_drv_status(wl, READY, _ndev); - wl->p2p->vif_created = true; - wl_set_mode_by_netdev(wl, _ndev, mode); - net_attach = wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION); - if (rtnl_is_locked()) { - rtnl_unlock(); - rollback_lock = true; - } - if (net_attach && !net_attach(wl->pub, _ndev->ifindex)) { - wl_alloc_netinfo(wl, _ndev, vwdev, mode); - WL_ERR((" virtual interface(%s) is " - "created net attach done\n", wl->p2p->vir_ifname)); -#if defined(WL_ENABLE_P2P_IF) - if (type == NL80211_IFTYPE_P2P_CLIENT) - dhd_mode = P2P_GC_ENABLED; - else if (type == NL80211_IFTYPE_P2P_GO) - dhd_mode = P2P_GO_ENABLED; - DNGL_FUNC(dhd_cfg80211_set_p2p_info, (wl, dhd_mode)); -#endif /* (WL_ENABLE_P2P_IF) */ - /* Start the P2P I/F with PM disabled. Enable PM from - * the framework - */ - if ((type == NL80211_IFTYPE_P2P_CLIENT) || ( - type == NL80211_IFTYPE_P2P_GO)) - vwdev->ps = NL80211_PS_DISABLED; - } else { - /* put back the rtnl_lock again */ - if (rollback_lock) - rtnl_lock(); - goto fail; - } - /* put back the rtnl_lock again */ - if (rollback_lock) - rtnl_lock(); - return _ndev; - - } else { - wl_clr_p2p_status(wl, IF_ADD); - WL_ERR((" virtual interface(%s) is not created \n", wl->p2p->vir_ifname)); - memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ); - wl->p2p->vif_created = false; - } - } -fail: - return ERR_PTR(-ENODEV); -} - -static s32 -wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev) -{ - struct ether_addr p2p_mac; - struct wl_priv *wl = wiphy_priv(wiphy); - s32 timeout = -1; - s32 ret = 0; - WL_DBG(("Enter\n")); - - if (wl->p2p_net == dev) { - /* Since there is no ifidx corresponding to p2p0, cmds to - * firmware should be routed through primary I/F - */ - dev = wl_to_prmry_ndev(wl); - } - - if (wl->p2p_supported) { - memcpy(p2p_mac.octet, wl->p2p->int_addr.octet, ETHER_ADDR_LEN); - - /* Clear GO_NEG_PHASE bit to take care of GO-NEG-FAIL cases - */ - WL_DBG(("P2P: GO_NEG_PHASE status cleared ")); - wl_clr_p2p_status(wl, GO_NEG_PHASE); - if (wl->p2p->vif_created) { - if (wl_get_drv_status(wl, SCANNING, dev)) { - wl_notify_escan_complete(wl, dev, true, true); - } - wldev_iovar_setint(dev, "mpc", 1); - wl_set_p2p_status(wl, IF_DELETING); - ret = wl_cfgp2p_ifdel(wl, &p2p_mac); - /* Firmware could not delete the interface so we will not get WLC_E_IF - * event for cleaning the dhd virtual nw interace - * So lets do it here. Failures from fw will ensure the application to do - * ifconfig down and up sequnce, which will reload the fw - * however we should cleanup the linux network virtual interfaces - */ - /* Request framework to RESET and clean up */ - if (ret) { - struct net_device *ndev = wl_to_prmry_ndev(wl); - WL_ERR(("Firmware returned an error (%d) from p2p_ifdel" - "HANG Notification sent to %s\n", ret, ndev->name)); - wl_cfg80211_hang(ndev, WLAN_REASON_DRIVER_ERROR); - } - - /* Wait for any pending scan req to get aborted from the sysioc context */ - timeout = wait_event_interruptible_timeout(wl->netif_change_event, - (wl->p2p->vif_created == false), - msecs_to_jiffies(MAX_WAIT_TIME)); - if (timeout > 0 && (wl->p2p->vif_created == false)) { - WL_DBG(("IFDEL operation done\n")); -#if defined(WL_ENABLE_P2P_IF) - DNGL_FUNC(dhd_cfg80211_clean_p2p_info, (wl)); -#endif /* (WL_ENABLE_P2P_IF)) */ - } else { - WL_ERR(("IFDEL didn't complete properly\n")); - } - ret = dhd_del_monitor(dev); - } - } - return ret; -} - -static s32 -wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev, - enum nl80211_iftype type, u32 *flags, - struct vif_params *params) -{ - s32 ap = 0; - s32 infra = 0; - s32 err = BCME_OK; - s32 timeout = -1; - s32 wlif_type; - s32 mode = 0; - chanspec_t chspec; - struct wl_priv *wl = wiphy_priv(wiphy); - - WL_DBG(("Enter type %d\n", type)); - switch (type) { - case NL80211_IFTYPE_MONITOR: - case NL80211_IFTYPE_WDS: - case NL80211_IFTYPE_MESH_POINT: - ap = 1; - WL_ERR(("type (%d) : currently we do not support this type\n", - type)); - break; - case NL80211_IFTYPE_ADHOC: - mode = WL_MODE_IBSS; - break; - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_P2P_CLIENT: - mode = WL_MODE_BSS; - infra = 1; - break; - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_AP_VLAN: - case NL80211_IFTYPE_P2P_GO: - mode = WL_MODE_AP; - ap = 1; - break; - default: - return -EINVAL; - } - WL_DBG(("%s : ap (%d), infra (%d), iftype: (%d)\n", ndev->name, ap, infra, type)); - - if (ap) { - wl_set_mode_by_netdev(wl, ndev, mode); - if (wl->p2p_supported && wl->p2p->vif_created) { - WL_DBG(("p2p_vif_created (%d) p2p_on (%d)\n", wl->p2p->vif_created, - p2p_on(wl))); - wldev_iovar_setint(ndev, "mpc", 0); - wl_notify_escan_complete(wl, ndev, true, true); - - /* In concurrency case, STA may be already associated in a particular - * channel. so retrieve the current channel of primary interface and - * then start the virtual interface on that. - */ - chspec = wl_cfg80211_get_shared_freq(wiphy); - - wlif_type = WL_P2P_IF_GO; - WL_ERR(("%s : ap (%d), infra (%d), iftype: (%d)\n", - ndev->name, ap, infra, type)); - wl_set_p2p_status(wl, IF_CHANGING); - wl_clr_p2p_status(wl, IF_CHANGED); - err = wl_cfgp2p_ifchange(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec); - timeout = wait_event_interruptible_timeout(wl->netif_change_event, - (wl_get_p2p_status(wl, IF_CHANGED) == true), - msecs_to_jiffies(MAX_WAIT_TIME)); - wl_set_mode_by_netdev(wl, ndev, mode); - wl_clr_p2p_status(wl, IF_CHANGING); - wl_clr_p2p_status(wl, IF_CHANGED); - } else if (ndev == wl_to_prmry_ndev(wl) && - !wl_get_drv_status(wl, AP_CREATED, ndev)) { - wl_set_drv_status(wl, AP_CREATING, ndev); - if (!wl->ap_info && - !(wl->ap_info = kzalloc(sizeof(struct ap_info), GFP_KERNEL))) { - WL_ERR(("struct ap_saved_ie allocation failed\n")); - return -ENOMEM; - } - } else { - WL_ERR(("Cannot change the interface for GO or SOFTAP\n")); - return -EINVAL; - } - } else { - infra = htod32(infra); - err = wldev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(s32), true); - if (err) { - WL_ERR(("WLC_SET_INFRA error (%d)\n", err)); - return -EAGAIN; - } - wl_set_mode_by_netdev(wl, ndev, mode); - } - - ndev->ieee80211_ptr->iftype = type; - return 0; -} - -s32 -wl_cfg80211_notify_ifadd(struct net_device *ndev, s32 idx, s32 bssidx, - void* _net_attach) -{ - struct wl_priv *wl = wlcfg_drv_priv; - s32 ret = BCME_OK; - WL_DBG(("Enter")); - if (!ndev) { - WL_ERR(("net is NULL\n")); - return 0; - } - if (wl->p2p_supported && wl_get_p2p_status(wl, IF_ADD)) { - WL_DBG(("IF_ADD event called from dongle, old interface name: %s," - "new name: %s\n", ndev->name, wl->p2p->vir_ifname)); - /* Assign the net device to CONNECT BSSCFG */ - strncpy(ndev->name, wl->p2p->vir_ifname, IFNAMSIZ - 1); - wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = ndev; - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) = bssidx; - wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION) = _net_attach; - ndev->ifindex = idx; - wl_clr_p2p_status(wl, IF_ADD); - - wake_up_interruptible(&wl->netif_change_event); - } else { - ret = BCME_NOTREADY; - } - return ret; -} - -s32 -wl_cfg80211_notify_ifdel(void) -{ - struct wl_priv *wl = wlcfg_drv_priv; - - WL_DBG(("Enter \n")); - wl_clr_p2p_status(wl, IF_DELETING); - wake_up_interruptible(&wl->netif_change_event); - return 0; -} - -s32 -wl_cfg80211_ifdel_ops(struct net_device *ndev) -{ - struct wl_priv *wl = wlcfg_drv_priv; - bool rollback_lock = false; - s32 index = 0; - - if (!ndev || !ndev->name) { - WL_ERR(("net is NULL\n")); - return 0; - } - - if (p2p_is_on(wl) && wl->p2p->vif_created && - wl_get_p2p_status(wl, IF_DELETING)) { - if (wl->scan_request && - (wl->escan_info.ndev == ndev)) { - /* Abort any pending scan requests */ - wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE; - if (!rtnl_is_locked()) { - rtnl_lock(); - rollback_lock = true; - } - WL_DBG(("ESCAN COMPLETED\n")); - wl_notify_escan_complete(wl, ndev, true, false); - if (rollback_lock) - rtnl_unlock(); - } - WL_ERR(("IF_DEL event called from dongle, net %x, vif name: %s\n", - (unsigned int)ndev, wl->p2p->vir_ifname)); - - memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ); - index = wl_cfgp2p_find_idx(wl, ndev); - wl_to_p2p_bss_ndev(wl, index) = NULL; - wl_to_p2p_bss_bssidx(wl, index) = 0; - wl->p2p->vif_created = false; - wl_cfgp2p_clear_management_ie(wl, - index); - WL_DBG(("index : %d\n", index)); - - } - - /* Wake up any waiting thread */ - wake_up_interruptible(&wl->netif_change_event); - - return 0; -} - -s32 -wl_cfg80211_is_progress_ifadd(void) -{ - s32 is_progress = 0; - struct wl_priv *wl = wlcfg_drv_priv; - if (wl_get_p2p_status(wl, IF_ADD)) - is_progress = 1; - return is_progress; -} - -s32 -wl_cfg80211_is_progress_ifchange(void) -{ - s32 is_progress = 0; - struct wl_priv *wl = wlcfg_drv_priv; - if (wl_get_p2p_status(wl, IF_CHANGING)) - is_progress = 1; - return is_progress; -} - - -s32 -wl_cfg80211_notify_ifchange(void) -{ - struct wl_priv *wl = wlcfg_drv_priv; - if (wl_get_p2p_status(wl, IF_CHANGING)) { - wl_set_p2p_status(wl, IF_CHANGED); - wake_up_interruptible(&wl->netif_change_event); - } - return 0; -} - -static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_request *request) -{ - u32 n_ssids; - u32 n_channels; - u16 channel; - chanspec_t chanspec; - s32 i, offset; - char *ptr; - wlc_ssid_t ssid; - - memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN); - params->bss_type = DOT11_BSSTYPE_ANY; - params->scan_type = 0; - params->nprobes = -1; - params->active_time = -1; - params->passive_time = -1; - params->home_time = -1; - params->channel_num = 0; - memset(¶ms->ssid, 0, sizeof(wlc_ssid_t)); - - WL_SCAN(("Preparing Scan request\n")); - WL_SCAN(("nprobes=%d\n", params->nprobes)); - WL_SCAN(("active_time=%d\n", params->active_time)); - WL_SCAN(("passive_time=%d\n", params->passive_time)); - WL_SCAN(("home_time=%d\n", params->home_time)); - WL_SCAN(("scan_type=%d\n", params->scan_type)); - - params->nprobes = htod32(params->nprobes); - params->active_time = htod32(params->active_time); - params->passive_time = htod32(params->passive_time); - params->home_time = htod32(params->home_time); - - /* if request is null just exit so it will be all channel broadcast scan */ - if (!request) - return; - - n_ssids = request->n_ssids; - n_channels = request->n_channels; - - /* Copy channel array if applicable */ - WL_SCAN(("### List of channelspecs to scan ###\n")); - if (n_channels > 0) { - for (i = 0; i < n_channels; i++) { - chanspec = 0; - channel = ieee80211_frequency_to_channel(request->channels[i]->center_freq); - if (request->channels[i]->band == IEEE80211_BAND_2GHZ) - chanspec |= WL_CHANSPEC_BAND_2G; - else - chanspec |= WL_CHANSPEC_BAND_5G; - - if (request->channels[i]->flags & IEEE80211_CHAN_NO_HT40) { - chanspec |= WL_CHANSPEC_BW_20; - chanspec |= WL_CHANSPEC_CTL_SB_NONE; - } else { - chanspec |= WL_CHANSPEC_BW_40; - if (request->channels[i]->flags & IEEE80211_CHAN_NO_HT40PLUS) - chanspec |= WL_CHANSPEC_CTL_SB_LOWER; - else - chanspec |= WL_CHANSPEC_CTL_SB_UPPER; - } - - params->channel_list[i] = channel; - params->channel_list[i] &= WL_CHANSPEC_CHAN_MASK; - params->channel_list[i] |= chanspec; - WL_SCAN(("Chan : %d, Channel spec: %x \n", - channel, params->channel_list[i])); - params->channel_list[i] = htod16(params->channel_list[i]); - } - } else { - WL_SCAN(("Scanning all channels\n")); - } - - /* Copy ssid array if applicable */ - WL_SCAN(("### List of SSIDs to scan ###\n")); - if (n_ssids > 0) { - offset = offsetof(wl_scan_params_t, channel_list) + n_channels * sizeof(u16); - offset = roundup(offset, sizeof(u32)); - ptr = (char*)params + offset; - for (i = 0; i < n_ssids; i++) { - memset(&ssid, 0, sizeof(wlc_ssid_t)); - ssid.SSID_len = request->ssids[i].ssid_len; - memcpy(ssid.SSID, request->ssids[i].ssid, ssid.SSID_len); - if (!ssid.SSID_len) - WL_SCAN(("%d: Broadcast scan\n", i)); - else - WL_SCAN(("%d: scan for %s size =%d\n", i, - ssid.SSID, ssid.SSID_len)); - memcpy(ptr, &ssid, sizeof(wlc_ssid_t)); - ptr += sizeof(wlc_ssid_t); - } - } else { - WL_SCAN(("Broadcast scan\n")); - } - /* Adding mask to channel numbers */ - params->channel_num = - htod32((n_ssids << WL_SCAN_PARAMS_NSSID_SHIFT) | - (n_channels & WL_SCAN_PARAMS_COUNT_MASK)); -} - -static s32 -wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request, u16 action) -{ - u32 n_channels; - u32 n_ssids; - s32 params_size = - (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params)); - struct wl_iscan_params *params; - s32 err = 0; - - if (request != NULL) { - n_channels = request->n_channels; - n_ssids = request->n_ssids; - /* Allocate space for populating ssids in wl_iscan_params struct */ - if (n_channels % 2) - /* If n_channels is odd, add a padd of u16 */ - params_size += sizeof(u16) * (n_channels + 1); - else - params_size += sizeof(u16) * n_channels; - - /* Allocate space for populating ssids in wl_iscan_params struct */ - params_size += sizeof(struct wlc_ssid) * n_ssids; - } - params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL); - if (!params) { - return -ENOMEM; - } - - wl_scan_prep(¶ms->params, request); - - params->version = htod32(ISCAN_REQ_VERSION); - params->action = htod16(action); - params->scan_duration = htod16(0); - - if (params_size + sizeof("iscan") >= WLC_IOCTL_MEDLEN) { - WL_ERR(("ioctl buffer length is not sufficient\n")); - err = -ENOMEM; - goto done; - } - err = wldev_iovar_setbuf(iscan->dev, "iscan", params, params_size, - iscan->ioctl_buf, WLC_IOCTL_MEDLEN, NULL); - if (unlikely(err)) { - if (err == -EBUSY) { - WL_ERR(("system busy : iscan canceled\n")); - } else { - WL_ERR(("error (%d)\n", err)); - } - } -done: - kfree(params); - return err; -} - -static s32 wl_do_iscan(struct wl_priv *wl, struct cfg80211_scan_request *request) -{ - struct wl_iscan_ctrl *iscan = wl_to_iscan(wl); - struct net_device *ndev = wl_to_prmry_ndev(wl); - s32 passive_scan; - s32 err = 0; - - iscan->state = WL_ISCAN_STATE_SCANING; - - passive_scan = wl->active_scan ? 0 : 1; - err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN, - &passive_scan, sizeof(passive_scan), false); - if (unlikely(err)) { - WL_DBG(("error (%d)\n", err)); - return err; - } - wl->iscan_kickstart = true; - wl_run_iscan(iscan, request, WL_SCAN_ACTION_START); - mod_timer(&iscan->timer, jiffies + msecs_to_jiffies(iscan->timer_ms)); - iscan->timer_on = 1; - - return err; -} - -static s32 -wl_get_valid_channels(struct net_device *ndev, u8 *valid_chan_list, s32 size) -{ - wl_uint32_list_t *list; - s32 err = BCME_OK; - if (valid_chan_list == NULL || size <= 0) - return -ENOMEM; - - memset(valid_chan_list, 0, size); - list = (wl_uint32_list_t *)(void *) valid_chan_list; - list->count = htod32(WL_NUMCHANNELS); - err = wldev_ioctl(ndev, WLC_GET_VALID_CHANNELS, valid_chan_list, size, false); - if (err != 0) { - WL_ERR(("get channels failed with %d\n", err)); - } - - return err; -} - -static s32 -wl_run_escan(struct wl_priv *wl, struct net_device *ndev, - struct cfg80211_scan_request *request, uint16 action) -{ - s32 err = BCME_OK; - u32 n_channels; - u32 n_ssids; - s32 params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_escan_params_t, params)); - wl_escan_params_t *params = NULL; - struct cfg80211_scan_request *scan_request = wl->scan_request; - u8 chan_buf[sizeof(u32)*(WL_NUMCHANNELS + 1)]; - u32 num_chans = 0; - s32 channel; - s32 n_valid_chan; - s32 search_state = WL_P2P_DISC_ST_SCAN; - u32 i, j, n_nodfs = 0; - u16 *default_chan_list = NULL; - wl_uint32_list_t *list; - struct net_device *dev = NULL; - WL_DBG(("Enter \n")); - - - if (!wl->p2p_supported || ((ndev == wl_to_prmry_ndev(wl)) && - !p2p_scan(wl))) { - /* LEGACY SCAN TRIGGER */ - WL_SCAN((" LEGACY E-SCAN START\n")); - - if (request != NULL) { - n_channels = request->n_channels; - n_ssids = request->n_ssids; - /* Allocate space for populating ssids in wl_iscan_params struct */ - if (n_channels % 2) - /* If n_channels is odd, add a padd of u16 */ - params_size += sizeof(u16) * (n_channels + 1); - else - params_size += sizeof(u16) * n_channels; - - /* Allocate space for populating ssids in wl_iscan_params struct */ - params_size += sizeof(struct wlc_ssid) * n_ssids; - } - params = (wl_escan_params_t *) kzalloc(params_size, GFP_KERNEL); - if (params == NULL) { - err = -ENOMEM; - goto exit; - } - - wl_scan_prep(¶ms->params, request); - params->version = htod32(ESCAN_REQ_VERSION); - params->action = htod16(action); - params->sync_id = htod16(0x1234); - if (params_size + sizeof("escan") >= WLC_IOCTL_MEDLEN) { - WL_ERR(("ioctl buffer length not sufficient\n")); - kfree(params); - err = -ENOMEM; - goto exit; - } - err = wldev_iovar_setbuf(ndev, "escan", params, params_size, - wl->escan_ioctl_buf, WLC_IOCTL_MEDLEN, NULL); - if (unlikely(err)) - WL_ERR((" Escan set error (%d)\n", err)); - kfree(params); - } - else if (p2p_is_on(wl) && p2p_scan(wl)) { - /* P2P SCAN TRIGGER */ - s32 _freq = 0; - n_nodfs = 0; - if (scan_request && scan_request->n_channels) { - num_chans = scan_request->n_channels; - WL_SCAN((" chann number : %d\n", num_chans)); - default_chan_list = kzalloc(num_chans * sizeof(*default_chan_list), - GFP_KERNEL); - if (default_chan_list == NULL) { - WL_ERR(("channel list allocation failed \n")); - err = -ENOMEM; - goto exit; - } - if (!wl_get_valid_channels(ndev, chan_buf, sizeof(chan_buf))) { - list = (wl_uint32_list_t *) chan_buf; - n_valid_chan = dtoh32(list->count); - for (i = 0; i < num_chans; i++) - { - _freq = scan_request->channels[i]->center_freq; - channel = ieee80211_frequency_to_channel(_freq); - /* remove DFS channels */ - if (channel < 52 || channel > 140) { - for (j = 0; j < n_valid_chan; j++) { - /* allows only supported channel on - * current reguatory - */ - if (channel == (dtoh32(list->element[j]))) - default_chan_list[n_nodfs++] = - channel; - } - } - - } - } - if (num_chans == 3 && ( - (default_chan_list[0] == SOCIAL_CHAN_1) && - (default_chan_list[1] == SOCIAL_CHAN_2) && - (default_chan_list[2] == SOCIAL_CHAN_3))) { - /* SOCIAL CHANNELS 1, 6, 11 */ - search_state = WL_P2P_DISC_ST_SEARCH; - WL_INFO(("P2P SEARCH PHASE START \n")); - } else if ((dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION)) && - (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP)) { - /* If you are already a GO, then do SEARCH only */ - WL_INFO(("Already a GO. Do SEARCH Only")); - search_state = WL_P2P_DISC_ST_SEARCH; - num_chans = n_nodfs; - - } else { - WL_INFO(("P2P SCAN STATE START \n")); - num_chans = n_nodfs; - } - - } - err = wl_cfgp2p_escan(wl, ndev, wl->active_scan, num_chans, default_chan_list, - search_state, action, - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); - kfree(default_chan_list); - } -exit: - if (unlikely(err)) { - WL_ERR(("error (%d)\n", err)); - } - return err; -} - - -static s32 -wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev, - struct cfg80211_scan_request *request) -{ - s32 err = BCME_OK; - s32 passive_scan; - wl_scan_results_t *results; - WL_SCAN(("Enter \n")); - - mutex_lock(&wl->usr_sync); - wl->escan_info.ndev = ndev; - wl->escan_info.wiphy = wiphy; - wl->escan_info.escan_state = WL_ESCAN_STATE_SCANING; - passive_scan = wl->active_scan ? 0 : 1; - err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN, - &passive_scan, sizeof(passive_scan), false); - if (unlikely(err)) { - WL_ERR(("error (%d)\n", err)); - goto exit; - } - results = (wl_scan_results_t *) wl->escan_info.escan_buf; - results->version = 0; - results->count = 0; - results->buflen = WL_SCAN_RESULTS_FIXED_SIZE; - - err = wl_run_escan(wl, ndev, request, WL_SCAN_ACTION_START); -exit: - mutex_unlock(&wl->usr_sync); - return err; -} - -static s32 -__wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, - struct cfg80211_scan_request *request, - struct cfg80211_ssid *this_ssid) -{ - struct wl_priv *wl = wiphy_priv(wiphy); - struct cfg80211_ssid *ssids; - struct wl_scan_req *sr = wl_to_sr(wl); - struct ether_addr primary_mac; - wpa_ie_fixed_t *wps_ie; - s32 passive_scan; - bool iscan_req; - bool escan_req = false; - bool p2p_ssid; - s32 err = 0; - s32 i; - u32 wpsie_len = 0; - u8 wpsie[IE_MAX_LEN]; - - /* If scan req comes for p2p0, send it over primary I/F - * Scan results will be delivered corresponding to cfg80211_scan_request - */ - if (ndev == wl->p2p_net) { - ndev = wl_to_prmry_ndev(wl); - } - - WL_DBG(("Enter wiphy (%p)\n", wiphy)); - if (wl_get_drv_status_all(wl, SCANNING)) { - WL_ERR(("Scanning already\n")); - return -EAGAIN; - } - if (wl_get_drv_status(wl, SCAN_ABORTING, ndev)) { - WL_ERR(("Scanning being aborted\n")); - return -EAGAIN; - } - if (request && request->n_ssids > WL_SCAN_PARAMS_SSID_MAX) { - WL_ERR(("request null or n_ssids > WL_SCAN_PARAMS_SSID_MAX\n")); - return -EOPNOTSUPP; - } - - /* Arm scan timeout timer */ - mod_timer(&wl->scan_timeout, jiffies + msecs_to_jiffies(WL_SCAN_TIMER_INTERVAL_MS)); - iscan_req = false; - if (request) { /* scan bss */ - ssids = request->ssids; - if (wl->iscan_on && (!ssids || !ssids->ssid_len || request->n_ssids != 1)) { - iscan_req = true; - } else if (wl->escan_on) { - escan_req = true; - p2p_ssid = false; - for (i = 0; i < request->n_ssids; i++) { - if (ssids[i].ssid_len && IS_P2P_SSID(ssids[i].ssid)) { - p2p_ssid = true; - break; - } - } - if (p2p_ssid) { - if (wl->p2p_supported) { - /* p2p scan trigger */ - if (p2p_on(wl) == false) { - /* p2p on at the first time */ - p2p_on(wl) = true; - wl_cfgp2p_set_firm_p2p(wl); - get_primary_mac(wl, &primary_mac); - wl_cfgp2p_generate_bss_mac(&primary_mac, - &wl->p2p->dev_addr, &wl->p2p->int_addr); - } - wl_clr_p2p_status(wl, GO_NEG_PHASE); - WL_DBG(("P2P: GO_NEG_PHASE status cleared \n")); - p2p_scan(wl) = true; - } - } else { - /* legacy scan trigger - * So, we have to disable p2p discovery if p2p discovery is on - */ - if (wl->p2p_supported) { - p2p_scan(wl) = false; - /* If Netdevice is not equals to primary and p2p is on - * , we will do p2p scan using P2PAPI_BSSCFG_DEVICE. - */ - if (p2p_on(wl) && (ndev != wl_to_prmry_ndev(wl))) - p2p_scan(wl) = true; - - if (p2p_scan(wl) == false) { - if (wl_get_p2p_status(wl, DISCOVERY_ON)) { - err = wl_cfgp2p_discover_enable_search(wl, - false); - if (unlikely(err)) { - goto scan_out; - } - - } - } - } - if (!wl->p2p_supported || !p2p_scan(wl)) { - if (ndev == wl_to_prmry_ndev(wl)) { - /* find the WPSIE */ - memset(wpsie, 0, sizeof(wpsie)); - if ((wps_ie = wl_cfgp2p_find_wpsie( - (u8 *)request->ie, - request->ie_len)) != NULL) { - wpsie_len = - wps_ie->length + WPA_RSN_IE_TAG_FIXED_LEN; - memcpy(wpsie, wps_ie, wpsie_len); - } else { - wpsie_len = 0; - } - if (wpsie_len > 0) { - err = wl_cfgp2p_set_management_ie(wl, - ndev, -1, VNDR_IE_PRBREQ_FLAG, - wpsie, wpsie_len); - if (unlikely(err)) { - goto scan_out; - } - } - } - } - } - } - } else { /* scan in ibss */ - /* we don't do iscan in ibss */ - ssids = this_ssid; - } - wl->scan_request = request; - wl_set_drv_status(wl, SCANNING, ndev); - if (iscan_req) { - err = wl_do_iscan(wl, request); - if (likely(!err)) - return err; - else - goto scan_out; - } else if (escan_req) { - if (wl->p2p_supported) { - if (p2p_on(wl) && p2p_scan(wl)) { - - err = wl_cfgp2p_enable_discovery(wl, ndev, - request->ie, request->ie_len); - - if (unlikely(err)) { - goto scan_out; - } - } - } - err = wl_do_escan(wl, wiphy, ndev, request); - if (likely(!err)) - return err; - else - goto scan_out; - - - } else { - memset(&sr->ssid, 0, sizeof(sr->ssid)); - sr->ssid.SSID_len = - min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len); - if (sr->ssid.SSID_len) { - memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len); - sr->ssid.SSID_len = htod32(sr->ssid.SSID_len); - WL_SCAN(("Specific scan ssid=\"%s\" len=%d\n", - sr->ssid.SSID, sr->ssid.SSID_len)); - } else { - WL_SCAN(("Broadcast scan\n")); - } - WL_SCAN(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len)); - passive_scan = wl->active_scan ? 0 : 1; - err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN, - &passive_scan, sizeof(passive_scan), false); - if (unlikely(err)) { - WL_SCAN(("WLC_SET_PASSIVE_SCAN error (%d)\n", err)); - goto scan_out; - } - err = wldev_ioctl(ndev, WLC_SCAN, &sr->ssid, - sizeof(sr->ssid), false); - if (err) { - if (err == -EBUSY) { - WL_ERR(("system busy : scan for \"%s\" " - "canceled\n", sr->ssid.SSID)); - } else { - WL_ERR(("WLC_SCAN error (%d)\n", err)); - } - goto scan_out; - } - } - - return 0; - -scan_out: - wl_clr_drv_status(wl, SCANNING, ndev); - if (timer_pending(&wl->scan_timeout)) - del_timer_sync(&wl->scan_timeout); - wl->scan_request = NULL; - return err; -} - -static s32 -wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, - struct cfg80211_scan_request *request) -{ - s32 err = 0; - struct wl_priv *wl = wiphy_priv(wiphy); - - WL_DBG(("Enter \n")); - CHECK_SYS_UP(wl); - - err = __wl_cfg80211_scan(wiphy, ndev, request, NULL); - if (unlikely(err)) { - WL_ERR(("scan error (%d)\n", err)); - if (err == BCME_BUSY) { - wl->scan_busy_count++; - if (wl->scan_busy_count > WL_SCAN_BUSY_MAX) { - wl->scan_busy_count = 0; - WL_ERR(("Continuous scan failures!! Exercising FW hang recovery\n")); - net_os_send_hang_message(ndev); - } - } - return err; - } - - return err; -} - -static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold) -{ - s32 err = 0; - - err = wldev_iovar_setint(dev, "rtsthresh", rts_threshold); - if (unlikely(err)) { - WL_ERR(("Error (%d)\n", err)); - return err; - } - return err; -} - -static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold) -{ - s32 err = 0; - - err = wldev_iovar_setint_bsscfg(dev, "fragthresh", frag_threshold, 0); - if (unlikely(err)) { - WL_ERR(("Error (%d)\n", err)); - return err; - } - return err; -} - -static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l) -{ - s32 err = 0; - u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL); - - retry = htod32(retry); - err = wldev_ioctl(dev, cmd, &retry, sizeof(retry), false); - if (unlikely(err)) { - WL_ERR(("cmd (%d) , error (%d)\n", cmd, err)); - return err; - } - return err; -} - -static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) -{ - struct wl_priv *wl = (struct wl_priv *)wiphy_priv(wiphy); - struct net_device *ndev = wl_to_prmry_ndev(wl); - s32 err = 0; - - CHECK_SYS_UP(wl); - WL_DBG(("Enter\n")); - if (changed & WIPHY_PARAM_RTS_THRESHOLD && - (wl->conf->rts_threshold != wiphy->rts_threshold)) { - wl->conf->rts_threshold = wiphy->rts_threshold; - err = wl_set_rts(ndev, wl->conf->rts_threshold); - if (!err) - return err; - } - if (changed & WIPHY_PARAM_FRAG_THRESHOLD && - (wl->conf->frag_threshold != wiphy->frag_threshold)) { - wl->conf->frag_threshold = wiphy->frag_threshold; - err = wl_set_frag(ndev, wl->conf->frag_threshold); - if (!err) - return err; - } - if (changed & WIPHY_PARAM_RETRY_LONG && - (wl->conf->retry_long != wiphy->retry_long)) { - wl->conf->retry_long = wiphy->retry_long; - err = wl_set_retry(ndev, wl->conf->retry_long, true); - if (!err) - return err; - } - if (changed & WIPHY_PARAM_RETRY_SHORT && - (wl->conf->retry_short != wiphy->retry_short)) { - wl->conf->retry_short = wiphy->retry_short; - err = wl_set_retry(ndev, wl->conf->retry_short, false); - if (!err) { - return err; - } - } - return err; -} - -static s32 -wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, - struct cfg80211_ibss_params *params) -{ - struct wl_priv *wl = wiphy_priv(wiphy); - struct wl_join_params join_params; - struct wlc_ssid ssid; - struct ether_addr bssid; - size_t join_params_size = 0; - s32 wsec = 0; - s32 bcnprd; - s32 err = 0; - - WL_TRACE(("In\n")); - CHECK_SYS_UP(wl); - - /* - * Cancel ongoing scan to sync up with sme state machine of cfg80211. - */ - if (wl->scan_request) { - wl_notify_escan_complete(wl, dev, true, true); - } - /* Clean BSSID */ - bzero(&bssid, sizeof(bssid)); - wl_update_prof(wl, dev, NULL, (void *)&bssid, WL_PROF_BSSID); - wl_update_prof(wl, dev, NULL, params->bssid, WL_PROF_PENDING_BSSID); - - if (params->ssid) - WL_INFO(("SSID: %s\n", params->ssid)); - else { - WL_ERR(("SSID: NULL, Not supported\n")); - err = -EOPNOTSUPP; - goto CleanUp; - } - - if (params->bssid) - WL_INFO(("BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n", - params->bssid[0], params->bssid[1], params->bssid[2], - params->bssid[3], params->bssid[4], params->bssid[5])); - - if (params->channel) - WL_INFO(("channel: %d\n", params->channel->center_freq)); - - if (params->channel_fixed) - WL_INFO(("fixed channel required\n")); - - if (params->ie && params->ie_len) - WL_INFO(("ie len: %d\n", params->ie_len)); - - if (params->beacon_interval) - WL_INFO(("beacon interval: %d\n", params->beacon_interval)); - - if (params->basic_rates) - WL_INFO(("basic rates: %08X\n", params->basic_rates)); - - if (params->privacy) - WL_INFO(("privacy required\n")); - - wl_set_drv_status(wl, CONNECTING, dev); - - /* Configure Privacy for starter */ - if (params->privacy) - wsec |= WEP_ENABLED; - - err = wldev_iovar_setint(dev, "wsec", wsec); - if (err) { - WL_ERR(("wsec failed (%d)\n", err)); - goto CleanUp; - } - - err = wldev_iovar_setint(dev, "auth", WL_AUTH_OPEN_SYSTEM); - if (err) { - WL_ERR(("auth failed (%d)\n", err)); - goto CleanUp; - } - - err = wldev_iovar_setint(dev, "wpa_auth", 0); - if (err) { - WL_ERR(("wpa_auth failed (%d)\n", err)); - goto CleanUp; - } - - /* Configure Beacon Interval for starter */ - if (params->beacon_interval) - bcnprd = params->beacon_interval; - else - bcnprd = 100; - - bcnprd = htod32(bcnprd); - err = wldev_ioctl(dev, WLC_SET_BCNPRD, &bcnprd, sizeof(bcnprd), true); - if (err) { - WL_ERR(("WLC_SET_BCNPRD failed (%d)\n", err)); - goto CleanUp; - } - - /* Configure required join parameter */ - memset(&join_params, 0, sizeof(struct wl_join_params)); - - /* SSID */ - memset(&ssid, 0, sizeof(struct wlc_ssid)); - ssid.SSID_len = MIN(params->ssid_len, 32); - join_params.ssid.SSID_len = htod32(ssid.SSID_len); - memcpy(ssid.SSID, params->ssid, ssid.SSID_len); - memcpy(join_params.ssid.SSID, params->ssid, ssid.SSID_len); - join_params_size = sizeof(join_params.ssid); - - wl_update_prof(wl, dev, NULL, &ssid, WL_PROF_SSID); - - /* BSSID */ - if (params->bssid) { - memcpy(&join_params.params.bssid, params->bssid, ETHER_ADDR_LEN); - join_params_size = sizeof(join_params.ssid) + - WL_ASSOC_PARAMS_FIXED_SIZE; - - wl_update_prof(wl, dev, NULL, params->bssid, WL_PROF_BSSID); - } else { - memcpy(&join_params.params.bssid, ðer_bcast, ETHER_ADDR_LEN); - } - - /* Channel */ - if (params->channel) { - u32 target_channel; - - target_channel = ieee80211_frequency_to_channel( - params->channel->center_freq); - if (params->channel_fixed) { - /* adding chanspec */ - wl_ch_to_chanspec(target_channel, - &join_params, &join_params_size); - } - - /* set channel for starter */ - target_channel = htod32(target_channel); - err = wldev_ioctl(dev, WLC_SET_CHANNEL, - &target_channel, sizeof(target_channel), true); - if (err) { - WL_ERR(("WLC_SET_CHANNEL failed (%d)\n", err)); - goto CleanUp; - } - } - - wl->ibss_starter = false; - - err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size, true); - if (err) { - WL_ERR(("WLC_SET_SSID failed (%d)\n", err)); - goto CleanUp; - } - -CleanUp: - - if (err) - wl_clr_drv_status(wl, CONNECTING, dev); - - WL_TRACE(("Exit\n")); - return err; -} - -static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) -{ - struct wl_priv *wl = wiphy_priv(wiphy); - scb_val_t scbval; - bool act = false; - s32 err = 0; - u8 *curbssid; - - WL_TRACE(("Enter\n")); - - CHECK_SYS_UP(wl); - act = *(bool *) wl_read_prof(wl, dev, WL_PROF_ACT); - curbssid = wl_read_prof(wl, dev, WL_PROF_BSSID); - if (act) { - /* - * Cancel ongoing scan to sync up with sme state machine of cfg80211. - */ - if (wl->scan_request) { - wl_notify_escan_complete(wl, dev, true, true); - } - wl_set_drv_status(wl, DISCONNECTING, dev); - scbval.val = DOT11_RC_DISASSOC_LEAVING; - memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN); - scbval.val = htod32(scbval.val); - err = wldev_ioctl(dev, WLC_DISASSOC, &scbval, - sizeof(scb_val_t), true); - if (unlikely(err)) { - wl_clr_drv_status(wl, DISCONNECTING, dev); - WL_ERR(("error (%d)\n", err)); - return err; - } - } - - WL_TRACE(("Exit\n")); - return err; -} - -static s32 -wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme) -{ - struct wl_priv *wl = wlcfg_drv_priv; - struct wl_security *sec; - s32 val = 0; - s32 err = 0; - s32 bssidx = wl_cfgp2p_find_idx(wl, dev); - - if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) - val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED; - else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) - val = WPA2_AUTH_PSK| WPA2_AUTH_UNSPECIFIED; - else - val = WPA_AUTH_DISABLED; - - if (is_wps_conn(sme)) - val = WPA_AUTH_DISABLED; - - WL_DBG(("setting wpa_auth to 0x%0x\n", val)); - err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx); - if (unlikely(err)) { - WL_ERR(("set wpa_auth failed (%d)\n", err)); - return err; - } - sec = wl_read_prof(wl, dev, WL_PROF_SEC); - sec->wpa_versions = sme->crypto.wpa_versions; - return err; -} - -static s32 -wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme) -{ - struct wl_priv *wl = wlcfg_drv_priv; - struct wl_security *sec; - s32 val = 0; - s32 err = 0; - s32 bssidx = wl_cfgp2p_find_idx(wl, dev); - switch (sme->auth_type) { - case NL80211_AUTHTYPE_OPEN_SYSTEM: - val = WL_AUTH_OPEN_SYSTEM; - WL_DBG(("open system\n")); - break; - case NL80211_AUTHTYPE_SHARED_KEY: - val = WL_AUTH_SHARED_KEY; - WL_DBG(("shared key\n")); - break; - case NL80211_AUTHTYPE_AUTOMATIC: - val = WL_AUTH_OPEN_SHARED; - WL_DBG(("automatic\n")); - break; - case NL80211_AUTHTYPE_NETWORK_EAP: - WL_DBG(("network eap\n")); - default: - val = WL_AUTH_OPEN_SHARED; - WL_ERR(("invalid auth type (%d)\n", sme->auth_type)); - break; - } - - err = wldev_iovar_setint_bsscfg(dev, "auth", val, bssidx); - if (unlikely(err)) { - WL_ERR(("set auth failed (%d)\n", err)); - return err; - } - sec = wl_read_prof(wl, dev, WL_PROF_SEC); - sec->auth_type = sme->auth_type; - return err; -} - -static s32 -wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) -{ - struct wl_priv *wl = wlcfg_drv_priv; - struct wl_security *sec; - s32 pval = 0; - s32 gval = 0; - s32 err = 0; - s32 bssidx = wl_cfgp2p_find_idx(wl, dev); - - if (sme->crypto.n_ciphers_pairwise) { - switch (sme->crypto.ciphers_pairwise[0]) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - pval = WEP_ENABLED; - break; - case WLAN_CIPHER_SUITE_TKIP: - pval = TKIP_ENABLED; - break; - case WLAN_CIPHER_SUITE_CCMP: - pval = AES_ENABLED; - break; - case WLAN_CIPHER_SUITE_AES_CMAC: - pval = AES_ENABLED; - break; - default: - WL_ERR(("invalid cipher pairwise (%d)\n", - sme->crypto.ciphers_pairwise[0])); - return -EINVAL; - } - } - if (sme->crypto.cipher_group) { - switch (sme->crypto.cipher_group) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - gval = WEP_ENABLED; - break; - case WLAN_CIPHER_SUITE_TKIP: - gval = TKIP_ENABLED; - break; - case WLAN_CIPHER_SUITE_CCMP: - gval = AES_ENABLED; - break; - case WLAN_CIPHER_SUITE_AES_CMAC: - gval = AES_ENABLED; - break; - default: - WL_ERR(("invalid cipher group (%d)\n", - sme->crypto.cipher_group)); - return -EINVAL; - } - } - - WL_DBG(("pval (%d) gval (%d)\n", pval, gval)); - - if (is_wps_conn(sme)) { - if (sme->privacy) - err = wldev_iovar_setint_bsscfg(dev, "wsec", 4, bssidx); - else - /* WPS-2.0 allowes no security */ - err = wldev_iovar_setint_bsscfg(dev, "wsec", 0, bssidx); - } else { - WL_DBG((" NO, is_wps_conn, Set pval | gval to WSEC")); - err = wldev_iovar_setint_bsscfg(dev, "wsec", - pval | gval, bssidx); - } - if (unlikely(err)) { - WL_ERR(("error (%d)\n", err)); - return err; - } - - sec = wl_read_prof(wl, dev, WL_PROF_SEC); - sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0]; - sec->cipher_group = sme->crypto.cipher_group; - - return err; -} - -static s32 -wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme) -{ - struct wl_priv *wl = wlcfg_drv_priv; - struct wl_security *sec; - s32 val = 0; - s32 err = 0; - s32 bssidx = wl_cfgp2p_find_idx(wl, dev); - - if (sme->crypto.n_akm_suites) { - err = wldev_iovar_getint(dev, "wpa_auth", &val); - if (unlikely(err)) { - WL_ERR(("could not get wpa_auth (%d)\n", err)); - return err; - } - if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) { - switch (sme->crypto.akm_suites[0]) { - case WLAN_AKM_SUITE_8021X: - val = WPA_AUTH_UNSPECIFIED; - break; - case WLAN_AKM_SUITE_PSK: - val = WPA_AUTH_PSK; - break; - default: - WL_ERR(("invalid cipher group (%d)\n", - sme->crypto.cipher_group)); - return -EINVAL; - } - } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) { - switch (sme->crypto.akm_suites[0]) { - case WLAN_AKM_SUITE_8021X: - val = WPA2_AUTH_UNSPECIFIED; - break; - case WLAN_AKM_SUITE_PSK: - val = WPA2_AUTH_PSK; - break; - default: - WL_ERR(("invalid cipher group (%d)\n", - sme->crypto.cipher_group)); - return -EINVAL; - } - } - WL_DBG(("setting wpa_auth to %d\n", val)); - - err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx); - if (unlikely(err)) { - WL_ERR(("could not set wpa_auth (%d)\n", err)); - return err; - } - } - sec = wl_read_prof(wl, dev, WL_PROF_SEC); - sec->wpa_auth = sme->crypto.akm_suites[0]; - - return err; -} - -static s32 -wl_set_set_sharedkey(struct net_device *dev, - struct cfg80211_connect_params *sme) -{ - struct wl_priv *wl = wlcfg_drv_priv; - struct wl_security *sec; - struct wl_wsec_key key; - s32 val; - s32 err = 0; - s32 bssidx = wl_cfgp2p_find_idx(wl, dev); - - WL_DBG(("key len (%d)\n", sme->key_len)); - if (sme->key_len) { - sec = wl_read_prof(wl, dev, WL_PROF_SEC); - WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n", - sec->wpa_versions, sec->cipher_pairwise)); - if (!(sec->wpa_versions & (NL80211_WPA_VERSION_1 | - NL80211_WPA_VERSION_2)) && - (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 | - WLAN_CIPHER_SUITE_WEP104))) - { - memset(&key, 0, sizeof(key)); - key.len = (u32) sme->key_len; - key.index = (u32) sme->key_idx; - if (unlikely(key.len > sizeof(key.data))) { - WL_ERR(("Too long key length (%u)\n", key.len)); - return -EINVAL; - } - memcpy(key.data, sme->key, key.len); - key.flags = WL_PRIMARY_KEY; - switch (sec->cipher_pairwise) { - case WLAN_CIPHER_SUITE_WEP40: - key.algo = CRYPTO_ALGO_WEP1; - break; - case WLAN_CIPHER_SUITE_WEP104: - key.algo = CRYPTO_ALGO_WEP128; - break; - default: - WL_ERR(("Invalid algorithm (%d)\n", - sme->crypto.ciphers_pairwise[0])); - return -EINVAL; - } - /* Set the new key/index */ - WL_DBG(("key length (%d) key index (%d) algo (%d)\n", - key.len, key.index, key.algo)); - WL_DBG(("key \"%s\"\n", key.data)); - swap_key_from_BE(&key); - err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), - wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); - if (unlikely(err)) { - WL_ERR(("WLC_SET_KEY error (%d)\n", err)); - return err; - } - if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) { - WL_DBG(("set auth_type to shared key\n")); - val = WL_AUTH_SHARED_KEY; /* shared key */ - err = wldev_iovar_setint_bsscfg(dev, "auth", val, bssidx); - if (unlikely(err)) { - WL_ERR(("set auth failed (%d)\n", err)); - return err; - } - } - } - } - return err; -} - -static s32 -wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, - struct cfg80211_connect_params *sme) -{ - struct wl_priv *wl = wiphy_priv(wiphy); - struct ieee80211_channel *chan = sme->channel; - wl_extjoin_params_t *ext_join_params; - struct wl_join_params join_params; - size_t join_params_size; - s32 err = 0; - wpa_ie_fixed_t *wpa_ie; - wpa_ie_fixed_t *wps_ie; - bcm_tlv_t *wpa2_ie; - u8* wpaie = 0; - u32 wpaie_len = 0; - u32 wpsie_len = 0; - u32 chan_cnt = 0; - u8 wpsie[IE_MAX_LEN]; - struct ether_addr bssid; - - WL_DBG(("In\n")); - CHECK_SYS_UP(wl); - - /* - * Cancel ongoing scan to sync up with sme state machine of cfg80211. - */ - if (wl->scan_request) { - wl_notify_escan_complete(wl, dev, true, true); - } - /* Clean BSSID */ - bzero(&bssid, sizeof(bssid)); - wl_update_prof(wl, dev, NULL, (void *)&bssid, WL_PROF_BSSID); - wl_update_prof(wl, dev, NULL, sme->bssid, WL_PROF_PENDING_BSSID); - - if (IS_P2P_SSID(sme->ssid) && (dev != wl_to_prmry_ndev(wl))) { - /* we only allow to connect using virtual interface in case of P2P */ - if (p2p_is_on(wl) && is_wps_conn(sme)) { - WL_DBG(("ASSOC1 p2p index : %d sme->ie_len %d\n", - wl_cfgp2p_find_idx(wl, dev), sme->ie_len)); - /* Have to apply WPS IE + P2P IE in assoc req frame */ - wl_cfgp2p_set_management_ie(wl, dev, - wl_cfgp2p_find_idx(wl, dev), VNDR_IE_PRBREQ_FLAG, - wl_to_p2p_bss_saved_ie(wl, P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie, - wl_to_p2p_bss_saved_ie(wl, - P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len); - wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev), - VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len); - } else if (p2p_is_on(wl) && (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) { - /* This is the connect req after WPS is done [credentials exchanged] - * currently identified with WPA_VERSION_2 . - * Update the previously set IEs with - * the newly received IEs from Supplicant. This will remove the WPS IE from - * the Assoc Req. - */ - WL_DBG(("ASSOC2 p2p index : %d sme->ie_len %d\n", - wl_cfgp2p_find_idx(wl, dev), sme->ie_len)); - wl_cfgp2p_set_management_ie(wl, dev, - wl_cfgp2p_find_idx(wl, dev), VNDR_IE_PRBREQ_FLAG, - sme->ie, sme->ie_len); - wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev), - VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len); - } - - } else if (dev == wl_to_prmry_ndev(wl)) { - /* find the RSN_IE */ - if ((wpa2_ie = bcm_parse_tlvs((u8 *)sme->ie, sme->ie_len, - DOT11_MNG_RSN_ID)) != NULL) { - WL_DBG((" WPA2 IE is found\n")); - } - /* find the WPA_IE */ - if ((wpa_ie = wl_cfgp2p_find_wpaie((u8 *)sme->ie, - sme->ie_len)) != NULL) { - WL_DBG((" WPA IE is found\n")); - } - if (wpa_ie != NULL || wpa2_ie != NULL) { - wpaie = (wpa_ie != NULL) ? (u8 *)wpa_ie : (u8 *)wpa2_ie; - wpaie_len = (wpa_ie != NULL) ? wpa_ie->length : wpa2_ie->len; - wpaie_len += WPA_RSN_IE_TAG_FIXED_LEN; - wldev_iovar_setbuf(dev, "wpaie", wpaie, wpaie_len, - wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); - } else { - wldev_iovar_setbuf(dev, "wpaie", NULL, 0, - wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); - } - - /* find the WPSIE */ - memset(wpsie, 0, sizeof(wpsie)); - if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)sme->ie, - sme->ie_len)) != NULL) { - wpsie_len = wps_ie->length +WPA_RSN_IE_TAG_FIXED_LEN; - memcpy(wpsie, wps_ie, wpsie_len); - } else { - wpsie_len = 0; - } - err = wl_cfgp2p_set_management_ie(wl, dev, -1, - VNDR_IE_ASSOCREQ_FLAG, wpsie, wpsie_len); - if (unlikely(err)) { - return err; - } - } - if (unlikely(!sme->ssid)) { - WL_ERR(("Invalid ssid\n")); - return -EOPNOTSUPP; - } - if (chan) { - wl->channel = ieee80211_frequency_to_channel(chan->center_freq); - chan_cnt = 1; - WL_DBG(("channel (%d), center_req (%d)\n", wl->channel, - chan->center_freq)); - } else - wl->channel = 0; - WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len)); - err = wl_set_wpa_version(dev, sme); - if (unlikely(err)) { - WL_ERR(("Invalid wpa_version\n")); - return err; - } - - err = wl_set_auth_type(dev, sme); - if (unlikely(err)) { - WL_ERR(("Invalid auth type\n")); - return err; - } - - err = wl_set_set_cipher(dev, sme); - if (unlikely(err)) { - WL_ERR(("Invalid ciper\n")); - return err; - } - - err = wl_set_key_mgmt(dev, sme); - if (unlikely(err)) { - WL_ERR(("Invalid key mgmt\n")); - return err; - } - - err = wl_set_set_sharedkey(dev, sme); - if (unlikely(err)) { - WL_ERR(("Invalid shared key\n")); - return err; - } - - /* - * Join with specific BSSID and cached SSID - * If SSID is zero join based on BSSID only - */ - join_params_size = WL_EXTJOIN_PARAMS_FIXED_SIZE + - chan_cnt * sizeof(chanspec_t); - ext_join_params = (wl_extjoin_params_t*)kzalloc(join_params_size, GFP_KERNEL); - if (ext_join_params == NULL) { - err = -ENOMEM; - wl_clr_drv_status(wl, CONNECTING, dev); - goto exit; - } - ext_join_params->ssid.SSID_len = min(sizeof(ext_join_params->ssid.SSID), sme->ssid_len); - memcpy(&ext_join_params->ssid.SSID, sme->ssid, ext_join_params->ssid.SSID_len); - ext_join_params->ssid.SSID_len = htod32(ext_join_params->ssid.SSID_len); - /* Set up join scan parameters */ - ext_join_params->scan.scan_type = -1; - ext_join_params->scan.nprobes = 2; - /* increate dwell time to receive probe response or detect Beacon - * from target AP at a noisy air only during connect command - */ - ext_join_params->scan.active_time = WL_SCAN_ACTIVE_TIME*3; - ext_join_params->scan.passive_time = WL_SCAN_PASSIVE_TIME*3; - ext_join_params->scan.home_time = -1; - - if (sme->bssid) - memcpy(&ext_join_params->assoc.bssid, sme->bssid, ETH_ALEN); - else - memcpy(&ext_join_params->assoc.bssid, ðer_bcast, ETH_ALEN); - ext_join_params->assoc.chanspec_num = chan_cnt; - if (chan_cnt) { - u16 channel, band, bw, ctl_sb; - chanspec_t chspec; - channel = wl->channel; - band = (channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G - : WL_CHANSPEC_BAND_5G; - bw = WL_CHANSPEC_BW_20; - ctl_sb = WL_CHANSPEC_CTL_SB_NONE; - chspec = (channel | band | bw | ctl_sb); - ext_join_params->assoc.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK; - ext_join_params->assoc.chanspec_list[0] |= chspec; - ext_join_params->assoc.chanspec_list[0] = - htodchanspec(ext_join_params->assoc.chanspec_list[0]); - } - ext_join_params->assoc.chanspec_num = htod32(ext_join_params->assoc.chanspec_num); - if (ext_join_params->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) { - WL_INFO(("ssid \"%s\", len (%d)\n", ext_join_params->ssid.SSID, - ext_join_params->ssid.SSID_len)); - } - wl_set_drv_status(wl, CONNECTING, dev); - err = wldev_iovar_setbuf_bsscfg(dev, "join", ext_join_params, join_params_size, - wl->ioctl_buf, WLC_IOCTL_MAXLEN, wl_cfgp2p_find_idx(wl, dev), &wl->ioctl_buf_sync); - kfree(ext_join_params); - if (err) { - wl_clr_drv_status(wl, CONNECTING, dev); - if (err == BCME_UNSUPPORTED) { - WL_DBG(("join iovar is not supported\n")); - goto set_ssid; - } else - WL_ERR(("error (%d)\n", err)); - } else - goto exit; - -set_ssid: - memset(&join_params, 0, sizeof(join_params)); - join_params_size = sizeof(join_params.ssid); - - join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len); - memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len); - join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len); - wl_update_prof(wl, dev, NULL, &join_params.ssid, WL_PROF_SSID); - if (sme->bssid) - memcpy(&join_params.params.bssid, sme->bssid, ETH_ALEN); - else - memcpy(&join_params.params.bssid, ðer_bcast, ETH_ALEN); - - wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size); - WL_DBG(("join_param_size %d\n", join_params_size)); - - if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) { - WL_INFO(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID, - join_params.ssid.SSID_len)); - } - wl_set_drv_status(wl, CONNECTING, dev); - err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size, true); - if (err) { - WL_ERR(("error (%d)\n", err)); - wl_clr_drv_status(wl, CONNECTING, dev); - } -exit: - return err; -} - -static s32 -wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, - u16 reason_code) -{ - struct wl_priv *wl = wiphy_priv(wiphy); - scb_val_t scbval; - bool act = false; - s32 err = 0; - u8 *curbssid; - WL_ERR(("Reason %d\n", reason_code)); - CHECK_SYS_UP(wl); - act = *(bool *) wl_read_prof(wl, dev, WL_PROF_ACT); - curbssid = wl_read_prof(wl, dev, WL_PROF_BSSID); - if (act) { - /* - * Cancel ongoing scan to sync up with sme state machine of cfg80211. - */ - if (wl->scan_request) { - wl_notify_escan_complete(wl, dev, true, true); - } - wl_set_drv_status(wl, DISCONNECTING, dev); - scbval.val = reason_code; - memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN); - scbval.val = htod32(scbval.val); - err = wldev_ioctl(dev, WLC_DISASSOC, &scbval, - sizeof(scb_val_t), true); - if (unlikely(err)) { - wl_clr_drv_status(wl, DISCONNECTING, dev); - WL_ERR(("error (%d)\n", err)); - return err; - } - } - - return err; -} - -static s32 -wl_cfg80211_set_tx_power(struct wiphy *wiphy, - enum nl80211_tx_power_setting type, s32 dbm) -{ - - struct wl_priv *wl = wiphy_priv(wiphy); - struct net_device *ndev = wl_to_prmry_ndev(wl); - u16 txpwrmw; - s32 err = 0; - s32 disable = 0; - - CHECK_SYS_UP(wl); - switch (type) { - case NL80211_TX_POWER_AUTOMATIC: - break; - case NL80211_TX_POWER_LIMITED: - if (dbm < 0) { - WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n")); - return -EINVAL; - } - break; - case NL80211_TX_POWER_FIXED: - if (dbm < 0) { - WL_ERR(("TX_POWER_FIXED - dbm is negative..\n")); - return -EINVAL; - } - break; - } - /* Make sure radio is off or on as far as software is concerned */ - disable = WL_RADIO_SW_DISABLE << 16; - disable = htod32(disable); - err = wldev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable), true); - if (unlikely(err)) { - WL_ERR(("WLC_SET_RADIO error (%d)\n", err)); - return err; - } - - if (dbm > 0xffff) - txpwrmw = 0xffff; - else - txpwrmw = (u16) dbm; - err = wldev_iovar_setint(ndev, "qtxpower", - (s32) (bcm_mw_to_qdbm(txpwrmw))); - if (unlikely(err)) { - WL_ERR(("qtxpower error (%d)\n", err)); - return err; - } - wl->conf->tx_power = dbm; - - return err; -} - -static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) -{ - struct wl_priv *wl = wiphy_priv(wiphy); - struct net_device *ndev = wl_to_prmry_ndev(wl); - s32 txpwrdbm; - u8 result; - s32 err = 0; - - CHECK_SYS_UP(wl); - err = wldev_iovar_getint(ndev, "qtxpower", &txpwrdbm); - if (unlikely(err)) { - WL_ERR(("error (%d)\n", err)); - return err; - } - result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE); - *dbm = (s32) bcm_qdbm_to_mw(result); - - return err; -} - -static s32 -wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool unicast, bool multicast) -{ - struct wl_priv *wl = wiphy_priv(wiphy); - u32 index; - s32 wsec; - s32 err = 0; - s32 bssidx = wl_cfgp2p_find_idx(wl, dev); - - WL_DBG(("key index (%d)\n", key_idx)); - CHECK_SYS_UP(wl); - err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx); - if (unlikely(err)) { - WL_ERR(("WLC_GET_WSEC error (%d)\n", err)); - return err; - } - if (wsec == WEP_ENABLED) { - /* Just select a new current key */ - index = (u32) key_idx; - index = htod32(index); - err = wldev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index, - sizeof(index), true); - if (unlikely(err)) { - WL_ERR(("error (%d)\n", err)); - } - } - return err; -} - -static s32 -wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, const u8 *mac_addr, struct key_params *params) -{ - struct wl_priv *wl = wiphy_priv(wiphy); - struct wl_wsec_key key; - s32 err = 0; - s32 bssidx = wl_cfgp2p_find_idx(wl, dev); - s32 mode = wl_get_mode_by_netdev(wl, dev); - memset(&key, 0, sizeof(key)); - key.index = (u32) key_idx; - - if (!ETHER_ISMULTI(mac_addr)) - memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN); - key.len = (u32) params->key_len; - - /* check for key index change */ - if (key.len == 0) { - /* key delete */ - swap_key_from_BE(&key); - wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), - wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); - if (unlikely(err)) { - WL_ERR(("key delete error (%d)\n", err)); - return err; - } - } else { - if (key.len > sizeof(key.data)) { - WL_ERR(("Invalid key length (%d)\n", key.len)); - return -EINVAL; - } - WL_DBG(("Setting the key index %d\n", key.index)); - memcpy(key.data, params->key, key.len); - - if ((mode == WL_MODE_BSS) && - (params->cipher == WLAN_CIPHER_SUITE_TKIP)) { - u8 keybuf[8]; - memcpy(keybuf, &key.data[24], sizeof(keybuf)); - memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); - memcpy(&key.data[16], keybuf, sizeof(keybuf)); - } - - /* if IW_ENCODE_EXT_RX_SEQ_VALID set */ - if (params->seq && params->seq_len == 6) { - /* rx iv */ - u8 *ivptr; - ivptr = (u8 *) params->seq; - key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) | - (ivptr[3] << 8) | ivptr[2]; - key.rxiv.lo = (ivptr[1] << 8) | ivptr[0]; - key.iv_initialized = true; - } - - switch (params->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - key.algo = CRYPTO_ALGO_WEP1; - WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n")); - break; - case WLAN_CIPHER_SUITE_WEP104: - key.algo = CRYPTO_ALGO_WEP128; - WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n")); - break; - case WLAN_CIPHER_SUITE_TKIP: - key.algo = CRYPTO_ALGO_TKIP; - WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n")); - break; - case WLAN_CIPHER_SUITE_AES_CMAC: - key.algo = CRYPTO_ALGO_AES_CCM; - WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n")); - break; - case WLAN_CIPHER_SUITE_CCMP: - key.algo = CRYPTO_ALGO_AES_CCM; - WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n")); - break; - default: - WL_ERR(("Invalid cipher (0x%x)\n", params->cipher)); - return -EINVAL; - } - swap_key_from_BE(&key); - wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), - wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); - if (unlikely(err)) { - WL_ERR(("WLC_SET_KEY error (%d)\n", err)); - return err; - } - } - return err; -} - -static s32 -wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool pairwise, const u8 *mac_addr, - struct key_params *params) -{ - struct wl_wsec_key key; - s32 val = 0; - s32 wsec = 0; - s32 err = 0; - u8 keybuf[8]; - s32 bssidx = 0; - struct wl_priv *wl = wiphy_priv(wiphy); - s32 mode = wl_get_mode_by_netdev(wl, dev); - WL_DBG(("key index (%d)\n", key_idx)); - CHECK_SYS_UP(wl); - - bssidx = wl_cfgp2p_find_idx(wl, dev); - - if (mac_addr && - ((params->cipher != WLAN_CIPHER_SUITE_WEP40) && - (params->cipher != WLAN_CIPHER_SUITE_WEP104))) { - wl_add_keyext(wiphy, dev, key_idx, mac_addr, params); - goto exit; - } - memset(&key, 0, sizeof(key)); - - key.len = (u32) params->key_len; - key.index = (u32) key_idx; - - if (unlikely(key.len > sizeof(key.data))) { - WL_ERR(("Too long key length (%u)\n", key.len)); - return -EINVAL; - } - memcpy(key.data, params->key, key.len); - - key.flags = WL_PRIMARY_KEY; - switch (params->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - key.algo = CRYPTO_ALGO_WEP1; - val = WEP_ENABLED; - WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n")); - break; - case WLAN_CIPHER_SUITE_WEP104: - key.algo = CRYPTO_ALGO_WEP128; - val = WEP_ENABLED; - WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n")); - break; - case WLAN_CIPHER_SUITE_TKIP: - key.algo = CRYPTO_ALGO_TKIP; - val = TKIP_ENABLED; - /* wpa_supplicant switches the third and fourth quarters of the TKIP key */ - if (mode == WL_MODE_BSS) { - bcopy(&key.data[24], keybuf, sizeof(keybuf)); - bcopy(&key.data[16], &key.data[24], sizeof(keybuf)); - bcopy(keybuf, &key.data[16], sizeof(keybuf)); - } - WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n")); - break; - case WLAN_CIPHER_SUITE_AES_CMAC: - key.algo = CRYPTO_ALGO_AES_CCM; - val = AES_ENABLED; - WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n")); - break; - case WLAN_CIPHER_SUITE_CCMP: - key.algo = CRYPTO_ALGO_AES_CCM; - val = AES_ENABLED; - WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n")); - break; - default: - WL_ERR(("Invalid cipher (0x%x)\n", params->cipher)); - return -EINVAL; - } - - /* Set the new key/index */ - swap_key_from_BE(&key); - err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), wl->ioctl_buf, - WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); - if (unlikely(err)) { - WL_ERR(("WLC_SET_KEY error (%d)\n", err)); - return err; - } - -exit: - err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx); - if (unlikely(err)) { - WL_ERR(("get wsec error (%d)\n", err)); - return err; - } - - wsec |= val; - err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx); - if (unlikely(err)) { - WL_ERR(("set wsec error (%d)\n", err)); - return err; - } - - return err; -} - -static s32 -wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool pairwise, const u8 *mac_addr) -{ - struct wl_wsec_key key; - struct wl_priv *wl = wiphy_priv(wiphy); - s32 err = 0; - s32 bssidx = wl_cfgp2p_find_idx(wl, dev); - - WL_DBG(("Enter\n")); - CHECK_SYS_UP(wl); - memset(&key, 0, sizeof(key)); - - key.flags = WL_PRIMARY_KEY; - key.algo = CRYPTO_ALGO_OFF; - key.index = (u32) key_idx; - - WL_DBG(("key index (%d)\n", key_idx)); - /* Set the new key/index */ - swap_key_from_BE(&key); - wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), wl->ioctl_buf, - WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); - if (unlikely(err)) { - if (err == -EINVAL) { - if (key.index >= DOT11_MAX_DEFAULT_KEYS) { - /* we ignore this key index in this case */ - WL_DBG(("invalid key index (%d)\n", key_idx)); - } - } else { - WL_ERR(("WLC_SET_KEY error (%d)\n", err)); - } - return err; - } - return err; -} - -static s32 -wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie, - void (*callback) (void *cookie, struct key_params * params)) -{ - struct key_params params; - struct wl_wsec_key key; - struct wl_priv *wl = wiphy_priv(wiphy); - struct wl_security *sec; - s32 wsec; - s32 err = 0; - s32 bssidx = wl_cfgp2p_find_idx(wl, dev); - - WL_DBG(("key index (%d)\n", key_idx)); - CHECK_SYS_UP(wl); - memset(&key, 0, sizeof(key)); - key.index = key_idx; - swap_key_to_BE(&key); - memset(¶ms, 0, sizeof(params)); - params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len); - memcpy(params.key, key.data, params.key_len); - - wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx); - if (unlikely(err)) { - WL_ERR(("WLC_GET_WSEC error (%d)\n", err)); - return err; - } - switch (wsec & ~SES_OW_ENABLED) { - case WEP_ENABLED: - sec = wl_read_prof(wl, dev, WL_PROF_SEC); - if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) { - params.cipher = WLAN_CIPHER_SUITE_WEP40; - WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n")); - } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) { - params.cipher = WLAN_CIPHER_SUITE_WEP104; - WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n")); - } - break; - case TKIP_ENABLED: - params.cipher = WLAN_CIPHER_SUITE_TKIP; - WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n")); - break; - case AES_ENABLED: - params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; - WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n")); - break; - default: - WL_ERR(("Invalid algo (0x%x)\n", wsec)); - return -EINVAL; - } - - callback(cookie, ¶ms); - return err; -} - -static s32 -wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, - struct net_device *dev, u8 key_idx) -{ - WL_INFO(("Not supported\n")); - return -EOPNOTSUPP; -} - -static s32 -wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, - u8 *mac, struct station_info *sinfo) -{ - struct wl_priv *wl = wiphy_priv(wiphy); - scb_val_t scb_val; - s32 rssi; - s32 rate; - s32 err = 0; - sta_info_t *sta; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) - s8 eabuf[ETHER_ADDR_STR_LEN]; -#endif - dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); - - CHECK_SYS_UP(wl); - if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP) { - err = wldev_iovar_getbuf(dev, "sta_info", (struct ether_addr *)mac, - ETHER_ADDR_LEN, wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); - if (err < 0) { - WL_ERR(("GET STA INFO failed, %d\n", err)); - return err; - } - sinfo->filled = STATION_INFO_INACTIVE_TIME; - sta = (sta_info_t *)wl->ioctl_buf; - sta->len = dtoh16(sta->len); - sta->cap = dtoh16(sta->cap); - sta->flags = dtoh32(sta->flags); - sta->idle = dtoh32(sta->idle); - sta->in = dtoh32(sta->in); - sinfo->inactive_time = sta->idle * 1000; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) - if (sta->flags & WL_STA_ASSOC) { - sinfo->filled |= STATION_INFO_CONNECTED_TIME; - sinfo->connected_time = sta->in; - } - WL_INFO(("STA %s : idle time : %d sec, connected time :%d ms\n", - bcm_ether_ntoa((const struct ether_addr *)mac, eabuf), sinfo->inactive_time, - sta->idle * 1000)); -#endif - } else if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_BSS) { - get_pktcnt_t pktcnt; - u8 *curmacp = wl_read_prof(wl, dev, WL_PROF_BSSID); - err = -ENODEV; - if (!wl_get_drv_status(wl, CONNECTED, dev) || - (dhd_is_associated(dhd, NULL, &err) == FALSE)) { - WL_ERR(("NOT assoc: %d\n", err)); - goto get_station_err; - } - if (memcmp(mac, curmacp, ETHER_ADDR_LEN)) { - WL_ERR(("Wrong Mac address: "MACSTR" != "MACSTR"\n", - MAC2STR(mac), MAC2STR(curmacp))); - } - - /* Report the current tx rate */ - err = wldev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate), false); - if (err) { - WL_ERR(("Could not get rate (%d)\n", err)); - } else { - rate = dtoh32(rate); - sinfo->filled |= STATION_INFO_TX_BITRATE; - sinfo->txrate.legacy = rate * 5; - WL_DBG(("Rate %d Mbps\n", (rate / 2))); - } - - memset(&scb_val, 0, sizeof(scb_val)); - scb_val.val = 0; - err = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val, - sizeof(scb_val_t), false); - if (err) { - WL_ERR(("Could not get rssi (%d)\n", err)); - goto get_station_err; - } - rssi = dtoh32(scb_val.val); - sinfo->filled |= STATION_INFO_SIGNAL; - sinfo->signal = rssi; - WL_DBG(("RSSI %d dBm\n", rssi)); - - err = wldev_ioctl(dev, WLC_GET_PKTCNTS, &pktcnt, - sizeof(pktcnt), false); - if (!err) { - sinfo->filled |= (STATION_INFO_RX_PACKETS | - STATION_INFO_RX_DROP_MISC | - STATION_INFO_TX_PACKETS | - STATION_INFO_TX_FAILED); - sinfo->rx_packets = pktcnt.rx_good_pkt; - sinfo->rx_dropped_misc = pktcnt.rx_bad_pkt; - sinfo->tx_packets = pktcnt.tx_good_pkt; - sinfo->tx_failed = pktcnt.tx_bad_pkt; - } - -get_station_err: - if (err && (err != -ETIMEDOUT) && (err != -EIO)) { - /* Disconnect due to zero BSSID or error to get RSSI */ - WL_ERR(("force cfg80211_disconnected: %d\n", err)); - wl_clr_drv_status(wl, CONNECTED, dev); - cfg80211_disconnected(dev, 0, NULL, 0, GFP_KERNEL); - wl_link_down(wl); - } - } - - return err; -} - -int wl_cfg80211_update_power_mode(struct net_device *dev) -{ - int pm = -1; - int err; - - err = wldev_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm), false); - if (err || (pm == -1)) { - WL_ERR(("error (%d)\n", err)); - } else { - pm = (pm == PM_OFF) ? false : true; - WL_DBG(("%s: %d\n", __func__, pm)); - if (dev->ieee80211_ptr) - dev->ieee80211_ptr->ps = pm; - } - return err; -} - -static s32 -wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, - bool enabled, s32 timeout) -{ - s32 pm; - s32 err = 0; - struct wl_priv *wl = wiphy_priv(wiphy); -#if !defined(SUPPORT_PM2_ONLY) - dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); -#endif - CHECK_SYS_UP(wl); - - WL_DBG(("Enter : power save %s\n", (enabled ? "enable" : "disable"))); - if (wl->p2p_net == dev) { - return err; - } - -#if !defined(SUPPORT_PM2_ONLY) - pm = enabled ? ((dhd->in_suspend) ? PM_MAX : PM_FAST) : PM_OFF; -#else - pm = enabled ? PM_FAST : PM_OFF; -#endif - pm = htod32(pm); - err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true); - if (unlikely(err)) { - if (err == -ENODEV) - WL_DBG(("net_device is not ready yet\n")); - else - WL_ERR(("error (%d)\n", err)); - return err; - } - WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled"))); - return err; -} - -static __used u32 wl_find_msb(u16 bit16) -{ - u32 ret = 0; - - if (bit16 & 0xff00) { - ret += 8; - bit16 >>= 8; - } - - if (bit16 & 0xf0) { - ret += 4; - bit16 >>= 4; - } - - if (bit16 & 0xc) { - ret += 2; - bit16 >>= 2; - } - - if (bit16 & 2) - ret += bit16 & 2; - else if (bit16) - ret += bit16; - - return ret; -} - -static s32 wl_cfg80211_resume(struct wiphy *wiphy) -{ - struct wl_priv *wl = wiphy_priv(wiphy); - struct net_device *ndev = wl_to_prmry_ndev(wl); - s32 err = 0; - - if (unlikely(!wl_get_drv_status(wl, READY, ndev))) { - WL_INFO(("device is not ready\n")); - return 0; - } - - wl_invoke_iscan(wl); - - return err; -} - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) -static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow) -#else -static s32 wl_cfg80211_suspend(struct wiphy *wiphy) -#endif -{ -#ifdef DHD_CLEAR_ON_SUSPEND - struct wl_priv *wl = wiphy_priv(wiphy); - struct net_info *iter, *next; - struct net_device *ndev = wl_to_prmry_ndev(wl); - unsigned long flags; - - if (unlikely(!wl_get_drv_status(wl, READY, ndev))) { - WL_INFO(("device is not ready : status (%d)\n", - (int)wl->status)); - return 0; - } - for_each_ndev(wl, iter, next) - wl_set_drv_status(wl, SCAN_ABORTING, iter->ndev); - wl_term_iscan(wl); - spin_lock_irqsave(&wl->cfgdrv_lock, flags); - if (wl->scan_request) { - cfg80211_scan_done(wl->scan_request, true); - wl->scan_request = NULL; - } - for_each_ndev(wl, iter, next) { - wl_clr_drv_status(wl, SCANNING, iter->ndev); - wl_clr_drv_status(wl, SCAN_ABORTING, iter->ndev); - } - spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); - for_each_ndev(wl, iter, next) { - if (wl_get_drv_status(wl, CONNECTING, iter->ndev)) { - wl_bss_connect_done(wl, iter->ndev, NULL, NULL, false); - } - } -#endif /* DHD_CLEAR_ON_SUSPEND */ - return 0; -} - -static s32 -wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list, - s32 err) -{ - int i, j; - struct wl_priv *wl = wlcfg_drv_priv; - struct net_device *primary_dev = wl_to_prmry_ndev(wl); - - if (!pmk_list) { - printk("pmk_list is NULL\n"); - return -EINVAL; - } - /* pmk list is supported only for STA interface i.e. primary interface - * Refer code wlc_bsscfg.c->wlc_bsscfg_sta_init - */ - if (primary_dev != dev) { - WL_INFO(("Not supporting Flushing pmklist on virtual" - " interfaces than primary interface\n")); - return err; - } - - WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid)); - for (i = 0; i < pmk_list->pmkids.npmkid; i++) { - WL_DBG(("PMKID[%d]: %pM =\n", i, - &pmk_list->pmkids.pmkid[i].BSSID)); - for (j = 0; j < WPA2_PMKID_LEN; j++) { - WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j])); - } - } - if (likely(!err)) { - err = wldev_iovar_setbuf(dev, "pmkid_info", (char *)pmk_list, - sizeof(*pmk_list), wl->ioctl_buf, WLC_IOCTL_MAXLEN, NULL); - } - - return err; -} - -static s32 -wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, - struct cfg80211_pmksa *pmksa) -{ - struct wl_priv *wl = wiphy_priv(wiphy); - s32 err = 0; - int i; - - CHECK_SYS_UP(wl); - for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++) - if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID, - ETHER_ADDR_LEN)) - break; - if (i < WL_NUM_PMKIDS_MAX) { - memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid, - ETHER_ADDR_LEN); - memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid, - WPA2_PMKID_LEN); - if (i == wl->pmk_list->pmkids.npmkid) - wl->pmk_list->pmkids.npmkid++; - } else { - err = -EINVAL; - } - WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n", - &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid - 1].BSSID)); - for (i = 0; i < WPA2_PMKID_LEN; i++) { - WL_DBG(("%02x\n", - wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid - 1]. - PMKID[i])); - } - - err = wl_update_pmklist(dev, wl->pmk_list, err); - - return err; -} - -static s32 -wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, - struct cfg80211_pmksa *pmksa) -{ - struct wl_priv *wl = wiphy_priv(wiphy); - struct _pmkid_list pmkid; - s32 err = 0; - int i; - - CHECK_SYS_UP(wl); - memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN); - memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN); - - WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n", - &pmkid.pmkid[0].BSSID)); - for (i = 0; i < WPA2_PMKID_LEN; i++) { - WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i])); - } - - for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++) - if (!memcmp - (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID, - ETHER_ADDR_LEN)) - break; - - if ((wl->pmk_list->pmkids.npmkid > 0) && - (i < wl->pmk_list->pmkids.npmkid)) { - memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t)); - for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) { - memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, - &wl->pmk_list->pmkids.pmkid[i + 1].BSSID, - ETHER_ADDR_LEN); - memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, - &wl->pmk_list->pmkids.pmkid[i + 1].PMKID, - WPA2_PMKID_LEN); - } - wl->pmk_list->pmkids.npmkid--; - } else { - err = -EINVAL; - } - - err = wl_update_pmklist(dev, wl->pmk_list, err); - - return err; - -} - -static s32 -wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev) -{ - struct wl_priv *wl = wiphy_priv(wiphy); - s32 err = 0; - CHECK_SYS_UP(wl); - memset(wl->pmk_list, 0, sizeof(*wl->pmk_list)); - err = wl_update_pmklist(dev, wl->pmk_list, err); - return err; - -} - -static wl_scan_params_t * -wl_cfg80211_scan_alloc_params(int channel, int nprobes, int *out_params_size) -{ - wl_scan_params_t *params; - int params_size; - int num_chans; - - *out_params_size = 0; - - /* Our scan params only need space for 1 channel and 0 ssids */ - params_size = WL_SCAN_PARAMS_FIXED_SIZE + 1 * sizeof(uint16); - params = (wl_scan_params_t*) kzalloc(params_size, GFP_KERNEL); - if (params == NULL) { - WL_ERR(("%s: mem alloc failed (%d bytes)\n", __func__, params_size)); - return params; - } - memset(params, 0, params_size); - params->nprobes = nprobes; - - num_chans = (channel == 0) ? 0 : 1; - - memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN); - params->bss_type = DOT11_BSSTYPE_ANY; - params->scan_type = DOT11_SCANTYPE_ACTIVE; - params->nprobes = htod32(1); - params->active_time = htod32(-1); - params->passive_time = htod32(-1); - params->home_time = htod32(10); - params->channel_list[0] = htodchanspec(channel); - - /* Our scan params have 1 channel and 0 ssids */ - params->channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) | - (num_chans & WL_SCAN_PARAMS_COUNT_MASK)); - - *out_params_size = params_size; /* rtn size to the caller */ - return params; -} - -static s32 -wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev, - struct ieee80211_channel * channel, - enum nl80211_channel_type channel_type, - unsigned int duration, u64 *cookie) -{ - s32 target_channel; - u32 id; - struct ether_addr primary_mac; - struct net_device *ndev = NULL; - - s32 err = BCME_OK; - struct wl_priv *wl = wiphy_priv(wiphy); - WL_DBG(("Enter, netdev_ifidx: %d \n", dev->ifindex)); - - if (wl->p2p_net == dev) { - ndev = wl_to_prmry_ndev(wl); - } else { - ndev = dev; - } - - if (wl_get_drv_status(wl, SCANNING, ndev)) { - wl_notify_escan_complete(wl, ndev, true, true); - } - target_channel = ieee80211_frequency_to_channel(channel->center_freq); - memcpy(&wl->remain_on_chan, channel, sizeof(struct ieee80211_channel)); - wl->remain_on_chan_type = channel_type; - id = ++wl->last_roc_id; - if (id == 0) - id = ++wl->last_roc_id; - *cookie = id; - cfg80211_ready_on_channel(dev, *cookie, channel, - channel_type, duration, GFP_KERNEL); - if (wl->p2p && !wl->p2p->on) { - get_primary_mac(wl, &primary_mac); - wl_cfgp2p_generate_bss_mac(&primary_mac, &wl->p2p->dev_addr, &wl->p2p->int_addr); - - /* In case of p2p_listen command, supplicant send remain_on_channel - * without turning on P2P - */ - - p2p_on(wl) = true; - err = wl_cfgp2p_enable_discovery(wl, ndev, NULL, 0); - - if (unlikely(err)) { - goto exit; - } - } - if (p2p_is_on(wl)) - wl_cfgp2p_discover_listen(wl, target_channel, duration); - - -exit: - return err; -} - -static s32 -wl_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct net_device *dev, - u64 cookie) -{ - s32 err = 0; - WL_DBG((" enter ) netdev_ifidx: %d \n", dev->ifindex)); - return err; -} - -static s32 -wl_cfg80211_send_pending_tx_act_frm(struct wl_priv *wl) -{ - wl_af_params_t *tx_act_frm; - struct net_device *dev = wl->afx_hdl->dev; - if (!p2p_is_on(wl)) - return -1; - - if (dev == wl->p2p_net) { - dev = wl_to_prmry_ndev(wl); - } - - tx_act_frm = wl->afx_hdl->pending_tx_act_frm; - WL_DBG(("Sending the action frame\n")); - wl->afx_hdl->pending_tx_act_frm = NULL; - if (tx_act_frm != NULL) { - /* Suspend P2P discovery's search-listen to prevent it from - * starting a scan or changing the channel. - */ - wl_clr_drv_status(wl, SENDING_ACT_FRM, wl->afx_hdl->dev); - wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev); - wl_notify_escan_complete(wl, dev, true, true); - wl_cfgp2p_discover_enable_search(wl, false); - tx_act_frm->channel = wl->afx_hdl->peer_chan; - wl->afx_hdl->ack_recv = (wl_cfgp2p_tx_action_frame(wl, dev, - tx_act_frm, wl->afx_hdl->bssidx)) ? false : true; - } - return 0; -} -static void -wl_cfg80211_afx_handler(struct work_struct *work) -{ - - struct afx_hdl *afx_instance; - struct wl_priv *wl = wlcfg_drv_priv; - afx_instance = container_of(work, struct afx_hdl, work); - if (afx_instance != NULL) { - wl_cfgp2p_act_frm_search(wl, wl->afx_hdl->dev, - wl->afx_hdl->bssidx, 0); - } -} - -static bool -wl_cfg80211_send_at_common_channel(struct wl_priv *wl, - struct net_device *dev, - wl_af_params_t *af_params) -{ - WL_DBG((" enter ) \n")); - /* initialize afx_hdl */ - wl->afx_hdl->pending_tx_act_frm = af_params; - wl->afx_hdl->bssidx = wl_cfgp2p_find_idx(wl, dev); - wl->afx_hdl->dev = dev; - wl->afx_hdl->retry = 0; - wl->afx_hdl->peer_chan = WL_INVALID; - wl->afx_hdl->ack_recv = false; - memcpy(wl->afx_hdl->pending_tx_dst_addr.octet, - af_params->action_frame.da.octet, - sizeof(wl->afx_hdl->pending_tx_dst_addr.octet)); - /* Loop to wait until we have sent the pending tx action frame or the - * pending action frame tx is cancelled. - */ - while ((wl->afx_hdl->retry < WL_CHANNEL_SYNC_RETRY) && - (wl->afx_hdl->peer_chan == WL_INVALID)) { - wl_set_drv_status(wl, SENDING_ACT_FRM, dev); - wl_set_drv_status(wl, SCANNING, dev); - WL_DBG(("Scheduling the action frame for sending.. retry %d\n", - wl->afx_hdl->retry)); - /* Do find_peer_for_action */ - schedule_work(&wl->afx_hdl->work); - wait_for_completion(&wl->act_frm_scan); - wl->afx_hdl->retry++; - } - if (wl->afx_hdl->peer_chan != WL_INVALID) - wl_cfg80211_send_pending_tx_act_frm(wl); - else { - WL_ERR(("Couldn't find the peer " MACSTR " after %d retries\n", - MAC2STR(wl->afx_hdl->pending_tx_dst_addr.octet), wl->afx_hdl->retry)); - } - wl->afx_hdl->dev = NULL; - wl->afx_hdl->bssidx = WL_INVALID; - wl_clr_drv_status(wl, SENDING_ACT_FRM, dev); - if (wl->afx_hdl->ack_recv) - return true; /* ACK */ - else - return false; /* NO ACK */ -} - -static s32 -wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev, - struct ieee80211_channel *channel, bool offchan, - enum nl80211_channel_type channel_type, - bool channel_type_valid, unsigned int wait, - const u8* buf, size_t len, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) - bool no_cck, -#endif - u64 *cookie) -{ - wl_action_frame_t *action_frame; - wl_af_params_t *af_params; - wifi_p2p_ie_t *p2p_ie; - wpa_ie_fixed_t *wps_ie; - scb_val_t scb_val; - wifi_wfd_ie_t *wfd_ie; - const struct ieee80211_mgmt *mgmt; - struct wl_priv *wl = wiphy_priv(wiphy); - struct net_device *dev = NULL; - s32 err = BCME_OK; - s32 bssidx = 0; - u32 p2pie_len = 0; - u32 wpsie_len = 0; - u32 wfdie_len = 0; - u32 id; - u32 retry = 0; - bool ack = false; - wifi_p2p_pub_act_frame_t *act_frm = NULL; - wifi_p2p_action_frame_t *p2p_act_frm = NULL; - wifi_p2psd_gas_pub_act_frame_t *sd_act_frm = NULL; - s8 eabuf[ETHER_ADDR_STR_LEN]; - int retry_cnt = 0; - - WL_DBG(("Enter \n")); - - if (ndev == wl->p2p_net) { - dev = wl_to_prmry_ndev(wl); - } else { - /* If TX req is for any valid ifidx. Use as is */ - dev = ndev; - } - - /* find bssidx based on ndev */ - bssidx = wl_cfgp2p_find_idx(wl, dev); - if (bssidx == -1) { - - WL_ERR(("Can not find the bssidx for dev( %p )\n", dev)); - return -ENODEV; - } - if (p2p_is_on(wl)) { - /* Suspend P2P discovery search-listen to prevent it from changing the - * channel. - */ - if ((err = wl_cfgp2p_discover_enable_search(wl, false)) < 0) { - WL_ERR(("Can not disable discovery mode\n")); - return -EFAULT; - } - } - *cookie = 0; - id = wl->send_action_id++; - if (id == 0) - id = wl->send_action_id++; - *cookie = id; - mgmt = (const struct ieee80211_mgmt *)buf; - if (ieee80211_is_mgmt(mgmt->frame_control)) { - if (ieee80211_is_probe_resp(mgmt->frame_control)) { - s32 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN; - s32 ie_len = len - ie_offset; - if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)(buf + ie_offset), ie_len)) - != NULL) { - /* Total length of P2P Information Element */ - p2pie_len = p2p_ie->len + sizeof(p2p_ie->len) + sizeof(p2p_ie->id); - } - if ((wfd_ie = wl_cfgp2p_find_wfdie((u8 *)(buf + ie_offset), ie_len)) - != NULL) { - /* Total length of WFD Information Element */ - wfdie_len = wfd_ie->len + sizeof(wfd_ie->len) + sizeof(wfd_ie->id); - } - if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)(buf + ie_offset), ie_len)) - != NULL) { - /* Order of Vendor IE is 1) WPS IE + - * 2) P2P IE created by supplicant - * So, it is ok to find start address of WPS IE - * to save IEs - */ - wpsie_len = wps_ie->length + sizeof(wps_ie->length) + - sizeof(wps_ie->tag); - wl_cfgp2p_set_management_ie(wl, dev, bssidx, - VNDR_IE_PRBRSP_FLAG, - (u8 *)wps_ie, wpsie_len + p2pie_len+ wfdie_len); - } - cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, true, GFP_KERNEL); - goto exit; - } else if (ieee80211_is_disassoc(mgmt->frame_control) || - ieee80211_is_deauth(mgmt->frame_control)) { - memcpy(scb_val.ea.octet, mgmt->da, ETH_ALEN); - scb_val.val = mgmt->u.disassoc.reason_code; - wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scb_val, - sizeof(scb_val_t), true); - WL_DBG(("Disconnect STA : %s scb_val.val %d\n", - bcm_ether_ntoa((const struct ether_addr *)mgmt->da, eabuf), - scb_val.val)); - /* Wait for the deauth event to come, supplicant will do the - * delete iface immediately and we will have problem in sending - * deauth frame if we delete the bss in firmware - */ - wl_delay(400); - cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, true, GFP_KERNEL); - goto exit; - - } else if (ieee80211_is_action(mgmt->frame_control)) { - /* Abort the dwell time of any previous off-channel - * action frame that may be still in effect. Sending - * off-channel action frames relies on the driver's - * scan engine. If a previous off-channel action frame - * tx is still in progress (including the dwell time), - * then this new action frame will not be sent out. - */ - wl_notify_escan_complete(wl, dev, true, true); - - } - - } else { - WL_ERR(("Driver only allows MGMT packet type\n")); - goto exit; - } - - af_params = (wl_af_params_t *) kzalloc(WL_WIFI_AF_PARAMS_SIZE, GFP_KERNEL); - - if (af_params == NULL) - { - WL_ERR(("unable to allocate frame\n")); - return -ENOMEM; - } - - action_frame = &af_params->action_frame; - - /* Add the packet Id */ - action_frame->packetId = *cookie; - WL_DBG(("action frame %d\n", action_frame->packetId)); - /* Add BSSID */ - memcpy(&action_frame->da, &mgmt->da[0], ETHER_ADDR_LEN); - memcpy(&af_params->BSSID, &mgmt->bssid[0], ETHER_ADDR_LEN); - - /* Add the length exepted for 802.11 header */ - action_frame->len = len - DOT11_MGMT_HDR_LEN; - WL_DBG(("action_frame->len: %d\n", action_frame->len)); - - /* Add the channel */ - af_params->channel = - ieee80211_frequency_to_channel(channel->center_freq); - - if (channel->band == IEEE80211_BAND_5GHZ) { - WL_DBG(("5GHz channel %d", af_params->channel)); - err = wldev_ioctl(dev, WLC_SET_CHANNEL, - &af_params->channel, sizeof(af_params->channel), true); - if (err < 0) { - WL_ERR(("WLC_SET_CHANNEL error %d\n", err)); - } - } - - /* Add the dwell time - * Dwell time to stay off-channel to wait for a response action frame - * after transmitting an GO Negotiation action frame - */ - af_params->dwell_time = WL_DWELL_TIME; - - memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN], action_frame->len); - if (wl_cfgp2p_is_pub_action(action_frame->data, action_frame->len)) { - act_frm = (wifi_p2p_pub_act_frame_t *) (action_frame->data); - WL_DBG(("P2P PUB action_frame->len: %d chan %d category %d subtype %d\n", - action_frame->len, af_params->channel, - act_frm->category, act_frm->subtype)); - if (act_frm && ((act_frm->subtype == P2P_PAF_GON_REQ) || - (act_frm->subtype == P2P_PAF_GON_RSP) || - (act_frm->subtype == P2P_PAF_GON_CONF) || - (act_frm->subtype == P2P_PAF_PROVDIS_REQ))) { - wldev_iovar_setint(dev, "mpc", 0); - } - - if (act_frm->subtype == P2P_PAF_GON_REQ) { - WL_DBG(("P2P: GO_NEG_PHASE status set \n")); - wl_set_p2p_status(wl, GO_NEG_PHASE); - } else if (act_frm->subtype == P2P_PAF_GON_CONF) { - /* If we reached till GO Neg confirmation - * reset the filter - */ - WL_DBG(("P2P: GO_NEG_PHASE status cleared \n")); - wl_clr_p2p_status(wl, GO_NEG_PHASE); - } - - if (act_frm->subtype == P2P_PAF_GON_RSP) - retry_cnt = 1; - else retry_cnt = WL_ACT_FRAME_RETRY; - - if (act_frm && act_frm->subtype == P2P_PAF_DEVDIS_REQ) { - af_params->dwell_time = WL_LONG_DWELL_TIME; - } else if (act_frm && - (act_frm->subtype == P2P_PAF_PROVDIS_REQ || - act_frm->subtype == P2P_PAF_PROVDIS_RSP || - act_frm->subtype == P2P_PAF_GON_RSP)) { - af_params->dwell_time = WL_MED_DWELL_TIME; - } - } else if (wl_cfgp2p_is_p2p_action(action_frame->data, action_frame->len)) { - p2p_act_frm = (wifi_p2p_action_frame_t *) (action_frame->data); - WL_DBG(("P2P action_frame->len: %d chan %d category %d subtype %d\n", - action_frame->len, af_params->channel, - p2p_act_frm->category, p2p_act_frm->subtype)); - } else if (wl_cfgp2p_is_gas_action(action_frame->data, action_frame->len)) { - sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *) (action_frame->data); - WL_DBG(("Service Discovery action_frame->len: %d chan %d category %d action %d\n", - action_frame->len, af_params->channel, - sd_act_frm->category, sd_act_frm->action)); - af_params->dwell_time = WL_MED_DWELL_TIME; - retry_cnt = WL_ACT_FRAME_RETRY; - } - wl_cfgp2p_print_actframe(true, action_frame->data, action_frame->len); - /* - * To make sure to send successfully action frame, we have to turn off mpc - */ - if (IS_P2P_SOCIAL(af_params->channel) && - (IS_P2P_PUB_ACT_REQ(act_frm, &act_frm->elts[0], action_frame->len) || - IS_GAS_REQ(sd_act_frm, action_frame->len)) && - wl_to_p2p_bss_saved_ie(wl, P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len) { - /* channel offload require P2P IE for Probe request - * otherwise, we will use wl_cfgp2p_tx_action_frame directly. - * channel offload for action request frame - */ - - /* channel offload for action request frame */ - ack = wl_cfg80211_send_at_common_channel(wl, dev, af_params); - /* We need to retry Service discovery frames as they don't get retried immediately by supplicant*/ - if ((!ack) && (IS_GAS_REQ(sd_act_frm, action_frame->len))) { - for (retry = 1; retry < retry_cnt; retry++) { - WL_DBG(("Service Discovery action_frame retry %d len: %d chan %d category %d action %d\n", - retry, action_frame->len, af_params->channel, - sd_act_frm->category, sd_act_frm->action)); - ack = (wl_cfgp2p_tx_action_frame(wl, dev, - af_params, bssidx)) ? false : true; - if (ack) - break; - } - } - } else { - ack = (wl_cfgp2p_tx_action_frame(wl, dev, af_params, bssidx)) ? false : true; - if (!ack) { - for (retry = 1; retry < retry_cnt; retry++) { - ack = (wl_cfgp2p_tx_action_frame(wl, dev, - af_params, bssidx)) ? false : true; - if (ack) - break; - } - } - - } - cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL); - if (act_frm && act_frm->subtype == P2P_PAF_GON_CONF) { - wldev_iovar_setint(dev, "mpc", 1); - } - kfree(af_params); -exit: - return err; -} - - -static void -wl_cfg80211_mgmt_frame_register(struct wiphy *wiphy, struct net_device *dev, - u16 frame_type, bool reg) -{ - - WL_DBG(("%s: frame_type: %x, reg: %d\n", __func__, frame_type, reg)); - - if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ)) - return; - - return; -} - - -static s32 -wl_cfg80211_change_bss(struct wiphy *wiphy, - struct net_device *dev, - struct bss_parameters *params) -{ - if (params->use_cts_prot >= 0) { - } - - if (params->use_short_preamble >= 0) { - } - - if (params->use_short_slot_time >= 0) { - } - - if (params->basic_rates) { - } - - if (params->ap_isolate >= 0) { - } - - if (params->ht_opmode >= 0) { - } - - return 0; -} - -static s32 -wl_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type) -{ - s32 channel; - s32 err = BCME_OK; - struct wl_priv *wl = wiphy_priv(wiphy); - - if (wl->p2p_net == dev) { - dev = wl_to_prmry_ndev(wl); - } - channel = ieee80211_frequency_to_channel(chan->center_freq); - - if (wl_get_drv_status(wl, AP_CREATING, dev)) { - WL_TRACE(("<0> %s: as!!! in AP creating mode, save chan num:%d\n", - __FUNCTION__, channel)); - wl->hostapd_chan = channel; - if (channel == 14) - return err; /* hostapd requested ch auto-select, will be done later */ - } - - WL_DBG(("netdev_ifidx(%d), chan_type(%d) target channel(%d) \n", - dev->ifindex, channel_type, channel)); - err = wldev_ioctl(dev, WLC_SET_CHANNEL, &channel, sizeof(channel), true); - if (err < 0) { - WL_ERR(("WLC_SET_CHANNEL error %d chip may not be supporting this channel\n", err)); - } - return err; -} - -static s32 -wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx) -{ - s32 len = 0; - s32 err = BCME_OK; - u16 auth = WL_AUTH_OPEN_SYSTEM; /* d11 open authentication */ - u32 wsec; - u32 pval = 0; - u32 gval = 0; - u32 wpa_auth = 0; - u8* tmp; - wpa_suite_mcast_t *mcast; - wpa_suite_ucast_t *ucast; - wpa_suite_auth_key_mgmt_t *mgmt; - if (wpa2ie == NULL) - goto exit; - - WL_DBG(("Enter \n")); - len = wpa2ie->len; - /* check the mcast cipher */ - mcast = (wpa_suite_mcast_t *)&wpa2ie->data[WPA2_VERSION_LEN]; - tmp = mcast->oui; - switch (tmp[DOT11_OUI_LEN]) { - case WPA_CIPHER_NONE: - gval = 0; - break; - case WPA_CIPHER_WEP_40: - case WPA_CIPHER_WEP_104: - gval = WEP_ENABLED; - break; - case WPA_CIPHER_TKIP: - gval = TKIP_ENABLED; - break; - case WPA_CIPHER_AES_CCM: - gval = AES_ENABLED; - break; - default: - WL_ERR(("No Security Info\n")); - break; - } - len -= WPA_SUITE_LEN; - /* check the unicast cipher */ - ucast = (wpa_suite_ucast_t *)&mcast[1]; - ltoh16_ua(&ucast->count); - tmp = ucast->list[0].oui; - switch (tmp[DOT11_OUI_LEN]) { - case WPA_CIPHER_NONE: - pval = 0; - break; - case WPA_CIPHER_WEP_40: - case WPA_CIPHER_WEP_104: - pval = WEP_ENABLED; - break; - case WPA_CIPHER_TKIP: - pval = TKIP_ENABLED; - break; - case WPA_CIPHER_AES_CCM: - pval = AES_ENABLED; - break; - default: - WL_ERR(("No Security Info\n")); - } - /* FOR WPS , set SEC_OW_ENABLED */ - wsec = (pval | gval | SES_OW_ENABLED); - /* check the AKM */ - mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[1]; - ltoh16_ua(&mgmt->count); - tmp = (u8 *)&mgmt->list[0]; - switch (tmp[DOT11_OUI_LEN]) { - case RSN_AKM_NONE: - wpa_auth = WPA_AUTH_NONE; - break; - case RSN_AKM_UNSPECIFIED: - wpa_auth = WPA2_AUTH_UNSPECIFIED; - break; - case RSN_AKM_PSK: - wpa_auth = WPA2_AUTH_PSK; - break; - default: - WL_ERR(("No Key Mgmt Info\n")); - } - /* set auth */ - err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx); - if (err < 0) { - WL_ERR(("auth error %d\n", err)); - return BCME_ERROR; - } - /* set wsec */ - err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx); - if (err < 0) { - WL_ERR(("wsec error %d\n", err)); - return BCME_ERROR; - } - /* set upper-layer auth */ - err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx); - if (err < 0) { - WL_ERR(("wpa_auth error %d\n", err)); - return BCME_ERROR; - } -exit: - return 0; -} - -static s32 -wl_validate_wpaie(struct net_device *dev, wpa_ie_fixed_t *wpaie, s32 bssidx) -{ - wpa_suite_mcast_t *mcast; - wpa_suite_ucast_t *ucast; - wpa_suite_auth_key_mgmt_t *mgmt; - u16 auth = WL_AUTH_OPEN_SYSTEM; /* d11 open authentication */ - u16 count; - s32 err = BCME_OK; - s32 len = 0; - u32 i; - u32 wsec; - u32 pval = 0; - u32 gval = 0; - u32 wpa_auth = 0; - u32 tmp = 0; - - if (wpaie == NULL) - goto exit; - WL_DBG(("Enter \n")); - len = wpaie->length; /* value length */ - len -= WPA_IE_TAG_FIXED_LEN; - /* check for multicast cipher suite */ - if (len < WPA_SUITE_LEN) { - WL_INFO(("no multicast cipher suite\n")); - goto exit; - } - - /* pick up multicast cipher */ - mcast = (wpa_suite_mcast_t *)&wpaie[1]; - len -= WPA_SUITE_LEN; - if (!bcmp(mcast->oui, WPA_OUI, WPA_OUI_LEN)) { - if (IS_WPA_CIPHER(mcast->type)) { - tmp = 0; - switch (mcast->type) { - case WPA_CIPHER_NONE: - tmp = 0; - break; - case WPA_CIPHER_WEP_40: - case WPA_CIPHER_WEP_104: - tmp = WEP_ENABLED; - break; - case WPA_CIPHER_TKIP: - tmp = TKIP_ENABLED; - break; - case WPA_CIPHER_AES_CCM: - tmp = AES_ENABLED; - break; - default: - WL_ERR(("No Security Info\n")); - } - gval |= tmp; - } - } - /* Check for unicast suite(s) */ - if (len < WPA_IE_SUITE_COUNT_LEN) { - WL_INFO(("no unicast suite\n")); - goto exit; - } - /* walk thru unicast cipher list and pick up what we recognize */ - ucast = (wpa_suite_ucast_t *)&mcast[1]; - count = ltoh16_ua(&ucast->count); - len -= WPA_IE_SUITE_COUNT_LEN; - for (i = 0; i < count && len >= WPA_SUITE_LEN; - i++, len -= WPA_SUITE_LEN) { - if (!bcmp(ucast->list[i].oui, WPA_OUI, WPA_OUI_LEN)) { - if (IS_WPA_CIPHER(ucast->list[i].type)) { - tmp = 0; - switch (ucast->list[i].type) { - case WPA_CIPHER_NONE: - tmp = 0; - break; - case WPA_CIPHER_WEP_40: - case WPA_CIPHER_WEP_104: - tmp = WEP_ENABLED; - break; - case WPA_CIPHER_TKIP: - tmp = TKIP_ENABLED; - break; - case WPA_CIPHER_AES_CCM: - tmp = AES_ENABLED; - break; - default: - WL_ERR(("No Security Info\n")); - } - pval |= tmp; - } - } - } - len -= (count - i) * WPA_SUITE_LEN; - /* Check for auth key management suite(s) */ - if (len < WPA_IE_SUITE_COUNT_LEN) { - WL_INFO((" no auth key mgmt suite\n")); - goto exit; - } - /* walk thru auth management suite list and pick up what we recognize */ - mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[count]; - count = ltoh16_ua(&mgmt->count); - len -= WPA_IE_SUITE_COUNT_LEN; - for (i = 0; i < count && len >= WPA_SUITE_LEN; - i++, len -= WPA_SUITE_LEN) { - if (!bcmp(mgmt->list[i].oui, WPA_OUI, WPA_OUI_LEN)) { - if (IS_WPA_AKM(mgmt->list[i].type)) { - tmp = 0; - switch (mgmt->list[i].type) { - case RSN_AKM_NONE: - tmp = WPA_AUTH_NONE; - break; - case RSN_AKM_UNSPECIFIED: - tmp = WPA_AUTH_UNSPECIFIED; - break; - case RSN_AKM_PSK: - tmp = WPA_AUTH_PSK; - break; - default: - WL_ERR(("No Key Mgmt Info\n")); - } - wpa_auth |= tmp; - } - } - - } - /* FOR WPS , set SEC_OW_ENABLED */ - wsec = (pval | gval | SES_OW_ENABLED); - /* set auth */ - err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx); - if (err < 0) { - WL_ERR(("auth error %d\n", err)); - return BCME_ERROR; - } - /* set wsec */ - err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx); - if (err < 0) { - WL_ERR(("wsec error %d\n", err)); - return BCME_ERROR; - } - /* set upper-layer auth */ - err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx); - if (err < 0) { - WL_ERR(("wpa_auth error %d\n", err)); - return BCME_ERROR; - } -exit: - return 0; -} - -static s32 -wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev, - struct beacon_parameters *info) -{ - s32 err = BCME_OK; - bcm_tlv_t *ssid_ie; - wlc_ssid_t ssid; - struct wl_priv *wl = wiphy_priv(wiphy); - struct wl_join_params join_params; - wpa_ie_fixed_t *wps_ie; - wpa_ie_fixed_t *wpa_ie; - bcm_tlv_t *wpa2_ie; - wifi_p2p_ie_t *p2p_ie; - wifi_wfd_ie_t *wfd_ie; - bool is_bssup = false; - bool update_bss = false; - bool pbc = false; - u16 wpsie_len = 0; - u16 p2pie_len = 0; - u32 wfdie_len = 0; - u8 beacon_ie[IE_MAX_LEN]; - s32 ie_offset = 0; - s32 bssidx = 0; - s32 infra = 1; - s32 join_params_size = 0; - s32 ap = 0; - WL_DBG(("interval (%d) dtim_period (%d) head_len (%d) tail_len (%d)\n", - info->interval, info->dtim_period, info->head_len, info->tail_len)); - - if (wl->p2p_net == dev) { - dev = wl_to_prmry_ndev(wl); - } - - bssidx = wl_cfgp2p_find_idx(wl, dev); - if (p2p_is_on(wl) && - (bssidx == wl_to_p2p_bss_bssidx(wl, - P2PAPI_BSSCFG_CONNECTION))) { - memset(beacon_ie, 0, sizeof(beacon_ie)); - /* We don't need to set beacon for P2P_GO, - * but need to parse ssid from beacon_parameters - * because there is no way to set ssid - */ - ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN; - /* find the SSID */ - if ((ssid_ie = bcm_parse_tlvs((u8 *)&info->head[ie_offset], - info->head_len - ie_offset, - DOT11_MNG_SSID_ID)) != NULL) { - memcpy(wl->p2p->ssid.SSID, ssid_ie->data, ssid_ie->len); - wl->p2p->ssid.SSID_len = ssid_ie->len; - WL_DBG(("SSID (%s) in Head \n", ssid_ie->data)); - - } else { - WL_ERR(("No SSID in beacon \n")); - } - - /* find the WPSIE */ - if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail, info->tail_len)) != NULL) { - wpsie_len = wps_ie->length + WPA_RSN_IE_TAG_FIXED_LEN; - /* - * Should be compared with saved ie before saving it - */ - wl_validate_wps_ie((char *) wps_ie, &pbc); - memcpy(beacon_ie, wps_ie, wpsie_len); - } else { - WL_ERR(("No WPSIE in beacon \n")); - } - - - /* find the P2PIE */ - if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)info->tail, info->tail_len)) != NULL) { - /* Total length of P2P Information Element */ - p2pie_len = p2p_ie->len + sizeof(p2p_ie->len) + sizeof(p2p_ie->id); - memcpy(&beacon_ie[wpsie_len], p2p_ie, p2pie_len); - - } else { - WL_ERR(("No P2PIE in beacon \n")); - } - /* find the WFD IEs */ - if ((wfd_ie = wl_cfgp2p_find_wfdie((u8 *)info->tail, info->tail_len)) != NULL) { - /* Total length of P2P Information Element */ - wfdie_len = wfd_ie->len + sizeof(wfd_ie->len) + sizeof(wfd_ie->id); - if ((wpsie_len + p2pie_len + wfdie_len) < IE_MAX_LEN) { - memcpy(&beacon_ie[wpsie_len + p2pie_len], wfd_ie, wfdie_len); - } else { - WL_ERR(("Found WFD IE but there is no space, (%d)(%d)(%d)\n", - wpsie_len, p2pie_len, wfdie_len)); - wfdie_len = 0; - } - } else { - WL_ERR(("No WFDIE in beacon \n")); - } - /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */ - wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc); - wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG, - beacon_ie, wpsie_len + p2pie_len + wfdie_len); - - /* find the RSN_IE */ - if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len, - DOT11_MNG_RSN_ID)) != NULL) { - WL_DBG((" WPA2 IE is found\n")); - } - is_bssup = wl_cfgp2p_bss_isup(dev, bssidx); - - if (!is_bssup && (wpa2_ie != NULL)) { - wldev_iovar_setint(dev, "mpc", 0); - if ((err = wl_validate_wpa2ie(dev, wpa2_ie, bssidx)) < 0) { - WL_ERR(("WPA2 IE parsing error")); - goto exit; - } - err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true); - if (err < 0) { - WL_ERR(("SET INFRA error %d\n", err)); - goto exit; - } - err = wldev_iovar_setbuf_bsscfg(dev, "ssid", &wl->p2p->ssid, - sizeof(wl->p2p->ssid), wl->ioctl_buf, WLC_IOCTL_MAXLEN, - bssidx, &wl->ioctl_buf_sync); - if (err < 0) { - WL_ERR(("GO SSID setting error %d\n", err)); - goto exit; - } - if ((err = wl_cfgp2p_bss(wl, dev, bssidx, 1)) < 0) { - WL_ERR(("GO Bring up error %d\n", err)); - goto exit; - } - } - } else if (wl_get_drv_status(wl, AP_CREATING, dev)) { - ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN; - ap = 1; - /* find the SSID */ - if ((ssid_ie = bcm_parse_tlvs((u8 *)&info->head[ie_offset], - info->head_len - ie_offset, - DOT11_MNG_SSID_ID)) != NULL) { - memset(&ssid, 0, sizeof(wlc_ssid_t)); - memcpy(ssid.SSID, ssid_ie->data, ssid_ie->len); - WL_DBG(("SSID is (%s) in Head \n", ssid.SSID)); - ssid.SSID_len = ssid_ie->len; - wldev_iovar_setint(dev, "mpc", 0); - wldev_ioctl(dev, WLC_DOWN, &ap, sizeof(s32), true); - wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true); - if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), true)) < 0) { - WL_ERR(("setting AP mode failed %d \n", err)); - return err; - } - - /* if requested, do softap ch autoselect */ - if (wl->hostapd_chan == 14) { - int auto_chan; - if ((err = wldev_get_auto_channel(dev, &auto_chan)) != 0) { - WL_ERR(("softap: auto chan select failed," - " will use ch 6\n")); - auto_chan = 6; - } else { - printf("<0>softap: got auto ch:%d\n", auto_chan); - } - err = wldev_ioctl(dev, WLC_SET_CHANNEL, - &auto_chan, sizeof(auto_chan), true); - if (err < 0) { - WL_ERR(("softap: WLC_SET_CHANNEL error %d chip" - " may not be supporting this channel\n", err)); - return err; - } - } - - /* find the RSN_IE */ - if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len, - DOT11_MNG_RSN_ID)) != NULL) { - WL_DBG((" WPA2 IE is found\n")); - } - /* find the WPA_IE */ - if ((wpa_ie = wl_cfgp2p_find_wpaie((u8 *)info->tail, - info->tail_len)) != NULL) { - WL_DBG((" WPA IE is found\n")); - } - if ((wpa_ie != NULL || wpa2_ie != NULL)) { - if (wl_validate_wpa2ie(dev, wpa2_ie, bssidx) < 0 || - wl_validate_wpaie(dev, wpa_ie, bssidx) < 0) { - wl->ap_info->security_mode = false; - return BCME_ERROR; - } - wl->ap_info->security_mode = true; - if (wl->ap_info->rsn_ie) { - kfree(wl->ap_info->rsn_ie); - wl->ap_info->rsn_ie = NULL; - } - if (wl->ap_info->wpa_ie) { - kfree(wl->ap_info->wpa_ie); - wl->ap_info->wpa_ie = NULL; - } - if (wl->ap_info->wps_ie) { - kfree(wl->ap_info->wps_ie); - wl->ap_info->wps_ie = NULL; - } - if (wpa_ie != NULL) { - /* WPAIE */ - wl->ap_info->rsn_ie = NULL; - wl->ap_info->wpa_ie = kmemdup(wpa_ie, - wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN, - GFP_KERNEL); - } else { - /* RSNIE */ - wl->ap_info->wpa_ie = NULL; - wl->ap_info->rsn_ie = kmemdup(wpa2_ie, - wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN, - GFP_KERNEL); - } - } else - wl->ap_info->security_mode = false; - /* find the WPSIE */ - if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail, - info->tail_len)) != NULL) { - wpsie_len = wps_ie->length +WPA_RSN_IE_TAG_FIXED_LEN; - /* - * Should be compared with saved ie before saving it - */ - wl_validate_wps_ie((char *) wps_ie, &pbc); - memcpy(beacon_ie, wps_ie, wpsie_len); - wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG, - beacon_ie, wpsie_len); - wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL); - /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */ - wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc); - } else { - WL_DBG(("No WPSIE in beacon \n")); - } - if (info->interval) { - if ((err = wldev_ioctl(dev, WLC_SET_BCNPRD, - &info->interval, sizeof(s32), true)) < 0) { - WL_ERR(("Beacon Interval Set Error, %d\n", err)); - return err; - } - } - if (info->dtim_period) { - if ((err = wldev_ioctl(dev, WLC_SET_DTIMPRD, - &info->dtim_period, sizeof(s32), true)) < 0) { - WL_ERR(("DTIM Interval Set Error, %d\n", err)); - return err; - } - } - err = wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), true); - if (unlikely(err)) { - WL_ERR(("WLC_UP error (%d)\n", err)); - return err; - } - memset(&join_params, 0, sizeof(join_params)); - /* join parameters starts with ssid */ - join_params_size = sizeof(join_params.ssid); - memcpy(join_params.ssid.SSID, ssid.SSID, ssid.SSID_len); - join_params.ssid.SSID_len = htod32(ssid.SSID_len); - /* create softap */ - if ((err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, - join_params_size, true)) == 0) { - wl_clr_drv_status(wl, AP_CREATING, dev); - wl_set_drv_status(wl, AP_CREATED, dev); - } - } - } else if (wl_get_drv_status(wl, AP_CREATED, dev)) { - ap = 1; - /* find the WPSIE */ - if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail, info->tail_len)) != NULL) { - wpsie_len = wps_ie->length + WPA_RSN_IE_TAG_FIXED_LEN; - /* - * Should be compared with saved ie before saving it - */ - wl_validate_wps_ie((char *) wps_ie, &pbc); - memcpy(beacon_ie, wps_ie, wpsie_len); - wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG, - beacon_ie, wpsie_len); - if (wl->ap_info->wps_ie && - memcmp(wl->ap_info->wps_ie, wps_ie, wpsie_len)) { - WL_DBG((" WPS IE is changed\n")); - kfree(wl->ap_info->wps_ie); - wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL); - /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */ - wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc); - } else if (wl->ap_info->wps_ie == NULL) { - WL_DBG((" WPS IE is added\n")); - wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL); - /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */ - wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc); - } - /* find the RSN_IE */ - if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len, - DOT11_MNG_RSN_ID)) != NULL) { - WL_DBG((" WPA2 IE is found\n")); - } - /* find the WPA_IE */ - if ((wpa_ie = wl_cfgp2p_find_wpaie((u8 *)info->tail, - info->tail_len)) != NULL) { - WL_DBG((" WPA IE is found\n")); - } - if ((wpa_ie != NULL || wpa2_ie != NULL)) { - if (!wl->ap_info->security_mode) { - /* change from open mode to security mode */ - update_bss = true; - if (wpa_ie != NULL) { - wl->ap_info->wpa_ie = kmemdup(wpa_ie, - wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN, - GFP_KERNEL); - } else { - wl->ap_info->rsn_ie = kmemdup(wpa2_ie, - wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN, - GFP_KERNEL); - } - } else if (wl->ap_info->wpa_ie) { - /* change from WPA mode to WPA2 mode */ - if (wpa2_ie != NULL) { - update_bss = true; - kfree(wl->ap_info->wpa_ie); - wl->ap_info->rsn_ie = kmemdup(wpa2_ie, - wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN, - GFP_KERNEL); - wl->ap_info->wpa_ie = NULL; - } - else if (memcmp(wl->ap_info->wpa_ie, - wpa_ie, wpa_ie->length + - WPA_RSN_IE_TAG_FIXED_LEN)) { - kfree(wl->ap_info->wpa_ie); - update_bss = true; - wl->ap_info->wpa_ie = kmemdup(wpa_ie, - wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN, - GFP_KERNEL); - wl->ap_info->rsn_ie = NULL; - } - } else { - /* change from WPA2 mode to WPA mode */ - if (wpa_ie != NULL) { - update_bss = true; - kfree(wl->ap_info->rsn_ie); - wl->ap_info->rsn_ie = NULL; - wl->ap_info->wpa_ie = kmemdup(wpa_ie, - wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN, - GFP_KERNEL); - } else if (memcmp(wl->ap_info->rsn_ie, - wpa2_ie, wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN)) { - update_bss = true; - kfree(wl->ap_info->rsn_ie); - wl->ap_info->rsn_ie = kmemdup(wpa2_ie, - wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN, - GFP_KERNEL); - wl->ap_info->wpa_ie = NULL; - } - } - if (update_bss) { - wl->ap_info->security_mode = true; - wl_cfgp2p_bss(wl, dev, bssidx, 0); - if (wl_validate_wpa2ie(dev, wpa2_ie, bssidx) < 0 || - wl_validate_wpaie(dev, wpa_ie, bssidx) < 0) { - return BCME_ERROR; - } - wl_cfgp2p_bss(wl, dev, bssidx, 1); - } - } - } else { - WL_ERR(("No WPSIE in beacon \n")); - } - } -exit: - if (err) - wldev_iovar_setint(dev, "mpc", 1); - return err; -} - -#ifdef WL_SCHED_SCAN -#define PNO_TIME 30 -#define PNO_REPEAT 4 -#define PNO_FREQ_EXPO_MAX 2 -int wl_cfg80211_sched_scan_start(struct wiphy *wiphy, - struct net_device *dev, - struct cfg80211_sched_scan_request *request) -{ - ushort pno_time = PNO_TIME; - int pno_repeat = PNO_REPEAT; - int pno_freq_expo_max = PNO_FREQ_EXPO_MAX; - wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT]; - struct wl_priv *wl = wiphy_priv(wiphy); - struct cfg80211_ssid *ssid = NULL; - int ssid_count = 0; - int i; - int ret = 0; - - WL_DBG(("Enter n_match_sets:%d n_ssids:%d \n", - request->n_match_sets, request->n_ssids)); - WL_DBG(("ssids:%d pno_time:%d pno_repeat:%d pno_freq:%d \n", - request->n_ssids, pno_time, pno_repeat, pno_freq_expo_max)); - -#if defined(WL_ENABLE_P2P_IF) - /* While GO is operational, PNO is not supported */ - if (dhd_cfg80211_get_opmode(wl) & P2P_GO_ENABLED) { - WL_DBG(("PNO not enabled! op_mode: P2P GO")); - return -1; - } -#endif - - if (!request || !request->n_ssids || !request->n_match_sets) { - WL_ERR(("Invalid sched scan req!! n_ssids:%d \n", request->n_ssids)); - return -EINVAL; - } - - memset(&ssids_local, 0, sizeof(ssids_local)); - - if (request->n_match_sets > 0) { - for (i = 0; i < request->n_match_sets; i++) { - ssid = &request->match_sets[i].ssid; - memcpy(ssids_local[i].SSID, ssid->ssid, ssid->ssid_len); - ssids_local[i].SSID_len = ssid->ssid_len; - WL_DBG((">>> PNO filter set for ssid (%s) \n", ssid->ssid)); - ssid_count++; - } - } - - if (request->n_ssids > 0) { - for (i = 0; i < request->n_ssids; i++) { - /* Active scan req for ssids */ - WL_DBG((">>> Active scan req for ssid (%s) \n", request->ssids[i].ssid)); - - /* match_set ssids is a supert set of n_ssid list, so we need - * not add these set seperately - */ - } - } - - if (ssid_count) { - if ((ret = dhd_dev_pno_set(dev, ssids_local, request->n_match_sets, - pno_time, pno_repeat, pno_freq_expo_max)) < 0) { - WL_ERR(("PNO setup failed!! ret=%d \n", ret)); - return -EINVAL; - } - - /* Enable the PNO */ - if (dhd_dev_pno_enable(dev, 1) < 0) { - WL_ERR(("PNO enable failed!! ret=%d \n", ret)); - return -EINVAL; - } - wl->sched_scan_req = request; - } else { - return -EINVAL; - } - - return 0; -} - -int wl_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev) -{ - struct wl_priv *wl = wiphy_priv(wiphy); - - WL_DBG(("Enter \n")); - - if (dhd_dev_pno_enable(dev, 0) < 0) - WL_ERR(("PNO disable failed")); - - if (dhd_dev_pno_reset(dev) < 0) - WL_ERR(("PNO reset failed")); - - if (wl->scan_request && wl->sched_scan_running) { - wl_notify_escan_complete(wl, dev, true, true); - } - - wl->sched_scan_req = NULL; - wl->sched_scan_running = FALSE; - - return 0; -} -#endif /* WL_SCHED_SCAN */ - -static struct cfg80211_ops wl_cfg80211_ops = { - .add_virtual_intf = wl_cfg80211_add_virtual_iface, - .del_virtual_intf = wl_cfg80211_del_virtual_iface, - .change_virtual_intf = wl_cfg80211_change_virtual_iface, - .scan = wl_cfg80211_scan, - .set_wiphy_params = wl_cfg80211_set_wiphy_params, - .join_ibss = wl_cfg80211_join_ibss, - .leave_ibss = wl_cfg80211_leave_ibss, - .get_station = wl_cfg80211_get_station, - .set_tx_power = wl_cfg80211_set_tx_power, - .get_tx_power = wl_cfg80211_get_tx_power, - .add_key = wl_cfg80211_add_key, - .del_key = wl_cfg80211_del_key, - .get_key = wl_cfg80211_get_key, - .set_default_key = wl_cfg80211_config_default_key, - .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key, - .set_power_mgmt = wl_cfg80211_set_power_mgmt, - .connect = wl_cfg80211_connect, - .disconnect = wl_cfg80211_disconnect, - .suspend = wl_cfg80211_suspend, - .resume = wl_cfg80211_resume, - .set_pmksa = wl_cfg80211_set_pmksa, - .del_pmksa = wl_cfg80211_del_pmksa, - .flush_pmksa = wl_cfg80211_flush_pmksa, - .remain_on_channel = wl_cfg80211_remain_on_channel, - .cancel_remain_on_channel = wl_cfg80211_cancel_remain_on_channel, - .mgmt_tx = wl_cfg80211_mgmt_tx, - .mgmt_frame_register = wl_cfg80211_mgmt_frame_register, - .change_bss = wl_cfg80211_change_bss, - .set_channel = wl_cfg80211_set_channel, - .set_beacon = wl_cfg80211_add_set_beacon, - .add_beacon = wl_cfg80211_add_set_beacon, - .mgmt_tx_cancel_wait = wl_cfg80211_mgmt_tx_cancel_wait, -#ifdef WL_SCHED_SCAN - .sched_scan_start = wl_cfg80211_sched_scan_start, - .sched_scan_stop = wl_cfg80211_sched_scan_stop, -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ -}; - -s32 wl_mode_to_nl80211_iftype(s32 mode) -{ - s32 err = 0; - - switch (mode) { - case WL_MODE_BSS: - return NL80211_IFTYPE_STATION; - case WL_MODE_IBSS: - return NL80211_IFTYPE_ADHOC; - case WL_MODE_AP: - return NL80211_IFTYPE_AP; - default: - return NL80211_IFTYPE_UNSPECIFIED; - } - - return err; -} - -static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev) -{ - s32 err = 0; - wdev->wiphy = - wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv)); - if (unlikely(!wdev->wiphy)) { - WL_ERR(("Couldn not allocate wiphy device\n")); - err = -ENOMEM; - return err; - } - set_wiphy_dev(wdev->wiphy, sdiofunc_dev); - wdev->wiphy->max_scan_ie_len = WL_SCAN_IE_LEN_MAX; - /* Report how many SSIDs Driver can support per Scan request */ - wdev->wiphy->max_scan_ssids = WL_SCAN_PARAMS_SSID_MAX; - wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; -#ifdef WL_SCHED_SCAN - wdev->wiphy->max_sched_scan_ssids = MAX_PFN_LIST_COUNT; - wdev->wiphy->max_match_sets = MAX_PFN_LIST_COUNT; - wdev->wiphy->max_sched_scan_ie_len = WL_SCAN_IE_LEN_MAX; - wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; -#endif /* WL_SCHED_SCAN */ - wdev->wiphy->interface_modes = - BIT(NL80211_IFTYPE_STATION) - | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR); - - wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; - /* wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; - set in runtime */ - wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; - wdev->wiphy->cipher_suites = __wl_cipher_suites; - wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); - wdev->wiphy->max_remain_on_channel_duration = 5000; - wdev->wiphy->mgmt_stypes = wl_cfg80211_default_mgmt_stypes; -#ifndef WL_POWERSAVE_DISABLED - wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; -#else - wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; -#endif /* !WL_POWERSAVE_DISABLED */ - wdev->wiphy->flags |= WIPHY_FLAG_NETNS_OK | - WIPHY_FLAG_4ADDR_AP | -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39) - WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS | -#endif - WIPHY_FLAG_4ADDR_STATION; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) - /* wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; */ -#endif - /* AP_SME flag can be advertised to remove patch from wpa_supplicant */ - wdev->wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME; - WL_DBG(("Registering custom regulatory)\n")); - wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; - wiphy_apply_custom_regulatory(wdev->wiphy, &brcm_regdom); - /* Now we can register wiphy with cfg80211 module */ - err = wiphy_register(wdev->wiphy); - if (unlikely(err < 0)) { - WL_ERR(("Couldn not register wiphy device (%d)\n", err)); - wiphy_free(wdev->wiphy); - } - return err; -} - -static void wl_free_wdev(struct wl_priv *wl) -{ - struct wireless_dev *wdev = wl->wdev; - struct wiphy *wiphy; - if (!wdev) { - WL_ERR(("wdev is invalid\n")); - return; - } - wiphy = wdev->wiphy; - wiphy_unregister(wdev->wiphy); - wdev->wiphy->dev.parent = NULL; - - wl_delete_all_netinfo(wl); - wiphy_free(wiphy); - /* PLEASE do NOT call any function after wiphy_free, the driver's private structure "wl", - * which is the private part of wiphy, has been freed in wiphy_free !!!!!!!!!!! - */ -} - -static s32 wl_inform_bss(struct wl_priv *wl) -{ - struct wl_scan_results *bss_list; - struct wl_bss_info *bi = NULL; /* must be initialized */ - s32 err = 0; - s32 i; - - bss_list = wl->bss_list; - WL_DBG(("scanned AP count (%d)\n", bss_list->count)); - bi = next_bss(bss_list, bi); - for_each_bss(bss_list, bi, i) { - err = wl_inform_single_bss(wl, bi); - if (unlikely(err)) - break; - } - return err; -} - -static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) -{ - struct wiphy *wiphy = wiphy_from_scan(wl); - struct ieee80211_mgmt *mgmt; - struct ieee80211_channel *channel; - struct ieee80211_supported_band *band; - struct wl_cfg80211_bss_info *notif_bss_info; - struct wl_scan_req *sr = wl_to_sr(wl); - struct beacon_proberesp *beacon_proberesp; - struct cfg80211_bss *cbss = NULL; - s32 mgmt_type; - s32 signal; - u32 freq; - s32 err = 0; - - if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) { - WL_DBG(("Beacon is larger than buffer. Discarding\n")); - return err; - } - notif_bss_info = kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - - sizeof(u8) + WL_BSS_INFO_MAX, GFP_KERNEL); - if (unlikely(!notif_bss_info)) { - WL_ERR(("notif_bss_info alloc failed\n")); - return -ENOMEM; - } - mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf; - notif_bss_info->channel = - bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec); - - if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL) - band = wiphy->bands[IEEE80211_BAND_2GHZ]; - else - band = wiphy->bands[IEEE80211_BAND_5GHZ]; - if (!band) { - WL_ERR(("No valid band")); - kfree(notif_bss_info); - return -EINVAL; - } - notif_bss_info->rssi = dtoh16(bi->RSSI); - memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN); - mgmt_type = (bi->flags & WL_BSS_FLAGS_FROM_BEACON) ? - IEEE80211_STYPE_BEACON : IEEE80211_STYPE_PROBE_RESP; - - if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) { - mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | mgmt_type); - } - beacon_proberesp = wl->active_scan ? - (struct beacon_proberesp *)&mgmt->u.probe_resp : - (struct beacon_proberesp *)&mgmt->u.beacon; - beacon_proberesp->timestamp = 0; - beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period); - beacon_proberesp->capab_info = cpu_to_le16(bi->capability); - wl_rst_ie(wl); - - wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length); - wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX - - offsetof(struct wl_cfg80211_bss_info, frame_buf)); - notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt, - u.beacon.variable) + wl_get_ielen(wl); -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) - freq = ieee80211_channel_to_frequency(notif_bss_info->channel); -#else - freq = ieee80211_channel_to_frequency(notif_bss_info->channel, band->band); -#endif - channel = ieee80211_get_channel(wiphy, freq); - if (!channel) { - WL_ERR(("No valid channel: %u\n", freq)); - kfree(notif_bss_info); - return -EINVAL; - } - - WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM" - "mgmt_type %d frame_len %d\n", bi->SSID, - notif_bss_info->rssi, notif_bss_info->channel, - mgmt->u.beacon.capab_info, &bi->BSSID, mgmt_type, - notif_bss_info->frame_len)); - - signal = notif_bss_info->rssi * 100; - - if (!mgmt->u.probe_resp.timestamp) { - struct timespec ts; - - get_monotonic_boottime(&ts); - mgmt->u.probe_resp.timestamp = ((u64)ts.tv_sec * 1000000) - + ts.tv_nsec / 1000; - } - - cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt, - le16_to_cpu(notif_bss_info->frame_len), signal, GFP_KERNEL); - if (unlikely(!cbss)) { - WL_ERR(("cfg80211_inform_bss_frame error\n")); - kfree(notif_bss_info); - return -EINVAL; - } - - cfg80211_put_bss(cbss); - kfree(notif_bss_info); - - return err; -} - -static s32 wl_inform_ibss(struct wl_priv *wl, const u8 *bssid) -{ - struct net_device *ndev = wl_to_prmry_ndev(wl); - struct wiphy *wiphy = wl_to_wiphy(wl); - struct wl_bss_info *bi = NULL; - struct ieee80211_channel *notify_channel; - struct ieee80211_supported_band *band; - struct cfg80211_bss *bss; - s32 err = 0; - u16 channel; - u32 freq; - u32 wsec = 0; - u16 notify_capability; - u16 notify_interval; - u8 *notify_ie; - size_t notify_ielen; - s32 notify_signal; - - WL_TRACE(("Enter\n")); - - if (wl->scan_request) { - wl_notify_escan_complete(wl, ndev, true, true); - } - - mutex_lock(&wl->usr_sync); - - *(u32 *)wl->extra_buf = htod32(WL_EXTRA_BUF_MAX); - err = wldev_ioctl(ndev, WLC_GET_BSS_INFO, wl->extra_buf, - WL_EXTRA_BUF_MAX, false); - if (err) { - WL_ERR(("Failed to get bss info for IBSS\n")); - err = -EIO; - goto CleanUp; - } - bi = (struct wl_bss_info *)(wl->extra_buf + 4); - - if (memcmp(bssid, &bi->BSSID, ETHER_ADDR_LEN)) { - WL_ERR(("BSSID mismatch: Inform %02x:%02x:%02x:%02x:%02x:%02x," - "%02x:%02x:%02x:%02x:%02x:%02x\n", - bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5], - bi->BSSID.octet[0], bi->BSSID.octet[1], bi->BSSID.octet[2], - bi->BSSID.octet[3], bi->BSSID.octet[4], - bi->BSSID.octet[5])); - err = -EINVAL; - goto CleanUp; - } - - err = wldev_iovar_getint(ndev, "wsec", &wsec); - if (err) { - WL_ERR(("wsec failed: %d\n", err)); - err = -EIO; - goto CleanUp; - } - - channel = bi->ctl_ch ? bi->ctl_ch : - CHSPEC_CHANNEL(dtohchanspec(bi->chanspec)); - if (channel <= CH_MAX_2G_CHANNEL) - band = wiphy->bands[IEEE80211_BAND_2GHZ]; - else - band = wiphy->bands[IEEE80211_BAND_5GHZ]; - -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) - freq = ieee80211_channel_to_frequency(channel); - (void)band->band; -#else - freq = ieee80211_channel_to_frequency(channel, band->band); -#endif - notify_channel = ieee80211_get_channel(wiphy, freq); - - notify_capability = dtoh16(bi->capability); - notify_interval = dtoh16(bi->beacon_period); - notify_ie = (u8 *)bi + dtoh16(bi->ie_offset); - notify_ielen = dtoh32(bi->ie_length); - notify_signal = (int16)dtoh16(bi->RSSI) * 100; - - if (wl->p2p_supported) { - notify_capability |= DOT11_CAP_IBSS; - if (wsec) - notify_capability |= DOT11_CAP_PRIVACY; - } - - WL_DBG(("BSSID %02x:%02x:%02x:%02x:%02x:%02x", - bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5])); - WL_INFO(("channel: %d(%d)\n", channel, freq)); - WL_INFO(("capability: %X\n", notify_capability)); - WL_INFO(("beacon interval: %d ms\n", notify_interval)); - WL_INFO(("signal: %d dBm\n", notify_signal)); - WL_INFO(("ie_len: %d\n", notify_ielen)); - bss = cfg80211_inform_bss(wiphy, notify_channel, bssid, 0, - notify_capability, notify_interval, - notify_ie, notify_ielen, notify_signal, GFP_KERNEL); - if (!bss) { - WL_ERR(("cfg80211_inform_bss() Failed\n")); - err = -ENOMEM; - goto CleanUp; - } - - cfg80211_put_bss(bss); - err = 0; - -CleanUp: - - mutex_unlock(&wl->usr_sync); - - WL_TRACE(("Exit\n")); - return err; -} - -static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev) -{ - u32 event = ntoh32(e->event_type); - u32 status = ntoh32(e->status); - u16 flags = ntoh16(e->flags); - - WL_DBG(("event %d, status %d flags %x\n", event, status, flags)); - if (event == WLC_E_SET_SSID) { - if (status == WLC_E_STATUS_SUCCESS) { - return true; - } - } else if (event == WLC_E_LINK) { - if (flags & WLC_EVENT_MSG_LINK) - if (!wl_is_ibssmode(wl, ndev)) - return true; - } - - WL_DBG(("wl_is_linkup false\n")); - return false; -} - -static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e) -{ - u32 event = ntoh32(e->event_type); - u16 flags = ntoh16(e->flags); - - if (event == WLC_E_DEAUTH_IND || - event == WLC_E_DISASSOC_IND || - event == WLC_E_DISASSOC || - event == WLC_E_DEAUTH) { - return true; - } else if (event == WLC_E_LINK) { - if (!(flags & WLC_EVENT_MSG_LINK)) - return true; - } - - return false; -} - -static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e) -{ - u32 event = ntoh32(e->event_type); - u32 status = ntoh32(e->status); - - if (event == WLC_E_LINK && status == WLC_E_STATUS_NO_NETWORKS) - return true; - if (event == WLC_E_SET_SSID && status != WLC_E_STATUS_SUCCESS) - return true; - - return false; -} - -/* The mainline kernel >= 3.2.0 has support for indicating new/del station - * to AP/P2P GO via events. If this change is backported to kernel for which - * this driver is being built, then define WL_CFG80211_STA_EVENT. You - * should use this new/del sta event mechanism for BRCM supplicant >= 22. - */ -static s32 -wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) -{ - s32 err = 0; - u32 event = ntoh32(e->event_type); - u32 reason = ntoh32(e->reason); - u32 len = ntoh32(e->datalen); - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !defined(WL_CFG80211_STA_EVENT) - bool isfree = false; - u8 *mgmt_frame; - u8 bsscfgidx = e->bsscfgidx; - s32 freq; - s32 channel; - u8 body[WL_FRAME_LEN]; - u16 fc = 0; - struct ieee80211_supported_band *band; - struct ether_addr da; - struct ether_addr bssid; - struct wiphy *wiphy = wl_to_wiphy(wl); - channel_info_t ci; -#else - struct station_info sinfo; -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !WL_CFG80211_STA_EVENT */ - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !defined(WL_CFG80211_STA_EVENT) - memset(body, 0, sizeof(body)); - memset(&bssid, 0, ETHER_ADDR_LEN); - WL_DBG(("Enter event %d ndev %p\n", event, ndev)); - if (wl_get_mode_by_netdev(wl, ndev) == WL_INVALID) - return WL_INVALID; - - if (len > WL_FRAME_LEN) { - WL_ERR(("Received frame length %d from dongle is greater than" - " allocated body buffer len %d", len, WL_FRAME_LEN)); - goto exit; - } - memcpy(body, data, len); - wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr", - NULL, 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bsscfgidx, &wl->ioctl_buf_sync); - memcpy(da.octet, wl->ioctl_buf, ETHER_ADDR_LEN); - err = wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false); - switch (event) { - case WLC_E_ASSOC_IND: - fc = FC_ASSOC_REQ; - break; - case WLC_E_REASSOC_IND: - fc = FC_REASSOC_REQ; - break; - case WLC_E_DISASSOC_IND: - fc = FC_DISASSOC; - break; - case WLC_E_DEAUTH_IND: - fc = FC_DISASSOC; - break; - case WLC_E_DEAUTH: - fc = FC_DISASSOC; - break; - default: - fc = 0; - goto exit; - } - if ((err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &ci, sizeof(ci), false))) - return err; - - channel = dtoh32(ci.hw_channel); - if (channel <= CH_MAX_2G_CHANNEL) - band = wiphy->bands[IEEE80211_BAND_2GHZ]; - else - band = wiphy->bands[IEEE80211_BAND_5GHZ]; - if (!band) { - WL_ERR(("No valid band")); - return -EINVAL; - } -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) - freq = ieee80211_channel_to_frequency(channel); -#else - freq = ieee80211_channel_to_frequency(channel, band->band); -#endif - - err = wl_frame_get_mgmt(fc, &da, &e->addr, &bssid, - &mgmt_frame, &len, body); - if (err < 0) - goto exit; - isfree = true; - - if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) { - cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC); - } else if (event == WLC_E_DISASSOC_IND) { - cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC); - } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) { - cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC); - } - -exit: - if (isfree) - kfree(mgmt_frame); - return err; -#else /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) && !WL_CFG80211_STA_EVENT */ - sinfo.filled = 0; - if (((event == WLC_E_ASSOC_IND) || (event == WLC_E_REASSOC_IND)) && - reason == DOT11_SC_SUCCESS) { - sinfo.filled = STATION_INFO_ASSOC_REQ_IES; - if (!data) { - WL_ERR(("No IEs present in ASSOC/REASSOC_IND")); - return -EINVAL; - } - sinfo.assoc_req_ies = data; - sinfo.assoc_req_ies_len = len; - cfg80211_new_sta(ndev, e->addr.octet, &sinfo, GFP_ATOMIC); - } else if (event == WLC_E_DISASSOC_IND) { - cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC); - } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) { - cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC); - } -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) && !WL_CFG80211_STA_EVENT */ - return err; -} - -static s32 -wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) -{ - bool act; - s32 err = 0; - u32 event = ntoh32(e->event_type); - u32 reason; - - if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) { - wl_notify_connect_status_ap(wl, ndev, e, data); - } else { - WL_DBG(("wl_notify_connect_status : event %d status : %d ndev %p\n", - ntoh32(e->event_type), ntoh32(e->status), ndev)); - if((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DISASSOC_IND)) { - reason = ntoh32(e->reason); - wl->deauth_reason = reason; - WL_ERR(("Received %s event with reason code: %d\n", - (event == WLC_E_DEAUTH_IND)? - "WLC_E_DEAUTH_IND":"WLC_E_DISASSOC_IND", reason)); - } - if (wl_is_linkup(wl, e, ndev)) { - wl_link_up(wl); - act = true; - wl_update_prof(wl, ndev, e, &act, WL_PROF_ACT); - wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID); - wl->deauth_reason = 0; - if (wl_is_ibssmode(wl, ndev)) { - wl_ibss_join_done(wl, ndev, e, data, true); - WL_DBG(("wl_ibss_join_done succeeded\n")); - } else { - if (!wl_get_drv_status(wl, DISCONNECTING, ndev)) { - printk("wl_bss_connect_done succeeded with " MACDBG "\n", - MAC2STRDBG((u8*)(&e->addr))); - wl_bss_connect_done(wl, ndev, e, data, true); - WL_DBG(("joined in BSS network \"%s\"\n", - ((struct wlc_ssid *) - wl_read_prof(wl, ndev, WL_PROF_SSID))->SSID)); - } - } - } else if (wl_is_linkdown(wl, e)) { - if (wl->scan_request) { - if (wl->escan_on) { - wl_notify_escan_complete(wl, ndev, true, true); - } else { - del_timer_sync(&wl->scan_timeout); - wl_iscan_aborted(wl); - } - } - if (wl_get_drv_status(wl, CONNECTED, ndev)) { - scb_val_t scbval; - u8 *curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID); - wl_clr_drv_status(wl, CONNECTED, ndev); - if (! wl_get_drv_status(wl, DISCONNECTING, ndev)) { - /* To make sure disconnect, explictly send dissassoc - * for BSSID 00:00:00:00:00:00 issue - */ - scbval.val = WLAN_REASON_DEAUTH_LEAVING; - - memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN); - scbval.val = htod32(scbval.val); - wldev_ioctl(ndev, WLC_DISASSOC, &scbval, - sizeof(scb_val_t), true); - WL_ERR(("link down, calling cfg80211_disconnected" - " with deauth_reason:%d\n", wl->deauth_reason)); - if (!wl_is_ibssmode(wl, ndev)) - cfg80211_disconnected(ndev, wl->deauth_reason, - NULL, 0, GFP_KERNEL); - wl_link_down(wl); - wl_init_prof(wl, ndev); - } - } - else if (wl_get_drv_status(wl, CONNECTING, ndev)) { - printk("link down, during connecting\n"); - if (wl_is_ibssmode(wl, ndev)) - wl_ibss_join_done(wl, ndev, e, data, false); - else - wl_bss_connect_done(wl, ndev, e, data, false); - } - wl_clr_drv_status(wl, DISCONNECTING, ndev); - - } else if (wl_is_nonetwork(wl, e)) { - printk("connect failed event=%d e->status %d e->reason %d\n", - event, (int)ntoh32(e->status), (int)ntoh32(e->reason)); - /* Clean up any pending scan request */ - if (wl->scan_request) { - if (wl->escan_on) { - wl_notify_escan_complete(wl, ndev, true, true); - } else { - del_timer_sync(&wl->scan_timeout); - wl_iscan_aborted(wl); - } - } - if (wl_get_drv_status(wl, CONNECTING, ndev)) - wl_bss_connect_done(wl, ndev, e, data, false); - } else { - printk("%s nothing\n", __FUNCTION__); - } - } - return err; -} - -static s32 -wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) -{ - bool act; - s32 err = 0; - u32 event = be32_to_cpu(e->event_type); - u32 status = be32_to_cpu(e->status); - WL_DBG(("Enter \n")); - if (event == WLC_E_ROAM && status == WLC_E_STATUS_SUCCESS) { - if (wl_get_drv_status(wl, CONNECTED, ndev)) - wl_bss_roaming_done(wl, ndev, e, data); - else - wl_bss_connect_done(wl, ndev, e, data, true); - act = true; - wl_update_prof(wl, ndev, e, &act, WL_PROF_ACT); - wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID); - } - return err; -} - -static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev) -{ - wl_assoc_info_t assoc_info; - struct wl_connect_info *conn_info = wl_to_conn(wl); - s32 err = 0; - - WL_DBG(("Enter \n")); - err = wldev_iovar_getbuf(ndev, "assoc_info", NULL, 0, wl->extra_buf, - WL_ASSOC_INFO_MAX, NULL); - if (unlikely(err)) { - WL_ERR(("could not get assoc info (%d)\n", err)); - return err; - } - memcpy(&assoc_info, wl->extra_buf, sizeof(wl_assoc_info_t)); - assoc_info.req_len = htod32(assoc_info.req_len); - assoc_info.resp_len = htod32(assoc_info.resp_len); - assoc_info.flags = htod32(assoc_info.flags); - if (conn_info->req_ie_len) { - conn_info->req_ie_len = 0; - bzero(conn_info->req_ie, sizeof(conn_info->req_ie)); - } - if (conn_info->resp_ie_len) { - conn_info->resp_ie_len = 0; - bzero(conn_info->resp_ie, sizeof(conn_info->resp_ie)); - } - if (assoc_info.req_len) { - err = wldev_iovar_getbuf(ndev, "assoc_req_ies", NULL, 0, wl->extra_buf, - WL_ASSOC_INFO_MAX, NULL); - if (unlikely(err)) { - WL_ERR(("could not get assoc req (%d)\n", err)); - return err; - } - conn_info->req_ie_len = assoc_info.req_len - sizeof(struct dot11_assoc_req); - if (assoc_info.flags & WLC_ASSOC_REQ_IS_REASSOC) { - conn_info->req_ie_len -= ETHER_ADDR_LEN; - } - if (conn_info->req_ie_len <= MAX_REQ_LINE) - memcpy(conn_info->req_ie, wl->extra_buf, conn_info->req_ie_len); - else { - WL_ERR(("%s IE size %d above max %d size \n", - __FUNCTION__, conn_info->req_ie_len, MAX_REQ_LINE)); - return err; - } - } else { - conn_info->req_ie_len = 0; - } - if (assoc_info.resp_len) { - err = wldev_iovar_getbuf(ndev, "assoc_resp_ies", NULL, 0, wl->extra_buf, - WL_ASSOC_INFO_MAX, NULL); - if (unlikely(err)) { - WL_ERR(("could not get assoc resp (%d)\n", err)); - return err; - } - conn_info->resp_ie_len = assoc_info.resp_len -sizeof(struct dot11_assoc_resp); - if (conn_info->resp_ie_len <= MAX_REQ_LINE) - memcpy(conn_info->resp_ie, wl->extra_buf, conn_info->resp_ie_len); - else { - WL_ERR(("%s IE size %d above max %d size \n", - __FUNCTION__, conn_info->resp_ie_len, MAX_REQ_LINE)); - return err; - } - } else { - conn_info->resp_ie_len = 0; - } - WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len, - conn_info->resp_ie_len)); - - return err; -} - -static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params, - size_t *join_params_size) -{ - chanspec_t chanspec = 0; - - if (ch != 0) { - join_params->params.chanspec_num = 1; - join_params->params.chanspec_list[0] = ch; - - if (join_params->params.chanspec_list[0] <= CH_MAX_2G_CHANNEL) - chanspec |= WL_CHANSPEC_BAND_2G; - else - chanspec |= WL_CHANSPEC_BAND_5G; - - chanspec |= WL_CHANSPEC_BW_20; - chanspec |= WL_CHANSPEC_CTL_SB_NONE; - - *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE + - join_params->params.chanspec_num * sizeof(chanspec_t); - - join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK; - join_params->params.chanspec_list[0] |= chanspec; - join_params->params.chanspec_list[0] = - htodchanspec(join_params->params.chanspec_list[0]); - - join_params->params.chanspec_num = - htod32(join_params->params.chanspec_num); - - WL_DBG(("%s join_params->params.chanspec_list[0]= %X\n", - __FUNCTION__, join_params->params.chanspec_list[0])); - - } -} - -static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev) -{ - struct cfg80211_bss *bss; - struct wl_bss_info *bi; - struct wlc_ssid *ssid; - struct bcm_tlv *tim; - s32 beacon_interval; - s32 dtim_period; - size_t ie_len; - u8 *ie; - u8 *curbssid; - s32 err = 0; - struct wiphy *wiphy; - - wiphy = wl_to_wiphy(wl); - - if (wl_is_ibssmode(wl, ndev)) - return err; - - ssid = (struct wlc_ssid *)wl_read_prof(wl, ndev, WL_PROF_SSID); - curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID); - bss = cfg80211_get_bss(wiphy, NULL, curbssid, - ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS, - WLAN_CAPABILITY_ESS); - - mutex_lock(&wl->usr_sync); - if (!bss) { - WL_DBG(("Could not find the AP\n")); - *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX); - err = wldev_ioctl(ndev, WLC_GET_BSS_INFO, - wl->extra_buf, WL_EXTRA_BUF_MAX, false); - if (unlikely(err)) { - WL_ERR(("Could not get bss info %d\n", err)); - goto update_bss_info_out; - } - bi = (struct wl_bss_info *)(wl->extra_buf + 4); - if (memcmp(bi->BSSID.octet, curbssid, ETHER_ADDR_LEN)) { - err = -EIO; - goto update_bss_info_out; - } - err = wl_inform_single_bss(wl, bi); - if (unlikely(err)) - goto update_bss_info_out; - - ie = ((u8 *)bi) + bi->ie_offset; - ie_len = bi->ie_length; - beacon_interval = cpu_to_le16(bi->beacon_period); - } else { - WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid)); - ie = bss->information_elements; - ie_len = bss->len_information_elements; - beacon_interval = bss->beacon_interval; - cfg80211_put_bss(bss); - } - - tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM); - if (tim) { - dtim_period = tim->data[1]; - } else { - /* - * active scan was done so we could not get dtim - * information out of probe response. - * so we speficially query dtim information. - */ - err = wldev_ioctl(ndev, WLC_GET_DTIMPRD, - &dtim_period, sizeof(dtim_period), false); - if (unlikely(err)) { - WL_ERR(("WLC_GET_DTIMPRD error (%d)\n", err)); - goto update_bss_info_out; - } - } - - wl_update_prof(wl, ndev, NULL, &beacon_interval, WL_PROF_BEACONINT); - wl_update_prof(wl, ndev, NULL, &dtim_period, WL_PROF_DTIMPERIOD); - -update_bss_info_out: - mutex_unlock(&wl->usr_sync); - return err; -} - -static s32 -wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) -{ - struct wl_connect_info *conn_info = wl_to_conn(wl); - s32 err = 0; - u8 *curbssid; - - wl_get_assoc_ies(wl, ndev); - wl_update_prof(wl, ndev, NULL, (void *)(e->addr.octet), WL_PROF_BSSID); - curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID); - wl_update_bss_info(wl, ndev); - wl_update_pmklist(ndev, wl->pmk_list, err); - cfg80211_roamed(ndev, -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) - NULL, -#endif - curbssid, - conn_info->req_ie, conn_info->req_ie_len, - conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); - WL_DBG(("Report roaming result\n")); - - wl_set_drv_status(wl, CONNECTED, ndev); - - return err; -} - -static s32 -wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data, bool completed) -{ - struct wl_connect_info *conn_info = wl_to_conn(wl); - s32 err = 0; - u8 *curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID); - - WL_DBG((" enter\n")); - - if (wl->scan_request) { - wl_notify_escan_complete(wl, ndev, true, true); - } - if (is_zero_ether_addr(curbssid)) { - curbssid = wl_read_prof(wl, ndev, WL_PROF_PENDING_BSSID); - if (is_zero_ether_addr(curbssid)) { - WL_ERR(("Invalid BSSID\n")); - curbssid = NULL; - } - } - if (wl_get_drv_status(wl, CONNECTING, ndev)) { - wl_clr_drv_status(wl, CONNECTING, ndev); - if (completed) { - wl_get_assoc_ies(wl, ndev); - wl_update_prof(wl, ndev, NULL, (void *)(e->addr.octet), WL_PROF_BSSID); - curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID); - wl_update_bss_info(wl, ndev); - wl_update_pmklist(ndev, wl->pmk_list, err); - wl_set_drv_status(wl, CONNECTED, ndev); - } - cfg80211_connect_result(ndev, - curbssid, - conn_info->req_ie, - conn_info->req_ie_len, - conn_info->resp_ie, - conn_info->resp_ie_len, - completed ? WLAN_STATUS_SUCCESS : - (e->reason) ? ntoh32(e->reason) : - WLAN_STATUS_UNSPECIFIED_FAILURE, - GFP_KERNEL); - if (completed) - WL_INFO(("Report connect result - connection succeeded\n")); - else - WL_ERR(("Report connect result - connection failed\n")); - } - return err; -} - -static s32 -wl_ibss_join_done(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data, bool completed) -{ - s32 err = 0; - - WL_TRACE(("Enter\n")); - - if (wl->scan_request) { - wl_notify_escan_complete(wl, ndev, true, true); - } - if (wl_get_drv_status(wl, CONNECTING, ndev)) { - wl_clr_drv_status(wl, CONNECTING, ndev); - if (completed) { - err = wl_inform_ibss(wl, (u8 *)&e->addr); - if (err) { - WL_ERR(("wl_inform_ibss() failed: %d\n", err)); - } - wl_set_drv_status(wl, CONNECTED, ndev); - - cfg80211_ibss_joined(ndev, (u8 *)&e->addr, GFP_KERNEL); - WL_DBG(("cfg80211_ibss_joined() called with valid BSSID\n")); - } - } - - WL_TRACE(("Exit\n")); - return err; -} - -static s32 -wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) -{ - u16 flags = ntoh16(e->flags); - enum nl80211_key_type key_type; - - mutex_lock(&wl->usr_sync); - if (flags & WLC_EVENT_MSG_GROUP) - key_type = NL80211_KEYTYPE_GROUP; - else - key_type = NL80211_KEYTYPE_PAIRWISE; - - cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1, - NULL, GFP_KERNEL); - mutex_unlock(&wl->usr_sync); - - return 0; -} - -#ifdef PNO_SUPPORT -static s32 -wl_notify_pfn_status(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) -{ - WL_ERR((" PNO Event\n")); - - mutex_lock(&wl->usr_sync); -#ifndef WL_SCHED_SCAN - /* TODO: Use cfg80211_sched_scan_results(wiphy); */ - cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL); -#else - /* If cfg80211 scheduled scan is supported, report the pno results via sched - * scan results - */ - wl_notify_sched_scan_results(wl, ndev, e, data); -#endif /* WL_SCHED_SCAN */ - mutex_unlock(&wl->usr_sync); - return 0; -} -#endif /* PNO_SUPPORT */ - -static s32 -wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) -{ - struct channel_info channel_inform; - struct wl_scan_results *bss_list; - u32 len = WL_SCAN_BUF_MAX; - s32 err = 0; - unsigned long flags; - - WL_DBG(("Enter \n")); - if (!wl_get_drv_status(wl, SCANNING, ndev)) { - WL_ERR(("scan is not ready \n")); - return err; - } - if (wl->iscan_on && wl->iscan_kickstart) - return wl_wakeup_iscan(wl_to_iscan(wl)); - - mutex_lock(&wl->usr_sync); - wl_clr_drv_status(wl, SCANNING, ndev); - err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform, - sizeof(channel_inform), false); - if (unlikely(err)) { - WL_ERR(("scan busy (%d)\n", err)); - goto scan_done_out; - } - channel_inform.scan_channel = dtoh32(channel_inform.scan_channel); - if (unlikely(channel_inform.scan_channel)) { - - WL_DBG(("channel_inform.scan_channel (%d)\n", - channel_inform.scan_channel)); - } - wl->bss_list = wl->scan_results; - bss_list = wl->bss_list; - memset(bss_list, 0, len); - bss_list->buflen = htod32(len); - err = wldev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len, false); - if (unlikely(err)) { - WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err)); - err = -EINVAL; - goto scan_done_out; - } - bss_list->buflen = dtoh32(bss_list->buflen); - bss_list->version = dtoh32(bss_list->version); - bss_list->count = dtoh32(bss_list->count); - - err = wl_inform_bss(wl); - -scan_done_out: - del_timer_sync(&wl->scan_timeout); - spin_lock_irqsave(&wl->cfgdrv_lock, flags); - if (wl->scan_request) { - WL_DBG(("cfg80211_scan_done\n")); - cfg80211_scan_done(wl->scan_request, false); - wl->scan_request = NULL; - } - spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); - mutex_unlock(&wl->usr_sync); - return err; -} -static s32 -wl_frame_get_mgmt(u16 fc, const struct ether_addr *da, - const struct ether_addr *sa, const struct ether_addr *bssid, - u8 **pheader, u32 *body_len, u8 *pbody) -{ - struct dot11_management_header *hdr; - u32 totlen = 0; - s32 err = 0; - u8 *offset; - u32 prebody_len = *body_len; - switch (fc) { - case FC_ASSOC_REQ: - /* capability , listen interval */ - totlen = DOT11_ASSOC_REQ_FIXED_LEN; - *body_len += DOT11_ASSOC_REQ_FIXED_LEN; - break; - - case FC_REASSOC_REQ: - /* capability, listen inteval, ap address */ - totlen = DOT11_REASSOC_REQ_FIXED_LEN; - *body_len += DOT11_REASSOC_REQ_FIXED_LEN; - break; - } - totlen += DOT11_MGMT_HDR_LEN + prebody_len; - *pheader = kzalloc(totlen, GFP_KERNEL); - if (*pheader == NULL) { - WL_ERR(("memory alloc failed \n")); - return -ENOMEM; - } - hdr = (struct dot11_management_header *) (*pheader); - hdr->fc = htol16(fc); - hdr->durid = 0; - hdr->seq = 0; - offset = (u8*)(hdr + 1) + (totlen - DOT11_MGMT_HDR_LEN - prebody_len); - bcopy((const char*)da, (u8*)&hdr->da, ETHER_ADDR_LEN); - bcopy((const char*)sa, (u8*)&hdr->sa, ETHER_ADDR_LEN); - bcopy((const char*)bssid, (u8*)&hdr->bssid, ETHER_ADDR_LEN); - bcopy((const char*)pbody, offset, prebody_len); - *body_len = totlen; - return err; -} -static s32 -wl_notify_rx_mgmt_frame(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) -{ - struct ieee80211_supported_band *band; - struct wiphy *wiphy = wl_to_wiphy(wl); - struct ether_addr da; - struct ether_addr bssid; - bool isfree = false; - s32 err = 0; - s32 freq; - struct net_device *dev = NULL; - wifi_p2p_pub_act_frame_t *act_frm = NULL; - wifi_p2p_action_frame_t *p2p_act_frm = NULL; - wifi_p2psd_gas_pub_act_frame_t *sd_act_frm = NULL; - wl_event_rx_frame_data_t *rxframe = - (wl_event_rx_frame_data_t*)data; - u32 event = ntoh32(e->event_type); - u8 *mgmt_frame; - u8 bsscfgidx = e->bsscfgidx; - u32 mgmt_frame_len = ntoh32(e->datalen) - sizeof(wl_event_rx_frame_data_t); - u16 channel = ((ntoh16(rxframe->channel) & WL_CHANSPEC_CHAN_MASK)); - - memset(&bssid, 0, ETHER_ADDR_LEN); - - if (wl->p2p_net == ndev) { - dev = wl_to_prmry_ndev(wl); - } else { - dev = ndev; - } - - if (channel <= CH_MAX_2G_CHANNEL) - band = wiphy->bands[IEEE80211_BAND_2GHZ]; - else - band = wiphy->bands[IEEE80211_BAND_5GHZ]; - if (!band) { - WL_ERR(("No valid band")); - return -EINVAL; - } - - if ((event == WLC_E_P2P_PROBREQ_MSG) && - wl->p2p && wl_get_p2p_status(wl, GO_NEG_PHASE)) { - WL_DBG(("Filtering P2P probe_req while being in GO-Neg state\n")); - goto exit; - } - -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) - freq = ieee80211_channel_to_frequency(channel); -#else - freq = ieee80211_channel_to_frequency(channel, band->band); -#endif - if (event == WLC_E_ACTION_FRAME_RX) { - wldev_iovar_getbuf_bsscfg(dev, "cur_etheraddr", - NULL, 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bsscfgidx, &wl->ioctl_buf_sync); - - wldev_ioctl(dev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false); - memcpy(da.octet, wl->ioctl_buf, ETHER_ADDR_LEN); - err = wl_frame_get_mgmt(FC_ACTION, &da, &e->addr, &bssid, - &mgmt_frame, &mgmt_frame_len, - (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1)); - if (err < 0) { - WL_ERR(("%s: Error in receiving action frame len %d channel %d freq %d\n", - __func__, mgmt_frame_len, channel, freq)); - goto exit; - } - isfree = true; - if (wl_cfgp2p_is_pub_action(&mgmt_frame[DOT11_MGMT_HDR_LEN], - mgmt_frame_len - DOT11_MGMT_HDR_LEN)) { - act_frm = (wifi_p2p_pub_act_frame_t *) - (&mgmt_frame[DOT11_MGMT_HDR_LEN]); - } else if (wl_cfgp2p_is_p2p_action(&mgmt_frame[DOT11_MGMT_HDR_LEN], - mgmt_frame_len - DOT11_MGMT_HDR_LEN)) { - p2p_act_frm = (wifi_p2p_action_frame_t *) - (&mgmt_frame[DOT11_MGMT_HDR_LEN]); - (void) p2p_act_frm; - } else if (wl_cfgp2p_is_gas_action(&mgmt_frame[DOT11_MGMT_HDR_LEN], - mgmt_frame_len - DOT11_MGMT_HDR_LEN)) { - sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *) - (&mgmt_frame[DOT11_MGMT_HDR_LEN]); - (void) sd_act_frm; - } - wl_cfgp2p_print_actframe(false, &mgmt_frame[DOT11_MGMT_HDR_LEN], - mgmt_frame_len - DOT11_MGMT_HDR_LEN); - /* - * After complete GO Negotiation, roll back to mpc mode - */ - if (act_frm && ((act_frm->subtype == P2P_PAF_GON_CONF) || - (act_frm->subtype == P2P_PAF_PROVDIS_RSP))) { - wldev_iovar_setint(dev, "mpc", 1); - } - - if (act_frm && (act_frm->subtype == P2P_PAF_GON_CONF)) { - WL_DBG(("P2P: GO_NEG_PHASE status cleared \n")); - wl_clr_p2p_status(wl, GO_NEG_PHASE); - } - - if (act_frm && (act_frm->subtype == P2P_PAF_GON_RSP)) { - /* Cancel the dwell time of req frame */ - WL_DBG(("P2P: Received GO NEG Resp frame, cancelling the dwell time\n")); - wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0, - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); - } - } else { - mgmt_frame = (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1); - } - - cfg80211_rx_mgmt(ndev, freq, mgmt_frame, mgmt_frame_len, GFP_ATOMIC); - - WL_DBG(("%s: mgmt_frame_len (%d) , e->datalen (%d), channel (%d), freq (%d)\n", __func__, - mgmt_frame_len, ntoh32(e->datalen), channel, freq)); - - if (isfree) - kfree(mgmt_frame); -exit: - return 0; -} - -#ifdef WL_SCHED_SCAN -/* If target scan is not reliable, set the below define to "1" to do a - * full escan - */ -#define FULL_ESCAN_ON_PFN_NET_FOUND 0 -static s32 -wl_notify_sched_scan_results(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) -{ - wl_pfn_net_info_t *netinfo, *pnetinfo; - struct cfg80211_scan_request request; - struct wiphy *wiphy = wl_to_wiphy(wl); - int err = 0; - struct cfg80211_ssid ssid[MAX_PFN_LIST_COUNT]; - struct ieee80211_channel *channel = NULL; - int channel_req = 0; - int band = 0; - struct wl_pfn_scanresults *pfn_result = (struct wl_pfn_scanresults *)data; - - WL_DBG(("Enter\n")); - - if (e->event_type == WLC_E_PFN_NET_LOST) { - WL_DBG(("PFN NET LOST event. Do Nothing \n")); - return 0; - } - WL_DBG(("PFN NET FOUND event. count:%d \n", pfn_result->count)); - if (pfn_result->count > 0) { - int i; - - memset(&request, 0x00, sizeof(struct cfg80211_scan_request)); - memset(&ssid, 0x00, sizeof(ssid)); - request.wiphy = wiphy; - - pnetinfo = (wl_pfn_net_info_t *)(data + sizeof(wl_pfn_scanresults_t) - - sizeof(wl_pfn_net_info_t)); - channel = (struct ieee80211_channel *)kzalloc( - (sizeof(struct ieee80211_channel) * MAX_PFN_LIST_COUNT), - GFP_KERNEL); - if (!channel) { - WL_ERR(("No memory")); - err = -ENOMEM; - goto out_err; - } - - for (i = 0; i < pfn_result->count; i++) { - netinfo = &pnetinfo[i]; - if (!netinfo) { - WL_ERR(("Invalid netinfo ptr. index:%d", i)); - err = -EINVAL; - goto out_err; - } - WL_DBG(("SSID:%s Channel:%d \n", - netinfo->pfnsubnet.SSID, netinfo->pfnsubnet.channel)); - /* PFN result doesn't have all the info which are required by the supplicant - * (For e.g IEs) Do a target Escan so that sched scan results are reported - * via wl_inform_single_bss in the required format. Escan does require the - * scan request in the form of cfg80211_scan_request. For timebeing, create - * cfg80211_scan_request one out of the received PNO event. - */ - memcpy(ssid[i].ssid, netinfo->pfnsubnet.SSID, - netinfo->pfnsubnet.SSID_len); - ssid[i].ssid_len = netinfo->pfnsubnet.SSID_len; - request.n_ssids++; - - channel_req = netinfo->pfnsubnet.channel; - band = (channel_req <= CH_MAX_2G_CHANNEL) ? NL80211_BAND_2GHZ - : NL80211_BAND_5GHZ; - channel[i].center_freq = ieee80211_channel_to_frequency(channel_req, band); - channel[i].band = band; - channel[i].flags |= IEEE80211_CHAN_NO_HT40; - request.channels[i] = &channel[i]; - request.n_channels++; - } - - /* assign parsed ssid array */ - if (request.n_ssids) - request.ssids = &ssid[0]; - - if (wl_get_drv_status_all(wl, SCANNING)) { - /* Abort any on-going scan */ - wl_notify_escan_complete(wl, ndev, true, true); - } - - if (wl_get_p2p_status(wl, DISCOVERY_ON)) { - err = wl_cfgp2p_discover_enable_search(wl, false); - if (unlikely(err)) { - wl_clr_drv_status(wl, SCANNING, ndev); - goto out_err; - } - } - - wl_set_drv_status(wl, SCANNING, ndev); -#if FULL_ESCAN_ON_PFN_NET_FOUND - err = wl_do_escan(wl, wiphy, ndev, NULL); -#else - err = wl_do_escan(wl, wiphy, ndev, &request); -#endif - if (err) { - wl_clr_drv_status(wl, SCANNING, ndev); - goto out_err; - } - wl->sched_scan_running = TRUE; - } - else { - WL_ERR(("FALSE PNO Event. (pfn_count == 0) \n")); - } -out_err: - if (channel) - kfree(channel); - return err; -} -#endif /* WL_SCHED_SCAN */ - -static void wl_init_conf(struct wl_conf *conf) -{ - WL_DBG(("Enter \n")); - conf->frag_threshold = (u32)-1; - conf->rts_threshold = (u32)-1; - conf->retry_short = (u32)-1; - conf->retry_long = (u32)-1; - conf->tx_power = -1; -} - -static void wl_init_prof(struct wl_priv *wl, struct net_device *ndev) -{ - unsigned long flags; - struct wl_profile *profile = wl_get_profile_by_netdev(wl, ndev); - - spin_lock_irqsave(&wl->cfgdrv_lock, flags); - memset(profile, 0, sizeof(struct wl_profile)); - spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); -} - -static void wl_init_event_handler(struct wl_priv *wl) -{ - memset(wl->evt_handler, 0, sizeof(wl->evt_handler)); - - wl->evt_handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status; - wl->evt_handler[WLC_E_LINK] = wl_notify_connect_status; - wl->evt_handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status; - wl->evt_handler[WLC_E_DEAUTH] = wl_notify_connect_status; - wl->evt_handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status; - wl->evt_handler[WLC_E_ASSOC_IND] = wl_notify_connect_status; - wl->evt_handler[WLC_E_REASSOC_IND] = wl_notify_connect_status; - wl->evt_handler[WLC_E_ROAM] = wl_notify_roaming_status; - wl->evt_handler[WLC_E_MIC_ERROR] = wl_notify_mic_status; - wl->evt_handler[WLC_E_SET_SSID] = wl_notify_connect_status; - wl->evt_handler[WLC_E_ACTION_FRAME_RX] = wl_notify_rx_mgmt_frame; - wl->evt_handler[WLC_E_PROBREQ_MSG] = wl_notify_rx_mgmt_frame; - wl->evt_handler[WLC_E_P2P_PROBREQ_MSG] = wl_notify_rx_mgmt_frame; - wl->evt_handler[WLC_E_P2P_DISC_LISTEN_COMPLETE] = wl_cfgp2p_listen_complete; - wl->evt_handler[WLC_E_ACTION_FRAME_COMPLETE] = wl_cfgp2p_action_tx_complete; - wl->evt_handler[WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE] = wl_cfgp2p_action_tx_complete; -#ifdef PNO_SUPPORT - wl->evt_handler[WLC_E_PFN_NET_FOUND] = wl_notify_pfn_status; -#endif /* PNO_SUPPORT */ -} - -static s32 wl_init_priv_mem(struct wl_priv *wl) -{ - WL_DBG(("Enter \n")); - wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL); - if (unlikely(!wl->scan_results)) { - WL_ERR(("Scan results alloc failed\n")); - goto init_priv_mem_out; - } - wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL); - if (unlikely(!wl->conf)) { - WL_ERR(("wl_conf alloc failed\n")); - goto init_priv_mem_out; - } - wl->scan_req_int = - (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL); - if (unlikely(!wl->scan_req_int)) { - WL_ERR(("Scan req alloc failed\n")); - goto init_priv_mem_out; - } - wl->ioctl_buf = (void *)kzalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL); - if (unlikely(!wl->ioctl_buf)) { - WL_ERR(("Ioctl buf alloc failed\n")); - goto init_priv_mem_out; - } - wl->escan_ioctl_buf = (void *)kzalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL); - if (unlikely(!wl->escan_ioctl_buf)) { - WL_ERR(("Ioctl buf alloc failed\n")); - goto init_priv_mem_out; - } - wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); - if (unlikely(!wl->extra_buf)) { - WL_ERR(("Extra buf alloc failed\n")); - goto init_priv_mem_out; - } - wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL); - if (unlikely(!wl->iscan)) { - WL_ERR(("Iscan buf alloc failed\n")); - goto init_priv_mem_out; - } - wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL); - if (unlikely(!wl->pmk_list)) { - WL_ERR(("pmk list alloc failed\n")); - goto init_priv_mem_out; - } - wl->sta_info = (void *)kzalloc(sizeof(*wl->sta_info), GFP_KERNEL); - if (unlikely(!wl->sta_info)) { - WL_ERR(("sta info alloc failed\n")); - goto init_priv_mem_out; - } - wl->afx_hdl = (void *)kzalloc(sizeof(*wl->afx_hdl), GFP_KERNEL); - if (unlikely(!wl->afx_hdl)) { - WL_ERR(("afx hdl alloc failed\n")); - goto init_priv_mem_out; - } else { - init_completion(&wl->act_frm_scan); - INIT_WORK(&wl->afx_hdl->work, wl_cfg80211_afx_handler); - } - return 0; - -init_priv_mem_out: - wl_deinit_priv_mem(wl); - - return -ENOMEM; -} - -static void wl_deinit_priv_mem(struct wl_priv *wl) -{ - kfree(wl->scan_results); - wl->scan_results = NULL; - kfree(wl->conf); - wl->conf = NULL; - kfree(wl->scan_req_int); - wl->scan_req_int = NULL; - kfree(wl->ioctl_buf); - wl->ioctl_buf = NULL; - kfree(wl->escan_ioctl_buf); - wl->escan_ioctl_buf = NULL; - kfree(wl->extra_buf); - wl->extra_buf = NULL; - kfree(wl->iscan); - wl->iscan = NULL; - kfree(wl->pmk_list); - wl->pmk_list = NULL; - kfree(wl->sta_info); - wl->sta_info = NULL; - if (wl->afx_hdl) { - cancel_work_sync(&wl->afx_hdl->work); - kfree(wl->afx_hdl); - wl->afx_hdl = NULL; - } - - if (wl->ap_info) { - kfree(wl->ap_info->wpa_ie); - kfree(wl->ap_info->rsn_ie); - kfree(wl->ap_info->wps_ie); - kfree(wl->ap_info); - wl->ap_info = NULL; - } -} - -static s32 wl_create_event_handler(struct wl_priv *wl) -{ - int ret = 0; - WL_DBG(("Enter \n")); - - /* Do not use DHD in cfg driver */ - wl->event_tsk.thr_pid = -1; - PROC_START(wl_event_handler, wl, &wl->event_tsk, 0); - if (wl->event_tsk.thr_pid < 0) - ret = -ENOMEM; - return ret; -} - -static void wl_destroy_event_handler(struct wl_priv *wl) -{ - if (wl->event_tsk.thr_pid >= 0) - PROC_STOP(&wl->event_tsk); -} - -static void wl_term_iscan(struct wl_priv *wl) -{ - struct wl_iscan_ctrl *iscan = wl_to_iscan(wl); - WL_TRACE(("In\n")); - if (wl->iscan_on && iscan->tsk) { - iscan->state = WL_ISCAN_STATE_IDLE; - WL_INFO(("SIGTERM\n")); - send_sig(SIGTERM, iscan->tsk, 1); - WL_DBG(("kthread_stop\n")); - kthread_stop(iscan->tsk); - iscan->tsk = NULL; - } -} - -static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted) -{ - struct wl_priv *wl = iscan_to_wl(iscan); - struct net_device *ndev = wl_to_prmry_ndev(wl); - unsigned long flags; - - WL_DBG(("Enter \n")); - if(!aborted) - wl->scan_busy_count = 0; - - if (!wl_get_drv_status(wl, SCANNING, ndev)) { - wl_clr_drv_status(wl, SCANNING, ndev); - WL_ERR(("Scan complete while device not scanning\n")); - return; - } - spin_lock_irqsave(&wl->cfgdrv_lock, flags); - wl_clr_drv_status(wl, SCANNING, ndev); - if (likely(wl->scan_request)) { - cfg80211_scan_done(wl->scan_request, aborted); - wl->scan_request = NULL; - } - spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); - wl->iscan_kickstart = false; -} - -static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan) -{ - if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) { - WL_DBG(("wake up iscan\n")); - up(&iscan->sync); - return 0; - } - - return -EIO; -} - -static s32 -wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status, - struct wl_scan_results **bss_list) -{ - struct wl_iscan_results list; - struct wl_scan_results *results; - struct wl_iscan_results *list_buf; - s32 err = 0; - - WL_DBG(("Enter \n")); - memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX); - list_buf = (struct wl_iscan_results *)iscan->scan_buf; - results = &list_buf->results; - results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE; - results->version = 0; - results->count = 0; - - memset(&list, 0, sizeof(list)); - list.results.buflen = htod32(WL_ISCAN_BUF_MAX); - err = wldev_iovar_getbuf(iscan->dev, "iscanresults", &list, - WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf, - WL_ISCAN_BUF_MAX, NULL); - if (unlikely(err)) { - WL_ERR(("error (%d)\n", err)); - return err; - } - results->buflen = dtoh32(results->buflen); - results->version = dtoh32(results->version); - results->count = dtoh32(results->count); - WL_DBG(("results->count = %d\n", results->count)); - WL_DBG(("results->buflen = %d\n", results->buflen)); - *status = dtoh32(list_buf->status); - *bss_list = results; - - return err; -} - -static s32 wl_iscan_done(struct wl_priv *wl) -{ - struct wl_iscan_ctrl *iscan = wl->iscan; - s32 err = 0; - - iscan->state = WL_ISCAN_STATE_IDLE; - mutex_lock(&wl->usr_sync); - wl_inform_bss(wl); - wl_notify_iscan_complete(iscan, false); - mutex_unlock(&wl->usr_sync); - - return err; -} - -static s32 wl_iscan_pending(struct wl_priv *wl) -{ - struct wl_iscan_ctrl *iscan = wl->iscan; - s32 err = 0; - - /* Reschedule the timer */ - mod_timer(&iscan->timer, jiffies + msecs_to_jiffies(iscan->timer_ms)); - iscan->timer_on = 1; - - return err; -} - -static s32 wl_iscan_inprogress(struct wl_priv *wl) -{ - struct wl_iscan_ctrl *iscan = wl->iscan; - s32 err = 0; - - mutex_lock(&wl->usr_sync); - wl_inform_bss(wl); - wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE); - mutex_unlock(&wl->usr_sync); - /* Reschedule the timer */ - mod_timer(&iscan->timer, jiffies + msecs_to_jiffies(iscan->timer_ms)); - iscan->timer_on = 1; - - return err; -} - -static s32 wl_iscan_aborted(struct wl_priv *wl) -{ - struct wl_iscan_ctrl *iscan = wl->iscan; - s32 err = 0; - - iscan->state = WL_ISCAN_STATE_IDLE; - mutex_lock(&wl->usr_sync); - wl_notify_iscan_complete(iscan, true); - mutex_unlock(&wl->usr_sync); - - return err; -} - -static s32 wl_iscan_thread(void *data) -{ - struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data; - struct wl_priv *wl = iscan_to_wl(iscan); - u32 status; - int err = 0; - - allow_signal(SIGTERM); - status = WL_SCAN_RESULTS_PARTIAL; - while (likely(!down_interruptible(&iscan->sync))) { - if (kthread_should_stop()) - break; - if (iscan->timer_on) { - del_timer_sync(&iscan->timer); - iscan->timer_on = 0; - } - mutex_lock(&wl->usr_sync); - err = wl_get_iscan_results(iscan, &status, &wl->bss_list); - if (unlikely(err)) { - status = WL_SCAN_RESULTS_ABORTED; - WL_ERR(("Abort iscan\n")); - } - mutex_unlock(&wl->usr_sync); - iscan->iscan_handler[status] (wl); - } - if (iscan->timer_on) { - del_timer_sync(&iscan->timer); - iscan->timer_on = 0; - } - WL_DBG(("%s was terminated\n", __func__)); - - return 0; -} - -static void wl_scan_timeout(unsigned long data) -{ - struct wl_priv *wl = (struct wl_priv *)data; - - schedule_work(&wl->work_scan_timeout); -} - -static void wl_scan_timeout_process(struct work_struct *work) -{ - struct wl_priv *wl; - - wl = (wl_priv_t *)container_of(work, wl_priv_t, work_scan_timeout); - - if (wl->scan_request) { - WL_ERR(("timer expired\n")); - if (wl->escan_on) - wl_notify_escan_complete(wl, wl->escan_info.ndev, true, true); - else - wl_notify_iscan_complete(wl_to_iscan(wl), true); - } - - /* Assume FW is in bad state if there are continuous scan timeouts */ - wl->scan_busy_count++; - if (wl->scan_busy_count > WL_SCAN_BUSY_MAX) { - wl->scan_busy_count = 0; - WL_ERR(("Continuous scan timeouts!! Exercising FW hang recovery\n")); - net_os_send_hang_message(wl->escan_info.ndev); - } -} - -static void wl_iscan_timer(unsigned long data) -{ - struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data; - - if (iscan) { - iscan->timer_on = 0; - WL_DBG(("timer expired\n")); - wl_wakeup_iscan(iscan); - } -} - -static s32 wl_invoke_iscan(struct wl_priv *wl) -{ - struct wl_iscan_ctrl *iscan = wl_to_iscan(wl); - int err = 0; - - if (wl->iscan_on && !iscan->tsk) { - iscan->state = WL_ISCAN_STATE_IDLE; - sema_init(&iscan->sync, 0); - iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan"); - if (IS_ERR(iscan->tsk)) { - WL_ERR(("Could not create iscan thread\n")); - iscan->tsk = NULL; - return -ENOMEM; - } - } - - return err; -} - -static void wl_init_iscan_handler(struct wl_iscan_ctrl *iscan) -{ - memset(iscan->iscan_handler, 0, sizeof(iscan->iscan_handler)); - iscan->iscan_handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done; - iscan->iscan_handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress; - iscan->iscan_handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending; - iscan->iscan_handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted; - iscan->iscan_handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted; -} - -static s32 -wl_cfg80211_netdev_notifier_call(struct notifier_block * nb, - unsigned long state, - void *ndev) -{ - struct net_device *dev = ndev; - struct wireless_dev *wdev = dev->ieee80211_ptr; - struct wl_priv *wl = wlcfg_drv_priv; - - WL_DBG(("Enter \n")); - if (!wdev || !wl || dev == wl_to_prmry_ndev(wl)) - return NOTIFY_DONE; - switch (state) { - case NETDEV_UNREGISTER: - /* after calling list_del_rcu(&wdev->list) */ - wl_dealloc_netinfo(wl, ndev); - break; - case NETDEV_GOING_DOWN: - /* At NETDEV_DOWN state, wdev_cleanup_work work will be called. - * In front of door, the function checks - * whether current scan is working or not. - * If the scanning is still working, wdev_cleanup_work call WARN_ON and - * make the scan done forcibly. - */ - if (wl_get_drv_status(wl, SCANNING, dev)) { - if (wl->escan_on) { - wl_notify_escan_complete(wl, dev, true, true); - } - } - break; - } - return NOTIFY_DONE; -} -static struct notifier_block wl_cfg80211_netdev_notifier = { - .notifier_call = wl_cfg80211_netdev_notifier_call, -}; - -static s32 wl_notify_escan_complete(struct wl_priv *wl, - struct net_device *ndev, - bool aborted, bool fw_abort) -{ - wl_scan_params_t *params = NULL; - s32 params_size = 0; - s32 err = BCME_OK; - unsigned long flags; - struct net_device *dev; - - WL_DBG(("Enter \n")); - - if(!aborted) - wl->scan_busy_count = 0; - - if (wl->scan_request) { - if (wl->scan_request->dev == wl->p2p_net) - dev = wl_to_prmry_ndev(wl); - else - dev = wl->scan_request->dev; - } - else { - WL_ERR(("wl->scan_request is NULL may be internal scan." - "doing scan_abort for ndev %p primary %p p2p_net %p", - ndev, wl_to_prmry_ndev(wl), wl->p2p_net)); - dev = ndev; - } - if (fw_abort && !in_atomic()) { - /* Our scan params only need space for 1 channel and 0 ssids */ - params = wl_cfg80211_scan_alloc_params(-1, 0, ¶ms_size); - if (params == NULL) { - WL_ERR(("scan params allocation failed \n")); - err = -ENOMEM; - } else { - /* Do a scan abort to stop the driver's scan engine */ - err = wldev_ioctl(dev, WLC_SCAN, params, params_size, true); - if (err < 0) { - WL_ERR(("scan abort failed \n")); - } - } - } - if (timer_pending(&wl->scan_timeout)) - del_timer_sync(&wl->scan_timeout); - spin_lock_irqsave(&wl->cfgdrv_lock, flags); - -#ifdef WL_SCHED_SCAN - if (wl->sched_scan_req && !wl->scan_request) { - WL_DBG((" REPORTING SCHED SCAN RESULTS \n")); - if (aborted) - cfg80211_sched_scan_stopped(wl->sched_scan_req->wiphy); - else - cfg80211_sched_scan_results(wl->sched_scan_req->wiphy); - wl->sched_scan_running = FALSE; - wl->sched_scan_req = NULL; - } -#endif /* WL_SCHED_SCAN */ - - if (likely(wl->scan_request)) { - cfg80211_scan_done(wl->scan_request, aborted); - wl->scan_request = NULL; - } - if (p2p_is_on(wl)) - wl_clr_p2p_status(wl, SCANNING); - wl_clr_drv_status(wl, SCANNING, dev); - spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); - if (params) - kfree(params); - - return err; -} - -static s32 wl_escan_handler(struct wl_priv *wl, - struct net_device *ndev, - const wl_event_msg_t *e, void *data) -{ - s32 err = BCME_OK; - s32 status = ntoh32(e->status); - wl_bss_info_t *bi; - wl_escan_result_t *escan_result; - wl_bss_info_t *bss = NULL; - wl_scan_results_t *list; - u32 bi_length; - u32 i; - wifi_p2p_ie_t * p2p_ie; - u8 *p2p_dev_addr = NULL; - - WL_DBG((" enter event type : %d, status : %d \n", - ntoh32(e->event_type), ntoh32(e->status))); - - mutex_lock(&wl->usr_sync); - /* P2P SCAN is coming from primary interface */ - if (wl_get_p2p_status(wl, SCANNING)) { - if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) - ndev = wl->afx_hdl->dev; - else - ndev = wl->escan_info.ndev; - - } - if (!ndev || !wl->escan_on || - !wl_get_drv_status(wl, SCANNING, ndev)) { - WL_ERR(("escan is not ready ndev %p wl->escan_on %d drv_status 0x%x\n", - ndev, wl->escan_on, wl_get_drv_status(wl, SCANNING, ndev))); - goto exit; - } - - if (status == WLC_E_STATUS_PARTIAL) { - WL_INFO(("WLC_E_STATUS_PARTIAL \n")); - escan_result = (wl_escan_result_t *) data; - if (!escan_result) { - WL_ERR(("Invalid escan result (NULL pointer)\n")); - goto exit; - } - if (dtoh16(escan_result->bss_count) != 1) { - WL_ERR(("Invalid bss_count %d: ignoring\n", escan_result->bss_count)); - goto exit; - } - bi = escan_result->bss_info; - if (!bi) { - WL_ERR(("Invalid escan bss info (NULL pointer)\n")); - goto exit; - } - bi_length = dtoh32(bi->length); - if (bi_length != (dtoh32(escan_result->buflen) - WL_ESCAN_RESULTS_FIXED_SIZE)) { - WL_ERR(("Invalid bss_info length %d: ignoring\n", bi_length)); - goto exit; - } - - if (!(wl_to_wiphy(wl)->interface_modes & BIT(NL80211_IFTYPE_ADHOC))) { - if (dtoh16(bi->capability) & DOT11_CAP_IBSS) { - WL_DBG(("Ignoring IBSS result\n")); - goto exit; - } - } - - if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) { - p2p_dev_addr = wl_cfgp2p_retreive_p2p_dev_addr(bi, bi_length); - if (p2p_dev_addr && !memcmp(p2p_dev_addr, - wl->afx_hdl->pending_tx_dst_addr.octet, ETHER_ADDR_LEN)) { - s32 channel = CHSPEC_CHANNEL(dtohchanspec(bi->chanspec)); - WL_DBG(("ACTION FRAME SCAN : Peer " MACSTR " found, channel : %d\n", - MAC2STR(wl->afx_hdl->pending_tx_dst_addr.octet), channel)); - wl_clr_p2p_status(wl, SCANNING); - wl->afx_hdl->peer_chan = channel; - complete(&wl->act_frm_scan); - goto exit; - } - - } else { - list = (wl_scan_results_t *)wl->escan_info.escan_buf; - if (bi_length > ESCAN_BUF_SIZE - list->buflen) { - WL_ERR(("Buffer is too small: ignoring\n")); - goto exit; - } -#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF) - if (wl->p2p_net && wl->scan_request && - wl->scan_request->dev == wl->p2p_net) { -#else - if (p2p_is_on(wl) && p2p_scan(wl)) { -#endif - /* p2p scan && allow only probe response */ - if (bi->flags & WL_BSS_FLAGS_FROM_BEACON) - goto exit; - if ((p2p_ie = wl_cfgp2p_find_p2pie(((u8 *) bi) + bi->ie_offset, - bi->ie_length)) == NULL) { - WL_ERR(("Couldn't find P2PIE in probe" - " response/beacon\n")); - goto exit; - } - } -#define WLC_BSS_RSSI_ON_CHANNEL 0x0002 - for (i = 0; i < list->count; i++) { - bss = bss ? (wl_bss_info_t *)((uintptr)bss + dtoh32(bss->length)) - : list->bss_info; - - if (!bcmp(&bi->BSSID, &bss->BSSID, ETHER_ADDR_LEN) && - CHSPEC_BAND(bi->chanspec) == CHSPEC_BAND(bss->chanspec) && - bi->SSID_len == bss->SSID_len && - !bcmp(bi->SSID, bss->SSID, bi->SSID_len)) { - if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) == - (bi->flags & WLC_BSS_RSSI_ON_CHANNEL)) { - /* preserve max RSSI if the measurements are - * both on-channel or both off-channel - */ - bss->RSSI = MAX(bss->RSSI, bi->RSSI); - } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) && - (bi->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) { - /* preserve the on-channel rssi measurement - * if the new measurement is off channel - */ - bss->RSSI = bi->RSSI; - bss->flags |= WLC_BSS_RSSI_ON_CHANNEL; - } - goto exit; - } - } - memcpy(&(wl->escan_info.escan_buf[list->buflen]), bi, bi_length); - list->version = dtoh32(bi->version); - list->buflen += bi_length; - list->count++; - } - - } - else if (status == WLC_E_STATUS_SUCCESS) { - wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE; - if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) { - WL_INFO(("ACTION FRAME SCAN DONE\n")); - wl_clr_p2p_status(wl, SCANNING); - wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev); - if (wl->afx_hdl->peer_chan == WL_INVALID) - complete(&wl->act_frm_scan); - } else if ((likely(wl->scan_request)) || (wl->sched_scan_running)) { - WL_INFO(("ESCAN COMPLETED\n")); - wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf; - wl_inform_bss(wl); - wl_notify_escan_complete(wl, ndev, false, false); - } - } - else if (status == WLC_E_STATUS_ABORT) { - wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE; - if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) { - WL_INFO(("ACTION FRAME SCAN DONE\n")); - wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev); - wl_clr_p2p_status(wl, SCANNING); - if (wl->afx_hdl->peer_chan == WL_INVALID) - complete(&wl->act_frm_scan); - } else if ((likely(wl->scan_request)) || (wl->sched_scan_running)) { - WL_INFO(("ESCAN ABORTED\n")); - wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf; - wl_inform_bss(wl); - wl_notify_escan_complete(wl, ndev, true, false); - } - } - else if (status == WLC_E_STATUS_NEWSCAN) { - /* Do Nothing. Ignore this event */ - } - else { - WL_ERR(("unexpected Escan Event %d : abort\n", status)); - wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE; - if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) { - WL_INFO(("ACTION FRAME SCAN DONE\n")); - wl_clr_p2p_status(wl, SCANNING); - wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev); - if (wl->afx_hdl->peer_chan == WL_INVALID) - complete(&wl->act_frm_scan); - } else if ((likely(wl->scan_request)) || (wl->sched_scan_running)) { - wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf; - wl_inform_bss(wl); - wl_notify_escan_complete(wl, ndev, true, false); - } - } -exit: - mutex_unlock(&wl->usr_sync); - return err; -} - -static s32 wl_init_scan(struct wl_priv *wl) -{ - struct wl_iscan_ctrl *iscan = wl_to_iscan(wl); - int err = 0; - - if (wl->iscan_on) { - iscan->dev = wl_to_prmry_ndev(wl); - iscan->state = WL_ISCAN_STATE_IDLE; - wl_init_iscan_handler(iscan); - iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS; - init_timer(&iscan->timer); - iscan->timer.data = (unsigned long) iscan; - iscan->timer.function = wl_iscan_timer; - sema_init(&iscan->sync, 0); - iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan"); - if (IS_ERR(iscan->tsk)) { - WL_ERR(("Could not create iscan thread\n")); - iscan->tsk = NULL; - return -ENOMEM; - } - iscan->data = wl; - } else if (wl->escan_on) { - wl->evt_handler[WLC_E_ESCAN_RESULT] = wl_escan_handler; - wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE; - } - /* Init scan_timeout timer */ - init_timer(&wl->scan_timeout); - wl->scan_timeout.data = (unsigned long) wl; - wl->scan_timeout.function = wl_scan_timeout; - - return err; -} - -static s32 wl_init_priv(struct wl_priv *wl) -{ - struct wiphy *wiphy = wl_to_wiphy(wl); - struct net_device *ndev = wl_to_prmry_ndev(wl); - s32 err = 0; - - wl->scan_request = NULL; - wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT); - wl->iscan_on = false; - wl->escan_on = true; - wl->roam_on = false; - wl->iscan_kickstart = false; - wl->active_scan = true; - wl->rf_blocked = false; - wl->deauth_reason = 0; - spin_lock_init(&wl->cfgdrv_lock); - mutex_init(&wl->ioctl_buf_sync); - init_waitqueue_head(&wl->netif_change_event); - wl_init_eq(wl); - err = wl_init_priv_mem(wl); - if (err) - return err; - if (wl_create_event_handler(wl)) - return -ENOMEM; - wl_init_event_handler(wl); - mutex_init(&wl->usr_sync); - INIT_WORK(&wl->work_scan_timeout, wl_scan_timeout_process); - err = wl_init_scan(wl); - if (err) - return err; - wl_init_conf(wl->conf); - wl_init_prof(wl, ndev); - wl_link_down(wl); - DNGL_FUNC(dhd_cfg80211_init, (wl)); - - return err; -} - -static void wl_deinit_priv(struct wl_priv *wl) -{ - DNGL_FUNC(dhd_cfg80211_deinit, (wl)); - wl_destroy_event_handler(wl); - wl_flush_eq(wl); - wl_link_down(wl); - del_timer_sync(&wl->scan_timeout); - wl_term_iscan(wl); - cancel_work_sync(&wl->work_scan_timeout); - wl_deinit_priv_mem(wl); - unregister_netdevice_notifier(&wl_cfg80211_netdev_notifier); -} - -#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF) -static s32 wl_cfg80211_attach_p2p(void) -{ - struct wl_priv *wl = wlcfg_drv_priv; - - WL_TRACE(("Enter \n")); - - if (wl_cfgp2p_register_ndev(wl) < 0) { - WL_ERR(("%s: P2P attach failed. \n", __func__)); - return -ENODEV; - } - - return 0; -} - -static s32 wl_cfg80211_detach_p2p(void) -{ - struct wl_priv *wl = wlcfg_drv_priv; - struct wireless_dev *wdev = wl->p2p_wdev; - - WL_DBG(("Enter \n")); - if (!wdev || !wl) { - WL_ERR(("Invalid Ptr\n")); - return -EINVAL; - } - - wl_cfgp2p_unregister_ndev(wl); - - wl->p2p_wdev = NULL; - wl->p2p_net = NULL; - WL_DBG(("Freeing 0x%08x \n", (unsigned int)wdev)); - kfree(wdev); - - return 0; -} -#endif /* defined(WLP2P) && defined(WL_ENABLE_P2P_IF) */ - -s32 wl_cfg80211_attach_post(struct net_device *ndev) -{ - struct wl_priv * wl = NULL; - s32 err = 0; - WL_TRACE(("In\n")); - if (unlikely(!ndev)) { - WL_ERR(("ndev is invaild\n")); - return -ENODEV; - } - wl = wlcfg_drv_priv; - if (wl && !wl_get_drv_status(wl, READY, ndev)) { - if (wl->wdev && - wl_cfgp2p_supported(wl, ndev)) { -#if !defined(WL_ENABLE_P2P_IF) - wl->wdev->wiphy->interface_modes |= - (BIT(NL80211_IFTYPE_P2P_CLIENT)| - BIT(NL80211_IFTYPE_P2P_GO)); -#endif - if ((err = wl_cfgp2p_init_priv(wl)) != 0) - goto fail; - -#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF) - if (wl->p2p_net) { - /* Update MAC addr for p2p0 interface here. */ - memcpy(wl->p2p_net->dev_addr, ndev->dev_addr, ETH_ALEN); - wl->p2p_net->dev_addr[0] |= 0x02; - printk("%s: p2p_dev_addr="MACSTR "\n", - wl->p2p_net->name, MAC2STR(wl->p2p_net->dev_addr)); - } else { - WL_ERR(("p2p_net not yet populated." - " Couldn't update the MAC Address for p2p0 \n")); - return -ENODEV; - } -#endif /* defined(WLP2P) && (WL_ENABLE_P2P_IF) */ - - wl->p2p_supported = true; - } - } else - return -ENODEV; - wl_set_drv_status(wl, READY, ndev); -fail: - return err; -} - -s32 wl_cfg80211_attach(struct net_device *ndev, void *data) -{ - struct wireless_dev *wdev; - struct wl_priv *wl; - s32 err = 0; - struct device *dev; - - WL_TRACE(("In\n")); - if (!ndev) { - WL_ERR(("ndev is invaild\n")); - return -ENODEV; - } - WL_DBG(("func %p\n", wl_cfg80211_get_parent_dev())); - dev = wl_cfg80211_get_parent_dev(); - - wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); - if (unlikely(!wdev)) { - WL_ERR(("Could not allocate wireless device\n")); - return -ENOMEM; - } - err = wl_setup_wiphy(wdev, dev); - if (unlikely(err)) { - kfree(wdev); - return -ENOMEM; - } - wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS); - wl = (struct wl_priv *)wiphy_priv(wdev->wiphy); - wl->wdev = wdev; - wl->pub = data; - INIT_LIST_HEAD(&wl->net_list); - ndev->ieee80211_ptr = wdev; - SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); - wdev->netdev = ndev; - err = wl_alloc_netinfo(wl, ndev, wdev, WL_MODE_BSS); - if (err) { - WL_ERR(("Failed to alloc net_info (%d)\n", err)); - goto cfg80211_attach_out; - } - err = wl_init_priv(wl); - if (err) { - WL_ERR(("Failed to init iwm_priv (%d)\n", err)); - goto cfg80211_attach_out; - } - - err = wl_setup_rfkill(wl, TRUE); - if (err) { - WL_ERR(("Failed to setup rfkill %d\n", err)); - goto cfg80211_attach_out; - } - err = register_netdevice_notifier(&wl_cfg80211_netdev_notifier); - if (err) { - WL_ERR(("Failed to register notifierl %d\n", err)); - goto cfg80211_attach_out; - } -#if defined(COEX_DHCP) - if (wl_cfg80211_btcoex_init(wl)) - goto cfg80211_attach_out; -#endif - - wlcfg_drv_priv = wl; - -#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF) - err = wl_cfg80211_attach_p2p(); - if (err) - goto cfg80211_attach_out; -#endif - - return err; - -cfg80211_attach_out: - err = wl_setup_rfkill(wl, FALSE); - wl_free_wdev(wl); - return err; -} - -void wl_cfg80211_detach(void *para) -{ - struct wl_priv *wl; - - wl = wlcfg_drv_priv; - - WL_TRACE(("In\n")); - -#if defined(COEX_DHCP) - wl_cfg80211_btcoex_deinit(wl); -#endif - -#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF) - wl_cfg80211_detach_p2p(); -#endif - wl_setup_rfkill(wl, FALSE); - if (wl->p2p_supported) - wl_cfgp2p_deinit_priv(wl); - wl_deinit_priv(wl); - wlcfg_drv_priv = NULL; - wl_cfg80211_clear_parent_dev(); - wl_free_wdev(wl); - /* PLEASE do NOT call any function after wl_free_wdev, the driver's private structure "wl", - * which is the private part of wiphy, has been freed in wl_free_wdev !!!!!!!!!!! - */ -} - -static void wl_wakeup_event(struct wl_priv *wl) -{ - if (wl->event_tsk.thr_pid >= 0) { - DHD_OS_WAKE_LOCK(wl->pub); - up(&wl->event_tsk.sema); - } -} - -static int wl_is_p2p_event(struct wl_event_q *e) -{ - switch (e->etype) { - /* We have to seperate out the P2P events received - * on primary interface so that it can be send up - * via p2p0 interface. - */ - case WLC_E_P2P_PROBREQ_MSG: - case WLC_E_P2P_DISC_LISTEN_COMPLETE: - case WLC_E_ACTION_FRAME_RX: - case WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE: - case WLC_E_ACTION_FRAME_COMPLETE: - - if (e->emsg.ifidx != 0) { - WL_TRACE(("P2P Event on Virtual I/F (ifidx:%d) \n", - e->emsg.ifidx)); - /* We are only bothered about the P2P events received - * on primary interface. For rest of them return false - * so that it is sent over the interface corresponding - * to the ifidx. - */ - return FALSE; - } else { - WL_TRACE(("P2P Event on Primary I/F (ifidx:%d)." - " Sent it to p2p0 \n", e->emsg.ifidx)); - return TRUE; - } - break; - - default: - WL_TRACE(("NON-P2P Event %d on ifidx (ifidx:%d) \n", - e->etype, e->emsg.ifidx)); - return FALSE; - } -} - -static s32 wl_event_handler(void *data) -{ - struct net_device *netdev; - struct wl_priv *wl = NULL; - struct wl_event_q *e; - tsk_ctl_t *tsk = (tsk_ctl_t *)data; - - wl = (struct wl_priv *)tsk->parent; - DAEMONIZE("dhd_cfg80211_event"); - complete(&tsk->completed); - - while (down_interruptible (&tsk->sema) == 0) { - SMP_RD_BARRIER_DEPENDS(); - if (tsk->terminated) - break; - while ((e = wl_deq_event(wl))) { - WL_DBG(("event type (%d), if idx: %d\n", e->etype, e->emsg.ifidx)); - /* All P2P device address related events comes on primary interface since - * there is no corresponding bsscfg for P2P interface. Map it to p2p0 - * interface. - */ - if ((wl_is_p2p_event(e) == TRUE) && (wl->p2p_net)) { - netdev = wl->p2p_net; - } else { - netdev = dhd_idx2net((struct dhd_pub *)(wl->pub), e->emsg.ifidx); - } - if (!netdev) - netdev = wl_to_prmry_ndev(wl); - if (e->etype < WLC_E_LAST && wl->evt_handler[e->etype]) { - wl->evt_handler[e->etype] (wl, netdev, &e->emsg, e->edata); - } else { - WL_DBG(("Unknown Event (%d): ignoring\n", e->etype)); - } - wl_put_event(e); - } - DHD_OS_WAKE_UNLOCK(wl->pub); - } - WL_ERR(("%s was terminated\n", __func__)); - complete_and_exit(&tsk->completed, 0); - return 0; -} - -void -wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data) -{ - u32 event_type = ntoh32(e->event_type); - struct wl_priv *wl = wlcfg_drv_priv; - -#if (WL_DBG_LEVEL > 0) - s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ? - wl_dbg_estr[event_type] : (s8 *) "Unknown"; - WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr)); -#endif /* (WL_DBG_LEVEL > 0) */ - - if (likely(!wl_enq_event(wl, ndev, event_type, e, data))) - wl_wakeup_event(wl); -} - -static void wl_init_eq(struct wl_priv *wl) -{ - wl_init_eq_lock(wl); - INIT_LIST_HEAD(&wl->eq_list); -} - -static void wl_flush_eq(struct wl_priv *wl) -{ - struct wl_event_q *e; - unsigned long flags; - - flags = wl_lock_eq(wl); - while (!list_empty(&wl->eq_list)) { - e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list); - list_del(&e->eq_list); - kfree(e); - } - wl_unlock_eq(wl, flags); -} - -/* -* retrieve first queued event from head -*/ - -static struct wl_event_q *wl_deq_event(struct wl_priv *wl) -{ - struct wl_event_q *e = NULL; - unsigned long flags; - - flags = wl_lock_eq(wl); - if (likely(!list_empty(&wl->eq_list))) { - e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list); - list_del(&e->eq_list); - } - wl_unlock_eq(wl, flags); - - return e; -} - -/* - * push event to tail of the queue - */ - -static s32 -wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 event, const wl_event_msg_t *msg, - void *data) -{ - struct wl_event_q *e; - s32 err = 0; - uint32 evtq_size; - uint32 data_len; - unsigned long flags; - gfp_t aflags; - - data_len = 0; - if (data) - data_len = ntoh32(msg->datalen); - evtq_size = sizeof(struct wl_event_q) + data_len; - aflags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; - e = kzalloc(evtq_size, aflags); - if (unlikely(!e)) { - WL_ERR(("event alloc failed\n")); - return -ENOMEM; - } - e->etype = event; - memcpy(&e->emsg, msg, sizeof(wl_event_msg_t)); - if (data) - memcpy(e->edata, data, data_len); - flags = wl_lock_eq(wl); - list_add_tail(&e->eq_list, &wl->eq_list); - wl_unlock_eq(wl, flags); - - return err; -} - -static void wl_put_event(struct wl_event_q *e) -{ - kfree(e); -} - -static s32 wl_config_ifmode(struct wl_priv *wl, struct net_device *ndev, s32 iftype) -{ - s32 infra = 0; - s32 err = 0; - s32 mode = 0; - switch (iftype) { - case NL80211_IFTYPE_MONITOR: - case NL80211_IFTYPE_WDS: - WL_ERR(("type (%d) : currently we do not support this mode\n", - iftype)); - err = -EINVAL; - return err; - case NL80211_IFTYPE_ADHOC: - mode = WL_MODE_IBSS; - break; - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_P2P_CLIENT: - mode = WL_MODE_BSS; - infra = 1; - break; - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_P2P_GO: - mode = WL_MODE_AP; - infra = 1; - break; - default: - err = -EINVAL; - WL_ERR(("invalid type (%d)\n", iftype)); - return err; - } - infra = htod32(infra); - err = wldev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra), true); - if (unlikely(err)) { - WL_ERR(("WLC_SET_INFRA error (%d)\n", err)); - return err; - } - - wl_set_mode_by_netdev(wl, ndev, mode); - - return 0; -} - -s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add) -{ - s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; - - s8 eventmask[WL_EVENTING_MASK_LEN]; - s32 err = 0; - - /* Setup event_msgs */ - bcm_mkiovar("event_msgs", NULL, 0, iovbuf, - sizeof(iovbuf)); - err = wldev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf), false); - if (unlikely(err)) { - WL_ERR(("Get event_msgs error (%d)\n", err)); - goto eventmsg_out; - } - memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN); - if (add) { - setbit(eventmask, event); - } else { - clrbit(eventmask, event); - } - bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, - sizeof(iovbuf)); - err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true); - if (unlikely(err)) { - WL_ERR(("Set event_msgs error (%d)\n", err)); - goto eventmsg_out; - } - -eventmsg_out: - return err; - -} - -static int wl_construct_reginfo(struct wl_priv *wl, s32 bw_cap) -{ - struct net_device *dev = wl_to_prmry_ndev(wl); - struct ieee80211_channel *band_chan_arr = NULL; - wl_uint32_list_t *list; - u32 i, j, index, n_2g, n_5g, band, channel, array_size; - u32 *n_cnt = NULL; - chanspec_t c = 0; - s32 err = BCME_OK; - bool update; - bool ht40_allowed; - u8 *pbuf = NULL; - -#define LOCAL_BUF_LEN 1024 - pbuf = kzalloc(LOCAL_BUF_LEN, GFP_KERNEL); - if (pbuf == NULL) { - WL_ERR(("failed to allocate local buf\n")); - return -ENOMEM; - } - - list = (wl_uint32_list_t *)(void *)pbuf; - list->count = htod32(WL_NUMCHANSPECS); - - err = wldev_iovar_getbuf_bsscfg(dev, "chanspecs", NULL, - 0, pbuf, LOCAL_BUF_LEN, 0, &wl->ioctl_buf_sync); - if (err != 0) { - WL_ERR(("get chanspecs failed with %d\n", err)); - kfree(pbuf); - return err; - } -#undef LOCAL_BUF_LEN - - band = array_size = n_2g = n_5g = 0; - for (i = 0; i < dtoh32(list->count); i++) { - index = 0; - update = FALSE; - ht40_allowed = FALSE; - c = (chanspec_t)dtoh32(list->element[i]); - channel = CHSPEC_CHANNEL(c); - if (CHSPEC_IS40(c)) { - if (CHSPEC_SB_UPPER(c)) - channel += CH_10MHZ_APART; - else - channel -= CH_10MHZ_APART; - } - - if (CHSPEC_IS2G(c) && channel <= CH_MAX_2G_CHANNEL) { - band_chan_arr = __wl_2ghz_channels; - array_size = ARRAYSIZE(__wl_2ghz_channels); - n_cnt = &n_2g; - band = IEEE80211_BAND_2GHZ; - ht40_allowed = (bw_cap == WLC_N_BW_40ALL) ? TRUE : FALSE; - } else if (CHSPEC_IS5G(c) && channel > CH_MAX_2G_CHANNEL) { - band_chan_arr = __wl_5ghz_a_channels; - array_size = ARRAYSIZE(__wl_5ghz_a_channels); - n_cnt = &n_5g; - band = IEEE80211_BAND_5GHZ; - ht40_allowed = (bw_cap == WLC_N_BW_20ALL) ? FALSE : TRUE; - } - else { - WL_ERR(("Invalid Channel received %x\n", channel)); - continue; - } - - for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) { - if (band_chan_arr[j].hw_value == channel) { - update = TRUE; - break; - } - } - - if (update) - index = j; - else - index = *n_cnt; - - if (index < array_size) { -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) - band_chan_arr[index].center_freq = - ieee80211_channel_to_frequency(channel); -#else - band_chan_arr[index].center_freq = - ieee80211_channel_to_frequency(channel, band); -#endif - band_chan_arr[index].hw_value = channel; - - if (CHSPEC_IS40(c) && ht40_allowed) { - u32 ht40_flag = band_chan_arr[index].flags & IEEE80211_CHAN_NO_HT40; - if (CHSPEC_SB_UPPER(c)) { - if (ht40_flag == IEEE80211_CHAN_NO_HT40) - band_chan_arr[index].flags &= ~IEEE80211_CHAN_NO_HT40; - band_chan_arr[index].flags |= IEEE80211_CHAN_NO_HT40PLUS; - } else { - band_chan_arr[index].flags &= ~IEEE80211_CHAN_NO_HT40; - if (ht40_flag == IEEE80211_CHAN_NO_HT40) - band_chan_arr[index].flags |= IEEE80211_CHAN_NO_HT40MINUS; - } - } else { - band_chan_arr[index].flags = IEEE80211_CHAN_NO_HT40; - if (band == IEEE80211_BAND_2GHZ) - channel |= WL_CHANSPEC_BAND_2G; - else - channel |= WL_CHANSPEC_BAND_5G; - err = wldev_iovar_getint(dev, "per_chan_info", &channel); - if (!err) { - if (channel & WL_CHAN_RADAR) { - band_chan_arr[index].flags |= IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS; - } - if (channel & WL_CHAN_PASSIVE) { - band_chan_arr[index].flags |= IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS; - } - } - } - - if (!update) - (*n_cnt)++; - } - } - - __wl_band_2ghz.n_channels = n_2g; - __wl_band_5ghz_a.n_channels = n_5g; - - kfree(pbuf); - return err; -} - -s32 wl_update_wiphybands(struct wl_priv *wl) -{ - struct wiphy *wiphy; - struct net_device *dev; - u32 bandlist[3]; - u32 nband = 0; - u32 i = 0; - s32 err = 0; - int nmode = 0; - int bw_cap = 0; - int index = 0; - bool rollback_lock = false; - - WL_DBG(("Entry")); - - if (wl == NULL) { - wl = wlcfg_drv_priv; - mutex_lock(&wl->usr_sync); - rollback_lock = true; - } - dev = wl_to_prmry_ndev(wl); - - memset(bandlist, 0, sizeof(bandlist)); - err = wldev_ioctl(dev, WLC_GET_BANDLIST, bandlist, - sizeof(bandlist), false); - if (unlikely(err)) { - WL_ERR(("error read bandlist (%d)\n", err)); - goto end_bands; - } - wiphy = wl_to_wiphy(wl); - nband = bandlist[0]; - wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; - wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; - - err = wldev_iovar_getint(dev, "nmode", &nmode); - if (unlikely(err)) { - WL_ERR(("error reading nmode (%d)\n", err)); - } else { - /* For nmodeonly check bw cap */ - err = wldev_iovar_getint(dev, "mimo_bw_cap", &bw_cap); - if (unlikely(err)) { - WL_ERR(("error get mimo_bw_cap (%d)\n", err)); - } - } - - err = wl_construct_reginfo(wl, bw_cap); - if (err) { - WL_ERR(("wl_construct_reginfo() fails err=%d\n", err)); - if (err != BCME_UNSUPPORTED) - goto end_bands; - /* Ignore error if "chanspecs" command is not supported */ - err = 0; - } - for (i = 1; i <= nband && i < sizeof(bandlist)/sizeof(u32); i++) { - index = -1; - if (bandlist[i] == WLC_BAND_5G && __wl_band_5ghz_a.n_channels > 0) { - wiphy->bands[IEEE80211_BAND_5GHZ] = - &__wl_band_5ghz_a; - index = IEEE80211_BAND_5GHZ; - if (bw_cap == WLC_N_BW_40ALL || bw_cap == WLC_N_BW_20IN2G_40IN5G) - wiphy->bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; - } else if (bandlist[i] == WLC_BAND_2G && __wl_band_2ghz.n_channels > 0) { - wiphy->bands[IEEE80211_BAND_2GHZ] = - &__wl_band_2ghz; - index = IEEE80211_BAND_2GHZ; - if (bw_cap == WLC_N_BW_40ALL) - wiphy->bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; - } - if ((index >= 0) && nmode) { - wiphy->bands[index]->ht_cap.cap |= - IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_DSSSCCK40; - wiphy->bands[index]->ht_cap.ht_supported = TRUE; - wiphy->bands[index]->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; - wiphy->bands[index]->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; - wiphy->bands[index]->ht_cap.mcs.rx_mask[0] = 0xff; - } - } - - wiphy_apply_custom_regulatory(wiphy, &brcm_regdom); - -end_bands: - if (rollback_lock) - mutex_unlock(&wl->usr_sync); - return err; -} - -static s32 __wl_cfg80211_up(struct wl_priv *wl) -{ - s32 err = 0; - struct net_device *ndev = wl_to_prmry_ndev(wl); - struct wireless_dev *wdev = ndev->ieee80211_ptr; - - WL_DBG(("In\n")); - - err = dhd_config_dongle(wl, false); - if (unlikely(err)) - return err; - - err = wl_config_ifmode(wl, ndev, wdev->iftype); - if (unlikely(err && err != -EINPROGRESS)) { - WL_ERR(("wl_config_ifmode failed\n")); - } - err = wl_update_wiphybands(wl); - if (unlikely(err)) { - WL_ERR(("wl_update_wiphybands failed\n")); - } - - err = dhd_monitor_init(wl->pub); - err = wl_invoke_iscan(wl); - wl_set_drv_status(wl, READY, ndev); - return err; -} - -static s32 __wl_cfg80211_down(struct wl_priv *wl) -{ - s32 err = 0; - unsigned long flags; - struct net_info *iter, *next; - struct net_device *ndev = wl_to_prmry_ndev(wl); -#ifdef WL_ENABLE_P2P_IF - struct wiphy *wiphy = wl_to_prmry_ndev(wl)->ieee80211_ptr->wiphy; - struct net_device *p2p_net = wl->p2p_net; -#endif - - WL_DBG(("In\n")); - /* Check if cfg80211 interface is already down */ - if (!wl_get_drv_status(wl, READY, ndev)) - return err; /* it is even not ready */ - for_each_ndev(wl, iter, next) - wl_set_drv_status(wl, SCAN_ABORTING, iter->ndev); - - wl_term_iscan(wl); - spin_lock_irqsave(&wl->cfgdrv_lock, flags); - if (wl->scan_request) { - cfg80211_scan_done(wl->scan_request, true); - wl->scan_request = NULL; - } - for_each_ndev(wl, iter, next) { - wl_clr_drv_status(wl, READY, iter->ndev); - wl_clr_drv_status(wl, SCANNING, iter->ndev); - wl_clr_drv_status(wl, SCAN_ABORTING, iter->ndev); - wl_clr_drv_status(wl, CONNECTING, iter->ndev); - wl_clr_drv_status(wl, CONNECTED, iter->ndev); - wl_clr_drv_status(wl, DISCONNECTING, iter->ndev); - wl_clr_drv_status(wl, AP_CREATED, iter->ndev); - wl_clr_drv_status(wl, AP_CREATING, iter->ndev); - } - wl_to_prmry_ndev(wl)->ieee80211_ptr->iftype = - NL80211_IFTYPE_STATION; -#ifdef WL_ENABLE_P2P_IF - wiphy->interface_modes = (wiphy->interface_modes) - & (~(BIT(NL80211_IFTYPE_P2P_CLIENT)| - BIT(NL80211_IFTYPE_P2P_GO))); - if ((p2p_net) && (p2p_net->flags & IFF_UP)) { - /* p2p0 interface is still UP. Bring it down */ - p2p_net->flags &= ~IFF_UP; - } -#endif /* WL_ENABLE_P2P_IF */ - spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); - - DNGL_FUNC(dhd_cfg80211_down, (wl)); - wl_flush_eq(wl); - wl_link_down(wl); - if (wl->p2p_supported) - wl_cfgp2p_down(wl); - dhd_monitor_uninit(); - - return err; -} - -s32 wl_cfg80211_up(void *para) -{ - struct wl_priv *wl; - s32 err = 0; - - WL_DBG(("In\n")); - wl = wlcfg_drv_priv; - mutex_lock(&wl->usr_sync); - wl_cfg80211_attach_post(wl_to_prmry_ndev(wl)); - err = __wl_cfg80211_up(wl); - if (err) - WL_ERR(("__wl_cfg80211_up failed\n")); - mutex_unlock(&wl->usr_sync); - return err; -} - -/* Private Event to Supplicant with indication that chip hangs */ -int wl_cfg80211_hang(struct net_device *dev, u16 reason) -{ - struct wl_priv *wl; - wl = wlcfg_drv_priv; - - WL_ERR(("In : chip crash eventing\n")); - cfg80211_disconnected(dev, reason, NULL, 0, GFP_KERNEL); - if (wl != NULL) { - wl_link_down(wl); - } - return 0; -} - -s32 wl_cfg80211_down(void *para) -{ - struct wl_priv *wl; - s32 err = 0; - - WL_DBG(("In\n")); - wl = wlcfg_drv_priv; - mutex_lock(&wl->usr_sync); - err = __wl_cfg80211_down(wl); - mutex_unlock(&wl->usr_sync); - - return err; -} - -static void *wl_read_prof(struct wl_priv *wl, struct net_device *ndev, s32 item) -{ - unsigned long flags; - void *rptr = NULL; - struct wl_profile *profile = wl_get_profile_by_netdev(wl, ndev); - - if (!profile) - return NULL; - spin_lock_irqsave(&wl->cfgdrv_lock, flags); - switch (item) { - case WL_PROF_SEC: - rptr = &profile->sec; - break; - case WL_PROF_ACT: - rptr = &profile->active; - break; - case WL_PROF_BSSID: - rptr = profile->bssid; - break; - case WL_PROF_PENDING_BSSID: - rptr = profile->pending_bssid; - break; - case WL_PROF_SSID: - rptr = &profile->ssid; - break; - } - spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); - if (!rptr) - WL_ERR(("invalid item (%d)\n", item)); - return rptr; -} - -static s32 -wl_update_prof(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data, s32 item) -{ - s32 err = 0; - struct wlc_ssid *ssid; - unsigned long flags; - struct wl_profile *profile = wl_get_profile_by_netdev(wl, ndev); - - if (!profile) - return WL_INVALID; - spin_lock_irqsave(&wl->cfgdrv_lock, flags); - switch (item) { - case WL_PROF_SSID: - ssid = (wlc_ssid_t *) data; - memset(profile->ssid.SSID, 0, - sizeof(profile->ssid.SSID)); - memcpy(profile->ssid.SSID, ssid->SSID, ssid->SSID_len); - profile->ssid.SSID_len = ssid->SSID_len; - break; - case WL_PROF_BSSID: - if (data) - memcpy(profile->bssid, data, ETHER_ADDR_LEN); - else - memset(profile->bssid, 0, ETHER_ADDR_LEN); - break; - case WL_PROF_PENDING_BSSID: - if (data) - memcpy(profile->pending_bssid, data, ETHER_ADDR_LEN); - else - memset(profile->pending_bssid, 0, ETHER_ADDR_LEN); - break; - case WL_PROF_SEC: - memcpy(&profile->sec, data, sizeof(profile->sec)); - break; - case WL_PROF_ACT: - profile->active = *(bool *)data; - break; - case WL_PROF_BEACONINT: - profile->beacon_interval = *(u16 *)data; - break; - case WL_PROF_DTIMPERIOD: - profile->dtim_period = *(u8 *)data; - break; - default: - WL_ERR(("unsupported item (%d)\n", item)); - err = -EOPNOTSUPP; - break; - } - spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); - return err; -} - -void wl_cfg80211_dbg_level(u32 level) -{ - /* - * prohibit to change debug level - * by insmod parameter. - * eventually debug level will be configured - * in compile time by using CONFIG_XXX - */ - /* wl_dbg_level = level; */ -} - -static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev) -{ - return wl_get_mode_by_netdev(wl, ndev) == WL_MODE_IBSS; -} - -static __used bool wl_is_ibssstarter(struct wl_priv *wl) -{ - return wl->ibss_starter; -} - -static void wl_rst_ie(struct wl_priv *wl) -{ - struct wl_ie *ie = wl_to_ie(wl); - - ie->offset = 0; -} - -static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v) -{ - struct wl_ie *ie = wl_to_ie(wl); - s32 err = 0; - - if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) { - WL_ERR(("ei crosses buffer boundary\n")); - return -ENOSPC; - } - ie->buf[ie->offset] = t; - ie->buf[ie->offset + 1] = l; - memcpy(&ie->buf[ie->offset + 2], v, l); - ie->offset += l + 2; - - return err; -} - -static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size) -{ - struct wl_ie *ie = wl_to_ie(wl); - s32 err = 0; - - if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) { - WL_ERR(("ei_stream crosses buffer boundary\n")); - return -ENOSPC; - } - memcpy(&ie->buf[ie->offset], ie_stream, ie_size); - ie->offset += ie_size; - - return err; -} - -static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size) -{ - struct wl_ie *ie = wl_to_ie(wl); - s32 err = 0; - - if (unlikely(ie->offset > dst_size)) { - WL_ERR(("dst_size is not enough\n")); - return -ENOSPC; - } - memcpy(dst, &ie->buf[0], ie->offset); - - return err; -} - -static u32 wl_get_ielen(struct wl_priv *wl) -{ - struct wl_ie *ie = wl_to_ie(wl); - - return ie->offset; -} - -static void wl_link_up(struct wl_priv *wl) -{ - wl->link_up = true; -} - -static void wl_link_down(struct wl_priv *wl) -{ - struct wl_connect_info *conn_info = wl_to_conn(wl); - - WL_DBG(("In\n")); - wl->link_up = false; - conn_info->req_ie_len = 0; - conn_info->resp_ie_len = 0; -} - -static unsigned long wl_lock_eq(struct wl_priv *wl) -{ - unsigned long flags; - - spin_lock_irqsave(&wl->eq_lock, flags); - return flags; -} - -static void wl_unlock_eq(struct wl_priv *wl, unsigned long flags) -{ - spin_unlock_irqrestore(&wl->eq_lock, flags); -} - -static void wl_init_eq_lock(struct wl_priv *wl) -{ - spin_lock_init(&wl->eq_lock); -} - -static void wl_delay(u32 ms) -{ - if (in_atomic() || (ms < jiffies_to_msecs(1))) { - mdelay(ms); - } else { - msleep(ms); - } -} - -s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr) -{ - struct wl_priv *wl = wlcfg_drv_priv; - struct ether_addr p2pif_addr; - struct ether_addr primary_mac; - - if (!wl->p2p) - return -1; - if (!p2p_is_on(wl)) { - get_primary_mac(wl, &primary_mac); - wl_cfgp2p_generate_bss_mac(&primary_mac, p2pdev_addr, &p2pif_addr); - } else { - memcpy(p2pdev_addr->octet, - wl->p2p->dev_addr.octet, ETHER_ADDR_LEN); - } - - return 0; -} -s32 wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len) -{ - struct wl_priv *wl; - - wl = wlcfg_drv_priv; - - return wl_cfgp2p_set_p2p_noa(wl, net, buf, len); -} - -s32 wl_cfg80211_get_p2p_noa(struct net_device *net, char* buf, int len) -{ - struct wl_priv *wl; - wl = wlcfg_drv_priv; - - return wl_cfgp2p_get_p2p_noa(wl, net, buf, len); -} - -s32 wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len) -{ - struct wl_priv *wl; - wl = wlcfg_drv_priv; - - return wl_cfgp2p_set_p2p_ps(wl, net, buf, len); -} - -s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len, - enum wl_management_type type) -{ - struct wl_priv *wl; - struct net_device *ndev = NULL; - struct ether_addr primary_mac; - s32 ret = 0; - s32 bssidx = 0; - s32 pktflag = 0; - wl = wlcfg_drv_priv; - - if (wl_get_drv_status(wl, AP_CREATING, net) || - wl_get_drv_status(wl, AP_CREATED, net)) { - ndev = net; - bssidx = 0; - } else if (wl->p2p) { - if (net == wl->p2p_net) { - net = wl_to_prmry_ndev(wl); - } - - if (!wl->p2p->on) { - get_primary_mac(wl, &primary_mac); - wl_cfgp2p_generate_bss_mac(&primary_mac, &wl->p2p->dev_addr, - &wl->p2p->int_addr); - /* In case of p2p_listen command, supplicant send remain_on_channel - * without turning on P2P - */ - p2p_on(wl) = true; - ret = wl_cfgp2p_enable_discovery(wl, ndev, NULL, 0); - - if (unlikely(ret)) { - goto exit; - } - } - if (net != wl_to_prmry_ndev(wl)) { - if (wl_get_mode_by_netdev(wl, net) == WL_MODE_AP) { - ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION); - bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION); - } - } else { - ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY); - bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE); - } - } - if (ndev != NULL) { - switch (type) { - case WL_BEACON: - pktflag = VNDR_IE_BEACON_FLAG; - break; - case WL_PROBE_RESP: - pktflag = VNDR_IE_PRBRSP_FLAG; - break; - case WL_ASSOC_RESP: - pktflag = VNDR_IE_ASSOCRSP_FLAG; - break; - } - if (pktflag) - ret = wl_cfgp2p_set_management_ie(wl, ndev, bssidx, pktflag, buf, len); - } -exit: - return ret; -} - -static const struct rfkill_ops wl_rfkill_ops = { - .set_block = wl_rfkill_set -}; - -static int wl_rfkill_set(void *data, bool blocked) -{ - struct wl_priv *wl = (struct wl_priv *)data; - - WL_DBG(("Enter \n")); - WL_DBG(("RF %s\n", blocked ? "blocked" : "unblocked")); - - if (!wl) - return -EINVAL; - - wl->rf_blocked = blocked; - - return 0; -} - -static int wl_setup_rfkill(struct wl_priv *wl, bool setup) -{ - s32 err = 0; - - WL_DBG(("Enter \n")); - if (!wl) - return -EINVAL; - if (setup) { - wl->rfkill = rfkill_alloc("brcmfmac-wifi", - wl_cfg80211_get_parent_dev(), - RFKILL_TYPE_WLAN, &wl_rfkill_ops, (void *)wl); - - if (!wl->rfkill) { - err = -ENOMEM; - goto err_out; - } - - err = rfkill_register(wl->rfkill); - - if (err) - rfkill_destroy(wl->rfkill); - } else { - if (!wl->rfkill) { - err = -ENOMEM; - goto err_out; - } - - rfkill_unregister(wl->rfkill); - rfkill_destroy(wl->rfkill); - } - -err_out: - return err; -} - -struct device *wl_cfg80211_get_parent_dev(void) -{ - return cfg80211_parent_dev; -} - -void wl_cfg80211_set_parent_dev(void *dev) -{ - cfg80211_parent_dev = dev; -} - -static void wl_cfg80211_clear_parent_dev(void) -{ - cfg80211_parent_dev = NULL; -} - -static void get_primary_mac(struct wl_priv *wl, struct ether_addr *mac) -{ - wldev_iovar_getbuf_bsscfg(wl_to_prmry_ndev(wl), "cur_etheraddr", NULL, - 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &wl->ioctl_buf_sync); - memcpy(mac->octet, wl->ioctl_buf, ETHER_ADDR_LEN); -} - -int wl_cfg80211_do_driver_init(struct net_device *net) -{ - struct wl_priv *wl = *(struct wl_priv **)netdev_priv(net); - - if (!wl || !wl->wdev) - return -EINVAL; - - if (dhd_do_driver_init(wl->wdev->netdev) < 0) - return -1; - - return 0; -} - -void wl_cfg80211_enable_trace(int level) -{ - wl_dbg_level |= WL_DBG_DBG; -} - -static s32 -wl_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, - struct net_device *dev, u64 cookie) -{ - return 0; -} diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/wl_cfg80211.h deleted file mode 100644 index 6d237eee2ccb..000000000000 --- a/drivers/net/wireless/bcmdhd/wl_cfg80211.h +++ /dev/null @@ -1,693 +0,0 @@ -/* - * Linux cfg80211 driver - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wl_cfg80211.h,v 1.1.4.1.2.8 2011/02/09 01:37:52 Exp $ - */ - -#ifndef _wl_cfg80211_h_ -#define _wl_cfg80211_h_ - -#include -#include -#include -#include -#include -#include -#include - -#include - -struct wl_conf; -struct wl_iface; -struct wl_priv; -struct wl_security; -struct wl_ibss; - - -#define htod32(i) i -#define htod16(i) i -#define dtoh32(i) i -#define dtoh16(i) i -#define htodchanspec(i) i -#define dtohchanspec(i) i - -#define WL_DBG_NONE 0 -#define WL_DBG_TRACE (1 << 4) -#define WL_DBG_SCAN (1 << 3) -#define WL_DBG_DBG (1 << 2) -#define WL_DBG_INFO (1 << 1) -#define WL_DBG_ERR (1 << 0) - -/* 0 invalidates all debug messages. default is 1 */ -#define WL_DBG_LEVEL 0xFF - -#if defined(DHD_DEBUG) -#define WL_ERR(args) \ -do { \ - if (wl_dbg_level & WL_DBG_ERR) { \ - printk(KERN_ERR "CFG80211-ERROR) %s : ", __func__); \ - printk args; \ - } \ -} while (0) -#else /* defined(DHD_DEBUG) */ -#define WL_ERR(args) \ -do { \ - if ((wl_dbg_level & WL_DBG_ERR) && net_ratelimit()) { \ - printk(KERN_INFO "CFG80211-ERROR) %s : ", __func__); \ - printk args; \ - } \ -} while (0) -#endif /* defined(DHD_DEBUG) */ - -#ifdef WL_INFO -#undef WL_INFO -#endif -#define WL_INFO(args) \ -do { \ - if (wl_dbg_level & WL_DBG_INFO) { \ - printk(KERN_ERR "CFG80211-INFO) %s : ", __func__); \ - printk args; \ - } \ -} while (0) -#ifdef WL_SCAN -#undef WL_SCAN -#endif -#define WL_SCAN(args) \ -do { \ - if (wl_dbg_level & WL_DBG_SCAN) { \ - printk(KERN_ERR "CFG80211-SCAN) %s :", __func__); \ - printk args; \ - } \ -} while (0) -#ifdef WL_TRACE -#undef WL_TRACE -#endif -#define WL_TRACE(args) \ -do { \ - if (wl_dbg_level & WL_DBG_TRACE) { \ - printk(KERN_ERR "CFG80211-TRACE) %s :", __func__); \ - printk args; \ - } \ -} while (0) -#if (WL_DBG_LEVEL > 0) -#define WL_DBG(args) \ -do { \ - if (wl_dbg_level & WL_DBG_DBG) { \ - printk(KERN_ERR "CFG80211-DEBUG) %s :", __func__); \ - printk args; \ - } \ -} while (0) -#else /* !(WL_DBG_LEVEL > 0) */ -#define WL_DBG(args) -#endif /* (WL_DBG_LEVEL > 0) */ - - -#define WL_SCAN_RETRY_MAX 3 -#define WL_NUM_PMKIDS_MAX MAXPMKID -#define WL_SCAN_BUF_MAX (1024 * 8) -#define WL_TLV_INFO_MAX 1024 -#define WL_SCAN_IE_LEN_MAX 2048 -#define WL_BSS_INFO_MAX 2048 -#define WL_ASSOC_INFO_MAX 512 -#define WL_IOCTL_LEN_MAX 1024 -#define WL_EXTRA_BUF_MAX 2048 -#define WL_ISCAN_BUF_MAX 2048 -#define WL_ISCAN_TIMER_INTERVAL_MS 3000 -#define WL_SCAN_ERSULTS_LAST (WL_SCAN_RESULTS_NO_MEM+1) -#define WL_AP_MAX 256 -#define WL_FILE_NAME_MAX 256 -#define WL_DWELL_TIME 200 -#define WL_MED_DWELL_TIME 400 -#define WL_LONG_DWELL_TIME 1000 -#define IFACE_MAX_CNT 2 - -#define WL_SCAN_TIMER_INTERVAL_MS 8000 /* Scan timeout */ -#define WL_CHANNEL_SYNC_RETRY 3 -#define WL_ACT_FRAME_RETRY 4 - -#define WL_INVALID -1 - - -/* Bring down SCB Timeout to 20secs from 60secs default */ -#ifndef WL_SCB_TIMEOUT -#define WL_SCB_TIMEOUT 20 -#endif - -#define WLAN_REASON_DRIVER_ERROR WLAN_REASON_UNSPECIFIED - -/* driver status */ -enum wl_status { - WL_STATUS_READY = 0, - WL_STATUS_SCANNING, - WL_STATUS_SCAN_ABORTING, - WL_STATUS_CONNECTING, - WL_STATUS_CONNECTED, - WL_STATUS_DISCONNECTING, - WL_STATUS_AP_CREATING, - WL_STATUS_AP_CREATED, - WL_STATUS_SENDING_ACT_FRM -}; - -/* wi-fi mode */ -enum wl_mode { - WL_MODE_BSS, - WL_MODE_IBSS, - WL_MODE_AP -}; - -/* driver profile list */ -enum wl_prof_list { - WL_PROF_MODE, - WL_PROF_SSID, - WL_PROF_SEC, - WL_PROF_IBSS, - WL_PROF_BAND, - WL_PROF_BSSID, - WL_PROF_PENDING_BSSID, - WL_PROF_ACT, - WL_PROF_BEACONINT, - WL_PROF_DTIMPERIOD -}; - -/* driver iscan state */ -enum wl_iscan_state { - WL_ISCAN_STATE_IDLE, - WL_ISCAN_STATE_SCANING -}; - -/* donlge escan state */ -enum wl_escan_state { - WL_ESCAN_STATE_IDLE, - WL_ESCAN_STATE_SCANING -}; -/* fw downloading status */ -enum wl_fw_status { - WL_FW_LOADING_DONE, - WL_NVRAM_LOADING_DONE -}; - -enum wl_management_type { - WL_BEACON = 0x1, - WL_PROBE_RESP = 0x2, - WL_ASSOC_RESP = 0x4 -}; -/* beacon / probe_response */ -struct beacon_proberesp { - __le64 timestamp; - __le16 beacon_int; - __le16 capab_info; - u8 variable[0]; -} __attribute__ ((packed)); - -/* driver configuration */ -struct wl_conf { - u32 frag_threshold; - u32 rts_threshold; - u32 retry_short; - u32 retry_long; - s32 tx_power; - struct ieee80211_channel channel; -}; - -typedef s32(*EVENT_HANDLER) (struct wl_priv *wl, - struct net_device *ndev, const wl_event_msg_t *e, void *data); - -/* bss inform structure for cfg80211 interface */ -struct wl_cfg80211_bss_info { - u16 band; - u16 channel; - s16 rssi; - u16 frame_len; - u8 frame_buf[1]; -}; - -/* basic structure of scan request */ -struct wl_scan_req { - struct wlc_ssid ssid; -}; - -/* basic structure of information element */ -struct wl_ie { - u16 offset; - u8 buf[WL_TLV_INFO_MAX]; -}; - -/* event queue for cfg80211 main event */ -struct wl_event_q { - struct list_head eq_list; - u32 etype; - wl_event_msg_t emsg; - s8 edata[1]; -}; - -/* security information with currently associated ap */ -struct wl_security { - u32 wpa_versions; - u32 auth_type; - u32 cipher_pairwise; - u32 cipher_group; - u32 wpa_auth; -}; - -/* ibss information for currently joined ibss network */ -struct wl_ibss { - u8 beacon_interval; /* in millisecond */ - u8 atim; /* in millisecond */ - s8 join_only; - u8 band; - u8 channel; -}; - -/* wl driver profile */ -struct wl_profile { - u32 mode; - s32 band; - struct wlc_ssid ssid; - struct wl_security sec; - struct wl_ibss ibss; - u8 bssid[ETHER_ADDR_LEN]; - u8 pending_bssid[ETHER_ADDR_LEN]; - u16 beacon_interval; - u8 dtim_period; - bool active; -}; - -struct net_info { - struct net_device *ndev; - struct wireless_dev *wdev; - struct wl_profile profile; - s32 mode; - unsigned long sme_state; - struct list_head list; /* list of all net_info structure */ -}; -typedef s32(*ISCAN_HANDLER) (struct wl_priv *wl); - -/* iscan controller */ -struct wl_iscan_ctrl { - struct net_device *dev; - struct timer_list timer; - u32 timer_ms; - u32 timer_on; - s32 state; - struct task_struct *tsk; - struct semaphore sync; - ISCAN_HANDLER iscan_handler[WL_SCAN_ERSULTS_LAST]; - void *data; - s8 ioctl_buf[WLC_IOCTL_SMLEN]; - s8 scan_buf[WL_ISCAN_BUF_MAX]; -}; - -/* association inform */ -#define MAX_REQ_LINE 1024 -struct wl_connect_info { - u8 req_ie[MAX_REQ_LINE]; - s32 req_ie_len; - u8 resp_ie[MAX_REQ_LINE]; - s32 resp_ie_len; -}; - -/* firmware /nvram downloading controller */ -struct wl_fw_ctrl { - const struct firmware *fw_entry; - unsigned long status; - u32 ptr; - s8 fw_name[WL_FILE_NAME_MAX]; - s8 nvram_name[WL_FILE_NAME_MAX]; -}; - -/* assoc ie length */ -struct wl_assoc_ielen { - u32 req_len; - u32 resp_len; -}; - -/* wpa2 pmk list */ -struct wl_pmk_list { - pmkid_list_t pmkids; - pmkid_t foo[MAXPMKID - 1]; -}; - - -#define ESCAN_BUF_SIZE (64 * 1024) - -struct escan_info { - u32 escan_state; - u8 escan_buf[ESCAN_BUF_SIZE]; - struct wiphy *wiphy; - struct net_device *ndev; -}; - -struct ap_info { -/* Structure to hold WPS, WPA IEs for a AP */ - u8 probe_res_ie[IE_MAX_LEN]; - u8 beacon_ie[IE_MAX_LEN]; - u32 probe_res_ie_len; - u32 beacon_ie_len; - u8 *wpa_ie; - u8 *rsn_ie; - u8 *wps_ie; - bool security_mode; -}; -struct btcoex_info { - struct timer_list timer; - u32 timer_ms; - u32 timer_on; - u32 ts_dhcp_start; /* ms ts ecord time stats */ - u32 ts_dhcp_ok; /* ms ts ecord time stats */ - bool dhcp_done; /* flag, indicates that host done with - * dhcp before t1/t2 expiration - */ - s32 bt_state; - struct work_struct work; - struct net_device *dev; -}; - -struct sta_info { - /* Structure to hold WPS IE for a STA */ - u8 probe_req_ie[IE_MAX_LEN]; - u8 assoc_req_ie[IE_MAX_LEN]; - u32 probe_req_ie_len; - u32 assoc_req_ie_len; -}; - -struct afx_hdl { - wl_af_params_t *pending_tx_act_frm; - struct ether_addr pending_tx_dst_addr; - struct net_device *dev; - struct work_struct work; - u32 bssidx; - u32 retry; - s32 peer_chan; - bool ack_recv; -}; - -/* private data of cfg80211 interface */ -typedef struct wl_priv { - struct wireless_dev *wdev; /* representing wl cfg80211 device */ - - struct wireless_dev *p2p_wdev; /* representing wl cfg80211 device for P2P */ - struct net_device *p2p_net; /* reference to p2p0 interface */ - - struct wl_conf *conf; - struct cfg80211_scan_request *scan_request; /* scan request object */ - EVENT_HANDLER evt_handler[WLC_E_LAST]; - struct list_head eq_list; /* used for event queue */ - struct list_head net_list; /* used for struct net_info */ - spinlock_t eq_lock; /* for event queue synchronization */ - spinlock_t cfgdrv_lock; /* to protect scan status (and others if needed) */ - struct completion act_frm_scan; - struct mutex usr_sync; /* maily for up/down synchronization */ - struct wl_scan_results *bss_list; - struct wl_scan_results *scan_results; - - /* scan request object for internal purpose */ - struct wl_scan_req *scan_req_int; - /* information element object for internal purpose */ - struct wl_ie ie; - struct wl_iscan_ctrl *iscan; /* iscan controller */ - - /* association information container */ - struct wl_connect_info conn_info; - - struct wl_pmk_list *pmk_list; /* wpa2 pmk list */ - tsk_ctl_t event_tsk; /* task of main event handler thread */ - void *pub; - u32 iface_cnt; - u32 channel; /* current channel */ - bool iscan_on; /* iscan on/off switch */ - bool iscan_kickstart; /* indicate iscan already started */ - bool escan_on; /* escan on/off switch */ - struct escan_info escan_info; /* escan information */ - bool active_scan; /* current scan mode */ - bool ibss_starter; /* indicates this sta is ibss starter */ - bool link_up; /* link/connection up flag */ - - /* indicate whether chip to support power save mode */ - bool pwr_save; - bool roam_on; /* on/off switch for self-roaming */ - bool scan_tried; /* indicates if first scan attempted */ - u8 *ioctl_buf; /* ioctl buffer */ - struct mutex ioctl_buf_sync; - u8 *escan_ioctl_buf; - u8 *extra_buf; /* maily to grab assoc information */ - struct dentry *debugfsdir; - struct rfkill *rfkill; - bool rf_blocked; - struct ieee80211_channel remain_on_chan; - enum nl80211_channel_type remain_on_chan_type; - u64 send_action_id; - u64 last_roc_id; - wait_queue_head_t netif_change_event; - struct afx_hdl *afx_hdl; - struct ap_info *ap_info; - struct sta_info *sta_info; - struct p2p_info *p2p; - bool p2p_supported; - struct btcoex_info *btcoex_info; - struct timer_list scan_timeout; /* Timer for catch scan event timeout */ -#ifdef WL_SCHED_SCAN - struct cfg80211_sched_scan_request *sched_scan_req; /* scheduled scan req */ -#endif /* WL_SCHED_SCAN */ - bool sched_scan_running; /* scheduled scan req status */ - u16 hostapd_chan; /* remember chan requested by framework for hostapd */ - u16 deauth_reason; /* Place holder to save deauth/disassoc reasons */ - u16 scan_busy_count; - struct work_struct work_scan_timeout; -} wl_priv_t; - - -static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, struct wl_bss_info *bss) -{ - return bss = bss ? - (struct wl_bss_info *)((uintptr) bss + dtoh32(bss->length)) : list->bss_info; -} - -static inline s32 -wl_alloc_netinfo(struct wl_priv *wl, struct net_device *ndev, - struct wireless_dev * wdev, s32 mode) -{ - struct net_info *_net_info; - s32 err = 0; - if (wl->iface_cnt == IFACE_MAX_CNT) - return -ENOMEM; - _net_info = kzalloc(sizeof(struct net_info), GFP_KERNEL); - if (!_net_info) - err = -ENOMEM; - else { - _net_info->mode = mode; - _net_info->ndev = ndev; - _net_info->wdev = wdev; - wl->iface_cnt++; - list_add(&_net_info->list, &wl->net_list); - } - return err; -} - -static inline void -wl_dealloc_netinfo(struct wl_priv *wl, struct net_device *ndev) -{ - struct net_info *_net_info, *next; - - list_for_each_entry_safe(_net_info, next, &wl->net_list, list) { - if (ndev && (_net_info->ndev == ndev)) { - list_del(&_net_info->list); - wl->iface_cnt--; - if (_net_info->wdev) { - kfree(_net_info->wdev); - ndev->ieee80211_ptr = NULL; - } - kfree(_net_info); - } - } -} - -static inline void -wl_delete_all_netinfo(struct wl_priv *wl) -{ - struct net_info *_net_info, *next; - - list_for_each_entry_safe(_net_info, next, &wl->net_list, list) { - list_del(&_net_info->list); - if (_net_info->wdev) - kfree(_net_info->wdev); - kfree(_net_info); - } - wl->iface_cnt = 0; -} - -static inline bool -wl_get_status_all(struct wl_priv *wl, s32 status) - -{ - struct net_info *_net_info, *next; - u32 cnt = 0; - list_for_each_entry_safe(_net_info, next, &wl->net_list, list) { - if (_net_info->ndev && - test_bit(status, &_net_info->sme_state)) - cnt++; - } - return cnt? true: false; -} - -static inline void -wl_set_status_by_netdev(struct wl_priv *wl, s32 status, - struct net_device *ndev, u32 op) -{ - - struct net_info *_net_info, *next; - - list_for_each_entry_safe(_net_info, next, &wl->net_list, list) { - if (ndev && (_net_info->ndev == ndev)) { - switch (op) { - case 1: - set_bit(status, &_net_info->sme_state); - break; - case 2: - clear_bit(status, &_net_info->sme_state); - break; - case 4: - change_bit(status, &_net_info->sme_state); - break; - } - } - - } -} - -static inline u32 -wl_get_status_by_netdev(struct wl_priv *wl, s32 status, - struct net_device *ndev) -{ - struct net_info *_net_info, *next; - - list_for_each_entry_safe(_net_info, next, &wl->net_list, list) { - if (ndev && (_net_info->ndev == ndev)) - return test_bit(status, &_net_info->sme_state); - } - return 0; -} - -static inline s32 -wl_get_mode_by_netdev(struct wl_priv *wl, struct net_device *ndev) -{ - struct net_info *_net_info, *next; - - list_for_each_entry_safe(_net_info, next, &wl->net_list, list) { - if (ndev && (_net_info->ndev == ndev)) - return _net_info->mode; - } - return -1; -} - -static inline void -wl_set_mode_by_netdev(struct wl_priv *wl, struct net_device *ndev, - s32 mode) -{ - struct net_info *_net_info, *next; - - list_for_each_entry_safe(_net_info, next, &wl->net_list, list) { - if (ndev && (_net_info->ndev == ndev)) - _net_info->mode = mode; - } -} - -static inline struct wl_profile * -wl_get_profile_by_netdev(struct wl_priv *wl, struct net_device *ndev) -{ - struct net_info *_net_info, *next; - - list_for_each_entry_safe(_net_info, next, &wl->net_list, list) { - if (ndev && (_net_info->ndev == ndev)) - return &_net_info->profile; - } - return NULL; -} -#define wl_to_wiphy(w) (w->wdev->wiphy) -#define wl_to_prmry_ndev(w) (w->wdev->netdev) -#define ndev_to_wl(n) (wdev_to_wl(n->ieee80211_ptr)) -#define wl_to_sr(w) (w->scan_req_int) -#define wl_to_ie(w) (&w->ie) -#define iscan_to_wl(i) ((struct wl_priv *)(i->data)) -#define wl_to_iscan(w) (w->iscan) -#define wl_to_conn(w) (&w->conn_info) -#define wiphy_from_scan(w) (w->escan_info.wiphy) -#define wl_get_drv_status_all(wl, stat) \ - (wl_get_status_all(wl, WL_STATUS_ ## stat)) -#define wl_get_drv_status(wl, stat, ndev) \ - (wl_get_status_by_netdev(wl, WL_STATUS_ ## stat, ndev)) -#define wl_set_drv_status(wl, stat, ndev) \ - (wl_set_status_by_netdev(wl, WL_STATUS_ ## stat, ndev, 1)) -#define wl_clr_drv_status(wl, stat, ndev) \ - (wl_set_status_by_netdev(wl, WL_STATUS_ ## stat, ndev, 2)) -#define wl_chg_drv_status(wl, stat, ndev) \ - (wl_set_status_by_netdev(wl, WL_STATUS_ ## stat, ndev, 4)) - -#define for_each_bss(list, bss, __i) \ - for (__i = 0; __i < list->count && __i < WL_AP_MAX; __i++, bss = next_bss(list, bss)) - -#define for_each_ndev(wl, iter, next) \ - list_for_each_entry_safe(iter, next, &wl->net_list, list) - - -/* In case of WPS from wpa_supplicant, pairwise siute and group suite is 0. - * In addtion to that, wpa_version is WPA_VERSION_1 - */ -#define is_wps_conn(_sme) \ - ((wl_cfgp2p_find_wpsie((u8 *)_sme->ie, _sme->ie_len) != NULL) && \ - (!_sme->crypto.n_ciphers_pairwise) && \ - (!_sme->crypto.cipher_group)) -extern s32 wl_cfg80211_attach(struct net_device *ndev, void *data); -extern s32 wl_cfg80211_attach_post(struct net_device *ndev); -extern void wl_cfg80211_detach(void *para); - -extern void wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t *e, - void *data); -void wl_cfg80211_set_parent_dev(void *dev); -struct device *wl_cfg80211_get_parent_dev(void); - -extern s32 wl_cfg80211_up(void *para); -extern s32 wl_cfg80211_down(void *para); -extern s32 wl_cfg80211_notify_ifadd(struct net_device *ndev, s32 idx, s32 bssidx, - void* _net_attach); -extern s32 wl_cfg80211_ifdel_ops(struct net_device *net); -extern s32 wl_cfg80211_notify_ifdel(void); -extern s32 wl_cfg80211_is_progress_ifadd(void); -extern s32 wl_cfg80211_is_progress_ifchange(void); -extern s32 wl_cfg80211_is_progress_ifadd(void); -extern s32 wl_cfg80211_notify_ifchange(void); -extern void wl_cfg80211_dbg_level(u32 level); -extern s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr); -extern s32 wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len); -extern s32 wl_cfg80211_get_p2p_noa(struct net_device *net, char* buf, int len); -extern s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len, - enum wl_management_type type); -extern s32 wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len); -extern int wl_cfg80211_hang(struct net_device *dev, u16 reason); -extern s32 wl_mode_to_nl80211_iftype(s32 mode); -int wl_cfg80211_do_driver_init(struct net_device *net); -void wl_cfg80211_enable_trace(int level); -extern s32 wl_update_wiphybands(struct wl_priv *wl); -extern s32 wl_cfg80211_if_is_group_owner(void); -extern int wl_cfg80211_update_power_mode(struct net_device *dev); -extern s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add); -#endif /* _wl_cfg80211_h_ */ diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c deleted file mode 100644 index 38c81cf94f42..000000000000 --- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c +++ /dev/null @@ -1,2033 +0,0 @@ -/* - * Linux cfgp2p driver - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wl_cfgp2p.c,v 1.1.4.1.2.14 2011-02-09 01:40:07 $ - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -static s8 scanparambuf[WLC_IOCTL_SMLEN]; - -static bool -wl_cfgp2p_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len, const u8 *oui, u32 oui_len, u8 type); - -static s32 -wl_cfgp2p_vndr_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, s32 pktflag, - s8 *oui, s32 ie_id, s8 *data, s32 data_len, s32 delete); - -static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev); -static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd); -static int wl_cfgp2p_if_open(struct net_device *net); -static int wl_cfgp2p_if_stop(struct net_device *net); -static s32 wl_cfgp2p_cancel_listen(struct wl_priv *wl, struct net_device *ndev, - bool notify); - -static const struct net_device_ops wl_cfgp2p_if_ops = { - .ndo_open = wl_cfgp2p_if_open, - .ndo_stop = wl_cfgp2p_if_stop, - .ndo_do_ioctl = wl_cfgp2p_do_ioctl, - .ndo_start_xmit = wl_cfgp2p_start_xmit, -}; - -bool wl_cfgp2p_is_pub_action(void *frame, u32 frame_len) -{ - wifi_p2p_pub_act_frame_t *pact_frm; - - if (frame == NULL) - return false; - pact_frm = (wifi_p2p_pub_act_frame_t *)frame; - if (frame_len < sizeof(wifi_p2p_pub_act_frame_t) -1) - return false; - - if (pact_frm->category == P2P_PUB_AF_CATEGORY && - pact_frm->action == P2P_PUB_AF_ACTION && - pact_frm->oui_type == P2P_VER && - memcmp(pact_frm->oui, P2P_OUI, sizeof(pact_frm->oui)) == 0) { - return true; - } - - return false; -} - -bool wl_cfgp2p_is_p2p_action(void *frame, u32 frame_len) -{ - wifi_p2p_action_frame_t *act_frm; - - if (frame == NULL) - return false; - act_frm = (wifi_p2p_action_frame_t *)frame; - if (frame_len < sizeof(wifi_p2p_action_frame_t) -1) - return false; - - if (act_frm->category == P2P_AF_CATEGORY && - act_frm->type == P2P_VER && - memcmp(act_frm->OUI, P2P_OUI, DOT11_OUI_LEN) == 0) { - return true; - } - - return false; -} - -bool wl_cfgp2p_is_gas_action(void *frame, u32 frame_len) -{ - - wifi_p2psd_gas_pub_act_frame_t *sd_act_frm; - - if (frame == NULL) - return false; - - sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)frame; - if (frame_len < sizeof(wifi_p2psd_gas_pub_act_frame_t) - 1) - return false; - if (sd_act_frm->category != P2PSD_ACTION_CATEGORY) - return false; - - if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_IREQ || - sd_act_frm->action == P2PSD_ACTION_ID_GAS_IRESP || - sd_act_frm->action == P2PSD_ACTION_ID_GAS_CREQ || - sd_act_frm->action == P2PSD_ACTION_ID_GAS_CRESP) - return true; - else - return false; - -} - -void wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len) -{ - wifi_p2p_pub_act_frame_t *pact_frm; - wifi_p2p_action_frame_t *act_frm; - wifi_p2psd_gas_pub_act_frame_t *sd_act_frm; - if (!frame || frame_len <= 2) - return; - - if (wl_cfgp2p_is_pub_action(frame, frame_len)) { - pact_frm = (wifi_p2p_pub_act_frame_t *)frame; - switch (pact_frm->subtype) { - case P2P_PAF_GON_REQ: - CFGP2P_DBG(("%s P2P Group Owner Negotiation Req Frame\n", - (tx)? "TX": "RX")); - break; - case P2P_PAF_GON_RSP: - CFGP2P_DBG(("%s P2P Group Owner Negotiation Rsp Frame\n", - (tx)? "TX": "RX")); - break; - case P2P_PAF_GON_CONF: - CFGP2P_DBG(("%s P2P Group Owner Negotiation Confirm Frame\n", - (tx)? "TX": "RX")); - break; - case P2P_PAF_INVITE_REQ: - CFGP2P_DBG(("%s P2P Invitation Request Frame\n", - (tx)? "TX": "RX")); - break; - case P2P_PAF_INVITE_RSP: - CFGP2P_DBG(("%s P2P Invitation Response Frame\n", - (tx)? "TX": "RX")); - break; - case P2P_PAF_DEVDIS_REQ: - CFGP2P_DBG(("%s P2P Device Discoverability Request Frame\n", - (tx)? "TX": "RX")); - break; - case P2P_PAF_DEVDIS_RSP: - CFGP2P_DBG(("%s P2P Device Discoverability Response Frame\n", - (tx)? "TX": "RX")); - break; - case P2P_PAF_PROVDIS_REQ: - CFGP2P_DBG(("%s P2P Provision Discovery Request Frame\n", - (tx)? "TX": "RX")); - break; - case P2P_PAF_PROVDIS_RSP: - CFGP2P_DBG(("%s P2P Provision Discovery Response Frame\n", - (tx)? "TX": "RX")); - break; - default: - CFGP2P_DBG(("%s Unknown P2P Public Action Frame\n", - (tx)? "TX": "RX")); - - } - - } else if (wl_cfgp2p_is_p2p_action(frame, frame_len)) { - act_frm = (wifi_p2p_action_frame_t *)frame; - switch (act_frm->subtype) { - case P2P_AF_NOTICE_OF_ABSENCE: - CFGP2P_DBG(("%s P2P Notice of Absence Frame\n", - (tx)? "TX": "RX")); - break; - case P2P_AF_PRESENCE_REQ: - CFGP2P_DBG(("%s P2P Presence Request Frame\n", - (tx)? "TX": "RX")); - break; - case P2P_AF_PRESENCE_RSP: - CFGP2P_DBG(("%s P2P Presence Response Frame\n", - (tx)? "TX": "RX")); - break; - case P2P_AF_GO_DISC_REQ: - CFGP2P_DBG(("%s P2P Discoverability Request Frame\n", - (tx)? "TX": "RX")); - break; - default: - CFGP2P_DBG(("%s Unknown P2P Action Frame\n", - (tx)? "TX": "RX")); - } - - } else if (wl_cfgp2p_is_gas_action(frame, frame_len)) { - sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)frame; - switch (sd_act_frm->action) { - case P2PSD_ACTION_ID_GAS_IREQ: - CFGP2P_DBG(("%s P2P GAS Initial Request\n", - (tx)? "TX" : "RX")); - break; - case P2PSD_ACTION_ID_GAS_IRESP: - CFGP2P_DBG(("%s P2P GAS Initial Response\n", - (tx)? "TX" : "RX")); - break; - case P2PSD_ACTION_ID_GAS_CREQ: - CFGP2P_DBG(("%s P2P GAS Comback Request\n", - (tx)? "TX" : "RX")); - break; - case P2PSD_ACTION_ID_GAS_CRESP: - CFGP2P_DBG(("%s P2P GAS Comback Response\n", - (tx)? "TX" : "RX")); - break; - default: - CFGP2P_DBG(("%s Unknown P2P GAS Frame\n", - (tx)? "TX" : "RX")); - } - } -} - -/* - * Initialize variables related to P2P - * - */ -s32 -wl_cfgp2p_init_priv(struct wl_priv *wl) -{ - if (!(wl->p2p = kzalloc(sizeof(struct p2p_info), GFP_KERNEL))) { - CFGP2P_ERR(("struct p2p_info allocation failed\n")); - return -ENOMEM; - } -#define INIT_IE(IE_TYPE, BSS_TYPE) \ - do { \ - memset(wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie, 0, \ - sizeof(wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie)); \ - wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie_len = 0; \ - } while (0); - - INIT_IE(probe_req, P2PAPI_BSSCFG_PRIMARY); - INIT_IE(probe_res, P2PAPI_BSSCFG_PRIMARY); - INIT_IE(assoc_req, P2PAPI_BSSCFG_PRIMARY); - INIT_IE(assoc_res, P2PAPI_BSSCFG_PRIMARY); - INIT_IE(beacon, P2PAPI_BSSCFG_PRIMARY); - INIT_IE(probe_req, P2PAPI_BSSCFG_DEVICE); - INIT_IE(probe_res, P2PAPI_BSSCFG_DEVICE); - INIT_IE(assoc_req, P2PAPI_BSSCFG_DEVICE); - INIT_IE(assoc_res, P2PAPI_BSSCFG_DEVICE); - INIT_IE(beacon, P2PAPI_BSSCFG_DEVICE); - INIT_IE(probe_req, P2PAPI_BSSCFG_CONNECTION); - INIT_IE(probe_res, P2PAPI_BSSCFG_CONNECTION); - INIT_IE(assoc_req, P2PAPI_BSSCFG_CONNECTION); - INIT_IE(assoc_res, P2PAPI_BSSCFG_CONNECTION); - INIT_IE(beacon, P2PAPI_BSSCFG_CONNECTION); -#undef INIT_IE - wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY) = wl_to_prmry_ndev(wl); - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_PRIMARY) = 0; - wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE) = NULL; - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = 0; - wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = NULL; - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) = 0; - return BCME_OK; - -} -/* - * Deinitialize variables related to P2P - * - */ -void -wl_cfgp2p_deinit_priv(struct wl_priv *wl) -{ - CFGP2P_DBG(("In\n")); - - if (wl->p2p) { - kfree(wl->p2p); - wl->p2p = NULL; - } - wl->p2p_supported = 0; -} -/* - * Set P2P functions into firmware - */ -s32 -wl_cfgp2p_set_firm_p2p(struct wl_priv *wl) -{ - struct net_device *ndev = wl_to_prmry_ndev(wl); - struct ether_addr null_eth_addr = { { 0, 0, 0, 0, 0, 0 } }; - s32 ret = BCME_OK; - s32 val = 0; - /* Do we have to check whether APSTA is enabled or not ? */ - wldev_iovar_getint(ndev, "apsta", &val); - if (val == 0) { - val = 1; - wldev_ioctl(ndev, WLC_DOWN, &val, sizeof(s32), true); - wldev_iovar_setint(ndev, "apsta", val); - wldev_ioctl(ndev, WLC_UP, &val, sizeof(s32), true); - } - val = 1; - /* Disable firmware roaming for P2P */ - wldev_iovar_setint(ndev, "roam_off", val); - /* In case of COB type, firmware has default mac address - * After Initializing firmware, we have to set current mac address to - * firmware for P2P device address - */ - ret = wldev_iovar_setbuf_bsscfg(ndev, "p2p_da_override", &null_eth_addr, - sizeof(null_eth_addr), wl->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &wl->ioctl_buf_sync); - if (ret && ret != BCME_UNSUPPORTED) { - CFGP2P_ERR(("failed to update device address ret %d\n", ret)); - } - return ret; -} - -/* Create a new P2P BSS. - * Parameters: - * @mac : MAC address of the BSS to create - * @if_type : interface type: WL_P2P_IF_GO or WL_P2P_IF_CLIENT - * @chspec : chspec to use if creating a GO BSS. - * Returns 0 if success. - */ -s32 -wl_cfgp2p_ifadd(struct wl_priv *wl, struct ether_addr *mac, u8 if_type, - chanspec_t chspec) -{ - wl_p2p_if_t ifreq; - s32 err; - struct net_device *ndev = wl_to_prmry_ndev(wl); - u32 scb_timeout = WL_SCB_TIMEOUT; - - ifreq.type = if_type; - ifreq.chspec = chspec; - memcpy(ifreq.addr.octet, mac->octet, sizeof(ifreq.addr.octet)); - - CFGP2P_DBG(("---wl p2p_ifadd %02x:%02x:%02x:%02x:%02x:%02x %s %u\n", - ifreq.addr.octet[0], ifreq.addr.octet[1], ifreq.addr.octet[2], - ifreq.addr.octet[3], ifreq.addr.octet[4], ifreq.addr.octet[5], - (if_type == WL_P2P_IF_GO) ? "go" : "client", - (chspec & WL_CHANSPEC_CHAN_MASK) >> WL_CHANSPEC_CHAN_SHIFT)); - - err = wldev_iovar_setbuf(ndev, "p2p_ifadd", &ifreq, sizeof(ifreq), - wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); - - if (unlikely(err < 0)) { - printk("'wl p2p_ifadd' error %d\n", err); - } else if (if_type == WL_P2P_IF_GO) { - err = wldev_ioctl(ndev, WLC_SET_SCB_TIMEOUT, &scb_timeout, sizeof(u32), true); - if (unlikely(err < 0)) - printk("'wl scb_timeout' error %d\n", err); - } - - return err; -} - -/* Delete a P2P BSS. - * Parameters: - * @mac : MAC address of the BSS to create - * Returns 0 if success. - */ -s32 -wl_cfgp2p_ifdel(struct wl_priv *wl, struct ether_addr *mac) -{ - s32 ret; - struct net_device *netdev = wl_to_prmry_ndev(wl); - - CFGP2P_INFO(("------primary idx %d : wl p2p_ifdel %02x:%02x:%02x:%02x:%02x:%02x\n", - netdev->ifindex, mac->octet[0], mac->octet[1], mac->octet[2], - mac->octet[3], mac->octet[4], mac->octet[5])); - ret = wldev_iovar_setbuf(netdev, "p2p_ifdel", mac, sizeof(*mac), - wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); - if (unlikely(ret < 0)) { - printk("'wl p2p_ifdel' error %d\n", ret); - } - return ret; -} - -/* Change a P2P Role. - * Parameters: - * @mac : MAC address of the BSS to change a role - * Returns 0 if success. - */ -s32 -wl_cfgp2p_ifchange(struct wl_priv *wl, struct ether_addr *mac, u8 if_type, - chanspec_t chspec) -{ - wl_p2p_if_t ifreq; - s32 err; - u32 scb_timeout = WL_SCB_TIMEOUT; - struct net_device *netdev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION); - - ifreq.type = if_type; - ifreq.chspec = chspec; - memcpy(ifreq.addr.octet, mac->octet, sizeof(ifreq.addr.octet)); - - CFGP2P_INFO(("---wl p2p_ifchange %02x:%02x:%02x:%02x:%02x:%02x %s %u\n", - ifreq.addr.octet[0], ifreq.addr.octet[1], ifreq.addr.octet[2], - ifreq.addr.octet[3], ifreq.addr.octet[4], ifreq.addr.octet[5], - (if_type == WL_P2P_IF_GO) ? "go" : "client", - (chspec & WL_CHANSPEC_CHAN_MASK) >> WL_CHANSPEC_CHAN_SHIFT)); - - err = wldev_iovar_setbuf(netdev, "p2p_ifupd", &ifreq, sizeof(ifreq), - wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); - - if (unlikely(err < 0)) { - printk("'wl p2p_ifupd' error %d\n", err); - } else if (if_type == WL_P2P_IF_GO) { - err = wldev_ioctl(netdev, WLC_SET_SCB_TIMEOUT, &scb_timeout, sizeof(u32), true); - if (unlikely(err < 0)) - printk("'wl scb_timeout' error %d\n", err); - } - return err; -} - - -/* Get the index of a created P2P BSS. - * Parameters: - * @mac : MAC address of the created BSS - * @index : output: index of created BSS - * Returns 0 if success. - */ -s32 -wl_cfgp2p_ifidx(struct wl_priv *wl, struct ether_addr *mac, s32 *index) -{ - s32 ret; - u8 getbuf[64]; - struct net_device *dev = wl_to_prmry_ndev(wl); - - CFGP2P_INFO(("---wl p2p_if %02x:%02x:%02x:%02x:%02x:%02x\n", - mac->octet[0], mac->octet[1], mac->octet[2], - mac->octet[3], mac->octet[4], mac->octet[5])); - - ret = wldev_iovar_getbuf_bsscfg(dev, "p2p_if", mac, sizeof(*mac), getbuf, - sizeof(getbuf), wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_PRIMARY), NULL); - - if (ret == 0) { - memcpy(index, getbuf, sizeof(index)); - CFGP2P_INFO(("---wl p2p_if ==> %d\n", *index)); - } - - return ret; -} - -static s32 -wl_cfgp2p_set_discovery(struct wl_priv *wl, s32 on) -{ - s32 ret = BCME_OK; - struct net_device *ndev = wl_to_prmry_ndev(wl); - CFGP2P_DBG(("enter\n")); - - ret = wldev_iovar_setint(ndev, "p2p_disc", on); - - if (unlikely(ret < 0)) { - CFGP2P_ERR(("p2p_disc %d error %d\n", on, ret)); - } - - return ret; -} - -/* Set the WL driver's P2P mode. - * Parameters : - * @mode : is one of WL_P2P_DISC_ST_{SCAN,LISTEN,SEARCH}. - * @channel : the channel to listen - * @listen_ms : the time (milli seconds) to wait - * @bssidx : bss index for BSSCFG - * Returns 0 if success - */ - -s32 -wl_cfgp2p_set_p2p_mode(struct wl_priv *wl, u8 mode, u32 channel, u16 listen_ms, int bssidx) -{ - wl_p2p_disc_st_t discovery_mode; - s32 ret; - struct net_device *dev; - CFGP2P_DBG(("enter\n")); - - if (unlikely(bssidx >= P2PAPI_BSSCFG_MAX)) { - CFGP2P_ERR((" %d index out of range\n", bssidx)); - return -1; - } - - dev = wl_to_p2p_bss_ndev(wl, bssidx); - if (unlikely(dev == NULL)) { - CFGP2P_ERR(("bssidx %d is not assigned\n", bssidx)); - return BCME_NOTFOUND; - } - - /* Put the WL driver into P2P Listen Mode to respond to P2P probe reqs */ - discovery_mode.state = mode; - discovery_mode.chspec = CH20MHZ_CHSPEC(channel); - discovery_mode.dwell = listen_ms; - ret = wldev_iovar_setbuf_bsscfg(dev, "p2p_state", &discovery_mode, - sizeof(discovery_mode), wl->ioctl_buf, WLC_IOCTL_MAXLEN, - bssidx, &wl->ioctl_buf_sync); - - return ret; -} - -/* Get the index of the P2P Discovery BSS */ -static s32 -wl_cfgp2p_get_disc_idx(struct wl_priv *wl, s32 *index) -{ - s32 ret; - struct net_device *dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY); - - ret = wldev_iovar_getint(dev, "p2p_dev", index); - CFGP2P_INFO(("p2p_dev bsscfg_idx=%d ret=%d\n", *index, ret)); - - if (unlikely(ret < 0)) { - CFGP2P_ERR(("'p2p_dev' error %d\n", ret)); - return ret; - } - return ret; -} - -s32 -wl_cfgp2p_init_discovery(struct wl_priv *wl) -{ - - s32 index = 0; - s32 ret = BCME_OK; - - CFGP2P_DBG(("enter\n")); - - if (wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) != 0) { - CFGP2P_ERR(("do nothing, already initialized\n")); - return ret; - } - - ret = wl_cfgp2p_set_discovery(wl, 1); - if (ret < 0) { - CFGP2P_ERR(("set discover error\n")); - return ret; - } - /* Enable P2P Discovery in the WL Driver */ - ret = wl_cfgp2p_get_disc_idx(wl, &index); - - if (ret < 0) { - return ret; - } - wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE) = - wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY); - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = index; - - /* Set the initial discovery state to SCAN */ - ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0, - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); - - if (unlikely(ret != 0)) { - CFGP2P_ERR(("unable to set WL_P2P_DISC_ST_SCAN\n")); - wl_cfgp2p_set_discovery(wl, 0); - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = 0; - wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE) = NULL; - return 0; - } - return ret; -} - -/* Deinitialize P2P Discovery - * Parameters : - * @wl : wl_private data - * Returns 0 if succes - */ -static s32 -wl_cfgp2p_deinit_discovery(struct wl_priv *wl) -{ - s32 ret = BCME_OK; - CFGP2P_DBG(("enter\n")); - - if (wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) == 0) { - CFGP2P_ERR(("do nothing, not initialized\n")); - return -1; - } - /* Set the discovery state to SCAN */ - ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0, - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); - /* Disable P2P discovery in the WL driver (deletes the discovery BSSCFG) */ - ret = wl_cfgp2p_set_discovery(wl, 0); - - /* Clear our saved WPS and P2P IEs for the discovery BSS. The driver - * deleted these IEs when wl_cfgp2p_set_discovery() deleted the discovery - * BSS. - */ - - /* Clear the saved bsscfg index of the discovery BSSCFG to indicate we - * have no discovery BSS. - */ - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = 0; - wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE) = NULL; - - return ret; - -} -/* Enable P2P Discovery - * Parameters: - * @wl : wl_private data - * @ie : probe request ie (WPS IE + P2P IE) - * @ie_len : probe request ie length - * Returns 0 if success. - */ -s32 -wl_cfgp2p_enable_discovery(struct wl_priv *wl, struct net_device *dev, - const u8 *ie, u32 ie_len) -{ - s32 ret = BCME_OK; - if (wl_get_p2p_status(wl, DISCOVERY_ON)) { - CFGP2P_INFO((" DISCOVERY is already initialized, we have nothing to do\n")); - goto set_ie; - } - - wl_set_p2p_status(wl, DISCOVERY_ON); - - CFGP2P_DBG(("enter\n")); - - ret = wl_cfgp2p_init_discovery(wl); - if (unlikely(ret < 0)) { - CFGP2P_ERR((" init discovery error %d\n", ret)); - goto exit; - } - /* Set wsec to any non-zero value in the discovery bsscfg to ensure our - * P2P probe responses have the privacy bit set in the 802.11 WPA IE. - * Some peer devices may not initiate WPS with us if this bit is not set. - */ - ret = wldev_iovar_setint_bsscfg(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE), - "wsec", AES_ENABLED, wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); - if (unlikely(ret < 0)) { - CFGP2P_ERR((" wsec error %d\n", ret)); - } -set_ie: - ret = wl_cfgp2p_set_management_ie(wl, dev, - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE), - VNDR_IE_PRBREQ_FLAG, ie, ie_len); - - if (unlikely(ret < 0)) { - CFGP2P_ERR(("set probreq ie occurs error %d\n", ret)); - goto exit; - } -exit: - return ret; -} - -/* Disable P2P Discovery - * Parameters: - * @wl : wl_private_data - * Returns 0 if success. - */ -s32 -wl_cfgp2p_disable_discovery(struct wl_priv *wl) -{ - s32 ret = BCME_OK; - CFGP2P_DBG((" enter\n")); - wl_clr_p2p_status(wl, DISCOVERY_ON); - - if (wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) == 0) { - CFGP2P_ERR((" do nothing, not initialized\n")); - goto exit; - } - - ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0, - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); - - if (unlikely(ret < 0)) { - - CFGP2P_ERR(("unable to set WL_P2P_DISC_ST_SCAN\n")); - } - /* Do a scan abort to stop the driver's scan engine in case it is still - * waiting out an action frame tx dwell time. - */ -#ifdef NOT_YET - if (wl_get_p2p_status(wl, SCANNING)) { - p2pwlu_scan_abort(hdl, FALSE); - } -#endif - wl_clr_p2p_status(wl, DISCOVERY_ON); - ret = wl_cfgp2p_deinit_discovery(wl); - -exit: - return ret; -} - -s32 -wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active, - u32 num_chans, u16 *channels, - s32 search_state, u16 action, u32 bssidx) -{ - s32 ret = BCME_OK; - s32 memsize; - s32 eparams_size; - u32 i; - s8 *memblk; - wl_p2p_scan_t *p2p_params; - wl_escan_params_t *eparams; - wlc_ssid_t ssid; - /* Scan parameters */ -#define P2PAPI_SCAN_NPROBES 1 -#define P2PAPI_SCAN_DWELL_TIME_MS 50 -#define P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS 40 -#define P2PAPI_SCAN_HOME_TIME_MS 60 - struct net_device *pri_dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY); - wl_set_p2p_status(wl, SCANNING); - /* Allocate scan params which need space for 3 channels and 0 ssids */ - eparams_size = (WL_SCAN_PARAMS_FIXED_SIZE + - OFFSETOF(wl_escan_params_t, params)) + - num_chans * sizeof(eparams->params.channel_list[0]); - - memsize = sizeof(wl_p2p_scan_t) + eparams_size; - memblk = scanparambuf; - if (memsize > sizeof(scanparambuf)) { - CFGP2P_ERR((" scanpar buf too small (%u > %u)\n", - memsize, sizeof(scanparambuf))); - return -1; - } - memset(memblk, 0, memsize); - memset(wl->ioctl_buf, 0, WLC_IOCTL_MAXLEN); - if (search_state == WL_P2P_DISC_ST_SEARCH) { - /* - * If we in SEARCH STATE, we don't need to set SSID explictly - * because dongle use P2P WILDCARD internally by default - */ - wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SEARCH, 0, 0, bssidx); - ssid.SSID_len = htod32(0); - - } else if (search_state == WL_P2P_DISC_ST_SCAN) { - /* SCAN STATE 802.11 SCAN - * WFD Supplicant has p2p_find command with (type=progressive, type= full) - * So if P2P_find command with type=progressive, - * we have to set ssid to P2P WILDCARD because - * we just do broadcast scan unless setting SSID - */ - strcpy(ssid.SSID, WL_P2P_WILDCARD_SSID); - ssid.SSID_len = htod32(WL_P2P_WILDCARD_SSID_LEN); - wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0, bssidx); - } - - - /* Fill in the P2P scan structure at the start of the iovar param block */ - p2p_params = (wl_p2p_scan_t*) memblk; - p2p_params->type = 'E'; - /* Fill in the Scan structure that follows the P2P scan structure */ - eparams = (wl_escan_params_t*) (p2p_params + 1); - eparams->params.bss_type = DOT11_BSSTYPE_ANY; - if (active) - eparams->params.scan_type = DOT11_SCANTYPE_ACTIVE; - else - eparams->params.scan_type = DOT11_SCANTYPE_PASSIVE; - - memcpy(&eparams->params.bssid, ðer_bcast, ETHER_ADDR_LEN); - if (ssid.SSID_len) - memcpy(&eparams->params.ssid, &ssid, sizeof(wlc_ssid_t)); - - eparams->params.nprobes = htod32(P2PAPI_SCAN_NPROBES); - eparams->params.home_time = htod32(P2PAPI_SCAN_HOME_TIME_MS); - if (wl_get_drv_status_all(wl, CONNECTED)) - eparams->params.active_time = htod32(-1); - else if (num_chans == 3) - eparams->params.active_time = htod32(P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS); - else - eparams->params.active_time = htod32(P2PAPI_SCAN_DWELL_TIME_MS); - eparams->params.passive_time = htod32(-1); - eparams->params.channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) | - (num_chans & WL_SCAN_PARAMS_COUNT_MASK)); - - for (i = 0; i < num_chans; i++) { - eparams->params.channel_list[i] = htodchanspec(channels[i]); - } - eparams->version = htod32(ESCAN_REQ_VERSION); - eparams->action = htod16(action); - eparams->sync_id = htod16(0x1234); - CFGP2P_INFO(("SCAN CHANNELS : ")); - - for (i = 0; i < num_chans; i++) { - if (i == 0) CFGP2P_INFO(("%d", channels[i])); - else CFGP2P_INFO((",%d", channels[i])); - } - - CFGP2P_INFO(("\n")); - - ret = wldev_iovar_setbuf_bsscfg(pri_dev, "p2p_scan", - memblk, memsize, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); - return ret; -} - -/* search function to reach at common channel to send action frame - * Parameters: - * @wl : wl_private data - * @ndev : net device for bssidx - * @bssidx : bssidx for BSS - * Returns 0 if success. - */ -s32 -wl_cfgp2p_act_frm_search(struct wl_priv *wl, struct net_device *ndev, - s32 bssidx, s32 channel) -{ - s32 ret = 0; - u32 chan_cnt = 0; - u16 *default_chan_list = NULL; - if (!p2p_is_on(wl)) - return -BCME_ERROR; - CFGP2P_ERR((" Enter\n")); - if (bssidx == P2PAPI_BSSCFG_PRIMARY) - bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE); - if (channel) - chan_cnt = 1; - else - chan_cnt = SOCIAL_CHAN_CNT; - default_chan_list = kzalloc(chan_cnt * sizeof(*default_chan_list), GFP_KERNEL); - if (default_chan_list == NULL) { - CFGP2P_ERR(("channel list allocation failed \n")); - ret = -ENOMEM; - goto exit; - } - if (channel) { - default_chan_list[0] = channel; - } else { - default_chan_list[0] = SOCIAL_CHAN_1; - default_chan_list[1] = SOCIAL_CHAN_2; - default_chan_list[2] = SOCIAL_CHAN_3; - } - ret = wl_cfgp2p_escan(wl, ndev, true, SOCIAL_CHAN_CNT, - default_chan_list, WL_P2P_DISC_ST_SEARCH, - WL_SCAN_ACTION_START, bssidx); - kfree(default_chan_list); -exit: - return ret; -} - -/* Check whether pointed-to IE looks like WPA. */ -#define wl_cfgp2p_is_wpa_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \ - (const uint8 *)WPS_OUI, WPS_OUI_LEN, WPA_OUI_TYPE) -/* Check whether pointed-to IE looks like WPS. */ -#define wl_cfgp2p_is_wps_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \ - (const uint8 *)WPS_OUI, WPS_OUI_LEN, WPS_OUI_TYPE) -/* Check whether the given IE looks like WFA P2P IE. */ -#define wl_cfgp2p_is_p2p_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \ - (const uint8 *)WFA_OUI, WFA_OUI_LEN, WFA_OUI_TYPE_P2P) - /* Check whether the given IE looks like WFA WFDisplay IE. */ -#define WFA_OUI_TYPE_WFD 0x0a /* WiFi Display OUI TYPE */ -#define wl_cfgp2p_is_wfd_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \ - (const uint8 *)WFA_OUI, WFA_OUI_LEN, WFA_OUI_TYPE_WFD) - -/* Delete and Set a management vndr ie to firmware - * Parameters: - * @wl : wl_private data - * @ndev : net device for bssidx - * @bssidx : bssidx for BSS - * @pktflag : packet flag for IE (VNDR_IE_PRBREQ_FLAG,VNDR_IE_PRBRSP_FLAG, VNDR_IE_ASSOCRSP_FLAG, - * VNDR_IE_ASSOCREQ_FLAG) - * @ie : VNDR IE (such as P2P IE , WPS IE) - * @ie_len : VNDR IE Length - * Returns 0 if success. - */ - -s32 -wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, - s32 pktflag, const u8 *vndr_ie, u32 vndr_ie_len) -{ - /* Vendor-specific Information Element ID */ -#define VNDR_SPEC_ELEMENT_ID 0xdd - s32 ret = BCME_OK; - u32 pos; - u8 *ie_buf; - u8 *mgmt_ie_buf = NULL; - u32 mgmt_ie_buf_len = 0; - u32 *mgmt_ie_len = 0; - u8 ie_id, ie_len; - u8 delete = 0; -#define IE_TYPE(type, bsstype) (wl_to_p2p_bss_saved_ie(wl, bsstype).p2p_ ## type ## _ie) -#define IE_TYPE_LEN(type, bsstype) (wl_to_p2p_bss_saved_ie(wl, bsstype).p2p_ ## type ## _ie_len) - if (p2p_is_on(wl) && bssidx != -1) { - if (bssidx == P2PAPI_BSSCFG_PRIMARY) - bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE); - switch (pktflag) { - case VNDR_IE_PRBREQ_FLAG : - mgmt_ie_buf = IE_TYPE(probe_req, bssidx); - mgmt_ie_len = &IE_TYPE_LEN(probe_req, bssidx); - mgmt_ie_buf_len = sizeof(IE_TYPE(probe_req, bssidx)); - break; - case VNDR_IE_PRBRSP_FLAG : - mgmt_ie_buf = IE_TYPE(probe_res, bssidx); - mgmt_ie_len = &IE_TYPE_LEN(probe_res, bssidx); - mgmt_ie_buf_len = sizeof(IE_TYPE(probe_res, bssidx)); - break; - case VNDR_IE_ASSOCREQ_FLAG : - mgmt_ie_buf = IE_TYPE(assoc_req, bssidx); - mgmt_ie_len = &IE_TYPE_LEN(assoc_req, bssidx); - mgmt_ie_buf_len = sizeof(IE_TYPE(assoc_req, bssidx)); - break; - case VNDR_IE_ASSOCRSP_FLAG : - mgmt_ie_buf = IE_TYPE(assoc_res, bssidx); - mgmt_ie_len = &IE_TYPE_LEN(assoc_res, bssidx); - mgmt_ie_buf_len = sizeof(IE_TYPE(assoc_res, bssidx)); - break; - case VNDR_IE_BEACON_FLAG : - mgmt_ie_buf = IE_TYPE(beacon, bssidx); - mgmt_ie_len = &IE_TYPE_LEN(beacon, bssidx); - mgmt_ie_buf_len = sizeof(IE_TYPE(beacon, bssidx)); - break; - default: - mgmt_ie_buf = NULL; - mgmt_ie_len = NULL; - CFGP2P_ERR(("not suitable type\n")); - return -1; - } - } else if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) { - switch (pktflag) { - case VNDR_IE_PRBRSP_FLAG : - mgmt_ie_buf = wl->ap_info->probe_res_ie; - mgmt_ie_len = &wl->ap_info->probe_res_ie_len; - mgmt_ie_buf_len = sizeof(wl->ap_info->probe_res_ie); - break; - case VNDR_IE_BEACON_FLAG : - mgmt_ie_buf = wl->ap_info->beacon_ie; - mgmt_ie_len = &wl->ap_info->beacon_ie_len; - mgmt_ie_buf_len = sizeof(wl->ap_info->beacon_ie); - break; - default: - mgmt_ie_buf = NULL; - mgmt_ie_len = NULL; - CFGP2P_ERR(("not suitable type\n")); - return -1; - } - bssidx = 0; - } else if (bssidx == -1 && wl_get_mode_by_netdev(wl, ndev) == WL_MODE_BSS) { - switch (pktflag) { - case VNDR_IE_PRBREQ_FLAG : - mgmt_ie_buf = wl->sta_info->probe_req_ie; - mgmt_ie_len = &wl->sta_info->probe_req_ie_len; - mgmt_ie_buf_len = sizeof(wl->sta_info->probe_req_ie); - break; - case VNDR_IE_ASSOCREQ_FLAG : - mgmt_ie_buf = wl->sta_info->assoc_req_ie; - mgmt_ie_len = &wl->sta_info->assoc_req_ie_len; - mgmt_ie_buf_len = sizeof(wl->sta_info->assoc_req_ie); - break; - default: - mgmt_ie_buf = NULL; - mgmt_ie_len = NULL; - CFGP2P_ERR(("not suitable type\n")); - return -1; - } - bssidx = 0; - } else { - CFGP2P_ERR(("not suitable type\n")); - return -1; - } - - if (vndr_ie_len > mgmt_ie_buf_len) { - CFGP2P_ERR(("extra IE size too big\n")); - ret = -ENOMEM; - } else { - if (mgmt_ie_buf != NULL) { - if (vndr_ie_len && (vndr_ie_len == *mgmt_ie_len) && - (memcmp(mgmt_ie_buf, vndr_ie, vndr_ie_len) == 0)) { - CFGP2P_INFO(("Previous mgmt IE is equals to current IE")); - goto exit; - } - pos = 0; - delete = 1; - ie_buf = (u8 *) mgmt_ie_buf; - while (pos < *mgmt_ie_len) { - ie_id = ie_buf[pos++]; - ie_len = ie_buf[pos++]; - if ((ie_id == DOT11_MNG_VS_ID) && - (wl_cfgp2p_is_wps_ie(&ie_buf[pos-2], NULL, 0) || - wl_cfgp2p_is_p2p_ie(&ie_buf[pos-2], NULL, 0) || - wl_cfgp2p_is_wfd_ie(&ie_buf[pos-2], NULL, 0))) { - CFGP2P_INFO(("DELELED ID : %d, Len : %d , OUI :" - "%02x:%02x:%02x\n", ie_id, ie_len, ie_buf[pos], - ie_buf[pos+1], ie_buf[pos+2])); - ret = wl_cfgp2p_vndr_ie(wl, ndev, bssidx, pktflag, - ie_buf+pos, VNDR_SPEC_ELEMENT_ID, ie_buf+pos+3, - ie_len-3, delete); - } - pos += ie_len; - } - - } - *mgmt_ie_len = 0; - /* Add if there is any extra IE */ - if (vndr_ie && vndr_ie_len) { - /* save the current IE in wl struct */ - memcpy(mgmt_ie_buf, vndr_ie, vndr_ie_len); - *mgmt_ie_len = vndr_ie_len; - pos = 0; - ie_buf = (u8 *) vndr_ie; - delete = 0; - while (pos < vndr_ie_len) { - ie_id = ie_buf[pos++]; - ie_len = ie_buf[pos++]; - if ((ie_id == DOT11_MNG_VS_ID) && - (wl_cfgp2p_is_wps_ie(&ie_buf[pos-2], NULL, 0) || - wl_cfgp2p_is_p2p_ie(&ie_buf[pos-2], NULL, 0) || - wl_cfgp2p_is_wfd_ie(&ie_buf[pos-2], NULL, 0))) { - CFGP2P_INFO(("ADDED ID : %d, Len : %d , OUI :" - "%02x:%02x:%02x\n", ie_id, ie_len, ie_buf[pos], - ie_buf[pos+1], ie_buf[pos+2])); - ret = wl_cfgp2p_vndr_ie(wl, ndev, bssidx, pktflag, - ie_buf+pos, VNDR_SPEC_ELEMENT_ID, ie_buf+pos+3, - ie_len-3, delete); - } - pos += ie_len; - } - } - } -#undef IE_TYPE -#undef IE_TYPE_LEN -exit: - return ret; -} - -/* Clear the manament IE buffer of BSSCFG - * Parameters: - * @wl : wl_private data - * @bssidx : bssidx for BSS - * - * Returns 0 if success. - */ -s32 -wl_cfgp2p_clear_management_ie(struct wl_priv *wl, s32 bssidx) -{ -#define INIT_IE(IE_TYPE, BSS_TYPE) \ - do { \ - memset(wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie, 0, \ - sizeof(wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie)); \ - wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie_len = 0; \ - } while (0); - if (bssidx < 0) { - CFGP2P_ERR(("invalid bssidx\n")); - return BCME_BADARG; - } - INIT_IE(probe_req, bssidx); - INIT_IE(probe_res, bssidx); - INIT_IE(assoc_req, bssidx); - INIT_IE(assoc_res, bssidx); - INIT_IE(beacon, bssidx); - return BCME_OK; -} - - -/* Is any of the tlvs the expected entry? If - * not update the tlvs buffer pointer/length. - */ -static bool -wl_cfgp2p_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len, const u8 *oui, u32 oui_len, u8 type) -{ - /* If the contents match the OUI and the type */ - if (ie[TLV_LEN_OFF] >= oui_len + 1 && - !bcmp(&ie[TLV_BODY_OFF], oui, oui_len) && - type == ie[TLV_BODY_OFF + oui_len]) { - return TRUE; - } - - if (tlvs == NULL) - return FALSE; - /* point to the next ie */ - ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN; - /* calculate the length of the rest of the buffer */ - *tlvs_len -= (int)(ie - *tlvs); - /* update the pointer to the start of the buffer */ - *tlvs = ie; - - return FALSE; -} - -wpa_ie_fixed_t * -wl_cfgp2p_find_wpaie(u8 *parse, u32 len) -{ - bcm_tlv_t *ie; - - while ((ie = bcm_parse_tlvs(parse, (u32)len, DOT11_MNG_VS_ID))) { - if (wl_cfgp2p_is_wpa_ie((u8*)ie, &parse, &len)) { - return (wpa_ie_fixed_t *)ie; - } - } - return NULL; -} - -wpa_ie_fixed_t * -wl_cfgp2p_find_wpsie(u8 *parse, u32 len) -{ - bcm_tlv_t *ie; - - while ((ie = bcm_parse_tlvs(parse, (u32)len, DOT11_MNG_VS_ID))) { - if (wl_cfgp2p_is_wps_ie((u8*)ie, &parse, &len)) { - return (wpa_ie_fixed_t *)ie; - } - } - return NULL; -} - -wifi_p2p_ie_t * -wl_cfgp2p_find_p2pie(u8 *parse, u32 len) -{ - bcm_tlv_t *ie; - - while ((ie = bcm_parse_tlvs(parse, (int)len, DOT11_MNG_VS_ID))) { - if (wl_cfgp2p_is_p2p_ie((uint8*)ie, &parse, &len)) { - return (wifi_p2p_ie_t *)ie; - } - } - return NULL; -} - -wifi_wfd_ie_t * -wl_cfgp2p_find_wfdie(u8 *parse, u32 len) -{ - bcm_tlv_t *ie; - - while ((ie = bcm_parse_tlvs(parse, (int)len, DOT11_MNG_VS_ID))) { - if (wl_cfgp2p_is_wfd_ie((uint8*)ie, &parse, &len)) { - return (wifi_wfd_ie_t *)ie; - } - } - return NULL; -} - -static s32 -wl_cfgp2p_vndr_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, s32 pktflag, - s8 *oui, s32 ie_id, s8 *data, s32 data_len, s32 delete) -{ - s32 err = BCME_OK; - s32 buf_len; - s32 iecount; - - vndr_ie_setbuf_t *ie_setbuf; - - /* Validate the pktflag parameter */ - if ((pktflag & ~(VNDR_IE_BEACON_FLAG | VNDR_IE_PRBRSP_FLAG | - VNDR_IE_ASSOCRSP_FLAG | VNDR_IE_AUTHRSP_FLAG | - VNDR_IE_PRBREQ_FLAG | VNDR_IE_ASSOCREQ_FLAG))) { - CFGP2P_ERR(("p2pwl_vndr_ie: Invalid packet flag 0x%x\n", pktflag)); - return -1; - } - - buf_len = sizeof(vndr_ie_setbuf_t) + data_len - 1; - ie_setbuf = (vndr_ie_setbuf_t *) kzalloc(buf_len, GFP_KERNEL); - - CFGP2P_INFO((" ie_id : %02x, data length : %d\n", ie_id, data_len)); - if (!ie_setbuf) { - - CFGP2P_ERR(("Error allocating buffer for IE\n")); - return -ENOMEM; - } - if (delete) - strcpy(ie_setbuf->cmd, "del"); - else - strcpy(ie_setbuf->cmd, "add"); - /* Buffer contains only 1 IE */ - iecount = htod32(1); - memcpy((void *)&ie_setbuf->vndr_ie_buffer.iecount, &iecount, sizeof(int)); - pktflag = htod32(pktflag); - memcpy((void *)&ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].pktflag, - &pktflag, sizeof(uint32)); - ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.id = ie_id; - ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.len - = (uchar)(data_len + VNDR_IE_MIN_LEN); - memcpy(ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui, oui, 3); - memcpy(ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.data, data, data_len); - err = wldev_iovar_setbuf_bsscfg(ndev, "vndr_ie", ie_setbuf, buf_len, - wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); - - CFGP2P_INFO(("vndr_ie iovar returns %d\n", err)); - kfree(ie_setbuf); - return err; -} - -/* - * Search the bssidx based on dev argument - * Parameters: - * @wl : wl_private data - * @ndev : net device to search bssidx - * Returns bssidx for ndev - */ -s32 -wl_cfgp2p_find_idx(struct wl_priv *wl, struct net_device *ndev) -{ - u32 i; - s32 index = -1; - - if (ndev == NULL) { - CFGP2P_ERR((" ndev is NULL\n")); - goto exit; - } - if (!wl->p2p_supported) { - return P2PAPI_BSSCFG_PRIMARY; - } - for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) { - if (ndev == wl_to_p2p_bss_ndev(wl, i)) { - index = wl_to_p2p_bss_bssidx(wl, i); - break; - } - } - if (index == -1) - return P2PAPI_BSSCFG_PRIMARY; -exit: - return index; -} -/* - * Callback function for WLC_E_P2P_DISC_LISTEN_COMPLETE - */ -s32 -wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) -{ - s32 ret = BCME_OK; - - CFGP2P_DBG((" Enter\n")); - - /* If p2p_info is de-initialized, do nothing */ - if (!wl->p2p) - return ret; - - if (wl_get_p2p_status(wl, LISTEN_EXPIRED) == 0) { - wl_set_p2p_status(wl, LISTEN_EXPIRED); - if (timer_pending(&wl->p2p->listen_timer)) { - del_timer_sync(&wl->p2p->listen_timer); - } - cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id, &wl->remain_on_chan, - wl->remain_on_chan_type, GFP_KERNEL); - if (wl_add_remove_eventmsg(wl_to_prmry_ndev(wl), - WLC_E_P2P_PROBREQ_MSG, false) != BCME_OK) { - CFGP2P_ERR((" failed to unset WLC_E_P2P_PROPREQ_MSG\n")); - } - } else - wl_clr_p2p_status(wl, LISTEN_EXPIRED); - - return ret; - -} - -/* - * Timer expire callback function for LISTEN - * We can't report cfg80211_remain_on_channel_expired from Timer ISR context, - * so lets do it from thread context. - */ -static void -wl_cfgp2p_listen_expired(unsigned long data) -{ - wl_event_msg_t msg; - struct wl_priv *wl = (struct wl_priv *) data; - - CFGP2P_DBG((" Enter\n")); - memset(&msg, 0, sizeof(wl_event_msg_t)); - msg.event_type = hton32(WLC_E_P2P_DISC_LISTEN_COMPLETE); - wl_cfg80211_event(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE), &msg, NULL); -} - -/* - * Routine for cancelling the P2P LISTEN - */ -static s32 -wl_cfgp2p_cancel_listen(struct wl_priv *wl, struct net_device *ndev, - bool notify) -{ - WL_DBG(("Enter \n")); - - /* Irrespective of whether timer is running or not, reset - * the LISTEN state. - */ - wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0, - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); - - if (timer_pending(&wl->p2p->listen_timer)) { - del_timer_sync(&wl->p2p->listen_timer); - - if (notify) - cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id, - &wl->remain_on_chan, wl->remain_on_chan_type, GFP_KERNEL); - } - - - return 0; -} - -/* - * Do a P2P Listen on the given channel for the given duration. - * A listen consists of sitting idle and responding to P2P probe requests - * with a P2P probe response. - * - * This fn assumes dongle p2p device discovery is already enabled. - * Parameters : - * @wl : wl_private data - * @channel : channel to listen - * @duration_ms : the time (milli seconds) to wait - */ -s32 -wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms) -{ -#define INIT_TIMER(timer, func, duration, extra_delay) \ - do { \ - init_timer(timer); \ - timer->function = func; \ - timer->expires = jiffies + msecs_to_jiffies(duration + extra_delay); \ - timer->data = (unsigned long) wl; \ - add_timer(timer); \ - } while (0); - - s32 ret = BCME_OK; - struct timer_list *_timer; - CFGP2P_DBG((" Enter Channel : %d, Duration : %d\n", channel, duration_ms)); - if (unlikely(wl_get_p2p_status(wl, DISCOVERY_ON) == 0)) { - - CFGP2P_ERR((" Discovery is not set, so we have noting to do\n")); - - ret = BCME_NOTREADY; - goto exit; - } - if (timer_pending(&wl->p2p->listen_timer)) { - CFGP2P_DBG(("previous LISTEN is not completed yet\n")); - goto exit; - - } else - wl_clr_p2p_status(wl, LISTEN_EXPIRED); - - if (wl_add_remove_eventmsg(wl_to_prmry_ndev(wl), WLC_E_P2P_PROBREQ_MSG, true) != BCME_OK) { - CFGP2P_ERR((" failed to set WLC_E_P2P_PROPREQ_MSG\n")); - } - wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_LISTEN, channel, (u16) duration_ms, - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); - _timer = &wl->p2p->listen_timer; - - /* We will wait to receive WLC_E_P2P_DISC_LISTEN_COMPLETE from dongle , - * otherwise we will wait up to duration_ms + 200ms - */ - INIT_TIMER(_timer, wl_cfgp2p_listen_expired, duration_ms, 200); - -#undef INIT_TIMER -exit: - return ret; -} - - -s32 -wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 enable) -{ - s32 ret = BCME_OK; - CFGP2P_DBG((" Enter\n")); - if (!wl_get_p2p_status(wl, DISCOVERY_ON)) { - - CFGP2P_DBG((" do nothing, discovery is off\n")); - return ret; - } - if (wl_get_p2p_status(wl, SEARCH_ENABLED) == enable) { - CFGP2P_DBG(("already : %d\n", enable)); - return ret; - } - - wl_chg_p2p_status(wl, SEARCH_ENABLED); - /* When disabling Search, reset the WL driver's p2p discovery state to - * WL_P2P_DISC_ST_SCAN. - */ - if (!enable) { - wl_clr_p2p_status(wl, SCANNING); - ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0, - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); - } - - return ret; -} - -/* - * Callback function for WLC_E_ACTION_FRAME_COMPLETE, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE - */ -s32 -wl_cfgp2p_action_tx_complete(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) -{ - s32 ret = BCME_OK; - u32 event_type = ntoh32(e->event_type); - u32 status = ntoh32(e->status); - CFGP2P_DBG((" Enter\n")); - if (event_type == WLC_E_ACTION_FRAME_COMPLETE) { - - CFGP2P_INFO((" WLC_E_ACTION_FRAME_COMPLETE is received : %d\n", status)); - if (status == WLC_E_STATUS_SUCCESS) { - wl_set_p2p_status(wl, ACTION_TX_COMPLETED); - } - else { - wl_set_p2p_status(wl, ACTION_TX_NOACK); - CFGP2P_ERR(("WLC_E_ACTION_FRAME_COMPLETE : NO ACK\n")); - } - } else { - CFGP2P_INFO((" WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE is received," - "status : %d\n", status)); - wake_up_interruptible(&wl->netif_change_event); - } - return ret; -} -/* Send an action frame immediately without doing channel synchronization. - * - * This function does not wait for a completion event before returning. - * The WLC_E_ACTION_FRAME_COMPLETE event will be received when the action - * frame is transmitted. - * The WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE event will be received when an - * 802.11 ack has been received for the sent action frame. - */ -s32 -wl_cfgp2p_tx_action_frame(struct wl_priv *wl, struct net_device *dev, - wl_af_params_t *af_params, s32 bssidx) -{ - s32 ret = BCME_OK; - s32 timeout = 0; - - - CFGP2P_INFO(("\n")); - CFGP2P_INFO(("channel : %u , dwell time : %u\n", - af_params->channel, af_params->dwell_time)); - - wl_clr_p2p_status(wl, ACTION_TX_COMPLETED); - wl_clr_p2p_status(wl, ACTION_TX_NOACK); -#define MAX_WAIT_TIME 2000 - if (bssidx == P2PAPI_BSSCFG_PRIMARY) - bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE); - - ret = wldev_iovar_setbuf_bsscfg(dev, "actframe", af_params, sizeof(*af_params), - wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); - - if (ret < 0) { - CFGP2P_ERR((" sending action frame is failed\n")); - goto exit; - } - timeout = wait_event_interruptible_timeout(wl->netif_change_event, - (wl_get_p2p_status(wl, ACTION_TX_COMPLETED) || wl_get_p2p_status(wl, ACTION_TX_NOACK)), - msecs_to_jiffies(MAX_WAIT_TIME)); - - if (timeout > 0 && wl_get_p2p_status(wl, ACTION_TX_COMPLETED)) { - CFGP2P_INFO(("tx action frame operation is completed\n")); - ret = BCME_OK; - } else { - ret = BCME_ERROR; - CFGP2P_INFO(("tx action frame operation is failed\n")); - } -exit: - CFGP2P_INFO((" via act frame iovar : status = %d\n", ret)); -#undef MAX_WAIT_TIME - return ret; -} - -/* Generate our P2P Device Address and P2P Interface Address from our primary - * MAC address. - */ -void -wl_cfgp2p_generate_bss_mac(struct ether_addr *primary_addr, - struct ether_addr *out_dev_addr, struct ether_addr *out_int_addr) -{ - memset(out_dev_addr, 0, sizeof(*out_dev_addr)); - memset(out_int_addr, 0, sizeof(*out_int_addr)); - - /* Generate the P2P Device Address. This consists of the device's - * primary MAC address with the locally administered bit set. - */ - memcpy(out_dev_addr, primary_addr, sizeof(*out_dev_addr)); - out_dev_addr->octet[0] |= 0x02; - - /* Generate the P2P Interface Address. If the discovery and connection - * BSSCFGs need to simultaneously co-exist, then this address must be - * different from the P2P Device Address. - */ - memcpy(out_int_addr, out_dev_addr, sizeof(*out_int_addr)); - out_int_addr->octet[4] ^= 0x80; - -} - -/* P2P IF Address change to Virtual Interface MAC Address */ -void -wl_cfg80211_change_ifaddr(u8* buf, struct ether_addr *p2p_int_addr, u8 element_id) -{ - wifi_p2p_ie_t *ie = (wifi_p2p_ie_t*) buf; - u16 len = ie->len; - u8 *subel; - u8 subelt_id; - u16 subelt_len; - CFGP2P_DBG((" Enter\n")); - - /* Point subel to the P2P IE's subelt field. - * Subtract the preceding fields (id, len, OUI, oui_type) from the length. - */ - subel = ie->subelts; - len -= 4; /* exclude OUI + OUI_TYPE */ - - while (len >= 3) { - /* attribute id */ - subelt_id = *subel; - subel += 1; - len -= 1; - - /* 2-byte little endian */ - subelt_len = *subel++; - subelt_len |= *subel++ << 8; - - len -= 2; - len -= subelt_len; /* for the remaining subelt fields */ - - if (subelt_id == element_id) { - if (subelt_id == P2P_SEID_INTINTADDR) { - memcpy(subel, p2p_int_addr->octet, ETHER_ADDR_LEN); - CFGP2P_INFO(("Intended P2P Interface Address ATTR FOUND\n")); - } else if (subelt_id == P2P_SEID_DEV_ID) { - memcpy(subel, p2p_int_addr->octet, ETHER_ADDR_LEN); - CFGP2P_INFO(("Device ID ATTR FOUND\n")); - } else if (subelt_id == P2P_SEID_DEV_INFO) { - memcpy(subel, p2p_int_addr->octet, ETHER_ADDR_LEN); - CFGP2P_INFO(("Device INFO ATTR FOUND\n")); - } else if (subelt_id == P2P_SEID_GROUP_ID) { - memcpy(subel, p2p_int_addr->octet, ETHER_ADDR_LEN); - CFGP2P_INFO(("GROUP ID ATTR FOUND\n")); - } return; - } else { - CFGP2P_DBG(("OTHER id : %d\n", subelt_id)); - } - subel += subelt_len; - } -} -/* - * Check if a BSS is up. - * This is a common implementation called by most OSL implementations of - * p2posl_bss_isup(). DO NOT call this function directly from the - * common code -- call p2posl_bss_isup() instead to allow the OSL to - * override the common implementation if necessary. - */ -bool -wl_cfgp2p_bss_isup(struct net_device *ndev, int bsscfg_idx) -{ - s32 result, val; - bool isup = false; - s8 getbuf[64]; - - /* Check if the BSS is up */ - *(int*)getbuf = -1; - result = wldev_iovar_getbuf_bsscfg(ndev, "bss", &bsscfg_idx, - sizeof(bsscfg_idx), getbuf, sizeof(getbuf), 0, NULL); - if (result != 0) { - CFGP2P_ERR(("'wl bss -C %d' failed: %d\n", bsscfg_idx, result)); - CFGP2P_ERR(("NOTE: this ioctl error is normal " - "when the BSS has not been created yet.\n")); - } else { - val = *(int*)getbuf; - val = dtoh32(val); - CFGP2P_INFO(("---wl bss -C %d ==> %d\n", bsscfg_idx, val)); - isup = (val ? TRUE : FALSE); - } - return isup; -} - - -/* Bring up or down a BSS */ -s32 -wl_cfgp2p_bss(struct wl_priv *wl, struct net_device *ndev, s32 bsscfg_idx, s32 up) -{ - s32 ret = BCME_OK; - s32 val = up ? 1 : 0; - - struct { - s32 cfg; - s32 val; - } bss_setbuf; - - bss_setbuf.cfg = htod32(bsscfg_idx); - bss_setbuf.val = htod32(val); - CFGP2P_INFO(("---wl bss -C %d %s\n", bsscfg_idx, up ? "up" : "down")); - ret = wldev_iovar_setbuf(ndev, "bss", &bss_setbuf, sizeof(bss_setbuf), - wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); - - if (ret != 0) { - CFGP2P_ERR(("'bss %d' failed with %d\n", up, ret)); - } - - return ret; -} - -/* Check if 'p2p' is supported in the driver */ -s32 -wl_cfgp2p_supported(struct wl_priv *wl, struct net_device *ndev) -{ - s32 ret = BCME_OK; - s32 p2p_supported = 0; - ret = wldev_iovar_getint(ndev, "p2p", - &p2p_supported); - if (ret < 0) { - CFGP2P_ERR(("wl p2p error %d\n", ret)); - return 0; - } - if (p2p_supported == 1) { - CFGP2P_INFO(("p2p is supported\n")); - } else { - CFGP2P_INFO(("p2p is unsupported\n")); - p2p_supported = 0; - } - return p2p_supported; -} - -/* Cleanup P2P resources */ -s32 -wl_cfgp2p_down(struct wl_priv *wl) -{ - - wl_cfgp2p_cancel_listen(wl, - wl->p2p_net ? wl->p2p_net : wl_to_prmry_ndev(wl), TRUE); - - wl_cfgp2p_deinit_priv(wl); - return 0; -} - -s32 -wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int len) -{ - s32 ret = -1; - int count, start, duration; - wl_p2p_sched_t dongle_noa; - - CFGP2P_DBG((" Enter\n")); - - memset(&dongle_noa, 0, sizeof(dongle_noa)); - - if (wl->p2p && wl->p2p->vif_created) { - - wl->p2p->noa.desc[0].start = 0; - - sscanf(buf, "%d %d %d", &count, &start, &duration); - CFGP2P_DBG(("set_p2p_noa count %d start %d duration %d\n", - count, start, duration)); - if (count != -1) - wl->p2p->noa.desc[0].count = count; - - /* supplicant gives interval as start */ - if (start != -1) - wl->p2p->noa.desc[0].interval = start; - - if (duration != -1) - wl->p2p->noa.desc[0].duration = duration; - - if (wl->p2p->noa.desc[0].count != 255) { - wl->p2p->noa.desc[0].start = 200; - dongle_noa.type = WL_P2P_SCHED_TYPE_REQ_ABS; - dongle_noa.action = WL_P2P_SCHED_ACTION_GOOFF; - dongle_noa.option = WL_P2P_SCHED_OPTION_TSFOFS; - } - else { - /* Continuous NoA interval. */ - dongle_noa.action = WL_P2P_SCHED_ACTION_NONE; - dongle_noa.type = WL_P2P_SCHED_TYPE_ABS; - if ((wl->p2p->noa.desc[0].interval == 102) || - (wl->p2p->noa.desc[0].interval == 100)) { - wl->p2p->noa.desc[0].start = 100 - - wl->p2p->noa.desc[0].duration; - dongle_noa.option = WL_P2P_SCHED_OPTION_BCNPCT; - } - else { - dongle_noa.option = WL_P2P_SCHED_OPTION_NORMAL; - } - } - /* Put the noa descriptor in dongle format for dongle */ - dongle_noa.desc[0].count = htod32(wl->p2p->noa.desc[0].count); - if (dongle_noa.option == WL_P2P_SCHED_OPTION_BCNPCT) { - dongle_noa.desc[0].start = htod32(wl->p2p->noa.desc[0].start); - dongle_noa.desc[0].duration = htod32(wl->p2p->noa.desc[0].duration); - } - else { - dongle_noa.desc[0].start = htod32(wl->p2p->noa.desc[0].start*1000); - dongle_noa.desc[0].duration = htod32(wl->p2p->noa.desc[0].duration*1000); - } - dongle_noa.desc[0].interval = htod32(wl->p2p->noa.desc[0].interval*1000); - - ret = wldev_iovar_setbuf(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION), - "p2p_noa", &dongle_noa, sizeof(dongle_noa), wl->ioctl_buf, WLC_IOCTL_MAXLEN, - &wl->ioctl_buf_sync); - - if (ret < 0) { - CFGP2P_ERR(("fw set p2p_noa failed %d\n", ret)); - } - } - else { - CFGP2P_ERR(("ERROR: set_noa in non-p2p mode\n")); - } - return ret; -} - -s32 -wl_cfgp2p_get_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int buf_len) -{ - wifi_p2p_noa_desc_t *noa_desc; - int len = 0, i; - char _buf[200]; - - CFGP2P_DBG((" Enter\n")); - buf[0] = '\0'; - if (wl->p2p && wl->p2p->vif_created) { - if (wl->p2p->noa.desc[0].count || wl->p2p->ops.ops) { - _buf[0] = 1; /* noa index */ - _buf[1] = (wl->p2p->ops.ops ? 0x80: 0) | - (wl->p2p->ops.ctw & 0x7f); /* ops + ctw */ - len += 2; - if (wl->p2p->noa.desc[0].count) { - noa_desc = (wifi_p2p_noa_desc_t*)&_buf[len]; - noa_desc->cnt_type = wl->p2p->noa.desc[0].count; - noa_desc->duration = wl->p2p->noa.desc[0].duration; - noa_desc->interval = wl->p2p->noa.desc[0].interval; - noa_desc->start = wl->p2p->noa.desc[0].start; - len += sizeof(wifi_p2p_noa_desc_t); - } - if (buf_len <= len * 2) { - CFGP2P_ERR(("ERROR: buf_len %d in not enough for" - "returning noa in string format\n", buf_len)); - return -1; - } - /* We have to convert the buffer data into ASCII strings */ - for (i = 0; i < len; i++) { - sprintf(buf, "%02x", _buf[i]); - buf += 2; - } - buf[i*2] = '\0'; - } - } - else { - CFGP2P_ERR(("ERROR: get_noa in non-p2p mode\n")); - return -1; - } - return len * 2; -} - -s32 -wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, struct net_device *ndev, char* buf, int len) -{ - int ps, ctw; - int ret = -1; - s32 legacy_ps; - - CFGP2P_DBG((" Enter\n")); - if (wl->p2p && wl->p2p->vif_created) { - sscanf(buf, "%d %d %d", &legacy_ps, &ps, &ctw); - CFGP2P_DBG((" Enter legacy_ps %d ps %d ctw %d\n", legacy_ps, ps, ctw)); - if (ctw != -1) { - wl->p2p->ops.ctw = ctw; - ret = 0; - } - if (ps != -1) { - wl->p2p->ops.ops = ps; - ret = wldev_iovar_setbuf(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION), - "p2p_ops", &wl->p2p->ops, sizeof(wl->p2p->ops), - wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); - if (ret < 0) { - CFGP2P_ERR(("fw set p2p_ops failed %d\n", ret)); - } - } - - if (legacy_ps != -1) { - s32 pm = legacy_ps ? PM_MAX : PM_OFF; -#if defined(SUPPORT_PM2_ONLY) - if (pm == PM_MAX) - pm = PM_FAST; -#endif /* SUPPORT_PM2_ONLY */ - ret = wldev_ioctl(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION), - WLC_SET_PM, &pm, sizeof(pm), true); - if (unlikely(ret)) { - CFGP2P_ERR(("error (%d)\n", ret)); - } else { - wl_cfg80211_update_power_mode(ndev); - } - } - } - else { - CFGP2P_ERR(("ERROR: set_p2p_ps in non-p2p mode\n")); - ret = -1; - } - return ret; -} - -u8 * -wl_cfgp2p_retreive_p2pattrib(void *buf, u8 element_id) -{ - wifi_p2p_ie_t *ie = NULL; - u16 len = 0; - u8 *subel; - u8 subelt_id; - u16 subelt_len; - - if (!buf) { - WL_ERR(("P2P IE not present")); - return 0; - } - - ie = (wifi_p2p_ie_t*) buf; - len = ie->len; - - /* Point subel to the P2P IE's subelt field. - * Subtract the preceding fields (id, len, OUI, oui_type) from the length. - */ - subel = ie->subelts; - len -= 4; /* exclude OUI + OUI_TYPE */ - - while (len >= 3) { - /* attribute id */ - subelt_id = *subel; - subel += 1; - len -= 1; - - /* 2-byte little endian */ - subelt_len = *subel++; - subelt_len |= *subel++ << 8; - - len -= 2; - len -= subelt_len; /* for the remaining subelt fields */ - - if (subelt_id == element_id) { - /* This will point to start of subelement attrib after - * attribute id & len - */ - return subel; - } - - /* Go to next subelement */ - subel += subelt_len; - } - - /* Not Found */ - return NULL; -} - -#define P2P_GROUP_CAPAB_GO_BIT 0x01 -u8 * -wl_cfgp2p_retreive_p2p_dev_addr(wl_bss_info_t *bi, u32 bi_length) -{ - wifi_p2p_ie_t * p2p_ie = NULL; - u8 *capability = NULL; - bool p2p_go = 0; - u8 *ptr = NULL; - - if (!(p2p_ie = wl_cfgp2p_find_p2pie(((u8 *) bi) + bi->ie_offset, bi->ie_length))) { - WL_ERR(("P2P IE not found")); - return NULL; - } - - if (!(capability = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_P2P_INFO))) { - WL_ERR(("P2P Capability attribute not found")); - return NULL; - } - - /* Check Group capability for Group Owner bit */ - p2p_go = capability[1] & P2P_GROUP_CAPAB_GO_BIT; - if (!p2p_go) { - return bi->BSSID.octet; - } - - /* In probe responses, DEVICE INFO attribute will be present */ - if (!(ptr = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_DEV_INFO))) { - /* If DEVICE_INFO is not found, this might be a beacon frame. - * check for DEVICE_ID in the beacon frame. - */ - ptr = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_DEV_ID); - } - - if (!ptr) - WL_ERR((" Both DEVICE_ID & DEVICE_INFO attribute not present in P2P IE ")); - - return ptr; -} - -s32 -wl_cfgp2p_register_ndev(struct wl_priv *wl) -{ - int ret = 0; - struct net_device* net = NULL; - struct wireless_dev *wdev; - uint8 temp_addr[ETHER_ADDR_LEN] = { 0x00, 0x90, 0x4c, 0x33, 0x22, 0x11 }; - - /* Allocate etherdev, including space for private structure */ - if (!(net = alloc_etherdev(sizeof(wl)))) { - CFGP2P_ERR(("%s: OOM - alloc_etherdev\n", __FUNCTION__)); - goto fail; - } - - strcpy(net->name, "p2p%d"); - net->name[IFNAMSIZ - 1] = '\0'; - - /* Copy the reference to wl_priv */ - memcpy((void *)netdev_priv(net), &wl, sizeof(wl)); - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) - ASSERT(!net->open); - net->do_ioctl = wl_cfgp2p_do_ioctl; - net->hard_start_xmit = wl_cfgp2p_start_xmit; - net->open = wl_cfgp2p_if_open; - net->stop = wl_cfgp2p_if_stop; -#else - ASSERT(!net->netdev_ops); - net->netdev_ops = &wl_cfgp2p_if_ops; -#endif - - /* Register with a dummy MAC addr */ - memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN); - - wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); - if (unlikely(!wdev)) { - WL_ERR(("Could not allocate wireless device\n")); - return -ENOMEM; - } - - wdev->wiphy = wl->wdev->wiphy; - - wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS); - - net->ieee80211_ptr = wdev; - - SET_NETDEV_DEV(net, wiphy_dev(wdev->wiphy)); - - /* Associate p2p0 network interface with new wdev */ - wdev->netdev = net; - - /* store p2p net ptr for further reference. Note that iflist won't have this - * entry as there corresponding firmware interface is a "Hidden" interface. - */ - if (wl->p2p_net) { - CFGP2P_ERR(("p2p_net defined already.\n")); - return -EINVAL; - } else { - wl->p2p_wdev = wdev; - wl->p2p_net = net; - } - - ret = register_netdev(net); - if (ret) { - CFGP2P_ERR((" register_netdevice failed (%d)\n", ret)); - goto fail; - } - - printk("%s: P2P Interface Registered\n", net->name); - - return ret; -fail: - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) - net->open = NULL; -#else - net->netdev_ops = NULL; -#endif - - if (net) { - unregister_netdev(net); - free_netdev(net); - } - - return -ENODEV; -} - -s32 -wl_cfgp2p_unregister_ndev(struct wl_priv *wl) -{ - - if (!wl || !wl->p2p_net) { - CFGP2P_ERR(("Invalid Ptr\n")); - return -EINVAL; - } - - unregister_netdev(wl->p2p_net); - free_netdev(wl->p2p_net); - - return 0; -} - -static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev) -{ - CFGP2P_DBG(("(%s) is not used for data operations. Droping the packet. \n", ndev->name)); - return 0; -} - -static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd) -{ - int ret = 0; - struct wl_priv *wl = *(struct wl_priv **)netdev_priv(net); - struct net_device *ndev = wl_to_prmry_ndev(wl); - - /* There is no ifidx corresponding to p2p0 in our firmware. So we should - * not Handle any IOCTL cmds on p2p0 other than ANDROID PRIVATE CMDs. - * For Android PRIV CMD handling map it to primary I/F - */ - if (cmd == SIOCDEVPRIVATE+1) { - ret = wl_android_priv_cmd(ndev, ifr, cmd); - - } else { - CFGP2P_ERR(("%s: IOCTL req 0x%x on p2p0 I/F. Ignoring. \n", - __FUNCTION__, cmd)); - return -1; - } - - return ret; -} - -static int wl_cfgp2p_if_open(struct net_device *net) -{ - struct wireless_dev *wdev = net->ieee80211_ptr; - - if (!wdev) - return -EINVAL; - - /* If suppose F/W download (ifconfig wlan0 up) hasn't been done by now, - * do it here. This will make sure that in concurrent mode, supplicant - * is not dependent on a particular order of interface initialization. - * i.e you may give wpa_supp -iwlan0 -N -ip2p0 or wpa_supp -ip2p0 -N - * -iwlan0. - */ - wl_cfg80211_do_driver_init(net); - - wdev->wiphy->interface_modes |= (BIT(NL80211_IFTYPE_P2P_CLIENT) - | BIT(NL80211_IFTYPE_P2P_GO)); - - return 0; -} - -static int wl_cfgp2p_if_stop(struct net_device *net) -{ - struct wireless_dev *wdev = net->ieee80211_ptr; - - if (!wdev) - return -EINVAL; - - wdev->wiphy->interface_modes = (wdev->wiphy->interface_modes) - & (~(BIT(NL80211_IFTYPE_P2P_CLIENT)| - BIT(NL80211_IFTYPE_P2P_GO))); - return 0; -} diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h b/drivers/net/wireless/bcmdhd/wl_cfgp2p.h deleted file mode 100644 index 03a645aea31a..000000000000 --- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Linux cfgp2p driver - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wl_cfgp2p.h,v 1.1.4.1.2.8 2011/02/09 01:37:52 Exp $ - */ -#ifndef _wl_cfgp2p_h_ -#define _wl_cfgp2p_h_ -#include -#include - -struct wl_priv; -extern u32 wl_dbg_level; - -typedef struct wifi_p2p_ie wifi_wfd_ie_t; - -/* Enumeration of the usages of the BSSCFGs used by the P2P Library. Do not - * confuse this with a bsscfg index. This value is an index into the - * saved_ie[] array of structures which in turn contains a bsscfg index field. - */ -typedef enum { - P2PAPI_BSSCFG_PRIMARY, /* maps to driver's primary bsscfg */ - P2PAPI_BSSCFG_DEVICE, /* maps to driver's P2P device discovery bsscfg */ - P2PAPI_BSSCFG_CONNECTION, /* maps to driver's P2P connection bsscfg */ - P2PAPI_BSSCFG_MAX -} p2p_bsscfg_type_t; - -#define IE_MAX_LEN 512 -/* Structure to hold all saved P2P and WPS IEs for a BSSCFG */ -struct p2p_saved_ie { - u8 p2p_probe_req_ie[IE_MAX_LEN]; - u8 p2p_probe_res_ie[IE_MAX_LEN]; - u8 p2p_assoc_req_ie[IE_MAX_LEN]; - u8 p2p_assoc_res_ie[IE_MAX_LEN]; - u8 p2p_beacon_ie[IE_MAX_LEN]; - u32 p2p_probe_req_ie_len; - u32 p2p_probe_res_ie_len; - u32 p2p_assoc_req_ie_len; - u32 p2p_assoc_res_ie_len; - u32 p2p_beacon_ie_len; -}; - -struct p2p_bss { - u32 bssidx; - struct net_device *dev; - struct p2p_saved_ie saved_ie; - void *private_data; -}; - -struct p2p_info { - bool on; /* p2p on/off switch */ - bool scan; - bool vif_created; - s8 vir_ifname[IFNAMSIZ]; - unsigned long status; - struct ether_addr dev_addr; - struct ether_addr int_addr; - struct p2p_bss bss_idx[P2PAPI_BSSCFG_MAX]; - struct timer_list listen_timer; - wl_p2p_sched_t noa; - wl_p2p_ops_t ops; - wlc_ssid_t ssid; -}; - -/* dongle status */ -enum wl_cfgp2p_status { - WLP2P_STATUS_DISCOVERY_ON = 0, - WLP2P_STATUS_SEARCH_ENABLED, - WLP2P_STATUS_IF_ADD, - WLP2P_STATUS_IF_DEL, - WLP2P_STATUS_IF_DELETING, - WLP2P_STATUS_IF_CHANGING, - WLP2P_STATUS_IF_CHANGED, - WLP2P_STATUS_LISTEN_EXPIRED, - WLP2P_STATUS_ACTION_TX_COMPLETED, - WLP2P_STATUS_ACTION_TX_NOACK, - WLP2P_STATUS_SCANNING, - WLP2P_STATUS_GO_NEG_PHASE -}; - - -#define wl_to_p2p_bss_ndev(w, type) ((wl)->p2p->bss_idx[type].dev) -#define wl_to_p2p_bss_bssidx(w, type) ((wl)->p2p->bss_idx[type].bssidx) -#define wl_to_p2p_bss_saved_ie(w, type) ((wl)->p2p->bss_idx[type].saved_ie) -#define wl_to_p2p_bss_private(w, type) ((wl)->p2p->bss_idx[type].private_data) -#define wl_to_p2p_bss(wl, type) ((wl)->p2p->bss_idx[type]) -#define wl_get_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0:test_bit(WLP2P_STATUS_ ## stat, \ - &(wl)->p2p->status)) -#define wl_set_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0:set_bit(WLP2P_STATUS_ ## stat, \ - &(wl)->p2p->status)) -#define wl_clr_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0:clear_bit(WLP2P_STATUS_ ## stat, \ - &(wl)->p2p->status)) -#define wl_chg_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0:change_bit(WLP2P_STATUS_ ## stat, \ - &(wl)->p2p->status)) -#define p2p_on(wl) ((wl)->p2p->on) -#define p2p_scan(wl) ((wl)->p2p->scan) -#define p2p_is_on(wl) ((wl)->p2p && (wl)->p2p->on) - -/* dword align allocation */ -#define WLC_IOCTL_MAXLEN 8192 -#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] -#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" - -#define CFGP2P_ERR(args) \ - do { \ - if (wl_dbg_level & WL_DBG_ERR) { \ - printk(KERN_ERR "CFGP2P-ERROR) %s : ", __func__); \ - printk args; \ - } \ - } while (0) -#define CFGP2P_INFO(args) \ - do { \ - if (wl_dbg_level & WL_DBG_INFO) { \ - printk(KERN_ERR "CFGP2P-INFO) %s : ", __func__); \ - printk args; \ - } \ - } while (0) -#define CFGP2P_DBG(args) \ - do { \ - if (wl_dbg_level & WL_DBG_DBG) { \ - printk(KERN_ERR "CFGP2P-DEBUG) %s :", __func__); \ - printk args; \ - } \ - } while (0) - -extern bool -wl_cfgp2p_is_pub_action(void *frame, u32 frame_len); -extern bool -wl_cfgp2p_is_p2p_action(void *frame, u32 frame_len); -extern bool -wl_cfgp2p_is_gas_action(void *frame, u32 frame_len); -extern void -wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len); -extern s32 -wl_cfgp2p_init_priv(struct wl_priv *wl); -extern void -wl_cfgp2p_deinit_priv(struct wl_priv *wl); -extern s32 -wl_cfgp2p_set_firm_p2p(struct wl_priv *wl); -extern s32 -wl_cfgp2p_set_p2p_mode(struct wl_priv *wl, u8 mode, - u32 channel, u16 listen_ms, int bssidx); -extern s32 -wl_cfgp2p_ifadd(struct wl_priv *wl, struct ether_addr *mac, u8 if_type, - chanspec_t chspec); -extern s32 -wl_cfgp2p_ifdel(struct wl_priv *wl, struct ether_addr *mac); -extern s32 -wl_cfgp2p_ifchange(struct wl_priv *wl, struct ether_addr *mac, u8 if_type, chanspec_t chspec); - -extern s32 -wl_cfgp2p_ifidx(struct wl_priv *wl, struct ether_addr *mac, s32 *index); - -extern s32 -wl_cfgp2p_init_discovery(struct wl_priv *wl); -extern s32 -wl_cfgp2p_enable_discovery(struct wl_priv *wl, struct net_device *dev, const u8 *ie, u32 ie_len); -extern s32 -wl_cfgp2p_disable_discovery(struct wl_priv *wl); -extern s32 -wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active, u32 num_chans, - u16 *channels, - s32 search_state, u16 action, u32 bssidx); - -extern s32 -wl_cfgp2p_act_frm_search(struct wl_priv *wl, struct net_device *ndev, - s32 bssidx, s32 channel); - -extern wpa_ie_fixed_t * -wl_cfgp2p_find_wpaie(u8 *parse, u32 len); - -extern wpa_ie_fixed_t * -wl_cfgp2p_find_wpsie(u8 *parse, u32 len); - -extern wifi_p2p_ie_t * -wl_cfgp2p_find_p2pie(u8 *parse, u32 len); - -extern wifi_wfd_ie_t * -wl_cfgp2p_find_wfdie(u8 *parse, u32 len); - -extern s32 -wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, - s32 pktflag, const u8 *vndr_ie, u32 vndr_ie_len); -extern s32 -wl_cfgp2p_clear_management_ie(struct wl_priv *wl, s32 bssidx); - -extern s32 -wl_cfgp2p_find_idx(struct wl_priv *wl, struct net_device *ndev); - - -extern s32 -wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data); -extern s32 -wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms); - -extern s32 -wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 enable); - -extern s32 -wl_cfgp2p_action_tx_complete(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data); -extern s32 -wl_cfgp2p_tx_action_frame(struct wl_priv *wl, struct net_device *dev, - wl_af_params_t *af_params, s32 bssidx); - -extern void -wl_cfgp2p_generate_bss_mac(struct ether_addr *primary_addr, struct ether_addr *out_dev_addr, - struct ether_addr *out_int_addr); - -extern void -wl_cfg80211_change_ifaddr(u8* buf, struct ether_addr *p2p_int_addr, u8 element_id); -extern bool -wl_cfgp2p_bss_isup(struct net_device *ndev, int bsscfg_idx); - -extern s32 -wl_cfgp2p_bss(struct wl_priv *wl, struct net_device *ndev, s32 bsscfg_idx, s32 up); - - -extern s32 -wl_cfgp2p_supported(struct wl_priv *wl, struct net_device *ndev); - -extern s32 -wl_cfgp2p_down(struct wl_priv *wl); - -extern s32 -wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int len); - -extern s32 -wl_cfgp2p_get_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int len); - -extern s32 -wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, struct net_device *ndev, char* buf, int len); - -extern u8 * -wl_cfgp2p_retreive_p2pattrib(void *buf, u8 element_id); - -extern u8 * -wl_cfgp2p_retreive_p2p_dev_addr(wl_bss_info_t *bi, u32 bi_length); - -extern s32 -wl_cfgp2p_register_ndev(struct wl_priv *wl); - -extern s32 -wl_cfgp2p_unregister_ndev(struct wl_priv *wl); - -/* WiFi Direct */ -#define SOCIAL_CHAN_1 1 -#define SOCIAL_CHAN_2 6 -#define SOCIAL_CHAN_3 11 -#define SOCIAL_CHAN_CNT 3 -#define WL_P2P_WILDCARD_SSID "DIRECT-" -#define WL_P2P_WILDCARD_SSID_LEN 7 -#define WL_P2P_INTERFACE_PREFIX "p2p" -#define WL_P2P_TEMP_CHAN "11" - -/* If the provision discovery is for JOIN operations, then we need not do an internal scan to find GO */ -#define IS_PROV_DISC_WITHOUT_GROUP_ID(p2p_ie, len) (wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_GROUP_ID) == NULL ) - -#define IS_GAS_REQ(frame, len) (wl_cfgp2p_is_gas_action(frame, len) && \ - ((frame->action == P2PSD_ACTION_ID_GAS_IREQ) || \ - (frame->action == P2PSD_ACTION_ID_GAS_CREQ))) -#define IS_P2P_PUB_ACT_REQ(frame, p2p_ie, len) (wl_cfgp2p_is_pub_action(frame, len) && \ - ((frame->subtype == P2P_PAF_GON_REQ) || \ - (frame->subtype == P2P_PAF_INVITE_REQ) || \ - ((frame->subtype == P2P_PAF_PROVDIS_REQ) && IS_PROV_DISC_WITHOUT_GROUP_ID(p2p_ie, len)))) -#define IS_P2P_SOCIAL(ch) ((ch == SOCIAL_CHAN_1) || (ch == SOCIAL_CHAN_2) || (ch == SOCIAL_CHAN_3)) -#define IS_P2P_SSID(ssid) (memcmp(ssid, WL_P2P_WILDCARD_SSID, WL_P2P_WILDCARD_SSID_LEN) == 0) -#endif /* _wl_cfgp2p_h_ */ diff --git a/drivers/net/wireless/bcmdhd/wl_dbg.h b/drivers/net/wireless/bcmdhd/wl_dbg.h deleted file mode 100644 index 0b99557cbe8d..000000000000 --- a/drivers/net/wireless/bcmdhd/wl_dbg.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Minimal debug/trace/assert driver definitions for - * Broadcom 802.11 Networking Adapter. - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wl_dbg.h,v 1.115.6.3 2010-12-15 21:42:23 Exp $ - */ - - - -#ifndef _wl_dbg_h_ -#define _wl_dbg_h_ - - -extern uint32 wl_msg_level; -extern uint32 wl_msg_level2; - -#define WL_PRINT(args) printf args - - - -#define WL_NONE(args) - -#define WL_ERROR(args) -#define WL_TRACE(args) - - -extern uint32 wl_msg_level; -extern uint32 wl_msg_level2; -#endif diff --git a/drivers/net/wireless/bcmdhd/wl_iw.c b/drivers/net/wireless/bcmdhd/wl_iw.c deleted file mode 100644 index d60c21c03671..000000000000 --- a/drivers/net/wireless/bcmdhd/wl_iw.c +++ /dev/null @@ -1,8894 +0,0 @@ -/* - * Linux Wireless Extensions support - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wl_iw.c,v 1.132.2.18 2011-02-05 01:44:47 $ - */ - -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include - -typedef void wlc_info_t; -typedef void wl_info_t; -typedef const struct si_pub si_t; -#include - -#include -#include -#include -#define WL_ERROR(x) printf x -#define WL_TRACE(x) -#define WL_ASSOC(x) -#define WL_INFORM(x) -#define WL_WSEC(x) -#define WL_SCAN(x) - - -#ifdef PNO_SET_DEBUG -#define WL_PNO(x) printf x -#else -#define WL_PNO(x) -#endif - - -#define JF2MS jiffies_to_msecs(jiffies) - -#ifdef COEX_DBG -#define WL_TRACE_COEX(x) printf("TS:%lu ", JF2MS); \ - printf x -#else -#define WL_TRACE_COEX(x) -#endif - -#ifdef SCAN_DBG -#define WL_TRACE_SCAN(x) printf("TS:%lu ", JF2MS); \ - printf x -#else -#define WL_TRACE_SCAN(x) -#endif - - -#include - - - - -#define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) - -#include - -#define WL_IW_USE_ISCAN 1 -#define ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS 1 - -#ifdef OEM_CHROMIUMOS -bool g_set_essid_before_scan = TRUE; -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 - struct mutex g_wl_ss_scan_lock; -#endif - -#if defined(SOFTAP) -#define WL_SOFTAP(x) -static struct net_device *priv_dev; -extern bool ap_cfg_running; -extern bool ap_fw_loaded; -struct net_device *ap_net_dev = NULL; -tsk_ctl_t ap_eth_ctl; -static int wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap); -static int wl_iw_softap_deassoc_stations(struct net_device *dev, u8 *mac); -#endif - - -#define WL_IW_IOCTL_CALL(func_call) \ - do { \ - func_call; \ - } while (0) - -#define RETURN_IF_EXTRA_NULL(extra) \ - if (!extra) { \ - WL_ERROR(("%s: error : extra is null pointer\n", __FUNCTION__)); \ - return -EINVAL; \ - } - -static int g_onoff = G_WLAN_SET_ON; -wl_iw_extra_params_t g_wl_iw_params; - - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 - -static struct mutex wl_cache_lock; -static struct mutex wl_softap_lock; - -#define DHD_OS_MUTEX_INIT(a) mutex_init(a) -#define DHD_OS_MUTEX_LOCK(a) mutex_lock(a) -#define DHD_OS_MUTEX_UNLOCK(a) mutex_unlock(a) - -#else - -#define DHD_OS_MUTEX_INIT(a) -#define DHD_OS_MUTEX_LOCK(a) -#define DHD_OS_MUTEX_UNLOCK(a) - -#endif - -#include -extern void dhd_customer_gpio_wlan_ctrl(int onoff); -extern uint dhd_dev_reset(struct net_device *dev, uint8 flag); -extern int dhd_dev_init_ioctl(struct net_device *dev); - -uint wl_msg_level = WL_ERROR_VAL; - -#define MAX_WLIW_IOCTL_LEN 1024 - - -#define htod32(i) i -#define htod16(i) i -#define dtoh32(i) i -#define dtoh16(i) i -#define htodchanspec(i) i -#define dtohchanspec(i) i - -extern struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev); -extern int dhd_wait_pend8021x(struct net_device *dev); - -#if WIRELESS_EXT < 19 -#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST) -#define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST) -#endif - -static void *g_scan = NULL; -static volatile uint g_scan_specified_ssid; -static wlc_ssid_t g_specific_ssid; - -static wlc_ssid_t g_ssid; - -#ifdef CONFIG_WPS2 -static char *g_wps_probe_req_ie; -static int g_wps_probe_req_ie_len; -#endif - -bool btcoex_is_sco_active(struct net_device *dev); -static wl_iw_ss_cache_ctrl_t g_ss_cache_ctrl; -#if defined(CONFIG_FIRST_SCAN) -static volatile uint g_first_broadcast_scan; -static volatile uint g_first_counter_scans; -#define MAX_ALLOWED_BLOCK_SCAN_FROM_FIRST_SCAN 3 -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define DAEMONIZE(a) daemonize(a); \ - allow_signal(SIGKILL); \ - allow_signal(SIGTERM); -#else -#define RAISE_RX_SOFTIRQ() \ - cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ) -#define DAEMONIZE(a) daemonize(); \ - do { if (a) \ - strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a) + 1))); \ - } while (0); -#endif - -#if defined(WL_IW_USE_ISCAN) -#if !defined(CSCAN) -static void wl_iw_free_ss_cache(void); -static int wl_iw_run_ss_cache_timer(int kick_off); -#endif -#if defined(CONFIG_FIRST_SCAN) -int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag); -#endif -static int dev_wlc_bufvar_set(struct net_device *dev, char *name, char *buf, int len); -#define ISCAN_STATE_IDLE 0 -#define ISCAN_STATE_SCANING 1 - - -#define WLC_IW_ISCAN_MAXLEN 2048 -typedef struct iscan_buf { - struct iscan_buf * next; - char iscan_buf[WLC_IW_ISCAN_MAXLEN]; -} iscan_buf_t; - -typedef struct iscan_info { - struct net_device *dev; - struct timer_list timer; - uint32 timer_ms; - uint32 timer_on; - int iscan_state; - iscan_buf_t * list_hdr; - iscan_buf_t * list_cur; - - - tsk_ctl_t tsk_ctl; - - uint32 scan_flag; -#if defined CSCAN - char ioctlbuf[WLC_IOCTL_MEDLEN]; -#else - char ioctlbuf[WLC_IOCTL_SMLEN]; -#endif - - wl_iscan_params_t *iscan_ex_params_p; - int iscan_ex_param_size; -} iscan_info_t; - - - -#define COEX_DHCP 1 -#ifdef COEX_DHCP - -#define BT_DHCP_eSCO_FIX -#define BT_DHCP_USE_FLAGS -#define BT_DHCP_OPPORTUNITY_WINDOW_TIME 2500 -#define BT_DHCP_FLAG_FORCE_TIME 5500 - - - -static int wl_iw_set_btcoex_dhcp( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -); - -static void wl_iw_bt_flag_set(struct net_device *dev, bool set); -static void wl_iw_bt_release(void); - -typedef enum bt_coex_status { - BT_DHCP_IDLE = 0, - BT_DHCP_START, - BT_DHCP_OPPORTUNITY_WINDOW, - BT_DHCP_FLAG_FORCE_TIMEOUT -} coex_status_t; - - -typedef struct bt_info { - struct net_device *dev; - struct timer_list timer; - uint32 timer_ms; - uint32 timer_on; - uint32 ts_dhcp_start; - uint32 ts_dhcp_ok; - bool dhcp_done; - int bt_state; - - - tsk_ctl_t tsk_ctl; - -} bt_info_t; - -bt_info_t *g_bt = NULL; -static void wl_iw_bt_timerfunc(ulong data); -#endif -iscan_info_t *g_iscan = NULL; -void dhd_print_buf(void *pbuf, int len, int bytes_per_line); -static void wl_iw_timerfunc(ulong data); -static void wl_iw_set_event_mask(struct net_device *dev); -static int -wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action); -#endif - -static int -wl_iw_set_scan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -); - -#ifndef CSCAN -static int -wl_iw_get_scan( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -); - -static uint -wl_iw_get_scan_prep( - wl_scan_results_t *list, - struct iw_request_info *info, - char *extra, - short max_size -); -#endif - -static void -swap_key_from_BE( - wl_wsec_key_t *key -) -{ - key->index = htod32(key->index); - key->len = htod32(key->len); - key->algo = htod32(key->algo); - key->flags = htod32(key->flags); - key->rxiv.hi = htod32(key->rxiv.hi); - key->rxiv.lo = htod16(key->rxiv.lo); - key->iv_initialized = htod32(key->iv_initialized); -} - -static void -swap_key_to_BE( - wl_wsec_key_t *key -) -{ - key->index = dtoh32(key->index); - key->len = dtoh32(key->len); - key->algo = dtoh32(key->algo); - key->flags = dtoh32(key->flags); - key->rxiv.hi = dtoh32(key->rxiv.hi); - key->rxiv.lo = dtoh16(key->rxiv.lo); - key->iv_initialized = dtoh32(key->iv_initialized); -} - -static int -dev_wlc_ioctl( - struct net_device *dev, - int cmd, - void *arg, - int len -) -{ - struct ifreq ifr; - wl_ioctl_t ioc; - mm_segment_t fs; - int ret = -EINVAL; - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return ret; - } - - net_os_wake_lock(dev); - - WL_INFORM(("%s, PID:%x: send Local IOCTL -> dhd: cmd:0x%x, buf:%p, len:%d ,\n", - __FUNCTION__, current->pid, cmd, arg, len)); - - if (g_onoff == G_WLAN_SET_ON) { - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = cmd; - ioc.buf = arg; - ioc.len = len; - - strcpy(ifr.ifr_name, dev->name); - ifr.ifr_data = (caddr_t) &ioc; - - - ret = dev_open(dev); - if (ret) { - WL_ERROR(("%s: Error dev_open: %d\n", __func__, ret)); - net_os_wake_unlock(dev); - return ret; - } - - fs = get_fs(); - set_fs(get_ds()); -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31) - ret = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE); -#else - ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE); -#endif - set_fs(fs); - } - else { - WL_TRACE(("%s: call after driver stop : ignored\n", __FUNCTION__)); - } - - net_os_wake_unlock(dev); - - return ret; -} - - -static int -dev_wlc_intvar_get_reg( - struct net_device *dev, - char *name, - uint reg, - int *retval) -{ - union { - char buf[WLC_IOCTL_SMLEN]; - int val; - } var; - int error; - - uint len; - len = bcm_mkiovar(name, (char *)(®), sizeof(reg), (char *)(&var), sizeof(var.buf)); - ASSERT(len); - error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)&var, len); - - *retval = dtoh32(var.val); - return (error); -} - - -static int -dev_wlc_intvar_set_reg( - struct net_device *dev, - char *name, - char *addr, - char * val) -{ - char reg_addr[8]; - - memset(reg_addr, 0, sizeof(reg_addr)); - memcpy((char *)®_addr[0], (char *)addr, 4); - memcpy((char *)®_addr[4], (char *)val, 4); - - return (dev_wlc_bufvar_set(dev, name, (char *)®_addr[0], sizeof(reg_addr))); -} - - - - -static int -dev_wlc_intvar_set( - struct net_device *dev, - char *name, - int val) -{ - char buf[WLC_IOCTL_SMLEN]; - uint len; - - val = htod32(val); - len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf)); - ASSERT(len); - - return (dev_wlc_ioctl(dev, WLC_SET_VAR, buf, len)); -} - -#if defined(WL_IW_USE_ISCAN) -static int -dev_iw_iovar_setbuf( - struct net_device *dev, - char *iovar, - void *param, - int paramlen, - void *bufptr, - int buflen) -{ - int iolen; - - iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen); - ASSERT(iolen); - - if (iolen == 0) - return 0; - - return (dev_wlc_ioctl(dev, WLC_SET_VAR, bufptr, iolen)); -} - -static int -dev_iw_iovar_getbuf( - struct net_device *dev, - char *iovar, - void *param, - int paramlen, - void *bufptr, - int buflen) -{ - int iolen; - - iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen); - ASSERT(iolen); - - return (dev_wlc_ioctl(dev, WLC_GET_VAR, bufptr, buflen)); -} -#endif - - -#if WIRELESS_EXT > 17 -static int -dev_wlc_bufvar_set( - struct net_device *dev, - char *name, - char *buf, int len) -{ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) - char ioctlbuf[MAX_WLIW_IOCTL_LEN]; -#else - static char ioctlbuf[MAX_WLIW_IOCTL_LEN]; -#endif - uint buflen; - - buflen = bcm_mkiovar(name, buf, len, ioctlbuf, sizeof(ioctlbuf)); - ASSERT(buflen); - - return (dev_wlc_ioctl(dev, WLC_SET_VAR, ioctlbuf, buflen)); -} -#endif - - -static int -dev_wlc_bufvar_get( - struct net_device *dev, - char *name, - char *buf, int buflen) -{ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) - char ioctlbuf[MAX_WLIW_IOCTL_LEN]; -#else - static char ioctlbuf[MAX_WLIW_IOCTL_LEN]; -#endif - int error; - uint len; - - len = bcm_mkiovar(name, NULL, 0, ioctlbuf, sizeof(ioctlbuf)); - ASSERT(len); - error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)ioctlbuf, MAX_WLIW_IOCTL_LEN); - if (!error) - bcopy(ioctlbuf, buf, buflen); - - return (error); -} - - - -static int -dev_wlc_intvar_get( - struct net_device *dev, - char *name, - int *retval) -{ - union { - char buf[WLC_IOCTL_SMLEN]; - int val; - } var; - int error; - - uint len; - uint data_null; - - len = bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), sizeof(var.buf)); - ASSERT(len); - error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)&var, len); - - *retval = dtoh32(var.val); - - return (error); -} - - -#if WIRELESS_EXT > 12 -static int -wl_iw_set_active_scan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int as = 0; - int error = 0; - char *p = extra; - -#if defined(WL_IW_USE_ISCAN) - if (g_iscan->iscan_state == ISCAN_STATE_IDLE) -#endif - error = dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &as, sizeof(as)); -#if defined(WL_IW_USE_ISCAN) - else - g_iscan->scan_flag = as; -#endif - p += snprintf(p, MAX_WX_STRING, "OK"); - - wrqu->data.length = p - extra + 1; - return error; -} - -static int -wl_iw_set_passive_scan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int ps = 1; - int error = 0; - char *p = extra; - -#if defined(WL_IW_USE_ISCAN) - if (g_iscan->iscan_state == ISCAN_STATE_IDLE) { -#endif - - - if (g_scan_specified_ssid == 0) { - error = dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &ps, sizeof(ps)); - } -#if defined(WL_IW_USE_ISCAN) - } - else - g_iscan->scan_flag = ps; -#endif - - p += snprintf(p, MAX_WX_STRING, "OK"); - - wrqu->data.length = p - extra + 1; - return error; -} - - -static int -wl_iw_set_txpower( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = 0; - char *p = extra; - int txpower = -1; - - txpower = bcm_atoi(extra + strlen(TXPOWER_SET_CMD) + 1); - if ((txpower >= 0) && (txpower <= 127)) - { - txpower |= WL_TXPWR_OVERRIDE; - txpower = htod32(txpower); - - error = dev_wlc_intvar_set(dev, "qtxpower", txpower); - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_TRACE(("%s: set TXpower 0x%X is OK\n", __FUNCTION__, txpower)); - } else { - WL_ERROR(("%s: set tx power failed\n", __FUNCTION__)); - p += snprintf(p, MAX_WX_STRING, "FAIL"); - } - - wrqu->data.length = p - extra + 1; - return error; -} - -static int -wl_iw_get_macaddr( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error; - char buf[128]; - struct ether_addr *id; - char *p = extra; - - - strcpy(buf, "cur_etheraddr"); - error = dev_wlc_ioctl(dev, WLC_GET_VAR, buf, sizeof(buf)); - id = (struct ether_addr *) buf; - p += snprintf(p, MAX_WX_STRING, "Macaddr = %02X:%02X:%02X:%02X:%02X:%02X\n", - id->octet[0], id->octet[1], id->octet[2], - id->octet[3], id->octet[4], id->octet[5]); - wrqu->data.length = p - extra + 1; - - return error; -} - - - -static int -wl_iw_set_country( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - char country_code[WLC_CNTRY_BUF_SZ]; - int error = 0; - char *p = extra; - int country_offset; - int country_code_size; - wl_country_t cspec = {{0}, 0, {0}}; - char smbuf[WLC_IOCTL_SMLEN]; - scb_val_t scbval; - - cspec.rev = -1; - memset(country_code, 0, sizeof(country_code)); - memset(smbuf, 0, sizeof(smbuf)); - - - country_offset = strcspn(extra, " "); - country_code_size = strlen(extra) - country_offset; - - - if (country_offset != 0) { - strncpy(country_code, extra + country_offset +1, - MIN(country_code_size, sizeof(country_code))); - - - bzero(&scbval, sizeof(scb_val_t)); - if ((error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)))) { - WL_ERROR(("%s: set country failed due to Disassoc error\n", __FUNCTION__)); - goto exit_failed; - } - - memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ); - memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ); - - get_customized_country_code((char *)&cspec.country_abbrev, &cspec); - - - if ((error = dev_iw_iovar_setbuf(dev, "country", &cspec, - sizeof(cspec), smbuf, sizeof(smbuf))) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_ERROR(("%s: set country for %s as %s rev %d is OK\n", - __FUNCTION__, country_code, cspec.ccode, cspec.rev)); - dhd_bus_country_set(dev, &cspec); - goto exit; - } - } - - WL_ERROR(("%s: set country for %s as %s rev %d failed\n", - __FUNCTION__, country_code, cspec.ccode, cspec.rev)); - -exit_failed: - p += snprintf(p, MAX_WX_STRING, "FAIL"); - -exit: - wrqu->data.length = p - extra + 1; - return error; -} - -static int -wl_iw_set_power_mode( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = 0; - char *p = extra; - static int pm = PM_FAST; - int pm_local = PM_OFF; - char powermode_val = 0; - - WL_TRACE_COEX(("%s: DHCP session cmd:%s\n", __FUNCTION__, extra)); - - strncpy((char *)&powermode_val, extra + strlen("POWERMODE") +1, 1); - - if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) { - - WL_TRACE(("%s: DHCP session starts\n", __FUNCTION__)); - - dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm)); - dev_wlc_ioctl(dev, WLC_SET_PM, &pm_local, sizeof(pm_local)); - - - net_os_set_packet_filter(dev, 0); - -#ifdef COEX_DHCP - g_bt->ts_dhcp_start = JF2MS; - g_bt->dhcp_done = FALSE; - WL_TRACE_COEX(("%s: DHCP start, pm:%d changed to pm:%d\n", - __FUNCTION__, pm, pm_local)); - -#endif - } else if (strnicmp((char *)&powermode_val, "0", strlen("0")) == 0) { - - - dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)); - - - net_os_set_packet_filter(dev, 1); - -#ifdef COEX_DHCP - g_bt->dhcp_done = TRUE; - g_bt->ts_dhcp_ok = JF2MS; - WL_TRACE_COEX(("%s: DHCP done for:%d ms, restored pm:%d\n", - __FUNCTION__, (g_bt->ts_dhcp_ok - g_bt->ts_dhcp_start), pm)); -#endif - - } else { - WL_ERROR(("%s Unkwown yet power setting, ignored\n", - __FUNCTION__)); - } - - p += snprintf(p, MAX_WX_STRING, "OK"); - - wrqu->data.length = p - extra + 1; - - return error; -} - - -bool btcoex_is_sco_active(struct net_device *dev) -{ - int ioc_res = 0; - bool res = FALSE; - int sco_id_cnt = 0; - int param27; - int i; - - for (i = 0; i < 12; i++) { - - ioc_res = dev_wlc_intvar_get_reg(dev, "btc_params", 27, ¶m27); - - WL_TRACE_COEX(("%s, sample[%d], btc params: 27:%x\n", - __FUNCTION__, i, param27)); - - if (ioc_res < 0) { - WL_ERROR(("%s ioc read btc params error\n", __FUNCTION__)); - break; - } - - if ((param27 & 0x6) == 2) { - sco_id_cnt++; - } - - if (sco_id_cnt > 2) { - WL_TRACE_COEX(("%s, sco/esco detected, pkt id_cnt:%d samples:%d\n", - __FUNCTION__, sco_id_cnt, i)); - res = TRUE; - break; - } - - msleep(5); - } - - return res; -} - -#if defined(BT_DHCP_eSCO_FIX) - -static int set_btc_esco_params(struct net_device *dev, bool trump_sco) -{ - static bool saved_status = FALSE; - - char buf_reg50va_dhcp_on[8] = { 50, 00, 00, 00, 0x22, 0x80, 0x00, 0x00 }; - char buf_reg51va_dhcp_on[8] = { 51, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - char buf_reg64va_dhcp_on[8] = { 64, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - char buf_reg65va_dhcp_on[8] = { 65, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - char buf_reg71va_dhcp_on[8] = { 71, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - - uint32 regaddr; - static uint32 saved_reg50; - static uint32 saved_reg51; - static uint32 saved_reg64; - static uint32 saved_reg65; - static uint32 saved_reg71; - - if (trump_sco) { - - - WL_TRACE_COEX(("Do new SCO/eSCO coex algo {save & override} \n")); - - - if ((!dev_wlc_intvar_get_reg(dev, "btc_params", 50, &saved_reg50)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 51, &saved_reg51)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 64, &saved_reg64)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 65, &saved_reg65)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 71, &saved_reg71))) { - - saved_status = TRUE; - WL_TRACE_COEX(("%s saved bt_params[50,51,64,65,71]:" - " 0x%x 0x%x 0x%x 0x%x 0x%x\n", - __FUNCTION__, saved_reg50, saved_reg51, - saved_reg64, saved_reg65, saved_reg71)); - - } else { - WL_ERROR((":%s: save btc_params failed\n", - __FUNCTION__)); - saved_status = FALSE; - return -1; - } - - WL_TRACE_COEX(("override with [50,51,64,65,71]:" - " 0x%x 0x%x 0x%x 0x%x 0x%x\n", - *(u32 *)(buf_reg50va_dhcp_on+4), - *(u32 *)(buf_reg51va_dhcp_on+4), - *(u32 *)(buf_reg64va_dhcp_on+4), - *(u32 *)(buf_reg65va_dhcp_on+4), - *(u32 *)(buf_reg71va_dhcp_on+4))); - - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg50va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg51va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg64va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg65va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg71va_dhcp_on[0], 8); - - saved_status = TRUE; - - } else if (saved_status) { - - WL_TRACE_COEX(("Do new SCO/eSCO coex algo {save & override} \n")); - - regaddr = 50; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg50); - regaddr = 51; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg51); - regaddr = 64; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg64); - regaddr = 65; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg65); - regaddr = 71; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg71); - - WL_TRACE_COEX(("restore bt_params[50,51,64,65,71]: 0x%x 0x%x 0x%x 0x%x 0x%x\n", - saved_reg50, saved_reg51, saved_reg64, - saved_reg65, saved_reg71)); - - saved_status = FALSE; - } else { - WL_ERROR((":%s att to restore not saved BTCOEX params\n", - __FUNCTION__)); - return -1; - } - return 0; -} -#endif - - -static int -wl_iw_get_power_mode( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = 0; - int pm_local; - char *p = extra; - - error = dev_wlc_ioctl(dev, WLC_GET_PM, &pm_local, sizeof(pm_local)); - if (!error) { - WL_TRACE(("%s: Powermode = %d\n", __func__, pm_local)); - if (pm_local == PM_OFF) - pm_local = 1; - else - pm_local = 0; - p += snprintf(p, MAX_WX_STRING, "powermode = %d", pm_local); - } - else { - WL_TRACE(("%s: Error = %d\n", __func__, error)); - p += snprintf(p, MAX_WX_STRING, "FAIL"); - } - wrqu->data.length = p - extra + 1; - return error; -} - -static int -wl_iw_set_btcoex_dhcp( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = 0; - char *p = extra; - char powermode_val = 0; - char buf_reg66va_dhcp_on[8] = { 66, 00, 00, 00, 0x10, 0x27, 0x00, 0x00 }; - char buf_reg41va_dhcp_on[8] = { 41, 00, 00, 00, 0x33, 0x00, 0x00, 0x00 }; - char buf_reg68va_dhcp_on[8] = { 68, 00, 00, 00, 0x90, 0x01, 0x00, 0x00 }; - - uint32 regaddr; - static uint32 saved_reg66; - static uint32 saved_reg41; - static uint32 saved_reg68; - static bool saved_status = FALSE; - -#ifdef COEX_DHCP - char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00}; -#endif - - - strncpy((char *)&powermode_val, extra + strlen("BTCOEXMODE") +1, 1); - - if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) { - - WL_TRACE(("%s: DHCP session starts\n", __FUNCTION__)); - - - if ((saved_status == FALSE) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 66, &saved_reg66)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 41, &saved_reg41)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 68, &saved_reg68))) { - saved_status = TRUE; - WL_TRACE(("Saved 0x%x 0x%x 0x%x\n", - saved_reg66, saved_reg41, saved_reg68)); - - - - -#ifdef COEX_DHCP - - if (btcoex_is_sco_active(dev)) { - - dev_wlc_bufvar_set(dev, "btc_params", - (char *)&buf_reg66va_dhcp_on[0], - sizeof(buf_reg66va_dhcp_on)); - - dev_wlc_bufvar_set(dev, "btc_params", - (char *)&buf_reg41va_dhcp_on[0], - sizeof(buf_reg41va_dhcp_on)); - - dev_wlc_bufvar_set(dev, "btc_params", - (char *)&buf_reg68va_dhcp_on[0], - sizeof(buf_reg68va_dhcp_on)); - saved_status = TRUE; - - g_bt->bt_state = BT_DHCP_START; - g_bt->timer_on = 1; - mod_timer(&g_bt->timer, g_bt->timer.expires); - WL_TRACE_COEX(("%s enable BT DHCP Timer\n", - __FUNCTION__)); - } -#endif - } - else if (saved_status == TRUE) { - WL_ERROR(("%s was called w/o DHCP OFF. Continue\n", __FUNCTION__)); - } - } - else if (strnicmp((char *)&powermode_val, "2", strlen("2")) == 0) { - - - - -#ifdef COEX_DHCP - - WL_TRACE(("%s disable BT DHCP Timer\n", __FUNCTION__)); - if (g_bt->timer_on) { - g_bt->timer_on = 0; - del_timer_sync(&g_bt->timer); - - if (g_bt->bt_state != BT_DHCP_IDLE) { - - WL_TRACE_COEX(("%s bt->bt_state:%d\n", - __FUNCTION__, g_bt->bt_state)); - - up(&g_bt->tsk_ctl.sema); - } - } - - - if (saved_status == TRUE) - dev_wlc_bufvar_set(dev, "btc_flags", - (char *)&buf_flag7_default[0], sizeof(buf_flag7_default)); -#endif - - - if (saved_status == TRUE) { - regaddr = 66; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg66); - regaddr = 41; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg41); - regaddr = 68; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg68); - - WL_TRACE_COEX(("restore regs {66,41,68} <- 0x%x 0x%x 0x%x\n", - saved_reg66, saved_reg41, saved_reg68)); - } - saved_status = FALSE; - - } - else { - WL_ERROR(("%s Unkwown yet power setting, ignored\n", - __FUNCTION__)); - } - - p += snprintf(p, MAX_WX_STRING, "OK"); - - wrqu->data.length = p - extra + 1; - - return error; -} - -static int -wl_iw_set_suspend_opt( -struct net_device *dev, -struct iw_request_info *info, -union iwreq_data *wrqu, -char *extra -) -{ - int suspend_flag; - int ret_now; - int ret = 0; - - suspend_flag = *(extra + strlen(SETSUSPENDOPT_CMD) + 1) - '0'; - - if (suspend_flag != 0) - suspend_flag = 1; - - ret_now = net_os_set_suspend_disable(dev, suspend_flag); - - if (ret_now != suspend_flag) { - if (!(ret = net_os_set_suspend(dev, ret_now, 1))) - WL_ERROR(("%s: Suspend Flag %d -> %d\n", - __FUNCTION__, ret_now, suspend_flag)); - else - WL_ERROR(("%s: failed %d\n", __FUNCTION__, ret)); - } - - return ret; -} - -static int -wl_iw_set_suspend_mode( -struct net_device *dev, -struct iw_request_info *info, -union iwreq_data *wrqu, -char *extra -) -{ - int ret = 0; - -#if !defined(CONFIG_HAS_EARLYSUSPEND) || !defined(DHD_USE_EARLYSUSPEND) - int suspend_flag; - - suspend_flag = *(extra + strlen(SETSUSPENDMODE_CMD) + 1) - '0'; - - if (suspend_flag != 0) - suspend_flag = 1; - - if (!(ret = net_os_set_suspend(dev, suspend_flag, 0))) - WL_ERROR(("%s: Suspend Mode %d\n",__FUNCTION__,suspend_flag)); - else - WL_ERROR(("%s: failed %d\n", __FUNCTION__, ret)); -#endif - return ret; -} - -static int -wl_format_ssid(char* ssid_buf, uint8* ssid, int ssid_len) -{ - int i, c; - char *p = ssid_buf; - - if (ssid_len > 32) ssid_len = 32; - - for (i = 0; i < ssid_len; i++) { - c = (int)ssid[i]; - if (c == '\\') { - *p++ = '\\'; - *p++ = '\\'; - } else if (isprint((uchar)c)) { - *p++ = (char)c; - } else { - p += sprintf(p, "\\x%02X", c); - } - } - *p = '\0'; - - return p - ssid_buf; -} - -static int -wl_iw_get_link_speed( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = 0; - char *p = extra; - static int link_speed; - - - net_os_wake_lock(dev); - if (g_onoff == G_WLAN_SET_ON) { - error = dev_wlc_ioctl(dev, WLC_GET_RATE, &link_speed, sizeof(link_speed)); - link_speed *= 500000; - } - - p += snprintf(p, MAX_WX_STRING, "LinkSpeed %d", link_speed/1000000); - - wrqu->data.length = p - extra + 1; - - net_os_wake_unlock(dev); - return error; -} - - -static int -wl_iw_get_dtim_skip( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - char iovbuf[32]; - - net_os_wake_lock(dev); - if (g_onoff == G_WLAN_SET_ON) { - - memset(iovbuf, 0, sizeof(iovbuf)); - strcpy(iovbuf, "bcn_li_dtim"); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_VAR, - &iovbuf, sizeof(iovbuf))) >= 0) { - - p += snprintf(p, MAX_WX_STRING, "Dtim_skip %d", iovbuf[0]); - WL_TRACE(("%s: get dtim_skip = %d\n", __FUNCTION__, iovbuf[0])); - wrqu->data.length = p - extra + 1; - } - else - WL_ERROR(("%s: get dtim_skip failed code %d\n", - __FUNCTION__, error)); - } - net_os_wake_unlock(dev); - return error; -} - - -static int -wl_iw_set_dtim_skip( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - int bcn_li_dtim; - char iovbuf[32]; - - net_os_wake_lock(dev); - if (g_onoff == G_WLAN_SET_ON) { - - bcn_li_dtim = htod32((uint)*(extra + strlen(DTIM_SKIP_SET_CMD) + 1) - '0'); - - if ((bcn_li_dtim >= 0) || ((bcn_li_dtim <= 5))) { - - memset(iovbuf, 0, sizeof(iovbuf)); - bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim, - 4, iovbuf, sizeof(iovbuf)); - - if ((error = dev_wlc_ioctl(dev, WLC_SET_VAR, - &iovbuf, sizeof(iovbuf))) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - - - net_os_set_dtim_skip(dev, bcn_li_dtim); - - WL_TRACE(("%s: set dtim_skip %d OK\n", __FUNCTION__, - bcn_li_dtim)); - goto exit; - } - else WL_ERROR(("%s: set dtim_skip %d failed code %d\n", - __FUNCTION__, bcn_li_dtim, error)); - } - else WL_ERROR(("%s Incorrect dtim_skip setting %d, ignored\n", - __FUNCTION__, bcn_li_dtim)); - } - - p += snprintf(p, MAX_WX_STRING, "FAIL"); - -exit: - wrqu->data.length = p - extra + 1; - net_os_wake_unlock(dev); - return error; -} - - -static int -wl_iw_get_band( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - static int band; - - net_os_wake_lock(dev); - - if (g_onoff == G_WLAN_SET_ON) { - error = dev_wlc_ioctl(dev, WLC_GET_BAND, &band, sizeof(band)); - - p += snprintf(p, MAX_WX_STRING, "Band %d", band); - - wrqu->data.length = p - extra + 1; - } - - net_os_wake_unlock(dev); - return error; -} - - -static int -wl_iw_set_band( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - uint band; - - net_os_wake_lock(dev); - - if (g_onoff == G_WLAN_SET_ON) { - - band = htod32((uint)*(extra + strlen(BAND_SET_CMD) + 1) - '0'); - - if ((band == WLC_BAND_AUTO) || (band == WLC_BAND_5G) || (band == WLC_BAND_2G)) { - - if ((error = dev_wlc_ioctl(dev, WLC_SET_BAND, - &band, sizeof(band))) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_TRACE(("%s: set band %d OK\n", __FUNCTION__, band)); - goto exit; - } else { - WL_ERROR(("%s: set band %d failed code %d\n", __FUNCTION__, - band, error)); - } - } else { - WL_ERROR(("%s Incorrect band setting %d, ignored\n", __FUNCTION__, band)); - } - } - - p += snprintf(p, MAX_WX_STRING, "FAIL"); - -exit: - wrqu->data.length = p - extra + 1; - net_os_wake_unlock(dev); - return error; -} - -#ifdef PNO_SUPPORT - -static int -wl_iw_set_pno_reset( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - - net_os_wake_lock(dev); - if ((g_onoff == G_WLAN_SET_ON) && (dev != NULL)) { - - if ((error = dhd_dev_pno_reset(dev)) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_TRACE(("%s: set OK\n", __FUNCTION__)); - goto exit; - } - else WL_ERROR(("%s: failed code %d\n", __FUNCTION__, error)); - } - - p += snprintf(p, MAX_WX_STRING, "FAIL"); - -exit: - wrqu->data.length = p - extra + 1; - net_os_wake_unlock(dev); - return error; -} - - - -static int -wl_iw_set_pno_enable( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - int pfn_enabled; - - net_os_wake_lock(dev); - pfn_enabled = htod32((uint)*(extra + strlen(PNOENABLE_SET_CMD) + 1) - '0'); - - if ((g_onoff == G_WLAN_SET_ON) && (dev != NULL)) { - - if ((error = dhd_dev_pno_enable(dev, pfn_enabled)) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_TRACE(("%s: set OK\n", __FUNCTION__)); - goto exit; - } - else WL_ERROR(("%s: failed code %d\n", __FUNCTION__, error)); - } - - p += snprintf(p, MAX_WX_STRING, "FAIL"); - -exit: - wrqu->data.length = p - extra + 1; - net_os_wake_unlock(dev); - return error; -} - - - -static int -wl_iw_set_pno_set( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int res = -1; - wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT]; - int nssid = 0; - cmd_tlv_t *cmd_tlv_temp; - char *str_ptr; - int tlv_size_left; - int pno_time; - int pno_repeat; - int pno_freq_expo_max; -#ifdef PNO_SET_DEBUG - int i; - char pno_in_example[] = { - 'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ', - 'S', '1', '2', '0', - 'S', - 0x04, - 'B', 'R', 'C', 'M', - 'S', - 0x04, - 'G', 'O', 'O', 'G', - 'T', - '1', 'E', - 'R', - '2', - 'M', - '2', - 0x00 - }; -#endif - - net_os_wake_lock(dev); - WL_ERROR(("\n### %s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); - goto exit_proc; - } - - if (wrqu->data.length < (strlen(PNOSETUP_SET_CMD) + sizeof(cmd_tlv_t))) { - WL_ERROR(("%s argument=%d less %d\n", __FUNCTION__, - wrqu->data.length, (int)(strlen(PNOSETUP_SET_CMD) + sizeof(cmd_tlv_t)))); - goto exit_proc; - } - -#ifdef PNO_SET_DEBUG - if (!(extra = kmalloc(sizeof(pno_in_example) +100, GFP_KERNEL))) { - res = -ENOMEM; - goto exit_proc; - } - memcpy(extra, pno_in_example, sizeof(pno_in_example)); - wrqu->data.length = sizeof(pno_in_example); - for (i = 0; i < wrqu->data.length; i++) - printf("%02X ", extra[i]); - printf("\n"); -#endif - - str_ptr = extra; -#ifdef PNO_SET_DEBUG - str_ptr += strlen("PNOSETUP "); - tlv_size_left = wrqu->data.length - strlen("PNOSETUP "); -#else - str_ptr += strlen(PNOSETUP_SET_CMD); - tlv_size_left = wrqu->data.length - strlen(PNOSETUP_SET_CMD); -#endif - - cmd_tlv_temp = (cmd_tlv_t *)str_ptr; - memset(ssids_local, 0, sizeof(ssids_local)); - pno_repeat = pno_freq_expo_max = 0; - - if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) && - (cmd_tlv_temp->version == PNO_TLV_VERSION) && - (cmd_tlv_temp->subver == PNO_TLV_SUBVERSION)) - { - str_ptr += sizeof(cmd_tlv_t); - tlv_size_left -= sizeof(cmd_tlv_t); - - - if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local, - MAX_PFN_LIST_COUNT, - &tlv_size_left)) <= 0) { - WL_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid)); - goto exit_proc; - } - else { - if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) { - WL_ERROR(("%s scan duration corrupted field size %d\n", - __FUNCTION__, tlv_size_left)); - goto exit_proc; - } - str_ptr++; - pno_time = simple_strtoul(str_ptr, &str_ptr, 16); - WL_PNO(("%s: pno_time=%d\n", __FUNCTION__, pno_time)); - - - if (str_ptr[0] != 0) { - if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) { - WL_ERROR(("%s pno repeat : corrupted field\n", - __FUNCTION__)); - goto exit_proc; - } - str_ptr++; - pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16); - WL_PNO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat)); - if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) { - WL_ERROR(("%s FREQ_EXPO_MAX corrupted field size\n", - __FUNCTION__)); - goto exit_proc; - } - str_ptr++; - pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16); - WL_PNO(("%s: pno_freq_expo_max=%d\n", - __FUNCTION__, pno_freq_expo_max)); - } - } - } - else { - WL_ERROR(("%s get wrong TLV command\n", __FUNCTION__)); - goto exit_proc; - } - - - res = dhd_dev_pno_set(dev, ssids_local, nssid, pno_time, pno_repeat, pno_freq_expo_max); - -exit_proc: - net_os_wake_unlock(dev); - return res; -} - -static int -wl_iw_set_pno_setadd( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int ret = -1; - char *tmp_ptr; - int size, tmp_size; - - net_os_wake_lock(dev); - WL_ERROR(("\n### %s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); - goto exit_proc; - } - - if (wrqu->data.length <= strlen(PNOSETADD_SET_CMD) + sizeof(cmd_tlv_t)) { - WL_ERROR(("%s argument=%d less than %d\n", __FUNCTION__, - wrqu->data.length, (int)(strlen(PNOSETADD_SET_CMD) + sizeof(cmd_tlv_t)))); - goto exit_proc; - } - - - bcopy(PNOSETUP_SET_CMD, extra, strlen(PNOSETUP_SET_CMD)); - - tmp_ptr = extra + strlen(PNOSETUP_SET_CMD); - size = wrqu->data.length - strlen(PNOSETUP_SET_CMD); - tmp_size = size; - - while (*tmp_ptr && tmp_size > 0) { - if ((*tmp_ptr == 'S') && (size - tmp_size) >= sizeof(cmd_tlv_t)) { - *(tmp_ptr + 1) = ((*(tmp_ptr + 1) - '0') << 4) + (*(tmp_ptr + 2) - '0'); - memmove(tmp_ptr + 2, tmp_ptr + 3, tmp_size - 3); - tmp_size -= 2 + *(tmp_ptr + 1); - tmp_ptr += 2 + *(tmp_ptr + 1); - size--; - } else { - tmp_ptr++; - tmp_size--; - } - } - - wrqu->data.length = strlen(PNOSETUP_SET_CMD) + size; - ret = wl_iw_set_pno_set(dev, info, wrqu, extra); - -exit_proc: - net_os_wake_unlock(dev); - return ret; - -} -#endif - -static int -wl_iw_get_rssi( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - static int rssi = 0; - static wlc_ssid_t ssid = {0}; - int error = 0; - char *p = extra; - static char ssidbuf[SSID_FMT_BUF_LEN]; - scb_val_t scb_val; - - net_os_wake_lock(dev); - - bzero(&scb_val, sizeof(scb_val_t)); - - if (g_onoff == G_WLAN_SET_ON) { - error = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)); - if (error) { - WL_ERROR(("%s: Fails %d\n", __FUNCTION__, error)); - net_os_wake_unlock(dev); - return error; - } - rssi = dtoh32(scb_val.val); - - error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)); - if (!error) { - ssid.SSID_len = dtoh32(ssid.SSID_len); - wl_format_ssid(ssidbuf, ssid.SSID, dtoh32(ssid.SSID_len)); - } - } - - p += snprintf(p, MAX_WX_STRING, "%s rssi %d ", ssidbuf, rssi); - wrqu->data.length = p - extra + 1; - - net_os_wake_unlock(dev); - return error; -} - -int -wl_iw_send_priv_event( - struct net_device *dev, - char *flag -) -{ - union iwreq_data wrqu; - char extra[IW_CUSTOM_MAX + 1]; - int cmd; - - cmd = IWEVCUSTOM; - memset(&wrqu, 0, sizeof(wrqu)); - if (strlen(flag) > sizeof(extra)) - return -1; - - strcpy(extra, flag); - wrqu.data.length = strlen(extra); - wireless_send_event(dev, cmd, &wrqu, extra); - net_os_wake_lock_ctrl_timeout_enable(dev, DHD_EVENT_TIMEOUT_MS); - WL_TRACE(("Send IWEVCUSTOM Event as %s\n", extra)); - - return 0; -} - - -int -wl_control_wl_start(struct net_device *dev) -{ - wl_iw_t *iw; - int ret = 0; - - WL_TRACE(("Enter %s \n", __FUNCTION__)); - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -1; - } - - iw = *(wl_iw_t **)netdev_priv(dev); - - if (!iw) { - WL_ERROR(("%s: wl is null\n", __FUNCTION__)); - return -1; - } - - dhd_net_if_lock(dev); - - if (g_onoff == G_WLAN_SET_OFF) { - dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON); - -#if defined(BCMLXSDMMC) - sdioh_start(NULL, 0); -#endif - - ret = dhd_dev_reset(dev, 0); - -#if defined(BCMLXSDMMC) - sdioh_start(NULL, 1); -#endif - if (!ret) - dhd_dev_init_ioctl(dev); - - g_onoff = G_WLAN_SET_ON; - } - WL_TRACE(("Exited %s\n", __FUNCTION__)); - - dhd_net_if_unlock(dev); - return ret; -} - - -static int -wl_iw_control_wl_off( - struct net_device *dev, - struct iw_request_info *info -) -{ - wl_iw_t *iw; - int ret = 0; - - WL_TRACE(("Enter %s\n", __FUNCTION__)); - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -1; - } - - iw = *(wl_iw_t **)netdev_priv(dev); - - if (!iw) { - WL_ERROR(("%s: wl is null\n", __FUNCTION__)); - return -1; - } - - dhd_net_if_lock(dev); - -#ifdef SOFTAP - ap_cfg_running = FALSE; -#endif - - if (g_onoff == G_WLAN_SET_ON) { - g_onoff = G_WLAN_SET_OFF; - -#if defined(WL_IW_USE_ISCAN) - g_iscan->iscan_state = ISCAN_STATE_IDLE; -#endif - - ret = dhd_dev_reset(dev, 1); - -#if defined(WL_IW_USE_ISCAN) -#if !defined(CSCAN) - - wl_iw_free_ss_cache(); - wl_iw_run_ss_cache_timer(0); - - g_ss_cache_ctrl.m_link_down = 1; -#endif - memset(g_scan, 0, G_SCAN_RESULTS); - g_scan_specified_ssid = 0; -#if defined(CONFIG_FIRST_SCAN) - - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_IDLE; - g_first_counter_scans = 0; -#endif -#endif - -#if defined(BCMLXSDMMC) - sdioh_stop(NULL); -#endif - - dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); - - wl_iw_send_priv_event(dev, "STOP"); - } - - dhd_net_if_unlock(dev); - - WL_TRACE(("Exited %s\n", __FUNCTION__)); - - return ret; -} - -static int -wl_iw_control_wl_on( - struct net_device *dev, - struct iw_request_info *info -) -{ - int ret = 0; - - WL_TRACE(("Enter %s \n", __FUNCTION__)); - - ret = wl_control_wl_start(dev); - - wl_iw_send_priv_event(dev, "START"); - -#ifdef SOFTAP - if (!ap_fw_loaded) { - wl_iw_iscan_set_scan_broadcast_prep(dev, 0); - } -#else - wl_iw_iscan_set_scan_broadcast_prep(dev, 0); -#endif - - WL_TRACE(("Exited %s\n", __FUNCTION__)); - - return ret; -} - -#ifdef SOFTAP -static struct ap_profile my_ap; -static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap); -static int get_assoc_sta_list(struct net_device *dev, char *buf, int len); -static int set_ap_mac_list(struct net_device *dev, void *buf); - -#define PTYPE_STRING 0 -#define PTYPE_INTDEC 1 -#define PTYPE_INTHEX 2 -#define PTYPE_STR_HEX 3 - -static int get_parameter_from_string( - char **str_ptr, const char *token, int param_type, void *dst, int param_max_len); - -static int -hex2num(char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - return -1; -} - - - -static int -hstr_2_buf(const char *txt, u8 *buf, int len) -{ - int i; - - for (i = 0; i < len; i++) { - int a, b; - - a = hex2num(*txt++); - if (a < 0) - return -1; - b = hex2num(*txt++); - if (b < 0) - return -1; - *buf++ = (a << 4) | b; - } - - return 0; -} - - - -static int -init_ap_profile_from_string(char *param_str, struct ap_profile *ap_cfg) -{ - char *str_ptr = param_str; - char sub_cmd[16]; - int ret = 0; - - memset(sub_cmd, 0, sizeof(sub_cmd)); - memset(ap_cfg, 0, sizeof(struct ap_profile)); - - - if (get_parameter_from_string(&str_ptr, "ASCII_CMD=", - PTYPE_STRING, sub_cmd, SSID_LEN) != 0) { - return -1; - } - if (strncmp(sub_cmd, "AP_CFG", 6)) { - WL_ERROR(("ERROR: sub_cmd:%s != 'AP_CFG'!\n", sub_cmd)); - return -1; - } - - - - ret = get_parameter_from_string(&str_ptr, "SSID=", PTYPE_STRING, ap_cfg->ssid, SSID_LEN); - - ret |= get_parameter_from_string(&str_ptr, "SEC=", PTYPE_STRING, ap_cfg->sec, SEC_LEN); - - ret |= get_parameter_from_string(&str_ptr, "KEY=", PTYPE_STRING, ap_cfg->key, KEY_LEN); - - ret |= get_parameter_from_string(&str_ptr, "CHANNEL=", PTYPE_INTDEC, &ap_cfg->channel, 5); - - - get_parameter_from_string(&str_ptr, "PREAMBLE=", PTYPE_INTDEC, &ap_cfg->preamble, 5); - - - get_parameter_from_string(&str_ptr, "MAX_SCB=", PTYPE_INTDEC, &ap_cfg->max_scb, 5); - - - get_parameter_from_string(&str_ptr, "HIDDEN=", - PTYPE_INTDEC, &ap_cfg->closednet, 5); - - - get_parameter_from_string(&str_ptr, "COUNTRY=", - PTYPE_STRING, &ap_cfg->country_code, 3); - - return ret; -} -#endif - - - -#ifdef SOFTAP -static int -iwpriv_set_ap_config(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int res = 0; - char *extra = NULL; - struct ap_profile *ap_cfg = &my_ap; - - WL_TRACE(("> Got IWPRIV SET_AP IOCTL: info->cmd:%x, info->flags:%x, u.data:%p, u.len:%d\n", - info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (!ap_fw_loaded) { - WL_ERROR(("Can't execute %s(), SOFTAP fw is not Loaded\n", - __FUNCTION__)); - return -1; - } - - if (wrqu->data.length != 0) { - - char *str_ptr; - - if (!(extra = kmalloc(wrqu->data.length+1, GFP_KERNEL))) - return -ENOMEM; - - if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) { - kfree(extra); - return -EFAULT; - } - - extra[wrqu->data.length] = 0; - WL_SOFTAP((" Got str param in iw_point:\n %s\n", extra)); - - memset(ap_cfg, 0, sizeof(struct ap_profile)); - - - - str_ptr = extra; - - if ((res = init_ap_profile_from_string(extra, ap_cfg)) < 0) { - WL_ERROR(("%s failed to parse %d\n", __FUNCTION__, res)); - kfree(extra); - return -1; - } - - } else { - - WL_ERROR(("IWPRIV argument len = 0 \n")); - return -1; - } - - if ((res = set_ap_cfg(dev, ap_cfg)) < 0) - WL_ERROR(("%s failed to set_ap_cfg %d\n", __FUNCTION__, res)); - - kfree(extra); - - return res; -} -#endif - - - -#ifdef SOFTAP -static int iwpriv_get_assoc_list(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *p_iwrq, - char *extra) -{ - int i, ret = 0; - char mac_buf[256]; - struct maclist *sta_maclist = (struct maclist *)mac_buf; - - char mac_lst[384]; - char *p_mac_str; - char *p_mac_str_end; - wl_iw_t *iw; - - if ((!dev) || (!extra)) { - - return -EINVAL; - } - - - iw = *(wl_iw_t **)netdev_priv(dev); - - net_os_wake_lock(dev); - DHD_OS_MUTEX_LOCK(&wl_softap_lock); - - WL_TRACE(("\n %s: IWPRIV IOCTL: cmd:%hx, flags:%hx, extra:%p, iwp.len:%d," - "iwp.len:%p, iwp.flags:%x \n", __FUNCTION__, info->cmd, info->flags, - extra, p_iwrq->data.length, p_iwrq->data.pointer, p_iwrq->data.flags)); - - - memset(sta_maclist, 0, sizeof(mac_buf)); - - sta_maclist->count = 8; - - WL_SOFTAP(("%s: net device:%s, buf_sz:%d\n", - __FUNCTION__, dev->name, sizeof(mac_buf))); - - if ((ret = get_assoc_sta_list(dev, mac_buf, sizeof(mac_buf))) < 0) { - WL_ERROR(("%s: sta list ioctl error:%d\n", - __FUNCTION__, ret)); - goto func_exit; - } - - WL_SOFTAP(("%s: got %d stations\n", __FUNCTION__, - sta_maclist->count)); - - - - memset(mac_lst, 0, sizeof(mac_lst)); - p_mac_str = mac_lst; - p_mac_str_end = &mac_lst[sizeof(mac_lst)-1]; - - for (i = 0; i < 8; i++) { - struct ether_addr * id = &sta_maclist->ea[i]; - if (!ETHER_ISNULLADDR(id->octet)) { - scb_val_t scb_val; - int rssi = 0; - bzero(&scb_val, sizeof(scb_val_t)); - - - if ((p_mac_str_end - p_mac_str) <= 36) { - WL_ERROR(("%s: mac list buf is < 36 for item[%i] item\n", - __FUNCTION__, i)); - break; - } - - p_mac_str += snprintf(p_mac_str, MAX_WX_STRING, - "\nMac[%d]=%02X:%02X:%02X:%02X:%02X:%02X,", i, - id->octet[0], id->octet[1], id->octet[2], - id->octet[3], id->octet[4], id->octet[5]); - - - bcopy(id->octet, &scb_val.ea, 6); - ret = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)); - if (ret < 0) { - snprintf(p_mac_str, MAX_WX_STRING, "RSSI:ERR"); - WL_ERROR(("%s: RSSI ioctl error:%d\n", - __FUNCTION__, ret)); - break; - } - - rssi = dtoh32(scb_val.val); - p_mac_str += snprintf(p_mac_str, MAX_WX_STRING, - "RSSI:%d", rssi); - } - } - - p_iwrq->data.length = strlen(mac_lst)+1; - - WL_SOFTAP(("%s: data to user:\n%s\n usr_ptr:%p\n", __FUNCTION__, - mac_lst, p_iwrq->data.pointer)); - - if (p_iwrq->data.length) { - bcopy(mac_lst, extra, p_iwrq->data.length); - } - -func_exit: - - DHD_OS_MUTEX_UNLOCK(&wl_softap_lock); - net_os_wake_unlock(dev); - - WL_SOFTAP(("%s: Exited\n", __FUNCTION__)); - return ret; -} -#endif - - -#ifdef SOFTAP - -#define MAC_FILT_MAX 8 -static int iwpriv_set_mac_filters(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int i, ret = -1; - char * extra = NULL; - int mac_cnt = 0; - int mac_mode = 0; - struct ether_addr *p_ea; - struct mac_list_set mflist_set; - - WL_SOFTAP((">>> Got IWPRIV SET_MAC_FILTER IOCTL: info->cmd:%x," - "info->flags:%x, u.data:%p, u.len:%d\n", - info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (wrqu->data.length != 0) { - - char *str_ptr; - - if (!(extra = kmalloc(wrqu->data.length+1, GFP_KERNEL))) - return -ENOMEM; - - if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) { - kfree(extra); - return -EFAULT; - } - - extra[wrqu->data.length] = 0; - WL_SOFTAP((" Got parameter string in iw_point:\n %s \n", extra)); - - memset(&mflist_set, 0, sizeof(mflist_set)); - - - str_ptr = extra; - - - - if (get_parameter_from_string(&str_ptr, "MAC_MODE=", - PTYPE_INTDEC, &mac_mode, 4) != 0) { - WL_ERROR(("ERROR: 'MAC_MODE=' token is missing\n")); - goto exit_proc; - } - - p_ea = &mflist_set.mac_list.ea[0]; - - if (get_parameter_from_string(&str_ptr, "MAC_CNT=", - PTYPE_INTDEC, &mac_cnt, 4) != 0) { - WL_ERROR(("ERROR: 'MAC_CNT=' token param is missing \n")); - goto exit_proc; - } - - if (mac_cnt > MAC_FILT_MAX) { - WL_ERROR(("ERROR: number of MAC filters > MAX\n")); - goto exit_proc; - } - - for (i=0; i< mac_cnt; i++) - if (get_parameter_from_string(&str_ptr, "MAC=", - PTYPE_STR_HEX, &p_ea[i], 12) != 0) { - WL_ERROR(("ERROR: MAC_filter[%d] is missing !\n", i)); - goto exit_proc; - } - - WL_SOFTAP(("MAC_MODE=:%d, MAC_CNT=%d, MACs:..\n", mac_mode, mac_cnt)); - for (i = 0; i < mac_cnt; i++) { - WL_SOFTAP(("mac_filt[%d]:", i)); - dhd_print_buf(&p_ea[i], 6, 0); - } - - - mflist_set.mode = mac_mode; - mflist_set.mac_list.count = mac_cnt; - set_ap_mac_list(dev, &mflist_set); - - - wrqu->data.pointer = NULL; - wrqu->data.length = 0; - ret = 0; - - } else { - - WL_ERROR(("IWPRIV argument len is 0\n")); - return -1; - } - - exit_proc: - kfree(extra); - return ret; -} -#endif - - -#ifdef SOFTAP - -static int iwpriv_set_ap_sta_disassoc(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int res = 0; - char sta_mac[6] = {0, 0, 0, 0, 0, 0}; - char cmd_buf[256]; - char *str_ptr = cmd_buf; - - WL_SOFTAP((">>%s called\n args: info->cmd:%x," - " info->flags:%x, u.data.p:%p, u.data.len:%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (wrqu->data.length != 0) { - - if (copy_from_user(cmd_buf, wrqu->data.pointer, wrqu->data.length)) { - return -EFAULT; - } - - if (get_parameter_from_string(&str_ptr, - "MAC=", PTYPE_STR_HEX, sta_mac, 12) == 0) { - res = wl_iw_softap_deassoc_stations(dev, sta_mac); - } else { - WL_ERROR(("ERROR: STA_MAC= token not found\n")); - } - } - - return res; -} -#endif - -#endif - -#if WIRELESS_EXT < 13 -struct iw_request_info -{ - __u16 cmd; - __u16 flags; -}; - -typedef int (*iw_handler)(struct net_device *dev, - struct iw_request_info *info, - void *wrqu, - char *extra); -#endif - -static int -wl_iw_config_commit( - struct net_device *dev, - struct iw_request_info *info, - void *zwrq, - char *extra -) -{ - wlc_ssid_t ssid; - int error; - struct sockaddr bssid; - - WL_TRACE(("%s: SIOCSIWCOMMIT\n", dev->name)); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)))) - return error; - - ssid.SSID_len = dtoh32(ssid.SSID_len); - - if (!ssid.SSID_len) - return 0; - - bzero(&bssid, sizeof(struct sockaddr)); - if ((error = dev_wlc_ioctl(dev, WLC_REASSOC, &bssid, ETHER_ADDR_LEN))) { - WL_ERROR(("%s: WLC_REASSOC to %s failed \n", __FUNCTION__, ssid.SSID)); - return error; - } - - return 0; -} - -static int -wl_iw_get_name( - struct net_device *dev, - struct iw_request_info *info, - char *cwrq, - char *extra -) -{ - WL_TRACE(("%s: SIOCGIWNAME\n", dev->name)); - - strcpy(cwrq, "IEEE 802.11-DS"); - - return 0; -} - -static int -wl_iw_set_freq( - struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *fwrq, - char *extra -) -{ - int error, chan; - uint sf = 0; - - WL_TRACE(("%s %s: SIOCSIWFREQ\n", __FUNCTION__, dev->name)); - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_TRACE(("%s:>> not executed, 'SOFT_AP is active' \n", __FUNCTION__)); - return 0; - } -#endif - - - if (fwrq->e == 0 && fwrq->m < MAXCHANNEL) { - chan = fwrq->m; - } - - else { - - if (fwrq->e >= 6) { - fwrq->e -= 6; - while (fwrq->e--) - fwrq->m *= 10; - } else if (fwrq->e < 6) { - while (fwrq->e++ < 6) - fwrq->m /= 10; - } - - if (fwrq->m > 4000 && fwrq->m < 5000) - sf = WF_CHAN_FACTOR_4_G; - - chan = wf_mhz2channel(fwrq->m, sf); - } - - chan = htod32(chan); - - if ((error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan)))) - return error; - - g_wl_iw_params.target_channel = chan; - - - return -EINPROGRESS; -} - -static int -wl_iw_get_freq( - struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *fwrq, - char *extra -) -{ - channel_info_t ci; - int error; - - WL_TRACE(("%s: SIOCGIWFREQ\n", dev->name)); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)))) - return error; - - - fwrq->m = dtoh32(ci.hw_channel); - fwrq->e = dtoh32(0); - return 0; -} - -static int -wl_iw_set_mode( - struct net_device *dev, - struct iw_request_info *info, - __u32 *uwrq, - char *extra -) -{ - int infra = 0, ap = 0, error = 0; - - WL_TRACE(("%s: SIOCSIWMODE\n", dev->name)); - - switch (*uwrq) { - case IW_MODE_MASTER: - infra = ap = 1; - break; - case IW_MODE_ADHOC: - case IW_MODE_AUTO: - break; - case IW_MODE_INFRA: - infra = 1; - break; - default: - return -EINVAL; - } - infra = htod32(infra); - ap = htod32(ap); - - if ((error = dev_wlc_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(infra))) || - (error = dev_wlc_ioctl(dev, WLC_SET_AP, &ap, sizeof(ap)))) - return error; - - - return -EINPROGRESS; -} - -static int -wl_iw_get_mode( - struct net_device *dev, - struct iw_request_info *info, - __u32 *uwrq, - char *extra -) -{ - int error, infra = 0, ap = 0; - - WL_TRACE(("%s: SIOCGIWMODE\n", dev->name)); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra))) || - (error = dev_wlc_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap)))) - return error; - - infra = dtoh32(infra); - ap = dtoh32(ap); - *uwrq = infra ? ap ? IW_MODE_MASTER : IW_MODE_INFRA : IW_MODE_ADHOC; - - return 0; -} - -static int -wl_iw_get_range( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - struct iw_range *range = (struct iw_range *) extra; - wl_uint32_list_t *list; - wl_rateset_t rateset; - int8 *channels; - int error, i, k; - uint sf, ch; - - int phytype; - int bw_cap = 0, sgi_tx = 0, nmode = 0; - channel_info_t ci; - uint8 nrate_list2copy = 0; - uint16 nrate_list[4][8] = { {13, 26, 39, 52, 78, 104, 117, 130}, - {14, 29, 43, 58, 87, 116, 130, 144}, - {27, 54, 81, 108, 162, 216, 243, 270}, - {30, 60, 90, 120, 180, 240, 270, 300}}; - - WL_TRACE(("%s: SIOCGIWRANGE\n", dev->name)); - - if (!extra) - return -EINVAL; - - channels = kmalloc((MAXCHANNEL+1)*4, GFP_KERNEL); - if (!channels) { - WL_ERROR(("Could not alloc channels\n")); - return -ENOMEM; - } - list = (wl_uint32_list_t *)channels; - - dwrq->length = sizeof(struct iw_range); - memset(range, 0, sizeof(*range)); - - - range->min_nwid = range->max_nwid = 0; - - - list->count = htod32(MAXCHANNEL); - if ((error = dev_wlc_ioctl(dev, WLC_GET_VALID_CHANNELS, channels, (MAXCHANNEL+1)*4))) { - kfree(channels); - return error; - } - for (i = 0; i < dtoh32(list->count) && i < IW_MAX_FREQUENCIES; i++) { - range->freq[i].i = dtoh32(list->element[i]); - - ch = dtoh32(list->element[i]); - if (ch <= CH_MAX_2G_CHANNEL) - sf = WF_CHAN_FACTOR_2_4_G; - else - sf = WF_CHAN_FACTOR_5_G; - - range->freq[i].m = wf_channel2mhz(ch, sf); - range->freq[i].e = 6; - } - range->num_frequency = range->num_channels = i; - - - range->max_qual.qual = 5; - - range->max_qual.level = 0x100 - 200; - - range->max_qual.noise = 0x100 - 200; - - range->sensitivity = 65535; - -#if WIRELESS_EXT > 11 - - range->avg_qual.qual = 3; - - range->avg_qual.level = 0x100 + WL_IW_RSSI_GOOD; - - range->avg_qual.noise = 0x100 - 75; -#endif - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset)))) { - kfree(channels); - return error; - } - rateset.count = dtoh32(rateset.count); - range->num_bitrates = rateset.count; - for (i = 0; i < rateset.count && i < IW_MAX_BITRATES; i++) - range->bitrate[i] = (rateset.rates[i]& 0x7f) * 500000; - dev_wlc_intvar_get(dev, "nmode", &nmode); - dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &phytype, sizeof(phytype)); - - if (nmode == 1 && phytype == WLC_PHY_TYPE_SSN) { - dev_wlc_intvar_get(dev, "mimo_bw_cap", &bw_cap); - dev_wlc_intvar_get(dev, "sgi_tx", &sgi_tx); - dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t)); - ci.hw_channel = dtoh32(ci.hw_channel); - - if (bw_cap == 0 || - (bw_cap == 2 && ci.hw_channel <= 14)) { - if (sgi_tx == 0) - nrate_list2copy = 0; - else - nrate_list2copy = 1; - } - if (bw_cap == 1 || - (bw_cap == 2 && ci.hw_channel >= 36)) { - if (sgi_tx == 0) - nrate_list2copy = 2; - else - nrate_list2copy = 3; - } - range->num_bitrates += 8; - for (k = 0; i < range->num_bitrates; k++, i++) { - - range->bitrate[i] = (nrate_list[nrate_list2copy][k]) * 500000; - } - } - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &i, sizeof(i)))) { - kfree(channels); - return error; - } - i = dtoh32(i); - if (i == WLC_PHY_TYPE_A) - range->throughput = 24000000; - else - range->throughput = 1500000; - - - range->min_rts = 0; - range->max_rts = 2347; - range->min_frag = 256; - range->max_frag = 2346; - - range->max_encoding_tokens = DOT11_MAX_DEFAULT_KEYS; - range->num_encoding_sizes = 4; - range->encoding_size[0] = WEP1_KEY_SIZE; - range->encoding_size[1] = WEP128_KEY_SIZE; -#if WIRELESS_EXT > 17 - range->encoding_size[2] = TKIP_KEY_SIZE; -#else - range->encoding_size[2] = 0; -#endif - range->encoding_size[3] = AES_KEY_SIZE; - - - range->min_pmp = 0; - range->max_pmp = 0; - range->min_pmt = 0; - range->max_pmt = 0; - range->pmp_flags = 0; - range->pm_capa = 0; - - - range->num_txpower = 2; - range->txpower[0] = 1; - range->txpower[1] = 255; - range->txpower_capa = IW_TXPOW_MWATT; - -#if WIRELESS_EXT > 10 - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 19; - - - range->retry_capa = IW_RETRY_LIMIT; - range->retry_flags = IW_RETRY_LIMIT; - range->r_time_flags = 0; - - range->min_retry = 1; - range->max_retry = 255; - - range->min_r_time = 0; - range->max_r_time = 0; -#endif - -#if WIRELESS_EXT > 17 - range->enc_capa = IW_ENC_CAPA_WPA; - range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP; - range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP; - range->enc_capa |= IW_ENC_CAPA_WPA2; - - - IW_EVENT_CAPA_SET_KERNEL(range->event_capa); - - IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP); - IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN); - IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP); - IW_EVENT_CAPA_SET(range->event_capa, IWEVMICHAELMICFAILURE); - IW_EVENT_CAPA_SET(range->event_capa, IWEVASSOCREQIE); - IW_EVENT_CAPA_SET(range->event_capa, IWEVASSOCRESPIE); - IW_EVENT_CAPA_SET(range->event_capa, IWEVPMKIDCAND); -#endif - - kfree(channels); - - return 0; -} - -static int -rssi_to_qual(int rssi) -{ - if (rssi <= WL_IW_RSSI_NO_SIGNAL) - return 0; - else if (rssi <= WL_IW_RSSI_VERY_LOW) - return 1; - else if (rssi <= WL_IW_RSSI_LOW) - return 2; - else if (rssi <= WL_IW_RSSI_GOOD) - return 3; - else if (rssi <= WL_IW_RSSI_VERY_GOOD) - return 4; - else - return 5; -} - -static int -wl_iw_set_spy( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_iw_t *iw = NETDEV_PRIV(dev); - struct sockaddr *addr = (struct sockaddr *) extra; - int i; - - WL_TRACE(("%s: SIOCSIWSPY\n", dev->name)); - - if (!extra) - return -EINVAL; - - iw->spy_num = MIN(ARRAYSIZE(iw->spy_addr), dwrq->length); - for (i = 0; i < iw->spy_num; i++) - memcpy(&iw->spy_addr[i], addr[i].sa_data, ETHER_ADDR_LEN); - memset(iw->spy_qual, 0, sizeof(iw->spy_qual)); - - return 0; -} - -static int -wl_iw_get_spy( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_iw_t *iw = NETDEV_PRIV(dev); - struct sockaddr *addr = (struct sockaddr *) extra; - struct iw_quality *qual = (struct iw_quality *) &addr[iw->spy_num]; - int i; - - WL_TRACE(("%s: SIOCGIWSPY\n", dev->name)); - - if (!extra) - return -EINVAL; - - dwrq->length = iw->spy_num; - for (i = 0; i < iw->spy_num; i++) { - memcpy(addr[i].sa_data, &iw->spy_addr[i], ETHER_ADDR_LEN); - addr[i].sa_family = AF_UNIX; - memcpy(&qual[i], &iw->spy_qual[i], sizeof(struct iw_quality)); - iw->spy_qual[i].updated = 0; - } - - return 0; -} - - -static int -wl_iw_ch_to_chanspec(int ch, wl_join_params_t *join_params, int *join_params_size) -{ - chanspec_t chanspec = 0; - - if (ch != 0) { - - join_params->params.chanspec_num = 1; - join_params->params.chanspec_list[0] = ch; - - if (join_params->params.chanspec_list[0]) - chanspec |= WL_CHANSPEC_BAND_2G; - else - chanspec |= WL_CHANSPEC_BAND_5G; - - chanspec |= WL_CHANSPEC_BW_20; - chanspec |= WL_CHANSPEC_CTL_SB_NONE; - - - *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE + - join_params->params.chanspec_num * sizeof(chanspec_t); - - - join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK; - join_params->params.chanspec_list[0] |= chanspec; - join_params->params.chanspec_list[0] = - htodchanspec(join_params->params.chanspec_list[0]); - - join_params->params.chanspec_num = htod32(join_params->params.chanspec_num); - - WL_TRACE(("%s join_params->params.chanspec_list[0]= %X\n", - __FUNCTION__, join_params->params.chanspec_list[0])); - } - return 1; -} - -static int -wl_iw_set_wap( - struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *awrq, - char *extra -) -{ - int error = -EINVAL; - wl_join_params_t join_params; - int join_params_size; - - WL_TRACE(("%s: SIOCSIWAP\n", dev->name)); - - if (awrq->sa_family != ARPHRD_ETHER) { - WL_ERROR(("Invalid Header...sa_family\n")); - return -EINVAL; - } - - - if (ETHER_ISBCAST(awrq->sa_data) || ETHER_ISNULLADDR(awrq->sa_data)) { - scb_val_t scbval; - - bzero(&scbval, sizeof(scb_val_t)); - - (void) dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)); - return 0; - } - - - - memset(&join_params, 0, sizeof(join_params)); - join_params_size = sizeof(join_params.ssid); - - memcpy(join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); - join_params.ssid.SSID_len = htod32(g_ssid.SSID_len); - memcpy(&join_params.params.bssid, awrq->sa_data, ETHER_ADDR_LEN); - - - - WL_TRACE(("%s target_channel=%d\n", __FUNCTION__, g_wl_iw_params.target_channel)); - wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params, &join_params_size); - - if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size))) { - WL_ERROR(("%s Invalid ioctl data=%d\n", __FUNCTION__, error)); - return error; - } - - if (g_ssid.SSID_len) { - WL_TRACE(("%s: join SSID=%s BSSID="MACSTR" ch=%d\n", __FUNCTION__, - g_ssid.SSID, MAC2STR((u8 *)awrq->sa_data), - g_wl_iw_params.target_channel)); - } - - - memset(&g_ssid, 0, sizeof(g_ssid)); - return 0; -} - -static int -wl_iw_get_wap( - struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *awrq, - char *extra -) -{ - WL_TRACE(("%s: SIOCGIWAP\n", dev->name)); - - awrq->sa_family = ARPHRD_ETHER; - memset(awrq->sa_data, 0, ETHER_ADDR_LEN); - - - (void) dev_wlc_ioctl(dev, WLC_GET_BSSID, awrq->sa_data, ETHER_ADDR_LEN); - - return 0; -} - -#if WIRELESS_EXT > 17 -static int -wl_iw_mlme( - struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *awrq, - char *extra -) -{ - struct iw_mlme *mlme; - scb_val_t scbval; - int error = -EINVAL; - - WL_TRACE(("%s: SIOCSIWMLME DISASSOC/DEAUTH\n", dev->name)); - - mlme = (struct iw_mlme *)extra; - if (mlme == NULL) { - WL_ERROR(("Invalid ioctl data.\n")); - return error; - } - - scbval.val = mlme->reason_code; - bcopy(&mlme->addr.sa_data, &scbval.ea, ETHER_ADDR_LEN); - - if (mlme->cmd == IW_MLME_DISASSOC) { - scbval.val = htod32(scbval.val); - error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)); - } - else if (mlme->cmd == IW_MLME_DEAUTH) { - scbval.val = htod32(scbval.val); - error = dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval, - sizeof(scb_val_t)); - } - else { - WL_ERROR(("Invalid ioctl data.\n")); - return error; - } - - return error; -} -#endif - -#ifndef WL_IW_USE_ISCAN -static int -wl_iw_get_aplist( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_scan_results_t *list; - struct sockaddr *addr = (struct sockaddr *) extra; - struct iw_quality qual[IW_MAX_AP]; - wl_bss_info_t *bi = NULL; - int error, i; - uint buflen = dwrq->length; - - WL_TRACE(("%s: SIOCGIWAPLIST\n", dev->name)); - - if (!extra) - return -EINVAL; - - - list = kmalloc(buflen, GFP_KERNEL); - if (!list) - return -ENOMEM; - memset(list, 0, buflen); - list->buflen = htod32(buflen); - if ((error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen))) { - WL_ERROR(("%d: Scan results error %d\n", __LINE__, error)); - kfree(list); - return error; - } - list->buflen = dtoh32(list->buflen); - list->version = dtoh32(list->version); - list->count = dtoh32(list->count); - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, list->version)); - kfree(list); - return -EINVAL; - } - - for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) { - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; - ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list + - buflen)); - - - if (!(dtoh16(bi->capability) & DOT11_CAP_ESS)) - continue; - - - memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN); - addr[dwrq->length].sa_family = ARPHRD_ETHER; - qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI)); - qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI); - qual[dwrq->length].noise = 0x100 + bi->phy_noise; - - -#if WIRELESS_EXT > 18 - qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; -#else - qual[dwrq->length].updated = 7; -#endif - - dwrq->length++; - } - - kfree(list); - - if (dwrq->length) { - memcpy(&addr[dwrq->length], qual, sizeof(struct iw_quality) * dwrq->length); - - dwrq->flags = 1; - } - - return 0; -} -#endif - -#ifdef WL_IW_USE_ISCAN -static int -wl_iw_iscan_get_aplist( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_scan_results_t *list; - iscan_buf_t * buf; - iscan_info_t *iscan = g_iscan; - - struct sockaddr *addr = (struct sockaddr *) extra; - struct iw_quality qual[IW_MAX_AP]; - wl_bss_info_t *bi = NULL; - int i; - - WL_TRACE(("%s: SIOCGIWAPLIST\n", dev->name)); - - if (!extra) - return -EINVAL; - - if ((!iscan) || (iscan->tsk_ctl.thr_pid < 0)) { - WL_ERROR(("%s error\n", __FUNCTION__)); - return 0; - } - - buf = iscan->list_hdr; - - while (buf) { - list = &((wl_iscan_results_t*)buf->iscan_buf)->results; - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, list->version)); - return -EINVAL; - } - - bi = NULL; - for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) { - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) - : list->bss_info; - ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list + - WLC_IW_ISCAN_MAXLEN)); - - - if (!(dtoh16(bi->capability) & DOT11_CAP_ESS)) - continue; - - - memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN); - addr[dwrq->length].sa_family = ARPHRD_ETHER; - qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI)); - qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI); - qual[dwrq->length].noise = 0x100 + bi->phy_noise; - - -#if WIRELESS_EXT > 18 - qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; -#else - qual[dwrq->length].updated = 7; -#endif - - dwrq->length++; - } - buf = buf->next; - } - if (dwrq->length) { - memcpy(&addr[dwrq->length], qual, sizeof(struct iw_quality) * dwrq->length); - - dwrq->flags = 1; - } - - return 0; -} - -static int -wl_iw_iscan_prep(wl_scan_params_t *params, wlc_ssid_t *ssid) -{ - int err = 0; - - memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN); - params->bss_type = DOT11_BSSTYPE_ANY; - params->scan_type = 0; - params->nprobes = -1; - params->active_time = -1; - params->passive_time = -1; - params->home_time = -1; - params->channel_num = 0; - -#if defined(CONFIG_FIRST_SCAN) - - if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_STARTED) - params->passive_time = 30; -#endif - params->nprobes = htod32(params->nprobes); - params->active_time = htod32(params->active_time); - params->passive_time = htod32(params->passive_time); - params->home_time = htod32(params->home_time); - if (ssid && ssid->SSID_len) - memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t)); - - return err; -} - -static int -wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action) -{ - int err = 0; - - iscan->iscan_ex_params_p->version = htod32(ISCAN_REQ_VERSION); - iscan->iscan_ex_params_p->action = htod16(action); - iscan->iscan_ex_params_p->scan_duration = htod16(0); - - WL_SCAN(("%s : nprobes=%d\n", __FUNCTION__, iscan->iscan_ex_params_p->params.nprobes)); - WL_SCAN(("active_time=%d\n", iscan->iscan_ex_params_p->params.active_time)); - WL_SCAN(("passive_time=%d\n", iscan->iscan_ex_params_p->params.passive_time)); - WL_SCAN(("home_time=%d\n", iscan->iscan_ex_params_p->params.home_time)); - WL_SCAN(("scan_type=%d\n", iscan->iscan_ex_params_p->params.scan_type)); - WL_SCAN(("bss_type=%d\n", iscan->iscan_ex_params_p->params.bss_type)); - - if ((dev_iw_iovar_setbuf(iscan->dev, "iscan", iscan->iscan_ex_params_p, - iscan->iscan_ex_param_size, iscan->ioctlbuf, sizeof(iscan->ioctlbuf)))) { - WL_ERROR(("Set ISCAN for %s failed with %d\n", __FUNCTION__, err)); - err = -1; - } - - return err; -} - -static void -wl_iw_timerfunc(ulong data) -{ - iscan_info_t *iscan = (iscan_info_t *)data; - if (iscan) { - iscan->timer_on = 0; - if (iscan->iscan_state != ISCAN_STATE_IDLE) { - WL_TRACE(("timer trigger\n")); - up(&iscan->tsk_ctl.sema); - } - } -} - -static void -wl_iw_set_event_mask(struct net_device *dev) -{ - char eventmask[WL_EVENTING_MASK_LEN]; - char iovbuf[WL_EVENTING_MASK_LEN + 12]; - - dev_iw_iovar_getbuf(dev, "event_msgs", "", 0, iovbuf, sizeof(iovbuf)); - bcopy(iovbuf, eventmask, WL_EVENTING_MASK_LEN); - setbit(eventmask, WLC_E_SCAN_COMPLETE); - dev_iw_iovar_setbuf(dev, "event_msgs", eventmask, WL_EVENTING_MASK_LEN, - iovbuf, sizeof(iovbuf)); -} - -static uint32 -wl_iw_iscan_get(iscan_info_t *iscan) -{ - iscan_buf_t * buf; - iscan_buf_t * ptr; - wl_iscan_results_t * list_buf; - wl_iscan_results_t list; - wl_scan_results_t *results; - uint32 status; - int res = 0; - - DHD_OS_MUTEX_LOCK(&wl_cache_lock); - if (iscan->list_cur) { - buf = iscan->list_cur; - iscan->list_cur = buf->next; - } - else { - buf = kmalloc(sizeof(iscan_buf_t), GFP_KERNEL); - if (!buf) { - WL_ERROR(("%s can't alloc iscan_buf_t : going to abort currect iscan\n", - __FUNCTION__)); - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); - return WL_SCAN_RESULTS_NO_MEM; - } - buf->next = NULL; - if (!iscan->list_hdr) - iscan->list_hdr = buf; - else { - ptr = iscan->list_hdr; - while (ptr->next) { - ptr = ptr->next; - } - ptr->next = buf; - } - } - memset(buf->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN); - list_buf = (wl_iscan_results_t*)buf->iscan_buf; - results = &list_buf->results; - results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE; - results->version = 0; - results->count = 0; - - memset(&list, 0, sizeof(list)); - list.results.buflen = htod32(WLC_IW_ISCAN_MAXLEN); - res = dev_iw_iovar_getbuf( - iscan->dev, - "iscanresults", - &list, - WL_ISCAN_RESULTS_FIXED_SIZE, - buf->iscan_buf, - WLC_IW_ISCAN_MAXLEN); - if (res == 0) { - results->buflen = dtoh32(results->buflen); - results->version = dtoh32(results->version); - results->count = dtoh32(results->count); - WL_TRACE(("results->count = %d\n", results->count)); - WL_TRACE(("results->buflen = %d\n", results->buflen)); - status = dtoh32(list_buf->status); - } else { - WL_ERROR(("%s returns error %d\n", __FUNCTION__, res)); - - status = WL_SCAN_RESULTS_NO_MEM; - } - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); - return status; -} - -static void -wl_iw_force_specific_scan(iscan_info_t *iscan) -{ - WL_TRACE(("%s force Specific SCAN for %s\n", __FUNCTION__, g_specific_ssid.SSID)); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_lock(); -#endif - - (void) dev_wlc_ioctl(iscan->dev, WLC_SCAN, &g_specific_ssid, sizeof(g_specific_ssid)); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_unlock(); -#endif -} - -static void -wl_iw_send_scan_complete(iscan_info_t *iscan) -{ - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - - - wireless_send_event(iscan->dev, SIOCGIWSCAN, &wrqu, NULL); -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_STARTED) - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_READY; -#endif - WL_TRACE(("Send Event ISCAN complete\n")); -} - -static int -_iscan_sysioc_thread(void *data) -{ - uint32 status; - - tsk_ctl_t *tsk_ctl = (tsk_ctl_t *)data; - iscan_info_t *iscan = (iscan_info_t *) tsk_ctl->parent; - - - static bool iscan_pass_abort = FALSE; - - DAEMONIZE("iscan_sysioc"); - - status = WL_SCAN_RESULTS_PARTIAL; - - - complete(&tsk_ctl->completed); - - while (down_interruptible(&tsk_ctl->sema) == 0) { - - SMP_RD_BARRIER_DEPENDS(); - if (tsk_ctl->terminated) { - break; - } -#if defined(SOFTAP) - - if (ap_cfg_running) { - WL_TRACE(("%s skipping SCAN ops in AP mode !!!\n", __FUNCTION__)); - net_os_wake_unlock(iscan->dev); - continue; - } -#endif - - if (iscan->timer_on) { - - iscan->timer_on = 0; - del_timer_sync(&iscan->timer); - } - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_lock(); -#endif - status = wl_iw_iscan_get(iscan); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_unlock(); -#endif - - if (g_scan_specified_ssid && (iscan_pass_abort == TRUE)) { - WL_TRACE(("%s Get results from specific scan status=%d\n", __FUNCTION__, status)); - wl_iw_send_scan_complete(iscan); - iscan_pass_abort = FALSE; - status = -1; - } - - switch (status) { - case WL_SCAN_RESULTS_PARTIAL: - WL_TRACE(("iscanresults incomplete\n")); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_lock(); -#endif - - wl_iw_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_unlock(); -#endif - - mod_timer(&iscan->timer, jiffies + msecs_to_jiffies(iscan->timer_ms)); - iscan->timer_on = 1; - break; - case WL_SCAN_RESULTS_SUCCESS: - WL_TRACE(("iscanresults complete\n")); - iscan->iscan_state = ISCAN_STATE_IDLE; - wl_iw_send_scan_complete(iscan); - break; - case WL_SCAN_RESULTS_PENDING: - WL_TRACE(("iscanresults pending\n")); - - mod_timer(&iscan->timer, jiffies + msecs_to_jiffies(iscan->timer_ms)); - iscan->timer_on = 1; - break; - case WL_SCAN_RESULTS_ABORTED: - WL_TRACE(("iscanresults aborted\n")); - iscan->iscan_state = ISCAN_STATE_IDLE; - if (g_scan_specified_ssid == 0) - wl_iw_send_scan_complete(iscan); - else { - iscan_pass_abort = TRUE; - wl_iw_force_specific_scan(iscan); - } - break; - case WL_SCAN_RESULTS_NO_MEM: - WL_TRACE(("iscanresults can't alloc memory: skip\n")); - iscan->iscan_state = ISCAN_STATE_IDLE; - break; - default: - WL_TRACE(("iscanresults returned unknown status %d\n", status)); - break; - } - - net_os_wake_unlock(iscan->dev); - } - - if (iscan->timer_on) { - iscan->timer_on = 0; - del_timer_sync(&iscan->timer); - } - complete_and_exit(&tsk_ctl->completed, 0); -} -#endif - -#if !defined(CSCAN) - -static void -wl_iw_set_ss_cache_timer_flag(void) -{ - g_ss_cache_ctrl.m_timer_expired = 1; - WL_TRACE(("%s called\n", __FUNCTION__)); -} - - -static int -wl_iw_init_ss_cache_ctrl(void) -{ - WL_TRACE(("%s :\n", __FUNCTION__)); - g_ss_cache_ctrl.m_prev_scan_mode = 0; - g_ss_cache_ctrl.m_cons_br_scan_cnt = 0; - g_ss_cache_ctrl.m_cache_head = NULL; - g_ss_cache_ctrl.m_link_down = 0; - g_ss_cache_ctrl.m_timer_expired = 0; - memset(g_ss_cache_ctrl.m_active_bssid, 0, ETHER_ADDR_LEN); - - g_ss_cache_ctrl.m_timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL); - if (!g_ss_cache_ctrl.m_timer) { - return -ENOMEM; - } - g_ss_cache_ctrl.m_timer->function = (void *)wl_iw_set_ss_cache_timer_flag; - init_timer(g_ss_cache_ctrl.m_timer); - - return 0; -} - - - -static void -wl_iw_free_ss_cache(void) -{ - wl_iw_ss_cache_t *node, *cur; - wl_iw_ss_cache_t **spec_scan_head; - - WL_TRACE(("%s called\n", __FUNCTION__)); - - DHD_OS_MUTEX_LOCK(&wl_cache_lock); - spec_scan_head = &g_ss_cache_ctrl.m_cache_head; - node = *spec_scan_head; - - for (;node;) { - WL_TRACE(("%s : SSID - %s\n", __FUNCTION__, node->bss_info->SSID)); - cur = node; - node = cur->next; - kfree(cur); - } - *spec_scan_head = NULL; - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); -} - - - -static int -wl_iw_run_ss_cache_timer(int kick_off) -{ - struct timer_list **timer; - - timer = &g_ss_cache_ctrl.m_timer; - - if (*timer) { - if (kick_off) { -#ifdef CONFIG_PRESCANNED - (*timer)->expires = jiffies + msecs_to_jiffies(70000); -#else - (*timer)->expires = jiffies + msecs_to_jiffies(30000); -#endif - add_timer(*timer); - WL_TRACE(("%s : timer starts \n", __FUNCTION__)); - } else { - del_timer_sync(*timer); - WL_TRACE(("%s : timer stops \n", __FUNCTION__)); - } - } - - return 0; -} - - -static void -wl_iw_release_ss_cache_ctrl(void) -{ - WL_TRACE(("%s :\n", __FUNCTION__)); - wl_iw_free_ss_cache(); - wl_iw_run_ss_cache_timer(0); - if (g_ss_cache_ctrl.m_timer) { - kfree(g_ss_cache_ctrl.m_timer); - } -} - - - -static void -wl_iw_reset_ss_cache(void) -{ - wl_iw_ss_cache_t *node, *prev, *cur; - wl_iw_ss_cache_t **spec_scan_head; - - DHD_OS_MUTEX_LOCK(&wl_cache_lock); - spec_scan_head = &g_ss_cache_ctrl.m_cache_head; - node = *spec_scan_head; - prev = node; - - for (;node;) { - WL_TRACE(("%s : node SSID %s \n", __FUNCTION__, node->bss_info->SSID)); - if (!node->dirty) { - cur = node; - if (cur == *spec_scan_head) { - *spec_scan_head = cur->next; - prev = *spec_scan_head; - } - else { - prev->next = cur->next; - } - node = cur->next; - - WL_TRACE(("%s : Del node : SSID %s\n", __FUNCTION__, cur->bss_info->SSID)); - kfree(cur); - continue; - } - - node->dirty = 0; - prev = node; - node = node->next; - } - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); -} - - -static int -wl_iw_add_bss_to_ss_cache(wl_scan_results_t *ss_list) -{ - - wl_iw_ss_cache_t *node, *prev, *leaf; - wl_iw_ss_cache_t **spec_scan_head; - wl_bss_info_t *bi = NULL; - int i; - - - if (!ss_list->count) { - return 0; - } - - DHD_OS_MUTEX_LOCK(&wl_cache_lock); - spec_scan_head = &g_ss_cache_ctrl.m_cache_head; - - for (i = 0; i < ss_list->count; i++) { - - node = *spec_scan_head; - prev = node; - - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info; - - WL_TRACE(("%s : find %d with specific SSID %s\n", __FUNCTION__, i, bi->SSID)); - for (;node;) { - if (!memcmp(&node->bss_info->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) { - - WL_TRACE(("dirty marked : SSID %s\n", bi->SSID)); - node->dirty = 1; - break; - } - prev = node; - node = node->next; - } - - if (node) { - continue; - } - - leaf = kmalloc(bi->length + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN, GFP_KERNEL); - if (!leaf) { - WL_ERROR(("Memory alloc failure %d\n", - bi->length + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN)); - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); - return -ENOMEM; - } - - memcpy(leaf->bss_info, bi, bi->length); - leaf->next = NULL; - leaf->dirty = 1; - leaf->count = 1; - leaf->version = ss_list->version; - - if (!prev) { - *spec_scan_head = leaf; - } - else { - prev->next = leaf; - } - } - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); - return 0; -} - - -static int -wl_iw_merge_scan_cache(struct iw_request_info *info, char *extra, uint buflen_from_user, -__u16 *merged_len) -{ - wl_iw_ss_cache_t *node; - wl_scan_results_t *list_merge; - - DHD_OS_MUTEX_LOCK(&wl_cache_lock); - node = g_ss_cache_ctrl.m_cache_head; - for (;node;) { - list_merge = (wl_scan_results_t *)&node->buflen; - WL_TRACE(("%s: Cached Specific APs list=%d\n", __FUNCTION__, list_merge->count)); - if (buflen_from_user - *merged_len > 0) { - *merged_len += (__u16) wl_iw_get_scan_prep(list_merge, info, - extra + *merged_len, buflen_from_user - *merged_len); - } - else { - WL_TRACE(("%s: exit with break\n", __FUNCTION__)); - break; - } - node = node->next; - } - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); - return 0; -} - - -static int -wl_iw_delete_bss_from_ss_cache(void *addr) -{ - - wl_iw_ss_cache_t *node, *prev; - wl_iw_ss_cache_t **spec_scan_head; - - DHD_OS_MUTEX_LOCK(&wl_cache_lock); - spec_scan_head = &g_ss_cache_ctrl.m_cache_head; - node = *spec_scan_head; - prev = node; - for (;node;) { - if (!memcmp(&node->bss_info->BSSID, addr, ETHER_ADDR_LEN)) { - if (node == *spec_scan_head) { - *spec_scan_head = node->next; - } - else { - prev->next = node->next; - } - - WL_TRACE(("%s : Del node : %s\n", __FUNCTION__, node->bss_info->SSID)); - kfree(node); - break; - } - - prev = node; - node = node->next; - } - - memset(addr, 0, ETHER_ADDR_LEN); - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); - return 0; -} - -#endif - -static int -wl_iw_set_scan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error; - WL_TRACE(("\n:%s dev:%s: SIOCSIWSCAN : SCAN\n", __FUNCTION__, dev->name)); - -#ifdef OEM_CHROMIUMOS - g_set_essid_before_scan = FALSE; -#endif - -#if defined(CSCAN) - WL_ERROR(("%s: Scan from SIOCGIWSCAN not supported\n", __FUNCTION__)); - return -EINVAL; -#endif - -#if defined(SOFTAP) - - if (ap_cfg_running) { - WL_TRACE(("\n>%s: Not executed, reason -'SOFTAP is active'\n", __FUNCTION__)); - return 0; - } -#endif - - - if (g_onoff == G_WLAN_SET_OFF) - return 0; - - - memset(&g_specific_ssid, 0, sizeof(g_specific_ssid)); -#ifndef WL_IW_USE_ISCAN - - g_scan_specified_ssid = 0; -#endif - -#if WIRELESS_EXT > 17 - - if (wrqu->data.length == sizeof(struct iw_scan_req)) { - if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - struct iw_scan_req *req = (struct iw_scan_req *)extra; -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan != BROADCAST_SCAN_FIRST_RESULT_CONSUMED) { - - WL_TRACE(("%s Ignoring SC %s first BC is not done = %d\n", - __FUNCTION__, req->essid, - g_first_broadcast_scan)); - return -EBUSY; - } -#endif - if (g_scan_specified_ssid) { - WL_TRACE(("%s Specific SCAN is not done ignore scan for = %s \n", - __FUNCTION__, req->essid)); - - return -EBUSY; - } - else { - g_specific_ssid.SSID_len = MIN(sizeof(g_specific_ssid.SSID), - req->essid_len); - memcpy(g_specific_ssid.SSID, req->essid, g_specific_ssid.SSID_len); - g_specific_ssid.SSID_len = htod32(g_specific_ssid.SSID_len); - g_scan_specified_ssid = 1; - WL_TRACE(("### Specific scan ssid=%s len=%d\n", - g_specific_ssid.SSID, g_specific_ssid.SSID_len)); - } - } - } -#endif - - if ((error = dev_wlc_ioctl(dev, WLC_SCAN, &g_specific_ssid, sizeof(g_specific_ssid)))) { - WL_TRACE(("#### Set SCAN for %s failed with %d\n", g_specific_ssid.SSID, error)); - - g_scan_specified_ssid = 0; - return -EBUSY; - } - - return 0; -} - -#ifdef WL_IW_USE_ISCAN -int -wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag) -{ - wlc_ssid_t ssid; - iscan_info_t *iscan = g_iscan; - -#if defined(CONFIG_FIRST_SCAN) - - if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_IDLE) { - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_STARTED; - WL_TRACE(("%s: First Brodcast scan was forced\n", __FUNCTION__)); - } - else if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_STARTED) { - WL_TRACE(("%s: ignore ISCAN request first BS is not done yet\n", __FUNCTION__)); - return 0; - } -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - if (flag) - rtnl_lock(); -#endif - - dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &iscan->scan_flag, sizeof(iscan->scan_flag)); - wl_iw_set_event_mask(dev); - - WL_TRACE(("+++: Set Broadcast ISCAN\n")); - - memset(&ssid, 0, sizeof(ssid)); - - iscan->list_cur = iscan->list_hdr; - iscan->iscan_state = ISCAN_STATE_SCANING; - - memset(&iscan->iscan_ex_params_p->params, 0, iscan->iscan_ex_param_size); - wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, &ssid); - wl_iw_iscan(iscan, &ssid, WL_SCAN_ACTION_START); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - if (flag) - rtnl_unlock(); -#endif - - mod_timer(&iscan->timer, jiffies + msecs_to_jiffies(iscan->timer_ms)); - - iscan->timer_on = 1; - - return 0; -} - -static int -wl_iw_iscan_set_scan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - wlc_ssid_t ssid; - iscan_info_t *iscan = g_iscan; - int ret = 0; - - WL_TRACE_SCAN(("%s: SIOCSIWSCAN : ISCAN\n", dev->name)); - -#if defined(CSCAN) - WL_ERROR(("%s: Scan from SIOCGIWSCAN not supported\n", __FUNCTION__)); - return -EINVAL; -#endif - - net_os_wake_lock(dev); - - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_TRACE(("\n>%s: Not executed, reason -'SOFTAP is active'\n", __FUNCTION__)); - goto set_scan_end; - } -#endif - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); - goto set_scan_end; - } - -#ifdef PNO_SUPPORT - - if (dhd_dev_get_pno_status(dev)) { - WL_ERROR(("%s: Scan called when PNO is active\n", __FUNCTION__)); - } -#endif - - - if ((!iscan) || (iscan->tsk_ctl.thr_pid < 0)) { - WL_ERROR(("%s error \n", __FUNCTION__)); - goto set_scan_end; - } - - if (g_scan_specified_ssid) { - WL_TRACE(("%s Specific SCAN already running ignoring BC scan\n", - __FUNCTION__)); - ret = EBUSY; - goto set_scan_end; - } - - - memset(&ssid, 0, sizeof(ssid)); - -#if WIRELESS_EXT > 17 - - if (wrqu->data.length == sizeof(struct iw_scan_req)) { - if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - int as = 0; - struct iw_scan_req *req = (struct iw_scan_req *)extra; - - ssid.SSID_len = MIN(sizeof(ssid.SSID), req->essid_len); - memcpy(ssid.SSID, req->essid, ssid.SSID_len); - ssid.SSID_len = htod32(ssid.SSID_len); - dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &as, sizeof(as)); - wl_iw_set_event_mask(dev); - ret = wl_iw_set_scan(dev, info, wrqu, extra); - goto set_scan_end; - } - else { - g_scan_specified_ssid = 0; - - if (iscan->iscan_state == ISCAN_STATE_SCANING) { - WL_TRACE(("%s ISCAN already in progress \n", __FUNCTION__)); - goto set_scan_end; - } - } - } -#endif - -#if defined(CONFIG_FIRST_SCAN) && !defined(CSCAN) - if (g_first_broadcast_scan < BROADCAST_SCAN_FIRST_RESULT_CONSUMED) { - if (++g_first_counter_scans == MAX_ALLOWED_BLOCK_SCAN_FROM_FIRST_SCAN) { - - WL_ERROR(("%s Clean up First scan flag which is %d\n", - __FUNCTION__, g_first_broadcast_scan)); - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_CONSUMED; - } - else { - WL_ERROR(("%s Ignoring Broadcast Scan:First Scan is not done yet %d\n", - __FUNCTION__, g_first_counter_scans)); - ret = -EBUSY; - goto set_scan_end; - } - } -#endif - - wl_iw_iscan_set_scan_broadcast_prep(dev, 0); - -set_scan_end: - net_os_wake_unlock(dev); - return ret; -} -#endif - -#if WIRELESS_EXT > 17 -static bool -ie_is_wpa_ie(uint8 **wpaie, uint8 **tlvs, int *tlvs_len) -{ - - - uint8 *ie = *wpaie; - - - if ((ie[1] >= 6) && - !bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x01"), 4)) { - return TRUE; - } - - - ie += ie[1] + 2; - - *tlvs_len -= (int)(ie - *tlvs); - - *tlvs = ie; - return FALSE; -} - -static bool -ie_is_wps_ie(uint8 **wpsie, uint8 **tlvs, int *tlvs_len) -{ - - - uint8 *ie = *wpsie; - - - if ((ie[1] >= 4) && - !bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x04"), 4)) { - return TRUE; - } - - - ie += ie[1] + 2; - - *tlvs_len -= (int)(ie - *tlvs); - - *tlvs = ie; - return FALSE; -} -#endif - - -static int -wl_iw_handle_scanresults_ies(char **event_p, char *end, - struct iw_request_info *info, wl_bss_info_t *bi) -{ -#if WIRELESS_EXT > 17 - struct iw_event iwe; - char *event; - - event = *event_p; - if (bi->ie_length) { - - bcm_tlv_t *ie; - uint8 *ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); - int ptr_len = bi->ie_length; - - if ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_RSN_ID))) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); - } - ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); - - while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) { - - if (ie_is_wps_ie(((uint8 **)&ie), &ptr, &ptr_len)) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); - break; - } - } - - ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); - ptr_len = bi->ie_length; - while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) { - if (ie_is_wpa_ie(((uint8 **)&ie), &ptr, &ptr_len)) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); - break; - } - } - - *event_p = event; - } -#endif - - return 0; -} - -#ifndef CSCAN -static uint -wl_iw_get_scan_prep( - wl_scan_results_t *list, - struct iw_request_info *info, - char *extra, - short max_size) -{ - int i, j; - struct iw_event iwe; - wl_bss_info_t *bi = NULL; - char *event = extra, *end = extra + max_size - WE_ADD_EVENT_FIX, *value; - int ret = 0; - - if (!list) { - WL_ERROR(("%s: Null list pointer", __FUNCTION__)); - return ret; - } - - - - for (i = 0; i < list->count && i < IW_MAX_AP; i++) { - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, list->version)); - return ret; - } - - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; - - WL_TRACE(("%s : %s\n", __FUNCTION__, bi->SSID)); - - - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN); - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN); - - iwe.u.data.length = dtoh32(bi->SSID_len); - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID); - - - if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) { - iwe.cmd = SIOCGIWMODE; - if (dtoh16(bi->capability) & DOT11_CAP_ESS) - iwe.u.mode = IW_MODE_INFRA; - else - iwe.u.mode = IW_MODE_ADHOC; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_UINT_LEN); - } - - - iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = wf_channel2mhz(CHSPEC_CHANNEL(bi->chanspec), - CHSPEC_CHANNEL(bi->chanspec) <= CH_MAX_2G_CHANNEL ? - WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G); - iwe.u.freq.e = 6; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN); - - - iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI)); - iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI); - iwe.u.qual.noise = 0x100 + bi->phy_noise; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN); - - - wl_iw_handle_scanresults_ies(&event, end, info, bi); - - - iwe.cmd = SIOCGIWENCODE; - if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event); - - - if (bi->rateset.count) { - if (((event -extra) + IW_EV_LCP_LEN) <= (uintptr)end) { - value = event + IW_EV_LCP_LEN; - iwe.cmd = SIOCGIWRATE; - - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; - for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) { - iwe.u.bitrate.value = - (bi->rateset.rates[j] & 0x7f) * 500000; - value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe, - IW_EV_PARAM_LEN); - } - event = value; - } - } - } - - if ((ret = (event - extra)) < 0) { - WL_ERROR(("==> Wrong size\n")); - ret = 0; - } - - WL_TRACE(("%s: size=%d bytes prepared \n", __FUNCTION__, (unsigned int)(event - extra))); - return (uint)ret; -} - -static int -wl_iw_get_scan( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - channel_info_t ci; - wl_scan_results_t *list_merge; - wl_scan_results_t *list = (wl_scan_results_t *) g_scan; - int error; - uint buflen_from_user = dwrq->length; - uint len = G_SCAN_RESULTS; - __u16 len_ret = 0; -#if !defined(CSCAN) - __u16 merged_len = 0; -#endif -#if defined(WL_IW_USE_ISCAN) - iscan_info_t *iscan = g_iscan; - iscan_buf_t * p_buf; -#if !defined(CSCAN) - uint32 counter = 0; -#endif -#endif - - WL_TRACE(("%s: buflen_from_user %d: \n", dev->name, buflen_from_user)); - - if (!extra) { - WL_TRACE(("%s: wl_iw_get_scan return -EINVAL\n", dev->name)); - return -EINVAL; - } - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)))) - return error; - ci.scan_channel = dtoh32(ci.scan_channel); - if (ci.scan_channel) - return -EAGAIN; - -#if !defined(CSCAN) - if (g_ss_cache_ctrl.m_timer_expired) { - wl_iw_free_ss_cache(); - g_ss_cache_ctrl.m_timer_expired ^= 1; - } - if ((!g_scan_specified_ssid && g_ss_cache_ctrl.m_prev_scan_mode) || - g_ss_cache_ctrl.m_cons_br_scan_cnt > 4) { - g_ss_cache_ctrl.m_cons_br_scan_cnt = 0; - - wl_iw_reset_ss_cache(); - } - g_ss_cache_ctrl.m_prev_scan_mode = g_scan_specified_ssid; - if (g_scan_specified_ssid) { - g_ss_cache_ctrl.m_cons_br_scan_cnt = 0; - } - else { - g_ss_cache_ctrl.m_cons_br_scan_cnt++; - } -#endif - - - - if (g_scan_specified_ssid) { - - list = kmalloc(len, GFP_KERNEL); - if (!list) { - WL_TRACE(("%s: wl_iw_get_scan return -ENOMEM\n", dev->name)); - g_scan_specified_ssid = 0; - return -ENOMEM; - } - } - - memset(list, 0, len); - list->buflen = htod32(len); - if ((error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, len))) { - WL_ERROR(("%s: %s : Scan_results ERROR %d\n", dev->name, __FUNCTION__, error)); - dwrq->length = len; - if (g_scan_specified_ssid) { - g_scan_specified_ssid = 0; - kfree(list); - } - return 0; - } - list->buflen = dtoh32(list->buflen); - list->version = dtoh32(list->version); - list->count = dtoh32(list->count); - - - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, list->version)); - if (g_scan_specified_ssid) { - g_scan_specified_ssid = 0; - kfree(list); - } - return -EINVAL; - } - -#if !defined(CSCAN) - if (g_scan_specified_ssid) { - - wl_iw_add_bss_to_ss_cache(list); - kfree(list); - } -#endif - -#if !defined(CSCAN) - DHD_OS_MUTEX_LOCK(&wl_cache_lock); -#if defined(WL_IW_USE_ISCAN) - if (g_scan_specified_ssid) - WL_TRACE(("%s: Specified scan APs from scan=%d\n", __FUNCTION__, list->count)); - p_buf = iscan->list_hdr; - - while (p_buf != iscan->list_cur) { - list_merge = &((wl_iscan_results_t*)p_buf->iscan_buf)->results; - WL_TRACE(("%s: Bcast APs list=%d\n", __FUNCTION__, list_merge->count)); - counter += list_merge->count; - if (list_merge->count > 0) - len_ret += (__u16) wl_iw_get_scan_prep(list_merge, info, - extra+len_ret, buflen_from_user -len_ret); - p_buf = p_buf->next; - } - WL_TRACE(("%s merged with total Bcast APs=%d\n", __FUNCTION__, counter)); -#else - list_merge = (wl_scan_results_t *) g_scan; - len_ret = (__u16) wl_iw_get_scan_prep(list_merge, info, extra, buflen_from_user); -#endif - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); - if (g_ss_cache_ctrl.m_link_down) { - - wl_iw_delete_bss_from_ss_cache(g_ss_cache_ctrl.m_active_bssid); - } - - wl_iw_merge_scan_cache(info, extra+len_ret, buflen_from_user-len_ret, &merged_len); - len_ret += merged_len; - wl_iw_run_ss_cache_timer(0); - wl_iw_run_ss_cache_timer(1); -#else - - - if (g_scan_specified_ssid) { - WL_TRACE(("%s: Specified scan APs in the list =%d\n", __FUNCTION__, list->count)); - len_ret = (__u16) wl_iw_get_scan_prep(list, info, extra, buflen_from_user); - kfree(list); - -#if defined(WL_IW_USE_ISCAN) - p_buf = iscan->list_hdr; - - while (p_buf != iscan->list_cur) { - list_merge = &((wl_iscan_results_t*)p_buf->iscan_buf)->results; - WL_TRACE(("%s: Bcast APs list=%d\n", __FUNCTION__, list_merge->count)); - if (list_merge->count > 0) - len_ret += (__u16) wl_iw_get_scan_prep(list_merge, info, - extra+len_ret, buflen_from_user -len_ret); - p_buf = p_buf->next; - } -#else - list_merge = (wl_scan_results_t *) g_scan; - WL_TRACE(("%s: Bcast APs list=%d\n", __FUNCTION__, list_merge->count)); - if (list_merge->count > 0) - len_ret += (__u16) wl_iw_get_scan_prep(list_merge, info, extra+len_ret, - buflen_from_user -len_ret); -#endif - } - else { - list = (wl_scan_results_t *) g_scan; - len_ret = (__u16) wl_iw_get_scan_prep(list, info, extra, buflen_from_user); - } -#endif - -#if defined(WL_IW_USE_ISCAN) - - g_scan_specified_ssid = 0; -#endif - - if ((len_ret + WE_ADD_EVENT_FIX) < buflen_from_user) - len = len_ret; - - dwrq->length = len; - dwrq->flags = 0; - - WL_TRACE(("%s return to WE %d bytes APs=%d\n", __FUNCTION__, dwrq->length, list->count)); - return 0; -} -#endif - -#if defined(WL_IW_USE_ISCAN) -static int -wl_iw_iscan_get_scan( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_scan_results_t *list; - struct iw_event iwe; - wl_bss_info_t *bi = NULL; - int ii, j; - int apcnt; - char *event = extra, *end = extra + dwrq->length, *value; - iscan_info_t *iscan = g_iscan; - iscan_buf_t * p_buf; - uint32 counter = 0; - uint8 channel; -#if !defined(CSCAN) - __u16 merged_len = 0; - uint buflen_from_user = dwrq->length; -#endif - - WL_TRACE(("%s %s buflen_from_user %d:\n", dev->name, __FUNCTION__, dwrq->length)); - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_TRACE(("%s: Not executed, reason -'SOFTAP is active'\n", __FUNCTION__)); - return -EINVAL; - } -#endif - - if (!extra) { - WL_TRACE(("%s: INVALID SIOCGIWSCAN GET bad parameter\n", dev->name)); - return -EINVAL; - } - -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan < BROADCAST_SCAN_FIRST_RESULT_READY) { - WL_TRACE(("%s %s: first ISCAN results are NOT ready yet \n", - dev->name, __FUNCTION__)); - return -EAGAIN; - } -#endif - - if ((!iscan) || (iscan->tsk_ctl.thr_pid < 0)) { - WL_ERROR(("%ssysioc_pid\n", __FUNCTION__)); - return EAGAIN; - } - - - -#if !defined(CSCAN) - if (g_ss_cache_ctrl.m_timer_expired) { - wl_iw_free_ss_cache(); - g_ss_cache_ctrl.m_timer_expired ^= 1; - } - if (g_scan_specified_ssid) { - return wl_iw_get_scan(dev, info, dwrq, extra); - } - else { - if (g_ss_cache_ctrl.m_link_down) { - - wl_iw_delete_bss_from_ss_cache(g_ss_cache_ctrl.m_active_bssid); - } - if (g_ss_cache_ctrl.m_prev_scan_mode || g_ss_cache_ctrl.m_cons_br_scan_cnt > 4) { - g_ss_cache_ctrl.m_cons_br_scan_cnt = 0; - - wl_iw_reset_ss_cache(); - } - g_ss_cache_ctrl.m_prev_scan_mode = g_scan_specified_ssid; - g_ss_cache_ctrl.m_cons_br_scan_cnt++; - } -#endif - - WL_TRACE(("%s: SIOCGIWSCAN GET broadcast results\n", dev->name)); - apcnt = 0; - p_buf = iscan->list_hdr; - - while (p_buf != iscan->list_cur) { - list = &((wl_iscan_results_t*)p_buf->iscan_buf)->results; - - counter += list->count; - - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, list->version)); - return -EINVAL; - } - - bi = NULL; - for (ii = 0; ii < list->count && apcnt < IW_MAX_AP; apcnt++, ii++) { - bi = (bi ? - (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : - list->bss_info); - ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list + - WLC_IW_ISCAN_MAXLEN)); - - - if (event + ETHER_ADDR_LEN + bi->SSID_len + - IW_EV_UINT_LEN + IW_EV_FREQ_LEN + IW_EV_QUAL_LEN >= end) - return -E2BIG; - - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN); - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN); - - - iwe.u.data.length = dtoh32(bi->SSID_len); - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID); - - - if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) { - iwe.cmd = SIOCGIWMODE; - if (dtoh16(bi->capability) & DOT11_CAP_ESS) - iwe.u.mode = IW_MODE_INFRA; - else - iwe.u.mode = IW_MODE_ADHOC; - event = IWE_STREAM_ADD_EVENT(info, event, end, - &iwe, IW_EV_UINT_LEN); - } - - - iwe.cmd = SIOCGIWFREQ; - channel = (bi->ctl_ch == 0) ? CHSPEC_CHANNEL(bi->chanspec) : bi->ctl_ch; - iwe.u.freq.m = wf_channel2mhz(channel, - channel <= CH_MAX_2G_CHANNEL ? - WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G); - iwe.u.freq.e = 6; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN); - - - iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI)); - iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI); - iwe.u.qual.noise = 0x100 + bi->phy_noise; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN); - - - wl_iw_handle_scanresults_ies(&event, end, info, bi); - - - iwe.cmd = SIOCGIWENCODE; - if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event); - - - if (bi->rateset.count) { - if (event + IW_MAX_BITRATES*IW_EV_PARAM_LEN >= end) - return -E2BIG; - - value = event + IW_EV_LCP_LEN; - iwe.cmd = SIOCGIWRATE; - - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; - for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) { - iwe.u.bitrate.value = - (bi->rateset.rates[j] & 0x7f) * 500000; - value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe, - IW_EV_PARAM_LEN); - } - event = value; - } - } - p_buf = p_buf->next; - } - - dwrq->length = event - extra; - dwrq->flags = 0; - -#if !defined(CSCAN) - - wl_iw_merge_scan_cache(info, event, buflen_from_user - dwrq->length, &merged_len); - dwrq->length += merged_len; - wl_iw_run_ss_cache_timer(0); - wl_iw_run_ss_cache_timer(1); -#endif - -#if defined(CONFIG_FIRST_SCAN) - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_CONSUMED; -#endif - - WL_TRACE(("%s return to WE %d bytes APs=%d\n", __FUNCTION__, dwrq->length, counter)); - - return 0; -} -#endif - -#define WL_JOIN_PARAMS_MAX 1600 -#ifdef CONFIG_PRESCANNED -static int -check_prescan(wl_join_params_t *join_params, int *join_params_size) -{ - int cnt = 0; - int indx = 0; - wl_iw_ss_cache_t *node = NULL; - wl_bss_info_t *bi = NULL; - iscan_info_t *iscan = g_iscan; - iscan_buf_t * buf; - wl_scan_results_t *list; - char *destbuf; - - buf = iscan->list_hdr; - - while (buf) { - list = &((wl_iscan_results_t*)buf->iscan_buf)->results; - bi = NULL; - for (indx = 0; indx < list->count; indx++) { - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) - : list->bss_info; - if (!(dtoh16(bi->capability) & DOT11_CAP_ESS)) - continue; - if ((dtoh32(bi->SSID_len) != join_params->ssid.SSID_len) || - memcmp(bi->SSID, join_params->ssid.SSID, - join_params->ssid.SSID_len)) - continue; - memcpy(&join_params->params.chanspec_list[cnt], - &bi->chanspec, sizeof(chanspec_t)); - WL_ERROR(("iscan : chanspec :%d, count %d \n", bi->chanspec, cnt)); - cnt++; - } - buf = buf->next; - } - - if (!cnt) { - MUTEX_LOCK_WL_SCAN_SET(); - node = g_ss_cache_ctrl.m_cache_head; - for (; node; ) { - if (!memcmp(&node->bss_info->SSID, join_params->ssid.SSID, - join_params->ssid.SSID_len)) { - memcpy(&join_params->params.chanspec_list[cnt], - &node->bss_info->chanspec, sizeof(chanspec_t)); - WL_ERROR(("cache_scan : chanspec :%d, count %d \n", - (int)node->bss_info->chanspec, cnt)); - cnt++; - } - node = node->next; - } - MUTEX_UNLOCK_WL_SCAN_SET(); - } - - if (!cnt) { - return 0; - } - - destbuf = (char *)&join_params->params.chanspec_list[cnt]; - *join_params_size = destbuf - (char*)join_params; - join_params->ssid.SSID_len = htod32(g_ssid.SSID_len); - memcpy(&(join_params->params.bssid), ðer_bcast, ETHER_ADDR_LEN); - join_params->params.chanspec_num = htod32(cnt); - - if ((*join_params_size) > WL_JOIN_PARAMS_MAX) { - WL_ERROR(("can't fit bssids for all %d APs found\n", cnt)); - kfree(join_params); - return 0; - } - - WL_ERROR(("Passing %d channel/bssid pairs.\n", cnt)); - return cnt; -} -#endif - -static int -wl_iw_set_essid( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - int error; - wl_join_params_t *join_params; - int join_params_size; - - WL_TRACE(("%s: SIOCSIWESSID\n", dev->name)); - - RETURN_IF_EXTRA_NULL(extra); - -#ifdef OEM_CHROMIUMOS - if (g_set_essid_before_scan) - return -EAGAIN; -#endif - if (!(join_params = kmalloc(WL_JOIN_PARAMS_MAX, GFP_KERNEL))) { - WL_ERROR(("allocation failed for join_params size is %d\n", WL_JOIN_PARAMS_MAX)); - return -ENOMEM; - } - - memset(join_params, 0, WL_JOIN_PARAMS_MAX); - - - memset(&g_ssid, 0, sizeof(g_ssid)); - - if (dwrq->length && extra) { -#if WIRELESS_EXT > 20 - g_ssid.SSID_len = MIN(sizeof(g_ssid.SSID), dwrq->length); -#else - g_ssid.SSID_len = MIN(sizeof(g_ssid.SSID), dwrq->length-1); -#endif - memcpy(g_ssid.SSID, extra, g_ssid.SSID_len); - -#ifdef CONFIG_PRESCANNED - memcpy(join_params->ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); - join_params->ssid.SSID_len = g_ssid.SSID_len; - - if (check_prescan(join_params, &join_params_size)) { - if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, - join_params, join_params_size))) { - WL_ERROR(("Invalid ioctl data=%d\n", error)); - kfree(join_params); - return error; - } - kfree(join_params); - return 0; - } else { - WL_ERROR(("No matched found\n Trying to join to specific channel\n")); - } -#endif - } else { - - g_ssid.SSID_len = 0; - } - g_ssid.SSID_len = htod32(g_ssid.SSID_len); - - - memset(join_params, 0, sizeof(*join_params)); - join_params_size = sizeof(join_params->ssid); - - memcpy(join_params->ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); - join_params->ssid.SSID_len = htod32(g_ssid.SSID_len); - memcpy(&(join_params->params.bssid), ðer_bcast, ETHER_ADDR_LEN); - - - - wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, join_params, &join_params_size); - - if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, join_params, join_params_size))) { - WL_ERROR(("Invalid ioctl data=%d\n", error)); - return error; - } - - if (g_ssid.SSID_len) { - WL_ERROR(("%s: join SSID=%s ch=%d\n", __FUNCTION__, - g_ssid.SSID, g_wl_iw_params.target_channel)); - } - kfree(join_params); - return 0; -} - -static int -wl_iw_get_essid( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wlc_ssid_t ssid; - int error; - - WL_TRACE(("%s: SIOCGIWESSID\n", dev->name)); - - if (!extra) - return -EINVAL; - - if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)))) { - WL_ERROR(("Error getting the SSID\n")); - return error; - } - - ssid.SSID_len = dtoh32(ssid.SSID_len); - - - memcpy(extra, ssid.SSID, ssid.SSID_len); - - dwrq->length = ssid.SSID_len; - - dwrq->flags = 1; - - return 0; -} - -static int -wl_iw_set_nick( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_iw_t *iw = NETDEV_PRIV(dev); - - WL_TRACE(("%s: SIOCSIWNICKN\n", dev->name)); - - if (!extra) - return -EINVAL; - - - if (dwrq->length > sizeof(iw->nickname)) - return -E2BIG; - - memcpy(iw->nickname, extra, dwrq->length); - iw->nickname[dwrq->length - 1] = '\0'; - - return 0; -} - -static int -wl_iw_get_nick( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_iw_t *iw = NETDEV_PRIV(dev); - - WL_TRACE(("%s: SIOCGIWNICKN\n", dev->name)); - - if (!extra) - return -EINVAL; - - strcpy(extra, iw->nickname); - dwrq->length = strlen(extra) + 1; - - return 0; -} - -static int -wl_iw_set_rate( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - wl_rateset_t rateset; - int error, rate, i, error_bg, error_a; - - WL_TRACE(("%s: SIOCSIWRATE\n", dev->name)); - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset)))) - return error; - - rateset.count = dtoh32(rateset.count); - - if (vwrq->value < 0) { - - rate = rateset.rates[rateset.count - 1] & 0x7f; - } else if (vwrq->value < rateset.count) { - - rate = rateset.rates[vwrq->value] & 0x7f; - } else { - - rate = vwrq->value / 500000; - } - - if (vwrq->fixed) { - - error_bg = dev_wlc_intvar_set(dev, "bg_rate", rate); - error_a = dev_wlc_intvar_set(dev, "a_rate", rate); - - if (error_bg && error_a) - return (error_bg | error_a); - } else { - - - error_bg = dev_wlc_intvar_set(dev, "bg_rate", 0); - - error_a = dev_wlc_intvar_set(dev, "a_rate", 0); - - if (error_bg && error_a) - return (error_bg | error_a); - - - for (i = 0; i < rateset.count; i++) - if ((rateset.rates[i] & 0x7f) > rate) - break; - rateset.count = htod32(i); - - - if ((error = dev_wlc_ioctl(dev, WLC_SET_RATESET, &rateset, sizeof(rateset)))) - return error; - } - - return 0; -} - -static int -wl_iw_get_rate( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, rate; - - WL_TRACE(("%s: SIOCGIWRATE\n", dev->name)); - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate)))) - return error; - rate = dtoh32(rate); - vwrq->value = rate * 500000; - - return 0; -} - -static int -wl_iw_set_rts( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, rts; - - WL_TRACE(("%s: SIOCSIWRTS\n", dev->name)); - - if (vwrq->disabled) - rts = DOT11_DEFAULT_RTS_LEN; - else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_RTS_LEN) - return -EINVAL; - else - rts = vwrq->value; - - if ((error = dev_wlc_intvar_set(dev, "rtsthresh", rts))) - return error; - - return 0; -} - -static int -wl_iw_get_rts( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, rts; - - WL_TRACE(("%s: SIOCGIWRTS\n", dev->name)); - - if ((error = dev_wlc_intvar_get(dev, "rtsthresh", &rts))) - return error; - - vwrq->value = rts; - vwrq->disabled = (rts >= DOT11_DEFAULT_RTS_LEN); - vwrq->fixed = 1; - - return 0; -} - -static int -wl_iw_set_frag( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, frag; - - WL_TRACE(("%s: SIOCSIWFRAG\n", dev->name)); - - if (vwrq->disabled) - frag = DOT11_DEFAULT_FRAG_LEN; - else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_FRAG_LEN) - return -EINVAL; - else - frag = vwrq->value; - - if ((error = dev_wlc_intvar_set(dev, "fragthresh", frag))) - return error; - - return 0; -} - -static int -wl_iw_get_frag( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, fragthreshold; - - WL_TRACE(("%s: SIOCGIWFRAG\n", dev->name)); - - if ((error = dev_wlc_intvar_get(dev, "fragthresh", &fragthreshold))) - return error; - - vwrq->value = fragthreshold; - vwrq->disabled = (fragthreshold >= DOT11_DEFAULT_FRAG_LEN); - vwrq->fixed = 1; - - return 0; -} - -static int -wl_iw_set_txpow( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, disable; - uint16 txpwrmw; - WL_TRACE(("%s: SIOCSIWTXPOW\n", dev->name)); - - - disable = vwrq->disabled ? WL_RADIO_SW_DISABLE : 0; - disable += WL_RADIO_SW_DISABLE << 16; - - disable = htod32(disable); - if ((error = dev_wlc_ioctl(dev, WLC_SET_RADIO, &disable, sizeof(disable)))) - return error; - - - if (disable & WL_RADIO_SW_DISABLE) - return 0; - - - if (!(vwrq->flags & IW_TXPOW_MWATT)) - return -EINVAL; - - - if (vwrq->value < 0) - return 0; - - if (vwrq->value > 0xffff) txpwrmw = 0xffff; - else txpwrmw = (uint16)vwrq->value; - - - error = dev_wlc_intvar_set(dev, "qtxpower", (int)(bcm_mw_to_qdbm(txpwrmw))); - return error; -} - -static int -wl_iw_get_txpow( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, disable, txpwrdbm; - uint8 result; - - WL_TRACE(("%s: SIOCGIWTXPOW\n", dev->name)); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_RADIO, &disable, sizeof(disable))) || - (error = dev_wlc_intvar_get(dev, "qtxpower", &txpwrdbm))) - return error; - - disable = dtoh32(disable); - result = (uint8)(txpwrdbm & ~WL_TXPWR_OVERRIDE); - vwrq->value = (int32)bcm_qdbm_to_mw(result); - vwrq->fixed = 0; - vwrq->disabled = (disable & (WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE)) ? 1 : 0; - vwrq->flags = IW_TXPOW_MWATT; - - return 0; -} - -#if WIRELESS_EXT > 10 -static int -wl_iw_set_retry( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, lrl, srl; - - WL_TRACE(("%s: SIOCSIWRETRY\n", dev->name)); - - - if (vwrq->disabled || (vwrq->flags & IW_RETRY_LIFETIME)) - return -EINVAL; - - - if (vwrq->flags & IW_RETRY_LIMIT) { - - -#if WIRELESS_EXT > 20 - if ((vwrq->flags & IW_RETRY_LONG) ||(vwrq->flags & IW_RETRY_MAX) || - !((vwrq->flags & IW_RETRY_SHORT) || (vwrq->flags & IW_RETRY_MIN))) { -#else - if ((vwrq->flags & IW_RETRY_MAX) || !(vwrq->flags & IW_RETRY_MIN)) { -#endif - lrl = htod32(vwrq->value); - if ((error = dev_wlc_ioctl(dev, WLC_SET_LRL, &lrl, sizeof(lrl)))) - return error; - } - - -#if WIRELESS_EXT > 20 - if ((vwrq->flags & IW_RETRY_SHORT) ||(vwrq->flags & IW_RETRY_MIN) || - !((vwrq->flags & IW_RETRY_LONG) || (vwrq->flags & IW_RETRY_MAX))) { -#else - if ((vwrq->flags & IW_RETRY_MIN) || !(vwrq->flags & IW_RETRY_MAX)) { -#endif - srl = htod32(vwrq->value); - if ((error = dev_wlc_ioctl(dev, WLC_SET_SRL, &srl, sizeof(srl)))) - return error; - } - } - return 0; -} - -static int -wl_iw_get_retry( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, lrl, srl; - - WL_TRACE(("%s: SIOCGIWRETRY\n", dev->name)); - - vwrq->disabled = 0; - - - if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) - return -EINVAL; - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_LRL, &lrl, sizeof(lrl))) || - (error = dev_wlc_ioctl(dev, WLC_GET_SRL, &srl, sizeof(srl)))) - return error; - - lrl = dtoh32(lrl); - srl = dtoh32(srl); - - - if (vwrq->flags & IW_RETRY_MAX) { - vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; - vwrq->value = lrl; - } else { - vwrq->flags = IW_RETRY_LIMIT; - vwrq->value = srl; - if (srl != lrl) - vwrq->flags |= IW_RETRY_MIN; - } - - return 0; -} -#endif - -static int -wl_iw_set_encode( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_wsec_key_t key; - int error, val, wsec; - - WL_TRACE(("%s: SIOCSIWENCODE index %d, len %d, flags %04x (%s%s%s%s%s)\n", - dev->name, dwrq->flags & IW_ENCODE_INDEX, dwrq->length, dwrq->flags, - dwrq->flags & IW_ENCODE_NOKEY ? "NOKEY" : "", - dwrq->flags & IW_ENCODE_DISABLED ? " DISABLED" : "", - dwrq->flags & IW_ENCODE_RESTRICTED ? " RESTRICTED" : "", - dwrq->flags & IW_ENCODE_OPEN ? " OPEN" : "", - dwrq->flags & IW_ENCODE_TEMP ? " TEMP" : "")); - - memset(&key, 0, sizeof(key)); - - if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { - - for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) { - val = htod32(key.index); - if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val)))) - return error; - val = dtoh32(val); - if (val) - break; - } - - if (key.index == DOT11_MAX_DEFAULT_KEYS) - key.index = 0; - } else { - key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - if (key.index >= DOT11_MAX_DEFAULT_KEYS) - return -EINVAL; - } - - - if (!extra || !dwrq->length || (dwrq->flags & IW_ENCODE_NOKEY)) { - - val = htod32(key.index); - if ((error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, &val, sizeof(val)))) - return error; - } else { - key.len = dwrq->length; - - if (dwrq->length > sizeof(key.data)) - return -EINVAL; - - memcpy(key.data, extra, dwrq->length); - - key.flags = WL_PRIMARY_KEY; - switch (key.len) { - case WEP1_KEY_SIZE: - key.algo = CRYPTO_ALGO_WEP1; - break; - case WEP128_KEY_SIZE: - key.algo = CRYPTO_ALGO_WEP128; - break; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) - case TKIP_KEY_SIZE: - key.algo = CRYPTO_ALGO_TKIP; - break; -#endif - case AES_KEY_SIZE: - key.algo = CRYPTO_ALGO_AES_CCM; - break; - default: - return -EINVAL; - } - - - swap_key_from_BE(&key); - if ((error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)))) - return error; - } - - - val = (dwrq->flags & IW_ENCODE_DISABLED) ? 0 : WEP_ENABLED; - - if ((error = dev_wlc_intvar_get(dev, "wsec", &wsec))) - return error; - - wsec &= ~(WEP_ENABLED); - wsec |= val; - - if ((error = dev_wlc_intvar_set(dev, "wsec", wsec))) - return error; - - - val = (dwrq->flags & IW_ENCODE_RESTRICTED) ? 1 : 0; - val = htod32(val); - if ((error = dev_wlc_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val)))) - return error; - - return 0; -} - -static int -wl_iw_get_encode( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_wsec_key_t key; - int error, val, wsec, auth; - - WL_TRACE(("%s: SIOCGIWENCODE\n", dev->name)); - - - bzero(&key, sizeof(wl_wsec_key_t)); - - if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { - - for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) { - val = key.index; - if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val)))) - return error; - val = dtoh32(val); - if (val) - break; - } - } else - key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - - if (key.index >= DOT11_MAX_DEFAULT_KEYS) - key.index = 0; - - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec))) || - (error = dev_wlc_ioctl(dev, WLC_GET_AUTH, &auth, sizeof(auth)))) - return error; - - swap_key_to_BE(&key); - - wsec = dtoh32(wsec); - auth = dtoh32(auth); - - dwrq->length = MIN(DOT11_MAX_KEY_SIZE, key.len); - - - dwrq->flags = key.index + 1; - if (!(wsec & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))) { - - dwrq->flags |= IW_ENCODE_DISABLED; - } - if (auth) { - - dwrq->flags |= IW_ENCODE_RESTRICTED; - } - - - if (dwrq->length && extra) - memcpy(extra, key.data, dwrq->length); - - return 0; -} - -static int -wl_iw_set_power( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, pm; - - WL_TRACE(("%s: SIOCSIWPOWER\n", dev->name)); - - pm = vwrq->disabled ? PM_OFF : PM_MAX; - - pm = htod32(pm); - if ((error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)))) - return error; - - return 0; -} - -static int -wl_iw_get_power( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, pm; - - WL_TRACE(("%s: SIOCGIWPOWER\n", dev->name)); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm)))) - return error; - - pm = dtoh32(pm); - vwrq->disabled = pm ? 0 : 1; - vwrq->flags = IW_POWER_ALL_R; - - return 0; -} - -#if WIRELESS_EXT > 17 -static int -wl_iw_set_wpaie( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *iwp, - char *extra -) -{ - - WL_TRACE(("%s: SIOCSIWGENIE\n", dev->name)); - - RETURN_IF_EXTRA_NULL(extra); - -#ifdef DHD_DEBUG - { - int i; - - for (i = 0; i < iwp->length; i++) - WL_TRACE(("%02X ", extra[i])); - WL_TRACE(("\n")); - } -#endif - - dev_wlc_bufvar_set(dev, "wpaie", extra, iwp->length); - - return 0; -} - -static int -wl_iw_get_wpaie( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *iwp, - char *extra -) -{ - WL_TRACE(("%s: SIOCGIWGENIE\n", dev->name)); - iwp->length = 64; - dev_wlc_bufvar_get(dev, "wpaie", extra, iwp->length); - return 0; -} - -static int -wl_iw_set_encodeext( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_wsec_key_t key; - int error; - struct iw_encode_ext *iwe; - - WL_TRACE(("%s: SIOCSIWENCODEEXT\n", dev->name)); - - RETURN_IF_EXTRA_NULL(extra); - - memset(&key, 0, sizeof(key)); - iwe = (struct iw_encode_ext *)extra; - - - if (dwrq->flags & IW_ENCODE_DISABLED) { - - } - - - key.index = 0; - if (dwrq->flags & IW_ENCODE_INDEX) - key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - - key.len = iwe->key_len; - - - if (!ETHER_ISMULTI(iwe->addr.sa_data)) - bcopy((void *)&iwe->addr.sa_data, (char *)&key.ea, ETHER_ADDR_LEN); - - - if (key.len == 0) { - if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - WL_WSEC(("Changing the the primary Key to %d\n", key.index)); - - key.index = htod32(key.index); - error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, - &key.index, sizeof(key.index)); - if (error) - return error; - } - - else { - swap_key_from_BE(&key); - dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - } - } - else { - if (iwe->key_len > sizeof(key.data)) - return -EINVAL; - - WL_WSEC(("Setting the key index %d\n", key.index)); - if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - WL_WSEC(("key is a Primary Key\n")); - key.flags = WL_PRIMARY_KEY; - } - - bcopy((void *)iwe->key, key.data, iwe->key_len); - - if (iwe->alg == IW_ENCODE_ALG_TKIP) { - uint8 keybuf[8]; - bcopy(&key.data[24], keybuf, sizeof(keybuf)); - bcopy(&key.data[16], &key.data[24], sizeof(keybuf)); - bcopy(keybuf, &key.data[16], sizeof(keybuf)); - } - - - if (iwe->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { - uchar *ivptr; - ivptr = (uchar *)iwe->rx_seq; - key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) | - (ivptr[3] << 8) | ivptr[2]; - key.rxiv.lo = (ivptr[1] << 8) | ivptr[0]; - key.iv_initialized = TRUE; - } - - switch (iwe->alg) { - case IW_ENCODE_ALG_NONE: - key.algo = CRYPTO_ALGO_OFF; - break; - case IW_ENCODE_ALG_WEP: - if (iwe->key_len == WEP1_KEY_SIZE) - key.algo = CRYPTO_ALGO_WEP1; - else - key.algo = CRYPTO_ALGO_WEP128; - break; - case IW_ENCODE_ALG_TKIP: - key.algo = CRYPTO_ALGO_TKIP; - break; - case IW_ENCODE_ALG_CCMP: - key.algo = CRYPTO_ALGO_AES_CCM; - break; - default: - break; - } - swap_key_from_BE(&key); - - dhd_wait_pend8021x(dev); - - error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - if (error) - return error; - } - return 0; -} - -#if WIRELESS_EXT > 17 -struct { - pmkid_list_t pmkids; - pmkid_t foo[MAXPMKID-1]; -} pmkid_list; - -static int -wl_iw_set_pmksa( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - struct iw_pmksa *iwpmksa; - uint i; - int ret = 0; - char eabuf[ETHER_ADDR_STR_LEN]; - pmkid_t * pmkid_array = pmkid_list.pmkids.pmkid; - - WL_WSEC(("%s: SIOCSIWPMKSA\n", dev->name)); - - RETURN_IF_EXTRA_NULL(extra); - - iwpmksa = (struct iw_pmksa *)extra; - bzero((char *)eabuf, ETHER_ADDR_STR_LEN); - - if (iwpmksa->cmd == IW_PMKSA_FLUSH) { - WL_WSEC(("wl_iw_set_pmksa - IW_PMKSA_FLUSH\n")); - bzero((char *)&pmkid_list, sizeof(pmkid_list)); - } - - else if (iwpmksa->cmd == IW_PMKSA_REMOVE) { - { - pmkid_list_t pmkid, *pmkidptr; - uint j; - pmkidptr = &pmkid; - - bcopy(&iwpmksa->bssid.sa_data[0], &pmkidptr->pmkid[0].BSSID, - ETHER_ADDR_LEN); - bcopy(&iwpmksa->pmkid[0], &pmkidptr->pmkid[0].PMKID, WPA2_PMKID_LEN); - - WL_WSEC(("wl_iw_set_pmksa,IW_PMKSA_REMOVE - PMKID: %s = ", - bcm_ether_ntoa(&pmkidptr->pmkid[0].BSSID, - eabuf))); - for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", pmkidptr->pmkid[0].PMKID[j])); - WL_WSEC(("\n")); - } - - for (i = 0; i < pmkid_list.pmkids.npmkid; i++) - if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_array[i].BSSID, - ETHER_ADDR_LEN)) - break; - - if ((pmkid_list.pmkids.npmkid > 0) && (i < pmkid_list.pmkids.npmkid)) { - bzero(&pmkid_array[i], sizeof(pmkid_t)); - for (; i < (pmkid_list.pmkids.npmkid - 1); i++) { - bcopy(&pmkid_array[i+1].BSSID, - &pmkid_array[i].BSSID, - ETHER_ADDR_LEN); - bcopy(&pmkid_array[i+1].PMKID, - &pmkid_array[i].PMKID, - WPA2_PMKID_LEN); - } - pmkid_list.pmkids.npmkid--; - } - else - ret = -EINVAL; - } - - else if (iwpmksa->cmd == IW_PMKSA_ADD) { - for (i = 0; i < pmkid_list.pmkids.npmkid; i++) - if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_array[i].BSSID, - ETHER_ADDR_LEN)) - break; - if (i < MAXPMKID) { - bcopy(&iwpmksa->bssid.sa_data[0], - &pmkid_array[i].BSSID, - ETHER_ADDR_LEN); - bcopy(&iwpmksa->pmkid[0], &pmkid_array[i].PMKID, - WPA2_PMKID_LEN); - if (i == pmkid_list.pmkids.npmkid) - pmkid_list.pmkids.npmkid++; - } - else - ret = -EINVAL; - - { - uint j; - uint k; - k = pmkid_list.pmkids.npmkid; - WL_WSEC(("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %s = ", - bcm_ether_ntoa(&pmkid_array[k].BSSID, - eabuf))); - for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", pmkid_array[k].PMKID[j])); - WL_WSEC(("\n")); - } - } - WL_WSEC(("PRINTING pmkid LIST - No of elements %d", pmkid_list.pmkids.npmkid)); - for (i = 0; i < pmkid_list.pmkids.npmkid; i++) { - uint j; - WL_WSEC(("\nPMKID[%d]: %s = ", i, - bcm_ether_ntoa(&pmkid_array[i].BSSID, - eabuf))); - for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", pmkid_array[i].PMKID[j])); - } - WL_WSEC(("\n")); - - if (!ret) - ret = dev_wlc_bufvar_set(dev, "pmkid_info", (char *)&pmkid_list, - sizeof(pmkid_list)); - return ret; -} -#endif - -static int -wl_iw_get_encodeext( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - WL_TRACE(("%s: SIOCGIWENCODEEXT\n", dev->name)); - return 0; -} - - -static uint32 -wl_iw_create_wpaauth_wsec(struct net_device *dev) -{ - wl_iw_t *iw = NETDEV_PRIV(dev); - uint32 wsec; - - - if (iw->pcipher & (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) - wsec = WEP_ENABLED; - else if (iw->pcipher & IW_AUTH_CIPHER_TKIP) - wsec = TKIP_ENABLED; - else if (iw->pcipher & IW_AUTH_CIPHER_CCMP) - wsec = AES_ENABLED; - else - wsec = 0; - - - if (iw->gcipher & (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) - wsec |= WEP_ENABLED; - else if (iw->gcipher & IW_AUTH_CIPHER_TKIP) - wsec |= TKIP_ENABLED; - else if (iw->gcipher & IW_AUTH_CIPHER_CCMP) - wsec |= AES_ENABLED; - - - if (wsec == 0 && iw->privacy_invoked) - wsec = WEP_ENABLED; - - WL_INFORM(("%s: returning wsec of %d\n", __FUNCTION__, wsec)); - - return wsec; -} - -static int -wl_iw_set_wpaauth( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error = 0; - int paramid; - int paramval; - int val = 0; - wl_iw_t *iw = NETDEV_PRIV(dev); - - paramid = vwrq->flags & IW_AUTH_INDEX; - paramval = vwrq->value; - - WL_TRACE(("%s: SIOCSIWAUTH, %s(%d), paramval = 0x%0x\n", - dev->name, - paramid == IW_AUTH_WPA_VERSION ? "IW_AUTH_WPA_VERSION" : - paramid == IW_AUTH_CIPHER_PAIRWISE ? "IW_AUTH_CIPHER_PAIRWISE" : - paramid == IW_AUTH_CIPHER_GROUP ? "IW_AUTH_CIPHER_GROUP" : - paramid == IW_AUTH_KEY_MGMT ? "IW_AUTH_KEY_MGMT" : - paramid == IW_AUTH_TKIP_COUNTERMEASURES ? "IW_AUTH_TKIP_COUNTERMEASURES" : - paramid == IW_AUTH_DROP_UNENCRYPTED ? "IW_AUTH_DROP_UNENCRYPTED" : - paramid == IW_AUTH_80211_AUTH_ALG ? "IW_AUTH_80211_AUTH_ALG" : - paramid == IW_AUTH_WPA_ENABLED ? "IW_AUTH_WPA_ENABLED" : - paramid == IW_AUTH_RX_UNENCRYPTED_EAPOL ? "IW_AUTH_RX_UNENCRYPTED_EAPOL" : - paramid == IW_AUTH_ROAMING_CONTROL ? "IW_AUTH_ROAMING_CONTROL" : - paramid == IW_AUTH_PRIVACY_INVOKED ? "IW_AUTH_PRIVACY_INVOKED" : - "UNKNOWN", - paramid, paramval)); - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_TRACE(("%s: Not executed, reason -'SOFTAP is active'\n", __FUNCTION__)); - return 0; - } -#endif - - switch (paramid) { - case IW_AUTH_WPA_VERSION: - - if (paramval & IW_AUTH_WPA_VERSION_DISABLED) - val = WPA_AUTH_DISABLED; - else if (paramval & (IW_AUTH_WPA_VERSION_WPA)) - val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED; - else if (paramval & IW_AUTH_WPA_VERSION_WPA2) - val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED; - WL_ERROR(("%s: %d: setting wpa_auth to 0x%0x\n", __FUNCTION__, __LINE__, val)); - if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val))) - return error; - break; - - case IW_AUTH_CIPHER_PAIRWISE: - iw->pcipher = paramval; - val = wl_iw_create_wpaauth_wsec(dev); - if ((error = dev_wlc_intvar_set(dev, "wsec", val))) - return error; - break; - - case IW_AUTH_CIPHER_GROUP: - iw->gcipher = paramval; - val = wl_iw_create_wpaauth_wsec(dev); - if ((error = dev_wlc_intvar_set(dev, "wsec", val))) - return error; - break; - - case IW_AUTH_KEY_MGMT: - if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) - return error; - - if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) { - if (paramval & IW_AUTH_KEY_MGMT_PSK) - val = WPA_AUTH_PSK; - else - val = WPA_AUTH_UNSPECIFIED; - if (paramval & 0x04) - val |= WPA2_AUTH_FT; - } - else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) { - if (paramval & IW_AUTH_KEY_MGMT_PSK) - val = WPA2_AUTH_PSK; - else - val = WPA2_AUTH_UNSPECIFIED; - if (paramval & 0x04) - val |= WPA2_AUTH_FT; - } - - else if (paramval & IW_AUTH_KEY_MGMT_PSK) { - if (iw->wpaversion == IW_AUTH_WPA_VERSION_WPA) - val = WPA_AUTH_PSK; - else if (iw->wpaversion == IW_AUTH_WPA_VERSION_WPA2) - val = WPA2_AUTH_PSK; - else - val = WPA_AUTH_DISABLED; - } else if (paramval & IW_AUTH_KEY_MGMT_802_1X) { - if (iw->wpaversion == IW_AUTH_WPA_VERSION_WPA) - val = WPA_AUTH_UNSPECIFIED; - else if (iw->wpaversion == IW_AUTH_WPA_VERSION_WPA2) - val = WPA2_AUTH_UNSPECIFIED; - else - val = WPA_AUTH_DISABLED; - } - else - val = WPA_AUTH_DISABLED; - - WL_INFORM(("%s: %d: setting wpa_auth to %d\n", __FUNCTION__, __LINE__, val)); - if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val))) - return error; - break; - - case IW_AUTH_TKIP_COUNTERMEASURES: - dev_wlc_bufvar_set(dev, "tkip_countermeasures", (char *)¶mval, 1); - break; - - case IW_AUTH_80211_AUTH_ALG: - - WL_INFORM(("Setting the D11auth %d\n", paramval)); - if (paramval == IW_AUTH_ALG_OPEN_SYSTEM) - val = 0; - else if (paramval == IW_AUTH_ALG_SHARED_KEY) - val = 1; - else if (paramval == (IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY)) - val = 2; - else - error = 1; - if (!error && (error = dev_wlc_intvar_set(dev, "auth", val))) - return error; - break; - - case IW_AUTH_WPA_ENABLED: - if (paramval == 0) { - iw->privacy_invoked = 0; - iw->pcipher = 0; - iw->gcipher = 0; - val = wl_iw_create_wpaauth_wsec(dev); - if ((error = dev_wlc_intvar_set(dev, "wsec", val))) - return error; - WL_INFORM(("%s: %d: setting wpa_auth to %d, wsec to %d\n", - __FUNCTION__, __LINE__, paramval, val)); - dev_wlc_intvar_set(dev, "wpa_auth", paramval); - return error; - } - - - break; - - case IW_AUTH_DROP_UNENCRYPTED: - if ((error = dev_wlc_intvar_set(dev, "wsec_restrict", paramval))) - return error; - break; - - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - dev_wlc_bufvar_set(dev, "rx_unencrypted_eapol", (char *)¶mval, 1); - break; - -#if WIRELESS_EXT > 17 - case IW_AUTH_ROAMING_CONTROL: - WL_INFORM(("%s: IW_AUTH_ROAMING_CONTROL\n", __FUNCTION__)); - - break; - - case IW_AUTH_PRIVACY_INVOKED: - iw->privacy_invoked = paramval; - val = wl_iw_create_wpaauth_wsec(dev); - if ((error = dev_wlc_intvar_set(dev, "wsec", val))) - return error; - break; - -#endif - default: - break; - } - return 0; -} -#define VAL_PSK(_val) (((_val) & WPA_AUTH_PSK) || ((_val) & WPA2_AUTH_PSK)) - -static int -wl_iw_get_wpaauth( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error; - int paramid; - int paramval = 0; - int val; - wl_iw_t *iw = NETDEV_PRIV(dev); - - WL_TRACE(("%s: SIOCGIWAUTH\n", dev->name)); - - paramid = vwrq->flags & IW_AUTH_INDEX; - - switch (paramid) { - case IW_AUTH_WPA_VERSION: - paramval = iw->wpaversion; - break; - - case IW_AUTH_CIPHER_PAIRWISE: - paramval = iw->pcipher; - break; - - case IW_AUTH_CIPHER_GROUP: - paramval = iw->gcipher; - break; - - case IW_AUTH_KEY_MGMT: - - if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) - return error; - if (VAL_PSK(val)) - paramval = IW_AUTH_KEY_MGMT_PSK; - else - paramval = IW_AUTH_KEY_MGMT_802_1X; - - break; - - case IW_AUTH_TKIP_COUNTERMEASURES: - dev_wlc_bufvar_get(dev, "tkip_countermeasures", (char *)¶mval, 1); - break; - - case IW_AUTH_DROP_UNENCRYPTED: - dev_wlc_intvar_get(dev, "wsec_restrict", ¶mval); - break; - - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - dev_wlc_bufvar_get(dev, "rx_unencrypted_eapol", (char *)¶mval, 1); - break; - - case IW_AUTH_80211_AUTH_ALG: - - if ((error = dev_wlc_intvar_get(dev, "auth", &val))) - return error; - if (!val) - paramval = IW_AUTH_ALG_OPEN_SYSTEM; - else - paramval = IW_AUTH_ALG_SHARED_KEY; - break; - case IW_AUTH_WPA_ENABLED: - if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) - return error; - if (val) - paramval = TRUE; - else - paramval = FALSE; - break; -#if WIRELESS_EXT > 17 - case IW_AUTH_ROAMING_CONTROL: - WL_ERROR(("%s: IW_AUTH_ROAMING_CONTROL\n", __FUNCTION__)); - - break; - case IW_AUTH_PRIVACY_INVOKED: - paramval = iw->privacy_invoked; - break; - -#endif - } - vwrq->value = paramval; - return 0; -} -#endif - - -#ifdef SOFTAP - -static int ap_macmode = MACLIST_MODE_DISABLED; -static struct mflist ap_black_list; - -static int -wl_iw_parse_wep(char *keystr, wl_wsec_key_t *key) -{ - char hex[] = "XX"; - unsigned char *data = key->data; - - switch (strlen(keystr)) { - case 5: - case 13: - case 16: - key->len = strlen(keystr); - memcpy(data, keystr, key->len + 1); - break; - case 12: - case 28: - case 34: - case 66: - - if (!strnicmp(keystr, "0x", 2)) - keystr += 2; - else - return -1; - - case 10: - case 26: - case 32: - case 64: - key->len = strlen(keystr) / 2; - while (*keystr) { - strncpy(hex, keystr, 2); - *data++ = (char) bcm_strtoul(hex, NULL, 16); - keystr += 2; - } - break; - default: - return -1; - } - - switch (key->len) { - case 5: - key->algo = CRYPTO_ALGO_WEP1; - break; - case 13: - key->algo = CRYPTO_ALGO_WEP128; - break; - case 16: - - key->algo = CRYPTO_ALGO_AES_CCM; - break; - case 32: - key->algo = CRYPTO_ALGO_TKIP; - break; - default: - return -1; - } - - - key->flags |= WL_PRIMARY_KEY; - - return 0; -} - -#ifdef EXT_WPA_CRYPTO -#define SHA1HashSize 20 -extern void pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len, - int iterations, u8 *buf, size_t buflen); - -#else - -#define SHA1HashSize 20 -static int -pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len, - int iterations, u8 *buf, size_t buflen) -{ - WL_ERROR(("WARNING: %s is not implemented !!!\n", __FUNCTION__)); - return -1; -} - -#endif - - -static int -dev_iw_write_cfg1_bss_var(struct net_device *dev, int val) -{ - struct { - int cfg; - int val; - } bss_setbuf; - - int bss_set_res; - char smbuf[WLC_IOCTL_SMLEN]; - memset(smbuf, 0, sizeof(smbuf)); - - bss_setbuf.cfg = 1; - bss_setbuf.val = val; - - bss_set_res = dev_iw_iovar_setbuf(dev, "bss", - &bss_setbuf, sizeof(bss_setbuf), smbuf, sizeof(smbuf)); - WL_TRACE(("%s: bss_set_result:%d set with %d\n", __FUNCTION__, bss_set_res, val)); - - return bss_set_res; -} - - - -#ifndef AP_ONLY -static int -wl_bssiovar_mkbuf( - const char *iovar, - int bssidx, - void *param, - int paramlen, - void *bufptr, - int buflen, - int *perr) -{ - const char *prefix = "bsscfg:"; - int8* p; - uint prefixlen; - uint namelen; - uint iolen; - - prefixlen = strlen(prefix); - namelen = strlen(iovar) + 1; - iolen = prefixlen + namelen + sizeof(int) + paramlen; - - - if (buflen < 0 || iolen > (uint)buflen) { - *perr = BCME_BUFTOOSHORT; - return 0; - } - - p = (int8*)bufptr; - - - memcpy(p, prefix, prefixlen); - p += prefixlen; - - - memcpy(p, iovar, namelen); - p += namelen; - - - bssidx = htod32(bssidx); - memcpy(p, &bssidx, sizeof(int32)); - p += sizeof(int32); - - - if (paramlen) - memcpy(p, param, paramlen); - - *perr = 0; - return iolen; -} -#endif - - - - -#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) - - -#if defined(CSCAN) - - - -static int -wl_iw_combined_scan_set(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid, int nchan) -{ - int params_size = WL_SCAN_PARAMS_FIXED_SIZE + WL_NUMCHANNELS * sizeof(uint16); - int err = 0; - char *p; - int i; - iscan_info_t *iscan = g_iscan; - - WL_TRACE(("%s nssid=%d nchan=%d\n", __FUNCTION__, nssid, nchan)); - - if ((!dev) && (!g_iscan) && (!iscan->iscan_ex_params_p)) { - WL_ERROR(("%s error exit\n", __FUNCTION__)); - err = -1; - goto exit; - } - -#ifdef PNO_SUPPORT - - if (dhd_dev_get_pno_status(dev)) { - WL_ERROR(("%s: Scan called when PNO is active\n", __FUNCTION__)); - } -#endif - - params_size += WL_SCAN_PARAMS_SSID_MAX * sizeof(wlc_ssid_t); - - - if (nssid > 0) { - i = OFFSETOF(wl_scan_params_t, channel_list) + nchan * sizeof(uint16); - i = ROUNDUP(i, sizeof(uint32)); - if (i + nssid * sizeof(wlc_ssid_t) > params_size) { - printf("additional ssids exceed params_size\n"); - err = -1; - goto exit; - } - - p = ((char*)&iscan->iscan_ex_params_p->params) + i; - memcpy(p, ssids_local, nssid * sizeof(wlc_ssid_t)); - p += nssid * sizeof(wlc_ssid_t); - } else { - p = (char*)iscan->iscan_ex_params_p->params.channel_list + nchan * sizeof(uint16); - } - - - iscan->iscan_ex_params_p->params.channel_num = - htod32((nssid << WL_SCAN_PARAMS_NSSID_SHIFT) | - (nchan & WL_SCAN_PARAMS_COUNT_MASK)); - - nssid = (uint) - ((iscan->iscan_ex_params_p->params.channel_num >> WL_SCAN_PARAMS_NSSID_SHIFT) & - WL_SCAN_PARAMS_COUNT_MASK); - - - params_size = (int) (p - (char*)iscan->iscan_ex_params_p + nssid * sizeof(wlc_ssid_t)); - iscan->iscan_ex_param_size = params_size; - - iscan->list_cur = iscan->list_hdr; - iscan->iscan_state = ISCAN_STATE_SCANING; - wl_iw_set_event_mask(dev); - mod_timer(&iscan->timer, jiffies + msecs_to_jiffies(iscan->timer_ms)); - - iscan->timer_on = 1; - -#ifdef SCAN_DUMP - { - int i; - WL_SCAN(("\n### List of SSIDs to scan ###\n")); - for (i = 0; i < nssid; i++) { - if (!ssids_local[i].SSID_len) - WL_SCAN(("%d: Broadcast scan\n", i)); - else - WL_SCAN(("%d: scan for %s size =%d\n", i, - ssids_local[i].SSID, ssids_local[i].SSID_len)); - } - WL_SCAN(("### List of channels to scan ###\n")); - for (i = 0; i < nchan; i++) - { - WL_SCAN(("%d ", iscan->iscan_ex_params_p->params.channel_list[i])); - } - WL_SCAN(("\nnprobes=%d\n", iscan->iscan_ex_params_p->params.nprobes)); - WL_SCAN(("active_time=%d\n", iscan->iscan_ex_params_p->params.active_time)); - WL_SCAN(("passive_time=%d\n", iscan->iscan_ex_params_p->params.passive_time)); - WL_SCAN(("home_time=%d\n", iscan->iscan_ex_params_p->params.home_time)); - WL_SCAN(("scan_type=%d\n", iscan->iscan_ex_params_p->params.scan_type)); - WL_SCAN(("\n###################\n")); - } -#endif - - if (params_size > WLC_IOCTL_MEDLEN) { - WL_ERROR(("Set ISCAN for %s due to params_size=%d \n", - __FUNCTION__, params_size)); - err = -1; - } - - if ((err = dev_iw_iovar_setbuf(dev, "iscan", iscan->iscan_ex_params_p, - iscan->iscan_ex_param_size, - iscan->ioctlbuf, sizeof(iscan->ioctlbuf)))) { - WL_TRACE(("Set ISCAN for %s failed with %d\n", __FUNCTION__, err)); - err = -1; - } - -exit: - return err; -} - - -static int -iwpriv_set_cscan(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *ext) -{ - int res; - char *extra = NULL; - iscan_info_t *iscan = g_iscan; - wlc_ssid_t ssids_local[WL_SCAN_PARAMS_SSID_MAX]; - int nssid = 0; - int nchan = 0; - char *str_ptr; - - WL_TRACE(("%s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); - return -ENODEV; - } - - if (wrqu->data.length == 0) { - WL_ERROR(("IWPRIV argument len = 0\n")); - return -EINVAL; - } - - if (!iscan->iscan_ex_params_p) { - return -EFAULT; - } - - if (!(extra = kmalloc(wrqu->data.length+1, GFP_KERNEL))) - return -ENOMEM; - - if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) { - res = -EFAULT; - goto exit_proc; - } - - extra[wrqu->data.length] = 0; - WL_ERROR(("Got str param in iw_point:\n %s\n", extra)); - - str_ptr = extra; - - - if (strncmp(str_ptr, GET_SSID, strlen(GET_SSID))) { - WL_ERROR(("%s Error: extracting SSID='' string\n", __FUNCTION__)); - res = -EINVAL; - goto exit_proc; - } - - str_ptr += strlen(GET_SSID); - nssid = wl_iw_parse_ssid_list(&str_ptr, ssids_local, nssid, - WL_SCAN_PARAMS_SSID_MAX); - if (nssid == -1) { - WL_ERROR(("%s wrong ssid list", __FUNCTION__)); - res = -EINVAL; - goto exit_proc; - } - - memset(iscan->iscan_ex_params_p, 0, iscan->iscan_ex_param_size); - ASSERT(iscan->iscan_ex_param_size < WLC_IOCTL_MAXLEN); - - - wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, NULL); - iscan->iscan_ex_params_p->version = htod32(ISCAN_REQ_VERSION); - iscan->iscan_ex_params_p->action = htod16(WL_SCAN_ACTION_START); - iscan->iscan_ex_params_p->scan_duration = htod16(0); - - - if ((nchan = wl_iw_parse_channel_list(&str_ptr, - &iscan->iscan_ex_params_p->params.channel_list[0], - WL_NUMCHANNELS)) == -1) { - WL_ERROR(("%s missing channel list\n", __FUNCTION__)); - res = -EINVAL; - goto exit_proc; - } - - - get_parameter_from_string(&str_ptr, - GET_NPROBE, PTYPE_INTDEC, - &iscan->iscan_ex_params_p->params.nprobes, 2); - - get_parameter_from_string(&str_ptr, GET_ACTIVE_ASSOC_DWELL, PTYPE_INTDEC, - &iscan->iscan_ex_params_p->params.active_time, 4); - - get_parameter_from_string(&str_ptr, GET_PASSIVE_ASSOC_DWELL, PTYPE_INTDEC, - &iscan->iscan_ex_params_p->params.passive_time, 4); - - get_parameter_from_string(&str_ptr, GET_HOME_DWELL, PTYPE_INTDEC, - &iscan->iscan_ex_params_p->params.home_time, 4); - - get_parameter_from_string(&str_ptr, GET_SCAN_TYPE, PTYPE_INTDEC, - &iscan->iscan_ex_params_p->params.scan_type, 1); - - - res = wl_iw_combined_scan_set(dev, ssids_local, nssid, nchan); - -exit_proc: - kfree(extra); - - return res; -} - - -static int -wl_iw_set_cscan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int res = -1; - iscan_info_t *iscan = g_iscan; - wlc_ssid_t ssids_local[WL_SCAN_PARAMS_SSID_MAX]; - int nssid = 0; - int nchan = 0; - cscan_tlv_t *cscan_tlv_temp; - char type; - char *str_ptr; - int tlv_size_left; -#ifdef TLV_DEBUG - int i; - char tlv_in_example[] = { - 'C', 'S', 'C', 'A', 'N', ' ', - 0x53, 0x01, 0x00, 0x00, - 'S', - 0x00, - 'S', - 0x04, - 'B', 'R', 'C', 'M', - 'C', - 0x06, - 'P', - 0x94, - 0x11, - 'T', - 0x01 - }; -#endif - - WL_TRACE(("\n### %s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - net_os_wake_lock(dev); - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); - return -1; - } - - if (wrqu->data.length < (strlen(CSCAN_COMMAND) + sizeof(cscan_tlv_t))) { - WL_ERROR(("%s argument=%d less %d\n", __FUNCTION__, - wrqu->data.length, (int)(strlen(CSCAN_COMMAND) + sizeof(cscan_tlv_t)))); - return -1; - } - -#ifdef TLV_DEBUG - memcpy(extra, tlv_in_example, sizeof(tlv_in_example)); - wrqu->data.length = sizeof(tlv_in_example); - for (i = 0; i < wrqu->data.length; i++) - printf("%02X ", extra[i]); - printf("\n"); -#endif - - str_ptr = extra; - str_ptr += strlen(CSCAN_COMMAND); - tlv_size_left = wrqu->data.length - strlen(CSCAN_COMMAND); - - cscan_tlv_temp = (cscan_tlv_t *)str_ptr; - memset(ssids_local, 0, sizeof(ssids_local)); - - if ((cscan_tlv_temp->prefix == CSCAN_TLV_PREFIX) && - (cscan_tlv_temp->version == CSCAN_TLV_VERSION) && - (cscan_tlv_temp->subver == CSCAN_TLV_SUBVERSION)) - { - str_ptr += sizeof(cscan_tlv_t); - tlv_size_left -= sizeof(cscan_tlv_t); - - - if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local, - WL_SCAN_PARAMS_SSID_MAX, &tlv_size_left)) <= 0) { - WL_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid)); - goto exit_proc; - } - else { - - memset(iscan->iscan_ex_params_p, 0, iscan->iscan_ex_param_size); - - - wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, NULL); - iscan->iscan_ex_params_p->version = htod32(ISCAN_REQ_VERSION); - iscan->iscan_ex_params_p->action = htod16(WL_SCAN_ACTION_START); - iscan->iscan_ex_params_p->scan_duration = htod16(0); - - - while (tlv_size_left > 0) - { - type = str_ptr[0]; - switch (type) { - case CSCAN_TLV_TYPE_CHANNEL_IE: - - if ((nchan = wl_iw_parse_channel_list_tlv(&str_ptr, - &iscan->iscan_ex_params_p->params.channel_list[0], - WL_NUMCHANNELS, &tlv_size_left)) == -1) { - WL_ERROR(("%s missing channel list\n", - __FUNCTION__)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_NPROBE_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, - &iscan->iscan_ex_params_p->params.nprobes, - sizeof(iscan->iscan_ex_params_p->params.nprobes), - type, sizeof(char), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", - __FUNCTION__, res)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_ACTIVE_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, - &iscan->iscan_ex_params_p->params.active_time, - sizeof(iscan->iscan_ex_params_p->params.active_time), - type, sizeof(short), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", - __FUNCTION__, res)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_PASSIVE_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, - &iscan->iscan_ex_params_p->params.passive_time, - sizeof(iscan->iscan_ex_params_p->params.passive_time), - type, sizeof(short), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", - __FUNCTION__, res)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_HOME_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, - &iscan->iscan_ex_params_p->params.home_time, - sizeof(iscan->iscan_ex_params_p->params.home_time), - type, sizeof(short), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", - __FUNCTION__, res)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_STYPE_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, - &iscan->iscan_ex_params_p->params.scan_type, - sizeof(iscan->iscan_ex_params_p->params.scan_type), - type, sizeof(char), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", - __FUNCTION__, res)); - goto exit_proc; - } - break; - - default : - WL_ERROR(("%s get unkwown type %X\n", - __FUNCTION__, type)); - goto exit_proc; - break; - } - } - } - } - else { - WL_ERROR(("%s get wrong TLV command\n", __FUNCTION__)); - goto exit_proc; - } - -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan < BROADCAST_SCAN_FIRST_RESULT_CONSUMED) { - if (++g_first_counter_scans == MAX_ALLOWED_BLOCK_SCAN_FROM_FIRST_SCAN) { - - WL_ERROR(("%s Clean up First scan flag which is %d\n", - __FUNCTION__, g_first_broadcast_scan)); - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_CONSUMED; - } - else { - WL_ERROR(("%s Ignoring CSCAN : First Scan is not done yet %d\n", - __FUNCTION__, g_first_counter_scans)); - return -EBUSY; - } - } -#endif - - - res = wl_iw_combined_scan_set(dev, ssids_local, nssid, nchan); - -exit_proc: - net_os_wake_unlock(dev); - return res; -} - -#endif - -#ifdef CONFIG_WPS2 -static int -wl_iw_del_wps_probe_req_ie( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int ret; - vndr_ie_setbuf_t *ie_delbuf; - - if (g_wps_probe_req_ie) { - ie_delbuf = (vndr_ie_setbuf_t *)(g_wps_probe_req_ie + strlen("vndr_ie ")); - strncpy(ie_delbuf->cmd, "del", 3); - ie_delbuf->cmd[3] = '\0'; - - ret = dev_wlc_ioctl(dev, WLC_SET_VAR, g_wps_probe_req_ie, g_wps_probe_req_ie_len); - if (ret) { - WL_ERROR(("ioctl failed %d \n", ret)); - } - - kfree(g_wps_probe_req_ie); - g_wps_probe_req_ie = NULL; - g_wps_probe_req_ie_len = 0; - } - - return 0; -} - -static int -wl_iw_add_wps_probe_req_ie( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - char *str_ptr = NULL; - char *bufptr = NULL; - uint buflen, datalen, iecount, pktflag, iolen, total_len; - int ret = 0; - vndr_ie_setbuf_t *ie_setbuf = NULL; - - if (!g_wps_probe_req_ie) { - ret = -1; - str_ptr = extra; - str_ptr += WPS_PROBE_REQ_IE_CMD_LENGTH; - datalen = wrqu->data.length - WPS_PROBE_REQ_IE_CMD_LENGTH; - - - - buflen = sizeof(vndr_ie_setbuf_t) + datalen - sizeof(vndr_ie_t); - ie_setbuf = (vndr_ie_setbuf_t *)kmalloc(buflen, GFP_KERNEL); - if (!ie_setbuf) { - WL_ERROR(("memory alloc failure ie_setbuf\n")); - return ret; - } - - memset(ie_setbuf, 0x00, buflen); - - - strncpy(ie_setbuf->cmd, "add", VNDR_IE_CMD_LEN - 1); - ie_setbuf->cmd[VNDR_IE_CMD_LEN - 1] = '\0'; - - - iecount = htod32(1); - memcpy((void *)&ie_setbuf->vndr_ie_buffer.iecount, &iecount, sizeof(int)); - - - pktflag = 0x10; - memcpy((void *)&ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].pktflag, - &pktflag, sizeof(uint32)); - - memcpy((void *)&ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data, - str_ptr, datalen); - - total_len = strlen("vndr_ie ") + buflen; - bufptr = (char *)kmalloc(total_len, GFP_KERNEL); - if (!bufptr) { - WL_ERROR(("memory alloc failure bufptr\n")); - goto fail; - } - - iolen = bcm_mkiovar("vndr_ie", (char *)ie_setbuf, buflen, bufptr, total_len); - if (iolen == 0) { - WL_ERROR(("Buffer length is illegal\n")); - goto fail2; - } - - ret = dev_wlc_ioctl(dev, WLC_SET_VAR, bufptr, iolen); - if (ret) { - WL_ERROR(("ioctl failed\n")); - goto fail2; - } - - g_wps_probe_req_ie = (char *)kmalloc(iolen, GFP_KERNEL); - if (!g_wps_probe_req_ie) { - WL_ERROR(("memory alloc failure g_wps_probe_req_ie\n")); - goto fail2; - } - - memcpy(g_wps_probe_req_ie, bufptr, iolen); - g_wps_probe_req_ie_len = iolen; - } - -fail2: - if (bufptr) { - kfree(bufptr); - bufptr = NULL; - } -fail: - if (ie_setbuf) { - kfree(ie_setbuf); - ie_setbuf = NULL; - } - return ret; -} -#endif - - -#ifdef SOFTAP -#ifndef AP_ONLY - - -static int -thr_wait_for_2nd_eth_dev(void *data) -{ - wl_iw_t *iw; - int ret = 0; - unsigned long flags = 0; - - tsk_ctl_t *tsk_ctl = (tsk_ctl_t *)data; - struct net_device *dev = (struct net_device *)tsk_ctl->parent; - iw = *(wl_iw_t **)netdev_priv(dev); - - DAEMONIZE("wl0_eth_wthread"); - - - WL_SOFTAP(("\n>%s threda started:, PID:%x\n", __FUNCTION__, current->pid)); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - if (!iw) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - tsk_ctl->thr_pid = -1; - complete(&tsk_ctl->completed); - return -1; - } - DHD_OS_WAKE_LOCK(iw->pub); - complete(&tsk_ctl->completed); - if (down_timeout(&tsk_ctl->sema, msecs_to_jiffies(1000)) != 0) { -#else - if (down_interruptible(&tsk_ctl->sema) != 0) { -#endif - WL_ERROR(("\n%s: sap_eth_sema timeout \n", __FUNCTION__)); - ret = -1; - goto fail; - } - - SMP_RD_BARRIER_DEPENDS(); - if (tsk_ctl->terminated) { - ret = -1; - goto fail; - } - - flags = dhd_os_spin_lock(iw->pub); - if (!ap_net_dev) { - WL_ERROR((" ap_net_dev is null !!!")); - ret = -1; - dhd_os_spin_unlock(iw->pub, flags); - goto fail; - } - - WL_SOFTAP(("\n>%s: Thread:'softap ethdev IF:%s is detected!'\n\n", - __FUNCTION__, ap_net_dev->name)); - - ap_cfg_running = TRUE; - - dhd_os_spin_unlock(iw->pub, flags); - bcm_mdelay(500); - - - wl_iw_send_priv_event(priv_dev, "AP_SET_CFG_OK"); - -fail: - - DHD_OS_WAKE_UNLOCK(iw->pub); - - WL_SOFTAP(("\n>%s, thread completed\n", __FUNCTION__)); - - complete_and_exit(&tsk_ctl->completed, 0); - return ret; -} -#endif -#ifndef AP_ONLY -static int last_auto_channel = 6; -#endif - -static int -get_softap_auto_channel(struct net_device *dev, struct ap_profile *ap) -{ - int chosen = 0; - wl_uint32_list_t request; - int retry = 0; - int updown = 0; - int ret = 0; - wlc_ssid_t null_ssid; - int res = 0; -#ifndef AP_ONLY - int iolen = 0; - int mkvar_err = 0; - int bsscfg_index = 1; - char buf[WLC_IOCTL_SMLEN]; -#endif - WL_SOFTAP(("Enter %s\n", __FUNCTION__)); - -#ifndef AP_ONLY - if (ap_cfg_running) { - ap->channel = last_auto_channel; - return res; - } -#endif - - memset(&null_ssid, 0, sizeof(wlc_ssid_t)); - res |= dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown)); - -#ifdef AP_ONLY - res |= dev_wlc_ioctl(dev, WLC_SET_SSID, &null_ssid, sizeof(null_ssid)); -#else - - iolen = wl_bssiovar_mkbuf("ssid", bsscfg_index, (char *)(&null_ssid), - null_ssid.SSID_len+4, buf, sizeof(buf), &mkvar_err); - ASSERT(iolen); - res |= dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen); - -#endif - - request.count = htod32(0); - ret = dev_wlc_ioctl(dev, WLC_START_CHANNEL_SEL, &request, sizeof(request)); - if (ret < 0) { - WL_ERROR(("can't start auto channel scan\n")); - goto fail; - } - - get_channel_retry: - bcm_mdelay(350); - - ret = dev_wlc_ioctl(dev, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen)); - if (ret < 0 || dtoh32(chosen) == 0) { - if (retry++ < 15) { - goto get_channel_retry; - } else { - if (ret < 0) { - WL_ERROR(("can't get auto channel sel, err = %d, " - "chosen = 0x%04X\n", ret, (uint16)chosen)); - goto fail; - } else { - ap->channel = (uint16)last_auto_channel; - WL_ERROR(("auto channel sel timed out. we get channel %d\n", - ap->channel)); - } - } - } - - if (chosen) { - ap->channel = (uint16)chosen & 0x00FF; - WL_SOFTAP(("%s: Got auto channel = %d, attempt:%d\n", - __FUNCTION__, ap->channel, retry)); - } - - if ((res = dev_wlc_ioctl(dev, WLC_DOWN, &updown, sizeof(updown))) < 0) { - WL_ERROR(("%s fail to set up err =%d\n", __FUNCTION__, res)); - goto fail; - } - -#ifndef AP_ONLY - if (!res || !ret) - last_auto_channel = ap->channel; -#endif - -fail : - if (ret < 0) { - WL_TRACE(("%s: return value %d\n", __FUNCTION__, ret)); - return ret; - } - return res; -} - - -static int -set_ap_cfg(struct net_device *dev, struct ap_profile *ap) -{ - int updown = 0; - int channel = 0; - - wlc_ssid_t ap_ssid; - int max_assoc = 8; - - int res = 0; - int apsta_var = 0; -#ifndef AP_ONLY - int mpc = 0; - int iolen = 0; - int mkvar_err = 0; - int bsscfg_index = 1; - char buf[WLC_IOCTL_SMLEN]; -#endif - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -1; - } - - net_os_wake_lock(dev); - DHD_OS_MUTEX_LOCK(&wl_softap_lock); - - WL_SOFTAP(("wl_iw: set ap profile:\n")); - WL_SOFTAP((" ssid = '%s'\n", ap->ssid)); - WL_SOFTAP((" security = '%s'\n", ap->sec)); - if (ap->key[0] != '\0') - WL_SOFTAP((" key = '%s'\n", ap->key)); - WL_SOFTAP((" channel = %d\n", ap->channel)); - WL_SOFTAP((" max scb = %d\n", ap->max_scb)); - -#ifdef AP_ONLY - if (ap_cfg_running) { - wl_iw_softap_deassoc_stations(dev, NULL); - ap_cfg_running = FALSE; - } -#endif - - - if (ap_cfg_running == FALSE) { - -#ifndef AP_ONLY - - - sema_init(&ap_eth_ctl.sema, 0); - - mpc = 0; - if ((res = dev_wlc_intvar_set(dev, "mpc", mpc))) { - WL_ERROR(("%s fail to set mpc\n", __FUNCTION__)); - goto fail; - } -#endif - - updown = 0; - if ((res = dev_wlc_ioctl(dev, WLC_DOWN, &updown, sizeof(updown)))) { - WL_ERROR(("%s fail to set updown\n", __FUNCTION__)); - goto fail; - } - -#ifdef AP_ONLY - - apsta_var = 0; - if ((res = dev_wlc_ioctl(dev, WLC_SET_AP, &apsta_var, sizeof(apsta_var)))) { - WL_ERROR(("%s fail to set apsta_var 0\n", __FUNCTION__)); - goto fail; - } - apsta_var = 1; - if ((res = dev_wlc_ioctl(dev, WLC_SET_AP, &apsta_var, sizeof(apsta_var)))) { - WL_ERROR(("%s fail to set apsta_var 1\n", __FUNCTION__)); - goto fail; - } - res = dev_wlc_ioctl(dev, WLC_GET_AP, &apsta_var, sizeof(apsta_var)); -#else - - apsta_var = 1; - iolen = wl_bssiovar_mkbuf("apsta", - bsscfg_index, &apsta_var, sizeof(apsta_var)+4, - buf, sizeof(buf), &mkvar_err); - ASSERT(iolen); - if ((res = dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen)) < 0) { - WL_ERROR(("%s fail to set apsta \n", __FUNCTION__)); - goto fail; - } - WL_TRACE(("\n>in %s: apsta set result: %d \n", __FUNCTION__, res)); - - - mpc = 0; - if ((res = dev_wlc_intvar_set(dev, "mpc", mpc))) { - WL_ERROR(("%s fail to set mpc\n", __FUNCTION__)); - goto fail; - } - - -#endif - - updown = 1; - if ((res = dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown))) < 0) { - WL_ERROR(("%s fail to set apsta \n", __FUNCTION__)); - goto fail; - } - - } else { - - if (!ap_net_dev) { - WL_ERROR(("%s: ap_net_dev is null\n", __FUNCTION__)); - goto fail; - } - - res = wl_iw_softap_deassoc_stations(ap_net_dev, NULL); - - - if ((res = dev_iw_write_cfg1_bss_var(dev, 0)) < 0) { - WL_ERROR(("%s fail to set bss down\n", __FUNCTION__)); - goto fail; - } - } - - - if (strlen(ap->country_code)) { - WL_ERROR(("%s: Igonored: Country MUST be specified" - "COUNTRY command with \n", __FUNCTION__)); - } else { - WL_SOFTAP(("%s: Country code is not specified," - " will use Radio's default\n", - __FUNCTION__)); - - } - iolen = wl_bssiovar_mkbuf("closednet", - bsscfg_index, &ap->closednet, sizeof(ap->closednet)+4, - buf, sizeof(buf), &mkvar_err); - ASSERT(iolen); - if ((res = dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen)) < 0) { - WL_ERROR(("%s failed to set 'closednet'for apsta \n", __FUNCTION__)); - goto fail; - } - - - if ((ap->channel == 0) && (get_softap_auto_channel(dev, ap) < 0)) { - ap->channel = 1; - WL_ERROR(("%s auto channel failed, use channel=%d\n", - __FUNCTION__, ap->channel)); - } - - channel = ap->channel; - if ((res = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &channel, sizeof(channel)))) { - WL_ERROR(("%s fail to set channel\n", __FUNCTION__)); - } - - - if (ap_cfg_running == FALSE) { - updown = 0; - if ((res = dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown)))) { - WL_ERROR(("%s fail to set up\n", __FUNCTION__)); - goto fail; - } - } - - max_assoc = ap->max_scb; - if ((res = dev_wlc_intvar_set(dev, "maxassoc", max_assoc))) { - WL_ERROR(("%s fail to set maxassoc\n", __FUNCTION__)); - goto fail; - } - - ap_ssid.SSID_len = strlen(ap->ssid); - strncpy(ap_ssid.SSID, ap->ssid, ap_ssid.SSID_len); - - -#ifdef AP_ONLY - if ((res = wl_iw_set_ap_security(dev, &my_ap)) != 0) { - WL_ERROR(("ERROR:%d in:%s, wl_iw_set_ap_security is skipped\n", - res, __FUNCTION__)); - goto fail; - } - wl_iw_send_priv_event(dev, "ASCII_CMD=AP_BSS_START"); - ap_cfg_running = TRUE; -#else - - iolen = wl_bssiovar_mkbuf("ssid", bsscfg_index, (char *)(&ap_ssid), - ap_ssid.SSID_len+4, buf, sizeof(buf), &mkvar_err); - ASSERT(iolen); - if ((res = dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen)) != 0) { - WL_ERROR(("ERROR:%d in:%s, Security & BSS reconfiguration is skipped\n", - res, __FUNCTION__)); - goto fail; - } - if (ap_cfg_running == FALSE) { - - PROC_START(thr_wait_for_2nd_eth_dev, dev, &ap_eth_ctl, 0); - } else { - ap_eth_ctl.thr_pid = -1; - - if (ap_net_dev == NULL) { - WL_ERROR(("%s ERROR: ap_net_dev is NULL !!!\n", __FUNCTION__)); - goto fail; - } - - WL_ERROR(("%s: %s Configure security & restart AP bss \n", - __FUNCTION__, ap_net_dev->name)); - - - if ((res = wl_iw_set_ap_security(ap_net_dev, &my_ap)) < 0) { - WL_ERROR(("%s fail to set security : %d\n", __FUNCTION__, res)); - goto fail; - } - - - if ((res = dev_iw_write_cfg1_bss_var(dev, 1)) < 0) { - WL_ERROR(("%s fail to set bss up\n", __FUNCTION__)); - goto fail; - } - } -#endif -fail: - WL_SOFTAP(("%s exit with %d\n", __FUNCTION__, res)); - - DHD_OS_MUTEX_UNLOCK(&wl_softap_lock); - net_os_wake_unlock(dev); - - return res; -} -#endif - - - -static int -wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap) -{ - int wsec = 0; - int wpa_auth = 0; - int res = 0; - int i; - char *ptr; -#ifdef AP_ONLY - int mpc = 0; - wlc_ssid_t ap_ssid; -#endif - wl_wsec_key_t key; - - WL_SOFTAP(("\nsetting SOFTAP security mode:\n")); - WL_SOFTAP(("wl_iw: set ap profile:\n")); - WL_SOFTAP((" ssid = '%s'\n", ap->ssid)); - WL_SOFTAP((" security = '%s'\n", ap->sec)); - if (ap->key[0] != '\0') - WL_SOFTAP((" key = '%s'\n", ap->key)); - WL_SOFTAP((" channel = %d\n", ap->channel)); - WL_SOFTAP((" max scb = %d\n", ap->max_scb)); - - - if (strnicmp(ap->sec, "open", strlen("open")) == 0) { - - - wsec = 0; - res = dev_wlc_intvar_set(dev, "wsec", wsec); - wpa_auth = WPA_AUTH_DISABLED; - res |= dev_wlc_intvar_set(dev, "wpa_auth", wpa_auth); - - WL_SOFTAP(("=====================\n")); - WL_SOFTAP((" wsec & wpa_auth set 'OPEN', result:&d %d\n", res)); - WL_SOFTAP(("=====================\n")); - - } else if (strnicmp(ap->sec, "wep", strlen("wep")) == 0) { - - - memset(&key, 0, sizeof(key)); - - wsec = WEP_ENABLED; - res = dev_wlc_intvar_set(dev, "wsec", wsec); - - key.index = 0; - if (wl_iw_parse_wep(ap->key, &key)) { - WL_SOFTAP(("wep key parse err!\n")); - return -1; - } - - key.index = htod32(key.index); - key.len = htod32(key.len); - key.algo = htod32(key.algo); - key.flags = htod32(key.flags); - - res |= dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - - wpa_auth = WPA_AUTH_DISABLED; - res |= dev_wlc_intvar_set(dev, "wpa_auth", wpa_auth); - - WL_SOFTAP(("=====================\n")); - WL_SOFTAP((" wsec & auth set 'WEP', result:&d %d\n", res)); - WL_SOFTAP(("=====================\n")); - - } else if (strnicmp(ap->sec, "wpa2-psk", strlen("wpa2-psk")) == 0) { - - - - wsec_pmk_t psk; - size_t key_len; - - wsec = AES_ENABLED; - dev_wlc_intvar_set(dev, "wsec", wsec); - - key_len = strlen(ap->key); - if (key_len < WSEC_MIN_PSK_LEN || key_len > WSEC_MAX_PSK_LEN) { - WL_SOFTAP(("passphrase must be between %d and %d characters long\n", - WSEC_MIN_PSK_LEN, WSEC_MAX_PSK_LEN)); - return -1; - } - - - if (key_len < WSEC_MAX_PSK_LEN) { - unsigned char output[2*SHA1HashSize]; - char key_str_buf[WSEC_MAX_PSK_LEN+1]; - - - memset(output, 0, sizeof(output)); - pbkdf2_sha1(ap->key, ap->ssid, strlen(ap->ssid), 4096, output, 32); - - ptr = key_str_buf; - for (i = 0; i < (WSEC_MAX_PSK_LEN/8); i++) { - - sprintf(ptr, "%02x%02x%02x%02x", (uint)output[i*4], - (uint)output[i*4+1], (uint)output[i*4+2], - (uint)output[i*4+3]); - ptr += 8; - } - WL_SOFTAP(("%s: passphase = %s\n", __FUNCTION__, key_str_buf)); - - psk.key_len = htod16((ushort)WSEC_MAX_PSK_LEN); - memcpy(psk.key, key_str_buf, psk.key_len); - } else { - psk.key_len = htod16((ushort) key_len); - memcpy(psk.key, ap->key, key_len); - } - psk.flags = htod16(WSEC_PASSPHRASE); - dev_wlc_ioctl(dev, WLC_SET_WSEC_PMK, &psk, sizeof(psk)); - - wpa_auth = WPA2_AUTH_PSK; - dev_wlc_intvar_set(dev, "wpa_auth", wpa_auth); - - } else if (strnicmp(ap->sec, "wpa-psk", strlen("wpa-psk")) == 0) { - - - wsec_pmk_t psk; - size_t key_len; - - wsec = TKIP_ENABLED; - res = dev_wlc_intvar_set(dev, "wsec", wsec); - - key_len = strlen(ap->key); - if (key_len < WSEC_MIN_PSK_LEN || key_len > WSEC_MAX_PSK_LEN) { - WL_SOFTAP(("passphrase must be between %d and %d characters long\n", - WSEC_MIN_PSK_LEN, WSEC_MAX_PSK_LEN)); - return -1; - } - - - if (key_len < WSEC_MAX_PSK_LEN) { - unsigned char output[2*SHA1HashSize]; - char key_str_buf[WSEC_MAX_PSK_LEN+1]; - bzero(output, 2*SHA1HashSize); - - WL_SOFTAP(("%s: do passhash...\n", __FUNCTION__)); - - pbkdf2_sha1(ap->key, ap->ssid, strlen(ap->ssid), 4096, output, 32); - - ptr = key_str_buf; - for (i = 0; i < (WSEC_MAX_PSK_LEN/8); i++) { - WL_SOFTAP(("[%02d]: %08x\n", i, *((unsigned int*)&output[i*4]))); - - sprintf(ptr, "%02x%02x%02x%02x", (uint)output[i*4], - (uint)output[i*4+1], (uint)output[i*4+2], - (uint)output[i*4+3]); - ptr += 8; - } - printk("%s: passphase = %s\n", __FUNCTION__, key_str_buf); - - psk.key_len = htod16((ushort)WSEC_MAX_PSK_LEN); - memcpy(psk.key, key_str_buf, psk.key_len); - } else { - psk.key_len = htod16((ushort) key_len); - memcpy(psk.key, ap->key, key_len); - } - - psk.flags = htod16(WSEC_PASSPHRASE); - res |= dev_wlc_ioctl(dev, WLC_SET_WSEC_PMK, &psk, sizeof(psk)); - - wpa_auth = WPA_AUTH_PSK; - res |= dev_wlc_intvar_set(dev, "wpa_auth", wpa_auth); - - WL_SOFTAP((" wsec & auth set 'wpa-psk' (TKIP), result:&d %d\n", res)); - } - -#ifdef AP_ONLY - ap_ssid.SSID_len = strlen(ap->ssid); - strncpy(ap_ssid.SSID, ap->ssid, ap_ssid.SSID_len); - res |= dev_wlc_ioctl(dev, WLC_SET_SSID, &ap_ssid, sizeof(ap_ssid)); - mpc = 0; - res |= dev_wlc_intvar_set(dev, "mpc", mpc); - if (strnicmp(ap->sec, "wep", strlen("wep")) == 0) { - res |= dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - } -#endif - return res; -} - - - -static int -get_parameter_from_string( - char **str_ptr, const char *token, - int param_type, void *dst, int param_max_len) -{ - char int_str[7] = "0"; - int parm_str_len; - char *param_str_begin; - char *param_str_end; - char *orig_str = *str_ptr; - - if ((*str_ptr) && !strncmp(*str_ptr, token, strlen(token))) { - - strsep(str_ptr, "=,"); - param_str_begin = *str_ptr; - strsep(str_ptr, "=,"); - - if (*str_ptr == NULL) { - - parm_str_len = strlen(param_str_begin); - } else { - param_str_end = *str_ptr-1; - parm_str_len = param_str_end - param_str_begin; - } - - WL_TRACE((" 'token:%s', len:%d, ", token, parm_str_len)); - - if (parm_str_len > param_max_len) { - WL_ERROR((" WARNING: extracted param len:%d is > MAX:%d\n", - parm_str_len, param_max_len)); - - parm_str_len = param_max_len; - } - - switch (param_type) { - - case PTYPE_INTDEC: { - - int *pdst_int = dst; - char *eptr; - - if (parm_str_len > sizeof(int_str)) - parm_str_len = sizeof(int_str); - - memcpy(int_str, param_str_begin, parm_str_len); - - *pdst_int = simple_strtoul(int_str, &eptr, 10); - - WL_TRACE((" written as integer:%d\n", *pdst_int)); - } - break; - case PTYPE_STR_HEX: { - u8 *buf = dst; - - param_max_len = param_max_len >> 1; - hstr_2_buf(param_str_begin, buf, param_max_len); - dhd_print_buf(buf, param_max_len, 0); - } - break; - default: - - memcpy(dst, param_str_begin, parm_str_len); - *((char *)dst + parm_str_len) = 0; - WL_ERROR((" written as a string:%s\n", (char *)dst)); - break; - - } - - return 0; - } else { - WL_ERROR(("\n %s: ERROR: can't find token:%s in str:%s \n", - __FUNCTION__, token, orig_str)); - - return -1; - } -} - -static int wl_iw_softap_deassoc_stations(struct net_device *dev, u8 *mac) -{ - int i; - int res = 0; - char mac_buf[128] = {0}; - char z_mac[6] = {0, 0, 0, 0, 0, 0}; - char *sta_mac; - struct maclist *assoc_maclist = (struct maclist *) mac_buf; - bool deauth_all = FALSE; - - - if (mac == NULL) { - deauth_all = TRUE; - sta_mac = z_mac; - } else { - sta_mac = mac; - } - - memset(assoc_maclist, 0, sizeof(mac_buf)); - assoc_maclist->count = 8; - - res = dev_wlc_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist, 128); - if (res != 0) { - WL_SOFTAP(("%s: Error:%d Couldn't get ASSOC List\n", __FUNCTION__, res)); - return res; - } - - if (assoc_maclist->count) - for (i = 0; i < assoc_maclist->count; i++) { - scb_val_t scbval; - scbval.val = htod32(1); - - bcopy(&assoc_maclist->ea[i], &scbval.ea, ETHER_ADDR_LEN); - - if (deauth_all || (memcmp(&scbval.ea, sta_mac, ETHER_ADDR_LEN) == 0)) { - - WL_SOFTAP(("%s, deauth STA:%d \n", __FUNCTION__, i)); - res |= dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, - &scbval, sizeof(scb_val_t)); - } - } else WL_SOFTAP(("%s: No Stations \n", __FUNCTION__)); - - if (res != 0) { - WL_ERROR(("%s: Error:%d\n", __FUNCTION__, res)); - } else if (assoc_maclist->count) { - - bcm_mdelay(200); - } - return res; -} - - - -static int -iwpriv_softap_stop(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int res = 0; - - WL_SOFTAP(("got iwpriv AP_BSS_STOP \n")); - - if ((!dev) && (!ap_net_dev)) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return res; - } - - net_os_wake_lock(dev); - DHD_OS_MUTEX_LOCK(&wl_softap_lock); - - if ((ap_cfg_running == TRUE)) { -#ifdef AP_ONLY - wl_iw_softap_deassoc_stations(dev, NULL); -#else - wl_iw_softap_deassoc_stations(ap_net_dev, NULL); - if ((res = dev_iw_write_cfg1_bss_var(dev, 2)) < 0) - WL_ERROR(("%s failed to del BSS err = %d", __FUNCTION__, res)); -#endif - - - bcm_mdelay(100); - - wrqu->data.length = 0; - ap_cfg_running = FALSE; - } else - WL_ERROR(("%s: was called when SoftAP is OFF : move on\n", __FUNCTION__)); - - WL_SOFTAP(("%s Done with %d\n", __FUNCTION__, res)); - DHD_OS_MUTEX_UNLOCK(&wl_softap_lock); - net_os_wake_unlock(dev); - - return res; -} - - - -static int -iwpriv_fw_reload(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int ret = -1; - char extra[256]; - char *fwstr = fw_path ; - - WL_SOFTAP(("current firmware_path[]=%s\n", fwstr)); - - WL_TRACE((">Got FW_RELOAD cmd:" - "info->cmd:%x, info->flags:%x, u.data:%p, u.len:%d, " - "fw_path:%p, len:%d \n", - info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length, fwstr, strlen(fwstr))); - - if ((wrqu->data.length > 4) && (wrqu->data.length < sizeof(extra))) { - char *str_ptr; - - if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) { - ret = -EFAULT; - goto exit_proc; - } - - - extra[wrqu->data.length] = 8; - str_ptr = extra; - - if (get_parameter_from_string(&str_ptr, - "FW_PATH=", PTYPE_STRING, fwstr, 255) != 0) { - WL_ERROR(("Error: extracting FW_PATH='' string\n")); - goto exit_proc; - } - - if (strstr(fwstr, "apsta") != NULL) { - WL_SOFTAP(("GOT APSTA FIRMWARE\n")); - ap_fw_loaded = TRUE; - } else { - WL_SOFTAP(("GOT STA FIRMWARE\n")); - ap_fw_loaded = FALSE; - } - - WL_SOFTAP(("SET firmware_path[]=%s , str_p:%p\n", fwstr, fwstr)); - ret = 0; - } else { - WL_ERROR(("Error: ivalid param len:%d\n", wrqu->data.length)); - } - -exit_proc: - return ret; -} - -#ifdef SOFTAP - -static int -iwpriv_wpasupp_loop_tst(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int res = 0; - char *params = NULL; - - WL_TRACE((">Got IWPRIV wp_supp loopback cmd test:" - "info->cmd:%x, info->flags:%x, u.data:%p, u.len:%d\n", - info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (wrqu->data.length != 0) { - - if (!(params = kmalloc(wrqu->data.length+1, GFP_KERNEL))) - return -ENOMEM; - - - if (copy_from_user(params, wrqu->data.pointer, wrqu->data.length)) { - kfree(params); - return -EFAULT; - } - - params[wrqu->data.length] = 0; - WL_SOFTAP(("\n>> copied from user:\n %s\n", params)); - } else { - WL_ERROR(("ERROR param length is 0\n")); - return -EFAULT; - } - - - res = wl_iw_send_priv_event(dev, params); - kfree(params); - - return res; -} -#endif - - -static int -iwpriv_en_ap_bss( - struct net_device *dev, - struct iw_request_info *info, - void *wrqu, - char *extra) -{ - int res = 0; - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -1; - } - - net_os_wake_lock(dev); - DHD_OS_MUTEX_LOCK(&wl_softap_lock); - - WL_TRACE(("%s: rcvd IWPRIV IOCTL: for dev:%s\n", __FUNCTION__, dev->name)); - - -#ifndef AP_ONLY - if ((res = wl_iw_set_ap_security(dev, &my_ap)) != 0) { - WL_ERROR((" %s ERROR setting SOFTAP security in :%d\n", __FUNCTION__, res)); - } - else { - - if ((res = dev_iw_write_cfg1_bss_var(dev, 1)) < 0) - WL_ERROR(("%s fail to set bss up err=%d\n", __FUNCTION__, res)); - else - - bcm_mdelay(100); - } - -#endif - WL_SOFTAP(("%s done with res %d \n", __FUNCTION__, res)); - - DHD_OS_MUTEX_UNLOCK(&wl_softap_lock); - net_os_wake_unlock(dev); - - return res; -} - -static int -get_assoc_sta_list(struct net_device *dev, char *buf, int len) -{ - - WL_TRACE(("%s: dev_wlc_ioctl(dev:%p, cmd:%d, buf:%p, len:%d)\n", - __FUNCTION__, dev, WLC_GET_ASSOCLIST, buf, len)); - - return dev_wlc_ioctl(dev, WLC_GET_ASSOCLIST, buf, len); - -} - - -void check_error(int res, const char *msg, const char *func, int line) -{ - if (res != 0) - WL_ERROR(("%s, %d function:%s, line:%d\n", msg, res, func, line)); -} - -static int -set_ap_mac_list(struct net_device *dev, void *buf) -{ - struct mac_list_set *mac_list_set = (struct mac_list_set *)buf; - struct maclist *maclist = (struct maclist *)&mac_list_set->mac_list; - int length; - int i; - int mac_mode = mac_list_set->mode; - int ioc_res = 0; - ap_macmode = mac_list_set->mode; - - - bzero(&ap_black_list, sizeof(struct mflist)); - - if (mac_mode == MACLIST_MODE_DISABLED) { - - ioc_res = dev_wlc_ioctl(dev, WLC_SET_MACMODE, &mac_mode, sizeof(mac_mode)); - check_error(ioc_res, "ioctl ERROR:", __FUNCTION__, __LINE__); - WL_SOFTAP(("%s: MAC filtering disabled\n", __FUNCTION__)); - } else { - - scb_val_t scbval; - char mac_buf[256] = {0}; - struct maclist *assoc_maclist = (struct maclist *) mac_buf; - - - bcopy(maclist, &ap_black_list, sizeof(ap_black_list)); - - - ioc_res = dev_wlc_ioctl(dev, WLC_SET_MACMODE, &mac_mode, sizeof(mac_mode)); - check_error(ioc_res, "ioctl ERROR:", __FUNCTION__, __LINE__); - - - length = sizeof(maclist->count) + maclist->count*ETHER_ADDR_LEN; - dev_wlc_ioctl(dev, WLC_SET_MACLIST, maclist, length); - - WL_SOFTAP(("%s: applied MAC List, mode:%d, length %d:\n", - __FUNCTION__, mac_mode, length)); - - for (i = 0; i < maclist->count; i++) - WL_SOFTAP(("mac %d: %02X:%02X:%02X:%02X:%02X:%02X\n", - i, maclist->ea[i].octet[0], maclist->ea[i].octet[1], - maclist->ea[i].octet[2], - maclist->ea[i].octet[3], maclist->ea[i].octet[4], - maclist->ea[i].octet[5])); - - - assoc_maclist->count = 8; - ioc_res = dev_wlc_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist, 256); - check_error(ioc_res, "ioctl ERROR:", __FUNCTION__, __LINE__); - WL_SOFTAP((" Cur assoc clients:%d\n", assoc_maclist->count)); - - - if (assoc_maclist->count) - for (i = 0; i < assoc_maclist->count; i++) { - int j; - bool assoc_mac_matched = FALSE; - - WL_SOFTAP(("\n Cheking assoc STA: ")); - dhd_print_buf(&assoc_maclist->ea[i], 6, 7); - WL_SOFTAP(("with the b/w list:")); - - for (j = 0; j < maclist->count; j++) - if (!bcmp(&assoc_maclist->ea[i], &maclist->ea[j], - ETHER_ADDR_LEN)) { - - assoc_mac_matched = TRUE; - break; - } - - - if (((mac_mode == MACLIST_MODE_ALLOW) && !assoc_mac_matched) || - ((mac_mode == MACLIST_MODE_DENY) && assoc_mac_matched)) { - - WL_SOFTAP(("b-match or w-mismatch," - " do deauth/disassoc \n")); - scbval.val = htod32(1); - bcopy(&assoc_maclist->ea[i], &scbval.ea, - ETHER_ADDR_LEN); - ioc_res = dev_wlc_ioctl(dev, - WLC_SCB_DEAUTHENTICATE_FOR_REASON, - &scbval, sizeof(scb_val_t)); - check_error(ioc_res, - "ioctl ERROR:", - __FUNCTION__, __LINE__); - - } else { - WL_SOFTAP((" no b/w list hits, let it be\n")); - } - } else { - WL_SOFTAP(("No ASSOC CLIENTS\n")); - } - - } - - WL_SOFTAP(("%s iocres:%d\n", __FUNCTION__, ioc_res)); - return ioc_res; -} -#endif - - - -#ifdef SOFTAP -#define PARAM_OFFSET PROFILE_OFFSET - -static int -wl_iw_process_private_ascii_cmd( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *dwrq, - char *cmd_str) -{ - int ret = 0; - char *sub_cmd = cmd_str + PROFILE_OFFSET + strlen("ASCII_CMD="); - - WL_SOFTAP(("\n %s: ASCII_CMD: offs_0:%s, offset_32:\n'%s'\n", - __FUNCTION__, cmd_str, cmd_str + PROFILE_OFFSET)); - - if (strnicmp(sub_cmd, "AP_CFG", strlen("AP_CFG")) == 0) { - - WL_SOFTAP((" AP_CFG \n")); - - - if (init_ap_profile_from_string(cmd_str+PROFILE_OFFSET, &my_ap) != 0) { - WL_ERROR(("ERROR: SoftAP CFG prams !\n")); - ret = -1; - } else { - ret = set_ap_cfg(dev, &my_ap); - } - - } else if (strnicmp(sub_cmd, "AP_BSS_START", strlen("AP_BSS_START")) == 0) { - - WL_SOFTAP(("\n SOFTAP - ENABLE BSS \n")); - - - WL_SOFTAP(("\n!!! got 'WL_AP_EN_BSS' from WPA supplicant, dev:%s\n", dev->name)); - -#ifndef AP_ONLY - if (ap_net_dev == NULL) { - printf("\n ERROR: SOFTAP net_dev* is NULL !!!\n"); - } else { - - if ((ret = iwpriv_en_ap_bss(ap_net_dev, info, dwrq, cmd_str)) < 0) - WL_ERROR(("%s line %d fail to set bss up\n", - __FUNCTION__, __LINE__)); - } -#else - if ((ret = iwpriv_en_ap_bss(dev, info, dwrq, cmd_str)) < 0) - WL_ERROR(("%s line %d fail to set bss up\n", - __FUNCTION__, __LINE__)); -#endif - } else if (strnicmp(sub_cmd, "ASSOC_LST", strlen("ASSOC_LST")) == 0) { - - - - } else if (strnicmp(sub_cmd, "AP_BSS_STOP", strlen("AP_BSS_STOP")) == 0) { - - WL_SOFTAP((" \n temp DOWN SOFTAP\n")); -#ifndef AP_ONLY - if ((ret = dev_iw_write_cfg1_bss_var(dev, 0)) < 0) { - WL_ERROR(("%s line %d fail to set bss down\n", - __FUNCTION__, __LINE__)); - } -#endif - } - - return ret; - -} -#endif - - -static int -wl_iw_set_priv( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *ext -) -{ - int ret = 0; - char * extra; - - if (!(extra = kmalloc(dwrq->length, GFP_KERNEL))) - return -ENOMEM; - - if (copy_from_user(extra, dwrq->pointer, dwrq->length)) { - kfree(extra); - return -EFAULT; - } - - WL_TRACE(("%s: SIOCSIWPRIV request %s, info->cmd:%x, info->flags:%d\n dwrq->length:%d\n", - dev->name, extra, info->cmd, info->flags, dwrq->length)); - - - - net_os_wake_lock(dev); - - if (dwrq->length && extra) { - if (strnicmp(extra, "START", strlen("START")) == 0) { - wl_iw_control_wl_on(dev, info); - WL_TRACE(("%s, Received regular START command\n", __FUNCTION__)); - } - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s, missing START, Fail\n", __FUNCTION__)); - kfree(extra); - net_os_wake_unlock(dev); - return -EFAULT; - } - - if (strnicmp(extra, "SCAN-ACTIVE", strlen("SCAN-ACTIVE")) == 0) { -#ifdef ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS - WL_TRACE(("%s: active scan setting suppressed\n", dev->name)); -#else - ret = wl_iw_set_active_scan(dev, info, (union iwreq_data *)dwrq, extra); -#endif - } - else if (strnicmp(extra, "SCAN-PASSIVE", strlen("SCAN-PASSIVE")) == 0) -#ifdef ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS - WL_TRACE(("%s: passive scan setting suppressed\n", dev->name)); -#else - ret = wl_iw_set_passive_scan(dev, info, (union iwreq_data *)dwrq, extra); -#endif - else if (strnicmp(extra, "RSSI", strlen("RSSI")) == 0) - ret = wl_iw_get_rssi(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "LINKSPEED", strlen("LINKSPEED")) == 0) - ret = wl_iw_get_link_speed(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "MACADDR", strlen("MACADDR")) == 0) - ret = wl_iw_get_macaddr(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "COUNTRY", strlen("COUNTRY")) == 0) - ret = wl_iw_set_country(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "STOP", strlen("STOP")) == 0) - ret = wl_iw_control_wl_off(dev, info); - else if (strnicmp(extra, BAND_GET_CMD, strlen(BAND_GET_CMD)) == 0) - ret = wl_iw_get_band(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, BAND_SET_CMD, strlen(BAND_SET_CMD)) == 0) - ret = wl_iw_set_band(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, DTIM_SKIP_GET_CMD, strlen(DTIM_SKIP_GET_CMD)) == 0) - ret = wl_iw_get_dtim_skip(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, DTIM_SKIP_SET_CMD, strlen(DTIM_SKIP_SET_CMD)) == 0) - ret = wl_iw_set_dtim_skip(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, SETSUSPENDOPT_CMD, strlen(SETSUSPENDOPT_CMD)) == 0) - ret = wl_iw_set_suspend_opt(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, SETSUSPENDMODE_CMD, strlen(SETSUSPENDMODE_CMD)) == 0) - ret = wl_iw_set_suspend_mode(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, TXPOWER_SET_CMD, strlen(TXPOWER_SET_CMD)) == 0) - ret = wl_iw_set_txpower(dev, info, (union iwreq_data *)dwrq, extra); -#if defined(PNO_SUPPORT) - else if (strnicmp(extra, PNOSSIDCLR_SET_CMD, strlen(PNOSSIDCLR_SET_CMD)) == 0) - ret = wl_iw_set_pno_reset(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, PNOSETUP_SET_CMD, strlen(PNOSETUP_SET_CMD)) == 0) - ret = wl_iw_set_pno_set(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, PNOSETADD_SET_CMD, strlen(PNOSETADD_SET_CMD)) == 0) - ret = wl_iw_set_pno_setadd(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, PNOENABLE_SET_CMD, strlen(PNOENABLE_SET_CMD)) == 0) - ret = wl_iw_set_pno_enable(dev, info, (union iwreq_data *)dwrq, extra); -#endif -#if defined(CSCAN) - - else if (strnicmp(extra, CSCAN_COMMAND, strlen(CSCAN_COMMAND)) == 0) - ret = wl_iw_set_cscan(dev, info, (union iwreq_data *)dwrq, extra); -#endif -#ifdef CONFIG_WPS2 - else if (strnicmp(extra, WPS_ADD_PROBE_REQ_IE_CMD, - strlen(WPS_ADD_PROBE_REQ_IE_CMD)) == 0) - ret = wl_iw_add_wps_probe_req_ie(dev, info, - (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, WPS_DEL_PROBE_REQ_IE_CMD, - strlen(WPS_DEL_PROBE_REQ_IE_CMD)) == 0) - ret = wl_iw_del_wps_probe_req_ie(dev, info, - (union iwreq_data *)dwrq, extra); -#endif - else if (strnicmp(extra, "POWERMODE", strlen("POWERMODE")) == 0) - ret = wl_iw_set_power_mode(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "BTCOEXMODE", strlen("BTCOEXMODE")) == 0) - ret = wl_iw_set_btcoex_dhcp(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "GETPOWER", strlen("GETPOWER")) == 0) - ret = wl_iw_get_power_mode(dev, info, (union iwreq_data *)dwrq, extra); -#ifdef SOFTAP - else if (strnicmp(extra, "ASCII_CMD", strlen("ASCII_CMD")) == 0) { - wl_iw_process_private_ascii_cmd(dev, info, (union iwreq_data *)dwrq, extra); - } - else if (strnicmp(extra, "AP_MAC_LIST_SET", strlen("AP_MAC_LIST_SET")) == 0) { - WL_SOFTAP(("penguin, set AP_MAC_LIST_SET\n")); - set_ap_mac_list(dev, (extra + PROFILE_OFFSET)); - } -#endif - else { - WL_ERROR(("Unknown PRIVATE command %s - ignored\n", extra)); - snprintf(extra, MAX_WX_STRING, "OK"); - dwrq->length = strlen("OK") + 1; - } - } - - net_os_wake_unlock(dev); - - if (extra) { - if (copy_to_user(dwrq->pointer, extra, dwrq->length)) { - kfree(extra); - return -EFAULT; - } - - kfree(extra); - } - - return ret; -} - -static const iw_handler wl_iw_handler[] = -{ - (iw_handler) wl_iw_config_commit, - (iw_handler) wl_iw_get_name, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_freq, - (iw_handler) wl_iw_get_freq, - (iw_handler) wl_iw_set_mode, - (iw_handler) wl_iw_get_mode, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_get_range, - (iw_handler) wl_iw_set_priv, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_spy, - (iw_handler) wl_iw_get_spy, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_wap, - (iw_handler) wl_iw_get_wap, -#if WIRELESS_EXT > 17 - (iw_handler) wl_iw_mlme, -#else - (iw_handler) NULL, -#endif -#if defined(WL_IW_USE_ISCAN) - (iw_handler) wl_iw_iscan_get_aplist, -#else - (iw_handler) wl_iw_get_aplist, -#endif -#if WIRELESS_EXT > 13 -#if defined(WL_IW_USE_ISCAN) - (iw_handler) wl_iw_iscan_set_scan, - (iw_handler) wl_iw_iscan_get_scan, -#else - (iw_handler) wl_iw_set_scan, - (iw_handler) wl_iw_get_scan, -#endif -#else - (iw_handler) NULL, - (iw_handler) NULL, -#endif - (iw_handler) wl_iw_set_essid, - (iw_handler) wl_iw_get_essid, - (iw_handler) wl_iw_set_nick, - (iw_handler) wl_iw_get_nick, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_rate, - (iw_handler) wl_iw_get_rate, - (iw_handler) wl_iw_set_rts, - (iw_handler) wl_iw_get_rts, - (iw_handler) wl_iw_set_frag, - (iw_handler) wl_iw_get_frag, - (iw_handler) wl_iw_set_txpow, - (iw_handler) wl_iw_get_txpow, -#if WIRELESS_EXT > 10 - (iw_handler) wl_iw_set_retry, - (iw_handler) wl_iw_get_retry, -#endif - (iw_handler) wl_iw_set_encode, - (iw_handler) wl_iw_get_encode, - (iw_handler) wl_iw_set_power, - (iw_handler) wl_iw_get_power, -#if WIRELESS_EXT > 17 - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_wpaie, - (iw_handler) wl_iw_get_wpaie, - (iw_handler) wl_iw_set_wpaauth, - (iw_handler) wl_iw_get_wpaauth, - (iw_handler) wl_iw_set_encodeext, - (iw_handler) wl_iw_get_encodeext, - (iw_handler) wl_iw_set_pmksa, -#endif -}; - -#if WIRELESS_EXT > 12 -static const iw_handler wl_iw_priv_handler[] = { - NULL, - (iw_handler)wl_iw_set_active_scan, - NULL, - (iw_handler)wl_iw_get_rssi, - NULL, - (iw_handler)wl_iw_set_passive_scan, - NULL, - (iw_handler)wl_iw_get_link_speed, - NULL, - (iw_handler)wl_iw_get_macaddr, - NULL, - (iw_handler)wl_iw_control_wl_off, - NULL, - (iw_handler)wl_iw_control_wl_on, -#ifdef SOFTAP - - - NULL, - (iw_handler)iwpriv_set_ap_config, - - - - NULL, - (iw_handler)iwpriv_get_assoc_list, - - - NULL, - (iw_handler)iwpriv_set_mac_filters, - - - NULL, - (iw_handler)iwpriv_en_ap_bss, - - - NULL, - (iw_handler)iwpriv_wpasupp_loop_tst, - - NULL, - (iw_handler)iwpriv_softap_stop, - - NULL, - (iw_handler)iwpriv_fw_reload, - NULL, - (iw_handler)iwpriv_set_ap_sta_disassoc, -#endif -#if defined(CSCAN) - - NULL, - (iw_handler)iwpriv_set_cscan -#endif -}; - -static const struct iw_priv_args wl_iw_priv_args[] = -{ - { - WL_IW_SET_ACTIVE_SCAN, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "SCAN-ACTIVE" - }, - { - WL_IW_GET_RSSI, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "RSSI" - }, - { - WL_IW_SET_PASSIVE_SCAN, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "SCAN-PASSIVE" - }, - { - WL_IW_GET_LINK_SPEED, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "LINKSPEED" - }, - { - WL_IW_GET_CURR_MACADDR, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "Macaddr" - }, - { - WL_IW_SET_STOP, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "STOP" - }, - { - WL_IW_SET_START, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "START" - }, - -#ifdef SOFTAP - - - { - WL_SET_AP_CFG, - IW_PRIV_TYPE_CHAR | 256, - 0, - "AP_SET_CFG" - }, - - { - WL_AP_STA_LIST, - IW_PRIV_TYPE_CHAR | 0, - IW_PRIV_TYPE_CHAR | 1024, - "AP_GET_STA_LIST" - }, - - { - WL_AP_MAC_FLTR, - IW_PRIV_TYPE_CHAR | 256, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - "AP_SET_MAC_FLTR" - }, - - { - WL_AP_BSS_START, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "AP_BSS_START" - }, - - { - AP_LPB_CMD, - IW_PRIV_TYPE_CHAR | 256, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - "AP_LPB_CMD" - }, - - { - WL_AP_STOP, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - "AP_BSS_STOP" - }, - { - WL_FW_RELOAD, - IW_PRIV_TYPE_CHAR | 256, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - "WL_FW_RELOAD" - }, -#endif -#if defined(CSCAN) - { - WL_COMBO_SCAN, - IW_PRIV_TYPE_CHAR | 1024, - 0, - "CSCAN" - }, -#endif - }; - -const struct iw_handler_def wl_iw_handler_def = -{ - .num_standard = ARRAYSIZE(wl_iw_handler), - .standard = (iw_handler *) wl_iw_handler, - .num_private = ARRAYSIZE(wl_iw_priv_handler), - .num_private_args = ARRAY_SIZE(wl_iw_priv_args), - .private = (iw_handler *)wl_iw_priv_handler, - .private_args = (void *) wl_iw_priv_args, - -#if WIRELESS_EXT >= 19 - get_wireless_stats: dhd_get_wireless_stats, -#endif - }; -#endif - - - -int -wl_iw_ioctl( - struct net_device *dev, - struct ifreq *rq, - int cmd -) -{ - struct iwreq *wrq = (struct iwreq *) rq; - struct iw_request_info info; - iw_handler handler; - char *extra = NULL; - size_t token_size = 1; - int max_tokens = 0, ret = 0; - - net_os_wake_lock(dev); - - WL_TRACE(("\n%s, cmd:%x called via dhd->do_ioctl()entry point\n", __FUNCTION__, cmd)); - if (cmd < SIOCIWFIRST || - IW_IOCTL_IDX(cmd) >= ARRAYSIZE(wl_iw_handler) || - !(handler = wl_iw_handler[IW_IOCTL_IDX(cmd)])) { - WL_ERROR(("%s: error in cmd=%x : not supported\n", __FUNCTION__, cmd)); - net_os_wake_unlock(dev); - return -EOPNOTSUPP; - } - - switch (cmd) { - - case SIOCSIWESSID: - case SIOCGIWESSID: - case SIOCSIWNICKN: - case SIOCGIWNICKN: - max_tokens = IW_ESSID_MAX_SIZE + 1; - break; - - case SIOCSIWENCODE: - case SIOCGIWENCODE: -#if WIRELESS_EXT > 17 - case SIOCSIWENCODEEXT: - case SIOCGIWENCODEEXT: -#endif - max_tokens = wrq->u.data.length; - break; - - case SIOCGIWRANGE: - - max_tokens = sizeof(struct iw_range) + 500; - break; - - case SIOCGIWAPLIST: - token_size = sizeof(struct sockaddr) + sizeof(struct iw_quality); - max_tokens = IW_MAX_AP; - break; - -#if WIRELESS_EXT > 13 - case SIOCGIWSCAN: -#if defined(WL_IW_USE_ISCAN) - if (g_iscan) - max_tokens = wrq->u.data.length; - else -#endif - max_tokens = IW_SCAN_MAX_DATA; - break; -#endif - - case SIOCSIWSPY: - token_size = sizeof(struct sockaddr); - max_tokens = IW_MAX_SPY; - break; - - case SIOCGIWSPY: - token_size = sizeof(struct sockaddr) + sizeof(struct iw_quality); - max_tokens = IW_MAX_SPY; - break; - -#if WIRELESS_EXT > 17 - case SIOCSIWPMKSA: - case SIOCSIWGENIE: -#endif - case SIOCSIWPRIV: - max_tokens = wrq->u.data.length; - break; - } - - if (max_tokens && wrq->u.data.pointer) { - if (wrq->u.data.length > max_tokens) { - WL_ERROR(("%s: error in cmd=%x wrq->u.data.length=%d > max_tokens=%d\n", - __FUNCTION__, cmd, wrq->u.data.length, max_tokens)); - ret = -E2BIG; - goto wl_iw_ioctl_done; - } - if (!(extra = kmalloc(max_tokens * token_size, GFP_KERNEL))) { - ret = -ENOMEM; - goto wl_iw_ioctl_done; - } - - if (copy_from_user(extra, wrq->u.data.pointer, wrq->u.data.length * token_size)) { - kfree(extra); - ret = -EFAULT; - goto wl_iw_ioctl_done; - } - } - - info.cmd = cmd; - info.flags = 0; - - ret = handler(dev, &info, &wrq->u, extra); - - if (extra) { - if (copy_to_user(wrq->u.data.pointer, extra, wrq->u.data.length * token_size)) { - kfree(extra); - ret = -EFAULT; - goto wl_iw_ioctl_done; - } - - kfree(extra); - } - -wl_iw_ioctl_done: - - net_os_wake_unlock(dev); - - return ret; -} - - -static bool -wl_iw_conn_status_str(uint32 event_type, uint32 status, uint32 reason, - char* stringBuf, uint buflen) -{ - typedef struct conn_fail_event_map_t { - uint32 inEvent; - uint32 inStatus; - uint32 inReason; - const char* outName; - const char* outCause; - } conn_fail_event_map_t; - - -#define WL_IW_DONT_CARE 9999 - const conn_fail_event_map_t event_map [] = { - - - {WLC_E_SET_SSID, WLC_E_STATUS_SUCCESS, WL_IW_DONT_CARE, - "Conn", "Success"}, - {WLC_E_SET_SSID, WLC_E_STATUS_NO_NETWORKS, WL_IW_DONT_CARE, - "Conn", "NoNetworks"}, - {WLC_E_SET_SSID, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE, - "Conn", "ConfigMismatch"}, - {WLC_E_PRUNE, WL_IW_DONT_CARE, WLC_E_PRUNE_ENCR_MISMATCH, - "Conn", "EncrypMismatch"}, - {WLC_E_PRUNE, WL_IW_DONT_CARE, WLC_E_RSN_MISMATCH, - "Conn", "RsnMismatch"}, - {WLC_E_AUTH, WLC_E_STATUS_TIMEOUT, WL_IW_DONT_CARE, - "Conn", "AuthTimeout"}, - {WLC_E_AUTH, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE, - "Conn", "AuthFail"}, - {WLC_E_AUTH, WLC_E_STATUS_NO_ACK, WL_IW_DONT_CARE, - "Conn", "AuthNoAck"}, - {WLC_E_REASSOC, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE, - "Conn", "ReassocFail"}, - {WLC_E_REASSOC, WLC_E_STATUS_TIMEOUT, WL_IW_DONT_CARE, - "Conn", "ReassocTimeout"}, - {WLC_E_REASSOC, WLC_E_STATUS_ABORT, WL_IW_DONT_CARE, - "Conn", "ReassocAbort"}, - {WLC_E_PSK_SUP, WLC_SUP_KEYED, WL_IW_DONT_CARE, - "Sup", "ConnSuccess"}, - {WLC_E_PSK_SUP, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Sup", "WpaHandshakeFail"}, - {WLC_E_DEAUTH_IND, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Conn", "Deauth"}, - {WLC_E_DISASSOC_IND, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Conn", "DisassocInd"}, - {WLC_E_DISASSOC, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Conn", "Disassoc"} - }; - - const char* name = ""; - const char* cause = NULL; - int i; - - - for (i = 0; i < sizeof(event_map)/sizeof(event_map[0]); i++) { - const conn_fail_event_map_t* row = &event_map[i]; - if (row->inEvent == event_type && - (row->inStatus == status || row->inStatus == WL_IW_DONT_CARE) && - (row->inReason == reason || row->inReason == WL_IW_DONT_CARE)) { - name = row->outName; - cause = row->outCause; - break; - } - } - - - if (cause) { - memset(stringBuf, 0, buflen); - snprintf(stringBuf, buflen, "%s %s %02d %02d", - name, cause, status, reason); - WL_INFORM(("Connection status: %s\n", stringBuf)); - return TRUE; - } else { - return FALSE; - } -} - -#if WIRELESS_EXT > 14 - -static bool -wl_iw_check_conn_fail(wl_event_msg_t *e, char* stringBuf, uint buflen) -{ - uint32 event = ntoh32(e->event_type); - uint32 status = ntoh32(e->status); - uint32 reason = ntoh32(e->reason); - - if (wl_iw_conn_status_str(event, status, reason, stringBuf, buflen)) { - return TRUE; - } - else - return FALSE; -} -#endif - -#ifndef IW_CUSTOM_MAX -#define IW_CUSTOM_MAX 256 -#endif - -void -wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data) -{ -#if WIRELESS_EXT > 13 - union iwreq_data wrqu; - char extra[IW_CUSTOM_MAX + 1]; - int cmd = 0; - uint32 event_type = ntoh32(e->event_type); - uint16 flags = ntoh16(e->flags); - uint32 datalen = ntoh32(e->datalen); - uint32 status = ntoh32(e->status); - uint32 toto; - memset(&wrqu, 0, sizeof(wrqu)); - memset(extra, 0, sizeof(extra)); - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return; - } - - net_os_wake_lock(dev); - - WL_TRACE(("%s: dev=%s event=%d \n", __FUNCTION__, dev->name, event_type)); - - - switch (event_type) { -#if defined(SOFTAP) - case WLC_E_PRUNE: - if (ap_cfg_running) { - char *macaddr = (char *)&e->addr; - WL_SOFTAP(("PRUNE received, %02X:%02X:%02X:%02X:%02X:%02X!\n", - macaddr[0], macaddr[1], macaddr[2], macaddr[3], - macaddr[4], macaddr[5])); - - - if (ap_macmode) - { - int i; - for (i = 0; i < ap_black_list.count; i++) { - if (!bcmp(macaddr, &ap_black_list.ea[i], - sizeof(struct ether_addr))) { - WL_SOFTAP(("mac in black list, ignore it\n")); - break; - } - } - - if (i == ap_black_list.count) { - - char mac_buf[32] = {0}; - sprintf(mac_buf, "STA_BLOCK %02X:%02X:%02X:%02X:%02X:%02X", - macaddr[0], macaddr[1], macaddr[2], - macaddr[3], macaddr[4], macaddr[5]); - wl_iw_send_priv_event(priv_dev, mac_buf); - } - } - } - break; -#endif - case WLC_E_TXFAIL: - cmd = IWEVTXDROP; - memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - break; -#if WIRELESS_EXT > 14 - case WLC_E_JOIN: - case WLC_E_ASSOC_IND: - case WLC_E_REASSOC_IND: -#if defined(SOFTAP) - WL_SOFTAP(("STA connect received %d\n", event_type)); - if (ap_cfg_running) { - wl_iw_send_priv_event(priv_dev, "STA_JOIN"); - goto wl_iw_event_end; - } -#endif - memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - cmd = IWEVREGISTERED; - break; - case WLC_E_ROAM: - if (status == WLC_E_STATUS_SUCCESS) { - WL_ASSOC((" WLC_E_ROAM : success \n")); - goto wl_iw_event_end; - } - break; - - case WLC_E_DEAUTH_IND: - case WLC_E_DISASSOC_IND: -#if defined(SOFTAP) - WL_SOFTAP(("STA disconnect received %d\n", event_type)); - if (ap_cfg_running) { - wl_iw_send_priv_event(priv_dev, "STA_LEAVE"); - goto wl_iw_event_end; - } -#endif - cmd = SIOCGIWAP; - bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - bzero(&extra, ETHER_ADDR_LEN); - break; - case WLC_E_LINK: - case WLC_E_NDIS_LINK: - cmd = SIOCGIWAP; - if (!(flags & WLC_EVENT_MSG_LINK)) { - - -#ifdef SOFTAP -#ifdef AP_ONLY - if (ap_cfg_running) { -#else - if (ap_cfg_running && !strncmp(dev->name, "wl0.1", 5)) { -#endif - - WL_SOFTAP(("AP DOWN %d\n", event_type)); - wl_iw_send_priv_event(priv_dev, "AP_DOWN"); - } else { - WL_TRACE(("STA_Link Down\n")); - g_ss_cache_ctrl.m_link_down = 1; - } -#else - g_ss_cache_ctrl.m_link_down = 1; -#endif - WL_TRACE(("Link Down\n")); - - bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN); - bzero(&extra, ETHER_ADDR_LEN); - } - else { - - memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN); - g_ss_cache_ctrl.m_link_down = 0; - - memcpy(g_ss_cache_ctrl.m_active_bssid, &e->addr, ETHER_ADDR_LEN); -#ifdef SOFTAP - -#ifdef AP_ONLY - if (ap_cfg_running) { -#else - if (ap_cfg_running && !strncmp(dev->name, "wl0.1", 5)) { -#endif - - WL_SOFTAP(("AP UP %d\n", event_type)); - wl_iw_send_priv_event(priv_dev, "AP_UP"); - } else { - WL_TRACE(("STA_LINK_UP\n")); - } -#else -#endif - WL_TRACE(("Link UP\n")); - - } - wrqu.addr.sa_family = ARPHRD_ETHER; - break; - case WLC_E_ACTION_FRAME: - cmd = IWEVCUSTOM; - if (datalen + 1 <= sizeof(extra)) { - wrqu.data.length = datalen + 1; - extra[0] = WLC_E_ACTION_FRAME; - memcpy(&extra[1], data, datalen); - WL_TRACE(("WLC_E_ACTION_FRAME len %d \n", wrqu.data.length)); - } - break; - - case WLC_E_ACTION_FRAME_COMPLETE: - cmd = IWEVCUSTOM; - memcpy(&toto, data, 4); - if (sizeof(status) + 1 <= sizeof(extra)) { - wrqu.data.length = sizeof(status) + 1; - extra[0] = WLC_E_ACTION_FRAME_COMPLETE; - memcpy(&extra[1], &status, sizeof(status)); - printf("wl_iw_event status %d PacketId %d \n", status, toto); - printf("WLC_E_ACTION_FRAME_COMPLETE len %d \n", wrqu.data.length); - } - break; -#endif -#if WIRELESS_EXT > 17 - case WLC_E_MIC_ERROR: { - struct iw_michaelmicfailure *micerrevt = (struct iw_michaelmicfailure *)&extra; - cmd = IWEVMICHAELMICFAILURE; - wrqu.data.length = sizeof(struct iw_michaelmicfailure); - if (flags & WLC_EVENT_MSG_GROUP) - micerrevt->flags |= IW_MICFAILURE_GROUP; - else - micerrevt->flags |= IW_MICFAILURE_PAIRWISE; - memcpy(micerrevt->src_addr.sa_data, &e->addr, ETHER_ADDR_LEN); - micerrevt->src_addr.sa_family = ARPHRD_ETHER; - - break; - } - - case WLC_E_ASSOC_REQ_IE: - cmd = IWEVASSOCREQIE; - wrqu.data.length = datalen; - if (datalen < sizeof(extra)) - memcpy(extra, data, datalen); - break; - - case WLC_E_ASSOC_RESP_IE: - cmd = IWEVASSOCRESPIE; - wrqu.data.length = datalen; - if (datalen < sizeof(extra)) - memcpy(extra, data, datalen); - break; - - case WLC_E_PMKID_CACHE: { - if (data) - { - struct iw_pmkid_cand *iwpmkidcand = (struct iw_pmkid_cand *)&extra; - pmkid_cand_list_t *pmkcandlist; - pmkid_cand_t *pmkidcand; - int count; - - cmd = IWEVPMKIDCAND; - pmkcandlist = data; - count = ntoh32_ua((uint8 *)&pmkcandlist->npmkid_cand); - ASSERT(count >= 0); - wrqu.data.length = sizeof(struct iw_pmkid_cand); - pmkidcand = pmkcandlist->pmkid_cand; - while (count) { - bzero(iwpmkidcand, sizeof(struct iw_pmkid_cand)); - if (pmkidcand->preauth) - iwpmkidcand->flags |= IW_PMKID_CAND_PREAUTH; - bcopy(&pmkidcand->BSSID, &iwpmkidcand->bssid.sa_data, - ETHER_ADDR_LEN); - wireless_send_event(dev, cmd, &wrqu, extra); - pmkidcand++; - count--; - } - } - goto wl_iw_event_end; - } -#endif - - case WLC_E_SCAN_COMPLETE: -#if defined(WL_IW_USE_ISCAN) - if (!g_iscan) { - WL_ERROR(("Event WLC_E_SCAN_COMPLETE on g_iscan NULL!")); - goto wl_iw_event_end; - } - - if ((g_iscan) && (g_iscan->tsk_ctl.thr_pid >= 0) && - (g_iscan->iscan_state != ISCAN_STATE_IDLE)) - { - up(&g_iscan->tsk_ctl.sema); - } else { - cmd = SIOCGIWSCAN; - wrqu.data.length = strlen(extra); - WL_TRACE(("Event WLC_E_SCAN_COMPLETE from specific scan %d\n", - g_iscan->iscan_state)); - } -#else - cmd = SIOCGIWSCAN; - wrqu.data.length = strlen(extra); - WL_TRACE(("Event WLC_E_SCAN_COMPLETE\n")); -#endif - break; - - - case WLC_E_PFN_NET_FOUND: - { - wl_pfn_net_info_t *netinfo; - netinfo = (wl_pfn_net_info_t *)(data + sizeof(wl_pfn_scanresults_t) - - sizeof(wl_pfn_net_info_t)); - WL_ERROR(("%s Event WLC_E_PFN_NET_FOUND, send %s up : find %s len=%d\n", - __FUNCTION__, PNO_EVENT_UP, netinfo->pfnsubnet.SSID, - netinfo->pfnsubnet.SSID_len)); - cmd = IWEVCUSTOM; - memset(&wrqu, 0, sizeof(wrqu)); - strcpy(extra, PNO_EVENT_UP); - wrqu.data.length = strlen(extra); - } - break; - - default: - - WL_TRACE(("Unknown Event %d: ignoring\n", event_type)); - break; - } - if (cmd) { - if (cmd == SIOCGIWSCAN) - wireless_send_event(dev, cmd, &wrqu, NULL); - else - wireless_send_event(dev, cmd, &wrqu, extra); - } - -#if WIRELESS_EXT > 14 - - memset(extra, 0, sizeof(extra)); - if (wl_iw_check_conn_fail(e, extra, sizeof(extra))) { - cmd = IWEVCUSTOM; - wrqu.data.length = strlen(extra); - wireless_send_event(dev, cmd, &wrqu, extra); - } -#endif - - goto wl_iw_event_end; -wl_iw_event_end: - - net_os_wake_unlock(dev); -#endif -} - -int -wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) -{ - int res = 0; - wl_cnt_t cnt; - int phy_noise; - int rssi; - scb_val_t scb_val; - - phy_noise = 0; - if ((res = dev_wlc_ioctl(dev, WLC_GET_PHY_NOISE, &phy_noise, sizeof(phy_noise)))) - goto done; - - phy_noise = dtoh32(phy_noise); - WL_TRACE(("wl_iw_get_wireless_stats phy noise=%d\n", phy_noise)); - - bzero(&scb_val, sizeof(scb_val_t)); - if ((res = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)))) - goto done; - - rssi = dtoh32(scb_val.val); - WL_TRACE(("wl_iw_get_wireless_stats rssi=%d\n", rssi)); - if (rssi <= WL_IW_RSSI_NO_SIGNAL) - wstats->qual.qual = 0; - else if (rssi <= WL_IW_RSSI_VERY_LOW) - wstats->qual.qual = 1; - else if (rssi <= WL_IW_RSSI_LOW) - wstats->qual.qual = 2; - else if (rssi <= WL_IW_RSSI_GOOD) - wstats->qual.qual = 3; - else if (rssi <= WL_IW_RSSI_VERY_GOOD) - wstats->qual.qual = 4; - else - wstats->qual.qual = 5; - - - wstats->qual.level = 0x100 + rssi; - wstats->qual.noise = 0x100 + phy_noise; -#if WIRELESS_EXT > 18 - wstats->qual.updated |= (IW_QUAL_ALL_UPDATED | IW_QUAL_DBM); -#else - wstats->qual.updated |= 7; -#endif - -#if WIRELESS_EXT > 11 - WL_TRACE(("wl_iw_get_wireless_stats counters=%d\n", (int)sizeof(wl_cnt_t))); - - memset(&cnt, 0, sizeof(wl_cnt_t)); - res = dev_wlc_bufvar_get(dev, "counters", (char *)&cnt, sizeof(wl_cnt_t)); - if (res) - { - WL_ERROR(("wl_iw_get_wireless_stats counters failed error=%d\n", res)); - goto done; - } - - cnt.version = dtoh16(cnt.version); - if (cnt.version != WL_CNT_T_VERSION) { - WL_TRACE(("\tIncorrect version of counters struct: expected %d; got %d\n", - WL_CNT_T_VERSION, cnt.version)); - goto done; - } - - wstats->discard.nwid = 0; - wstats->discard.code = dtoh32(cnt.rxundec); - wstats->discard.fragment = dtoh32(cnt.rxfragerr); - wstats->discard.retries = dtoh32(cnt.txfail); - wstats->discard.misc = dtoh32(cnt.rxrunt) + dtoh32(cnt.rxgiant); - wstats->miss.beacon = 0; - - WL_TRACE(("wl_iw_get_wireless_stats counters txframe=%d txbyte=%d\n", - dtoh32(cnt.txframe), dtoh32(cnt.txbyte))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxfrmtoolong=%d\n", dtoh32(cnt.rxfrmtoolong))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxbadplcp=%d\n", dtoh32(cnt.rxbadplcp))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxundec=%d\n", dtoh32(cnt.rxundec))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxfragerr=%d\n", dtoh32(cnt.rxfragerr))); - WL_TRACE(("wl_iw_get_wireless_stats counters txfail=%d\n", dtoh32(cnt.txfail))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxrunt=%d\n", dtoh32(cnt.rxrunt))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxgiant=%d\n", dtoh32(cnt.rxgiant))); - -#endif - -done: - return res; -} -#if defined(COEX_DHCP) -static void -wl_iw_bt_flag_set( - struct net_device *dev, - bool set) -{ -#if defined(BT_DHCP_USE_FLAGS) - char buf_flag7_dhcp_on[8] = { 7, 00, 00, 00, 0x1, 0x0, 0x00, 0x00 }; - char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00}; -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_lock(); -#endif - - -#if defined(BT_DHCP_eSCO_FIX) - - set_btc_esco_params(dev, set); -#endif - - -#if defined(BT_DHCP_USE_FLAGS) - WL_TRACE_COEX(("WI-FI priority boost via bt flags, set:%d\n", set)); - if (set == TRUE) { - - dev_wlc_bufvar_set(dev, "btc_flags", - (char *)&buf_flag7_dhcp_on[0], sizeof(buf_flag7_dhcp_on)); - } - else { - - dev_wlc_bufvar_set(dev, "btc_flags", - (char *)&buf_flag7_default[0], sizeof(buf_flag7_default)); - } -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_unlock(); -#endif -} - -static void -wl_iw_bt_timerfunc(ulong data) -{ - bt_info_t *bt_local = (bt_info_t *)data; - bt_local->timer_on = 0; - WL_TRACE(("%s\n", __FUNCTION__)); - - up(&bt_local->tsk_ctl.sema); -} - -static int -_bt_dhcp_sysioc_thread(void *data) -{ - tsk_ctl_t *tsk_ctl = (tsk_ctl_t *)data; - - DAEMONIZE("dhcp_sysioc"); - - complete(&tsk_ctl->completed); - - while (down_interruptible(&tsk_ctl->sema) == 0) { - - SMP_RD_BARRIER_DEPENDS(); - if (tsk_ctl->terminated) { - break; - } - - if (g_bt->timer_on) { - g_bt->timer_on = 0; - del_timer_sync(&g_bt->timer); - } - - switch (g_bt->bt_state) { - case BT_DHCP_START: - - WL_TRACE_COEX(("%s bt_dhcp stm: started \n", __FUNCTION__)); - g_bt->bt_state = BT_DHCP_OPPORTUNITY_WINDOW; - mod_timer(&g_bt->timer, - jiffies + msecs_to_jiffies(BT_DHCP_OPPORTUNITY_WINDOW_TIME)); - g_bt->timer_on = 1; - break; - - case BT_DHCP_OPPORTUNITY_WINDOW: - if (g_bt->dhcp_done) { - WL_TRACE_COEX(("%s DHCP Done before T1 expiration\n", - __FUNCTION__)); - goto btc_coex_idle; - } - - - WL_TRACE_COEX(("%s DHCP T1:%d expired\n", - __FUNCTION__, BT_DHCP_OPPORTUNITY_WINDOW_TIME)); - - if (g_bt->dev) wl_iw_bt_flag_set(g_bt->dev, TRUE); - g_bt->bt_state = BT_DHCP_FLAG_FORCE_TIMEOUT; - mod_timer(&g_bt->timer, jiffies + msecs_to_jiffies(BT_DHCP_FLAG_FORCE_TIME)); - g_bt->timer_on = 1; - break; - - case BT_DHCP_FLAG_FORCE_TIMEOUT: - if (g_bt->dhcp_done) { - WL_TRACE_COEX(("%s DHCP Done before T2 expiration\n", - __FUNCTION__)); - } else { - - WL_TRACE_COEX(("%s DHCP wait interval T2:%d msec expired\n", - __FUNCTION__, BT_DHCP_FLAG_FORCE_TIME)); - } - - - if (g_bt->dev) wl_iw_bt_flag_set(g_bt->dev, FALSE); - btc_coex_idle: - g_bt->bt_state = BT_DHCP_IDLE; - g_bt->timer_on = 0; - break; - - default: - WL_ERROR(("%s error g_status=%d !!!\n", __FUNCTION__, - g_bt->bt_state)); - if (g_bt->dev) wl_iw_bt_flag_set(g_bt->dev, FALSE); - g_bt->bt_state = BT_DHCP_IDLE; - g_bt->timer_on = 0; - break; - } - - net_os_wake_unlock(g_bt->dev); - } - - if (g_bt->timer_on) { - g_bt->timer_on = 0; - del_timer_sync(&g_bt->timer); - } - complete_and_exit(&tsk_ctl->completed, 0); -} - -static void -wl_iw_bt_release(void) -{ - bt_info_t *bt_local = g_bt; - - if (!bt_local) { - return; - } - - if (bt_local->tsk_ctl.thr_pid >= 0) { - PROC_STOP(&bt_local->tsk_ctl); - } - kfree(bt_local); - g_bt = NULL; -} - -static int -wl_iw_bt_init(struct net_device *dev) -{ - bt_info_t *bt_dhcp = NULL; - - bt_dhcp = kmalloc(sizeof(bt_info_t), GFP_KERNEL); - if (!bt_dhcp) - return -ENOMEM; - - memset(bt_dhcp, 0, sizeof(bt_info_t)); - - g_bt = bt_dhcp; - bt_dhcp->dev = dev; - bt_dhcp->bt_state = BT_DHCP_IDLE; - - - bt_dhcp->timer_ms = 10; - init_timer(&bt_dhcp->timer); - bt_dhcp->timer.data = (ulong)bt_dhcp; - bt_dhcp->timer.function = wl_iw_bt_timerfunc; - bt_dhcp->ts_dhcp_start = 0; - bt_dhcp->ts_dhcp_ok = 0; - - PROC_START(_bt_dhcp_sysioc_thread, bt_dhcp, &bt_dhcp->tsk_ctl, 0); - if (bt_dhcp->tsk_ctl.thr_pid < 0) { - WL_ERROR(("Failed in %s\n", __FUNCTION__)); - return -ENOMEM; - } - - return 0; -} -#endif - -int -wl_iw_attach(struct net_device *dev, void * dhdp) -{ -#if defined(WL_IW_USE_ISCAN) - int params_size = 0; -#endif - wl_iw_t *iw; -#if defined(WL_IW_USE_ISCAN) - iscan_info_t *iscan = NULL; -#endif - - DHD_OS_MUTEX_INIT(&wl_cache_lock); - DHD_OS_MUTEX_INIT(&wl_softap_lock); - -#if defined(WL_IW_USE_ISCAN) - if (!dev) - return 0; - - - memset(&g_wl_iw_params, 0, sizeof(wl_iw_extra_params_t)); - - -#ifdef CSCAN - params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params)) + - (WL_NUMCHANNELS * sizeof(uint16)) + WL_SCAN_PARAMS_SSID_MAX * sizeof(wlc_ssid_t); -#else - params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params)); -#endif - iscan = kmalloc(sizeof(iscan_info_t), GFP_KERNEL); - if (!iscan) - return -ENOMEM; - memset(iscan, 0, sizeof(iscan_info_t)); - - - iscan->iscan_ex_params_p = (wl_iscan_params_t*)kmalloc(params_size, GFP_KERNEL); - if (!iscan->iscan_ex_params_p) { - kfree(iscan); - return -ENOMEM; - } - iscan->iscan_ex_param_size = params_size; - - - g_iscan = iscan; - iscan->dev = dev; - iscan->iscan_state = ISCAN_STATE_IDLE; - -#if defined(CONFIG_FIRST_SCAN) - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_IDLE; - g_first_counter_scans = 0; - g_iscan->scan_flag = 0; -#endif - -#ifdef CONFIG_WPS2 - g_wps_probe_req_ie = NULL; - g_wps_probe_req_ie_len = 0; -#endif - - iscan->timer_ms = 8000; - init_timer(&iscan->timer); - iscan->timer.data = (ulong)iscan; - iscan->timer.function = wl_iw_timerfunc; - - PROC_START(_iscan_sysioc_thread, iscan, &iscan->tsk_ctl, 0); - if (iscan->tsk_ctl.thr_pid < 0) - return -ENOMEM; -#endif - - iw = *(wl_iw_t **)netdev_priv(dev); - iw->pub = (dhd_pub_t *)dhdp; -#ifdef SOFTAP - priv_dev = dev; -#endif - g_scan = NULL; - - - g_scan = (void *)kmalloc(G_SCAN_RESULTS, GFP_KERNEL); - if (!g_scan) - return -ENOMEM; - - memset(g_scan, 0, G_SCAN_RESULTS); - g_scan_specified_ssid = 0; - -#if !defined(CSCAN) - - wl_iw_init_ss_cache_ctrl(); -#endif -#ifdef COEX_DHCP - - wl_iw_bt_init(dev); -#endif - - - return 0; -} - -void -wl_iw_detach(void) -{ -#if defined(WL_IW_USE_ISCAN) - iscan_buf_t *buf; - iscan_info_t *iscan = g_iscan; - - if (!iscan) - return; - if (iscan->tsk_ctl.thr_pid >= 0) { - PROC_STOP(&iscan->tsk_ctl); - } - DHD_OS_MUTEX_LOCK(&wl_cache_lock); - while (iscan->list_hdr) { - buf = iscan->list_hdr->next; - kfree(iscan->list_hdr); - iscan->list_hdr = buf; - } - kfree(iscan->iscan_ex_params_p); - kfree(iscan); - g_iscan = NULL; - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); -#endif - - if (g_scan) - kfree(g_scan); - - g_scan = NULL; -#ifdef CONFIG_WPS2 - - if (g_wps_probe_req_ie) { - kfree(g_wps_probe_req_ie); - g_wps_probe_req_ie = NULL; - g_wps_probe_req_ie_len = 0; - } -#endif -#if !defined(CSCAN) - wl_iw_release_ss_cache_ctrl(); -#endif -#ifdef COEX_DHCP - wl_iw_bt_release(); -#endif - -#ifdef SOFTAP - if (ap_cfg_running) { - WL_TRACE(("\n%s AP is going down\n", __FUNCTION__)); - - wl_iw_send_priv_event(priv_dev, "AP_DOWN"); - } -#endif - -} diff --git a/drivers/net/wireless/bcmdhd/wl_iw.h b/drivers/net/wireless/bcmdhd/wl_iw.h deleted file mode 100644 index 9cdb53dfef8c..000000000000 --- a/drivers/net/wireless/bcmdhd/wl_iw.h +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Linux Wireless Extensions support - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wl_iw.h,v 1.15.80.6 2010-12-23 01:13:23 $ - */ - - -#ifndef _wl_iw_h_ -#define _wl_iw_h_ - -#include - -#include -#include -#include - -#define WL_SCAN_PARAMS_SSID_MAX 10 -#define GET_SSID "SSID=" -#define GET_CHANNEL "CH=" -#define GET_NPROBE "NPROBE=" -#define GET_ACTIVE_ASSOC_DWELL "ACTIVE=" -#define GET_PASSIVE_ASSOC_DWELL "PASSIVE=" -#define GET_HOME_DWELL "HOME=" -#define GET_SCAN_TYPE "TYPE=" - -#define BAND_GET_CMD "GETBAND" -#define BAND_SET_CMD "SETBAND" -#define DTIM_SKIP_GET_CMD "DTIMSKIPGET" -#define DTIM_SKIP_SET_CMD "DTIMSKIPSET" -#define SETSUSPENDOPT_CMD "SETSUSPENDOPT" -#define SETSUSPENDMODE_CMD "SETSUSPENDMODE" -#define PNOSSIDCLR_SET_CMD "PNOSSIDCLR" - -#define PNOSETUP_SET_CMD "PNOSETUP " -#define PNOSETADD_SET_CMD "PNOSETADD" -#define PNOENABLE_SET_CMD "PNOFORCE" -#define PNODEBUG_SET_CMD "PNODEBUG" -#define TXPOWER_SET_CMD "TXPOWER" - -#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] -#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" - - -typedef struct wl_iw_extra_params { - int target_channel; -} wl_iw_extra_params_t; - -struct cntry_locales_custom { - char iso_abbrev[WLC_CNTRY_BUF_SZ]; - char custom_locale[WLC_CNTRY_BUF_SZ]; - int32 custom_locale_rev; -}; - - -#define WL_IW_RSSI_MINVAL -200 -#define WL_IW_RSSI_NO_SIGNAL -91 -#define WL_IW_RSSI_VERY_LOW -80 -#define WL_IW_RSSI_LOW -70 -#define WL_IW_RSSI_GOOD -68 -#define WL_IW_RSSI_VERY_GOOD -58 -#define WL_IW_RSSI_EXCELLENT -57 -#define WL_IW_RSSI_INVALID 0 -#define MAX_WX_STRING 80 -#define isprint(c) bcm_isprint(c) -#define WL_IW_SET_ACTIVE_SCAN (SIOCIWFIRSTPRIV+1) -#define WL_IW_GET_RSSI (SIOCIWFIRSTPRIV+3) -#define WL_IW_SET_PASSIVE_SCAN (SIOCIWFIRSTPRIV+5) -#define WL_IW_GET_LINK_SPEED (SIOCIWFIRSTPRIV+7) -#define WL_IW_GET_CURR_MACADDR (SIOCIWFIRSTPRIV+9) -#define WL_IW_SET_STOP (SIOCIWFIRSTPRIV+11) -#define WL_IW_SET_START (SIOCIWFIRSTPRIV+13) - - -#define WL_SET_AP_CFG (SIOCIWFIRSTPRIV+15) -#define WL_AP_STA_LIST (SIOCIWFIRSTPRIV+17) -#define WL_AP_MAC_FLTR (SIOCIWFIRSTPRIV+19) -#define WL_AP_BSS_START (SIOCIWFIRSTPRIV+21) -#define AP_LPB_CMD (SIOCIWFIRSTPRIV+23) -#define WL_AP_STOP (SIOCIWFIRSTPRIV+25) -#define WL_FW_RELOAD (SIOCIWFIRSTPRIV+27) -#define WL_AP_STA_DISASSOC (SIOCIWFIRSTPRIV+29) -#define WL_COMBO_SCAN (SIOCIWFIRSTPRIV+31) - - -#define G_SCAN_RESULTS 8*1024 -#define WE_ADD_EVENT_FIX 0x80 -#define G_WLAN_SET_ON 0 -#define G_WLAN_SET_OFF 1 - -#define CHECK_EXTRA_FOR_NULL(extra) \ -if (!extra) { \ - WL_ERROR(("%s: error : extra is null pointer\n", __FUNCTION__)); \ - return -EINVAL; \ -} - -typedef struct wl_iw { - char nickname[IW_ESSID_MAX_SIZE]; - - struct iw_statistics wstats; - - int spy_num; - int wpaversion; - int pcipher; - int gcipher; - int privacy_invoked; - - struct ether_addr spy_addr[IW_MAX_SPY]; - struct iw_quality spy_qual[IW_MAX_SPY]; - void *wlinfo; - dhd_pub_t * pub; -} wl_iw_t; - -int wl_control_wl_start(struct net_device *dev); -#define WLC_IW_SS_CACHE_MAXLEN 2048 -#define WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN 32 -#define WLC_IW_BSS_INFO_MAXLEN \ - (WLC_IW_SS_CACHE_MAXLEN - WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN) - -typedef struct wl_iw_ss_cache { - struct wl_iw_ss_cache *next; - int dirty; - uint32 buflen; - uint32 version; - uint32 count; - wl_bss_info_t bss_info[1]; -} wl_iw_ss_cache_t; - -typedef struct wl_iw_ss_cache_ctrl { - wl_iw_ss_cache_t *m_cache_head; - int m_link_down; - int m_timer_expired; - char m_active_bssid[ETHER_ADDR_LEN]; - uint m_prev_scan_mode; - uint m_cons_br_scan_cnt; - struct timer_list *m_timer; -} wl_iw_ss_cache_ctrl_t; - -typedef enum broadcast_first_scan { - BROADCAST_SCAN_FIRST_IDLE = 0, - BROADCAST_SCAN_FIRST_STARTED, - BROADCAST_SCAN_FIRST_RESULT_READY, - BROADCAST_SCAN_FIRST_RESULT_CONSUMED -} broadcast_first_scan_t; -#ifdef SOFTAP -#define SSID_LEN 33 -#define SEC_LEN 16 -#define KEY_LEN 65 -#define PROFILE_OFFSET 32 -struct ap_profile { - uint8 ssid[SSID_LEN]; - uint8 sec[SEC_LEN]; - uint8 key[KEY_LEN]; - uint32 channel; - uint32 preamble; - uint32 max_scb; - uint32 closednet; - char country_code[WLC_CNTRY_BUF_SZ]; -}; - - -#define MACLIST_MODE_DISABLED 0 -#define MACLIST_MODE_DENY 1 -#define MACLIST_MODE_ALLOW 2 -struct mflist { - uint count; - struct ether_addr ea[16]; -}; -struct mac_list_set { - uint32 mode; - struct mflist mac_list; -}; -#endif - -#if WIRELESS_EXT > 12 -#include -extern const struct iw_handler_def wl_iw_handler_def; -#endif - -extern int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -extern void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data); -extern int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats); -int wl_iw_attach(struct net_device *dev, void * dhdp); -void wl_iw_detach(void); - -extern int net_os_wake_lock(struct net_device *dev); -extern int net_os_wake_unlock(struct net_device *dev); -extern int net_os_wake_lock_timeout(struct net_device *dev); -extern int net_os_wake_lock_ctrl_timeout_enable(struct net_device *dev, int val); -extern int net_os_set_suspend_disable(struct net_device *dev, int val); -extern int net_os_set_suspend(struct net_device *dev, int val, int force); -extern int net_os_set_dtim_skip(struct net_device *dev, int val); -extern void get_customized_country_code(char *country_iso_code, wl_country_t *cspec); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) -#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \ - iwe_stream_add_event(info, stream, ends, iwe, extra) -#define IWE_STREAM_ADD_VALUE(info, event, value, ends, iwe, event_len) \ - iwe_stream_add_value(info, event, value, ends, iwe, event_len) -#define IWE_STREAM_ADD_POINT(info, stream, ends, iwe, extra) \ - iwe_stream_add_point(info, stream, ends, iwe, extra) -#else -#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \ - iwe_stream_add_event(stream, ends, iwe, extra) -#define IWE_STREAM_ADD_VALUE(info, event, value, ends, iwe, event_len) \ - iwe_stream_add_value(event, value, ends, iwe, event_len) -#define IWE_STREAM_ADD_POINT(info, stream, ends, iwe, extra) \ - iwe_stream_add_point(stream, ends, iwe, extra) -#endif - -extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled); -extern int dhd_pno_clean(dhd_pub_t *dhd); -extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, - ushort scan_fr, int pno_repeat, int pno_freq_expo_max); -extern int dhd_pno_get_status(dhd_pub_t *dhd); -extern int dhd_dev_pno_reset(struct net_device *dev); -extern int dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local, - int nssid, ushort scan_fr, int pno_repeat, int pno_freq_expo_max); -extern int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled); -extern int dhd_dev_get_pno_status(struct net_device *dev); -extern int dhd_get_dtim_skip(dhd_pub_t *dhd); - -void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec); - -#define PNO_TLV_PREFIX 'S' -#define PNO_TLV_VERSION '1' -#define PNO_TLV_SUBVERSION '2' -#define PNO_TLV_RESERVED '0' -#define PNO_TLV_TYPE_SSID_IE 'S' -#define PNO_TLV_TYPE_TIME 'T' -#define PNO_TLV_FREQ_REPEAT 'R' -#define PNO_TLV_FREQ_EXPO_MAX 'M' -#define PNO_EVENT_UP "PNO_EVENT" - -typedef struct cmd_tlv { - char prefix; - char version; - char subver; - char reserved; -} cmd_tlv_t; - - - - -typedef struct cscan_tlv { - char prefix; - char version; - char subver; - char reserved; -} cscan_tlv_t; - -#define CSCAN_COMMAND "CSCAN " -#define CSCAN_TLV_PREFIX 'S' -#define CSCAN_TLV_VERSION 1 -#define CSCAN_TLV_SUBVERSION 0 -#define CSCAN_TLV_TYPE_SSID_IE 'S' -#define CSCAN_TLV_TYPE_CHANNEL_IE 'C' -#define CSCAN_TLV_TYPE_NPROBE_IE 'N' -#define CSCAN_TLV_TYPE_ACTIVE_IE 'A' -#define CSCAN_TLV_TYPE_PASSIVE_IE 'P' -#define CSCAN_TLV_TYPE_HOME_IE 'H' -#define CSCAN_TLV_TYPE_STYPE_IE 'T' - -#ifdef SOFTAP_TLV_CFG - -#define SOFTAP_SET_CMD "SOFTAPSET " -#define SOFTAP_TLV_PREFIX 'A' -#define SOFTAP_TLV_VERSION '1' -#define SOFTAP_TLV_SUBVERSION '0' -#define SOFTAP_TLV_RESERVED '0' - -#define TLV_TYPE_SSID 'S' -#define TLV_TYPE_SECUR 'E' -#define TLV_TYPE_KEY 'K' -#define TLV_TYPE_CHANNEL 'C' -#endif - -extern int wl_iw_parse_channel_list_tlv(char** list_str, uint16* channel_list, - int channel_num, int *bytes_left); - -extern int wl_iw_parse_data_tlv(char** list_str, void *dst, int dst_size, - const char token, int input_size, int *bytes_left); - -extern int wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, - int max, int *bytes_left); - -extern int wl_iw_parse_ssid_list(char** list_str, wlc_ssid_t* ssid, int idx, int max); - -extern int wl_iw_parse_channel_list(char** list_str, uint16* channel_list, int channel_num); - - -#define NETDEV_PRIV(dev) (*(wl_iw_t **)netdev_priv(dev)) - -#ifdef CONFIG_WPS2 -#define WPS_ADD_PROBE_REQ_IE_CMD "ADD_WPS_PROBE_REQ_IE " -#define WPS_DEL_PROBE_REQ_IE_CMD "DEL_WPS_PROBE_REQ_IE " -#define WPS_PROBE_REQ_IE_CMD_LENGTH 21 -#endif - -#endif diff --git a/drivers/net/wireless/bcmdhd/wl_linux_mon.c b/drivers/net/wireless/bcmdhd/wl_linux_mon.c deleted file mode 100644 index f44b4b04bb96..000000000000 --- a/drivers/net/wireless/bcmdhd/wl_linux_mon.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Broadcom Dongle Host Driver (DHD), Linux monitor network interface - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wl_linux_mon.c 303266 2011-12-16 00:15:23Z $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -typedef enum monitor_states -{ - MONITOR_STATE_DEINIT = 0x0, - MONITOR_STATE_INIT = 0x1, - MONITOR_STATE_INTERFACE_ADDED = 0x2, - MONITOR_STATE_INTERFACE_DELETED = 0x4 -} monitor_states_t; -extern int dhd_start_xmit(struct sk_buff *skb, struct net_device *net); - -/** - * Local declarations and defintions (not exposed) - */ -#define MON_PRINT(format, ...) printk("DHD-MON: %s " format, __func__, ##__VA_ARGS__) -#define MON_TRACE MON_PRINT - -typedef struct monitor_interface { - int radiotap_enabled; - struct net_device* real_ndev; /* The real interface that the monitor is on */ - struct net_device* mon_ndev; -} monitor_interface; - -typedef struct dhd_linux_monitor { - void *dhd_pub; - monitor_states_t monitor_state; - monitor_interface mon_if[DHD_MAX_IFS]; - struct mutex lock; /* lock to protect mon_if */ -} dhd_linux_monitor_t; - -static dhd_linux_monitor_t g_monitor; - -static struct net_device* lookup_real_netdev(char *name); -static monitor_interface* ndev_to_monif(struct net_device *ndev); -static int dhd_mon_if_open(struct net_device *ndev); -static int dhd_mon_if_stop(struct net_device *ndev); -static int dhd_mon_if_subif_start_xmit(struct sk_buff *skb, struct net_device *ndev); -static void dhd_mon_if_set_multicast_list(struct net_device *ndev); -static int dhd_mon_if_change_mac(struct net_device *ndev, void *addr); - -static const struct net_device_ops dhd_mon_if_ops = { - .ndo_open = dhd_mon_if_open, - .ndo_stop = dhd_mon_if_stop, - .ndo_start_xmit = dhd_mon_if_subif_start_xmit, - .ndo_set_multicast_list = dhd_mon_if_set_multicast_list, - .ndo_set_mac_address = dhd_mon_if_change_mac, -}; - -/** - * Local static function defintions - */ - -/* Look up dhd's net device table to find a match (e.g. interface "eth0" is a match for "mon.eth0" - * "p2p-eth0-0" is a match for "mon.p2p-eth0-0") - */ -static struct net_device* lookup_real_netdev(char *name) -{ - int i; - int len = 0; - int last_name_len = 0; - struct net_device *ndev; - struct net_device *ndev_found = NULL; - - /* We need to find interface "p2p-p2p-0" corresponding to monitor interface "mon-p2p-0", - * Once mon iface name reaches IFNAMSIZ, it is reset to p2p0-0 and corresponding mon - * iface would be mon-p2p0-0. - */ - for (i = 0; i < DHD_MAX_IFS; i++) { - ndev = dhd_idx2net(g_monitor.dhd_pub, i); - - /* Skip "p2p" and look for "-p2p0-x" in monitor interface name. If it - * it matches, then this netdev is the corresponding real_netdev. - */ - if (ndev && strstr(ndev->name, "p2p-p2p0")) { - len = strlen("p2p"); - } else { - /* if p2p- is not present, then the IFNAMSIZ have reached and name - * would have got reset. In this casse,look for p2p0-x in mon-p2p0-x - */ - len = 0; - } - if (ndev && strstr(name, (ndev->name + len))) { - if (strlen(ndev->name) > last_name_len) { - ndev_found = ndev; - last_name_len = strlen(ndev->name); - } - } - } - - return ndev_found; -} - -static monitor_interface* ndev_to_monif(struct net_device *ndev) -{ - int i; - - for (i = 0; i < DHD_MAX_IFS; i++) { - if (g_monitor.mon_if[i].mon_ndev == ndev) - return &g_monitor.mon_if[i]; - } - - return NULL; -} - -static int dhd_mon_if_open(struct net_device *ndev) -{ - int ret = 0; - - MON_PRINT("enter\n"); - return ret; -} - -static int dhd_mon_if_stop(struct net_device *ndev) -{ - int ret = 0; - - MON_PRINT("enter\n"); - return ret; -} - -static int dhd_mon_if_subif_start_xmit(struct sk_buff *skb, struct net_device *ndev) -{ - int ret = 0; - int rtap_len; - int qos_len = 0; - int dot11_hdr_len = 24; - int snap_len = 6; - unsigned char *pdata; - unsigned short frame_ctl; - unsigned char src_mac_addr[6]; - unsigned char dst_mac_addr[6]; - struct ieee80211_hdr *dot11_hdr; - struct ieee80211_radiotap_header *rtap_hdr; - monitor_interface* mon_if; - - MON_PRINT("enter\n"); - - mon_if = ndev_to_monif(ndev); - if (mon_if == NULL || mon_if->real_ndev == NULL) { - MON_PRINT(" cannot find matched net dev, skip the packet\n"); - goto fail; - } - - if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header))) - goto fail; - - rtap_hdr = (struct ieee80211_radiotap_header *)skb->data; - if (unlikely(rtap_hdr->it_version)) - goto fail; - - rtap_len = ieee80211_get_radiotap_len(skb->data); - if (unlikely(skb->len < rtap_len)) - goto fail; - - MON_PRINT("radiotap len (should be 14): %d\n", rtap_len); - - /* Skip the ratio tap header */ - skb_pull(skb, rtap_len); - - dot11_hdr = (struct ieee80211_hdr *)skb->data; - frame_ctl = le16_to_cpu(dot11_hdr->frame_control); - /* Check if the QoS bit is set */ - if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) { - /* Check if this ia a Wireless Distribution System (WDS) frame - * which has 4 MAC addresses - */ - if (dot11_hdr->frame_control & 0x0080) - qos_len = 2; - if ((dot11_hdr->frame_control & 0x0300) == 0x0300) - dot11_hdr_len += 6; - - memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr)); - memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr)); - - /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for - * for two MAC addresses - */ - skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2); - pdata = (unsigned char*)skb->data; - memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr)); - memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr)); - - MON_PRINT("if name: %s, matched if name %s\n", ndev->name, mon_if->real_ndev->name); - - /* Use the real net device to transmit the packet */ - ret = dhd_start_xmit(skb, mon_if->real_ndev); - - return ret; - } -fail: - dev_kfree_skb(skb); - return 0; -} - -static void dhd_mon_if_set_multicast_list(struct net_device *ndev) -{ - monitor_interface* mon_if; - - mon_if = ndev_to_monif(ndev); - if (mon_if == NULL || mon_if->real_ndev == NULL) { - MON_PRINT(" cannot find matched net dev, skip the packet\n"); - } else { - MON_PRINT("enter, if name: %s, matched if name %s\n", - ndev->name, mon_if->real_ndev->name); - } -} - -static int dhd_mon_if_change_mac(struct net_device *ndev, void *addr) -{ - int ret = 0; - monitor_interface* mon_if; - - mon_if = ndev_to_monif(ndev); - if (mon_if == NULL || mon_if->real_ndev == NULL) { - MON_PRINT(" cannot find matched net dev, skip the packet\n"); - } else { - MON_PRINT("enter, if name: %s, matched if name %s\n", - ndev->name, mon_if->real_ndev->name); - } - return ret; -} - -/** - * Global function definitions (declared in dhd_linux_mon.h) - */ - -int dhd_add_monitor(char *name, struct net_device **new_ndev) -{ - int i; - int idx = -1; - int ret = 0; - struct net_device* ndev = NULL; - dhd_linux_monitor_t **dhd_mon; - - mutex_lock(&g_monitor.lock); - - MON_TRACE("enter, if name: %s\n", name); - if (!name || !new_ndev) { - MON_PRINT("invalid parameters\n"); - ret = -EINVAL; - goto out; - } - - /* - * Find a vacancy - */ - for (i = 0; i < DHD_MAX_IFS; i++) - if (g_monitor.mon_if[i].mon_ndev == NULL) { - idx = i; - break; - } - if (idx == -1) { - MON_PRINT("exceeds maximum interfaces\n"); - ret = -EFAULT; - goto out; - } - - ndev = alloc_etherdev(sizeof(dhd_linux_monitor_t*)); - if (!ndev) { - MON_PRINT("failed to allocate memory\n"); - ret = -ENOMEM; - goto out; - } - - ndev->type = ARPHRD_IEEE80211_RADIOTAP; - strncpy(ndev->name, name, IFNAMSIZ); - ndev->name[IFNAMSIZ - 1] = 0; - ndev->netdev_ops = &dhd_mon_if_ops; - - ret = register_netdevice(ndev); - if (ret) { - MON_PRINT(" register_netdevice failed (%d)\n", ret); - goto out; - } - - *new_ndev = ndev; - g_monitor.mon_if[idx].radiotap_enabled = TRUE; - g_monitor.mon_if[idx].mon_ndev = ndev; - g_monitor.mon_if[idx].real_ndev = lookup_real_netdev(name); - dhd_mon = (dhd_linux_monitor_t **)netdev_priv(ndev); - *dhd_mon = &g_monitor; - g_monitor.monitor_state = MONITOR_STATE_INTERFACE_ADDED; - MON_PRINT("net device returned: 0x%p\n", ndev); - MON_PRINT("found a matched net device, name %s\n", g_monitor.mon_if[idx].real_ndev->name); - -out: - if (ret && ndev) - free_netdev(ndev); - - mutex_unlock(&g_monitor.lock); - return ret; - -} - -int dhd_del_monitor(struct net_device *ndev) -{ - int i; - bool rollback_lock = false; - if (!ndev) - return -EINVAL; - mutex_lock(&g_monitor.lock); - for (i = 0; i < DHD_MAX_IFS; i++) { - if (g_monitor.mon_if[i].mon_ndev == ndev || - g_monitor.mon_if[i].real_ndev == ndev) { - g_monitor.mon_if[i].real_ndev = NULL; - if (rtnl_is_locked()) { - rtnl_unlock(); - rollback_lock = true; - } - unregister_netdev(g_monitor.mon_if[i].mon_ndev); - free_netdev(g_monitor.mon_if[i].mon_ndev); - g_monitor.mon_if[i].mon_ndev = NULL; - g_monitor.monitor_state = MONITOR_STATE_INTERFACE_DELETED; - break; - } - } - if (rollback_lock) { - rtnl_lock(); - rollback_lock = false; - } - - if (g_monitor.monitor_state != - MONITOR_STATE_INTERFACE_DELETED) - MON_PRINT("interface not found in monitor IF array, is this a monitor IF? 0x%p\n", - ndev); - mutex_unlock(&g_monitor.lock); - - return 0; -} - -int dhd_monitor_init(void *dhd_pub) -{ - if (g_monitor.monitor_state == MONITOR_STATE_DEINIT) { - g_monitor.dhd_pub = dhd_pub; - mutex_init(&g_monitor.lock); - g_monitor.monitor_state = MONITOR_STATE_INIT; - } - return 0; -} - -int dhd_monitor_uninit(void) -{ - int i; - struct net_device *ndev; - bool rollback_lock = false; - mutex_lock(&g_monitor.lock); - if (g_monitor.monitor_state != MONITOR_STATE_DEINIT) { - for (i = 0; i < DHD_MAX_IFS; i++) { - ndev = g_monitor.mon_if[i].mon_ndev; - if (ndev) { - if (rtnl_is_locked()) { - rtnl_unlock(); - rollback_lock = true; - } - unregister_netdev(ndev); - free_netdev(ndev); - g_monitor.mon_if[i].real_ndev = NULL; - g_monitor.mon_if[i].mon_ndev = NULL; - if (rollback_lock) { - rtnl_lock(); - rollback_lock = false; - } - } - } - g_monitor.monitor_state = MONITOR_STATE_DEINIT; - } - mutex_unlock(&g_monitor.lock); - return 0; -} diff --git a/drivers/net/wireless/bcmdhd/wldev_common.c b/drivers/net/wireless/bcmdhd/wldev_common.c deleted file mode 100644 index 7bea3dcfa716..000000000000 --- a/drivers/net/wireless/bcmdhd/wldev_common.c +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Common function shared by Linux WEXT, cfg80211 and p2p drivers - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wldev_common.c,v 1.1.4.1.2.14 2011-02-09 01:40:07 $ - */ - -#include -#include -#include -#include - -#include -#include - -#define htod32(i) i -#define htod16(i) i -#define dtoh32(i) i -#define dtoh16(i) i -#define htodchanspec(i) i -#define dtohchanspec(i) i - -#define WLDEV_ERROR(args) \ - do { \ - printk(KERN_ERR "WLDEV-ERROR) %s : ", __func__); \ - printk args; \ - } while (0) - -extern int dhd_ioctl_entry_local(struct net_device *net, wl_ioctl_t *ioc, int cmd); - -s32 wldev_ioctl( - struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set) -{ - s32 ret = 0; - struct wl_ioctl ioc; - - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = cmd; - ioc.buf = arg; - ioc.len = len; - ioc.set = set; - - ret = dhd_ioctl_entry_local(dev, &ioc, cmd); - return ret; -} - -/* Format a iovar buffer, not bsscfg indexed. The bsscfg index will be - * taken care of in dhd_ioctl_entry. Internal use only, not exposed to - * wl_iw, wl_cfg80211 and wl_cfgp2p - */ -static s32 wldev_mkiovar( - s8 *iovar_name, s8 *param, s32 paramlen, - s8 *iovar_buf, u32 buflen) -{ - s32 iolen = 0; - - iolen = bcm_mkiovar(iovar_name, param, paramlen, iovar_buf, buflen); - return iolen; -} - -s32 wldev_iovar_getbuf( - struct net_device *dev, s8 *iovar_name, - void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync) -{ - s32 ret = 0; - s32 iovar_len = 0; - if (buf_sync) { - mutex_lock(buf_sync); - } - iovar_len = wldev_mkiovar(iovar_name, param, paramlen, buf, buflen); - ret = wldev_ioctl(dev, WLC_GET_VAR, buf, buflen, FALSE); - if (buf_sync) - mutex_unlock(buf_sync); - return ret; -} - - -s32 wldev_iovar_setbuf( - struct net_device *dev, s8 *iovar_name, - void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync) -{ - s32 ret = 0; - s32 iovar_len; - if (buf_sync) { - mutex_lock(buf_sync); - } - iovar_len = wldev_mkiovar(iovar_name, param, paramlen, buf, buflen); - ret = wldev_ioctl(dev, WLC_SET_VAR, buf, iovar_len, TRUE); - if (buf_sync) - mutex_unlock(buf_sync); - return ret; -} - -s32 wldev_iovar_setint( - struct net_device *dev, s8 *iovar, s32 val) -{ - s8 iovar_buf[WLC_IOCTL_SMLEN]; - - val = htod32(val); - memset(iovar_buf, 0, sizeof(iovar_buf)); - return wldev_iovar_setbuf(dev, iovar, &val, sizeof(val), iovar_buf, - sizeof(iovar_buf), NULL); -} - - -s32 wldev_iovar_getint( - struct net_device *dev, s8 *iovar, s32 *pval) -{ - s8 iovar_buf[WLC_IOCTL_SMLEN]; - s32 err; - - memset(iovar_buf, 0, sizeof(iovar_buf)); - err = wldev_iovar_getbuf(dev, iovar, pval, sizeof(*pval), iovar_buf, - sizeof(iovar_buf), NULL); - if (err == 0) - { - memcpy(pval, iovar_buf, sizeof(*pval)); - *pval = dtoh32(*pval); - } - return err; -} - -/** Format a bsscfg indexed iovar buffer. The bsscfg index will be - * taken care of in dhd_ioctl_entry. Internal use only, not exposed to - * wl_iw, wl_cfg80211 and wl_cfgp2p - */ -s32 wldev_mkiovar_bsscfg( - const s8 *iovar_name, s8 *param, s32 paramlen, - s8 *iovar_buf, s32 buflen, s32 bssidx) -{ - const s8 *prefix = "bsscfg:"; - s8 *p; - u32 prefixlen; - u32 namelen; - u32 iolen; - - if (bssidx == 0) { - return wldev_mkiovar((s8*)iovar_name, (s8 *)param, paramlen, - (s8 *) iovar_buf, buflen); - } - - prefixlen = (u32) strlen(prefix); /* lengh of bsscfg prefix */ - namelen = (u32) strlen(iovar_name) + 1; /* lengh of iovar name + null */ - iolen = prefixlen + namelen + sizeof(u32) + paramlen; - - if (buflen < 0 || iolen > (u32)buflen) - { - WLDEV_ERROR(("%s: buffer is too short\n", __FUNCTION__)); - return BCME_BUFTOOSHORT; - } - - p = (s8 *)iovar_buf; - - /* copy prefix, no null */ - memcpy(p, prefix, prefixlen); - p += prefixlen; - - /* copy iovar name including null */ - memcpy(p, iovar_name, namelen); - p += namelen; - - /* bss config index as first param */ - bssidx = htod32(bssidx); - memcpy(p, &bssidx, sizeof(u32)); - p += sizeof(u32); - - /* parameter buffer follows */ - if (paramlen) - memcpy(p, param, paramlen); - - return iolen; - -} - -s32 wldev_iovar_getbuf_bsscfg( - struct net_device *dev, s8 *iovar_name, - void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync) -{ - s32 ret = 0; - s32 iovar_len = 0; - if (buf_sync) { - mutex_lock(buf_sync); - } - iovar_len = wldev_mkiovar_bsscfg(iovar_name, param, paramlen, buf, buflen, bsscfg_idx); - ret = wldev_ioctl(dev, WLC_GET_VAR, buf, buflen, FALSE); - if (buf_sync) { - mutex_unlock(buf_sync); - } - return ret; - -} - -s32 wldev_iovar_setbuf_bsscfg( - struct net_device *dev, s8 *iovar_name, - void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync) -{ - s32 ret = 0; - s32 iovar_len; - if (buf_sync) { - mutex_lock(buf_sync); - } - iovar_len = wldev_mkiovar_bsscfg(iovar_name, param, paramlen, buf, buflen, bsscfg_idx); - - ret = wldev_ioctl(dev, WLC_SET_VAR, buf, iovar_len, TRUE); - if (buf_sync) { - mutex_unlock(buf_sync); - } - return ret; -} - -s32 wldev_iovar_setint_bsscfg( - struct net_device *dev, s8 *iovar, s32 val, s32 bssidx) -{ - s8 iovar_buf[WLC_IOCTL_SMLEN]; - - val = htod32(val); - memset(iovar_buf, 0, sizeof(iovar_buf)); - return wldev_iovar_setbuf_bsscfg(dev, iovar, &val, sizeof(val), iovar_buf, - sizeof(iovar_buf), bssidx, NULL); -} - - -s32 wldev_iovar_getint_bsscfg( - struct net_device *dev, s8 *iovar, s32 *pval, s32 bssidx) -{ - s8 iovar_buf[WLC_IOCTL_SMLEN]; - s32 err; - - memset(iovar_buf, 0, sizeof(iovar_buf)); - err = wldev_iovar_getbuf_bsscfg(dev, iovar, pval, sizeof(*pval), iovar_buf, - sizeof(iovar_buf), bssidx, NULL); - if (err == 0) - { - memcpy(pval, iovar_buf, sizeof(*pval)); - *pval = dtoh32(*pval); - } - return err; -} - -int wldev_get_link_speed( - struct net_device *dev, int *plink_speed) -{ - int error; - - if (!plink_speed) - return -ENOMEM; - error = wldev_ioctl(dev, WLC_GET_RATE, plink_speed, sizeof(int), 0); - if (unlikely(error)) - return error; - - /* Convert internal 500Kbps to Kbps */ - *plink_speed *= 500; - return error; -} - -int wldev_get_rssi( - struct net_device *dev, int *prssi) -{ - scb_val_t scb_val; - int error; - - if (!prssi) - return -ENOMEM; - bzero(&scb_val, sizeof(scb_val_t)); - - error = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t), 0); - if (unlikely(error)) - return error; - - *prssi = dtoh32(scb_val.val); - return error; -} - -int wldev_get_ssid( - struct net_device *dev, wlc_ssid_t *pssid) -{ - int error; - - if (!pssid) - return -ENOMEM; - error = wldev_ioctl(dev, WLC_GET_SSID, pssid, sizeof(wlc_ssid_t), 0); - if (unlikely(error)) - return error; - pssid->SSID_len = dtoh32(pssid->SSID_len); - return error; -} - -int wldev_get_band( - struct net_device *dev, uint *pband) -{ - int error; - - error = wldev_ioctl(dev, WLC_GET_BAND, pband, sizeof(uint), 0); - return error; -} - -int wldev_set_band( - struct net_device *dev, uint band) -{ - int error = -1; - - if ((band == WLC_BAND_AUTO) || (band == WLC_BAND_5G) || (band == WLC_BAND_2G)) { - error = wldev_ioctl(dev, WLC_SET_BAND, &band, sizeof(band), 1); - if (!error) - dhd_bus_band_set(dev, band); - } - return error; -} - -int wldev_set_country( - struct net_device *dev, char *country_code) -{ - int error = -1; - wl_country_t cspec = {{0}, 0, {0}}; - scb_val_t scbval; - char smbuf[WLC_IOCTL_SMLEN]; - - if (!country_code) { - WLDEV_ERROR(("%s: set country failed for %s\n", - __FUNCTION__, country_code)); - return error; - } - - error = wldev_iovar_getbuf(dev, "country", &cspec, sizeof(cspec), - smbuf, sizeof(smbuf), NULL); - if (error < 0) - WLDEV_ERROR(("%s: get country failed = %d\n", __FUNCTION__, error)); - - if ((error < 0) || - (strncmp(country_code, smbuf, WLC_CNTRY_BUF_SZ) != 0)) { - bzero(&scbval, sizeof(scb_val_t)); - error = wldev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t), 1); - if (error < 0) { - WLDEV_ERROR(("%s: set country failed due to Disassoc error %d\n", - __FUNCTION__, error)); - return error; - } - - cspec.rev = -1; - memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ); - memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ); - get_customized_country_code((char *)&cspec.country_abbrev, &cspec); - error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec), - smbuf, sizeof(smbuf), NULL); - if (error < 0) { - WLDEV_ERROR(("%s: set country for %s as %s rev %d failed\n", - __FUNCTION__, country_code, cspec.ccode, cspec.rev)); - return error; - } - dhd_bus_country_set(dev, &cspec); - WLDEV_ERROR(("%s: set country for %s as %s rev %d\n", - __FUNCTION__, country_code, cspec.ccode, cspec.rev)); - } - return 0; -} - -/* - * softap channel autoselect - */ -int wldev_get_auto_channel(struct net_device *dev, int *chan) -{ - int chosen = 0; - wl_uint32_list_t request; - int retry = 0; - int updown = 0; - int ret = 0; - wlc_ssid_t null_ssid; - - memset(&null_ssid, 0, sizeof(wlc_ssid_t)); - ret |= wldev_ioctl(dev, WLC_UP, &updown, sizeof(updown), true); - - ret |= wldev_ioctl(dev, WLC_SET_SSID, &null_ssid, sizeof(null_ssid), true); - - request.count = htod32(0); - ret = wldev_ioctl(dev, WLC_START_CHANNEL_SEL, &request, sizeof(request), true); - if (ret < 0) { - WLDEV_ERROR(("can't start auto channel scan:%d\n", ret)); - goto fail; - } - - while (retry++ < 15) { - - bcm_mdelay(350); - - ret = wldev_ioctl(dev, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen), false); - - if ((ret == 0) && (dtoh32(chosen) != 0)) { - *chan = (uint16)chosen & 0x00FF; /* covert chanspec --> chan number */ - printf("%s: Got channel = %d, attempt:%d\n", - __FUNCTION__, *chan, retry); - break; - } - } - - if ((ret = wldev_ioctl(dev, WLC_DOWN, &updown, sizeof(updown), true)) < 0) { - WLDEV_ERROR(("%s fail to WLC_DOWN ioctl err =%d\n", __FUNCTION__, ret)); - goto fail; - } - -fail : - if (ret < 0) { - WLDEV_ERROR(("%s: return value %d\n", __FUNCTION__, ret)); - } - return ret; -} diff --git a/drivers/net/wireless/bcmdhd/wldev_common.h b/drivers/net/wireless/bcmdhd/wldev_common.h deleted file mode 100644 index dd3c899d12ca..000000000000 --- a/drivers/net/wireless/bcmdhd/wldev_common.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Common function shared by Linux WEXT, cfg80211 and p2p drivers - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wldev_common.h,v 1.1.4.1.2.14 2011-02-09 01:40:07 $ - */ -#ifndef __WLDEV_COMMON_H__ -#define __WLDEV_COMMON_H__ - -#include - -/* wl_dev_ioctl - get/set IOCTLs, will call net_device's do_ioctl (or - * netdev_ops->ndo_do_ioctl in new kernels) - * @dev: the net_device handle - */ -s32 wldev_ioctl( - struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set); - -/** Retrieve named IOVARs, this function calls wl_dev_ioctl with - * WLC_GET_VAR IOCTL code - */ -s32 wldev_iovar_getbuf( - struct net_device *dev, s8 *iovar_name, - void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync); - -/** Set named IOVARs, this function calls wl_dev_ioctl with - * WLC_SET_VAR IOCTL code - */ -s32 wldev_iovar_setbuf( - struct net_device *dev, s8 *iovar_name, - void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync); - -s32 wldev_iovar_setint( - struct net_device *dev, s8 *iovar, s32 val); - -s32 wldev_iovar_getint( - struct net_device *dev, s8 *iovar, s32 *pval); - -/** The following function can be implemented if there is a need for bsscfg - * indexed IOVARs - */ - -s32 wldev_mkiovar_bsscfg( - const s8 *iovar_name, s8 *param, s32 paramlen, - s8 *iovar_buf, s32 buflen, s32 bssidx); - -/** Retrieve named and bsscfg indexed IOVARs, this function calls wl_dev_ioctl with - * WLC_GET_VAR IOCTL code - */ -s32 wldev_iovar_getbuf_bsscfg( - struct net_device *dev, s8 *iovar_name, void *param, s32 paramlen, - void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync); - -/** Set named and bsscfg indexed IOVARs, this function calls wl_dev_ioctl with - * WLC_SET_VAR IOCTL code - */ -s32 wldev_iovar_setbuf_bsscfg( - struct net_device *dev, s8 *iovar_name, void *param, s32 paramlen, - void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync); - -s32 wldev_iovar_getint_bsscfg( - struct net_device *dev, s8 *iovar, s32 *pval, s32 bssidx); - -s32 wldev_iovar_setint_bsscfg( - struct net_device *dev, s8 *iovar, s32 val, s32 bssidx); - -extern void get_customized_country_code(char *country_iso_code, wl_country_t *cspec); -extern void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec); -extern void dhd_bus_band_set(struct net_device *dev, uint band); -extern int wldev_set_country(struct net_device *dev, char *country_code); -extern int net_os_wake_lock(struct net_device *dev); -extern int net_os_wake_unlock(struct net_device *dev); -extern int net_os_wake_lock_timeout(struct net_device *dev); -extern int net_os_wake_lock_timeout_enable(struct net_device *dev, int val); -extern int net_os_set_dtim_skip(struct net_device *dev, int val); -extern int net_os_set_suspend_disable(struct net_device *dev, int val); -extern int net_os_set_suspend(struct net_device *dev, int val, int force); -extern int wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, - int max, int *bytes_left); - -/* Get the link speed from dongle, speed is in kpbs */ -int wldev_get_link_speed(struct net_device *dev, int *plink_speed); - -int wldev_get_rssi(struct net_device *dev, int *prssi); - -int wldev_get_ssid(struct net_device *dev, wlc_ssid_t *pssid); - -int wldev_get_band(struct net_device *dev, uint *pband); - -int wldev_set_band(struct net_device *dev, uint band); - -int wldev_get_auto_channel(struct net_device *dev, int *chan); - -#endif /* __WLDEV_COMMON_H__ */ diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 89a116fba1de..d5084829c9e5 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c @@ -855,7 +855,6 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local, iface = netdev_priv(dev); ether_setup(dev); - dev->priv_flags &= ~IFF_TX_SKB_SHARING; /* kernel callbacks */ if (iface) { diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index b2707d733e92..87813c33bdc2 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -2182,7 +2182,6 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) { int rc = 0; unsigned long flags; - unsigned long now, end; spin_lock_irqsave(&priv->lock, flags); if (priv->status & STATUS_HCMD_ACTIVE) { @@ -2224,20 +2223,10 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) } spin_unlock_irqrestore(&priv->lock, flags); - now = jiffies; - end = now + HOST_COMPLETE_TIMEOUT; -again: rc = wait_event_interruptible_timeout(priv->wait_command_queue, !(priv-> status & STATUS_HCMD_ACTIVE), - end - now); - if (rc < 0) { - now = jiffies; - if (time_before(now, end)) - goto again; - rc = 0; - } - + HOST_COMPLETE_TIMEOUT); if (rc == 0) { spin_lock_irqsave(&priv->lock, flags); if (priv->status & STATUS_HCMD_ACTIVE) { diff --git a/drivers/net/wireless/iwlegacy/iwl-3945-rs.c b/drivers/net/wireless/iwlegacy/iwl-3945-rs.c index 164bcae821f8..977bd2477c6a 100644 --- a/drivers/net/wireless/iwlegacy/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlegacy/iwl-3945-rs.c @@ -822,15 +822,12 @@ static void iwl3945_rs_get_rate(void *priv_r, struct ieee80211_sta *sta, out: - if (sband->band == IEEE80211_BAND_5GHZ) { - if (WARN_ON_ONCE(index < IWL_FIRST_OFDM_RATE)) - index = IWL_FIRST_OFDM_RATE; - rs_sta->last_txrate_idx = index; - info->control.rates[0].idx = index - IWL_FIRST_OFDM_RATE; - } else { - rs_sta->last_txrate_idx = index; + rs_sta->last_txrate_idx = index; + if (sband->band == IEEE80211_BAND_5GHZ) + info->control.rates[0].idx = rs_sta->last_txrate_idx - + IWL_FIRST_OFDM_RATE; + else info->control.rates[0].idx = rs_sta->last_txrate_idx; - } IWL_DEBUG_RATE(priv, "leave: %d\n", index); } diff --git a/drivers/net/wireless/iwlegacy/iwl-3945.c b/drivers/net/wireless/iwlegacy/iwl-3945.c index effeabb031b5..d096dc28204d 100644 --- a/drivers/net/wireless/iwlegacy/iwl-3945.c +++ b/drivers/net/wireless/iwlegacy/iwl-3945.c @@ -1747,11 +1747,7 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); - /* - * We do not commit tx power settings while channel changing, - * do it now if tx power changed. - */ - iwl_legacy_set_tx_power(priv, priv->tx_power_next, false); + return 0; } @@ -1872,12 +1868,11 @@ static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, _3945.thermal_periodic.work); - mutex_lock(&priv->mutex); - if (test_bit(STATUS_EXIT_PENDING, &priv->status) || priv->txq == NULL) - goto out; + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + mutex_lock(&priv->mutex); iwl3945_reg_txpower_periodic(priv); -out: mutex_unlock(&priv->mutex); } diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c index 0a1babb23316..facc94e74b07 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965.c @@ -1237,12 +1237,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); iwl_legacy_print_rx_config_cmd(priv, ctx); - /* - * We do not commit tx power settings while channel changing, - * do it now if tx power changed. - */ - iwl_legacy_set_tx_power(priv, priv->tx_power_next, false); - return 0; + goto set_tx_power; } /* If we are currently associated and the new config requires @@ -1322,6 +1317,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c iwl4965_init_sensitivity(priv); +set_tx_power: /* If we issue a new RXON command which required a tune then we must * send a new TXPOWER command or we won't be able to Tx any frames */ ret = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true); diff --git a/drivers/net/wireless/iwlegacy/iwl-core.c b/drivers/net/wireless/iwlegacy/iwl-core.c index d273d507e0ce..3be76bd5499a 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.c +++ b/drivers/net/wireless/iwlegacy/iwl-core.c @@ -938,7 +938,7 @@ void iwl_legacy_irq_handle_error(struct iwl_priv *priv) &priv->contexts[IWL_RXON_CTX_BSS]); #endif - wake_up(&priv->wait_command_queue); + wake_up_interruptible(&priv->wait_command_queue); /* Keep the restart process from trying to send host * commands by clearing the INIT status bit */ @@ -1776,7 +1776,7 @@ int iwl_legacy_force_reset(struct iwl_priv *priv, int mode, bool external) IWL_ERR(priv, "On demand firmware reload\n"); /* Set the FW error flag -- cleared on iwl_down */ set_bit(STATUS_FW_ERROR, &priv->status); - wake_up(&priv->wait_command_queue); + wake_up_interruptible(&priv->wait_command_queue); /* * Keep the restart process from trying to send host * commands by clearing the INIT status bit diff --git a/drivers/net/wireless/iwlegacy/iwl-hcmd.c b/drivers/net/wireless/iwlegacy/iwl-hcmd.c index ce1fc9feb61f..62b4b09122cb 100644 --- a/drivers/net/wireless/iwlegacy/iwl-hcmd.c +++ b/drivers/net/wireless/iwlegacy/iwl-hcmd.c @@ -167,7 +167,7 @@ int iwl_legacy_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) goto out; } - ret = wait_event_timeout(priv->wait_command_queue, + ret = wait_event_interruptible_timeout(priv->wait_command_queue, !test_bit(STATUS_HCMD_ACTIVE, &priv->status), HOST_COMPLETE_TIMEOUT); if (!ret) { diff --git a/drivers/net/wireless/iwlegacy/iwl-tx.c b/drivers/net/wireless/iwlegacy/iwl-tx.c index ef9e268bf8a0..4fff995c6f3e 100644 --- a/drivers/net/wireless/iwlegacy/iwl-tx.c +++ b/drivers/net/wireless/iwlegacy/iwl-tx.c @@ -625,8 +625,6 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) cmd = txq->cmd[cmd_index]; meta = &txq->meta[cmd_index]; - txq->time_stamp = jiffies; - pci_unmap_single(priv->pci_dev, dma_unmap_addr(meta, mapping), dma_unmap_len(meta, len), @@ -647,7 +645,7 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) clear_bit(STATUS_HCMD_ACTIVE, &priv->status); IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s\n", iwl_legacy_get_cmd_string(cmd->hdr.cmd)); - wake_up(&priv->wait_command_queue); + wake_up_interruptible(&priv->wait_command_queue); } /* Mark as unmapped */ diff --git a/drivers/net/wireless/iwlegacy/iwl3945-base.c b/drivers/net/wireless/iwlegacy/iwl3945-base.c index 101a2c2fe177..0ee6be6a9c5d 100644 --- a/drivers/net/wireless/iwlegacy/iwl3945-base.c +++ b/drivers/net/wireless/iwlegacy/iwl3945-base.c @@ -841,7 +841,7 @@ static void iwl3945_rx_card_state_notif(struct iwl_priv *priv, wiphy_rfkill_set_hw_state(priv->hw->wiphy, test_bit(STATUS_RF_KILL_HW, &priv->status)); else - wake_up(&priv->wait_command_queue); + wake_up_interruptible(&priv->wait_command_queue); } /** @@ -2518,7 +2518,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) iwl3945_reg_txpower_periodic(priv); IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); - wake_up(&priv->wait_command_queue); + wake_up_interruptible(&priv->wait_command_queue); return; @@ -2549,7 +2549,7 @@ static void __iwl3945_down(struct iwl_priv *priv) iwl_legacy_clear_driver_stations(priv); /* Unblock any waiting calls */ - wake_up_all(&priv->wait_command_queue); + wake_up_interruptible_all(&priv->wait_command_queue); /* Wipe out the EXIT_PENDING status bit if we are not actually * exiting the module */ @@ -2763,7 +2763,7 @@ static void iwl3945_bg_alive_start(struct work_struct *data) container_of(data, struct iwl_priv, alive_start.work); mutex_lock(&priv->mutex); - if (test_bit(STATUS_EXIT_PENDING, &priv->status) || priv->txq == NULL) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) goto out; iwl3945_alive_start(priv); @@ -2910,13 +2910,14 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) IWL_WARN(priv, "Invalid scan band\n"); return -EIO; } + /* - * If active scaning is requested but a certain channel is marked - * passive, we can do active scanning if we detect transmissions. For - * passive only scanning disable switching to active on any channel. + * If active scaning is requested but a certain channel + * is marked passive, we can do active scanning if we + * detect transmissions. */ scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : - IWL_GOOD_CRC_TH_NEVER; + IWL_GOOD_CRC_TH_DISABLED; if (!priv->is_internal_short_scan) { scan->tx_cmd.len = cpu_to_le16( @@ -3124,7 +3125,7 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw) /* Wait for START_ALIVE from ucode. Otherwise callbacks from * mac80211 will not be run successfully. */ - ret = wait_event_timeout(priv->wait_command_queue, + ret = wait_event_interruptible_timeout(priv->wait_command_queue, test_bit(STATUS_READY, &priv->status), UCODE_READY_TIMEOUT); if (!ret) { diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c index 0c37c025400b..7157ba529680 100644 --- a/drivers/net/wireless/iwlegacy/iwl4965-base.c +++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c @@ -704,7 +704,7 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv, wiphy_rfkill_set_hw_state(priv->hw->wiphy, test_bit(STATUS_RF_KILL_HW, &priv->status)); else - wake_up(&priv->wait_command_queue); + wake_up_interruptible(&priv->wait_command_queue); } /** @@ -1054,7 +1054,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) handled |= CSR_INT_BIT_FH_TX; /* Wake up uCode load routine, now that load is complete */ priv->ucode_write_complete = 1; - wake_up(&priv->wait_command_queue); + wake_up_interruptible(&priv->wait_command_queue); } if (inta & ~handled) { @@ -2126,7 +2126,7 @@ static void iwl4965_alive_start(struct iwl_priv *priv) iwl4965_rf_kill_ct_config(priv); IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); - wake_up(&priv->wait_command_queue); + wake_up_interruptible(&priv->wait_command_queue); iwl_legacy_power_update_mode(priv, true); IWL_DEBUG_INFO(priv, "Updated power mode\n"); @@ -2159,7 +2159,7 @@ static void __iwl4965_down(struct iwl_priv *priv) iwl_legacy_clear_driver_stations(priv); /* Unblock any waiting calls */ - wake_up_all(&priv->wait_command_queue); + wake_up_interruptible_all(&priv->wait_command_queue); /* Wipe out the EXIT_PENDING status bit if we are not actually * exiting the module */ @@ -2597,7 +2597,7 @@ int iwl4965_mac_start(struct ieee80211_hw *hw) /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from * mac80211 will not be run successfully. */ - ret = wait_event_timeout(priv->wait_command_queue, + ret = wait_event_interruptible_timeout(priv->wait_command_queue, test_bit(STATUS_READY, &priv->status), UCODE_READY_TIMEOUT); if (!ret) { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index f1c3f49c0feb..e816c27db794 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -421,7 +421,6 @@ static struct iwl_base_params iwl5000_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, - .no_idle_support = true, }; static struct iwl_ht_params iwl5000_ht_params = { .ht_greenfield_support = true, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 857cf613092f..f803fb62f8bc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -2023,7 +2023,6 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) case IEEE80211_SMPS_STATIC: case IEEE80211_SMPS_DYNAMIC: return IWL_NUM_IDLE_CHAINS_SINGLE; - case IEEE80211_SMPS_AUTOMATIC: case IEEE80211_SMPS_OFF: return active_cnt; default: diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 2aed7a05e2cd..592b0cfcf717 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -878,7 +878,6 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, if ((priv->bt_traffic_load != priv->last_bt_traffic_load) || (priv->bt_full_concurrent != full_concurrent)) { priv->bt_full_concurrent = full_concurrent; - priv->last_bt_traffic_load = priv->bt_traffic_load; /* Update uCode's rate table. */ tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 272bcdfe53a4..09f679d6046f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -411,24 +411,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) return 0; } -void iwlagn_config_ht40(struct ieee80211_conf *conf, - struct iwl_rxon_context *ctx) -{ - if (conf_is_ht40_minus(conf)) { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_BELOW; - ctx->ht.is_40mhz = true; - } else if (conf_is_ht40_plus(conf)) { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - ctx->ht.is_40mhz = true; - } else { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_NONE; - ctx->ht.is_40mhz = false; - } -} - int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) { struct iwl_priv *priv = hw->priv; @@ -442,9 +424,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) mutex_lock(&priv->mutex); - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - goto out; - if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) { IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); goto out; @@ -491,11 +470,19 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) ctx->ht.enabled = conf_is_ht(conf); if (ctx->ht.enabled) { - /* if HT40 is used, it should not change - * after associated except channel switch */ - if (!ctx->ht.is_40mhz || - !iwl_is_associated_ctx(ctx)) - iwlagn_config_ht40(conf, ctx); + if (conf_is_ht40_minus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_BELOW; + ctx->ht.is_40mhz = true; + } else if (conf_is_ht40_plus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + ctx->ht.is_40mhz = true; + } else { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_NONE; + ctx->ht.is_40mhz = false; + } } else ctx->ht.is_40mhz = false; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 5c9999db33ba..0bd722cee5ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -477,7 +477,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, sizeof(struct iwl_keyinfo)); priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID; - priv->stations[sta_id].sta.key.key_offset = keyconf->hw_key_idx; + priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET; priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 67cd2e3b6b6c..4974cd7837cb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -385,10 +385,7 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, tx_cmd->tid_tspec = qc[0] & 0xf; tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; } else { - if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) - tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; - else - tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; + tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; } priv->cfg->ops->utils->tx_cmd_protection(priv, info, fc, &tx_flags); @@ -778,7 +775,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd)); iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); - iwlagn_txq_update_byte_cnt_tbl(priv, txq, le16_to_cpu(tx_cmd->len)); + /* Set up entry for this TFD in Tx byte-count array */ + if (info->flags & IEEE80211_TX_CTL_AMPDU) + iwlagn_txq_update_byte_cnt_tbl(priv, txq, + le16_to_cpu(tx_cmd->len)); pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys, firstlen, PCI_DMA_BIDIRECTIONAL); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index a03dbcc46d0f..97de5d9de67b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -144,8 +144,13 @@ static int iwlagn_load_section(struct iwl_priv *priv, const char *name, FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); IWL_DEBUG_INFO(priv, "%s uCode section being loaded...\n", name); - ret = wait_event_timeout(priv->wait_command_queue, - priv->ucode_write_complete, 5 * HZ); + ret = wait_event_interruptible_timeout(priv->wait_command_queue, + priv->ucode_write_complete, 5 * HZ); + if (ret == -ERESTARTSYS) { + IWL_ERR(priv, "Could not load the %s uCode section due " + "to interrupt\n", name); + return ret; + } if (!ret) { IWL_ERR(priv, "Could not load the %s uCode section\n", name); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 67d4c2d948dc..8e1942ebd9a0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -797,7 +797,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) handled |= CSR_INT_BIT_FH_TX; /* Wake up uCode load routine, now that load is complete */ priv->ucode_write_complete = 1; - wake_up(&priv->wait_command_queue); + wake_up_interruptible(&priv->wait_command_queue); } if (inta & ~handled) { @@ -2440,12 +2440,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, IEEE80211_HW_SPECTRUM_MGMT | IEEE80211_HW_REPORTS_TX_ACK_STATUS; - /* - * Including the following line will crash some AP's. This - * workaround removes the stimulus which causes the crash until - * the AP software can be fixed. hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF; - */ hw->flags |= IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; @@ -2872,9 +2867,21 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, /* Configure HT40 channels */ ctx->ht.enabled = conf_is_ht(conf); - if (ctx->ht.enabled) - iwlagn_config_ht40(conf, ctx); - else + if (ctx->ht.enabled) { + if (conf_is_ht40_minus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_BELOW; + ctx->ht.is_40mhz = true; + } else if (conf_is_ht40_plus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + ctx->ht.is_40mhz = true; + } else { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_NONE; + ctx->ht.is_40mhz = false; + } + } else ctx->ht.is_40mhz = false; if ((le16_to_cpu(ctx->staging.channel) != ch)) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 5a0acab0bbc3..d1716844002e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -152,8 +152,6 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changes); -void iwlagn_config_ht40(struct ieee80211_conf *conf, - struct iwl_rxon_context *ctx); /* uCode */ void iwlagn_rx_calib_result(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 563840783361..45cc51c9c93e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -899,7 +899,7 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) * commands by clearing the ready bit */ clear_bit(STATUS_READY, &priv->status); - wake_up(&priv->wait_command_queue); + wake_up_interruptible(&priv->wait_command_queue); if (!ondemand) { /* @@ -950,7 +950,7 @@ void iwl_irq_handle_error(struct iwl_priv *priv) */ clear_bit(STATUS_READY, &priv->status); clear_bit(STATUS_HCMD_ACTIVE, &priv->status); - wake_up(&priv->wait_command_queue); + wake_up_interruptible(&priv->wait_command_queue); IWL_ERR(priv, "RF is used by WiMAX\n"); return; } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index b76996ae15fe..a54d416ec345 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -195,7 +195,6 @@ struct iwl_mod_params { * @temperature_kelvin: temperature report by uCode in kelvin * @max_event_log_size: size of event log buffer size for ucode event logging * @shadow_reg_enable: HW shadhow register bit - * @no_idle_support: do not support idle mode */ struct iwl_base_params { int eeprom_size; @@ -217,7 +216,6 @@ struct iwl_base_params { bool temperature_kelvin; u32 max_event_log_size; const bool shadow_reg_enable; - const bool no_idle_support; }; /* * @advanced_bt_coexist: support advanced bt coexist diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index fc1127763ba6..76f996623140 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -194,7 +194,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) return ret; } - ret = wait_event_timeout(priv->wait_command_queue, + ret = wait_event_interruptible_timeout(priv->wait_command_queue, !test_bit(STATUS_HCMD_ACTIVE, &priv->status), HOST_COMPLETE_TIMEOUT); if (!ret) { diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 4a05a6ace3ca..595c930b28ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -355,8 +355,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, dtimper = priv->hw->conf.ps_dtim_period ?: 1; - if (!priv->cfg->base_params->no_idle_support && - priv->hw->conf.flags & IEEE80211_CONF_IDLE) + if (priv->hw->conf.flags & IEEE80211_CONF_IDLE) iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); else if (iwl_tt_is_low_power_state(priv)) { /* in thermal throttling low power state */ diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 865ac1a61bb7..b774517aa9fa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -738,7 +738,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, wiphy_rfkill_set_hw_state(priv->hw->wiphy, test_bit(STATUS_RF_KILL_HW, &priv->status)); else - wake_up(&priv->wait_command_queue); + wake_up_interruptible(&priv->wait_command_queue); } static void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index f5240162ef7c..d60d630cb93a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -406,33 +406,31 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); + if (test_bit(STATUS_SCANNING, &priv->status) && + priv->scan_type != IWL_SCAN_NORMAL) { + IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); + ret = -EAGAIN; + goto out_unlock; + } + + /* mac80211 will only ask for one band at a time */ + priv->scan_request = req; + priv->scan_vif = vif; + /* * If an internal scan is in progress, just set * up the scan_request as per above. */ if (priv->scan_type != IWL_SCAN_NORMAL) { - IWL_DEBUG_SCAN(priv, - "SCAN request during internal scan - defer\n"); - priv->scan_request = req; - priv->scan_vif = vif; + IWL_DEBUG_SCAN(priv, "SCAN request during internal scan\n"); ret = 0; - } else { - priv->scan_request = req; - priv->scan_vif = vif; - /* - * mac80211 will only ask for one band at a time - * so using channels[0] here is ok - */ + } else ret = iwl_scan_initiate(priv, vif, IWL_SCAN_NORMAL, req->channels[0]->band); - if (ret) { - priv->scan_request = NULL; - priv->scan_vif = NULL; - } - } IWL_DEBUG_MAC80211(priv, "leave\n"); +out_unlock: mutex_unlock(&priv->mutex); return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 93152c38b679..137dba95b1ad 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -802,8 +802,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) cmd = txq->cmd[cmd_index]; meta = &txq->meta[cmd_index]; - txq->time_stamp = jiffies; - iwlagn_unmap_tfd(priv, meta, &txq->tfds[index], PCI_DMA_BIDIRECTIONAL); /* Input error checking is done when commands are added to queue. */ @@ -821,7 +819,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) clear_bit(STATUS_HCMD_ACTIVE, &priv->status); IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s\n", get_cmd_string(cmd->hdr.cmd)); - wake_up(&priv->wait_command_queue); + wake_up_interruptible(&priv->wait_command_queue); } /* Mark as unmapped */ diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index db39742db3aa..463352c890d7 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c @@ -997,7 +997,6 @@ static int if_spi_host_to_card(struct lbs_private *priv, spin_unlock_irqrestore(&card->buffer_lock, flags); break; default: - kfree(packet); netdev_err(priv->dev, "can't transfer buffer of type %d\n", type); err = -EINVAL; diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index d2358cfcbe93..e5dfdc39a921 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -267,8 +267,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, else last_seq = priv->rx_seq[tid]; - if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM && - last_seq >= new_node->start_win) + if (last_seq >= new_node->start_win) new_node->start_win = last_seq + 1; new_node->win_size = win_size; @@ -613,5 +612,5 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv) spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); - mwifiex_reset_11n_rx_seq_num(priv); + memset(priv->rx_seq, 0, sizeof(priv->rx_seq)); } diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h index 7576c2ab93b5..f3ca8c8c18f9 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h @@ -37,13 +37,6 @@ #define ADDBA_RSP_STATUS_ACCEPT 0 -#define MWIFIEX_DEF_11N_RX_SEQ_NUM 0xffff - -static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv) -{ - memset(priv->rx_seq, 0xff, sizeof(priv->rx_seq)); -} - int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *, u16 seqNum, u16 tid, u8 *ta, diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index 3b1217f094ee..d425dbd91d19 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -122,6 +122,7 @@ static int mwifiex_sdio_suspend(struct device *dev) struct sdio_mmc_card *card; struct mwifiex_adapter *adapter; mmc_pm_flag_t pm_flag = 0; + int hs_actived = 0; int i; int ret = 0; @@ -148,14 +149,12 @@ static int mwifiex_sdio_suspend(struct device *dev) adapter = card->adapter; /* Enable the Host Sleep */ - if (!mwifiex_enable_hs(adapter)) { - dev_err(adapter->dev, "cmd: failed to suspend\n"); - return -EFAULT; + hs_actived = mwifiex_enable_hs(adapter); + if (hs_actived) { + pr_debug("cmd: suspend with MMC_PM_KEEP_POWER\n"); + ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); } - dev_dbg(adapter->dev, "cmd: suspend with MMC_PM_KEEP_POWER\n"); - ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); - /* Indicate device suspended */ adapter->is_suspended = true; diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 2cdb41ac7439..91634daec306 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -406,8 +406,6 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; - mwifiex_reset_11n_rx_seq_num(priv); - atomic_set(&priv->wmm.tx_pkts_queued, 0); atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); } diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index d895ff972d66..6d9204fef90b 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c @@ -589,6 +589,8 @@ static void p54spi_op_stop(struct ieee80211_hw *dev) WARN_ON(priv->fw_state != FW_STATE_READY); + cancel_work_sync(&priv->work); + p54spi_power_off(priv); spin_lock_irqsave(&priv->tx_lock, flags); INIT_LIST_HEAD(&priv->tx_pending); @@ -596,8 +598,6 @@ static void p54spi_op_stop(struct ieee80211_hw *dev) priv->fw_state = FW_STATE_OFF; mutex_unlock(&priv->mutex); - - cancel_work_sync(&priv->work); } static int __devinit p54spi_probe(struct spi_device *spi) @@ -623,19 +623,19 @@ static int __devinit p54spi_probe(struct spi_device *spi) ret = spi_setup(spi); if (ret < 0) { dev_err(&priv->spi->dev, "spi_setup failed"); - goto err_free; + goto err_free_common; } ret = gpio_request(p54spi_gpio_power, "p54spi power"); if (ret < 0) { dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret); - goto err_free; + goto err_free_common; } ret = gpio_request(p54spi_gpio_irq, "p54spi irq"); if (ret < 0) { dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret); - goto err_free_gpio_power; + goto err_free_common; } gpio_direction_output(p54spi_gpio_power, 0); @@ -646,7 +646,7 @@ static int __devinit p54spi_probe(struct spi_device *spi) priv->spi); if (ret < 0) { dev_err(&priv->spi->dev, "request_irq() failed"); - goto err_free_gpio_irq; + goto err_free_common; } irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING); @@ -657,7 +657,6 @@ static int __devinit p54spi_probe(struct spi_device *spi) init_completion(&priv->fw_comp); INIT_LIST_HEAD(&priv->tx_pending); mutex_init(&priv->mutex); - spin_lock_init(&priv->tx_lock); SET_IEEE80211_DEV(hw, &spi->dev); priv->common.open = p54spi_op_start; priv->common.stop = p54spi_op_stop; @@ -678,12 +677,6 @@ static int __devinit p54spi_probe(struct spi_device *spi) return 0; err_free_common: - free_irq(gpio_to_irq(p54spi_gpio_irq), spi); -err_free_gpio_irq: - gpio_free(p54spi_gpio_irq); -err_free_gpio_power: - gpio_free(p54spi_gpio_power); -err_free: p54_free_common(priv->hw); return ret; } diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index f1fa7636baaf..a8f3bc740dfa 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -41,12 +41,11 @@ MODULE_FIRMWARE("isl3887usb"); * whenever you add a new device. */ -static struct usb_device_id p54u_table[] = { +static struct usb_device_id p54u_table[] __devinitdata = { /* Version 1 devices (pci chip + net2280) */ {USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */ {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */ {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */ - {USB_DEVICE(0x0675, 0x0530)}, /* DrayTek Vigor 530 */ {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */ {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */ {USB_DEVICE(0x07aa, 0x001c)}, /* Corega CG-WLUSB2GT */ @@ -82,8 +81,6 @@ static struct usb_device_id p54u_table[] = { {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */ {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ - {USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */ - {USB_DEVICE(0x083a, 0x4503)}, /* T-Com Sinus 154 data II */ {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ {USB_DEVICE(0x083a, 0xc501)}, /* Zoom Wireless-G 4410 */ {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */ @@ -103,7 +100,6 @@ static struct usb_device_id p54u_table[] = { {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */ {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ - /* {USB_DEVICE(0x15a9, 0x0002)}, * Also SparkLAN WL-682 with 3887 */ {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */ {USB_DEVICE(0x1740, 0x1000)}, /* Senao NUB-350 */ {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 1493171f55cb..937f9e8bf05f 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1618,7 +1618,6 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) { int retval; - u32 reg; /* * Allocate eeprom data. @@ -1631,14 +1630,6 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) if (retval) return retval; - /* - * Enable rfkill polling by setting GPIO direction of the - * rfkill switch GPIO pin correctly. - */ - rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); - rt2x00_set_field32(®, GPIOCSR_BIT8, 1); - rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg); - /* * Initialize hw specifications. */ diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h index 7564ae992b73..d3a4a68cc439 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.h +++ b/drivers/net/wireless/rt2x00/rt2400pci.h @@ -670,7 +670,6 @@ #define GPIOCSR_BIT5 FIELD32(0x00000020) #define GPIOCSR_BIT6 FIELD32(0x00000040) #define GPIOCSR_BIT7 FIELD32(0x00000080) -#define GPIOCSR_BIT8 FIELD32(0x00000100) /* * BBPPCSR: BBP Pin control register. diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index cdd480f92021..d27d7b8ba3b6 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1936,7 +1936,6 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) { int retval; - u32 reg; /* * Allocate eeprom data. @@ -1949,14 +1948,6 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) if (retval) return retval; - /* - * Enable rfkill polling by setting GPIO direction of the - * rfkill switch GPIO pin correctly. - */ - rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); - rt2x00_set_field32(®, GPIOCSR_DIR0, 1); - rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg); - /* * Initialize hw specifications. */ diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index f124a1b736d3..15237c275486 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -283,7 +283,7 @@ static int rt2500usb_rfkill_poll(struct rt2x00_dev *rt2x00dev) u16 reg; rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); - return rt2x00_get_field16(reg, MAC_CSR19_BIT7); + return rt2x00_get_field32(reg, MAC_CSR19_BIT7); } #ifdef CONFIG_RT2X00_LIB_LEDS @@ -1768,7 +1768,6 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) { int retval; - u16 reg; /* * Allocate eeprom data. @@ -1781,14 +1780,6 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) if (retval) return retval; - /* - * Enable rfkill polling by setting GPIO direction of the - * rfkill switch GPIO pin correctly. - */ - rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); - rt2x00_set_field16(®, MAC_CSR19_BIT8, 0); - rt2500usb_register_write(rt2x00dev, MAC_CSR19, reg); - /* * Initialize hw specifications. */ diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h index 196bd5103e4f..b493306a7eed 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.h +++ b/drivers/net/wireless/rt2x00/rt2500usb.h @@ -189,15 +189,14 @@ * MAC_CSR19: GPIO control register. */ #define MAC_CSR19 0x0426 -#define MAC_CSR19_BIT0 FIELD16(0x0001) -#define MAC_CSR19_BIT1 FIELD16(0x0002) -#define MAC_CSR19_BIT2 FIELD16(0x0004) -#define MAC_CSR19_BIT3 FIELD16(0x0008) -#define MAC_CSR19_BIT4 FIELD16(0x0010) -#define MAC_CSR19_BIT5 FIELD16(0x0020) -#define MAC_CSR19_BIT6 FIELD16(0x0040) -#define MAC_CSR19_BIT7 FIELD16(0x0080) -#define MAC_CSR19_BIT8 FIELD16(0x0100) +#define MAC_CSR19_BIT0 FIELD32(0x0001) +#define MAC_CSR19_BIT1 FIELD32(0x0002) +#define MAC_CSR19_BIT2 FIELD32(0x0004) +#define MAC_CSR19_BIT3 FIELD32(0x0008) +#define MAC_CSR19_BIT4 FIELD32(0x0010) +#define MAC_CSR19_BIT5 FIELD32(0x0020) +#define MAC_CSR19_BIT6 FIELD32(0x0040) +#define MAC_CSR19_BIT7 FIELD32(0x0080) /* * MAC_CSR20: LED control register. diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index d44ce307e93d..2a6aa85cc6c9 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -38,7 +38,6 @@ #include #include #include -#include #include "rt2x00.h" #include "rt2800lib.h" @@ -608,15 +607,6 @@ static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg) int wcid, ack, pid; int tx_wcid, tx_ack, tx_pid; - if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || - !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) { - WARNING(entry->queue->rt2x00dev, - "Data pending for entry %u in queue %u\n", - entry->entry_idx, entry->queue->qid); - cond_resched(); - return false; - } - wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); @@ -764,11 +754,12 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); if (rt2800_txdone_entry_check(entry, reg)) break; - entry = NULL; } - if (entry) - rt2800_txdone_entry(entry, reg); + if (!entry || rt2x00queue_empty(queue)) + break; + + rt2800_txdone_entry(entry, reg); } } EXPORT_SYMBOL_GPL(rt2800_txdone); @@ -793,7 +784,8 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) /* * Add space for the TXWI in front of the skb. */ - memset(skb_push(entry->skb, TXWI_DESC_SIZE), 0, TXWI_DESC_SIZE); + skb_push(entry->skb, TXWI_DESC_SIZE); + memset(entry->skb, 0, TXWI_DESC_SIZE); /* * Register descriptor details in skb frame descriptor. @@ -1935,7 +1927,7 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev) /* * Check if temperature compensation is supported. */ - if (tssi_bounds[4] == 0xff || step == 0xff) + if (tssi_bounds[4] == 0xff) return 0; /* @@ -3512,15 +3504,14 @@ static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i) rt2800_regbusy_read(rt2x00dev, EFUSE_CTRL, EFUSE_CTRL_KICK, ®); /* Apparently the data is read from end to start */ - rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, ®); - /* The returned value is in CPU order, but eeprom is le */ - *(u32 *)&rt2x00dev->eeprom[i] = cpu_to_le32(reg); - rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, ®); - *(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg); - rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, ®); - *(u32 *)&rt2x00dev->eeprom[i + 4] = cpu_to_le32(reg); - rt2800_register_read_lock(rt2x00dev, EFUSE_DATA0, ®); - *(u32 *)&rt2x00dev->eeprom[i + 6] = cpu_to_le32(reg); + rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, + (u32 *)&rt2x00dev->eeprom[i]); + rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, + (u32 *)&rt2x00dev->eeprom[i + 2]); + rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, + (u32 *)&rt2x00dev->eeprom[i + 4]); + rt2800_register_read_lock(rt2x00dev, EFUSE_DATA0, + (u32 *)&rt2x00dev->eeprom[i + 6]); mutex_unlock(&rt2x00dev->csr_mutex); } @@ -3686,23 +3677,19 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) return -ENODEV; } - switch (rt2x00dev->chip.rf) { - case RF2820: - case RF2850: - case RF2720: - case RF2750: - case RF3020: - case RF2020: - case RF3021: - case RF3022: - case RF3052: - case RF3320: - case RF5370: - case RF5390: - break; - default: - ERROR(rt2x00dev, "Invalid RF chipset 0x%x detected.\n", - rt2x00dev->chip.rf); + if (!rt2x00_rf(rt2x00dev, RF2820) && + !rt2x00_rf(rt2x00dev, RF2850) && + !rt2x00_rf(rt2x00dev, RF2720) && + !rt2x00_rf(rt2x00dev, RF2750) && + !rt2x00_rf(rt2x00dev, RF3020) && + !rt2x00_rf(rt2x00dev, RF2020) && + !rt2x00_rf(rt2x00dev, RF3021) && + !rt2x00_rf(rt2x00dev, RF3022) && + !rt2x00_rf(rt2x00dev, RF3052) && + !rt2x00_rf(rt2x00dev, RF3320) && + !rt2x00_rf(rt2x00dev, RF5370) && + !rt2x00_rf(rt2x00dev, RF5390)) { + ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); return -ENODEV; } diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index e947d3abbe98..cc4a54f571b8 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -426,6 +426,7 @@ static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev) static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, enum dev_state state) { + int mask = (state == STATE_RADIO_IRQ_ON); u32 reg; unsigned long flags; @@ -447,14 +448,25 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, } spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); - reg = 0; - if (state == STATE_RADIO_IRQ_ON) { - rt2x00_set_field32(®, INT_MASK_CSR_RX_DONE, 1); - rt2x00_set_field32(®, INT_MASK_CSR_TBTT, 1); - rt2x00_set_field32(®, INT_MASK_CSR_PRE_TBTT, 1); - rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, 1); - rt2x00_set_field32(®, INT_MASK_CSR_AUTO_WAKEUP, 1); - } + rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); + rt2x00_set_field32(®, INT_MASK_CSR_RXDELAYINT, 0); + rt2x00_set_field32(®, INT_MASK_CSR_TXDELAYINT, 0); + rt2x00_set_field32(®, INT_MASK_CSR_RX_DONE, mask); + rt2x00_set_field32(®, INT_MASK_CSR_AC0_DMA_DONE, 0); + rt2x00_set_field32(®, INT_MASK_CSR_AC1_DMA_DONE, 0); + rt2x00_set_field32(®, INT_MASK_CSR_AC2_DMA_DONE, 0); + rt2x00_set_field32(®, INT_MASK_CSR_AC3_DMA_DONE, 0); + rt2x00_set_field32(®, INT_MASK_CSR_HCCA_DMA_DONE, 0); + rt2x00_set_field32(®, INT_MASK_CSR_MGMT_DMA_DONE, 0); + rt2x00_set_field32(®, INT_MASK_CSR_MCU_COMMAND, 0); + rt2x00_set_field32(®, INT_MASK_CSR_RXTX_COHERENT, 0); + rt2x00_set_field32(®, INT_MASK_CSR_TBTT, mask); + rt2x00_set_field32(®, INT_MASK_CSR_PRE_TBTT, mask); + rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, mask); + rt2x00_set_field32(®, INT_MASK_CSR_AUTO_WAKEUP, mask); + rt2x00_set_field32(®, INT_MASK_CSR_GPTIMER, 0); + rt2x00_set_field32(®, INT_MASK_CSR_RX_COHERENT, 0); + rt2x00_set_field32(®, INT_MASK_CSR_TX_COHERENT, 0); rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); @@ -941,7 +953,6 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) { int retval; - u32 reg; /* * Allocate eeprom data. @@ -954,14 +965,6 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) if (retval) return retval; - /* - * Enable rfkill polling by setting GPIO direction of the - * rfkill switch GPIO pin correctly. - */ - rt2x00pci_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); - rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT2, 1); - rt2x00pci_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); - /* * Initialize hw specifications. */ @@ -1155,7 +1158,6 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { #endif #ifdef CONFIG_RT2800PCI_RT53XX { PCI_DEVICE(0x1814, 0x5390) }, - { PCI_DEVICE(0x1814, 0x539f) }, #endif { 0, } }; diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 9366ef03e67b..ba82c972703a 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -477,10 +477,8 @@ static void rt2800usb_work_txdone(struct work_struct *work) while (!rt2x00queue_empty(queue)) { entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || - !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) break; - if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); else if (rt2x00queue_status_timeout(entry)) @@ -600,7 +598,6 @@ static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) { int retval; - u32 reg; /* * Allocate eeprom data. @@ -613,14 +610,6 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) if (retval) return retval; - /* - * Enable rfkill polling by setting GPIO direction of the - * rfkill switch GPIO pin correctly. - */ - rt2x00usb_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); - rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT2, 1); - rt2x00usb_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); - /* * Initialize hw specifications. */ @@ -828,17 +817,13 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x050d, 0x8053) }, { USB_DEVICE(0x050d, 0x805c) }, { USB_DEVICE(0x050d, 0x815c) }, - { USB_DEVICE(0x050d, 0x825a) }, { USB_DEVICE(0x050d, 0x825b) }, { USB_DEVICE(0x050d, 0x935a) }, { USB_DEVICE(0x050d, 0x935b) }, /* Buffalo */ { USB_DEVICE(0x0411, 0x00e8) }, - { USB_DEVICE(0x0411, 0x0158) }, - { USB_DEVICE(0x0411, 0x015d) }, { USB_DEVICE(0x0411, 0x016f) }, { USB_DEVICE(0x0411, 0x01a2) }, - { USB_DEVICE(0x0411, 0x01ee) }, /* Corega */ { USB_DEVICE(0x07aa, 0x002f) }, { USB_DEVICE(0x07aa, 0x003c) }, @@ -851,17 +836,13 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x07d1, 0x3c0e) }, { USB_DEVICE(0x07d1, 0x3c0f) }, { USB_DEVICE(0x07d1, 0x3c11) }, - { USB_DEVICE(0x07d1, 0x3c13) }, - { USB_DEVICE(0x07d1, 0x3c15) }, { USB_DEVICE(0x07d1, 0x3c16) }, - { USB_DEVICE(0x2001, 0x3c1b) }, /* Draytek */ { USB_DEVICE(0x07fa, 0x7712) }, /* Edimax */ { USB_DEVICE(0x7392, 0x7711) }, { USB_DEVICE(0x7392, 0x7717) }, { USB_DEVICE(0x7392, 0x7718) }, - { USB_DEVICE(0x7392, 0x7722) }, /* Encore */ { USB_DEVICE(0x203d, 0x1480) }, { USB_DEVICE(0x203d, 0x14a9) }, @@ -895,8 +876,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x13b1, 0x0031) }, { USB_DEVICE(0x1737, 0x0070) }, { USB_DEVICE(0x1737, 0x0071) }, - { USB_DEVICE(0x1737, 0x0077) }, - { USB_DEVICE(0x1737, 0x0078) }, /* Logitec */ { USB_DEVICE(0x0789, 0x0162) }, { USB_DEVICE(0x0789, 0x0163) }, @@ -920,13 +899,9 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0db0, 0x871b) }, { USB_DEVICE(0x0db0, 0x871c) }, { USB_DEVICE(0x0db0, 0x899a) }, - /* Ovislink */ - { USB_DEVICE(0x1b75, 0x3071) }, - { USB_DEVICE(0x1b75, 0x3072) }, /* Para */ { USB_DEVICE(0x20b8, 0x8888) }, /* Pegatron */ - { USB_DEVICE(0x1d4d, 0x0002) }, { USB_DEVICE(0x1d4d, 0x000c) }, { USB_DEVICE(0x1d4d, 0x000e) }, { USB_DEVICE(0x1d4d, 0x0011) }, @@ -964,7 +939,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0df6, 0x0048) }, { USB_DEVICE(0x0df6, 0x0051) }, { USB_DEVICE(0x0df6, 0x005f) }, - { USB_DEVICE(0x0df6, 0x0060) }, /* SMC */ { USB_DEVICE(0x083a, 0x6618) }, { USB_DEVICE(0x083a, 0x7511) }, @@ -979,9 +953,7 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Sparklan */ { USB_DEVICE(0x15a9, 0x0006) }, /* Sweex */ - { USB_DEVICE(0x177f, 0x0153) }, { USB_DEVICE(0x177f, 0x0302) }, - { USB_DEVICE(0x177f, 0x0313) }, /* U-Media */ { USB_DEVICE(0x157e, 0x300e) }, { USB_DEVICE(0x157e, 0x3013) }, @@ -999,8 +971,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0586, 0x341e) }, { USB_DEVICE(0x0586, 0x343e) }, #ifdef CONFIG_RT2800USB_RT33XX - /* Belkin */ - { USB_DEVICE(0x050d, 0x945b) }, /* Ralink */ { USB_DEVICE(0x148f, 0x3370) }, { USB_DEVICE(0x148f, 0x8070) }, @@ -1025,7 +995,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x148f, 0x3572) }, /* Sitecom */ { USB_DEVICE(0x0df6, 0x0041) }, - { USB_DEVICE(0x0df6, 0x0062) }, /* Toshiba */ { USB_DEVICE(0x0930, 0x0a07) }, /* Zinwell */ @@ -1065,24 +1034,27 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x13d3, 0x3322) }, /* Belkin */ { USB_DEVICE(0x050d, 0x1003) }, + { USB_DEVICE(0x050d, 0x825a) }, /* Buffalo */ { USB_DEVICE(0x0411, 0x012e) }, { USB_DEVICE(0x0411, 0x0148) }, { USB_DEVICE(0x0411, 0x0150) }, + { USB_DEVICE(0x0411, 0x015d) }, /* Corega */ { USB_DEVICE(0x07aa, 0x0041) }, { USB_DEVICE(0x07aa, 0x0042) }, { USB_DEVICE(0x18c5, 0x0008) }, /* D-Link */ { USB_DEVICE(0x07d1, 0x3c0b) }, + { USB_DEVICE(0x07d1, 0x3c13) }, + { USB_DEVICE(0x07d1, 0x3c15) }, { USB_DEVICE(0x07d1, 0x3c17) }, { USB_DEVICE(0x2001, 0x3c17) }, /* Edimax */ { USB_DEVICE(0x7392, 0x4085) }, + { USB_DEVICE(0x7392, 0x7722) }, /* Encore */ { USB_DEVICE(0x203d, 0x14a1) }, - /* Fujitsu Stylistic 550 */ - { USB_DEVICE(0x1690, 0x0761) }, /* Gemtek */ { USB_DEVICE(0x15a9, 0x0010) }, /* Gigabyte */ @@ -1094,13 +1066,20 @@ static struct usb_device_id rt2800usb_device_table[] = { /* LevelOne */ { USB_DEVICE(0x1740, 0x0605) }, { USB_DEVICE(0x1740, 0x0615) }, + /* Linksys */ + { USB_DEVICE(0x1737, 0x0077) }, + { USB_DEVICE(0x1737, 0x0078) }, /* Logitec */ { USB_DEVICE(0x0789, 0x0168) }, { USB_DEVICE(0x0789, 0x0169) }, /* Motorola */ { USB_DEVICE(0x100d, 0x9032) }, + /* Ovislink */ + { USB_DEVICE(0x1b75, 0x3071) }, + { USB_DEVICE(0x1b75, 0x3072) }, /* Pegatron */ { USB_DEVICE(0x05a6, 0x0101) }, + { USB_DEVICE(0x1d4d, 0x0002) }, { USB_DEVICE(0x1d4d, 0x0010) }, /* Planex */ { USB_DEVICE(0x2019, 0x5201) }, @@ -1114,11 +1093,16 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0df6, 0x004a) }, { USB_DEVICE(0x0df6, 0x004d) }, { USB_DEVICE(0x0df6, 0x0053) }, + { USB_DEVICE(0x0df6, 0x0060) }, + { USB_DEVICE(0x0df6, 0x0062) }, /* SMC */ { USB_DEVICE(0x083a, 0xa512) }, { USB_DEVICE(0x083a, 0xc522) }, { USB_DEVICE(0x083a, 0xd522) }, { USB_DEVICE(0x083a, 0xf511) }, + /* Sweex */ + { USB_DEVICE(0x177f, 0x0153) }, + { USB_DEVICE(0x177f, 0x0313) }, /* Zyxel */ { USB_DEVICE(0x0586, 0x341a) }, #endif diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 8c822113b088..c446db69bd3c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -922,7 +922,6 @@ struct rt2x00_dev { * Powersaving work */ struct delayed_work autowakeup_work; - struct work_struct sleep_work; /* * Data queue arrays for RX, TX, Beacon and ATIM. diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 5bd2c55c991f..939821b4af2f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -410,14 +410,10 @@ void rt2x00lib_txdone(struct queue_entry *entry, /* * If the data queue was below the threshold before the txdone * handler we must make sure the packet queue in the mac80211 stack - * is reenabled when the txdone handler has finished. This has to be - * serialized with rt2x00mac_tx(), otherwise we can wake up queue - * before it was stopped. + * is reenabled when the txdone handler has finished. */ - spin_lock_bh(&entry->queue->tx_lock); if (!rt2x00queue_threshold(entry->queue)) rt2x00queue_unpause_queue(entry->queue); - spin_unlock_bh(&entry->queue->tx_lock); } EXPORT_SYMBOL_GPL(rt2x00lib_txdone); @@ -453,23 +449,6 @@ static u8 *rt2x00lib_find_ie(u8 *data, unsigned int len, u8 ie) return NULL; } -static void rt2x00lib_sleep(struct work_struct *work) -{ - struct rt2x00_dev *rt2x00dev = - container_of(work, struct rt2x00_dev, sleep_work); - - if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) - return; - - /* - * Check again is powersaving is enabled, to prevent races from delayed - * work execution. - */ - if (!test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags)) - rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf, - IEEE80211_CONF_CHANGE_PS); -} - static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb, struct rxdone_entry_desc *rxdesc) @@ -517,7 +496,8 @@ static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev, cam |= (tim_ie->bitmap_ctrl & 0x01); if (!cam && !test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags)) - queue_work(rt2x00dev->workqueue, &rt2x00dev->sleep_work); + rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf, + IEEE80211_CONF_CHANGE_PS); } static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, @@ -1128,7 +1108,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); - INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep); /* * Let the driver probe the device to detect the capabilities. @@ -1185,7 +1164,6 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) */ cancel_work_sync(&rt2x00dev->intf_work); cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); - cancel_work_sync(&rt2x00dev->sleep_work); if (rt2x00_is_usb(rt2x00dev)) { del_timer_sync(&rt2x00dev->txstatus_timer); cancel_work_sync(&rt2x00dev->rxdone_work); diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index bc159bed4f6d..93bec140e598 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -113,7 +113,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * due to possible race conditions in mac80211. */ if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) - goto exit_free_skb; + goto exit_fail; /* * Use the ATIM queue if appropriate and present. @@ -127,7 +127,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ERROR(rt2x00dev, "Attempt to send packet over invalid queue %d.\n" "Please file bug report to %s.\n", qid, DRV_PROJECT); - goto exit_free_skb; + goto exit_fail; } /* @@ -152,23 +152,13 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) if (unlikely(rt2x00queue_write_tx_frame(queue, skb, false))) goto exit_fail; - /* - * Pausing queue has to be serialized with rt2x00lib_txdone(). Note - * we should not use spin_lock_bh variant as bottom halve was already - * disabled before ieee80211_xmit() call. - */ - spin_lock(&queue->tx_lock); if (rt2x00queue_threshold(queue)) rt2x00queue_pause_queue(queue); - spin_unlock(&queue->tx_lock); return; exit_fail: - spin_lock(&queue->tx_lock); rt2x00queue_pause_queue(queue); - spin_unlock(&queue->tx_lock); - exit_free_skb: dev_kfree_skb_any(skb); } EXPORT_SYMBOL_GPL(rt2x00mac_tx); diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 76f26ad044a2..ab8c16f8bcaf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -556,24 +556,15 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, bool local) { struct ieee80211_tx_info *tx_info; - struct queue_entry *entry; + struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); struct txentry_desc txdesc; struct skb_frame_desc *skbdesc; u8 rate_idx, rate_flags; - int ret = 0; - - /* - * That function must be called with bh disabled. - */ - spin_lock(&queue->tx_lock); - - entry = rt2x00queue_get_entry(queue, Q_INDEX); if (unlikely(rt2x00queue_full(queue))) { ERROR(queue->rt2x00dev, "Dropping frame due to full tx queue %d.\n", queue->qid); - ret = -ENOBUFS; - goto out; + return -ENOBUFS; } if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, @@ -582,8 +573,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, "Arrived at non-free entry in the non-full queue %d.\n" "Please file bug report to %s.\n", queue->qid, DRV_PROJECT); - ret = -EINVAL; - goto out; + return -EINVAL; } /* @@ -645,8 +635,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, if (unlikely(rt2x00queue_write_tx_data(entry, &txdesc))) { clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); entry->skb = NULL; - ret = -EIO; - goto out; + return -EIO; } set_bit(ENTRY_DATA_PENDING, &entry->flags); @@ -655,9 +644,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, rt2x00queue_write_tx_descriptor(entry, &txdesc); rt2x00queue_kick_tx_queue(queue, &txdesc); -out: - spin_unlock(&queue->tx_lock); - return ret; + return 0; } int rt2x00queue_clear_beacon(struct rt2x00_dev *rt2x00dev, @@ -1198,7 +1185,6 @@ static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev, struct data_queue *queue, enum data_queue_qid qid) { mutex_init(&queue->status_lock); - spin_lock_init(&queue->tx_lock); spin_lock_init(&queue->index_lock); queue->rt2x00dev = rt2x00dev; diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index ad3d5271cfa8..167d45873dca 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -432,7 +432,6 @@ enum data_queue_flags { * @flags: Entry flags, see &enum queue_entry_flags. * @status_lock: The mutex for protecting the start/stop/flush * handling on this queue. - * @tx_lock: Spinlock to serialize tx operations on this queue. * @index_lock: Spinlock to protect index handling. Whenever @index, @index_done or * @index_crypt needs to be changed this lock should be grabbed to prevent * index corruption due to concurrency. @@ -459,7 +458,6 @@ struct data_queue { unsigned long flags; struct mutex status_lock; - spinlock_t tx_lock; spinlock_t index_lock; unsigned int count; diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 99fa41614403..8f90f6268077 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -262,20 +262,23 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) struct queue_entry *entry = (struct queue_entry *)urb->context; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; + + if (rt2x00dev->ops->lib->tx_dma_done) + rt2x00dev->ops->lib->tx_dma_done(entry); + + /* + * Report the frame as DMA done + */ + rt2x00lib_dmadone(entry); + /* * Check if the frame was correctly uploaded */ if (urb->status) set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); - /* - * Report the frame as DMA done - */ - rt2x00lib_dmadone(entry); - if (rt2x00dev->ops->lib->tx_dma_done) - rt2x00dev->ops->lib->tx_dma_done(entry); /* * Schedule the delayed work for reading the TX status * from the device. @@ -426,8 +429,8 @@ void rt2x00usb_kick_queue(struct data_queue *queue) case QID_RX: if (!rt2x00queue_full(queue)) rt2x00queue_for_each_entry(queue, - Q_INDEX, Q_INDEX_DONE, + Q_INDEX, NULL, rt2x00usb_kick_rx_entry); break; @@ -870,8 +873,18 @@ int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state) { struct ieee80211_hw *hw = usb_get_intfdata(usb_intf); struct rt2x00_dev *rt2x00dev = hw->priv; + int retval; + + retval = rt2x00lib_suspend(rt2x00dev, state); + if (retval) + return retval; - return rt2x00lib_suspend(rt2x00dev, state); + /* + * Decrease usbdev refcount. + */ + usb_put_dev(interface_to_usbdev(usb_intf)); + + return 0; } EXPORT_SYMBOL_GPL(rt2x00usb_suspend); @@ -880,6 +893,8 @@ int rt2x00usb_resume(struct usb_interface *usb_intf) struct ieee80211_hw *hw = usb_get_intfdata(usb_intf); struct rt2x00_dev *rt2x00dev = hw->priv; + usb_get_dev(interface_to_usbdev(usb_intf)); + return rt2x00lib_resume(rt2x00dev); } EXPORT_SYMBOL_GPL(rt2x00usb_resume); diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 17de24eb6869..9d35ec16a3a5 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2254,7 +2254,8 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) static void rt61pci_wakeup(struct rt2x00_dev *rt2x00dev) { - struct rt2x00lib_conf libconf = { .conf = &rt2x00dev->hw->conf }; + struct ieee80211_conf conf = { .flags = 0 }; + struct rt2x00lib_conf libconf = { .conf = &conf }; rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); } @@ -2840,7 +2841,6 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) { int retval; - u32 reg; /* * Disable power saving. @@ -2858,14 +2858,6 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) if (retval) return retval; - /* - * Enable rfkill polling by setting GPIO direction of the - * rfkill switch GPIO pin correctly. - */ - rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); - rt2x00_set_field32(®, MAC_CSR13_BIT13, 1); - rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); - /* * Initialize hw specifications. */ diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index 8f3da5a56766..e3cd6db76b0e 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h @@ -372,7 +372,6 @@ struct hw_pairwise_ta_entry { #define MAC_CSR13_BIT10 FIELD32(0x00000400) #define MAC_CSR13_BIT11 FIELD32(0x00000800) #define MAC_CSR13_BIT12 FIELD32(0x00001000) -#define MAC_CSR13_BIT13 FIELD32(0x00002000) /* * MAC_CSR14: LED control register. diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 1a06231cfc74..ad20953cbf05 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2177,7 +2177,6 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) { int retval; - u32 reg; /* * Allocate eeprom data. @@ -2190,14 +2189,6 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) if (retval) return retval; - /* - * Enable rfkill polling by setting GPIO direction of the - * rfkill switch GPIO pin correctly. - */ - rt2x00usb_register_read(rt2x00dev, MAC_CSR13, ®); - rt2x00_set_field32(®, MAC_CSR13_BIT15, 0); - rt2x00usb_register_write(rt2x00dev, MAC_CSR13, reg); - /* * Initialize hw specifications. */ diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index df1cc116b83b..9f6b470414d3 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h @@ -282,9 +282,6 @@ struct hw_pairwise_ta_entry { #define MAC_CSR13_BIT10 FIELD32(0x00000400) #define MAC_CSR13_BIT11 FIELD32(0x00000800) #define MAC_CSR13_BIT12 FIELD32(0x00001000) -#define MAC_CSR13_BIT13 FIELD32(0x00002000) -#define MAC_CSR13_BIT14 FIELD32(0x00004000) -#define MAC_CSR13_BIT15 FIELD32(0x00008000) /* * MAC_CSR14: LED control register. diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index bf01d218d375..1e0be14d10d4 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c @@ -43,7 +43,7 @@ MODULE_AUTHOR("Larry Finger "); MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver"); MODULE_LICENSE("GPL"); -static struct usb_device_id rtl8187_table[] = { +static struct usb_device_id rtl8187_table[] __devinitdata = { /* Asus */ {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187}, /* Belkin */ diff --git a/drivers/net/wireless/rtl818x/rtl8187/leds.c b/drivers/net/wireless/rtl818x/rtl8187/leds.c index c2d5b495c179..2e0de2f5f0f9 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/leds.c +++ b/drivers/net/wireless/rtl818x/rtl8187/leds.c @@ -117,7 +117,7 @@ static void rtl8187_led_brightness_set(struct led_classdev *led_dev, radio_on = true; } else if (radio_on) { radio_on = false; - cancel_delayed_work(&priv->led_on); + cancel_delayed_work_sync(&priv->led_on); ieee80211_queue_delayed_work(hw, &priv->led_off, 0); } } else if (radio_on) { diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index ce0444cd785c..d2ec2535aa3c 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -610,11 +610,6 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, mac->link_state = MAC80211_NOLINK; memset(mac->bssid, 0, 6); - - /* reset sec info */ - rtl_cam_reset_sec_info(hw); - - rtl_cam_reset_all_entry(hw); mac->vendor = PEER_UNKNOWN; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, @@ -1068,9 +1063,6 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, *or clear all entry here. */ rtl_cam_delete_one_entry(hw, mac_addr, key_idx); - - rtl_cam_reset_sec_info(hw); - break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index c29f3980c1fd..254b64ba4bf6 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -954,13 +954,8 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); ring = &rtlpci->tx_ring[BEACON_QUEUE]; pskb = __skb_dequeue(&ring->queue); - if (pskb) { - struct rtl_tx_desc *entry = &ring->desc[ring->idx]; - pci_unmap_single(rtlpci->pdev, rtlpriv->cfg->ops->get_desc( - (u8 *) entry, true, HW_DESC_TXBUFF_ADDR), - pskb->len, PCI_DMA_TODEVICE); + if (pskb) kfree_skb(pskb); - } /*NB: the beacon data buffer must be 32-bit aligned. */ pskb = ieee80211_beacon_get(hw, mac->vif); @@ -1185,12 +1180,10 @@ static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw, ring->idx = (ring->idx + 1) % ring->entries; } - if (ring->desc) { - pci_free_consistent(rtlpci->pdev, - sizeof(*ring->desc) * ring->entries, - ring->desc, ring->dma); - ring->desc = NULL; - } + pci_free_consistent(rtlpci->pdev, + sizeof(*ring->desc) * ring->entries, + ring->desc, ring->dma); + ring->desc = NULL; } static void _rtl_pci_free_rx_ring(struct rtl_pci *rtlpci) @@ -1214,14 +1207,12 @@ static void _rtl_pci_free_rx_ring(struct rtl_pci *rtlpci) kfree_skb(skb); } - if (rtlpci->rx_ring[rx_queue_idx].desc) { - pci_free_consistent(rtlpci->pdev, + pci_free_consistent(rtlpci->pdev, sizeof(*rtlpci->rx_ring[rx_queue_idx]. desc) * rtlpci->rxringcount, rtlpci->rx_ring[rx_queue_idx].desc, rtlpci->rx_ring[rx_queue_idx].dma); - rtlpci->rx_ring[rx_queue_idx].desc = NULL; - } + rtlpci->rx_ring[rx_queue_idx].desc = NULL; } } @@ -1718,17 +1709,15 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn); pcipriv->ndis_adapter.funcnumber = PCI_FUNC(pdev->devfn); - if (bridge_pdev) { - /*find bridge info if available */ - pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor; - for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { - if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { - pcipriv->ndis_adapter.pcibridge_vendor = tmp; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Pci Bridge Vendor is found index:" - " %d\n", tmp)); - break; - } + /*find bridge info */ + pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor; + for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { + if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { + pcipriv->ndis_adapter.pcibridge_vendor = tmp; + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("Pci Bridge Vendor is found index: %d\n", + tmp)); + break; } } @@ -1988,7 +1977,6 @@ void rtl_pci_disconnect(struct pci_dev *pdev) rtl_deinit_deferred_work(hw); rtlpriv->intf_ops->adapter_stop(hw); } - rtlpriv->cfg->ops->disable_interrupt(hw); /*deinit rfkill */ rtl_deinit_rfkill(hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index 2d33d7d8403f..97183829b9be 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -523,10 +523,6 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw) dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, dm_digtable.backoff_val)); - dm_digtable.cur_igvalue += 2; - if (dm_digtable.cur_igvalue > 0x3f) - dm_digtable.cur_igvalue = 0x3f; - if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, dm_digtable.cur_igvalue); @@ -1222,18 +1218,13 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) ("PreState = %d, CurState = %d\n", p_ra->pre_ratr_state, p_ra->ratr_state)); - /* Only the PCI card uses sta in the update rate table - * callback routine */ - if (rtlhal->interface == INTF_PCI) { - rcu_read_lock(); - sta = ieee80211_find_sta(mac->vif, mac->bssid); - } + rcu_read_lock(); + sta = ieee80211_find_sta(mac->vif, mac->bssid); rtlpriv->cfg->ops->update_rate_tbl(hw, sta, p_ra->ratr_state); p_ra->pre_ratr_state = p_ra->ratr_state; - if (rtlhal->interface == INTF_PCI) - rcu_read_unlock(); + rcu_read_unlock(); } } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index 3bee79eab74e..c7576ec4744e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c @@ -104,7 +104,7 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, tx_agc[RF90_PATH_A] = 0x10101010; tx_agc[RF90_PATH_B] = 0x10101010; } else if (rtlpriv->dm.dynamic_txhighpower_lvl == - TXHIGHPWRLEVEL_LEVEL2) { + TXHIGHPWRLEVEL_LEVEL1) { tx_agc[RF90_PATH_A] = 0x00000000; tx_agc[RF90_PATH_B] = 0x00000000; } else{ diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 354f9b159341..942f7a3969a7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -295,7 +295,6 @@ static struct usb_device_id rtl8192c_usb_ids[] = { /*=== Customer ID ===*/ /****** 8188CU ********/ {RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/ - {RTL_USB_DEVICE(0x050d, 0x11f2, rtl92cu_hal_cfg)}, /*Belkin - ISY*/ {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 10b2ef0241d8..3a92ba3c4a1e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -549,16 +549,15 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, (tcb_desc->rts_use_shortpreamble ? 1 : 0) : (tcb_desc->rts_use_shortgi ? 1 : 0))); if (mac->bw_40) { - if (rate_flag & IEEE80211_TX_RC_DUP_DATA) { + if (tcb_desc->packet_bw) { SET_TX_DESC_DATA_BW(txdesc, 1); SET_TX_DESC_DATA_SC(txdesc, 3); - } else if(rate_flag & IEEE80211_TX_RC_40_MHZ_WIDTH){ - SET_TX_DESC_DATA_BW(txdesc, 1); - SET_TX_DESC_DATA_SC(txdesc, mac->cur_40_prime_sc); } else { SET_TX_DESC_DATA_BW(txdesc, 0); - SET_TX_DESC_DATA_SC(txdesc, 0); - } + if (rate_flag & IEEE80211_TX_RC_DUP_DATA) + SET_TX_DESC_DATA_SC(txdesc, + mac->cur_40_prime_sc); + } } else { SET_TX_DESC_DATA_BW(txdesc, 0); SET_TX_DESC_DATA_SC(txdesc, 0); diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c index 0c77a14a3821..3b5af0113d7f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c @@ -196,8 +196,6 @@ static bool _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw, /* Allocate skb buffer to contain firmware */ /* info and tx descriptor info. */ skb = dev_alloc_skb(frag_length); - if (!skb) - return false; skb_reserve(skb, extra_descoffset); seg_ptr = (u8 *)skb_put(skb, (u32)(frag_length - extra_descoffset)); @@ -577,8 +575,6 @@ static bool _rtl92s_firmware_set_h2c_cmd(struct ieee80211_hw *hw, u8 h2c_cmd, len = _rtl92s_get_h2c_cmdlen(MAX_TRANSMIT_BUFFER_SIZE, 1, &cmd_len); skb = dev_alloc_skb(len); - if (!skb) - return false; cb_desc = (struct rtl_tcb_desc *)(skb->cb); cb_desc->queue_index = TXCMD_QUEUE; cb_desc->cmd_or_init = DESC_PACKET_TYPE_NORMAL; diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index dbcf5a9cff98..a9367eba1ea7 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -542,8 +542,8 @@ static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb) WARN_ON(skb_queue_empty(&rx_queue)); while (!skb_queue_empty(&rx_queue)) { _skb = skb_dequeue(&rx_queue); - _rtl_usb_rx_process_agg(hw, _skb); - ieee80211_rx_irqsafe(hw, _skb); + _rtl_usb_rx_process_agg(hw, skb); + ieee80211_rx_irqsafe(hw, skb); } } @@ -861,7 +861,6 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb, u8 tid = 0; u16 seq_number = 0; - memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); if (ieee80211_is_auth(fc)) { RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); rtl_ips_nic_on(hw); diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index de9210c102eb..a14a48c99cdc 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -479,7 +479,6 @@ static void wl1251_op_stop(struct ieee80211_hw *hw) cancel_work_sync(&wl->irq_work); cancel_work_sync(&wl->tx_work); cancel_work_sync(&wl->filter_work); - cancel_delayed_work_sync(&wl->elp_work); mutex_lock(&wl->mutex); diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c index 4cf5c2e201d5..f51a0241a440 100644 --- a/drivers/net/wireless/wl1251/sdio.c +++ b/drivers/net/wireless/wl1251/sdio.c @@ -259,7 +259,6 @@ static int wl1251_sdio_probe(struct sdio_func *func, } if (wl->irq) { - irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl); if (ret < 0) { wl1251_error("request_irq() failed: %d", ret); @@ -267,6 +266,7 @@ static int wl1251_sdio_probe(struct sdio_func *func, } irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); + disable_irq(wl->irq); wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq; @@ -314,8 +314,8 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func) if (wl->irq) free_irq(wl->irq, wl); - wl1251_free_hw(wl); kfree(wl_sdio); + wl1251_free_hw(wl); sdio_claim_host(func); sdio_release_irq(func); diff --git a/drivers/net/wireless/wl1251/spi.c b/drivers/net/wireless/wl1251/spi.c index 49f3651423de..af6448c4d3e2 100644 --- a/drivers/net/wireless/wl1251/spi.c +++ b/drivers/net/wireless/wl1251/spi.c @@ -280,7 +280,6 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi) wl->use_eeprom = pdata->use_eeprom; - irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl); if (ret < 0) { wl1251_error("request_irq() failed: %d", ret); @@ -289,6 +288,8 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi) irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); + disable_irq(wl->irq); + ret = wl1251_init_ieee80211(wl); if (ret) goto out_irq; diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index e0e16888fe8e..b07f8b7e5f11 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c @@ -328,9 +328,6 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) nvs_ptr += 3; for (i = 0; i < burst_len; i++) { - if (nvs_ptr + 3 >= (u8 *) wl->nvs + nvs_len) - goto out_badnvs; - val = (nvs_ptr[0] | (nvs_ptr[1] << 8) | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24)); @@ -342,9 +339,6 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) nvs_ptr += 4; dest_addr += 4; } - - if (nvs_ptr >= (u8 *) wl->nvs + nvs_len) - goto out_badnvs; } /* @@ -356,10 +350,6 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) */ nvs_ptr = (u8 *)wl->nvs + ALIGN(nvs_ptr - (u8 *)wl->nvs + 7, 4); - - if (nvs_ptr >= (u8 *) wl->nvs + nvs_len) - goto out_badnvs; - nvs_len -= nvs_ptr - (u8 *)wl->nvs; /* Now we must set the partition correctly */ @@ -375,10 +365,6 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) kfree(nvs_aligned); return 0; - -out_badnvs: - wl1271_error("nvs data is malformed"); - return -EILSEQ; } static void wl1271_boot_enable_interrupts(struct wl1271 *wl) diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index b8ec8cd69b04..42935ac72663 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -121,11 +121,6 @@ int wl1271_cmd_general_parms(struct wl1271 *wl) if (!wl->nvs) return -ENODEV; - if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) { - wl1271_warning("FEM index from INI out of bounds"); - return -EINVAL; - } - gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL); if (!gen_parms) return -ENOMEM; @@ -149,12 +144,6 @@ int wl1271_cmd_general_parms(struct wl1271 *wl) gp->tx_bip_fem_manufacturer = gen_parms->general_params.tx_bip_fem_manufacturer; - if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) { - wl1271_warning("FEM index from FW out of bounds"); - ret = -EINVAL; - goto out; - } - wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n", answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer); @@ -174,11 +163,6 @@ int wl128x_cmd_general_parms(struct wl1271 *wl) if (!wl->nvs) return -ENODEV; - if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) { - wl1271_warning("FEM index from ini out of bounds"); - return -EINVAL; - } - gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL); if (!gen_parms) return -ENOMEM; @@ -203,12 +187,6 @@ int wl128x_cmd_general_parms(struct wl1271 *wl) gp->tx_bip_fem_manufacturer = gen_parms->general_params.tx_bip_fem_manufacturer; - if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) { - wl1271_warning("FEM index from FW out of bounds"); - ret = -EINVAL; - goto out; - } - wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n", answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer); diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index 9542e4662b6e..56f76abc754d 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -83,18 +83,14 @@ static int wl1271_get_scan_channels(struct wl1271 *wl, for (i = 0, j = 0; i < req->n_channels && j < WL1271_SCAN_MAX_CHANNELS; i++) { + flags = req->channels[i]->flags; if (!test_bit(i, wl->scan.scanned_ch) && !(flags & IEEE80211_CHAN_DISABLED) && - (req->channels[i]->band == band) && - /* - * In passive scans, we scan all remaining - * channels, even if not marked as such. - * In active scans, we only scan channels not - * marked as passive. - */ - (passive || !(flags & IEEE80211_CHAN_PASSIVE_SCAN))) { + ((!!(flags & IEEE80211_CHAN_PASSIVE_SCAN)) == passive) && + (req->channels[i]->band == band)) { + wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", req->channels[i]->band, req->channels[i]->center_freq); @@ -146,10 +142,6 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band, int ret; u16 scan_options = 0; - /* skip active scans if we don't have SSIDs */ - if (!passive && wl->scan.req->n_ssids == 0) - return WL1271_NOTHING_TO_SCAN; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); trigger = kzalloc(sizeof(*trigger), GFP_KERNEL); if (!cmd || !trigger) { @@ -160,7 +152,8 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band, /* We always use high priority scans */ scan_options = WL1271_SCAN_OPT_PRIORITY_HIGH; - if (passive) + /* No SSIDs means that we have a forced passive scan */ + if (passive || wl->scan.req->n_ssids == 0) scan_options |= WL1271_SCAN_OPT_PASSIVE; cmd->params.scan_options = cpu_to_le16(scan_options); diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h index 810a47290ab6..161f207786a4 100644 --- a/drivers/net/xen-netback/common.h +++ b/drivers/net/xen-netback/common.h @@ -152,9 +152,6 @@ void xen_netbk_queue_tx_skb(struct xenvif *vif, struct sk_buff *skb); /* Notify xenvif that ring now has space to send an skb to the frontend */ void xenvif_notify_tx_completion(struct xenvif *vif); -/* Prevent the device from generating any further traffic. */ -void xenvif_carrier_off(struct xenvif *vif); - /* Returns number of ring slots required to send an skb to the frontend */ unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb); diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index 5925e0b93bde..0ca86f9ec4ed 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -327,12 +327,12 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, xenvif_get(vif); rtnl_lock(); + if (netif_running(vif->dev)) + xenvif_up(vif); if (!vif->can_sg && vif->dev->mtu > ETH_DATA_LEN) dev_set_mtu(vif->dev, ETH_DATA_LEN); netdev_update_features(vif->dev); netif_carrier_on(vif->dev); - if (netif_running(vif->dev)) - xenvif_up(vif); rtnl_unlock(); return 0; @@ -342,22 +342,17 @@ err: return err; } -void xenvif_carrier_off(struct xenvif *vif) -{ - struct net_device *dev = vif->dev; - - rtnl_lock(); - netif_carrier_off(dev); /* discard queued packets */ - if (netif_running(dev)) - xenvif_down(vif); - rtnl_unlock(); - xenvif_put(vif); -} - void xenvif_disconnect(struct xenvif *vif) { - if (netif_carrier_ok(vif->dev)) - xenvif_carrier_off(vif); + struct net_device *dev = vif->dev; + if (netif_carrier_ok(dev)) { + rtnl_lock(); + netif_carrier_off(dev); /* discard queued packets */ + if (netif_running(dev)) + xenvif_down(vif); + rtnl_unlock(); + xenvif_put(vif); + } atomic_dec(&vif->refcnt); wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0); diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 9068d32d2d5c..0e4851b8a773 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -143,8 +143,7 @@ void xen_netbk_remove_xenvif(struct xenvif *vif) atomic_dec(&netbk->netfront_count); } -static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx, - u8 status); +static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx); static void make_tx_response(struct xenvif *vif, struct xen_netif_tx_request *txp, s8 st); @@ -839,7 +838,7 @@ static void netbk_tx_err(struct xenvif *vif, do { make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR); - if (cons == end) + if (cons >= end) break; txp = RING_GET_REQUEST(&vif->tx, cons++); } while (1); @@ -848,13 +847,6 @@ static void netbk_tx_err(struct xenvif *vif, xenvif_put(vif); } -static void netbk_fatal_tx_err(struct xenvif *vif) -{ - netdev_err(vif->dev, "fatal error; disabling device\n"); - xenvif_carrier_off(vif); - xenvif_put(vif); -} - static int netbk_count_requests(struct xenvif *vif, struct xen_netif_tx_request *first, struct xen_netif_tx_request *txp, @@ -868,22 +860,19 @@ static int netbk_count_requests(struct xenvif *vif, do { if (frags >= work_to_do) { - netdev_err(vif->dev, "Need more frags\n"); - netbk_fatal_tx_err(vif); + netdev_dbg(vif->dev, "Need more frags\n"); return -frags; } if (unlikely(frags >= MAX_SKB_FRAGS)) { - netdev_err(vif->dev, "Too many frags\n"); - netbk_fatal_tx_err(vif); + netdev_dbg(vif->dev, "Too many frags\n"); return -frags; } memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + frags), sizeof(*txp)); if (txp->size > first->size) { - netdev_err(vif->dev, "Frag is bigger than frame.\n"); - netbk_fatal_tx_err(vif); + netdev_dbg(vif->dev, "Frags galore\n"); return -frags; } @@ -891,9 +880,8 @@ static int netbk_count_requests(struct xenvif *vif, frags++; if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) { - netdev_err(vif->dev, "txp->offset: %x, size: %u\n", + netdev_dbg(vif->dev, "txp->offset: %x, size: %u\n", txp->offset, txp->size); - netbk_fatal_tx_err(vif); return -frags; } } while ((txp++)->flags & XEN_NETTXF_more_data); @@ -937,7 +925,7 @@ static struct gnttab_copy *xen_netbk_get_requests(struct xen_netbk *netbk, pending_idx = netbk->pending_ring[index]; page = xen_netbk_alloc_page(netbk, skb, pending_idx); if (!page) - goto err; + return NULL; netbk->mmap_pages[pending_idx] = page; @@ -961,17 +949,6 @@ static struct gnttab_copy *xen_netbk_get_requests(struct xen_netbk *netbk, } return gop; -err: - /* Unwind, freeing all pages and sending error responses. */ - while (i-- > start) { - xen_netbk_idx_release(netbk, (unsigned long)shinfo->frags[i].page, - XEN_NETIF_RSP_ERROR); - } - /* The head too, if necessary. */ - if (start) - xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_ERROR); - - return NULL; } static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, @@ -980,20 +957,30 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, { struct gnttab_copy *gop = *gopp; int pending_idx = *((u16 *)skb->data); + struct pending_tx_info *pending_tx_info = netbk->pending_tx_info; + struct xenvif *vif = pending_tx_info[pending_idx].vif; + struct xen_netif_tx_request *txp; struct skb_shared_info *shinfo = skb_shinfo(skb); int nr_frags = shinfo->nr_frags; int i, err, start; /* Check status of header. */ err = gop->status; - if (unlikely(err)) - xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_ERROR); + if (unlikely(err)) { + pending_ring_idx_t index; + index = pending_index(netbk->pending_prod++); + txp = &pending_tx_info[pending_idx].req; + make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR); + netbk->pending_ring[index] = pending_idx; + xenvif_put(vif); + } /* Skip first skb fragment if it is on same page as header fragment. */ - start = ((unsigned long)shinfo->frags[i].page == pending_idx); + start = ((unsigned long)shinfo->frags[0].page == pending_idx); for (i = start; i < nr_frags; i++) { int j, newerr; + pending_ring_idx_t index; pending_idx = (unsigned long)shinfo->frags[i].page; @@ -1002,12 +989,16 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, if (likely(!newerr)) { /* Had a previous error? Invalidate this fragment. */ if (unlikely(err)) - xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY); + xen_netbk_idx_release(netbk, pending_idx); continue; } /* Error on this fragment: respond to client with an error. */ - xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_ERROR); + txp = &netbk->pending_tx_info[pending_idx].req; + make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR); + index = pending_index(netbk->pending_prod++); + netbk->pending_ring[index] = pending_idx; + xenvif_put(vif); /* Not the first error? Preceding frags already invalidated. */ if (err) @@ -1015,10 +1006,10 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, /* First error: invalidate header and preceding fragments. */ pending_idx = *((u16 *)skb->data); - xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY); + xen_netbk_idx_release(netbk, pending_idx); for (j = start; j < i; j++) { pending_idx = (unsigned long)shinfo->frags[i].page; - xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY); + xen_netbk_idx_release(netbk, pending_idx); } /* Remember the error: invalidate all subsequent fragments. */ @@ -1053,7 +1044,7 @@ static void xen_netbk_fill_frags(struct xen_netbk *netbk, struct sk_buff *skb) /* Take an extra reference to offset xen_netbk_idx_release */ get_page(netbk->mmap_pages[pending_idx]); - xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY); + xen_netbk_idx_release(netbk, pending_idx); } } @@ -1066,8 +1057,7 @@ static int xen_netbk_get_extras(struct xenvif *vif, do { if (unlikely(work_to_do-- <= 0)) { - netdev_err(vif->dev, "Missing extra info\n"); - netbk_fatal_tx_err(vif); + netdev_dbg(vif->dev, "Missing extra info\n"); return -EBADR; } @@ -1076,9 +1066,8 @@ static int xen_netbk_get_extras(struct xenvif *vif, if (unlikely(!extra.type || extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) { vif->tx.req_cons = ++cons; - netdev_err(vif->dev, + netdev_dbg(vif->dev, "Invalid extra type: %d\n", extra.type); - netbk_fatal_tx_err(vif); return -EINVAL; } @@ -1094,15 +1083,13 @@ static int netbk_set_skb_gso(struct xenvif *vif, struct xen_netif_extra_info *gso) { if (!gso->u.gso.size) { - netdev_err(vif->dev, "GSO size must not be zero.\n"); - netbk_fatal_tx_err(vif); + netdev_dbg(vif->dev, "GSO size must not be zero.\n"); return -EINVAL; } /* Currently only TCPv4 S.O. is supported. */ if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) { - netdev_err(vif->dev, "Bad GSO type %d.\n", gso->u.gso.type); - netbk_fatal_tx_err(vif); + netdev_dbg(vif->dev, "Bad GSO type %d.\n", gso->u.gso.type); return -EINVAL; } @@ -1239,25 +1226,9 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) /* Get a netif from the list with work to do. */ vif = poll_net_schedule_list(netbk); - /* This can sometimes happen because the test of - * list_empty(net_schedule_list) at the top of the - * loop is unlocked. Just go back and have another - * look. - */ if (!vif) continue; - if (vif->tx.sring->req_prod - vif->tx.req_cons > - XEN_NETIF_TX_RING_SIZE) { - netdev_err(vif->dev, - "Impossible number of requests. " - "req_prod %d, req_cons %d, size %ld\n", - vif->tx.sring->req_prod, vif->tx.req_cons, - XEN_NETIF_TX_RING_SIZE); - netbk_fatal_tx_err(vif); - continue; - } - RING_FINAL_CHECK_FOR_REQUESTS(&vif->tx, work_to_do); if (!work_to_do) { xenvif_put(vif); @@ -1285,14 +1256,17 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) work_to_do = xen_netbk_get_extras(vif, extras, work_to_do); idx = vif->tx.req_cons; - if (unlikely(work_to_do < 0)) + if (unlikely(work_to_do < 0)) { + netbk_tx_err(vif, &txreq, idx); continue; + } } ret = netbk_count_requests(vif, &txreq, txfrags, work_to_do); - if (unlikely(ret < 0)) + if (unlikely(ret < 0)) { + netbk_tx_err(vif, &txreq, idx - ret); continue; - + } idx += ret; if (unlikely(txreq.size < ETH_HLEN)) { @@ -1304,11 +1278,11 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) /* No crossing a page as the payload mustn't fragment. */ if (unlikely((txreq.offset + txreq.size) > PAGE_SIZE)) { - netdev_err(vif->dev, + netdev_dbg(vif->dev, "txreq.offset: %x, size: %u, end: %lu\n", txreq.offset, txreq.size, (txreq.offset&~PAGE_MASK) + txreq.size); - netbk_fatal_tx_err(vif); + netbk_tx_err(vif, &txreq, idx); continue; } @@ -1336,8 +1310,8 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1]; if (netbk_set_skb_gso(vif, skb, gso)) { - /* Failure in netbk_set_skb_gso is fatal. */ kfree_skb(skb); + netbk_tx_err(vif, &txreq, idx); continue; } } @@ -1438,7 +1412,7 @@ static void xen_netbk_tx_submit(struct xen_netbk *netbk) txp->size -= data_len; } else { /* Schedule a response immediately. */ - xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY); + xen_netbk_idx_release(netbk, pending_idx); } if (txp->flags & XEN_NETTXF_csum_blank) @@ -1493,8 +1467,7 @@ static void xen_netbk_tx_action(struct xen_netbk *netbk) } -static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx, - u8 status) +static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx) { struct xenvif *vif; struct pending_tx_info *pending_tx_info; @@ -1508,7 +1481,7 @@ static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx, vif = pending_tx_info->vif; - make_tx_response(vif, &pending_tx_info->req, status); + make_tx_response(vif, &pending_tx_info->req, XEN_NETIF_RSP_OKAY); index = pending_index(netbk->pending_prod++); netbk->pending_ring[index] = pending_idx; diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c index f8c752e408a6..dccd8636095c 100644 --- a/drivers/oprofile/oprof.c +++ b/drivers/oprofile/oprof.c @@ -239,45 +239,26 @@ int oprofile_set_ulong(unsigned long *addr, unsigned long val) return err; } -static int timer_mode; - static int __init oprofile_init(void) { int err; - /* always init architecture to setup backtrace support */ err = oprofile_arch_init(&oprofile_ops); - - timer_mode = err || timer; /* fall back to timer mode on errors */ - if (timer_mode) { - if (!err) - oprofile_arch_exit(); + if (err < 0 || timer) { + printk(KERN_INFO "oprofile: using timer interrupt.\n"); err = oprofile_timer_init(&oprofile_ops); if (err) return err; } - - err = oprofilefs_register(); - if (!err) - return 0; - - /* failed */ - if (timer_mode) - oprofile_timer_exit(); - else - oprofile_arch_exit(); - - return err; + return oprofilefs_register(); } static void __exit oprofile_exit(void) { + oprofile_timer_exit(); oprofilefs_unregister(); - if (timer_mode) - oprofile_timer_exit(); - else - oprofile_arch_exit(); + oprofile_arch_exit(); } diff --git a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c index 84a208dbed93..89f63456646f 100644 --- a/drivers/oprofile/oprofile_files.c +++ b/drivers/oprofile/oprofile_files.c @@ -45,7 +45,7 @@ static ssize_t timeout_write(struct file *file, char const __user *buf, return -EINVAL; retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval <= 0) + if (retval) return retval; retval = oprofile_set_timeout(val); @@ -84,7 +84,7 @@ static ssize_t depth_write(struct file *file, char const __user *buf, size_t cou return -EINVAL; retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval <= 0) + if (retval) return retval; retval = oprofile_set_ulong(&oprofile_backtrace_depth, val); @@ -141,10 +141,9 @@ static ssize_t enable_write(struct file *file, char const __user *buf, size_t co return -EINVAL; retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval <= 0) + if (retval) return retval; - retval = 0; if (val) retval = oprofile_start(); else diff --git a/drivers/oprofile/oprofile_perf.c b/drivers/oprofile/oprofile_perf.c index 137406ca73f6..9046f7b2ed79 100644 --- a/drivers/oprofile/oprofile_perf.c +++ b/drivers/oprofile/oprofile_perf.c @@ -25,7 +25,7 @@ static int oprofile_perf_enabled; static DEFINE_MUTEX(oprofile_perf_mutex); static struct op_counter_config *counter_config; -static struct perf_event **perf_events[NR_CPUS]; +static struct perf_event **perf_events[nr_cpumask_bits]; static int num_counters; /* diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c index 1c0b799b30bc..e9ff6f7770be 100644 --- a/drivers/oprofile/oprofilefs.c +++ b/drivers/oprofile/oprofilefs.c @@ -60,13 +60,6 @@ ssize_t oprofilefs_ulong_to_user(unsigned long val, char __user *buf, size_t cou } -/* - * Note: If oprofilefs_ulong_from_user() returns 0, then *val remains - * unchanged and might be uninitialized. This follows write syscall - * implementation when count is zero: "If count is zero ... [and if] - * no errors are detected, 0 will be returned without causing any - * other effect." (man 2 write) - */ int oprofilefs_ulong_from_user(unsigned long *val, char const __user *buf, size_t count) { char tmpbuf[TMPBUFSIZE]; @@ -86,7 +79,7 @@ int oprofilefs_ulong_from_user(unsigned long *val, char const __user *buf, size_ spin_lock_irqsave(&oprofilefs_lock, flags); *val = simple_strtoul(tmpbuf, NULL, 0); spin_unlock_irqrestore(&oprofilefs_lock, flags); - return count; + return 0; } @@ -106,7 +99,7 @@ static ssize_t ulong_write_file(struct file *file, char const __user *buf, size_ return -EINVAL; retval = oprofilefs_ulong_from_user(&value, buf, count); - if (retval <= 0) + if (retval) return retval; retval = oprofile_set_ulong(file->private_data, value); diff --git a/drivers/oprofile/timer_int.c b/drivers/oprofile/timer_int.c index 878fba126582..3ef44624f510 100644 --- a/drivers/oprofile/timer_int.c +++ b/drivers/oprofile/timer_int.c @@ -110,7 +110,6 @@ int oprofile_timer_init(struct oprofile_operations *ops) ops->start = oprofile_hrtimer_start; ops->stop = oprofile_hrtimer_stop; ops->cpu_type = "timer"; - printk(KERN_INFO "oprofile: using timer interrupt.\n"); return 0; } diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 6dcc7e2d54de..3dc9befa5aec 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -1388,7 +1388,7 @@ int dmar_set_interrupt(struct intel_iommu *iommu) return ret; } - ret = request_irq(irq, dmar_fault, IRQF_NO_THREAD, iommu->name, iommu); + ret = request_irq(irq, dmar_fault, 0, iommu->name, iommu); if (ret) printk(KERN_ERR "IOMMU: can't request irq\n"); return ret; diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 7bd36947deb3..a70fa89f76fd 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -131,12 +131,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) return AE_OK; - status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); - if (ACPI_FAILURE(status)) { - warn("can't evaluate _ADR (%#x)\n", status); - return AE_OK; - } - + acpi_evaluate_integer(handle, "_ADR", NULL, &adr); device = (adr >> 16) & 0xffff; function = adr & 0xffff; diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index dd7e0c51a33e..aca972bbfb4c 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -278,8 +278,8 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) static int is_shpc_capable(struct pci_dev *dev) { - if (dev->vendor == PCI_VENDOR_ID_AMD && - dev->device == PCI_DEVICE_ID_AMD_GOLAM_7450) + if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device == + PCI_DEVICE_ID_AMD_GOLAM_7450)) return 1; if (!pci_find_capability(dev, PCI_CAP_ID_SHPC)) return 0; diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 75ba2311b54f..36547f0ce305 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -944,8 +944,8 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ ctrl_dbg(ctrl, "Hotplug Controller:\n"); - if (pdev->vendor == PCI_VENDOR_ID_AMD && - pdev->device == PCI_DEVICE_ID_AMD_GOLAM_7450) { + if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == + PCI_DEVICE_ID_AMD_GOLAM_7450)) { /* amd shpc driver doesn't use Base Offset; assume 0 */ ctrl->mmio_base = pci_resource_start(pdev, 0); ctrl->mmio_size = pci_resource_len(pdev, 0); diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index ae762ecc658b..f02c34d26d1b 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -307,11 +307,6 @@ static inline bool dma_pte_present(struct dma_pte *pte) return (pte->val & 3) != 0; } -static inline bool dma_pte_superpage(struct dma_pte *pte) -{ - return (pte->val & (1 << 7)); -} - static inline int first_pte_in_page(struct dma_pte *pte) { return !((unsigned long)pte & ~VTD_PAGE_MASK); @@ -583,18 +578,17 @@ static void domain_update_iommu_snooping(struct dmar_domain *domain) static void domain_update_iommu_superpage(struct dmar_domain *domain) { - struct dmar_drhd_unit *drhd; - struct intel_iommu *iommu = NULL; - int mask = 0xf; + int i, mask = 0xf; if (!intel_iommu_superpage) { domain->iommu_superpage = 0; return; } - /* set iommu_superpage to the smallest common denominator */ - for_each_active_iommu(iommu, drhd) { - mask &= cap_super_page_val(iommu->cap); + domain->iommu_superpage = 4; /* 1TiB */ + + for_each_set_bit(i, &domain->iommu_bmp, g_num_of_iommus) { + mask |= cap_super_page_val(g_iommus[i]->cap); if (!mask) { break; } @@ -737,23 +731,29 @@ out: } static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, - unsigned long pfn, int target_level) + unsigned long pfn, int large_level) { int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; struct dma_pte *parent, *pte = NULL; int level = agaw_to_level(domain->agaw); - int offset; + int offset, target_level; BUG_ON(!domain->pgd); BUG_ON(addr_width < BITS_PER_LONG && pfn >> addr_width); parent = domain->pgd; + /* Search pte */ + if (!large_level) + target_level = 1; + else + target_level = large_level; + while (level > 0) { void *tmp_page; offset = pfn_level_offset(pfn, level); pte = &parent[offset]; - if (!target_level && (dma_pte_superpage(pte) || !dma_pte_present(pte))) + if (!large_level && (pte->val & DMA_PTE_LARGE_PAGE)) break; if (level == target_level) break; @@ -817,14 +817,13 @@ static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain, } /* clear last level pte, a tlb flush should be followed */ -static int dma_pte_clear_range(struct dmar_domain *domain, +static void dma_pte_clear_range(struct dmar_domain *domain, unsigned long start_pfn, unsigned long last_pfn) { int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; unsigned int large_page = 1; struct dma_pte *first_pte, *pte; - int order; BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width); @@ -848,9 +847,6 @@ static int dma_pte_clear_range(struct dmar_domain *domain, (void *)pte - (void *)first_pte); } while (start_pfn && start_pfn <= last_pfn); - - order = (large_page - 1) * 9; - return order; } /* free page table pages. last level pte should already be cleared */ @@ -1793,17 +1789,10 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, if (!pte) return -ENOMEM; /* It is large page*/ - if (largepage_lvl > 1) { + if (largepage_lvl > 1) pteval |= DMA_PTE_LARGE_PAGE; - /* Ensure that old small page tables are removed to make room - for superpage, if they exist. */ - dma_pte_clear_range(domain, iov_pfn, - iov_pfn + lvl_to_nr_pages(largepage_lvl) - 1); - dma_pte_free_pagetable(domain, iov_pfn, - iov_pfn + lvl_to_nr_pages(largepage_lvl) - 1); - } else { + else pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE; - } } /* We don't need lock here, nobody else @@ -2289,39 +2278,8 @@ static int domain_add_dev_info(struct dmar_domain *domain, return 0; } -static bool device_has_rmrr(struct pci_dev *dev) -{ - struct dmar_rmrr_unit *rmrr; - int i; - - for_each_rmrr_units(rmrr) { - for (i = 0; i < rmrr->devices_cnt; i++) { - /* - * Return TRUE if this RMRR contains the device that - * is passed in. - */ - if (rmrr->devices[i] == dev) - return true; - } - } - return false; -} - static int iommu_should_identity_map(struct pci_dev *pdev, int startup) { - - /* - * We want to prevent any device associated with an RMRR from - * getting placed into the SI Domain. This is done because - * problems exist when devices are moved in and out of domains - * and their respective RMRR info is lost. We exempt USB devices - * from this process due to their usage of RMRRs that are known - * to not be needed after BIOS hand-off to OS. - */ - if (device_has_rmrr(pdev) && - (pdev->class >> 8) != PCI_CLASS_SERIAL_USB) - return 0; - if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev)) return 1; @@ -3611,8 +3569,6 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain, found = 1; } - spin_unlock_irqrestore(&device_domain_lock, flags); - if (found == 0) { unsigned long tmp_flags; spin_lock_irqsave(&domain->iommu_lock, tmp_flags); @@ -3629,6 +3585,8 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain, spin_unlock_irqrestore(&iommu->lock, tmp_flags); } } + + spin_unlock_irqrestore(&device_domain_lock, flags); } static void vm_domain_remove_all_dev_info(struct dmar_domain *domain) @@ -3782,7 +3740,6 @@ static int intel_iommu_domain_init(struct iommu_domain *domain) vm_domain_exit(dmar_domain); return -ENOMEM; } - domain_update_iommu_cap(dmar_domain); domain->priv = dmar_domain; return 0; @@ -3908,15 +3865,14 @@ static int intel_iommu_unmap(struct iommu_domain *domain, { struct dmar_domain *dmar_domain = domain->priv; size_t size = PAGE_SIZE << gfp_order; - int order; - order = dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT, + dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT, (iova + size - 1) >> VTD_PAGE_SHIFT); if (dmar_domain->max_addr == iova + size) dmar_domain->max_addr = iova; - return order; + return gfp_order; } static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index e1749825008d..2f10328bf661 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -869,15 +869,5 @@ EXPORT_SYMBOL(pci_msi_enabled); void pci_msi_init_pci_dev(struct pci_dev *dev) { - int pos; INIT_LIST_HEAD(&dev->msi_list); - - /* Disable the msi hardware to avoid screaming interrupts - * during boot. This is the power on reset default so - * usually this should be a noop. - */ - pos = pci_find_capability(dev, PCI_CAP_ID_MSI); - if (pos) - msi_set_enable(dev, pos, 0); - msix_set_enable(dev, 0); } diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 56b04bc80a12..d36f41ea8cbf 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -393,6 +393,7 @@ static int __init acpi_pci_init(void) if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n"); + pcie_clear_aspm(); pcie_no_aspm(); } diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 5d5bdf7ecf5f..46767c53917a 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -726,18 +726,6 @@ static int pci_pm_suspend_noirq(struct device *dev) pci_pm_set_unknown_state(pci_dev); - /* - * Some BIOSes from ASUS have a bug: If a USB EHCI host controller's - * PCI COMMAND register isn't 0, the BIOS assumes that the controller - * hasn't been quiesced and tries to turn it off. If the controller - * is already in D3, this can hang or cause memory corruption. - * - * Since the value of the COMMAND register doesn't matter once the - * device has been suspended, we can safely set it to 0 here. - */ - if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI) - pci_write_config_word(pci_dev, PCI_COMMAND, 0); - return 0; } @@ -936,13 +924,6 @@ static int pci_pm_poweroff_noirq(struct device *dev) if (!pci_dev->state_saved && !pci_is_bridge(pci_dev)) pci_prepare_to_sleep(pci_dev); - /* - * The reason for doing this here is the same as for the analogous code - * in pci_pm_suspend_noirq(). - */ - if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI) - pci_write_config_word(pci_dev, PCI_COMMAND, 0); - return 0; } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d549bbc93cdd..692671b11667 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1905,7 +1905,7 @@ void pci_enable_ari(struct pci_dev *dev) { int pos; u32 cap; - u16 flags, ctrl; + u16 ctrl; struct pci_dev *bridge; if (!pci_is_pcie(dev) || dev->devfn) @@ -1923,11 +1923,6 @@ void pci_enable_ari(struct pci_dev *dev) if (!pos) return; - /* ARI is a PCIe v2 feature */ - pci_read_config_word(bridge, pos + PCI_EXP_FLAGS, &flags); - if ((flags & PCI_EXP_FLAGS_VERS) < 2) - return; - pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap); if (!(cap & PCI_EXP_DEVCAP2_ARI)) return; diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 9b9305ae93a3..6892601fc76f 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -68,7 +68,7 @@ struct pcie_link_state { struct aspm_latency acceptable[8]; }; -static int aspm_disabled, aspm_force; +static int aspm_disabled, aspm_force, aspm_clear_state; static bool aspm_support_enabled = true; static DEFINE_MUTEX(aspm_lock); static LIST_HEAD(link_list); @@ -500,6 +500,9 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) int pos; u32 reg32; + if (aspm_clear_state) + return -EINVAL; + /* * Some functions in a slot might not all be PCIe functions, * very strange. Disable ASPM for the whole slot @@ -508,16 +511,6 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) pos = pci_pcie_cap(child); if (!pos) return -EINVAL; - - /* - * If ASPM is disabled then we're not going to change - * the BIOS state. It's safe to continue even if it's a - * pre-1.1 device - */ - - if (aspm_disabled) - continue; - /* * Disable ASPM for pre-1.1 PCIe device, we follow MS to use * RBER bit to determine if a function is 1.1 version device @@ -581,6 +574,9 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) return; + if (aspm_disabled && !aspm_clear_state) + return; + /* VIA has a strange chipset, root port is under a bridge */ if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT && pdev->bus->self) @@ -612,7 +608,7 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) * the BIOS's expectation, we'll do so once pci_enable_device() is * called. */ - if (aspm_policy != POLICY_POWERSAVE) { + if (aspm_policy != POLICY_POWERSAVE || aspm_clear_state) { pcie_config_aspm_path(link); pcie_set_clkpm(link, policy_to_clkpm_state(link)); } @@ -653,7 +649,8 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) struct pci_dev *parent = pdev->bus->self; struct pcie_link_state *link, *root, *parent_link; - if (!pci_is_pcie(pdev) || !parent || !parent->link_state) + if ((aspm_disabled && !aspm_clear_state) || !pci_is_pcie(pdev) || + !parent || !parent->link_state) return; if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) @@ -737,18 +734,13 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev) * pci_disable_link_state - disable pci device's link state, so the link will * never enter specific states */ -static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem, - bool force) +static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem) { struct pci_dev *parent = pdev->bus->self; struct pcie_link_state *link; - if (aspm_disabled && !force) - return; - - if (!pci_is_pcie(pdev)) + if (aspm_disabled || !pci_is_pcie(pdev)) return; - if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT || pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) parent = pdev; @@ -776,34 +768,16 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem, void pci_disable_link_state_locked(struct pci_dev *pdev, int state) { - __pci_disable_link_state(pdev, state, false, false); + __pci_disable_link_state(pdev, state, false); } EXPORT_SYMBOL(pci_disable_link_state_locked); void pci_disable_link_state(struct pci_dev *pdev, int state) { - __pci_disable_link_state(pdev, state, true, false); + __pci_disable_link_state(pdev, state, true); } EXPORT_SYMBOL(pci_disable_link_state); -void pcie_clear_aspm(struct pci_bus *bus) -{ - struct pci_dev *child; - - if (aspm_force) - return; - - /* - * Clear any ASPM setup that the firmware has carried out on this bus - */ - list_for_each_entry(child, &bus->devices, bus_list) { - __pci_disable_link_state(child, PCIE_LINK_STATE_L0S | - PCIE_LINK_STATE_L1 | - PCIE_LINK_STATE_CLKPM, - false, true); - } -} - static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp) { int i; @@ -961,7 +935,6 @@ void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev) static int __init pcie_aspm_disable(char *str) { if (!strcmp(str, "off")) { - aspm_policy = POLICY_DEFAULT; aspm_disabled = 1; aspm_support_enabled = false; printk(KERN_INFO "PCIe ASPM is disabled\n"); @@ -974,18 +947,16 @@ static int __init pcie_aspm_disable(char *str) __setup("pcie_aspm=", pcie_aspm_disable); +void pcie_clear_aspm(void) +{ + if (!aspm_force) + aspm_clear_state = 1; +} + void pcie_no_aspm(void) { - /* - * Disabling ASPM is intended to prevent the kernel from modifying - * existing hardware state, not to clear existing state. To that end: - * (a) set policy to POLICY_DEFAULT in order to avoid changing state - * (b) prevent userspace from changing policy - */ - if (!aspm_force) { - aspm_policy = POLICY_DEFAULT; + if (!aspm_force) aspm_disabled = 1; - } } /** diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 0d5d0bfcb663..bafb3c3d4a89 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -657,17 +657,10 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, dev_dbg(&dev->dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n", secondary, subordinate, pass); - if (!primary && (primary != bus->number) && secondary && subordinate) { - dev_warn(&dev->dev, "Primary bus is hard wired to 0\n"); - primary = bus->number; - } - /* Check if setup is sensible at all */ if (!pass && - (primary != bus->number || secondary <= bus->number || - secondary > subordinate)) { - dev_info(&dev->dev, "bridge configuration invalid ([bus %02x-%02x]), reconfiguring\n", - secondary, subordinate); + (primary != bus->number || secondary <= bus->number)) { + dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n"); broken = 1; } diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index a9b124976764..02145e9697a9 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2745,29 +2745,6 @@ static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev) /* disable must be done via function #0 */ if (PCI_FUNC(dev->devfn)) return; - /* - * RICOH 0xe822 and 0xe823 SD/MMC card readers fail to recognize - * certain types of SD/MMC cards. Lowering the SD base - * clock frequency from 200Mhz to 50Mhz fixes this issue. - * - * 0x150 - SD2.0 mode enable for changing base clock - * frequency to 50Mhz - * 0xe1 - Base clock frequency - * 0x32 - 50Mhz new clock frequency - * 0xf9 - Key register for 0x150 - * 0xfc - key register for 0xe1 - */ - if (dev->device == PCI_DEVICE_ID_RICOH_R5CE822 || - dev->device == PCI_DEVICE_ID_RICOH_R5CE823) { - pci_write_config_byte(dev, 0xf9, 0xfc); - pci_write_config_byte(dev, 0x150, 0x10); - pci_write_config_byte(dev, 0xf9, 0x00); - pci_write_config_byte(dev, 0xfc, 0x01); - pci_write_config_byte(dev, 0xe1, 0x32); - pci_write_config_byte(dev, 0xfc, 0x00); - - dev_notice(&dev->dev, "MMC controller base frequency changed to 50Mhz.\n"); - } pci_read_config_byte(dev, 0xCB, &disable); @@ -2781,12 +2758,9 @@ static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev) dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n"); dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n"); - } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE822, ricoh_mmc_fixup_r5c832); -DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE822, ricoh_mmc_fixup_r5c832); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE823, ricoh_mmc_fixup_r5c832); DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE823, ricoh_mmc_fixup_r5c832); #endif /*CONFIG_MMC_RICOH_MMC*/ @@ -2825,40 +2799,6 @@ static void __devinit fixup_ti816x_class(struct pci_dev* dev) } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_TI, 0xb800, fixup_ti816x_class); -/* - * Some BIOS implementations leave the Intel GPU interrupts enabled, - * even though no one is handling them (f.e. i915 driver is never loaded). - * Additionally the interrupt destination is not set up properly - * and the interrupt ends up -somewhere-. - * - * These spurious interrupts are "sticky" and the kernel disables - * the (shared) interrupt line after 100.000+ generated interrupts. - * - * Fix it by disabling the still enabled interrupts. - * This resolves crashes often seen on monitor unplug. - */ -#define I915_DEIER_REG 0x4400c -static void __devinit disable_igfx_irq(struct pci_dev *dev) -{ - void __iomem *regs = pci_iomap(dev, 0, 0); - if (regs == NULL) { - dev_warn(&dev->dev, "igfx quirk: Can't iomap PCI device\n"); - return; - } - - /* Check if any interrupt line is still enabled */ - if (readl(regs + I915_DEIER_REG) != 0) { - dev_warn(&dev->dev, "BIOS left Intel GPU interrupts enabled; " - "disabling\n"); - - writel(0, regs + I915_DEIER_REG); - } - - pci_iounmap(dev, regs); -} -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); - static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) { diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index f53da9eda76c..7f87beed35ac 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -19,8 +19,6 @@ static void pci_free_resources(struct pci_dev *dev) static void pci_stop_dev(struct pci_dev *dev) { - pci_pme_active(dev, false); - if (dev->is_added) { pci_proc_detach_device(dev); pci_remove_sysfs_dev_files(dev); diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 49e03234c728..9995842e45b5 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -34,7 +34,6 @@ struct resource_list_x { resource_size_t start; resource_size_t end; resource_size_t add_size; - resource_size_t min_align; unsigned long flags; }; @@ -66,7 +65,7 @@ void pci_realloc(void) */ static void add_to_list(struct resource_list_x *head, struct pci_dev *dev, struct resource *res, - resource_size_t add_size, resource_size_t min_align) + resource_size_t add_size) { struct resource_list_x *list = head; struct resource_list_x *ln = list->next; @@ -85,16 +84,13 @@ static void add_to_list(struct resource_list_x *head, tmp->end = res->end; tmp->flags = res->flags; tmp->add_size = add_size; - tmp->min_align = min_align; list->next = tmp; } static void add_to_failed_list(struct resource_list_x *head, struct pci_dev *dev, struct resource *res) { - add_to_list(head, dev, res, - 0 /* dont care */, - 0 /* dont care */); + add_to_list(head, dev, res, 0); } static void __dev_sort_resources(struct pci_dev *dev, @@ -163,16 +159,13 @@ static void adjust_resources_sorted(struct resource_list_x *add_head, idx = res - &list->dev->resource[0]; add_size=list->add_size; - if (!resource_size(res)) { - res->end = res->start + add_size - 1; - if(pci_assign_resource(list->dev, idx)) + if (!resource_size(res) && add_size) { + res->end = res->start + add_size - 1; + if(pci_assign_resource(list->dev, idx)) reset_resource(res); - } else { - resource_size_t align = list->min_align; - res->flags |= list->flags & (IORESOURCE_STARTALIGN|IORESOURCE_SIZEALIGN); - if (pci_reassign_resource(list->dev, idx, add_size, align)) - dev_printk(KERN_DEBUG, &list->dev->dev, "failed to add optional resources res=%pR\n", - res); + } else if (add_size) { + adjust_resource(res, res->start, + resource_size(res) + add_size); } out: tmp = list; @@ -550,20 +543,6 @@ static resource_size_t calculate_memsize(resource_size_t size, return size; } -static resource_size_t get_res_add_size(struct resource_list_x *add_head, - struct resource *res) -{ - struct resource_list_x *list; - - /* check if it is in add_head list */ - for (list = add_head->next; list && list->res != res; - list = list->next); - if (list) - return list->add_size; - - return 0; -} - /** * pbus_size_io() - size the io window of a given bus * @@ -583,7 +562,6 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, struct pci_dev *dev; struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); unsigned long size = 0, size0 = 0, size1 = 0; - resource_size_t children_add_size = 0; if (!b_res) return; @@ -604,17 +582,12 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, size += r_size; else size1 += r_size; - - if (add_head) - children_add_size += get_res_add_size(add_head, r); } } size0 = calculate_iosize(size, min_size, size1, resource_size(b_res), 4096); - if (children_add_size > add_size) - add_size = children_add_size; size1 = (!add_head || (add_head && !add_size)) ? size0 : - calculate_iosize(size, min_size, add_size + size1, + calculate_iosize(size, min_size+add_size, size1, resource_size(b_res), 4096); if (!size0 && !size1) { if (b_res->start || b_res->end) @@ -629,7 +602,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, b_res->end = b_res->start + size0 - 1; b_res->flags |= IORESOURCE_STARTALIGN; if (size1 > size0 && add_head) - add_to_list(add_head, bus->self, b_res, size1-size0, 4096); + add_to_list(add_head, bus->self, b_res, size1-size0); } /** @@ -654,7 +627,6 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, int order, max_order; struct resource *b_res = find_free_bus_resource(bus, type); unsigned int mem64_mask = 0; - resource_size_t children_add_size = 0; if (!b_res) return 0; @@ -696,9 +668,6 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, if (order > max_order) max_order = order; mem64_mask &= r->flags & IORESOURCE_MEM_64; - - if (add_head) - children_add_size += get_res_add_size(add_head, r); } } align = 0; @@ -715,10 +684,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, align += aligns[order]; } size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align); - if (children_add_size > add_size) - add_size = children_add_size; size1 = (!add_head || (add_head && !add_size)) ? size0 : - calculate_memsize(size, min_size, add_size, + calculate_memsize(size, min_size+add_size, 0, resource_size(b_res), min_align); if (!size0 && !size1) { if (b_res->start || b_res->end) @@ -732,7 +699,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, b_res->end = size0 + min_align - 1; b_res->flags |= IORESOURCE_STARTALIGN | mem64_mask; if (size1 > size0 && add_head) - add_to_list(add_head, bus->self, b_res, size1-size0, min_align); + add_to_list(add_head, bus->self, b_res, size1-size0); return 1; } diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index e4261498fcf6..bc0e6eea0fff 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -129,16 +129,16 @@ void pci_disable_bridge_window(struct pci_dev *dev) } #endif /* CONFIG_PCI_QUIRKS */ - - static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, - int resno, resource_size_t size, resource_size_t align) + int resno) { struct resource *res = dev->resource + resno; - resource_size_t min; + resource_size_t size, min, align; int ret; + size = resource_size(res); min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; + align = pci_resource_alignment(dev, res); /* First, try exact prefetching match.. */ ret = pci_bus_alloc_resource(bus, res, size, align, min, @@ -155,102 +155,56 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, ret = pci_bus_alloc_resource(bus, res, size, align, min, 0, pcibios_align_resource, dev); } - return ret; -} - -static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, - int resno, resource_size_t size) -{ - struct resource *root, *conflict; - resource_size_t start, end; - int ret = 0; - - if (res->flags & IORESOURCE_IO) - root = &ioport_resource; - else - root = &iomem_resource; - - start = res->start; - end = res->end; - res->start = dev->fw_addr[resno]; - res->end = res->start + size - 1; - dev_info(&dev->dev, "BAR %d: trying firmware assignment %pR\n", - resno, res); - conflict = request_resource_conflict(root, res); - if (conflict) { - dev_info(&dev->dev, - "BAR %d: %pR conflicts with %s %pR\n", resno, - res, conflict->name, conflict); - res->start = start; - res->end = end; - ret = 1; - } - return ret; -} -static int _pci_assign_resource(struct pci_dev *dev, int resno, int size, resource_size_t min_align) -{ - struct resource *res = dev->resource + resno; - struct pci_bus *bus; - int ret; - char *type; + if (ret < 0 && dev->fw_addr[resno]) { + struct resource *root, *conflict; + resource_size_t start, end; - bus = dev->bus; - while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) { - if (!bus->parent || !bus->self->transparent) - break; - bus = bus->parent; - } + /* + * If we failed to assign anything, let's try the address + * where firmware left it. That at least has a chance of + * working, which is better than just leaving it disabled. + */ - if (ret) { - if (res->flags & IORESOURCE_MEM) - if (res->flags & IORESOURCE_PREFETCH) - type = "mem pref"; - else - type = "mem"; - else if (res->flags & IORESOURCE_IO) - type = "io"; + if (res->flags & IORESOURCE_IO) + root = &ioport_resource; else - type = "unknown"; - dev_info(&dev->dev, - "BAR %d: can't assign %s (size %#llx)\n", - resno, type, (unsigned long long) resource_size(res)); + root = &iomem_resource; + + start = res->start; + end = res->end; + res->start = dev->fw_addr[resno]; + res->end = res->start + size - 1; + dev_info(&dev->dev, "BAR %d: trying firmware assignment %pR\n", + resno, res); + conflict = request_resource_conflict(root, res); + if (conflict) { + dev_info(&dev->dev, + "BAR %d: %pR conflicts with %s %pR\n", resno, + res, conflict->name, conflict); + res->start = start; + res->end = end; + } else + ret = 0; } - return ret; -} - -int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsize, - resource_size_t min_align) -{ - struct resource *res = dev->resource + resno; - resource_size_t new_size; - int ret; - - if (!res->parent) { - dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resouce %pR " - "\n", resno, res); - return -EINVAL; - } - - /* already aligned with min_align */ - new_size = resource_size(res) + addsize; - ret = _pci_assign_resource(dev, resno, new_size, min_align); if (!ret) { res->flags &= ~IORESOURCE_STARTALIGN; - dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res); + dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); if (resno < PCI_BRIDGE_RESOURCES) pci_update_resource(dev, resno); } + return ret; } int pci_assign_resource(struct pci_dev *dev, int resno) { struct resource *res = dev->resource + resno; - resource_size_t align, size; + resource_size_t align; struct pci_bus *bus; int ret; + char *type; align = pci_resource_alignment(dev, res); if (!align) { @@ -260,27 +214,34 @@ int pci_assign_resource(struct pci_dev *dev, int resno) } bus = dev->bus; - size = resource_size(res); - ret = _pci_assign_resource(dev, resno, size, align); - - /* - * If we failed to assign anything, let's try the address - * where firmware left it. That at least has a chance of - * working, which is better than just leaving it disabled. - */ - if (ret < 0 && dev->fw_addr[resno]) - ret = pci_revert_fw_address(res, dev, resno, size); + while ((ret = __pci_assign_resource(bus, dev, resno))) { + if (bus->parent && bus->self->transparent) + bus = bus->parent; + else + bus = NULL; + if (bus) + continue; + break; + } - if (!ret) { - res->flags &= ~IORESOURCE_STARTALIGN; - dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); - if (resno < PCI_BRIDGE_RESOURCES) - pci_update_resource(dev, resno); + if (ret) { + if (res->flags & IORESOURCE_MEM) + if (res->flags & IORESOURCE_PREFETCH) + type = "mem pref"; + else + type = "mem"; + else if (res->flags & IORESOURCE_IO) + type = "io"; + else + type = "unknown"; + dev_info(&dev->dev, + "BAR %d: can't assign %s (size %#llx)\n", + resno, type, (unsigned long long) resource_size(res)); } + return ret; } - /* Sort resources by alignment */ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) { diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index d4e7a1052259..492b7d807fe8 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c @@ -400,8 +400,9 @@ static int pcifront_claim_resource(struct pci_dev *dev, void *data) dev_info(&pdev->xdev->dev, "claiming resource %s/%d\n", pci_name(dev), i); if (pci_claim_resource(dev, i)) { - dev_err(&pdev->xdev->dev, "Could not claim resource %s/%d! " - "Device offline. Try using e820_host=1 in the guest config.\n", + dev_err(&pdev->xdev->dev, "Could not claim " + "resource %s/%d! Device offline. Try " + "giving less than 4GB to domain.\n", pci_name(dev), i); } } diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 1932029de48d..749c2a16012c 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -1269,8 +1269,10 @@ static int pcmcia_bus_add(struct pcmcia_socket *skt) static int pcmcia_bus_early_resume(struct pcmcia_socket *skt) { - if (!verify_cis_cache(skt)) + if (!verify_cis_cache(skt)) { + pcmcia_put_socket(skt); return 0; + } dev_dbg(&skt->dev, "cis mismatch - different card\n"); diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index 097fa0092f5a..81af2b3bcc00 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c @@ -222,7 +222,7 @@ static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) sharpsl_pcmcia_init_reset(skt); } -static struct pcmcia_low_level sharpsl_pcmcia_ops = { +static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = { .owner = THIS_MODULE, .hw_init = sharpsl_pcmcia_hw_init, .hw_shutdown = sharpsl_pcmcia_hw_shutdown, diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 202b567a706c..e1c4938b301b 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -104,7 +104,6 @@ static const struct key_entry acer_wmi_keymap[] = { {KE_KEY, 0x22, {KEY_PROG2} }, /* Arcade */ {KE_KEY, 0x23, {KEY_PROG3} }, /* P_Key */ {KE_KEY, 0x24, {KEY_PROG4} }, /* Social networking_Key */ - {KE_KEY, 0x29, {KEY_PROG3} }, /* P_Key for TM8372 */ {KE_IGNORE, 0x41, {KEY_MUTE} }, {KE_IGNORE, 0x42, {KEY_PREVIOUSSONG} }, {KE_IGNORE, 0x43, {KEY_NEXTSONG} }, @@ -305,10 +304,6 @@ static struct quirk_entry quirk_fujitsu_amilo_li_1718 = { .wireless = 2, }; -static struct quirk_entry quirk_lenovo_ideapad_s205 = { - .wireless = 3, -}; - /* The Aspire One has a dummy ACPI-WMI interface - disable it */ static struct dmi_system_id __devinitdata acer_blacklist[] = { { @@ -455,24 +450,6 @@ static struct dmi_system_id acer_quirks[] = { }, .driver_data = &quirk_medion_md_98300, }, - { - .callback = dmi_matched, - .ident = "Lenovo Ideapad S205", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "10382LG"), - }, - .driver_data = &quirk_lenovo_ideapad_s205, - }, - { - .callback = dmi_matched, - .ident = "Lenovo 3000 N200", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "0687A31"), - }, - .driver_data = &quirk_fujitsu_amilo_li_1718, - }, {} }; @@ -565,12 +542,6 @@ struct wmi_interface *iface) return AE_ERROR; *value = result & 0x1; return AE_OK; - case 3: - err = ec_read(0x78, &result); - if (err) - return AE_ERROR; - *value = result & 0x1; - return AE_OK; default: err = ec_read(0xA, &result); if (err) @@ -677,33 +648,6 @@ static acpi_status AMW0_find_mailled(void) return AE_OK; } -static int AMW0_set_cap_acpi_check_device_found; - -static acpi_status AMW0_set_cap_acpi_check_device_cb(acpi_handle handle, - u32 level, void *context, void **retval) -{ - AMW0_set_cap_acpi_check_device_found = 1; - return AE_OK; -} - -static const struct acpi_device_id norfkill_ids[] = { - { "VPC2004", 0}, - { "IBM0068", 0}, - { "LEN0068", 0}, - { "SNY5001", 0}, /* sony-laptop in charge */ - { "", 0}, -}; - -static int AMW0_set_cap_acpi_check_device(void) -{ - const struct acpi_device_id *id; - - for (id = norfkill_ids; id->id[0]; id++) - acpi_get_devices(id->id, AMW0_set_cap_acpi_check_device_cb, - NULL, NULL); - return AMW0_set_cap_acpi_check_device_found; -} - static acpi_status AMW0_set_capabilities(void) { struct wmab_args args; @@ -717,9 +661,7 @@ static acpi_status AMW0_set_capabilities(void) * work. */ if (wmi_has_guid(AMW0_GUID2)) { - if ((quirks != &quirk_unknown) || - !AMW0_set_cap_acpi_check_device()) - interface->capability |= ACER_CAP_WIRELESS; + interface->capability |= ACER_CAP_WIRELESS; return AE_OK; } @@ -1323,15 +1265,9 @@ static void acer_rfkill_update(struct work_struct *ignored) u32 state; acpi_status status; - if (has_cap(ACER_CAP_WIRELESS)) { - status = get_u32(&state, ACER_CAP_WIRELESS); - if (ACPI_SUCCESS(status)) { - if (quirks->wireless == 3) - rfkill_set_hw_state(wireless_rfkill, !state); - else - rfkill_set_sw_state(wireless_rfkill, !state); - } - } + status = get_u32(&state, ACER_CAP_WIRELESS); + if (ACPI_SUCCESS(status)) + rfkill_set_sw_state(wireless_rfkill, !state); if (has_cap(ACER_CAP_BLUETOOTH)) { status = get_u32(&state, ACER_CAP_BLUETOOTH); @@ -1398,24 +1334,19 @@ static struct rfkill *acer_rfkill_register(struct device *dev, static int acer_rfkill_init(struct device *dev) { - int err; - - if (has_cap(ACER_CAP_WIRELESS)) { - wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN, - "acer-wireless", ACER_CAP_WIRELESS); - if (IS_ERR(wireless_rfkill)) { - err = PTR_ERR(wireless_rfkill); - goto error_wireless; - } - } + wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN, + "acer-wireless", ACER_CAP_WIRELESS); + if (IS_ERR(wireless_rfkill)) + return PTR_ERR(wireless_rfkill); if (has_cap(ACER_CAP_BLUETOOTH)) { bluetooth_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_BLUETOOTH, "acer-bluetooth", ACER_CAP_BLUETOOTH); if (IS_ERR(bluetooth_rfkill)) { - err = PTR_ERR(bluetooth_rfkill); - goto error_bluetooth; + rfkill_unregister(wireless_rfkill); + rfkill_destroy(wireless_rfkill); + return PTR_ERR(bluetooth_rfkill); } } @@ -1424,44 +1355,30 @@ static int acer_rfkill_init(struct device *dev) RFKILL_TYPE_WWAN, "acer-threeg", ACER_CAP_THREEG); if (IS_ERR(threeg_rfkill)) { - err = PTR_ERR(threeg_rfkill); - goto error_threeg; + rfkill_unregister(wireless_rfkill); + rfkill_destroy(wireless_rfkill); + rfkill_unregister(bluetooth_rfkill); + rfkill_destroy(bluetooth_rfkill); + return PTR_ERR(threeg_rfkill); } } rfkill_inited = true; - if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) && - has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG)) + if (ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ)); return 0; - -error_threeg: - if (has_cap(ACER_CAP_BLUETOOTH)) { - rfkill_unregister(bluetooth_rfkill); - rfkill_destroy(bluetooth_rfkill); - } -error_bluetooth: - if (has_cap(ACER_CAP_WIRELESS)) { - rfkill_unregister(wireless_rfkill); - rfkill_destroy(wireless_rfkill); - } -error_wireless: - return err; } static void acer_rfkill_exit(void) { - if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) && - has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG)) + if (ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) cancel_delayed_work_sync(&acer_rfkill_work); - if (has_cap(ACER_CAP_WIRELESS)) { - rfkill_unregister(wireless_rfkill); - rfkill_destroy(wireless_rfkill); - } + rfkill_unregister(wireless_rfkill); + rfkill_destroy(wireless_rfkill); if (has_cap(ACER_CAP_BLUETOOTH)) { rfkill_unregister(bluetooth_rfkill); diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 26f7f01a7a27..d65df92e2acc 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -646,9 +646,9 @@ static ssize_t show_infos(struct device *dev, * The significance of others is yet to be found. * If we don't find the method, we assume the device are present. */ - rv = acpi_evaluate_integer(asus->handle, "HWRS", NULL, &temp); + rv = acpi_evaluate_integer(asus->handle, "HRWS", NULL, &temp); if (!ACPI_FAILURE(rv)) - len += sprintf(page + len, "HWRS value : %#x\n", + len += sprintf(page + len, "HRWS value : %#x\n", (uint) temp); /* * Another value for userspace: the ASYM method returns 0x02 for @@ -1340,9 +1340,9 @@ static int asus_laptop_get_info(struct asus_laptop *asus) * The significance of others is yet to be found. */ status = - acpi_evaluate_integer(asus->handle, "HWRS", NULL, &hwrs_result); + acpi_evaluate_integer(asus->handle, "HRWS", NULL, &hwrs_result); if (!ACPI_FAILURE(status)) - pr_notice(" HWRS returned %x", (int)hwrs_result); + pr_notice(" HRWS returned %x", (int)hwrs_result); if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL)) asus->have_rsts = true; diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c index 9827fe9c4da5..0580d99b0798 100644 --- a/drivers/platform/x86/asus-nb-wmi.c +++ b/drivers/platform/x86/asus-nb-wmi.c @@ -68,10 +68,6 @@ static const struct key_entry asus_nb_wmi_keymap[] = { { KE_KEY, 0x8A, { KEY_PROG1 } }, { KE_KEY, 0x95, { KEY_MEDIA } }, { KE_KEY, 0x99, { KEY_PHONE } }, - { KE_KEY, 0xA0, { KEY_SWITCHVIDEOMODE } }, /* SDSP HDMI only */ - { KE_KEY, 0xA1, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + HDMI */ - { KE_KEY, 0xA2, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + HDMI */ - { KE_KEY, 0xA3, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV + HDMI */ { KE_KEY, 0xb5, { KEY_CALC } }, { KE_KEY, 0xc4, { KEY_KBDILLUMUP } }, { KE_KEY, 0xc5, { KEY_KBDILLUMDOWN } }, diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index e1678b90083f..3c7857c71a23 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -797,8 +797,8 @@ exit: * Hwmon device */ static ssize_t asus_hwmon_pwm1(struct device *dev, - struct device_attribute *attr, - char *buf) + struct device_attribute *attr, + char *buf) { struct asus_wmi *asus = dev_get_drvdata(dev); u32 value; @@ -809,7 +809,7 @@ static ssize_t asus_hwmon_pwm1(struct device *dev, if (err < 0) return err; - value &= 0xFF; + value |= 0xFF; if (value == 1) /* Low Speed */ value = 85; @@ -869,7 +869,7 @@ static mode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj, * - reverved bits are non-zero * - sfun and presence bit are not set */ - if (value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000 + if (value != ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000 || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT))) ok = false; } @@ -904,7 +904,6 @@ static int asus_wmi_hwmon_init(struct asus_wmi *asus) pr_err("Could not register asus hwmon device\n"); return PTR_ERR(hwmon); } - dev_set_drvdata(hwmon, asus); asus->hwmon_device = hwmon; result = sysfs_create_group(&hwmon->kobj, &hwmon_attribute_group); if (result) @@ -1165,18 +1164,14 @@ ASUS_WMI_CREATE_DEVICE_ATTR(cardr, 0644, ASUS_WMI_DEVID_CARDREADER); static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - int value, rv; + int value; if (!count || sscanf(buf, "%i", &value) != 1) return -EINVAL; if (value < 0 || value > 2) return -EINVAL; - rv = asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL); - if (rv < 0) - return rv; - - return count; + return asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL); } static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv); diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index e66bbba9929d..5ffe7c398148 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -72,7 +72,6 @@ #include #include #include -#include #include #include #include @@ -1506,24 +1505,6 @@ static DEFINE_PCI_DEVICE_TABLE(ips_id_table) = { MODULE_DEVICE_TABLE(pci, ips_id_table); -static int ips_blacklist_callback(const struct dmi_system_id *id) -{ - pr_info("Blacklisted intel_ips for %s\n", id->ident); - return 1; -} - -static const struct dmi_system_id ips_blacklist[] = { - { - .callback = ips_blacklist_callback, - .ident = "HP ProBook", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook"), - }, - }, - { } /* terminating entry */ -}; - static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) { u64 platform_info; @@ -1533,9 +1514,6 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) u16 htshi, trc, trc_required_mask; u8 tse; - if (dmi_check_system(ips_blacklist)) - return -ENODEV; - ips = kzalloc(sizeof(struct ips_driver), GFP_KERNEL); if (!ips) return -ENOMEM; diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c index ec85987b2246..d347116d150e 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c @@ -370,17 +370,15 @@ static u8 read_brightness(void) &sretval); if (!retval) { user_brightness = sretval.retval[0]; - if (user_brightness > sabi_config->min_brightness) + if (user_brightness != 0) user_brightness -= sabi_config->min_brightness; - else - user_brightness = 0; } return user_brightness; } static void set_brightness(u8 user_brightness) { - u8 user_level = user_brightness + sabi_config->min_brightness; + u8 user_level = user_brightness - sabi_config->min_brightness; sabi_set_command(sabi_config->commands.set_brightness, user_level); } @@ -602,16 +600,6 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .callback = dmi_check_cb, }, - { - .ident = "N150/N210/N220", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, - "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"), - DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"), - }, - .callback = dmi_check_cb, - }, { .ident = "N150/N210/N220/N230", .matches = { @@ -632,15 +620,6 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .callback = dmi_check_cb, }, - { - .ident = "R700", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "SR700"), - DMI_MATCH(DMI_BOARD_NAME, "SR700"), - }, - .callback = dmi_check_cb, - }, { .ident = "R530/R730", .matches = { @@ -686,24 +665,6 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "P460"), }, .callback = dmi_check_cb, - }, - { - .ident = "X520", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "X520"), - DMI_MATCH(DMI_BOARD_NAME, "X520"), - }, - .callback = dmi_check_cb, - }, - { - .ident = "R528/R728", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "R528/R728"), - DMI_MATCH(DMI_BOARD_NAME, "R528/R728"), - }, - .callback = dmi_check_cb, }, { }, }; @@ -789,7 +750,7 @@ static int __init samsung_init(void) sabi_iface = ioremap_nocache(ifaceP, 16); if (!sabi_iface) { pr_err("Can't remap %x\n", ifaceP); - goto error_no_signature; + goto exit; } if (debug) { printk(KERN_DEBUG "ifaceP = 0x%08x\n", ifaceP); @@ -821,8 +782,7 @@ static int __init samsung_init(void) /* create a backlight device to talk to this one */ memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_PLATFORM; - props.max_brightness = sabi_config->max_brightness - - sabi_config->min_brightness; + props.max_brightness = sabi_config->max_brightness; backlight_device = backlight_device_register("samsung", &sdev->dev, NULL, &backlight_ops, &props); @@ -841,6 +801,7 @@ static int __init samsung_init(void) if (retval) goto error_file_create; +exit: return 0; error_file_create: diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 35dae412635d..bbd182e178cb 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -127,7 +127,7 @@ MODULE_PARM_DESC(minor, "default is -1 (automatic)"); #endif -static int kbd_backlight = 1; +static int kbd_backlight; /* = 1 */ module_param(kbd_backlight, int, 0444); MODULE_PARM_DESC(kbd_backlight, "set this to 0 to disable keyboard backlight, " diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 9b88be42b6cd..f23d5a84e7b1 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -754,13 +754,9 @@ static void wmi_free_devices(void) struct wmi_block *wblock, *next; /* Delete devices for all the GUIDs */ - list_for_each_entry_safe(wblock, next, &wmi_block_list, list) { - list_del(&wblock->list); + list_for_each_entry_safe(wblock, next, &wmi_block_list, list) if (wblock->dev.class) device_unregister(&wblock->dev); - else - kfree(wblock); - } } static bool guid_already_parsed(const char *guid_string) diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 8ac530a4c92f..ca84d5099ce7 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -57,7 +57,7 @@ static inline int __init is_exclusive_device(struct acpi_device *dev) if (!(('0' <= (c) && (c) <= '9') || ('A' <= (c) && (c) <= 'F'))) \ return 0 #define TEST_ALPHA(c) \ - if (!('A' <= (c) && (c) <= 'Z')) \ + if (!('@' <= (c) || (c) <= 'Z')) \ return 0 static int __init ispnpidacpi(const char *id) { @@ -94,9 +94,6 @@ static int pnpacpi_set_resources(struct pnp_dev *dev) return -ENODEV; } - if (WARN_ON_ONCE(acpi_dev != dev->data)) - dev->data = acpi_dev; - ret = pnpacpi_build_resource_template(dev, &buffer); if (ret) return ret; @@ -323,14 +320,9 @@ static int __init acpi_pnp_match(struct device *dev, void *_pnp) { struct acpi_device *acpi = to_acpi_device(dev); struct pnp_dev *pnp = _pnp; - struct device *physical_device; - - physical_device = acpi_get_physical_device(acpi->handle); - if (physical_device) - put_device(physical_device); /* true means it matched */ - return !physical_device + return !acpi_get_physical_device(acpi->handle) && compare_pnp_id(pnp->id, acpi_device_hid(acpi)); } diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index 258fef272ea7..dfbd5a6cc58b 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c @@ -295,45 +295,6 @@ static void quirk_system_pci_resources(struct pnp_dev *dev) } } -#ifdef CONFIG_AMD_NB - -#include - -static void quirk_amd_mmconfig_area(struct pnp_dev *dev) -{ - resource_size_t start, end; - struct pnp_resource *pnp_res; - struct resource *res; - struct resource mmconfig_res, *mmconfig; - - mmconfig = amd_get_mmconfig_range(&mmconfig_res); - if (!mmconfig) - return; - - list_for_each_entry(pnp_res, &dev->resources, list) { - res = &pnp_res->res; - if (res->end < mmconfig->start || res->start > mmconfig->end || - (res->start == mmconfig->start && res->end == mmconfig->end)) - continue; - - dev_info(&dev->dev, FW_BUG - "%pR covers only part of AMD MMCONFIG area %pR; adding more reservations\n", - res, mmconfig); - if (mmconfig->start < res->start) { - start = mmconfig->start; - end = res->start - 1; - pnp_add_mem_resource(dev, start, end, 0); - } - if (mmconfig->end > res->end) { - start = res->end + 1; - end = mmconfig->end; - pnp_add_mem_resource(dev, start, end, 0); - } - break; - } -} -#endif - /* * PnP Quirks * Cards or devices that need some tweaking due to incomplete resource info @@ -361,9 +322,6 @@ static struct pnp_fixup pnp_fixups[] = { /* PnP resources that might overlap PCI BARs */ {"PNP0c01", quirk_system_pci_resources}, {"PNP0c02", quirk_system_pci_resources}, -#ifdef CONFIG_AMD_NB - {"PNP0c01", quirk_amd_mmconfig_area}, -#endif {""} }; diff --git a/drivers/power/ds2780_battery.c b/drivers/power/ds2780_battery.c index 91a783d72360..1fefe82e12e3 100644 --- a/drivers/power/ds2780_battery.c +++ b/drivers/power/ds2780_battery.c @@ -39,7 +39,6 @@ struct ds2780_device_info { struct device *dev; struct power_supply bat; struct device *w1_dev; - struct task_struct *mutex_holder; }; enum current_types { @@ -50,8 +49,8 @@ enum current_types { static const char model[] = "DS2780"; static const char manufacturer[] = "Maxim/Dallas"; -static inline struct ds2780_device_info * -to_ds2780_device_info(struct power_supply *psy) +static inline struct ds2780_device_info *to_ds2780_device_info( + struct power_supply *psy) { return container_of(psy, struct ds2780_device_info, bat); } @@ -61,28 +60,17 @@ static inline struct power_supply *to_power_supply(struct device *dev) return dev_get_drvdata(dev); } -static inline int ds2780_battery_io(struct ds2780_device_info *dev_info, - char *buf, int addr, size_t count, int io) +static inline int ds2780_read8(struct device *dev, u8 *val, int addr) { - if (dev_info->mutex_holder == current) - return w1_ds2780_io_nolock(dev_info->w1_dev, buf, addr, count, io); - else - return w1_ds2780_io(dev_info->w1_dev, buf, addr, count, io); -} - -static inline int ds2780_read8(struct ds2780_device_info *dev_info, u8 *val, - int addr) -{ - return ds2780_battery_io(dev_info, val, addr, sizeof(u8), 0); + return w1_ds2780_io(dev, val, addr, sizeof(u8), 0); } -static int ds2780_read16(struct ds2780_device_info *dev_info, s16 *val, - int addr) +static int ds2780_read16(struct device *dev, s16 *val, int addr) { int ret; u8 raw[2]; - ret = ds2780_battery_io(dev_info, raw, addr, sizeof(raw), 0); + ret = w1_ds2780_io(dev, raw, addr, sizeof(u8) * 2, 0); if (ret < 0) return ret; @@ -91,16 +79,16 @@ static int ds2780_read16(struct ds2780_device_info *dev_info, s16 *val, return 0; } -static inline int ds2780_read_block(struct ds2780_device_info *dev_info, - u8 *val, int addr, size_t count) +static inline int ds2780_read_block(struct device *dev, u8 *val, int addr, + size_t count) { - return ds2780_battery_io(dev_info, val, addr, count, 0); + return w1_ds2780_io(dev, val, addr, count, 0); } -static inline int ds2780_write(struct ds2780_device_info *dev_info, u8 *val, - int addr, size_t count) +static inline int ds2780_write(struct device *dev, u8 *val, int addr, + size_t count) { - return ds2780_battery_io(dev_info, val, addr, count, 1); + return w1_ds2780_io(dev, val, addr, count, 1); } static inline int ds2780_store_eeprom(struct device *dev, int addr) @@ -134,7 +122,7 @@ static int ds2780_set_sense_register(struct ds2780_device_info *dev_info, { int ret; - ret = ds2780_write(dev_info, &conductance, + ret = ds2780_write(dev_info->w1_dev, &conductance, DS2780_RSNSP_REG, sizeof(u8)); if (ret < 0) return ret; @@ -146,7 +134,7 @@ static int ds2780_set_sense_register(struct ds2780_device_info *dev_info, static int ds2780_get_rsgain_register(struct ds2780_device_info *dev_info, u16 *rsgain) { - return ds2780_read16(dev_info, rsgain, DS2780_RSGAIN_MSB_REG); + return ds2780_read16(dev_info->w1_dev, rsgain, DS2780_RSGAIN_MSB_REG); } /* Set RSGAIN value from 0 to 1.999 in steps of 0.001 */ @@ -156,8 +144,8 @@ static int ds2780_set_rsgain_register(struct ds2780_device_info *dev_info, int ret; u8 raw[] = {rsgain >> 8, rsgain & 0xFF}; - ret = ds2780_write(dev_info, raw, - DS2780_RSGAIN_MSB_REG, sizeof(raw)); + ret = ds2780_write(dev_info->w1_dev, raw, + DS2780_RSGAIN_MSB_REG, sizeof(u8) * 2); if (ret < 0) return ret; @@ -179,7 +167,7 @@ static int ds2780_get_voltage(struct ds2780_device_info *dev_info, * Bits 2 - 0 of the voltage value are in bits 7 - 5 of the * voltage LSB register */ - ret = ds2780_read16(dev_info, &voltage_raw, + ret = ds2780_read16(dev_info->w1_dev, &voltage_raw, DS2780_VOLT_MSB_REG); if (ret < 0) return ret; @@ -208,7 +196,7 @@ static int ds2780_get_temperature(struct ds2780_device_info *dev_info, * Bits 2 - 0 of the temperature value are in bits 7 - 5 of the * temperature LSB register */ - ret = ds2780_read16(dev_info, &temperature_raw, + ret = ds2780_read16(dev_info->w1_dev, &temperature_raw, DS2780_TEMP_MSB_REG); if (ret < 0) return ret; @@ -234,13 +222,13 @@ static int ds2780_get_current(struct ds2780_device_info *dev_info, * The units of measurement for current are dependent on the value of * the sense resistor. */ - ret = ds2780_read8(dev_info, &sense_res_raw, DS2780_RSNSP_REG); + ret = ds2780_read8(dev_info->w1_dev, &sense_res_raw, DS2780_RSNSP_REG); if (ret < 0) return ret; if (sense_res_raw == 0) { dev_err(dev_info->dev, "sense resistor value is 0\n"); - return -EINVAL; + return -ENXIO; } sense_res = 1000 / sense_res_raw; @@ -260,7 +248,7 @@ static int ds2780_get_current(struct ds2780_device_info *dev_info, * Bits 7 - 0 of the current value are in bits 7 - 0 of the current * LSB register */ - ret = ds2780_read16(dev_info, ¤t_raw, reg_msb); + ret = ds2780_read16(dev_info->w1_dev, ¤t_raw, reg_msb); if (ret < 0) return ret; @@ -279,7 +267,7 @@ static int ds2780_get_accumulated_current(struct ds2780_device_info *dev_info, * The units of measurement for accumulated current are dependent on * the value of the sense resistor. */ - ret = ds2780_read8(dev_info, &sense_res_raw, DS2780_RSNSP_REG); + ret = ds2780_read8(dev_info->w1_dev, &sense_res_raw, DS2780_RSNSP_REG); if (ret < 0) return ret; @@ -297,7 +285,7 @@ static int ds2780_get_accumulated_current(struct ds2780_device_info *dev_info, * Bits 7 - 0 of the ACR value are in bits 7 - 0 of the ACR * LSB register */ - ret = ds2780_read16(dev_info, ¤t_raw, DS2780_ACR_MSB_REG); + ret = ds2780_read16(dev_info->w1_dev, ¤t_raw, DS2780_ACR_MSB_REG); if (ret < 0) return ret; @@ -311,7 +299,7 @@ static int ds2780_get_capacity(struct ds2780_device_info *dev_info, int ret; u8 raw; - ret = ds2780_read8(dev_info, &raw, DS2780_RARC_REG); + ret = ds2780_read8(dev_info->w1_dev, &raw, DS2780_RARC_REG); if (ret < 0) return ret; @@ -357,7 +345,7 @@ static int ds2780_get_charge_now(struct ds2780_device_info *dev_info, * Bits 7 - 0 of the RAAC value are in bits 7 - 0 of the RAAC * LSB register */ - ret = ds2780_read16(dev_info, &charge_raw, DS2780_RAAC_MSB_REG); + ret = ds2780_read16(dev_info->w1_dev, &charge_raw, DS2780_RAAC_MSB_REG); if (ret < 0) return ret; @@ -368,7 +356,7 @@ static int ds2780_get_charge_now(struct ds2780_device_info *dev_info, static int ds2780_get_control_register(struct ds2780_device_info *dev_info, u8 *control_reg) { - return ds2780_read8(dev_info, control_reg, DS2780_CONTROL_REG); + return ds2780_read8(dev_info->w1_dev, control_reg, DS2780_CONTROL_REG); } static int ds2780_set_control_register(struct ds2780_device_info *dev_info, @@ -376,7 +364,7 @@ static int ds2780_set_control_register(struct ds2780_device_info *dev_info, { int ret; - ret = ds2780_write(dev_info, &control_reg, + ret = ds2780_write(dev_info->w1_dev, &control_reg, DS2780_CONTROL_REG, sizeof(u8)); if (ret < 0) return ret; @@ -515,7 +503,7 @@ static ssize_t ds2780_get_sense_resistor_value(struct device *dev, struct power_supply *psy = to_power_supply(dev); struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); - ret = ds2780_read8(dev_info, &sense_resistor, DS2780_RSNSP_REG); + ret = ds2780_read8(dev_info->w1_dev, &sense_resistor, DS2780_RSNSP_REG); if (ret < 0) return ret; @@ -596,7 +584,7 @@ static ssize_t ds2780_get_pio_pin(struct device *dev, struct power_supply *psy = to_power_supply(dev); struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); - ret = ds2780_read8(dev_info, &sfr, DS2780_SFR_REG); + ret = ds2780_read8(dev_info->w1_dev, &sfr, DS2780_SFR_REG); if (ret < 0) return ret; @@ -623,7 +611,7 @@ static ssize_t ds2780_set_pio_pin(struct device *dev, return -EINVAL; } - ret = ds2780_write(dev_info, &new_setting, + ret = ds2780_write(dev_info->w1_dev, &new_setting, DS2780_SFR_REG, sizeof(u8)); if (ret < 0) return ret; @@ -644,7 +632,7 @@ static ssize_t ds2780_read_param_eeprom_bin(struct file *filp, DS2780_EEPROM_BLOCK1_END - DS2780_EEPROM_BLOCK1_START + 1 - off); - return ds2780_read_block(dev_info, buf, + return ds2780_read_block(dev_info->w1_dev, buf, DS2780_EEPROM_BLOCK1_START + off, count); } @@ -662,7 +650,7 @@ static ssize_t ds2780_write_param_eeprom_bin(struct file *filp, DS2780_EEPROM_BLOCK1_END - DS2780_EEPROM_BLOCK1_START + 1 - off); - ret = ds2780_write(dev_info, buf, + ret = ds2780_write(dev_info->w1_dev, buf, DS2780_EEPROM_BLOCK1_START + off, count); if (ret < 0) return ret; @@ -697,8 +685,9 @@ static ssize_t ds2780_read_user_eeprom_bin(struct file *filp, DS2780_EEPROM_BLOCK0_END - DS2780_EEPROM_BLOCK0_START + 1 - off); - return ds2780_read_block(dev_info, buf, + return ds2780_read_block(dev_info->w1_dev, buf, DS2780_EEPROM_BLOCK0_START + off, count); + } static ssize_t ds2780_write_user_eeprom_bin(struct file *filp, @@ -715,7 +704,7 @@ static ssize_t ds2780_write_user_eeprom_bin(struct file *filp, DS2780_EEPROM_BLOCK0_END - DS2780_EEPROM_BLOCK0_START + 1 - off); - ret = ds2780_write(dev_info, buf, + ret = ds2780_write(dev_info->w1_dev, buf, DS2780_EEPROM_BLOCK0_START + off, count); if (ret < 0) return ret; @@ -779,7 +768,6 @@ static int __devinit ds2780_battery_probe(struct platform_device *pdev) dev_info->bat.properties = ds2780_battery_props; dev_info->bat.num_properties = ARRAY_SIZE(ds2780_battery_props); dev_info->bat.get_property = ds2780_battery_get_property; - dev_info->mutex_holder = current; ret = power_supply_register(&pdev->dev, &dev_info->bat); if (ret) { @@ -809,8 +797,6 @@ static int __devinit ds2780_battery_probe(struct platform_device *pdev) goto fail_remove_bin_file; } - dev_info->mutex_holder = NULL; - return 0; fail_remove_bin_file: @@ -830,8 +816,6 @@ static int __devexit ds2780_battery_remove(struct platform_device *pdev) { struct ds2780_device_info *dev_info = platform_get_drvdata(pdev); - dev_info->mutex_holder = current; - /* remove attributes */ sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group); diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c index 81b720107c3a..69f8aa3a6a4b 100644 --- a/drivers/power/pda_power.c +++ b/drivers/power/pda_power.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -39,8 +38,9 @@ static struct timer_list supply_timer; static struct timer_list polling_timer; static int polling; +#ifdef CONFIG_USB_OTG_UTILS static struct otg_transceiver *transceiver; -static struct notifier_block otg_nb; +#endif static struct regulator *ac_draw; enum { @@ -222,42 +222,7 @@ static void polling_timer_func(unsigned long unused) #ifdef CONFIG_USB_OTG_UTILS static int otg_is_usb_online(void) { - return (transceiver->last_event == USB_EVENT_VBUS || - transceiver->last_event == USB_EVENT_ENUMERATED); -} - -static int otg_is_ac_online(void) -{ - return (transceiver->last_event == USB_EVENT_CHARGER); -} - -static int otg_handle_notification(struct notifier_block *nb, - unsigned long event, void *unused) -{ - switch (event) { - case USB_EVENT_CHARGER: - ac_status = PDA_PSY_TO_CHANGE; - break; - case USB_EVENT_VBUS: - case USB_EVENT_ENUMERATED: - usb_status = PDA_PSY_TO_CHANGE; - break; - case USB_EVENT_NONE: - ac_status = PDA_PSY_TO_CHANGE; - usb_status = PDA_PSY_TO_CHANGE; - break; - default: - return NOTIFY_OK; - } - - /* - * Wait a bit before reading ac/usb line status and setting charger, - * because ac/usb status readings may lag from irq. - */ - mod_timer(&charger_timer, - jiffies + msecs_to_jiffies(pdata->wait_for_status)); - - return NOTIFY_OK; + return (transceiver->state == OTG_STATE_B_PERIPHERAL); } #endif @@ -317,14 +282,6 @@ static int pda_power_probe(struct platform_device *pdev) ret = PTR_ERR(ac_draw); } - transceiver = otg_get_transceiver(); - if (transceiver && !pdata->is_usb_online) { - pdata->is_usb_online = otg_is_usb_online; - } - if (transceiver && !pdata->is_ac_online) { - pdata->is_ac_online = otg_is_ac_online; - } - if (pdata->is_ac_online) { ret = power_supply_register(&pdev->dev, &pda_psy_ac); if (ret) { @@ -346,6 +303,13 @@ static int pda_power_probe(struct platform_device *pdev) } } +#ifdef CONFIG_USB_OTG_UTILS + transceiver = otg_get_transceiver(); + if (transceiver && !pdata->is_usb_online) { + pdata->is_usb_online = otg_is_usb_online; + } +#endif + if (pdata->is_usb_online) { ret = power_supply_register(&pdev->dev, &pda_psy_usb); if (ret) { @@ -367,16 +331,6 @@ static int pda_power_probe(struct platform_device *pdev) } } - if (transceiver && pdata->use_otg_notifier) { - otg_nb.notifier_call = otg_handle_notification; - ret = otg_register_notifier(transceiver, &otg_nb); - if (ret) { - dev_err(dev, "failure to register otg notifier\n"); - goto otg_reg_notifier_failed; - } - polling = 0; - } - if (polling) { dev_dbg(dev, "will poll for status\n"); setup_timer(&polling_timer, polling_timer_func, 0); @@ -389,17 +343,16 @@ static int pda_power_probe(struct platform_device *pdev) return 0; -otg_reg_notifier_failed: - if (pdata->is_usb_online && usb_irq) - free_irq(usb_irq->start, &pda_psy_usb); usb_irq_failed: if (pdata->is_usb_online) power_supply_unregister(&pda_psy_usb); usb_supply_failed: if (pdata->is_ac_online && ac_irq) free_irq(ac_irq->start, &pda_psy_ac); +#ifdef CONFIG_USB_OTG_UTILS if (transceiver) otg_put_transceiver(transceiver); +#endif ac_irq_failed: if (pdata->is_ac_online) power_supply_unregister(&pda_psy_ac); diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c index 03810ce5633f..329b46b2327d 100644 --- a/drivers/power/power_supply_core.c +++ b/drivers/power/power_supply_core.c @@ -41,40 +41,23 @@ static int __power_supply_changed_work(struct device *dev, void *data) static void power_supply_changed_work(struct work_struct *work) { - unsigned long flags; struct power_supply *psy = container_of(work, struct power_supply, changed_work); dev_dbg(psy->dev, "%s\n", __func__); - spin_lock_irqsave(&psy->changed_lock, flags); - if (psy->changed) { - psy->changed = false; - spin_unlock_irqrestore(&psy->changed_lock, flags); + class_for_each_device(power_supply_class, NULL, psy, + __power_supply_changed_work); - class_for_each_device(power_supply_class, NULL, psy, - __power_supply_changed_work); + power_supply_update_leds(psy); - power_supply_update_leds(psy); - - kobject_uevent(&psy->dev->kobj, KOBJ_CHANGE); - spin_lock_irqsave(&psy->changed_lock, flags); - } - if (!psy->changed) - wake_unlock(&psy->work_wake_lock); - spin_unlock_irqrestore(&psy->changed_lock, flags); + kobject_uevent(&psy->dev->kobj, KOBJ_CHANGE); } void power_supply_changed(struct power_supply *psy) { - unsigned long flags; - dev_dbg(psy->dev, "%s\n", __func__); - spin_lock_irqsave(&psy->changed_lock, flags); - psy->changed = true; - wake_lock(&psy->work_wake_lock); - spin_unlock_irqrestore(&psy->changed_lock, flags); schedule_work(&psy->changed_work); } EXPORT_SYMBOL_GPL(power_supply_changed); @@ -198,9 +181,6 @@ int power_supply_register(struct device *parent, struct power_supply *psy) if (rc) goto device_add_failed; - spin_lock_init(&psy->changed_lock); - wake_lock_init(&psy->work_wake_lock, WAKE_LOCK_SUSPEND, "power-supply"); - rc = power_supply_create_triggers(psy); if (rc) goto create_triggers_failed; @@ -210,7 +190,6 @@ int power_supply_register(struct device *parent, struct power_supply *psy) goto success; create_triggers_failed: - wake_lock_destroy(&psy->work_wake_lock); device_del(dev); kobject_set_name_failed: device_add_failed: @@ -224,7 +203,6 @@ void power_supply_unregister(struct power_supply *psy) { cancel_work_sync(&psy->changed_work); power_supply_remove_triggers(psy); - wake_lock_destroy(&psy->work_wake_lock); device_unregister(psy->dev); } EXPORT_SYMBOL_GPL(power_supply_unregister); diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index 10451a15e828..cf3f9997546d 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -101,9 +101,7 @@ static s32 scaled_ppm_to_ppb(long ppm) static int ptp_clock_getres(struct posix_clock *pc, struct timespec *tp) { - tp->tv_sec = 0; - tp->tv_nsec = 1; - return 0; + return 1; /* always round timer functions to one nanosecond */ } static int ptp_clock_settime(struct posix_clock *pc, const struct timespec *tp) diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index ebe77dd87daf..ee893581d4b7 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -505,7 +505,8 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, rdev->dev.dma_mask = &rdev->dma_mask; rdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - if (rdev->dst_ops & RIO_DST_OPS_DOORBELL) + if ((rdev->pef & RIO_PEF_INB_DOORBELL) && + (rdev->dst_ops & RIO_DST_OPS_DOORBELL)) rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff); diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index acda58e6ef02..d63fddb0fbb0 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -195,7 +195,7 @@ static const unsigned int LDO12_suspend_table[] = { }; static const unsigned int LDO13_table[] = { - 1200000, 1300000, 1800000, 2000000, 2500000, 2800000, 3000000, 0, + 1300000, 1800000, 2000000, 2500000, 2800000, 3000000, 0, 0, }; static const unsigned int LDO13_suspend_table[] = { @@ -388,10 +388,10 @@ static struct pm8607_regulator_info pm8607_regulator_info[] = { PM8607_LDO( 7, LDO7, 0, 3, SUPPLIES_EN12, 1), PM8607_LDO( 8, LDO8, 0, 3, SUPPLIES_EN12, 2), PM8607_LDO( 9, LDO9, 0, 3, SUPPLIES_EN12, 3), - PM8607_LDO(10, LDO10, 0, 4, SUPPLIES_EN12, 4), + PM8607_LDO(10, LDO10, 0, 3, SUPPLIES_EN12, 4), PM8607_LDO(12, LDO12, 0, 4, SUPPLIES_EN12, 5), PM8607_LDO(13, VIBRATOR_SET, 1, 3, VIBRATOR_SET, 0), - PM8607_LDO(14, LDO14, 0, 3, SUPPLIES_EN12, 6), + PM8607_LDO(14, LDO14, 0, 4, SUPPLIES_EN12, 6), }; static int __devinit pm8607_regulator_probe(struct platform_device *pdev) diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index a8fb668c03a8..ad6628ca94f4 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -688,7 +688,7 @@ static int max8997_set_voltage_buck(struct regulator_dev *rdev, } new_val++; - } while (desc->min + desc->step * new_val <= desc->max); + } while (desc->min + desc->step + new_val <= desc->max); new_idx = tmp_idx; new_val = tmp_val; diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c index 229b6f4bb8b4..9166aa0a9df7 100644 --- a/drivers/regulator/tps6524x-regulator.c +++ b/drivers/regulator/tps6524x-regulator.c @@ -481,7 +481,7 @@ static int set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, if (i >= info->n_voltages) i = info->n_voltages - 1; - *selector = i; + *selector = info->voltages[i]; return write_field(hw, &info->voltage, i); } diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 425aab38981e..55dd4e6650db 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -759,13 +759,8 @@ static int tps65910_list_voltage_dcdc(struct regulator_dev *dev, mult = (selector / VDD1_2_NUM_VOLTS) + 1; volt = VDD1_2_MIN_VOLT + (selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET; - break; case TPS65911_REG_VDDCTRL: volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET); - break; - default: - BUG(); - return -EINVAL; } return volt * 100 * mult; @@ -903,11 +898,9 @@ static __devinit int tps65910_probe(struct platform_device *pdev) case TPS65910: pmic->get_ctrl_reg = &tps65910_get_ctrl_register; info = tps65910_regs; - break; case TPS65911: pmic->get_ctrl_reg = &tps65911_get_ctrl_register; info = tps65911_regs; - break; default: pr_err("Invalid tps chip version\n"); return -ENODEV; diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 27c37743e2c9..ce2aabf5c550 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -106,24 +106,6 @@ config RTC_INTF_DEV_UIE_EMUL clock several times per second, please enable this option only if you know that you really need it. -config RTC_INTF_ALARM - bool "Android alarm driver" - depends on RTC_CLASS - default y - help - Provides non-wakeup and rtc backed wakeup alarms based on rtc or - elapsed realtime, and a non-wakeup alarm on the monotonic clock. - Also provides an interface to set the wall time which must be used - for elapsed realtime to work. - -config RTC_INTF_ALARM_DEV - bool "Android alarm device" - depends on RTC_INTF_ALARM - default y - help - Exports the alarm interface to user-space. - - config RTC_DRV_TEST tristate "Test driver/device" help diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 7d2795810431..0ffefe877bfa 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -9,8 +9,6 @@ obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o obj-$(CONFIG_RTC_CLASS) += rtc-core.o rtc-core-y := class.o interface.o -obj-$(CONFIG_RTC_INTF_ALARM) += alarm.o -obj-$(CONFIG_RTC_INTF_ALARM_DEV) += alarm-dev.o rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o diff --git a/drivers/rtc/alarm-dev.c b/drivers/rtc/alarm-dev.c deleted file mode 100644 index 686e6f7ed480..000000000000 --- a/drivers/rtc/alarm-dev.c +++ /dev/null @@ -1,286 +0,0 @@ -/* drivers/rtc/alarm-dev.c - * - * Copyright (C) 2007-2009 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ANDROID_ALARM_PRINT_INFO (1U << 0) -#define ANDROID_ALARM_PRINT_IO (1U << 1) -#define ANDROID_ALARM_PRINT_INT (1U << 2) - -static int debug_mask = ANDROID_ALARM_PRINT_INFO; -module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); - -#define pr_alarm(debug_level_mask, args...) \ - do { \ - if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) { \ - pr_info(args); \ - } \ - } while (0) - -#define ANDROID_ALARM_WAKEUP_MASK ( \ - ANDROID_ALARM_RTC_WAKEUP_MASK | \ - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) - -/* support old usespace code */ -#define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) /* set alarm */ -#define ANDROID_ALARM_SET_AND_WAIT_OLD _IOW('a', 3, time_t) - -static int alarm_opened; -static DEFINE_SPINLOCK(alarm_slock); -static struct wake_lock alarm_wake_lock; -static DECLARE_WAIT_QUEUE_HEAD(alarm_wait_queue); -static uint32_t alarm_pending; -static uint32_t alarm_enabled; -static uint32_t wait_pending; - -static struct alarm alarms[ANDROID_ALARM_TYPE_COUNT]; - -static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - int rv = 0; - unsigned long flags; - struct timespec new_alarm_time; - struct timespec new_rtc_time; - struct timespec tmp_time; - enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); - uint32_t alarm_type_mask = 1U << alarm_type; - - if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) - return -EINVAL; - - if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { - if ((file->f_flags & O_ACCMODE) == O_RDONLY) - return -EPERM; - if (file->private_data == NULL && - cmd != ANDROID_ALARM_SET_RTC) { - spin_lock_irqsave(&alarm_slock, flags); - if (alarm_opened) { - spin_unlock_irqrestore(&alarm_slock, flags); - return -EBUSY; - } - alarm_opened = 1; - file->private_data = (void *)1; - spin_unlock_irqrestore(&alarm_slock, flags); - } - } - - switch (ANDROID_ALARM_BASE_CMD(cmd)) { - case ANDROID_ALARM_CLEAR(0): - spin_lock_irqsave(&alarm_slock, flags); - pr_alarm(IO, "alarm %d clear\n", alarm_type); - alarm_try_to_cancel(&alarms[alarm_type]); - if (alarm_pending) { - alarm_pending &= ~alarm_type_mask; - if (!alarm_pending && !wait_pending) - wake_unlock(&alarm_wake_lock); - } - alarm_enabled &= ~alarm_type_mask; - spin_unlock_irqrestore(&alarm_slock, flags); - break; - - case ANDROID_ALARM_SET_OLD: - case ANDROID_ALARM_SET_AND_WAIT_OLD: - if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) { - rv = -EFAULT; - goto err1; - } - new_alarm_time.tv_nsec = 0; - goto from_old_alarm_set; - - case ANDROID_ALARM_SET_AND_WAIT(0): - case ANDROID_ALARM_SET(0): - if (copy_from_user(&new_alarm_time, (void __user *)arg, - sizeof(new_alarm_time))) { - rv = -EFAULT; - goto err1; - } -from_old_alarm_set: - spin_lock_irqsave(&alarm_slock, flags); - pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type, - new_alarm_time.tv_sec, new_alarm_time.tv_nsec); - alarm_enabled |= alarm_type_mask; - alarm_start_range(&alarms[alarm_type], - timespec_to_ktime(new_alarm_time), - timespec_to_ktime(new_alarm_time)); - spin_unlock_irqrestore(&alarm_slock, flags); - if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) - && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD) - break; - /* fall though */ - case ANDROID_ALARM_WAIT: - spin_lock_irqsave(&alarm_slock, flags); - pr_alarm(IO, "alarm wait\n"); - if (!alarm_pending && wait_pending) { - wake_unlock(&alarm_wake_lock); - wait_pending = 0; - } - spin_unlock_irqrestore(&alarm_slock, flags); - rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); - if (rv) - goto err1; - spin_lock_irqsave(&alarm_slock, flags); - rv = alarm_pending; - wait_pending = 1; - alarm_pending = 0; - spin_unlock_irqrestore(&alarm_slock, flags); - break; - case ANDROID_ALARM_SET_RTC: - if (copy_from_user(&new_rtc_time, (void __user *)arg, - sizeof(new_rtc_time))) { - rv = -EFAULT; - goto err1; - } - rv = alarm_set_rtc(new_rtc_time); - spin_lock_irqsave(&alarm_slock, flags); - alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; - wake_up(&alarm_wait_queue); - spin_unlock_irqrestore(&alarm_slock, flags); - if (rv < 0) - goto err1; - break; - case ANDROID_ALARM_GET_TIME(0): - switch (alarm_type) { - case ANDROID_ALARM_RTC_WAKEUP: - case ANDROID_ALARM_RTC: - getnstimeofday(&tmp_time); - break; - case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: - case ANDROID_ALARM_ELAPSED_REALTIME: - tmp_time = - ktime_to_timespec(alarm_get_elapsed_realtime()); - break; - case ANDROID_ALARM_TYPE_COUNT: - case ANDROID_ALARM_SYSTEMTIME: - ktime_get_ts(&tmp_time); - break; - } - if (copy_to_user((void __user *)arg, &tmp_time, - sizeof(tmp_time))) { - rv = -EFAULT; - goto err1; - } - break; - - default: - rv = -EINVAL; - goto err1; - } -err1: - return rv; -} - -static int alarm_open(struct inode *inode, struct file *file) -{ - file->private_data = NULL; - return 0; -} - -static int alarm_release(struct inode *inode, struct file *file) -{ - int i; - unsigned long flags; - - spin_lock_irqsave(&alarm_slock, flags); - if (file->private_data != 0) { - for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { - uint32_t alarm_type_mask = 1U << i; - if (alarm_enabled & alarm_type_mask) { - pr_alarm(INFO, "alarm_release: clear alarm, " - "pending %d\n", - !!(alarm_pending & alarm_type_mask)); - alarm_enabled &= ~alarm_type_mask; - } - spin_unlock_irqrestore(&alarm_slock, flags); - alarm_cancel(&alarms[i]); - spin_lock_irqsave(&alarm_slock, flags); - } - if (alarm_pending | wait_pending) { - if (alarm_pending) - pr_alarm(INFO, "alarm_release: clear " - "pending alarms %x\n", alarm_pending); - wake_unlock(&alarm_wake_lock); - wait_pending = 0; - alarm_pending = 0; - } - alarm_opened = 0; - } - spin_unlock_irqrestore(&alarm_slock, flags); - return 0; -} - -static void alarm_triggered(struct alarm *alarm) -{ - unsigned long flags; - uint32_t alarm_type_mask = 1U << alarm->type; - - pr_alarm(INT, "alarm_triggered type %d\n", alarm->type); - spin_lock_irqsave(&alarm_slock, flags); - if (alarm_enabled & alarm_type_mask) { - wake_lock_timeout(&alarm_wake_lock, 5 * HZ); - alarm_enabled &= ~alarm_type_mask; - alarm_pending |= alarm_type_mask; - wake_up(&alarm_wait_queue); - } - spin_unlock_irqrestore(&alarm_slock, flags); -} - -static const struct file_operations alarm_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = alarm_ioctl, - .open = alarm_open, - .release = alarm_release, -}; - -static struct miscdevice alarm_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "alarm", - .fops = &alarm_fops, -}; - -static int __init alarm_dev_init(void) -{ - int err; - int i; - - err = misc_register(&alarm_device); - if (err) - return err; - - for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) - alarm_init(&alarms[i], i, alarm_triggered); - wake_lock_init(&alarm_wake_lock, WAKE_LOCK_SUSPEND, "alarm"); - - return 0; -} - -static void __exit alarm_dev_exit(void) -{ - misc_deregister(&alarm_device); - wake_lock_destroy(&alarm_wake_lock); -} - -module_init(alarm_dev_init); -module_exit(alarm_dev_exit); - diff --git a/drivers/rtc/alarm.c b/drivers/rtc/alarm.c deleted file mode 100644 index 28b0df836a30..000000000000 --- a/drivers/rtc/alarm.c +++ /dev/null @@ -1,590 +0,0 @@ -/* drivers/rtc/alarm.c - * - * Copyright (C) 2007-2009 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ANDROID_ALARM_PRINT_ERROR (1U << 0) -#define ANDROID_ALARM_PRINT_INIT_STATUS (1U << 1) -#define ANDROID_ALARM_PRINT_TSET (1U << 2) -#define ANDROID_ALARM_PRINT_CALL (1U << 3) -#define ANDROID_ALARM_PRINT_SUSPEND (1U << 4) -#define ANDROID_ALARM_PRINT_INT (1U << 5) -#define ANDROID_ALARM_PRINT_FLOW (1U << 6) - -static int debug_mask = ANDROID_ALARM_PRINT_ERROR | \ - ANDROID_ALARM_PRINT_INIT_STATUS; -module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); - -#define pr_alarm(debug_level_mask, args...) \ - do { \ - if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) { \ - pr_info(args); \ - } \ - } while (0) - -#define ANDROID_ALARM_WAKEUP_MASK ( \ - ANDROID_ALARM_RTC_WAKEUP_MASK | \ - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) - -/* support old usespace code */ -#define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) /* set alarm */ -#define ANDROID_ALARM_SET_AND_WAIT_OLD _IOW('a', 3, time_t) - -struct alarm_queue { - struct rb_root alarms; - struct rb_node *first; - struct hrtimer timer; - ktime_t delta; - bool stopped; - ktime_t stopped_time; -}; - -static struct rtc_device *alarm_rtc_dev; -static DEFINE_SPINLOCK(alarm_slock); -static DEFINE_MUTEX(alarm_setrtc_mutex); -static struct wake_lock alarm_rtc_wake_lock; -static struct platform_device *alarm_platform_dev; -struct alarm_queue alarms[ANDROID_ALARM_TYPE_COUNT]; -static bool suspended; - -static void update_timer_locked(struct alarm_queue *base, bool head_removed) -{ - struct alarm *alarm; - bool is_wakeup = base == &alarms[ANDROID_ALARM_RTC_WAKEUP] || - base == &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]; - - if (base->stopped) { - pr_alarm(FLOW, "changed alarm while setting the wall time\n"); - return; - } - - if (is_wakeup && !suspended && head_removed) - wake_unlock(&alarm_rtc_wake_lock); - - if (!base->first) - return; - - alarm = container_of(base->first, struct alarm, node); - - pr_alarm(FLOW, "selected alarm, type %d, func %pF at %lld\n", - alarm->type, alarm->function, ktime_to_ns(alarm->expires)); - - if (is_wakeup && suspended) { - pr_alarm(FLOW, "changed alarm while suspened\n"); - wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ); - return; - } - - hrtimer_try_to_cancel(&base->timer); - base->timer.node.expires = ktime_add(base->delta, alarm->expires); - base->timer._softexpires = ktime_add(base->delta, alarm->softexpires); - hrtimer_start_expires(&base->timer, HRTIMER_MODE_ABS); -} - -static void alarm_enqueue_locked(struct alarm *alarm) -{ - struct alarm_queue *base = &alarms[alarm->type]; - struct rb_node **link = &base->alarms.rb_node; - struct rb_node *parent = NULL; - struct alarm *entry; - int leftmost = 1; - bool was_first = false; - - pr_alarm(FLOW, "added alarm, type %d, func %pF at %lld\n", - alarm->type, alarm->function, ktime_to_ns(alarm->expires)); - - if (base->first == &alarm->node) { - base->first = rb_next(&alarm->node); - was_first = true; - } - if (!RB_EMPTY_NODE(&alarm->node)) { - rb_erase(&alarm->node, &base->alarms); - RB_CLEAR_NODE(&alarm->node); - } - - while (*link) { - parent = *link; - entry = rb_entry(parent, struct alarm, node); - /* - * We dont care about collisions. Nodes with - * the same expiry time stay together. - */ - if (alarm->expires.tv64 < entry->expires.tv64) { - link = &(*link)->rb_left; - } else { - link = &(*link)->rb_right; - leftmost = 0; - } - } - if (leftmost) - base->first = &alarm->node; - if (leftmost || was_first) - update_timer_locked(base, was_first); - - rb_link_node(&alarm->node, parent, link); - rb_insert_color(&alarm->node, &base->alarms); -} - -/** - * alarm_init - initialize an alarm - * @alarm: the alarm to be initialized - * @type: the alarm type to be used - * @function: alarm callback function - */ -void alarm_init(struct alarm *alarm, - enum android_alarm_type type, void (*function)(struct alarm *)) -{ - RB_CLEAR_NODE(&alarm->node); - alarm->type = type; - alarm->function = function; - - pr_alarm(FLOW, "created alarm, type %d, func %pF\n", type, function); -} - - -/** - * alarm_start_range - (re)start an alarm - * @alarm: the alarm to be added - * @start: earliest expiry time - * @end: expiry time - */ -void alarm_start_range(struct alarm *alarm, ktime_t start, ktime_t end) -{ - unsigned long flags; - - spin_lock_irqsave(&alarm_slock, flags); - alarm->softexpires = start; - alarm->expires = end; - alarm_enqueue_locked(alarm); - spin_unlock_irqrestore(&alarm_slock, flags); -} - -/** - * alarm_try_to_cancel - try to deactivate an alarm - * @alarm: alarm to stop - * - * Returns: - * 0 when the alarm was not active - * 1 when the alarm was active - * -1 when the alarm may currently be excuting the callback function and - * cannot be stopped (it may also be inactive) - */ -int alarm_try_to_cancel(struct alarm *alarm) -{ - struct alarm_queue *base = &alarms[alarm->type]; - unsigned long flags; - bool first = false; - int ret = 0; - - spin_lock_irqsave(&alarm_slock, flags); - if (!RB_EMPTY_NODE(&alarm->node)) { - pr_alarm(FLOW, "canceled alarm, type %d, func %pF at %lld\n", - alarm->type, alarm->function, - ktime_to_ns(alarm->expires)); - ret = 1; - if (base->first == &alarm->node) { - base->first = rb_next(&alarm->node); - first = true; - } - rb_erase(&alarm->node, &base->alarms); - RB_CLEAR_NODE(&alarm->node); - if (first) - update_timer_locked(base, true); - } else - pr_alarm(FLOW, "tried to cancel alarm, type %d, func %pF\n", - alarm->type, alarm->function); - spin_unlock_irqrestore(&alarm_slock, flags); - if (!ret && hrtimer_callback_running(&base->timer)) - ret = -1; - return ret; -} - -/** - * alarm_cancel - cancel an alarm and wait for the handler to finish. - * @alarm: the alarm to be cancelled - * - * Returns: - * 0 when the alarm was not active - * 1 when the alarm was active - */ -int alarm_cancel(struct alarm *alarm) -{ - for (;;) { - int ret = alarm_try_to_cancel(alarm); - if (ret >= 0) - return ret; - cpu_relax(); - } -} - -/** - * alarm_set_rtc - set the kernel and rtc walltime - * @new_time: timespec value containing the new time - */ -int alarm_set_rtc(struct timespec new_time) -{ - int i; - int ret; - unsigned long flags; - struct rtc_time rtc_new_rtc_time; - struct timespec tmp_time; - - rtc_time_to_tm(new_time.tv_sec, &rtc_new_rtc_time); - - pr_alarm(TSET, "set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n", - new_time.tv_sec, new_time.tv_nsec, - rtc_new_rtc_time.tm_hour, rtc_new_rtc_time.tm_min, - rtc_new_rtc_time.tm_sec, rtc_new_rtc_time.tm_mon + 1, - rtc_new_rtc_time.tm_mday, - rtc_new_rtc_time.tm_year + 1900); - - mutex_lock(&alarm_setrtc_mutex); - spin_lock_irqsave(&alarm_slock, flags); - wake_lock(&alarm_rtc_wake_lock); - getnstimeofday(&tmp_time); - for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { - hrtimer_try_to_cancel(&alarms[i].timer); - alarms[i].stopped = true; - alarms[i].stopped_time = timespec_to_ktime(tmp_time); - } - alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta = - alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta = - ktime_sub(alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta, - timespec_to_ktime(timespec_sub(tmp_time, new_time))); - spin_unlock_irqrestore(&alarm_slock, flags); - ret = do_settimeofday(&new_time); - spin_lock_irqsave(&alarm_slock, flags); - for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { - alarms[i].stopped = false; - update_timer_locked(&alarms[i], false); - } - spin_unlock_irqrestore(&alarm_slock, flags); - if (ret < 0) { - pr_alarm(ERROR, "alarm_set_rtc: Failed to set time\n"); - goto err; - } - if (!alarm_rtc_dev) { - pr_alarm(ERROR, - "alarm_set_rtc: no RTC, time will be lost on reboot\n"); - goto err; - } - ret = rtc_set_time(alarm_rtc_dev, &rtc_new_rtc_time); - if (ret < 0) - pr_alarm(ERROR, "alarm_set_rtc: " - "Failed to set RTC, time will be lost on reboot\n"); -err: - wake_unlock(&alarm_rtc_wake_lock); - mutex_unlock(&alarm_setrtc_mutex); - return ret; -} - -/** - * alarm_get_elapsed_realtime - get the elapsed real time in ktime_t format - * - * returns the time in ktime_t format - */ -ktime_t alarm_get_elapsed_realtime(void) -{ - ktime_t now; - unsigned long flags; - struct alarm_queue *base = &alarms[ANDROID_ALARM_ELAPSED_REALTIME]; - - spin_lock_irqsave(&alarm_slock, flags); - now = base->stopped ? base->stopped_time : ktime_get_real(); - now = ktime_sub(now, base->delta); - spin_unlock_irqrestore(&alarm_slock, flags); - return now; -} - -static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) -{ - struct alarm_queue *base; - struct alarm *alarm; - unsigned long flags; - ktime_t now; - - spin_lock_irqsave(&alarm_slock, flags); - - base = container_of(timer, struct alarm_queue, timer); - now = base->stopped ? base->stopped_time : hrtimer_cb_get_time(timer); - now = ktime_sub(now, base->delta); - - pr_alarm(INT, "alarm_timer_triggered type %d at %lld\n", - base - alarms, ktime_to_ns(now)); - - while (base->first) { - alarm = container_of(base->first, struct alarm, node); - if (alarm->softexpires.tv64 > now.tv64) { - pr_alarm(FLOW, "don't call alarm, %pF, %lld (s %lld)\n", - alarm->function, ktime_to_ns(alarm->expires), - ktime_to_ns(alarm->softexpires)); - break; - } - base->first = rb_next(&alarm->node); - rb_erase(&alarm->node, &base->alarms); - RB_CLEAR_NODE(&alarm->node); - pr_alarm(CALL, "call alarm, type %d, func %pF, %lld (s %lld)\n", - alarm->type, alarm->function, - ktime_to_ns(alarm->expires), - ktime_to_ns(alarm->softexpires)); - spin_unlock_irqrestore(&alarm_slock, flags); - alarm->function(alarm); - spin_lock_irqsave(&alarm_slock, flags); - } - if (!base->first) - pr_alarm(FLOW, "no more alarms of type %d\n", base - alarms); - update_timer_locked(base, true); - spin_unlock_irqrestore(&alarm_slock, flags); - return HRTIMER_NORESTART; -} - -static void alarm_triggered_func(void *p) -{ - struct rtc_device *rtc = alarm_rtc_dev; - if (!(rtc->irq_data & RTC_AF)) - return; - pr_alarm(INT, "rtc alarm triggered\n"); - wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ); -} - -static int alarm_suspend(struct platform_device *pdev, pm_message_t state) -{ - int err = 0; - unsigned long flags; - struct rtc_wkalrm rtc_alarm; - struct rtc_time rtc_current_rtc_time; - unsigned long rtc_current_time; - unsigned long rtc_alarm_time; - struct timespec rtc_delta; - struct timespec wall_time; - struct alarm_queue *wakeup_queue = NULL; - struct alarm_queue *tmp_queue = NULL; - - pr_alarm(SUSPEND, "alarm_suspend(%p, %d)\n", pdev, state.event); - - spin_lock_irqsave(&alarm_slock, flags); - suspended = true; - spin_unlock_irqrestore(&alarm_slock, flags); - - hrtimer_cancel(&alarms[ANDROID_ALARM_RTC_WAKEUP].timer); - hrtimer_cancel(&alarms[ - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].timer); - - tmp_queue = &alarms[ANDROID_ALARM_RTC_WAKEUP]; - if (tmp_queue->first) - wakeup_queue = tmp_queue; - tmp_queue = &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]; - if (tmp_queue->first && (!wakeup_queue || - hrtimer_get_expires(&tmp_queue->timer).tv64 < - hrtimer_get_expires(&wakeup_queue->timer).tv64)) - wakeup_queue = tmp_queue; - if (wakeup_queue) { - rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); - getnstimeofday(&wall_time); - rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time); - set_normalized_timespec(&rtc_delta, - wall_time.tv_sec - rtc_current_time, - wall_time.tv_nsec); - - rtc_alarm_time = timespec_sub(ktime_to_timespec( - hrtimer_get_expires(&wakeup_queue->timer)), - rtc_delta).tv_sec; - - rtc_time_to_tm(rtc_alarm_time, &rtc_alarm.time); - rtc_alarm.enabled = 1; - rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); - rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); - rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time); - pr_alarm(SUSPEND, - "rtc alarm set at %ld, now %ld, rtc delta %ld.%09ld\n", - rtc_alarm_time, rtc_current_time, - rtc_delta.tv_sec, rtc_delta.tv_nsec); - if (rtc_current_time + 1 >= rtc_alarm_time) { - pr_alarm(SUSPEND, "alarm about to go off\n"); - memset(&rtc_alarm, 0, sizeof(rtc_alarm)); - rtc_alarm.enabled = 0; - rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); - - spin_lock_irqsave(&alarm_slock, flags); - suspended = false; - wake_lock_timeout(&alarm_rtc_wake_lock, 2 * HZ); - update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP], - false); - update_timer_locked(&alarms[ - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP], false); - err = -EBUSY; - spin_unlock_irqrestore(&alarm_slock, flags); - } - } - return err; -} - -static int alarm_resume(struct platform_device *pdev) -{ - struct rtc_wkalrm alarm; - unsigned long flags; - - pr_alarm(SUSPEND, "alarm_resume(%p)\n", pdev); - - memset(&alarm, 0, sizeof(alarm)); - alarm.enabled = 0; - rtc_set_alarm(alarm_rtc_dev, &alarm); - - spin_lock_irqsave(&alarm_slock, flags); - suspended = false; - update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP], false); - update_timer_locked(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP], - false); - spin_unlock_irqrestore(&alarm_slock, flags); - - return 0; -} - -static struct rtc_task alarm_rtc_task = { - .func = alarm_triggered_func -}; - -static int rtc_alarm_add_device(struct device *dev, - struct class_interface *class_intf) -{ - int err; - struct rtc_device *rtc = to_rtc_device(dev); - - mutex_lock(&alarm_setrtc_mutex); - - if (alarm_rtc_dev) { - err = -EBUSY; - goto err1; - } - - alarm_platform_dev = - platform_device_register_simple("alarm", -1, NULL, 0); - if (IS_ERR(alarm_platform_dev)) { - err = PTR_ERR(alarm_platform_dev); - goto err2; - } - err = rtc_irq_register(rtc, &alarm_rtc_task); - if (err) - goto err3; - alarm_rtc_dev = rtc; - pr_alarm(INIT_STATUS, "using rtc device, %s, for alarms", rtc->name); - mutex_unlock(&alarm_setrtc_mutex); - - return 0; - -err3: - platform_device_unregister(alarm_platform_dev); -err2: -err1: - mutex_unlock(&alarm_setrtc_mutex); - return err; -} - -static void rtc_alarm_remove_device(struct device *dev, - struct class_interface *class_intf) -{ - if (dev == &alarm_rtc_dev->dev) { - pr_alarm(INIT_STATUS, "lost rtc device for alarms"); - rtc_irq_unregister(alarm_rtc_dev, &alarm_rtc_task); - platform_device_unregister(alarm_platform_dev); - alarm_rtc_dev = NULL; - } -} - -static struct class_interface rtc_alarm_interface = { - .add_dev = &rtc_alarm_add_device, - .remove_dev = &rtc_alarm_remove_device, -}; - -static struct platform_driver alarm_driver = { - .suspend = alarm_suspend, - .resume = alarm_resume, - .driver = { - .name = "alarm" - } -}; - -static int __init alarm_late_init(void) -{ - unsigned long flags; - struct timespec tmp_time, system_time; - - /* this needs to run after the rtc is read at boot */ - spin_lock_irqsave(&alarm_slock, flags); - /* We read the current rtc and system time so we can later calulate - * elasped realtime to be (boot_systemtime + rtc - boot_rtc) == - * (rtc - (boot_rtc - boot_systemtime)) - */ - getnstimeofday(&tmp_time); - ktime_get_ts(&system_time); - alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta = - alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta = - timespec_to_ktime(timespec_sub(tmp_time, system_time)); - - spin_unlock_irqrestore(&alarm_slock, flags); - return 0; -} - -static int __init alarm_driver_init(void) -{ - int err; - int i; - - for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { - hrtimer_init(&alarms[i].timer, - CLOCK_REALTIME, HRTIMER_MODE_ABS); - alarms[i].timer.function = alarm_timer_triggered; - } - hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].timer, - CLOCK_MONOTONIC, HRTIMER_MODE_ABS); - alarms[ANDROID_ALARM_SYSTEMTIME].timer.function = alarm_timer_triggered; - err = platform_driver_register(&alarm_driver); - if (err < 0) - goto err1; - wake_lock_init(&alarm_rtc_wake_lock, WAKE_LOCK_SUSPEND, "alarm_rtc"); - rtc_alarm_interface.class = rtc_class; - err = class_interface_register(&rtc_alarm_interface); - if (err < 0) - goto err2; - - return 0; - -err2: - wake_lock_destroy(&alarm_rtc_wake_lock); - platform_driver_unregister(&alarm_driver); -err1: - return err; -} - -static void __exit alarm_exit(void) -{ - class_interface_unregister(&rtc_alarm_interface); - wake_lock_destroy(&alarm_rtc_wake_lock); - platform_driver_unregister(&alarm_driver); -} - -late_initcall(alarm_late_init); -module_init(alarm_driver_init); -module_exit(alarm_exit); - diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index b82a1554cdc1..4194e59e14cd 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -41,41 +41,20 @@ static void rtc_device_release(struct device *dev) * system's wall clock; restore it on resume(). */ -static struct timespec old_rtc, old_system, old_delta; - +static time_t oldtime; +static struct timespec oldts; static int rtc_suspend(struct device *dev, pm_message_t mesg) { struct rtc_device *rtc = to_rtc_device(dev); struct rtc_time tm; - struct timespec delta, delta_delta; + if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) return 0; - /* snapshot the current RTC and system time at suspend*/ rtc_read_time(rtc, &tm); - getnstimeofday(&old_system); - rtc_tm_to_time(&tm, &old_rtc.tv_sec); - - - /* - * To avoid drift caused by repeated suspend/resumes, - * which each can add ~1 second drift error, - * try to compensate so the difference in system time - * and rtc time stays close to constant. - */ - delta = timespec_sub(old_system, old_rtc); - delta_delta = timespec_sub(delta, old_delta); - if (delta_delta.tv_sec < -2 || delta_delta.tv_sec >= 2) { - /* - * if delta_delta is too large, assume time correction - * has occured and set old_delta to the current delta. - */ - old_delta = delta; - } else { - /* Otherwise try to adjust old_system to compensate */ - old_system = timespec_sub(old_system, delta_delta); - } + ktime_get_ts(&oldts); + rtc_tm_to_time(&tm, &oldtime); return 0; } @@ -84,42 +63,32 @@ static int rtc_resume(struct device *dev) { struct rtc_device *rtc = to_rtc_device(dev); struct rtc_time tm; - struct timespec new_system, new_rtc; - struct timespec sleep_time; + time_t newtime; + struct timespec time; + struct timespec newts; if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) return 0; - /* snapshot the current rtc and system time at resume */ - getnstimeofday(&new_system); + ktime_get_ts(&newts); rtc_read_time(rtc, &tm); if (rtc_valid_tm(&tm) != 0) { pr_debug("%s: bogus resume time\n", dev_name(&rtc->dev)); return 0; } - rtc_tm_to_time(&tm, &new_rtc.tv_sec); - new_rtc.tv_nsec = 0; - - if (new_rtc.tv_sec < old_rtc.tv_sec) { - pr_debug("%s: time travel!\n", dev_name(&rtc->dev)); + rtc_tm_to_time(&tm, &newtime); + if (newtime <= oldtime) { + if (newtime < oldtime) + pr_debug("%s: time travel!\n", dev_name(&rtc->dev)); return 0; } + /* calculate the RTC time delta */ + set_normalized_timespec(&time, newtime - oldtime, 0); + + /* subtract kernel time between rtc_suspend to rtc_resume */ + time = timespec_sub(time, timespec_sub(newts, oldts)); - /* calculate the RTC time delta (sleep time)*/ - sleep_time = timespec_sub(new_rtc, old_rtc); - - /* - * Since these RTC suspend/resume handlers are not called - * at the very end of suspend or the start of resume, - * some run-time may pass on either sides of the sleep time - * so subtract kernel run-time between rtc_suspend to rtc_resume - * to keep things accurate. - */ - sleep_time = timespec_sub(sleep_time, - timespec_sub(new_system, old_system)); - - if (sleep_time.tv_sec >= 0) - timekeeping_inject_sleeptime(&sleep_time); + timekeeping_inject_sleeptime(&time); return 0; } diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 636a2ec21810..df68618f6dbb 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -227,11 +227,11 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) alarm->time.tm_hour = now.tm_hour; /* For simplicity, only support date rollover for now */ - if (alarm->time.tm_mday < 1 || alarm->time.tm_mday > 31) { + if (alarm->time.tm_mday == -1) { alarm->time.tm_mday = now.tm_mday; missing = day; } - if ((unsigned)alarm->time.tm_mon >= 12) { + if (alarm->time.tm_mon == -1) { alarm->time.tm_mon = now.tm_mon; if (missing == none) missing = month; @@ -636,29 +636,6 @@ void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task) } EXPORT_SYMBOL_GPL(rtc_irq_unregister); -static int rtc_update_hrtimer(struct rtc_device *rtc, int enabled) -{ - /* - * We unconditionally cancel the timer here, because otherwise - * we could run into BUG_ON(timer->state != HRTIMER_STATE_CALLBACK); - * when we manage to start the timer before the callback - * returns HRTIMER_RESTART. - * - * We cannot use hrtimer_cancel() here as a running callback - * could be blocked on rtc->irq_task_lock and hrtimer_cancel() - * would spin forever. - */ - if (hrtimer_try_to_cancel(&rtc->pie_timer) < 0) - return -1; - - if (enabled) { - ktime_t period = ktime_set(0, NSEC_PER_SEC / rtc->irq_freq); - - hrtimer_start(&rtc->pie_timer, period, HRTIMER_MODE_REL); - } - return 0; -} - /** * rtc_irq_set_state - enable/disable 2^N Hz periodic IRQs * @rtc: the rtc device @@ -674,21 +651,21 @@ int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled int err = 0; unsigned long flags; -retry: spin_lock_irqsave(&rtc->irq_task_lock, flags); if (rtc->irq_task != NULL && task == NULL) err = -EBUSY; if (rtc->irq_task != task) err = -EACCES; - if (!err) { - if (rtc_update_hrtimer(rtc, enabled) < 0) { - spin_unlock_irqrestore(&rtc->irq_task_lock, flags); - cpu_relax(); - goto retry; - } - rtc->pie_enabled = enabled; + + if (enabled) { + ktime_t period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq); + hrtimer_start(&rtc->pie_timer, period, HRTIMER_MODE_REL); + } else { + hrtimer_cancel(&rtc->pie_timer); } + rtc->pie_enabled = enabled; spin_unlock_irqrestore(&rtc->irq_task_lock, flags); + return err; } EXPORT_SYMBOL_GPL(rtc_irq_set_state); @@ -708,20 +685,22 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) int err = 0; unsigned long flags; - if (freq <= 0 || freq > RTC_MAX_FREQ) + if (freq <= 0) return -EINVAL; -retry: + spin_lock_irqsave(&rtc->irq_task_lock, flags); if (rtc->irq_task != NULL && task == NULL) err = -EBUSY; if (rtc->irq_task != task) err = -EACCES; - if (!err) { + if (err == 0) { rtc->irq_freq = freq; - if (rtc->pie_enabled && rtc_update_hrtimer(rtc, 1) < 0) { - spin_unlock_irqrestore(&rtc->irq_task_lock, flags); - cpu_relax(); - goto retry; + if (rtc->pie_enabled) { + ktime_t period; + hrtimer_cancel(&rtc->pie_timer); + period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq); + hrtimer_start(&rtc->pie_timer, period, + HRTIMER_MODE_REL); } } spin_unlock_irqrestore(&rtc->irq_task_lock, flags); @@ -762,14 +741,6 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) return 0; } -static void rtc_alarm_disable(struct rtc_device *rtc) -{ - if (!rtc->ops || !rtc->ops->alarm_irq_enable) - return; - - rtc->ops->alarm_irq_enable(rtc->dev.parent, false); -} - /** * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue * @rtc rtc device @@ -791,10 +762,8 @@ static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer) struct rtc_wkalrm alarm; int err; next = timerqueue_getnext(&rtc->timerqueue); - if (!next) { - rtc_alarm_disable(rtc); + if (!next) return; - } alarm.time = rtc_ktime_to_tm(next->expires); alarm.enabled = 1; err = __rtc_set_alarm(rtc, &alarm); @@ -856,8 +825,7 @@ again: err = __rtc_set_alarm(rtc, &alarm); if (err == -ETIME) goto again; - } else - rtc_alarm_disable(rtc); + } mutex_unlock(&rtc->ops_lock); } diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index d007609555c0..2dd3c0163272 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c @@ -391,8 +391,6 @@ static int dryice_rtc_probe(struct platform_device *pdev) if (imxdi->ioaddr == NULL) return -ENOMEM; - spin_lock_init(&imxdi->irq_lock); - imxdi->irq = platform_get_irq(pdev, 0); if (imxdi->irq < 0) return imxdi->irq; diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index 627b66aa78d1..da8beb8cae51 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -494,7 +494,6 @@ isl1208_rtc_interrupt(int irq, void *data) { unsigned long timeout = jiffies + msecs_to_jiffies(1000); struct i2c_client *client = data; - struct rtc_device *rtc = i2c_get_clientdata(client); int handled = 0, sr, err; /* @@ -517,8 +516,6 @@ isl1208_rtc_interrupt(int irq, void *data) if (sr & ISL1208_REG_SR_ALM) { dev_dbg(&client->dev, "alarm!\n"); - rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF); - /* Clear the alarm */ sr &= ~ISL1208_REG_SR_ALM; sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr); diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 64aedd8cc095..eda128fc1d38 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -357,19 +357,10 @@ static int m41t80_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t) static struct rtc_class_ops m41t80_rtc_ops = { .read_time = m41t80_rtc_read_time, .set_time = m41t80_rtc_set_time, - /* - * XXX - m41t80 alarm functionality is reported broken. - * until it is fixed, don't register alarm functions. - * .read_alarm = m41t80_rtc_read_alarm, .set_alarm = m41t80_rtc_set_alarm, - */ .proc = m41t80_rtc_proc, - /* - * See above comment on broken alarm - * .alarm_irq_enable = m41t80_rtc_alarm_irq_enable, - */ }; #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 51603543def6..39e41fbdf08b 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -191,11 +191,10 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id) struct platform_device *pdev = dev_id; struct rtc_plat_data *pdata = platform_get_drvdata(pdev); void __iomem *ioaddr = pdata->ioaddr; - unsigned long flags; u32 status; u32 events = 0; - spin_lock_irqsave(&pdata->rtc->irq_lock, flags); + spin_lock_irq(&pdata->rtc->irq_lock); status = readw(ioaddr + RTC_RTCISR) & readw(ioaddr + RTC_RTCIENR); /* clear interrupt sources */ writew(status, ioaddr + RTC_RTCISR); @@ -218,7 +217,7 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id) rtc_update_alarm(&pdev->dev, &pdata->g_rtc_alarm); rtc_update_irq(pdata->rtc, 1, events); - spin_unlock_irqrestore(&pdata->rtc->irq_lock, flags); + spin_unlock_irq(&pdata->rtc->irq_lock); return IRQ_HANDLED; } diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 1e80a48057e5..ff1b84bd9bb5 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c @@ -312,7 +312,6 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) int ret; struct pl031_local *ldata; struct rtc_class_ops *ops = id->data; - unsigned long time; ret = amba_request_regions(adev, NULL); if (ret) @@ -340,27 +339,11 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) dev_dbg(&adev->dev, "revision = 0x%01x\n", ldata->hw_revision); /* Enable the clockwatch on ST Variants */ - if (ldata->hw_designer == AMBA_VENDOR_ST) + if ((ldata->hw_designer == AMBA_VENDOR_ST) && + (ldata->hw_revision > 1)) writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN, ldata->base + RTC_CR); - /* - * On ST PL031 variants, the RTC reset value does not provide correct - * weekday for 2000-01-01. Correct the erroneous sunday to saturday. - */ - if (ldata->hw_designer == AMBA_VENDOR_ST) { - if (readl(ldata->base + RTC_YDR) == 0x2000) { - time = readl(ldata->base + RTC_DR); - if ((time & - (RTC_MON_MASK | RTC_MDAY_MASK | RTC_WDAY_MASK)) - == 0x02120000) { - time = time | (0x7 << RTC_WDAY_SHIFT); - writel(0x2000, ldata->base + RTC_YLR); - writel(time, ldata->base + RTC_LR); - } - } - } - ldata->rtc = rtc_device_register("pl031", &adev->dev, ops, THIS_MODULE); if (IS_ERR(ldata->rtc)) { diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c index 15e6d5cb1115..368d0e63cf83 100644 --- a/drivers/rtc/rtc-rs5c348.c +++ b/drivers/rtc/rtc-rs5c348.c @@ -121,12 +121,9 @@ rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm) tm->tm_min = bcd2bin(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK); tm->tm_hour = bcd2bin(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK); if (!pdata->rtc_24h) { - if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) { - tm->tm_hour -= 20; - tm->tm_hour %= 12; + tm->tm_hour %= 12; + if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) tm->tm_hour += 12; - } else - tm->tm_hour %= 12; } tm->tm_wday = bcd2bin(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK); tm->tm_mday = bcd2bin(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK); diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c index 75259fe38602..2fc31aac3f4e 100644 --- a/drivers/rtc/rtc-tegra.c +++ b/drivers/rtc/rtc-tegra.c @@ -343,7 +343,7 @@ static int __devinit tegra_rtc_probe(struct platform_device *pdev) /* set context info. */ info->pdev = pdev; - spin_lock_init(&info->tegra_rtc_lock); + info->tegra_rtc_lock = __SPIN_LOCK_UNLOCKED(info->tegra_rtc_lock); platform_set_drvdata(pdev, info); diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index 5e4e725440ac..f9a2799c44d6 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -490,11 +490,6 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev) goto out2; } - /* ensure interrupts are disabled, bootloaders can be strange */ - ret = twl_rtc_write_u8(0, REG_RTC_INTERRUPTS_REG); - if (ret < 0) - dev_warn(&pdev->dev, "unable to disable interrupt\n"); - /* init cached IRQ enable bits */ ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG); if (ret < 0) diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c index 8a16f2c737a5..efd6066b5cd2 100644 --- a/drivers/rtc/rtc-vt8500.c +++ b/drivers/rtc/rtc-vt8500.c @@ -69,7 +69,7 @@ | ALARM_SEC_BIT) #define VT8500_RTC_CR_ENABLE (1 << 0) /* Enable RTC */ -#define VT8500_RTC_CR_12H (1 << 1) /* 12h time format */ +#define VT8500_RTC_CR_24H (1 << 1) /* 24h time format */ #define VT8500_RTC_CR_SM_ENABLE (1 << 2) /* Enable periodic irqs */ #define VT8500_RTC_CR_SM_SEC (1 << 3) /* 0: 1Hz/60, 1: 1Hz */ #define VT8500_RTC_CR_CALIB (1 << 4) /* Enable calibration */ @@ -116,7 +116,7 @@ static int vt8500_rtc_read_time(struct device *dev, struct rtc_time *tm) tm->tm_min = bcd2bin((time & TIME_MIN_MASK) >> TIME_MIN_S); tm->tm_hour = bcd2bin((time & TIME_HOUR_MASK) >> TIME_HOUR_S); tm->tm_mday = bcd2bin(date & DATE_DAY_MASK); - tm->tm_mon = bcd2bin((date & DATE_MONTH_MASK) >> DATE_MONTH_S) - 1; + tm->tm_mon = bcd2bin((date & DATE_MONTH_MASK) >> DATE_MONTH_S); tm->tm_year = bcd2bin((date & DATE_YEAR_MASK) >> DATE_YEAR_S) + ((date >> DATE_CENTURY_S) & 1 ? 200 : 100); tm->tm_wday = (time & TIME_DOW_MASK) >> TIME_DOW_S; @@ -135,9 +135,8 @@ static int vt8500_rtc_set_time(struct device *dev, struct rtc_time *tm) } writel((bin2bcd(tm->tm_year - 100) << DATE_YEAR_S) - | (bin2bcd(tm->tm_mon + 1) << DATE_MONTH_S) - | (bin2bcd(tm->tm_mday)) - | ((tm->tm_year >= 200) << DATE_CENTURY_S), + | (bin2bcd(tm->tm_mon) << DATE_MONTH_S) + | (bin2bcd(tm->tm_mday)), vt8500_rtc->regbase + VT8500_RTC_DS); writel((bin2bcd(tm->tm_wday) << TIME_DOW_S) | (bin2bcd(tm->tm_hour) << TIME_HOUR_S) @@ -247,7 +246,7 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev) } /* Enable RTC and set it to 24-hour mode */ - writel(VT8500_RTC_CR_ENABLE, + writel(VT8500_RTC_CR_ENABLE | VT8500_RTC_CR_24H, vt8500_rtc->regbase + VT8500_RTC_CR); vt8500_rtc->rtc = rtc_device_register("vt8500-rtc", &pdev->dev, diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c index f3c211099a14..bdc909bd56da 100644 --- a/drivers/rtc/rtc-wm831x.c +++ b/drivers/rtc/rtc-wm831x.c @@ -24,7 +24,7 @@ #include #include #include -#include + /* * R16416 (0x4020) - RTC Write Counter @@ -96,26 +96,6 @@ struct wm831x_rtc { unsigned int alarm_enabled:1; }; -static void wm831x_rtc_add_randomness(struct wm831x *wm831x) -{ - int ret; - u16 reg; - - /* - * The write counter contains a pseudo-random number which is - * regenerated every time we set the RTC so it should be a - * useful per-system source of entropy. - */ - ret = wm831x_reg_read(wm831x, WM831X_RTC_WRITE_COUNTER); - if (ret >= 0) { - reg = ret; - add_device_randomness(®, sizeof(reg)); - } else { - dev_warn(wm831x->dev, "Failed to read RTC write counter: %d\n", - ret); - } -} - /* * Read current time and date in RTC */ @@ -469,8 +449,6 @@ static int wm831x_rtc_probe(struct platform_device *pdev) alm_irq, ret); } - wm831x_rtc_add_randomness(wm831x); - return 0; err: diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index cc2dd7fb289f..30fb979d684d 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -18,12 +18,12 @@ #include /* HDIO_GETGEO */ #include #include -#include #include #include #include #include +#include #include #include #include diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index 9caeaea5d099..72261e4c516d 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c @@ -13,7 +13,6 @@ #define KMSG_COMPONENT "dasd" #include -#include #include #include #include diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index 2150824303a5..f6489eb7e976 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index 84e569c9c150..31a3ccbb6495 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index cda9bd6e48e8..5c567414c4bb 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -87,12 +87,6 @@ static void __ccwgroup_remove_cdev_refs(struct ccwgroup_device *gdev) } } -static ssize_t ccwgroup_online_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count); -static ssize_t ccwgroup_online_show(struct device *dev, - struct device_attribute *attr, - char *buf); /* * Provide an 'ungroup' attribute so the user can remove group devices no * longer needed or accidentially created. Saves memory :) @@ -140,20 +134,6 @@ out: } static DEVICE_ATTR(ungroup, 0200, NULL, ccwgroup_ungroup_store); -static DEVICE_ATTR(online, 0644, ccwgroup_online_show, ccwgroup_online_store); - -static struct attribute *ccwgroup_attrs[] = { - &dev_attr_online.attr, - &dev_attr_ungroup.attr, - NULL, -}; -static struct attribute_group ccwgroup_attr_group = { - .attrs = ccwgroup_attrs, -}; -static const struct attribute_group *ccwgroup_attr_groups[] = { - &ccwgroup_attr_group, - NULL, -}; static void ccwgroup_release (struct device *dev) @@ -313,17 +293,25 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id, } dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev)); - gdev->dev.groups = ccwgroup_attr_groups; + rc = device_add(&gdev->dev); if (rc) goto error; get_device(&gdev->dev); + rc = device_create_file(&gdev->dev, &dev_attr_ungroup); + + if (rc) { + device_unregister(&gdev->dev); + goto error; + } + rc = __ccwgroup_create_symlinks(gdev); if (!rc) { mutex_unlock(&gdev->reg_mutex); put_device(&gdev->dev); return 0; } + device_remove_file(&gdev->dev, &dev_attr_ungroup); device_unregister(&gdev->dev); error: for (i = 0; i < num_devices; i++) @@ -435,7 +423,7 @@ ccwgroup_online_store (struct device *dev, struct device_attribute *attr, const int ret; if (!dev->driver) - return -EINVAL; + return -ENODEV; gdev = to_ccwgroupdev(dev); gdrv = to_ccwgroupdrv(dev->driver); @@ -468,6 +456,8 @@ ccwgroup_online_show (struct device *dev, struct device_attribute *attr, char *b return sprintf(buf, online ? "1\n" : "0\n"); } +static DEVICE_ATTR(online, 0644, ccwgroup_online_show, ccwgroup_online_store); + static int ccwgroup_probe (struct device *dev) { @@ -479,7 +469,12 @@ ccwgroup_probe (struct device *dev) gdev = to_ccwgroupdev(dev); gdrv = to_ccwgroupdrv(dev->driver); + if ((ret = device_create_file(dev, &dev_attr_online))) + return ret; + ret = gdrv->probe ? gdrv->probe(gdev) : -ENODEV; + if (ret) + device_remove_file(dev, &dev_attr_online); return ret; } @@ -490,6 +485,9 @@ ccwgroup_remove (struct device *dev) struct ccwgroup_device *gdev; struct ccwgroup_driver *gdrv; + device_remove_file(dev, &dev_attr_online); + device_remove_file(dev, &dev_attr_ungroup); + if (!dev->driver) return 0; diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index ec760297dd38..e950f1ad4dd1 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c @@ -8,7 +8,6 @@ */ #include -#include #include #include #include diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index daa6b903aa91..07a4fd29f096 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c @@ -234,7 +234,7 @@ static int pgid_cmp(struct pgid *p1, struct pgid *p2) * Determine pathgroup state from PGID data. */ static void pgid_analyze(struct ccw_device *cdev, struct pgid **p, - int *mismatch, u8 *reserved, u8 *reset) + int *mismatch, int *reserved, u8 *reset) { struct pgid *pgid = &cdev->private->pgid[0]; struct pgid *first = NULL; @@ -248,7 +248,7 @@ static void pgid_analyze(struct ccw_device *cdev, struct pgid **p, if ((cdev->private->pgid_valid_mask & lpm) == 0) continue; if (pgid->inf.ps.state2 == SNID_STATE2_RESVD_ELSE) - *reserved |= lpm; + *reserved = 1; if (pgid_is_reset(pgid)) { *reset |= lpm; continue; @@ -316,14 +316,14 @@ static void snid_done(struct ccw_device *cdev, int rc) struct subchannel *sch = to_subchannel(cdev->dev.parent); struct pgid *pgid; int mismatch = 0; - u8 reserved = 0; + int reserved = 0; u8 reset = 0; u8 donepm; if (rc) goto out; pgid_analyze(cdev, &pgid, &mismatch, &reserved, &reset); - if (reserved == cdev->private->pgid_valid_mask) + if (reserved) rc = -EUSERS; else if (mismatch) rc = -EOPNOTSUPP; @@ -336,7 +336,7 @@ static void snid_done(struct ccw_device *cdev, int rc) } out: CIO_MSG_EVENT(2, "snid: device 0.%x.%04x: rc=%d pvm=%02x vpm=%02x " - "todo=%02x mism=%d rsvd=%02x reset=%02x\n", id->ssid, + "todo=%02x mism=%d rsvd=%d reset=%02x\n", id->ssid, id->devno, rc, cdev->private->pgid_valid_mask, sch->vpm, cdev->private->pgid_todo_mask, mismatch, reserved, reset); switch (rc) { diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c index 68be6e157126..5c4e741d8221 100644 --- a/drivers/s390/cio/qdio_thinint.c +++ b/drivers/s390/cio/qdio_thinint.c @@ -95,11 +95,9 @@ void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr) } } -static inline u32 clear_shared_ind(void) +static inline u32 shared_ind_set(void) { - if (!atomic_read(&q_indicators[TIQDIO_SHARED_IND].count)) - return 0; - return xchg(&q_indicators[TIQDIO_SHARED_IND].ind, 0); + return q_indicators[TIQDIO_SHARED_IND].ind; } /** @@ -109,7 +107,7 @@ static inline u32 clear_shared_ind(void) */ static void tiqdio_thinint_handler(void *alsi, void *data) { - u32 si_used = clear_shared_ind(); + u32 si_used = shared_ind_set(); struct qdio_q *q; last_ai_time = S390_lowcore.int_clock; @@ -152,6 +150,13 @@ static void tiqdio_thinint_handler(void *alsi, void *data) qperf_inc(q, adapter_int); } rcu_read_unlock(); + + /* + * If the shared indicator was used clear it now after all queues + * were processed. + */ + if (si_used && shared_ind_set()) + xchg(&q_indicators[TIQDIO_SHARED_IND].ind, 0); } static int set_subchannel_ind(struct qdio_irq *irq_ptr, int reset) diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index e2c9ac5fcb36..fd69da3fa6b4 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2742,14 +2742,9 @@ static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) int inline qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb) { int cast_type = RTN_UNSPEC; - struct neighbour *n = NULL; - struct dst_entry *dst; - - dst = skb_dst(skb); - if (dst) - n = dst_get_neighbour(dst); - if (n) { - cast_type = n->type; + + if (skb_dst(skb) && skb_dst(skb)->neighbour) { + cast_type = skb_dst(skb)->neighbour->type; if ((cast_type == RTN_BROADCAST) || (cast_type == RTN_MULTICAST) || (cast_type == RTN_ANYCAST)) @@ -2792,9 +2787,6 @@ int inline qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb) static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, struct sk_buff *skb, int ipv, int cast_type) { - struct neighbour *n = NULL; - struct dst_entry *dst; - memset(hdr, 0, sizeof(struct qeth_hdr)); hdr->hdr.l3.id = QETH_HEADER_TYPE_LAYER3; hdr->hdr.l3.ext_flags = 0; @@ -2812,16 +2804,13 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, } hdr->hdr.l3.length = skb->len - sizeof(struct qeth_hdr); - dst = skb_dst(skb); - if (dst) - n = dst_get_neighbour(dst); if (ipv == 4) { /* IPv4 */ hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags4(cast_type); memset(hdr->hdr.l3.dest_addr, 0, 12); - if (n) { + if ((skb_dst(skb)) && (skb_dst(skb)->neighbour)) { *((u32 *) (&hdr->hdr.l3.dest_addr[12])) = - *((u32 *) n->primary_key); + *((u32 *) skb_dst(skb)->neighbour->primary_key); } else { /* fill in destination address used in ip header */ *((u32 *) (&hdr->hdr.l3.dest_addr[12])) = @@ -2832,9 +2821,9 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags6(cast_type); if (card->info.type == QETH_CARD_TYPE_IQD) hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU; - if (n) { + if ((skb_dst(skb)) && (skb_dst(skb)->neighbour)) { memcpy(hdr->hdr.l3.dest_addr, - n->primary_key, 16); + skb_dst(skb)->neighbour->primary_key, 16); } else { /* fill in destination address used in ip header */ memcpy(hdr->hdr.l3.dest_addr, diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 61da2cd22508..645b0fcbb370 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -518,7 +518,6 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, rwlock_init(&port->unit_list_lock); INIT_LIST_HEAD(&port->unit_list); - atomic_set(&port->units, 0); INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup); INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work); diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index de1bcfa23f35..e8b7cee62046 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c @@ -38,23 +38,17 @@ void zfcp_ccw_adapter_put(struct zfcp_adapter *adapter) spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags); } -/** - * zfcp_ccw_activate - activate adapter and wait for it to finish - * @cdev: pointer to belonging ccw device - * @clear: Status flags to clear. - * @tag: s390dbf trace record tag - */ -static int zfcp_ccw_activate(struct ccw_device *cdev, int clear, char *tag) +static int zfcp_ccw_activate(struct ccw_device *cdev) + { struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); if (!adapter) return 0; - zfcp_erp_clear_adapter_status(adapter, clear); zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING); zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, - tag); + "ccresu2"); zfcp_erp_wait(adapter); flush_work(&adapter->scan_work); @@ -169,47 +163,32 @@ static int zfcp_ccw_set_online(struct ccw_device *cdev) BUG_ON(!zfcp_reqlist_isempty(adapter->req_list)); adapter->req_no = 0; - zfcp_ccw_activate(cdev, 0, "ccsonl1"); + zfcp_ccw_activate(cdev); zfcp_ccw_adapter_put(adapter); return 0; } /** - * zfcp_ccw_offline_sync - shut down adapter and wait for it to finish + * zfcp_ccw_set_offline - set_offline function of zfcp driver * @cdev: pointer to belonging ccw device - * @set: Status flags to set. - * @tag: s390dbf trace record tag * * This function gets called by the common i/o layer and sets an adapter * into state offline. */ -static int zfcp_ccw_offline_sync(struct ccw_device *cdev, int set, char *tag) +static int zfcp_ccw_set_offline(struct ccw_device *cdev) { struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); if (!adapter) return 0; - zfcp_erp_set_adapter_status(adapter, set); - zfcp_erp_adapter_shutdown(adapter, 0, tag); + zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1"); zfcp_erp_wait(adapter); zfcp_ccw_adapter_put(adapter); return 0; } -/** - * zfcp_ccw_set_offline - set_offline function of zfcp driver - * @cdev: pointer to belonging ccw device - * - * This function gets called by the common i/o layer and sets an adapter - * into state offline. - */ -static int zfcp_ccw_set_offline(struct ccw_device *cdev) -{ - return zfcp_ccw_offline_sync(cdev, 0, "ccsoff1"); -} - /** * zfcp_ccw_notify - ccw notify function * @cdev: pointer to belonging ccw device @@ -227,11 +206,6 @@ static int zfcp_ccw_notify(struct ccw_device *cdev, int event) switch (event) { case CIO_GONE: - if (atomic_read(&adapter->status) & - ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */ - zfcp_dbf_hba_basic("ccnigo1", adapter); - break; - } dev_warn(&cdev->dev, "The FCP device has been detached\n"); zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1"); break; @@ -241,11 +215,6 @@ static int zfcp_ccw_notify(struct ccw_device *cdev, int event) zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2"); break; case CIO_OPER: - if (atomic_read(&adapter->status) & - ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */ - zfcp_dbf_hba_basic("ccniop1", adapter); - break; - } dev_info(&cdev->dev, "The FCP device is operational again\n"); zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING); @@ -281,28 +250,6 @@ static void zfcp_ccw_shutdown(struct ccw_device *cdev) zfcp_ccw_adapter_put(adapter); } -static int zfcp_ccw_suspend(struct ccw_device *cdev) -{ - zfcp_ccw_offline_sync(cdev, ZFCP_STATUS_ADAPTER_SUSPENDED, "ccsusp1"); - return 0; -} - -static int zfcp_ccw_thaw(struct ccw_device *cdev) -{ - /* trace records for thaw and final shutdown during suspend - can only be found in system dump until the end of suspend - but not after resume because it's based on the memory image - right after the very first suspend (freeze) callback */ - zfcp_ccw_activate(cdev, 0, "ccthaw1"); - return 0; -} - -static int zfcp_ccw_resume(struct ccw_device *cdev) -{ - zfcp_ccw_activate(cdev, ZFCP_STATUS_ADAPTER_SUSPENDED, "ccresu1"); - return 0; -} - struct ccw_driver zfcp_ccw_driver = { .driver = { .owner = THIS_MODULE, @@ -315,7 +262,7 @@ struct ccw_driver zfcp_ccw_driver = { .set_offline = zfcp_ccw_set_offline, .notify = zfcp_ccw_notify, .shutdown = zfcp_ccw_shutdown, - .freeze = zfcp_ccw_suspend, - .thaw = zfcp_ccw_thaw, - .restore = zfcp_ccw_resume, + .freeze = zfcp_ccw_set_offline, + .thaw = zfcp_ccw_activate, + .restore = zfcp_ccw_activate, }; diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c index 8ed63aa9abea..303dde09d294 100644 --- a/drivers/s390/scsi/zfcp_cfdc.c +++ b/drivers/s390/scsi/zfcp_cfdc.c @@ -11,7 +11,6 @@ #define KMSG_COMPONENT "zfcp" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt -#include #include #include #include @@ -293,7 +292,7 @@ void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *adapter) } read_unlock_irqrestore(&adapter->port_list_lock, flags); - shost_for_each_device(sdev, adapter->scsi_host) { + shost_for_each_device(sdev, port->adapter->scsi_host) { zfcp_sdev = sdev_to_zfcp(sdev); status = atomic_read(&zfcp_sdev->status); if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) || diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 8b18dc04f068..96d1462e0bf5 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -163,26 +163,6 @@ void zfcp_dbf_hba_bit_err(char *tag, struct zfcp_fsf_req *req) spin_unlock_irqrestore(&dbf->hba_lock, flags); } -/** - * zfcp_dbf_hba_basic - trace event for basic adapter events - * @adapter: pointer to struct zfcp_adapter - */ -void zfcp_dbf_hba_basic(char *tag, struct zfcp_adapter *adapter) -{ - struct zfcp_dbf *dbf = adapter->dbf; - struct zfcp_dbf_hba *rec = &dbf->hba_buf; - unsigned long flags; - - spin_lock_irqsave(&dbf->hba_lock, flags); - memset(rec, 0, sizeof(*rec)); - - memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); - rec->id = ZFCP_DBF_HBA_BASIC; - - debug_event(dbf->hba, 1, rec, sizeof(*rec)); - spin_unlock_irqrestore(&dbf->hba_lock, flags); -} - static void zfcp_dbf_set_common(struct zfcp_dbf_rec *rec, struct zfcp_adapter *adapter, struct zfcp_port *port, diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h index 3ac7a4b30dd9..714f087eb7a9 100644 --- a/drivers/s390/scsi/zfcp_dbf.h +++ b/drivers/s390/scsi/zfcp_dbf.h @@ -154,7 +154,6 @@ enum zfcp_dbf_hba_id { ZFCP_DBF_HBA_RES = 1, ZFCP_DBF_HBA_USS = 2, ZFCP_DBF_HBA_BIT = 3, - ZFCP_DBF_HBA_BASIC = 4, }; /** diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index ebbf7606c13c..527ba48eea57 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -76,7 +76,6 @@ struct zfcp_reqlist; #define ZFCP_STATUS_ADAPTER_SIOSL_ISSUED 0x00000004 #define ZFCP_STATUS_ADAPTER_XCONFIG_OK 0x00000008 #define ZFCP_STATUS_ADAPTER_HOST_CON_INIT 0x00000010 -#define ZFCP_STATUS_ADAPTER_SUSPENDED 0x00000040 #define ZFCP_STATUS_ADAPTER_ERP_PENDING 0x00000100 #define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200 #define ZFCP_STATUS_ADAPTER_DATA_DIV_ENABLED 0x00000400 @@ -204,7 +203,6 @@ struct zfcp_port { struct zfcp_adapter *adapter; /* adapter used to access port */ struct list_head unit_list; /* head of logical unit list */ rwlock_t unit_list_lock; /* unit list lock */ - atomic_t units; /* zfcp_unit count */ atomic_t status; /* status of this remote port */ u64 wwnn; /* WWNN if known */ u64 wwpn; /* WWPN */ diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 3ad6399cc8bf..03627cfd81cd 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -53,7 +53,6 @@ extern void zfcp_dbf_hba_fsf_uss(char *, struct zfcp_fsf_req *); extern void zfcp_dbf_hba_fsf_res(char *, struct zfcp_fsf_req *); extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *); extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *); -extern void zfcp_dbf_hba_basic(char *, struct zfcp_adapter *); extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32); extern void zfcp_dbf_san_res(char *, struct zfcp_fsf_req *); extern void zfcp_dbf_san_in_els(char *, struct zfcp_fsf_req *); @@ -158,7 +157,6 @@ extern void zfcp_scsi_dif_sense_error(struct scsi_cmnd *, int); extern struct attribute_group zfcp_sysfs_unit_attrs; extern struct attribute_group zfcp_sysfs_adapter_attrs; extern struct attribute_group zfcp_sysfs_port_attrs; -extern struct mutex zfcp_sysfs_port_units_mutex; extern struct device_attribute *zfcp_sysfs_sdev_attrs[]; extern struct device_attribute *zfcp_sysfs_shost_attrs[]; diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 6e73bfe92daa..022fb6a8cb83 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -219,7 +219,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) return; } - zfcp_dbf_hba_fsf_uss("fssrh_4", req); + zfcp_dbf_hba_fsf_uss("fssrh_2", req); switch (sr_buf->status_type) { case FSF_STATUS_READ_PORT_CLOSED: @@ -771,14 +771,12 @@ out: static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req) { struct scsi_device *sdev = req->data; - struct zfcp_scsi_dev *zfcp_sdev; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); union fsf_status_qual *fsq = &req->qtcb->header.fsf_status_qual; if (req->status & ZFCP_STATUS_FSFREQ_ERROR) return; - zfcp_sdev = sdev_to_zfcp(sdev); - switch (req->qtcb->header.fsf_status) { case FSF_PORT_HANDLE_NOT_VALID: if (fsq->word[0] == fsq->word[1]) { @@ -887,7 +885,7 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req) switch (header->fsf_status) { case FSF_GOOD: - zfcp_dbf_san_res("fsscth2", req); + zfcp_dbf_san_res("fsscth1", req); ct->status = 0; break; case FSF_SERVICE_CLASS_NOT_SUPPORTED: @@ -1732,15 +1730,13 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req) { struct zfcp_adapter *adapter = req->adapter; struct scsi_device *sdev = req->data; - struct zfcp_scsi_dev *zfcp_sdev; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); struct fsf_qtcb_header *header = &req->qtcb->header; struct fsf_qtcb_bottom_support *bottom = &req->qtcb->bottom.support; if (req->status & ZFCP_STATUS_FSFREQ_ERROR) return; - zfcp_sdev = sdev_to_zfcp(sdev); - atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | ZFCP_STATUS_COMMON_ACCESS_BOXED | ZFCP_STATUS_LUN_SHARED | @@ -1851,13 +1847,11 @@ out: static void zfcp_fsf_close_lun_handler(struct zfcp_fsf_req *req) { struct scsi_device *sdev = req->data; - struct zfcp_scsi_dev *zfcp_sdev; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); if (req->status & ZFCP_STATUS_FSFREQ_ERROR) return; - zfcp_sdev = sdev_to_zfcp(sdev); - switch (req->qtcb->header.fsf_status) { case FSF_PORT_HANDLE_NOT_VALID: zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0, "fscuh_1"); @@ -1947,7 +1941,7 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi) { struct fsf_qual_latency_info *lat_in; struct latency_cont *lat = NULL; - struct zfcp_scsi_dev *zfcp_sdev; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scsi->device); struct zfcp_blk_drv_data blktrc; int ticks = req->adapter->timer_ticks; @@ -1962,7 +1956,6 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi) if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA && !(req->status & ZFCP_STATUS_FSFREQ_ERROR)) { - zfcp_sdev = sdev_to_zfcp(scsi->device); blktrc.flags |= ZFCP_BLK_LAT_VALID; blktrc.channel_lat = lat_in->channel_lat * ticks; blktrc.fabric_lat = lat_in->fabric_lat * ticks; @@ -2000,14 +1993,12 @@ static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req) { struct scsi_cmnd *scmnd = req->data; struct scsi_device *sdev = scmnd->device; - struct zfcp_scsi_dev *zfcp_sdev; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); struct fsf_qtcb_header *header = &req->qtcb->header; if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) return; - zfcp_sdev = sdev_to_zfcp(sdev); - switch (header->fsf_status) { case FSF_HANDLE_MISMATCH: case FSF_PORT_HANDLE_NOT_VALID: diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 3a417dff1b89..2a4991d6d4d5 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -57,10 +57,6 @@ static void zfcp_scsi_slave_destroy(struct scsi_device *sdev) { struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); - /* if previous slave_alloc returned early, there is nothing to do */ - if (!zfcp_sdev->port) - return; - zfcp_erp_lun_shutdown_wait(sdev, "scssd_1"); put_device(&zfcp_sdev->port->dev); } diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index 9e62210b294f..cdc4ff78a7ba 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -227,8 +227,6 @@ static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev, static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL, zfcp_sysfs_port_rescan_store); -DEFINE_MUTEX(zfcp_sysfs_port_units_mutex); - static ssize_t zfcp_sysfs_port_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -251,16 +249,6 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev, else retval = 0; - mutex_lock(&zfcp_sysfs_port_units_mutex); - if (atomic_read(&port->units) > 0) { - retval = -EBUSY; - mutex_unlock(&zfcp_sysfs_port_units_mutex); - goto out; - } - /* port is about to be removed, so no more unit_add */ - atomic_set(&port->units, -1); - mutex_unlock(&zfcp_sysfs_port_units_mutex); - write_lock_irq(&adapter->port_list_lock); list_del(&port->list); write_unlock_irq(&adapter->port_list_lock); @@ -301,14 +289,12 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev, { struct zfcp_port *port = container_of(dev, struct zfcp_port, dev); u64 fcp_lun; - int retval; if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) return -EINVAL; - retval = zfcp_unit_add(port, fcp_lun); - if (retval) - return retval; + if (zfcp_unit_add(port, fcp_lun)) + return -EINVAL; return count; } diff --git a/drivers/s390/scsi/zfcp_unit.c b/drivers/s390/scsi/zfcp_unit.c index 4e6a5356bdbd..20796ebc33ce 100644 --- a/drivers/s390/scsi/zfcp_unit.c +++ b/drivers/s390/scsi/zfcp_unit.c @@ -104,7 +104,7 @@ static void zfcp_unit_release(struct device *dev) { struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev); - atomic_dec(&unit->port->units); + put_device(&unit->port->dev); kfree(unit); } @@ -119,27 +119,16 @@ static void zfcp_unit_release(struct device *dev) int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun) { struct zfcp_unit *unit; - int retval = 0; - - mutex_lock(&zfcp_sysfs_port_units_mutex); - if (atomic_read(&port->units) == -1) { - /* port is already gone */ - retval = -ENODEV; - goto out; - } unit = zfcp_unit_find(port, fcp_lun); if (unit) { put_device(&unit->dev); - retval = -EEXIST; - goto out; + return -EEXIST; } unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL); - if (!unit) { - retval = -ENOMEM; - goto out; - } + if (!unit) + return -ENOMEM; unit->port = port; unit->fcp_lun = fcp_lun; @@ -150,33 +139,28 @@ int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun) if (dev_set_name(&unit->dev, "0x%016llx", (unsigned long long) fcp_lun)) { kfree(unit); - retval = -ENOMEM; - goto out; + return -ENOMEM; } + get_device(&port->dev); + if (device_register(&unit->dev)) { put_device(&unit->dev); - retval = -ENOMEM; - goto out; + return -ENOMEM; } if (sysfs_create_group(&unit->dev.kobj, &zfcp_sysfs_unit_attrs)) { device_unregister(&unit->dev); - retval = -EINVAL; - goto out; + return -EINVAL; } - atomic_inc(&port->units); /* under zfcp_sysfs_port_units_mutex ! */ - write_lock_irq(&port->unit_list_lock); list_add_tail(&unit->list, &port->unit_list); write_unlock_irq(&port->unit_list_lock); zfcp_unit_scsi_scan(unit); -out: - mutex_unlock(&zfcp_sysfs_port_units_mutex); - return retval; + return 0; } /** diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 3868ab2397c6..b7bd5b0cc7aa 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -1800,12 +1800,10 @@ static int twa_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_ switch (retval) { case SCSI_MLQUEUE_HOST_BUSY: twa_free_request_id(tw_dev, request_id); - twa_unmap_scsi_data(tw_dev, request_id); break; case 1: tw_dev->state[request_id] = TW_S_COMPLETED; twa_free_request_id(tw_dev, request_id); - twa_unmap_scsi_data(tw_dev, request_id); SCpnt->result = (DID_ERROR << 16); done(SCpnt); retval = 0; diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 6153a66a8a31..3c08f5352b2d 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -88,7 +88,7 @@ obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas408.o qlogicfas.o obj-$(CONFIG_PCMCIA_QLOGIC) += qlogicfas408.o obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx/ -obj-$(CONFIG_SCSI_QLA_ISCSI) += libiscsi.o qla4xxx/ +obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx/ obj-$(CONFIG_SCSI_LPFC) += lpfc/ obj-$(CONFIG_SCSI_BFA_FC) += bfa/ obj-$(CONFIG_SCSI_PAS16) += pas16.o diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index e5f2d7d9002e..e7d0d47b9185 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1283,8 +1283,6 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced) kfree(aac->queues); aac->queues = NULL; free_irq(aac->pdev->irq, aac); - if (aac->msi) - pci_disable_msi(aac->pdev); kfree(aac->fsa_dev); aac->fsa_dev = NULL; quirks = aac_get_driver_ident(index)->quirks; diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index c7b6fed88735..3382475dc22d 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -1109,9 +1108,6 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, unique_id++; } - pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | - PCIE_LINK_STATE_CLKPM); - error = pci_enable_device(pdev); if (error) goto out; diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 59fc5a1fdae0..7e6eca4a125e 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1174,16 +1174,7 @@ wait_io1: outw(val, tmport); outb(2, 0x80); TCM_SYNC: - /* - * The funny division into multiple delays is to accomodate - * arches like ARM where udelay() multiplies its argument by - * a large number to initialize a loop counter. To avoid - * overflow, the maximum supported udelay is 2000 microseconds. - * - * XXX it would be more polite to find a way to use msleep() - */ - mdelay(2); - udelay(48); + udelay(0x800); if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */ outw(0, tmport--); outb(0, tmport); diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h index 856fcbfbb7e9..0a404bfb44fe 100644 --- a/drivers/scsi/bnx2fc/bnx2fc.h +++ b/drivers/scsi/bnx2fc/bnx2fc.h @@ -152,6 +152,7 @@ struct bnx2fc_percpu_s { spinlock_t fp_work_lock; }; + struct bnx2fc_hba { struct list_head link; struct cnic_dev *cnic; @@ -178,7 +179,6 @@ struct bnx2fc_hba { #define BNX2FC_CTLR_INIT_DONE 1 #define BNX2FC_CREATE_DONE 2 struct fcoe_ctlr ctlr; - struct list_head vports; u8 vlan_enabled; int vlan_id; u32 next_conn_id; @@ -232,11 +232,6 @@ struct bnx2fc_hba { #define bnx2fc_from_ctlr(fip) container_of(fip, struct bnx2fc_hba, ctlr) -struct bnx2fc_lport { - struct list_head list; - struct fc_lport *lport; -}; - struct bnx2fc_cmd_mgr { struct bnx2fc_hba *hba; u16 next_idx; @@ -428,7 +423,6 @@ struct bnx2fc_work { struct bnx2fc_unsol_els { struct fc_lport *lport; struct fc_frame *fp; - struct bnx2fc_hba *hba; struct work_struct unsol_els_work; }; diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index bdf62a5fc192..ab255fbc7f36 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -1225,7 +1225,6 @@ static int bnx2fc_interface_setup(struct bnx2fc_hba *hba, hba->ctlr.get_src_addr = bnx2fc_get_src_mac; set_bit(BNX2FC_CTLR_INIT_DONE, &hba->init_done); - INIT_LIST_HEAD(&hba->vports); rc = bnx2fc_netdev_setup(hba); if (rc) goto setup_err; @@ -1262,15 +1261,8 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_hba *hba, struct fcoe_port *port; struct Scsi_Host *shost; struct fc_vport *vport = dev_to_vport(parent); - struct bnx2fc_lport *blport; int rc = 0; - blport = kzalloc(sizeof(struct bnx2fc_lport), GFP_KERNEL); - if (!blport) { - BNX2FC_HBA_DBG(hba->ctlr.lp, "Unable to alloc bnx2fc_lport\n"); - return NULL; - } - /* Allocate Scsi_Host structure */ if (!npiv) lport = libfc_host_alloc(&bnx2fc_shost_template, sizeof(*port)); @@ -1279,7 +1271,7 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_hba *hba, if (!lport) { printk(KERN_ERR PFX "could not allocate scsi host structure\n"); - goto free_blport; + return NULL; } shost = lport->host; port = lport_priv(lport); @@ -1335,20 +1327,12 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_hba *hba, } bnx2fc_interface_get(hba); - - spin_lock_bh(&hba->hba_lock); - blport->lport = lport; - list_add_tail(&blport->list, &hba->vports); - spin_unlock_bh(&hba->hba_lock); - return lport; shost_err: scsi_remove_host(shost); lp_config_err: scsi_host_put(lport->host); -free_blport: - kfree(blport); return NULL; } @@ -1364,7 +1348,6 @@ static void bnx2fc_if_destroy(struct fc_lport *lport) { struct fcoe_port *port = lport_priv(lport); struct bnx2fc_hba *hba = port->priv; - struct bnx2fc_lport *blport, *tmp; BNX2FC_HBA_DBG(hba->ctlr.lp, "ENTERED bnx2fc_if_destroy\n"); /* Stop the transmit retry timer */ @@ -1389,15 +1372,6 @@ static void bnx2fc_if_destroy(struct fc_lport *lport) /* Free memory used by statistical counters */ fc_lport_free_stats(lport); - spin_lock_bh(&hba->hba_lock); - list_for_each_entry_safe(blport, tmp, &hba->vports, list) { - if (blport->lport == lport) { - list_del(&blport->list); - kfree(blport); - } - } - spin_unlock_bh(&hba->hba_lock); - /* Release Scsi_Host */ scsi_host_put(lport->host); diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c index 78baa46c39cd..f756d5f85c7a 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c +++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c @@ -480,36 +480,16 @@ int bnx2fc_send_session_destroy_req(struct bnx2fc_hba *hba, return rc; } -static bool is_valid_lport(struct bnx2fc_hba *hba, struct fc_lport *lport) -{ - struct bnx2fc_lport *blport; - - spin_lock_bh(&hba->hba_lock); - list_for_each_entry(blport, &hba->vports, list) { - if (blport->lport == lport) { - spin_unlock_bh(&hba->hba_lock); - return true; - } - } - spin_unlock_bh(&hba->hba_lock); - return false; - -} - - static void bnx2fc_unsol_els_work(struct work_struct *work) { struct bnx2fc_unsol_els *unsol_els; struct fc_lport *lport; - struct bnx2fc_hba *hba; struct fc_frame *fp; unsol_els = container_of(work, struct bnx2fc_unsol_els, unsol_els_work); lport = unsol_els->lport; fp = unsol_els->fp; - hba = unsol_els->hba; - if (is_valid_lport(hba, lport)) - fc_exch_recv(lport, fp); + fc_exch_recv(lport, fp); kfree(unsol_els); } @@ -519,7 +499,6 @@ void bnx2fc_process_l2_frame_compl(struct bnx2fc_rport *tgt, { struct fcoe_port *port = tgt->port; struct fc_lport *lport = port->lport; - struct bnx2fc_hba *hba = port->priv; struct bnx2fc_unsol_els *unsol_els; struct fc_frame_header *fh; struct fc_frame *fp; @@ -580,7 +559,6 @@ void bnx2fc_process_l2_frame_compl(struct bnx2fc_rport *tgt, fr_eof(fp) = FC_EOF_T; fr_crc(fp) = cpu_to_le32(~crc); unsol_els->lport = lport; - unsol_els->hba = hba; unsol_els->fp = fp; INIT_WORK(&unsol_els->unsol_els_work, bnx2fc_unsol_els_work); queue_work(bnx2fc_wq, &unsol_els->unsol_els_work); diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index 454c72cdafbc..b5b5c346d779 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c @@ -1734,6 +1734,7 @@ void bnx2fc_process_scsi_cmd_compl(struct bnx2fc_cmd *io_req, printk(KERN_ERR PFX "SCp.ptr is NULL\n"); return; } + io_req->sc_cmd = NULL; if (io_req->on_active_queue) { list_del_init(&io_req->link); @@ -1753,7 +1754,6 @@ void bnx2fc_process_scsi_cmd_compl(struct bnx2fc_cmd *io_req, } bnx2fc_unmap_sg_list(io_req); - io_req->sc_cmd = NULL; switch (io_req->fcp_status) { case FC_GOOD: diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index ca397f80ff08..5c54a2d9b834 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -1260,9 +1260,6 @@ int bnx2i_send_fw_iscsi_init_msg(struct bnx2i_hba *hba) int rc = 0; u64 mask64; - memset(&iscsi_init, 0x00, sizeof(struct iscsi_kwqe_init1)); - memset(&iscsi_init2, 0x00, sizeof(struct iscsi_kwqe_init2)); - bnx2i_adjust_qp_size(hba); iscsi_init.flags = diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c index 143f2682bdab..fc2cdb62f53b 100644 --- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c +++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c @@ -913,7 +913,7 @@ static void l2t_put(struct cxgbi_sock *csk) struct t3cdev *t3dev = (struct t3cdev *)csk->cdev->lldev; if (csk->l2t) { - l2t_release(t3dev, csk->l2t); + l2t_release(L2DATA(t3dev), csk->l2t); csk->l2t = NULL; cxgbi_sock_put(csk); } @@ -985,7 +985,7 @@ static int init_act_open(struct cxgbi_sock *csk) csk->saddr.sin_addr.s_addr = chba->ipv4addr; csk->rss_qid = 0; - csk->l2t = t3_l2t_get(t3dev, dst_get_neighbour(dst), ndev); + csk->l2t = t3_l2t_get(t3dev, dst->neighbour, ndev); if (!csk->l2t) { pr_err("NO l2t available.\n"); return -EINVAL; diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c index ae13c4993aa3..f3a4cd7cf782 100644 --- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c +++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c @@ -1160,7 +1160,7 @@ static int init_act_open(struct cxgbi_sock *csk) cxgbi_sock_set_flag(csk, CTPF_HAS_ATID); cxgbi_sock_get(csk); - csk->l2t = cxgb4_l2t_get(lldi->l2t, dst_get_neighbour(csk->dst), ndev, 0); + csk->l2t = cxgb4_l2t_get(lldi->l2t, csk->dst->neighbour, ndev, 0); if (!csk->l2t) { pr_err("%s, cannot alloc l2t.\n", ndev->name); goto rel_resource; diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index 77ac217ad5ce..a2a9c7c6c643 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -492,7 +492,7 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr) goto err_out; } dst = &rt->dst; - ndev = dst_get_neighbour(dst)->dev; + ndev = dst->neighbour->dev; if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) { pr_info("multi-cast route %pI4, port %u, dev %s.\n", @@ -506,7 +506,7 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr) ndev = ip_dev_find(&init_net, daddr->sin_addr.s_addr); mtu = ndev->mtu; pr_info("rt dev %s, loopback -> %s, mtu %u.\n", - dst_get_neighbour(dst)->dev->name, ndev->name, mtu); + dst->neighbour->dev->name, ndev->name, mtu); } cdev = cxgbi_device_find_by_netdev(ndev, &port); diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c index d973325ded2a..0119b8147797 100644 --- a/drivers/scsi/device_handler/scsi_dh.c +++ b/drivers/scsi/device_handler/scsi_dh.c @@ -398,15 +398,7 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data) spin_lock_irqsave(q->queue_lock, flags); sdev = q->queuedata; - if (!sdev) { - spin_unlock_irqrestore(q->queue_lock, flags); - err = SCSI_DH_NOSYS; - if (fn) - fn(data, err); - return err; - } - - if (sdev->scsi_dh_data) + if (sdev && sdev->scsi_dh_data) scsi_dh = sdev->scsi_dh_data->scsi_dh; dev = get_device(&sdev->sdev_gendev); if (!scsi_dh || !dev || diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 5391e6a18529..6fec9fe5dc39 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -619,7 +619,8 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) h->state = TPGS_STATE_STANDBY; break; case TPGS_STATE_OFFLINE: - /* Path unusable */ + case TPGS_STATE_UNAVAILABLE: + /* Path unusable for unavailable/offline */ err = SCSI_DH_DEV_OFFLINED; break; default: diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index f829adcb3b79..155d7b9bdeae 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -749,27 +749,12 @@ static int fcoe_shost_config(struct fc_lport *lport, struct device *dev) * The offload EM that this routine is associated with will handle any * packets that are for SCSI read requests. * - * This has been enhanced to work when FCoE stack is operating in target - * mode. - * * Returns: True for read types I/O, otherwise returns false. */ bool fcoe_oem_match(struct fc_frame *fp) { - struct fc_frame_header *fh = fc_frame_header_get(fp); - struct fcp_cmnd *fcp; - - if (fc_fcp_is_read(fr_fsp(fp)) && - (fr_fsp(fp)->data_len > fcoe_ddp_min)) - return true; - else if (!(ntoh24(fh->fh_f_ctl) & FC_FC_EX_CTX)) { - fcp = fc_frame_payload_get(fp, sizeof(*fcp)); - if (ntohs(fh->fh_rx_id) == FC_XID_UNKNOWN && - fcp && (ntohl(fcp->fc_dl) > fcoe_ddp_min) && - (fcp->fc_flags & FCP_CFL_WRDATA)) - return true; - } - return false; + return fc_fcp_is_read(fr_fsp(fp)) && + (fr_fsp(fp)->data_len > fcoe_ddp_min); } /** @@ -1561,7 +1546,6 @@ static inline int fcoe_filter_frames(struct fc_lport *lport, stats->InvalidCRCCount++; if (stats->InvalidCRCCount < 5) printk(KERN_WARNING "fcoe: dropping frame with CRC error\n"); - put_cpu(); return -EINVAL; } diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 351dc0b86fab..4f7a5829ea4c 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -286,7 +286,6 @@ static void scsi_host_dev_release(struct device *dev) { struct Scsi_Host *shost = dev_to_shost(dev); struct device *parent = dev->parent; - struct request_queue *q; scsi_proc_hostdir_rm(shost->hostt); @@ -294,11 +293,9 @@ static void scsi_host_dev_release(struct device *dev) kthread_stop(shost->ehandler); if (shost->work_q) destroy_workqueue(shost->work_q); - q = shost->uspace_req_q; - if (q) { - kfree(q->queuedata); - q->queuedata = NULL; - scsi_free_queue(q); + if (shost->uspace_req_q) { + kfree(shost->uspace_req_q->queuedata); + scsi_free_queue(shost->uspace_req_q); } scsi_destroy_command_freelist(shost); diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 1e33d39a722e..6bba23a26303 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -677,16 +676,6 @@ static void hpsa_scsi_replace_entry(struct ctlr_info *h, int hostno, BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA); removed[*nremoved] = h->dev[entry]; (*nremoved)++; - - /* - * New physical devices won't have target/lun assigned yet - * so we need to preserve the values in the slot we are replacing. - */ - if (new_entry->target == -1) { - new_entry->target = h->dev[entry]->target; - new_entry->lun = h->dev[entry]->lun; - } - h->dev[entry] = new_entry; added[*nadded] = new_entry; (*nadded)++; @@ -1209,9 +1198,8 @@ static void complete_scsi_command(struct CommandList *cp) } break; case CMD_PROTOCOL_ERR: - cmd->result = DID_ERROR << 16; dev_warn(&h->pdev->dev, "cp %p has " - "protocol error\n", cp); + "protocol error \n", cp); break; case CMD_HARDWARE_ERR: cmd->result = DID_ERROR << 16; @@ -1560,17 +1548,10 @@ static inline void hpsa_set_bus_target_lun(struct hpsa_scsi_dev_t *device, } static int hpsa_update_device_info(struct ctlr_info *h, - unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device, - unsigned char *is_OBDR_device) + unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device) { - -#define OBDR_SIG_OFFSET 43 -#define OBDR_TAPE_SIG "$DR-10" -#define OBDR_SIG_LEN (sizeof(OBDR_TAPE_SIG) - 1) -#define OBDR_TAPE_INQ_SIZE (OBDR_SIG_OFFSET + OBDR_SIG_LEN) - +#define OBDR_TAPE_INQ_SIZE 49 unsigned char *inq_buff; - unsigned char *obdr_sig; inq_buff = kzalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); if (!inq_buff) @@ -1602,16 +1583,6 @@ static int hpsa_update_device_info(struct ctlr_info *h, else this_device->raid_level = RAID_UNKNOWN; - if (is_OBDR_device) { - /* See if this is a One-Button-Disaster-Recovery device - * by looking for "$DR-10" at offset 43 in inquiry data. - */ - obdr_sig = &inq_buff[OBDR_SIG_OFFSET]; - *is_OBDR_device = (this_device->devtype == TYPE_ROM && - strncmp(obdr_sig, OBDR_TAPE_SIG, - OBDR_SIG_LEN) == 0); - } - kfree(inq_buff); return 0; @@ -1655,26 +1626,30 @@ static void figure_bus_target_lun(struct ctlr_info *h, if (is_logical_dev_addr_mode(lunaddrbytes)) { /* logical device */ - lunid = le32_to_cpu(*((__le32 *) lunaddrbytes)); - if (is_msa2xxx(h, device)) { - /* msa2xxx way, put logicals on bus 1 - * and match target/lun numbers box - * reports. + if (unlikely(is_scsi_rev_5(h))) { + /* p1210m, logical drives lun assignments + * match SCSI REPORT LUNS data. */ - *bus = 1; - *target = (lunid >> 16) & 0x3fff; - *lun = lunid & 0x00ff; + lunid = le32_to_cpu(*((__le32 *) lunaddrbytes)); + *bus = 0; + *target = 0; + *lun = (lunid & 0x3fff) + 1; } else { - if (likely(is_scsi_rev_5(h))) { - /* All current smart arrays (circa 2011) */ - *bus = 0; - *target = 0; - *lun = (lunid & 0x3fff) + 1; + /* not p1210m... */ + lunid = le32_to_cpu(*((__le32 *) lunaddrbytes)); + if (is_msa2xxx(h, device)) { + /* msa2xxx way, put logicals on bus 1 + * and match target/lun numbers box + * reports. + */ + *bus = 1; + *target = (lunid >> 16) & 0x3fff; + *lun = lunid & 0x00ff; } else { - /* Traditional old smart array way. */ + /* Traditional smart array way. */ *bus = 0; - *target = lunid & 0x3fff; *lun = 0; + *target = lunid & 0x3fff; } } } else { @@ -1741,7 +1716,7 @@ static int add_msa2xxx_enclosure_device(struct ctlr_info *h, return 0; } - if (hpsa_update_device_info(h, scsi3addr, this_device, NULL)) + if (hpsa_update_device_info(h, scsi3addr, this_device)) return 0; (*nmsa2xxx_enclosures)++; hpsa_set_bus_target_lun(this_device, bus, target, 0); @@ -1833,6 +1808,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) */ struct ReportLUNdata *physdev_list = NULL; struct ReportLUNdata *logdev_list = NULL; + unsigned char *inq_buff = NULL; u32 nphysicals = 0; u32 nlogicals = 0; u32 ndev_allocated = 0; @@ -1848,9 +1824,11 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) GFP_KERNEL); physdev_list = kzalloc(reportlunsize, GFP_KERNEL); logdev_list = kzalloc(reportlunsize, GFP_KERNEL); + inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL); - if (!currentsd || !physdev_list || !logdev_list || !tmpdevice) { + if (!currentsd || !physdev_list || !logdev_list || + !inq_buff || !tmpdevice) { dev_err(&h->pdev->dev, "out of memory\n"); goto out; } @@ -1885,7 +1863,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) /* adjust our table of devices */ nmsa2xxx_enclosures = 0; for (i = 0; i < nphysicals + nlogicals + 1; i++) { - u8 *lunaddrbytes, is_OBDR = 0; + u8 *lunaddrbytes; /* Figure out where the LUN ID info is coming from */ lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position, @@ -1896,8 +1874,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) continue; /* Get device type, vendor, model, device id */ - if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice, - &is_OBDR)) + if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice)) continue; /* skip it if we can't talk to it. */ figure_bus_target_lun(h, lunaddrbytes, &bus, &target, &lun, tmpdevice); @@ -1921,7 +1898,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) hpsa_set_bus_target_lun(this_device, bus, target, lun); switch (this_device->devtype) { - case TYPE_ROM: + case TYPE_ROM: { /* We don't *really* support actual CD-ROM devices, * just "One Button Disaster Recovery" tape drive * which temporarily pretends to be a CD-ROM drive. @@ -1929,8 +1906,15 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) * device by checking for "$DR-10" in bytes 43-48 of * the inquiry data. */ - if (is_OBDR) - ncurrent++; + char obdr_sig[7]; +#define OBDR_TAPE_SIG "$DR-10" + strncpy(obdr_sig, &inq_buff[43], 6); + obdr_sig[6] = '\0'; + if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0) + /* Not OBDR device, ignore it. */ + break; + } + ncurrent++; break; case TYPE_DISK: if (i < nphysicals) @@ -1963,6 +1947,7 @@ out: for (i = 0; i < ndev_allocated; i++) kfree(currentsd[i]); kfree(currentsd); + kfree(inq_buff); kfree(physdev_list); kfree(logdev_list); } @@ -2893,7 +2878,7 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, c->Request.Timeout = 0; /* Don't time out */ memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB)); c->Request.CDB[0] = cmd; - c->Request.CDB[1] = HPSA_RESET_TYPE_LUN; + c->Request.CDB[1] = 0x03; /* Reset target above */ /* If bytes 4-7 are zero, it means reset the */ /* LunID device */ c->Request.CDB[4] = 0x00; @@ -3298,13 +3283,6 @@ static int hpsa_controller_hard_reset(struct pci_dev *pdev, pmcsr &= ~PCI_PM_CTRL_STATE_MASK; pmcsr |= PCI_D0; pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); - - /* - * The P600 requires a small delay when changing states. - * Otherwise we may think the board did not reset and we bail. - * This for kdump only and is particular to the P600. - */ - msleep(500); } return 0; } @@ -3885,10 +3863,6 @@ static int __devinit hpsa_pci_init(struct ctlr_info *h) dev_warn(&h->pdev->dev, "controller appears to be disabled\n"); return -ENODEV; } - - pci_disable_link_state(h->pdev, PCIE_LINK_STATE_L0S | - PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM); - err = pci_enable_device(h->pdev); if (err) { dev_warn(&h->pdev->dev, "unable to enable PCI device\n"); @@ -4034,10 +4008,10 @@ static int hpsa_request_irq(struct ctlr_info *h, if (h->msix_vector || h->msi_vector) rc = request_irq(h->intr[h->intr_mode], msixhandler, - 0, h->devname, h); + IRQF_DISABLED, h->devname, h); else rc = request_irq(h->intr[h->intr_mode], intxhandler, - IRQF_SHARED, h->devname, h); + IRQF_DISABLED, h->devname, h); if (rc) { dev_err(&h->pdev->dev, "unable to get irq %d for %s\n", h->intr[h->intr_mode], h->devname); diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h index 7f53ceaa7239..6d8dcd4dd06b 100644 --- a/drivers/scsi/hpsa.h +++ b/drivers/scsi/hpsa.h @@ -214,7 +214,7 @@ static void SA5_submit_command(struct ctlr_info *h, dev_dbg(&h->pdev->dev, "Sending %x, tag = %x\n", c->busaddr, c->Header.Tag.lower); writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); - (void) readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); + (void) readl(h->vaddr + SA5_REQUEST_PORT_OFFSET); h->commands_outstanding++; if (h->commands_outstanding > h->max_outstanding) h->max_outstanding = h->commands_outstanding; diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 36aca4b1ec00..3d391dc3f11f 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1547,9 +1547,6 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata, host_config = &evt_struct->iu.mad.host_config; - /* The transport length field is only 16-bit */ - length = min(0xffff, length); - /* Set up a lun reset SRP command */ memset(host_config, 0x00, sizeof(*host_config)); host_config->common.type = VIOSRP_HOST_CONFIG_TYPE; diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index c5c7c3abb4b9..888086c4e709 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -8812,7 +8812,7 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg32); if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT)) ioa_cfg->needs_hard_reset = 1; - if ((interrupts & IPR_PCII_ERROR_INTERRUPTS) || reset_devices) + if (interrupts & IPR_PCII_ERROR_INTERRUPTS) ioa_cfg->needs_hard_reset = 1; if (interrupts & IPR_PCII_IOA_UNIT_CHECKED) ioa_cfg->ioa_unit_checked = 1; diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c index ef46d8323377..26072f1e9852 100644 --- a/drivers/scsi/isci/host.c +++ b/drivers/scsi/isci/host.c @@ -531,9 +531,6 @@ static void sci_controller_process_completions(struct isci_host *ihost) break; case SCU_COMPLETION_TYPE_EVENT: - sci_controller_event_completion(ihost, ent); - break; - case SCU_COMPLETION_TYPE_NOTIFY: { event_cycle ^= ((event_get+1) & SCU_MAX_EVENTS) << (SMU_COMPLETION_QUEUE_GET_EVENT_CYCLE_BIT_SHIFT - SCU_MAX_EVENTS_SHIFT); diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c index 0365d580c976..61e0d09e2b57 100644 --- a/drivers/scsi/isci/init.c +++ b/drivers/scsi/isci/init.c @@ -454,10 +454,11 @@ static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_devic if (!orom) orom = isci_request_oprom(pdev); - for (i = 0; orom && i < num_controllers(pdev); i++) { + for (i = 0; orom && i < ARRAY_SIZE(orom->ctrl); i++) { if (sci_oem_parameters_validate(&orom->ctrl[i])) { dev_warn(&pdev->dev, "[%d]: invalid oem parameters detected, falling back to firmware\n", i); + devm_kfree(&pdev->dev, orom); orom = NULL; break; } diff --git a/drivers/scsi/isci/isci.h b/drivers/scsi/isci/isci.h index 8efeb6b08321..d1de63312e7f 100644 --- a/drivers/scsi/isci/isci.h +++ b/drivers/scsi/isci/isci.h @@ -97,7 +97,7 @@ #define SCU_MAX_COMPLETION_QUEUE_SHIFT (ilog2(SCU_MAX_COMPLETION_QUEUE_ENTRIES)) #define SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES (4096) -#define SCU_UNSOLICITED_FRAME_BUFFER_SIZE (1024U) +#define SCU_UNSOLICITED_FRAME_BUFFER_SIZE (1024) #define SCU_INVALID_FRAME_INDEX (0xFFFF) #define SCU_IO_REQUEST_MAX_SGE_SIZE (0x00FFFFFF) diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c index 430fc8ff014a..79313a7a2356 100644 --- a/drivers/scsi/isci/phy.c +++ b/drivers/scsi/isci/phy.c @@ -104,7 +104,6 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy, u32 parity_count = 0; u32 llctl, link_rate; u32 clksm_value = 0; - u32 sp_timeouts = 0; iphy->link_layer_registers = reg; @@ -212,18 +211,6 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy, llctl |= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE, link_rate); writel(llctl, &iphy->link_layer_registers->link_layer_control); - sp_timeouts = readl(&iphy->link_layer_registers->sas_phy_timeouts); - - /* Clear the default 0x36 (54us) RATE_CHANGE timeout value. */ - sp_timeouts &= ~SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0xFF); - - /* Set RATE_CHANGE timeout value to 0x3B (59us). This ensures SCU can - * lock with 3Gb drive when SCU max rate is set to 1.5Gb. - */ - sp_timeouts |= SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0x3B); - - writel(sp_timeouts, &iphy->link_layer_registers->sas_phy_timeouts); - if (is_a2(ihost->pdev)) { /* Program the max ARB time for the PHY to 700us so we inter-operate with * the PMC expander which shuts down PHYs if the expander PHY generates too diff --git a/drivers/scsi/isci/port_config.c b/drivers/scsi/isci/port_config.c index 38a99d281141..486b113c634a 100644 --- a/drivers/scsi/isci/port_config.c +++ b/drivers/scsi/isci/port_config.c @@ -678,7 +678,7 @@ static void apc_agent_timeout(unsigned long data) configure_phy_mask = ~port_agent->phy_configured_mask & port_agent->phy_ready_mask; if (!configure_phy_mask) - goto done; + return; for (index = 0; index < SCI_MAX_PHYS; index++) { if ((configure_phy_mask & (1 << index)) == 0) diff --git a/drivers/scsi/isci/probe_roms.c b/drivers/scsi/isci/probe_roms.c index 7cd637d501a8..b5f4341de243 100644 --- a/drivers/scsi/isci/probe_roms.c +++ b/drivers/scsi/isci/probe_roms.c @@ -104,6 +104,7 @@ struct isci_orom *isci_request_oprom(struct pci_dev *pdev) if (i >= len) { dev_err(&pdev->dev, "oprom parse error\n"); + devm_kfree(&pdev->dev, rom); rom = NULL; } pci_unmap_biosrom(oprom); diff --git a/drivers/scsi/isci/registers.h b/drivers/scsi/isci/registers.h index 00afc738bbed..9b266c7428e8 100644 --- a/drivers/scsi/isci/registers.h +++ b/drivers/scsi/isci/registers.h @@ -1299,18 +1299,6 @@ struct scu_transport_layer_registers { #define SCU_AFE_XCVRCR_OFFSET 0x00DC #define SCU_AFE_LUTCR_OFFSET 0x00E0 -#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_ALIGN_DETECTION_SHIFT (0UL) -#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_ALIGN_DETECTION_MASK (0x000000FFUL) -#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_HOT_PLUG_SHIFT (8UL) -#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_HOT_PLUG_MASK (0x0000FF00UL) -#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_COMSAS_DETECTION_SHIFT (16UL) -#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_COMSAS_DETECTION_MASK (0x00FF0000UL) -#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_RATE_CHANGE_SHIFT (24UL) -#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_RATE_CHANGE_MASK (0xFF000000UL) - -#define SCU_SAS_PHYTOV_GEN_VAL(name, value) \ - SCU_GEN_VALUE(SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_##name, value) - #define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_SHIFT (0) #define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_MASK (0x00000003) #define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1 (0) diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index b70f9992b836..a46e07ac789f 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c @@ -732,20 +732,12 @@ sci_io_request_terminate(struct isci_request *ireq) sci_change_state(&ireq->sm, SCI_REQ_ABORTING); return SCI_SUCCESS; case SCI_REQ_TASK_WAIT_TC_RESP: - /* The task frame was already confirmed to have been - * sent by the SCU HW. Since the state machine is - * now only waiting for the task response itself, - * abort the request and complete it immediately - * and don't wait for the task response. - */ sci_change_state(&ireq->sm, SCI_REQ_ABORTING); sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); return SCI_SUCCESS; case SCI_REQ_ABORTING: - /* If a request has a termination requested twice, return - * a failure indication, since HW confirmation of the first - * abort is still outstanding. - */ + sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); + return SCI_SUCCESS; case SCI_REQ_COMPLETED: default: dev_warn(&ireq->owning_controller->pdev->dev, @@ -1490,30 +1482,29 @@ sci_io_request_frame_handler(struct isci_request *ireq, return SCI_SUCCESS; case SCI_REQ_SMP_WAIT_RESP: { - struct sas_task *task = isci_request_access_task(ireq); - struct scatterlist *sg = &task->smp_task.smp_resp; - void *frame_header, *kaddr; - u8 *rsp; + struct smp_resp *rsp_hdr = &ireq->smp.rsp; + void *frame_header; sci_unsolicited_frame_control_get_header(&ihost->uf_control, - frame_index, - &frame_header); - kaddr = kmap_atomic(sg_page(sg), KM_IRQ0); - rsp = kaddr + sg->offset; - sci_swab32_cpy(rsp, frame_header, 1); + frame_index, + &frame_header); + + /* byte swap the header. */ + word_cnt = SMP_RESP_HDR_SZ / sizeof(u32); + sci_swab32_cpy(rsp_hdr, frame_header, word_cnt); - if (rsp[0] == SMP_RESPONSE) { + if (rsp_hdr->frame_type == SMP_RESPONSE) { void *smp_resp; sci_unsolicited_frame_control_get_buffer(&ihost->uf_control, - frame_index, - &smp_resp); + frame_index, + &smp_resp); + + word_cnt = (sizeof(struct smp_resp) - SMP_RESP_HDR_SZ) / + sizeof(u32); - word_cnt = (sg->length/4)-1; - if (word_cnt > 0) - word_cnt = min_t(unsigned int, word_cnt, - SCU_UNSOLICITED_FRAME_BUFFER_SIZE/4); - sci_swab32_cpy(rsp + 4, smp_resp, word_cnt); + sci_swab32_cpy(((u8 *) rsp_hdr) + SMP_RESP_HDR_SZ, + smp_resp, word_cnt); ireq->scu_status = SCU_TASK_DONE_GOOD; ireq->sci_status = SCI_SUCCESS; @@ -1529,13 +1520,12 @@ sci_io_request_frame_handler(struct isci_request *ireq, __func__, ireq, frame_index, - rsp[0]); + rsp_hdr->frame_type); ireq->scu_status = SCU_TASK_DONE_SMP_FRM_TYPE_ERR; ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR; sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); } - kunmap_atomic(kaddr, KM_IRQ0); sci_controller_release_frame(ihost, frame_index); @@ -1693,7 +1683,7 @@ sci_io_request_frame_handler(struct isci_request *ireq, frame_index, (void **)&frame_buffer); - sci_controller_copy_sata_response(&ireq->stp.rsp, + sci_controller_copy_sata_response(&ireq->stp.req, frame_header, frame_buffer); @@ -2409,19 +2399,22 @@ static void isci_task_save_for_upper_layer_completion( } } -static void isci_process_stp_response(struct sas_task *task, struct dev_to_host_fis *fis) +static void isci_request_process_stp_response(struct sas_task *task, + void *response_buffer) { + struct dev_to_host_fis *d2h_reg_fis = response_buffer; struct task_status_struct *ts = &task->task_status; struct ata_task_resp *resp = (void *)&ts->buf[0]; - resp->frame_len = sizeof(*fis); - memcpy(resp->ending_fis, fis, sizeof(*fis)); + resp->frame_len = le16_to_cpu(*(__le16 *)(response_buffer + 6)); + memcpy(&resp->ending_fis[0], response_buffer + 16, 24); ts->buf_valid_size = sizeof(*resp); - /* If the device fault bit is set in the status register, then + /** + * If the device fault bit is set in the status register, then * set the sense data and return. */ - if (fis->status & ATA_DF) + if (d2h_reg_fis->status & ATA_DF) ts->stat = SAS_PROTO_RESPONSE; else ts->stat = SAM_STAT_GOOD; @@ -2435,6 +2428,7 @@ static void isci_request_io_request_complete(struct isci_host *ihost, { struct sas_task *task = isci_request_access_task(request); struct ssp_response_iu *resp_iu; + void *resp_buf; unsigned long task_flags; struct isci_remote_device *idev = isci_lookup_device(task->dev); enum service_response response = SAS_TASK_UNDELIVERED; @@ -2571,7 +2565,9 @@ static void isci_request_io_request_complete(struct isci_host *ihost, task); if (sas_protocol_ata(task->task_proto)) { - isci_process_stp_response(task, &request->stp.rsp); + resp_buf = &request->stp.rsp; + isci_request_process_stp_response(task, + resp_buf); } else if (SAS_PROTOCOL_SSP == task->task_proto) { /* crack the iu response buffer. */ @@ -2605,7 +2601,18 @@ static void isci_request_io_request_complete(struct isci_host *ihost, status = SAM_STAT_GOOD; set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); - if (completion_status == SCI_IO_SUCCESS_IO_DONE_EARLY) { + if (task->task_proto == SAS_PROTOCOL_SMP) { + void *rsp = &request->smp.rsp; + + dev_dbg(&ihost->pdev->dev, + "%s: SMP protocol completion\n", + __func__); + + sg_copy_from_buffer( + &task->smp_task.smp_resp, 1, + rsp, sizeof(struct smp_resp)); + } else if (completion_status + == SCI_IO_SUCCESS_IO_DONE_EARLY) { /* This was an SSP / STP / SATA transfer. * There is a possibility that less data than diff --git a/drivers/scsi/isci/request.h b/drivers/scsi/isci/request.h index 58d70b6606ef..7a1d5a9778eb 100644 --- a/drivers/scsi/isci/request.h +++ b/drivers/scsi/isci/request.h @@ -173,6 +173,9 @@ struct isci_request { u8 rsp_buf[SSP_RESP_IU_MAX_SIZE]; }; } ssp; + struct { + struct smp_resp rsp; + } smp; struct { struct isci_stp_request req; struct host_to_dev_fis cmd; diff --git a/drivers/scsi/isci/sas.h b/drivers/scsi/isci/sas.h index dc26b4aea99e..462b15174d3f 100644 --- a/drivers/scsi/isci/sas.h +++ b/drivers/scsi/isci/sas.h @@ -204,6 +204,8 @@ struct smp_req { u8 req_data[0]; } __packed; +#define SMP_RESP_HDR_SZ 4 + /* * struct sci_sas_address - This structure depicts how a SAS address is * represented by SCI. diff --git a/drivers/scsi/isci/unsolicited_frame_control.c b/drivers/scsi/isci/unsolicited_frame_control.c index 16f88ab939c8..e9e1e2abacb9 100644 --- a/drivers/scsi/isci/unsolicited_frame_control.c +++ b/drivers/scsi/isci/unsolicited_frame_control.c @@ -72,7 +72,7 @@ int sci_unsolicited_frame_control_construct(struct isci_host *ihost) */ buf_len = SCU_MAX_UNSOLICITED_FRAMES * SCU_UNSOLICITED_FRAME_BUFFER_SIZE; header_len = SCU_MAX_UNSOLICITED_FRAMES * sizeof(struct scu_unsolicited_frame_header); - size = buf_len + header_len + SCU_MAX_UNSOLICITED_FRAMES * sizeof(uf_control->address_table.array[0]); + size = buf_len + header_len + SCU_MAX_UNSOLICITED_FRAMES * sizeof(dma_addr_t); /* * The Unsolicited Frame buffers are set at the start of the UF diff --git a/drivers/scsi/isci/unsolicited_frame_control.h b/drivers/scsi/isci/unsolicited_frame_control.h index 75d896686f5a..31cb9506f52d 100644 --- a/drivers/scsi/isci/unsolicited_frame_control.h +++ b/drivers/scsi/isci/unsolicited_frame_control.h @@ -214,7 +214,7 @@ struct sci_uf_address_table_array { * starting address of the UF address table. * 64-bit pointers are required by the hardware. */ - u64 *array; + dma_addr_t *array; /** * This field specifies the physical address location for the UF diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 7724414588fa..3df985305f69 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -107,12 +107,10 @@ static int iscsi_sw_tcp_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, * If the socket is in CLOSE or CLOSE_WAIT we should * not close the connection if there is still some * data pending. - * - * Must be called with sk_callback_lock. */ static inline int iscsi_sw_sk_state_check(struct sock *sk) { - struct iscsi_conn *conn = sk->sk_user_data; + struct iscsi_conn *conn = (struct iscsi_conn*)sk->sk_user_data; if ((sk->sk_state == TCP_CLOSE_WAIT || sk->sk_state == TCP_CLOSE) && !atomic_read(&sk->sk_rmem_alloc)) { @@ -125,17 +123,11 @@ static inline int iscsi_sw_sk_state_check(struct sock *sk) static void iscsi_sw_tcp_data_ready(struct sock *sk, int flag) { - struct iscsi_conn *conn; - struct iscsi_tcp_conn *tcp_conn; + struct iscsi_conn *conn = sk->sk_user_data; + struct iscsi_tcp_conn *tcp_conn = conn->dd_data; read_descriptor_t rd_desc; read_lock(&sk->sk_callback_lock); - conn = sk->sk_user_data; - if (!conn) { - read_unlock(&sk->sk_callback_lock); - return; - } - tcp_conn = conn->dd_data; /* * Use rd_desc to pass 'conn' to iscsi_tcp_recv. @@ -149,10 +141,11 @@ static void iscsi_sw_tcp_data_ready(struct sock *sk, int flag) iscsi_sw_sk_state_check(sk); + read_unlock(&sk->sk_callback_lock); + /* If we had to (atomically) map a highmem page, * unmap it now. */ iscsi_tcp_segment_unmap(&tcp_conn->in.segment); - read_unlock(&sk->sk_callback_lock); } static void iscsi_sw_tcp_state_change(struct sock *sk) @@ -164,11 +157,8 @@ static void iscsi_sw_tcp_state_change(struct sock *sk) void (*old_state_change)(struct sock *); read_lock(&sk->sk_callback_lock); - conn = sk->sk_user_data; - if (!conn) { - read_unlock(&sk->sk_callback_lock); - return; - } + + conn = (struct iscsi_conn*)sk->sk_user_data; session = conn->session; iscsi_sw_sk_state_check(sk); @@ -188,25 +178,11 @@ static void iscsi_sw_tcp_state_change(struct sock *sk) **/ static void iscsi_sw_tcp_write_space(struct sock *sk) { - struct iscsi_conn *conn; - struct iscsi_tcp_conn *tcp_conn; - struct iscsi_sw_tcp_conn *tcp_sw_conn; - void (*old_write_space)(struct sock *); - - read_lock_bh(&sk->sk_callback_lock); - conn = sk->sk_user_data; - if (!conn) { - read_unlock_bh(&sk->sk_callback_lock); - return; - } - - tcp_conn = conn->dd_data; - tcp_sw_conn = tcp_conn->dd_data; - old_write_space = tcp_sw_conn->old_write_space; - read_unlock_bh(&sk->sk_callback_lock); - - old_write_space(sk); + struct iscsi_conn *conn = (struct iscsi_conn*)sk->sk_user_data; + struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; + tcp_sw_conn->old_write_space(sk); ISCSI_SW_TCP_DBG(conn, "iscsi_write_space\n"); iscsi_conn_queue_work(conn); } @@ -616,17 +592,20 @@ static void iscsi_sw_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) /* userspace may have goofed up and not bound us */ if (!sock) return; + /* + * Make sure our recv side is stopped. + * Older tools called conn stop before ep_disconnect + * so IO could still be coming in. + */ + write_lock_bh(&tcp_sw_conn->sock->sk->sk_callback_lock); + set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); + write_unlock_bh(&tcp_sw_conn->sock->sk->sk_callback_lock); sock->sk->sk_err = EIO; wake_up_interruptible(sk_sleep(sock->sk)); - /* stop xmit side */ - iscsi_suspend_tx(conn); - - /* stop recv side and release socket */ - iscsi_sw_tcp_release_conn(conn); - iscsi_conn_stop(cls_conn, flag); + iscsi_sw_tcp_release_conn(conn); } static int diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 3b6693774066..49e1ccca09d5 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c @@ -801,20 +801,6 @@ static void fc_rport_recv_flogi_req(struct fc_lport *lport, switch (rdata->rp_state) { case RPORT_ST_INIT: - /* - * If received the FLOGI request on RPORT which is INIT state - * (means not transition to FLOGI either fc_rport timeout - * function didn;t trigger or this end hasn;t received - * beacon yet from other end. In that case only, allow RPORT - * state machine to continue, otherwise fall through which - * causes the code to send reject response. - * NOTE; Not checking for FIP->state such as VNMP_UP or - * VNMP_CLAIM because if FIP state is not one of those, - * RPORT wouldn;t have created and 'rport_lookup' would have - * failed anyway in that case. - */ - if (lport->point_to_multipoint) - break; case RPORT_ST_DELETE: mutex_unlock(&rdata->rp_mutex); rjt_data.reason = ELS_RJT_FIP; diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index 09b232fd9a1b..e98ae33f1295 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c @@ -1084,8 +1084,7 @@ iscsi_tcp_conn_setup(struct iscsi_cls_session *cls_session, int dd_data_size, struct iscsi_cls_conn *cls_conn; struct iscsi_tcp_conn *tcp_conn; - cls_conn = iscsi_conn_setup(cls_session, - sizeof(*tcp_conn) + dd_data_size, conn_idx); + cls_conn = iscsi_conn_setup(cls_session, sizeof(*tcp_conn), conn_idx); if (!cls_conn) return NULL; conn = cls_conn->dd_data; @@ -1097,13 +1096,22 @@ iscsi_tcp_conn_setup(struct iscsi_cls_session *cls_session, int dd_data_size, tcp_conn = conn->dd_data; tcp_conn->iscsi_conn = conn; - tcp_conn->dd_data = conn->dd_data + sizeof(*tcp_conn); + + tcp_conn->dd_data = kzalloc(dd_data_size, GFP_KERNEL); + if (!tcp_conn->dd_data) { + iscsi_conn_teardown(cls_conn); + return NULL; + } return cls_conn; } EXPORT_SYMBOL_GPL(iscsi_tcp_conn_setup); void iscsi_tcp_conn_teardown(struct iscsi_cls_conn *cls_conn) { + struct iscsi_conn *conn = cls_conn->dd_data; + struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + + kfree(tcp_conn->dd_data); iscsi_conn_teardown(cls_conn); } EXPORT_SYMBOL_GPL(iscsi_tcp_conn_teardown); diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index d2f95761ba32..874e29d9533f 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -192,22 +192,13 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, phy->attached_sata_ps = dr->attached_sata_ps; phy->attached_iproto = dr->iproto << 1; phy->attached_tproto = dr->tproto << 1; - /* help some expanders that fail to zero sas_address in the 'no - * device' case - */ - if (phy->attached_dev_type == NO_DEVICE || - phy->linkrate < SAS_LINK_RATE_1_5_GBPS) - memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE); - else - memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE); + memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE); phy->attached_phy_id = dr->attached_phy_id; phy->phy_change_count = dr->change_count; phy->routing_attr = dr->routing_attr; phy->virtual = dr->virtual; phy->last_da_index = -1; - phy->phy->identify.sas_address = SAS_ADDR(phy->attached_sas_addr); - phy->phy->identify.device_type = phy->attached_dev_type; phy->phy->identify.initiator_port_protocols = phy->attached_iproto; phy->phy->identify.target_port_protocols = phy->attached_tproto; phy->phy->identify.phy_identifier = phy_id; @@ -770,7 +761,7 @@ static struct domain_device *sas_ex_discover_end_dev( } /* See if this phy is part of a wide port */ -static bool sas_ex_join_wide_port(struct domain_device *parent, int phy_id) +static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id) { struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id]; int i; @@ -786,11 +777,11 @@ static bool sas_ex_join_wide_port(struct domain_device *parent, int phy_id) sas_port_add_phy(ephy->port, phy->phy); phy->port = ephy->port; phy->phy_state = PHY_DEVICE_DISCOVERED; - return true; + return 0; } } - return false; + return -ENODEV; } static struct domain_device *sas_ex_discover_expander( @@ -858,9 +849,6 @@ static struct domain_device *sas_ex_discover_expander( res = sas_discover_expander(child); if (res) { - spin_lock_irq(&parent->port->dev_list_lock); - list_del(&child->dev_list_node); - spin_unlock_irq(&parent->port->dev_list_lock); kfree(child); return NULL; } @@ -928,7 +916,8 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) return res; } - if (sas_ex_join_wide_port(dev, phy_id)) { + res = sas_ex_join_wide_port(dev, phy_id); + if (!res) { SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n", phy_id, SAS_ADDR(ex_phy->attached_sas_addr)); return res; @@ -973,7 +962,8 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) if (SAS_ADDR(ex->ex_phy[i].attached_sas_addr) == SAS_ADDR(child->sas_addr)) { ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED; - if (sas_ex_join_wide_port(dev, i)) + res = sas_ex_join_wide_port(dev, i); + if (!res) SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n", i, SAS_ADDR(ex->ex_phy[i].attached_sas_addr)); @@ -1637,17 +1627,9 @@ static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id, int phy_change_count = 0; res = sas_get_phy_change_count(dev, i, &phy_change_count); - switch (res) { - case SMP_RESP_PHY_VACANT: - case SMP_RESP_NO_PHY: - continue; - case SMP_RESP_FUNC_ACC: - break; - default: - return res; - } - - if (phy_change_count != ex->ex_phy[i].phy_change_count) { + if (res) + goto out; + else if (phy_change_count != ex->ex_phy[i].phy_change_count) { if (update) ex->ex_phy[i].phy_change_count = phy_change_count; @@ -1655,7 +1637,8 @@ static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id, return 0; } } - return 0; +out: + return res; } static int sas_get_ex_change_count(struct domain_device *dev, int *ecc) @@ -1735,7 +1718,7 @@ static int sas_find_bcast_dev(struct domain_device *dev, list_for_each_entry(ch, &ex->children, siblings) { if (ch->dev_type == EDGE_DEV || ch->dev_type == FANOUT_DEV) { res = sas_find_bcast_dev(ch, src_dev); - if (*src_dev) + if (src_dev) return res; } } @@ -1783,12 +1766,10 @@ static void sas_unregister_devs_sas_addr(struct domain_device *parent, sas_disable_routing(parent, phy->attached_sas_addr); } memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE); - if (phy->port) { - sas_port_delete_phy(phy->port, phy->phy); - if (phy->port->num_phys == 0) - sas_port_delete(phy->port); - phy->port = NULL; - } + sas_port_delete_phy(phy->port, phy->phy); + if (phy->port->num_phys == 0) + sas_port_delete(phy->port); + phy->port = NULL; } static int sas_discover_bfs_by_root_level(struct domain_device *root, @@ -1836,20 +1817,32 @@ static int sas_discover_new(struct domain_device *dev, int phy_id) { struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id]; struct domain_device *child; - int res; + bool found = false; + int res, i; SAS_DPRINTK("ex %016llx phy%d new device attached\n", SAS_ADDR(dev->sas_addr), phy_id); res = sas_ex_phy_discover(dev, phy_id); if (res) - return res; - - if (sas_ex_join_wide_port(dev, phy_id)) + goto out; + /* to support the wide port inserted */ + for (i = 0; i < dev->ex_dev.num_phys; i++) { + struct ex_phy *ex_phy_temp = &dev->ex_dev.ex_phy[i]; + if (i == phy_id) + continue; + if (SAS_ADDR(ex_phy_temp->attached_sas_addr) == + SAS_ADDR(ex_phy->attached_sas_addr)) { + found = true; + break; + } + } + if (found) { + sas_ex_join_wide_port(dev, phy_id); return 0; - + } res = sas_ex_discover_devices(dev, phy_id); - if (res) - return res; + if (!res) + goto out; list_for_each_entry(child, &dev->ex_dev.children, siblings) { if (SAS_ADDR(child->sas_addr) == SAS_ADDR(ex_phy->attached_sas_addr)) { @@ -1859,6 +1852,7 @@ static int sas_discover_new(struct domain_device *dev, int phy_id) break; } } +out: return res; } @@ -1957,7 +1951,9 @@ int sas_ex_revalidate_domain(struct domain_device *port_dev) struct domain_device *dev = NULL; res = sas_find_bcast_dev(port_dev, &dev); - while (res == 0 && dev) { + if (res) + goto out; + if (dev) { struct expander_device *ex = &dev->ex_dev; int i = 0, phy_id; @@ -1969,10 +1965,8 @@ int sas_ex_revalidate_domain(struct domain_device *port_dev) res = sas_rediscover(dev, phy_id); i = phy_id + 1; } while (i < ex->num_phys); - - dev = NULL; - res = sas_find_bcast_dev(port_dev, &dev); } +out: return res; } diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 0441361c79c8..8ec2c86a49d4 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -20,11 +20,6 @@ *******************************************************************/ #include - -#if defined(CONFIG_DEBUG_FS) && !defined(CONFIG_SCSI_LPFC_DEBUG_FS) -#define CONFIG_SCSI_LPFC_DEBUG_FS -#endif - struct lpfc_sli2_slim; #define LPFC_PCI_DEV_LP 0x1 @@ -470,10 +465,9 @@ enum intr_type_t { struct unsol_rcv_ct_ctx { uint32_t ctxt_id; uint32_t SID; + uint32_t oxid; uint32_t flags; #define UNSOL_VALID 0x00000001 - uint16_t oxid; - uint16_t rxid; }; #define LPFC_USER_LINK_SPEED_AUTO 0 /* auto select (default)*/ diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 80ca11c5158c..135a53baa735 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -754,47 +754,6 @@ lpfc_issue_reset(struct device *dev, struct device_attribute *attr, return status; } -/** - * lpfc_sli4_pdev_status_reg_wait - Wait for pdev status register for readyness - * @phba: lpfc_hba pointer. - * - * Description: - * SLI4 interface type-2 device to wait on the sliport status register for - * the readyness after performing a firmware reset. - * - * Returns: - * zero for success - **/ -static int -lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba) -{ - struct lpfc_register portstat_reg; - int i; - - - lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr, - &portstat_reg.word0); - - /* wait for the SLI port firmware ready after firmware reset */ - for (i = 0; i < LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT; i++) { - msleep(10); - lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr, - &portstat_reg.word0); - if (!bf_get(lpfc_sliport_status_err, &portstat_reg)) - continue; - if (!bf_get(lpfc_sliport_status_rn, &portstat_reg)) - continue; - if (!bf_get(lpfc_sliport_status_rdy, &portstat_reg)) - continue; - break; - } - - if (i < LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT) - return 0; - else - return -EIO; -} - /** * lpfc_sli4_pdev_reg_request - Request physical dev to perform a register acc * @phba: lpfc_hba pointer. @@ -846,10 +805,7 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode) readl(phba->sli4_hba.conf_regs_memmap_p + LPFC_CTL_PDEV_CTL_OFFSET); /* delay driver action following IF_TYPE_2 reset */ - rc = lpfc_sli4_pdev_status_reg_wait(phba); - - if (rc) - return -EIO; + msleep(100); init_completion(&online_compl); rc = lpfc_workq_post_event(phba, &status, &online_compl, @@ -939,10 +895,6 @@ lpfc_board_mode_store(struct device *dev, struct device_attribute *attr, if (!phba->cfg_enable_hba_reset) return -EACCES; - - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "3050 lpfc_board_mode set to %s\n", buf); - init_completion(&online_compl); if(strncmp(buf, "online", sizeof("online") - 1) == 0) { @@ -1338,10 +1290,6 @@ lpfc_poll_store(struct device *dev, struct device_attribute *attr, if (phba->sli_rev == LPFC_SLI_REV4) val = 0; - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "3051 lpfc_poll changed from %d to %d\n", - phba->cfg_poll, val); - spin_lock_irq(&phba->hbalock); old_val = phba->cfg_poll; @@ -1466,10 +1414,80 @@ lpfc_sriov_hw_max_virtfn_show(struct device *dev, struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; - uint16_t max_nr_virtfn; + struct pci_dev *pdev = phba->pcidev; + union lpfc_sli4_cfg_shdr *shdr; + uint32_t shdr_status, shdr_add_status; + LPFC_MBOXQ_t *mboxq; + struct lpfc_mbx_get_prof_cfg *get_prof_cfg; + struct lpfc_rsrc_desc_pcie *desc; + uint32_t max_nr_virtfn; + uint32_t desc_count; + int length, rc, i; + + if ((phba->sli_rev < LPFC_SLI_REV4) || + (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != + LPFC_SLI_INTF_IF_TYPE_2)) + return -EPERM; + + if (!pdev->is_physfn) + return snprintf(buf, PAGE_SIZE, "%d\n", 0); + + mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!mboxq) + return -ENOMEM; - max_nr_virtfn = lpfc_sli_sriov_nr_virtfn_get(phba); - return snprintf(buf, PAGE_SIZE, "%d\n", max_nr_virtfn); + /* get the maximum number of virtfn support by physfn */ + length = (sizeof(struct lpfc_mbx_get_prof_cfg) - + sizeof(struct lpfc_sli4_cfg_mhdr)); + lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON, + LPFC_MBOX_OPCODE_GET_PROFILE_CONFIG, + length, LPFC_SLI4_MBX_EMBED); + shdr = (union lpfc_sli4_cfg_shdr *) + &mboxq->u.mqe.un.sli4_config.header.cfg_shdr; + bf_set(lpfc_mbox_hdr_pf_num, &shdr->request, + phba->sli4_hba.iov.pf_number + 1); + + get_prof_cfg = &mboxq->u.mqe.un.get_prof_cfg; + bf_set(lpfc_mbx_get_prof_cfg_prof_tp, &get_prof_cfg->u.request, + LPFC_CFG_TYPE_CURRENT_ACTIVE); + + rc = lpfc_sli_issue_mbox_wait(phba, mboxq, + lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG)); + + if (rc != MBX_TIMEOUT) { + /* check return status */ + shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); + shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, + &shdr->response); + if (shdr_status || shdr_add_status || rc) + goto error_out; + + } else + goto error_out; + + desc_count = get_prof_cfg->u.response.prof_cfg.rsrc_desc_count; + + for (i = 0; i < LPFC_RSRC_DESC_MAX_NUM; i++) { + desc = (struct lpfc_rsrc_desc_pcie *) + &get_prof_cfg->u.response.prof_cfg.desc[i]; + if (LPFC_RSRC_DESC_TYPE_PCIE == + bf_get(lpfc_rsrc_desc_pcie_type, desc)) { + max_nr_virtfn = bf_get(lpfc_rsrc_desc_pcie_nr_virtfn, + desc); + break; + } + } + + if (i < LPFC_RSRC_DESC_MAX_NUM) { + if (rc != MBX_TIMEOUT) + mempool_free(mboxq, phba->mbox_mem_pool); + return snprintf(buf, PAGE_SIZE, "%d\n", max_nr_virtfn); + } + +error_out: + if (rc != MBX_TIMEOUT) + mempool_free(mboxq, phba->mbox_mem_pool); + return -EIO; } /** @@ -1587,9 +1605,6 @@ static int \ lpfc_##attr##_set(struct lpfc_hba *phba, uint val) \ { \ if (val >= minval && val <= maxval) {\ - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \ - "3052 lpfc_" #attr " changed from %d to %d\n", \ - phba->cfg_##attr, val); \ phba->cfg_##attr = val;\ return 0;\ }\ @@ -1747,9 +1762,6 @@ static int \ lpfc_##attr##_set(struct lpfc_vport *vport, uint val) \ { \ if (val >= minval && val <= maxval) {\ - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \ - "3053 lpfc_" #attr " changed from %d to %d\n", \ - vport->cfg_##attr, val); \ vport->cfg_##attr = val;\ return 0;\ }\ @@ -2666,9 +2678,6 @@ lpfc_topology_store(struct device *dev, struct device_attribute *attr, if (nolip) return strlen(buf); - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "3054 lpfc_topology changed from %d to %d\n", - prev_val, val); err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport)); if (err) { phba->cfg_topology = prev_val; @@ -3092,10 +3101,6 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr, if (sscanf(val_buf, "%i", &val) != 1) return -EINVAL; - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "3055 lpfc_link_speed changed from %d to %d %s\n", - phba->cfg_link_speed, val, nolip ? "(nolip)" : "(lip)"); - if (((val == LPFC_USER_LINK_SPEED_1G) && !(phba->lmt & LMT_1Gb)) || ((val == LPFC_USER_LINK_SPEED_2G) && !(phba->lmt & LMT_2Gb)) || ((val == LPFC_USER_LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) || @@ -3673,9 +3678,7 @@ LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable BlockGuard Support"); # - Default will result in registering capabilities for all profiles. # */ -unsigned int lpfc_prot_mask = SHOST_DIF_TYPE1_PROTECTION | - SHOST_DIX_TYPE0_PROTECTION | - SHOST_DIX_TYPE1_PROTECTION; +unsigned int lpfc_prot_mask = SHOST_DIF_TYPE1_PROTECTION; module_param(lpfc_prot_mask, uint, S_IRUGO); MODULE_PARM_DESC(lpfc_prot_mask, "host protection mask"); diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index f46378fb802c..7fb0ba4cbfa7 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -960,10 +960,8 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, evt_dat->immed_dat].oxid, phba->ct_ctx[ evt_dat->immed_dat].SID); - phba->ct_ctx[evt_dat->immed_dat].rxid = - piocbq->iocb.ulpContext; phba->ct_ctx[evt_dat->immed_dat].oxid = - piocbq->iocb.unsli3.rcvsli3.ox_id; + piocbq->iocb.ulpContext; phba->ct_ctx[evt_dat->immed_dat].SID = piocbq->iocb.un.rcvels.remoteID; phba->ct_ctx[evt_dat->immed_dat].flags = UNSOL_VALID; @@ -1314,8 +1312,7 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct fc_bsg_job *job, uint32_t tag, rc = IOCB_ERROR; goto issue_ct_rsp_exit; } - icmd->ulpContext = phba->ct_ctx[tag].rxid; - icmd->unsli3.rcvsli3.ox_id = phba->ct_ctx[tag].oxid; + icmd->ulpContext = phba->ct_ctx[tag].oxid; ndlp = lpfc_findnode_did(phba->pport, phba->ct_ctx[tag].SID); if (!ndlp) { lpfc_printf_log(phba, KERN_WARNING, LOG_ELS, @@ -1340,7 +1337,9 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct fc_bsg_job *job, uint32_t tag, goto issue_ct_rsp_exit; } - icmd->un.ulpWord[3] = + icmd->un.ulpWord[3] = ndlp->nlp_rpi; + if (phba->sli_rev == LPFC_SLI_REV4) + icmd->ulpContext = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; /* The exchange is done, mark the entry as invalid */ @@ -1352,8 +1351,8 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct fc_bsg_job *job, uint32_t tag, /* Xmit CT response on exchange */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "2722 Xmit CT response on exchange x%x Data: x%x x%x x%x\n", - icmd->ulpContext, icmd->ulpIoTag, tag, phba->link_state); + "2722 Xmit CT response on exchange x%x Data: x%x x%x\n", + icmd->ulpContext, icmd->ulpIoTag, phba->link_state); ctiocb->iocb_cmpl = NULL; ctiocb->iocb_flag |= LPFC_IO_LIBDFC; @@ -1472,12 +1471,13 @@ send_mgmt_rsp_exit: /** * lpfc_bsg_diag_mode_enter - process preparing into device diag loopback mode * @phba: Pointer to HBA context object. + * @job: LPFC_BSG_VENDOR_DIAG_MODE * * This function is responsible for preparing driver for diag loopback * on device. */ static int -lpfc_bsg_diag_mode_enter(struct lpfc_hba *phba) +lpfc_bsg_diag_mode_enter(struct lpfc_hba *phba, struct fc_bsg_job *job) { struct lpfc_vport **vports; struct Scsi_Host *shost; @@ -1521,6 +1521,7 @@ lpfc_bsg_diag_mode_enter(struct lpfc_hba *phba) /** * lpfc_bsg_diag_mode_exit - exit process from device diag loopback mode * @phba: Pointer to HBA context object. + * @job: LPFC_BSG_VENDOR_DIAG_MODE * * This function is responsible for driver exit processing of setting up * diag loopback mode on device. @@ -1585,7 +1586,7 @@ lpfc_sli3_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job) goto job_error; } - rc = lpfc_bsg_diag_mode_enter(phba); + rc = lpfc_bsg_diag_mode_enter(phba, job); if (rc) goto job_error; @@ -1757,7 +1758,7 @@ lpfc_sli4_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job) goto job_error; } - rc = lpfc_bsg_diag_mode_enter(phba); + rc = lpfc_bsg_diag_mode_enter(phba, job); if (rc) goto job_error; @@ -1981,7 +1982,7 @@ lpfc_sli4_bsg_link_diag_test(struct fc_bsg_job *job) goto job_error; } - rc = lpfc_bsg_diag_mode_enter(phba); + rc = lpfc_bsg_diag_mode_enter(phba, job); if (rc) goto job_error; @@ -3510,7 +3511,7 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job, lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, "2947 Issued SLI_CONFIG ext-buffer " "maibox command, rc:x%x\n", rc); - return SLI_CONFIG_HANDLED; + return 1; } lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, "2948 Failed to issue SLI_CONFIG ext-buffer " @@ -3548,7 +3549,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job, LPFC_MBOXQ_t *pmboxq = NULL; MAILBOX_t *pmb; uint8_t *mbx; - int rc = SLI_CONFIG_NOT_HANDLED, i; + int rc = 0, i; mbox_req = (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd; @@ -3659,7 +3660,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job, lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, "2955 Issued SLI_CONFIG ext-buffer " "maibox command, rc:x%x\n", rc); - return SLI_CONFIG_HANDLED; + return 1; } lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, "2956 Failed to issue SLI_CONFIG ext-buffer " @@ -3667,11 +3668,6 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job, rc = -EPIPE; } - /* wait for additoinal external buffers */ - job->reply->result = 0; - job->job_done(job); - return SLI_CONFIG_HANDLED; - job_error: if (pmboxq) mempool_free(pmboxq, phba->mbox_mem_pool); @@ -3963,7 +3959,7 @@ lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct fc_bsg_job *job, lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, "2969 Issued SLI_CONFIG ext-buffer " "maibox command, rc:x%x\n", rc); - return SLI_CONFIG_HANDLED; + return 1; } lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, "2970 Failed to issue SLI_CONFIG ext-buffer " @@ -4043,14 +4039,14 @@ lpfc_bsg_handle_sli_cfg_ext(struct lpfc_hba *phba, struct fc_bsg_job *job, struct lpfc_dmabuf *dmabuf) { struct dfc_mbox_req *mbox_req; - int rc = SLI_CONFIG_NOT_HANDLED; + int rc; mbox_req = (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd; /* mbox command with/without single external buffer */ if (mbox_req->extMboxTag == 0 && mbox_req->extSeqNum == 0) - return rc; + return SLI_CONFIG_NOT_HANDLED; /* mbox command and first external buffer */ if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_IDLE) { @@ -4253,7 +4249,7 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, * mailbox extension size */ if ((transmit_length > receive_length) || - (transmit_length > BSG_MBOX_SIZE - sizeof(MAILBOX_t))) { + (transmit_length > MAILBOX_EXT_SIZE)) { rc = -ERANGE; goto job_done; } @@ -4276,7 +4272,7 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, /* receive length cannot be greater than mailbox * extension size */ - if (receive_length > BSG_MBOX_SIZE - sizeof(MAILBOX_t)) { + if (receive_length > MAILBOX_EXT_SIZE) { rc = -ERANGE; goto job_done; } @@ -4310,8 +4306,7 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, bde = (struct ulp_bde64 *)&pmb->un.varWords[4]; /* bde size cannot be greater than mailbox ext size */ - if (bde->tus.f.bdeSize > - BSG_MBOX_SIZE - sizeof(MAILBOX_t)) { + if (bde->tus.f.bdeSize > MAILBOX_EXT_SIZE) { rc = -ERANGE; goto job_done; } @@ -4337,8 +4332,7 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, * mailbox extension size */ if ((receive_length == 0) || - (receive_length > - BSG_MBOX_SIZE - sizeof(MAILBOX_t))) { + (receive_length > MAILBOX_EXT_SIZE)) { rc = -ERANGE; goto job_done; } diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 1e41af8dea74..fc20c247f36b 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -432,7 +432,6 @@ void lpfc_handle_rrq_active(struct lpfc_hba *); int lpfc_send_rrq(struct lpfc_hba *, struct lpfc_node_rrq *); int lpfc_set_rrq_active(struct lpfc_hba *, struct lpfc_nodelist *, uint16_t, uint16_t, uint16_t); -uint16_t lpfc_sli4_xri_inrange(struct lpfc_hba *, uint16_t); void lpfc_cleanup_wt_rrqs(struct lpfc_hba *); void lpfc_cleanup_vports_rrqs(struct lpfc_vport *, struct lpfc_nodelist *); struct lpfc_node_rrq *lpfc_get_active_rrq(struct lpfc_vport *, uint16_t, @@ -440,4 +439,3 @@ struct lpfc_node_rrq *lpfc_get_active_rrq(struct lpfc_vport *, uint16_t, int lpfc_wr_object(struct lpfc_hba *, struct list_head *, uint32_t, uint32_t *); /* functions to support SR-IOV */ int lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *, int); -uint16_t lpfc_sli_sriov_nr_virtfn_get(struct lpfc_hba *); diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 1725b81770e9..32a084534f3e 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -647,15 +647,21 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, } lpfc_cleanup_pending_mbox(vport); - if (phba->sli_rev == LPFC_SLI_REV4) { + if (phba->sli_rev == LPFC_SLI_REV4) lpfc_sli4_unreg_all_rpis(vport); + + if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { lpfc_mbx_unreg_vpi(vport); spin_lock_irq(shost->host_lock); vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; - /* - * If VPI is unreged, driver need to do INIT_VPI - * before re-registering - */ + spin_unlock_irq(shost->host_lock); + } + /* + * If VPI is unreged, driver need to do INIT_VPI + * before re-registering + */ + if (phba->sli_rev == LPFC_SLI_REV4) { + spin_lock_irq(shost->host_lock); vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; spin_unlock_irq(shost->host_lock); } @@ -1090,14 +1096,11 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, /* Set the fcfi to the fcfi we registered with */ elsiocb->iocb.ulpContext = phba->fcf.fcfi; } - } else { - if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { - sp->cmn.request_multiple_Nport = 1; - /* For FLOGI, Let FLOGI rsp set the NPortID for VPI 0 */ - icmd->ulpCt_h = 1; - icmd->ulpCt_l = 0; - } else - sp->cmn.request_multiple_Nport = 0; + } else if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { + sp->cmn.request_multiple_Nport = 1; + /* For FLOGI, Let FLOGI rsp set the NPortID for VPI 0 */ + icmd->ulpCt_h = 1; + icmd->ulpCt_l = 0; } if (phba->fc_topology != LPFC_TOPOLOGY_LOOP) { @@ -3653,8 +3656,7 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, } icmd = &elsiocb->iocb; - icmd->ulpContext = oldcmd->ulpContext; /* Xri / rx_id */ - icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id; + icmd->ulpContext = oldcmd->ulpContext; /* Xri */ pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt); *((uint32_t *) (pcmd)) = ELS_CMD_ACC; pcmd += sizeof(uint32_t); @@ -3671,8 +3673,7 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, return 1; icmd = &elsiocb->iocb; - icmd->ulpContext = oldcmd->ulpContext; /* Xri / rx_id */ - icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id; + icmd->ulpContext = oldcmd->ulpContext; /* Xri */ pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt); if (mbox) @@ -3694,8 +3695,7 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, return 1; icmd = &elsiocb->iocb; - icmd->ulpContext = oldcmd->ulpContext; /* Xri / rx_id */ - icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id; + icmd->ulpContext = oldcmd->ulpContext; /* Xri */ pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt); memcpy(pcmd, ((struct lpfc_dmabuf *) oldiocb->context2)->virt, @@ -3781,8 +3781,7 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, icmd = &elsiocb->iocb; oldcmd = &oldiocb->iocb; - icmd->ulpContext = oldcmd->ulpContext; /* Xri / rx_id */ - icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id; + icmd->ulpContext = oldcmd->ulpContext; /* Xri */ pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); *((uint32_t *) (pcmd)) = ELS_CMD_LS_RJT; @@ -3854,8 +3853,7 @@ lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, icmd = &elsiocb->iocb; oldcmd = &oldiocb->iocb; - icmd->ulpContext = oldcmd->ulpContext; /* Xri / rx_id */ - icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id; + icmd->ulpContext = oldcmd->ulpContext; /* Xri */ /* Xmit ADISC ACC response tag */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, @@ -3933,9 +3931,7 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, icmd = &elsiocb->iocb; oldcmd = &oldiocb->iocb; - icmd->ulpContext = oldcmd->ulpContext; /* Xri / rx_id */ - icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id; - + icmd->ulpContext = oldcmd->ulpContext; /* Xri */ /* Xmit PRLI ACC response tag */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0131 Xmit PRLI ACC response tag x%x xri x%x, " @@ -4039,9 +4035,7 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format, icmd = &elsiocb->iocb; oldcmd = &oldiocb->iocb; - icmd->ulpContext = oldcmd->ulpContext; /* Xri / rx_id */ - icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id; - + icmd->ulpContext = oldcmd->ulpContext; /* Xri */ /* Xmit RNID ACC response tag */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0132 Xmit RNID ACC response tag x%x xri x%x\n", @@ -4169,9 +4163,7 @@ lpfc_els_rsp_echo_acc(struct lpfc_vport *vport, uint8_t *data, if (!elsiocb) return 1; - elsiocb->iocb.ulpContext = oldiocb->iocb.ulpContext; /* Xri / rx_id */ - elsiocb->iocb.unsli3.rcvsli3.ox_id = oldiocb->iocb.unsli3.rcvsli3.ox_id; - + elsiocb->iocb.ulpContext = oldiocb->iocb.ulpContext; /* Xri */ /* Xmit ECHO ACC response tag */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "2876 Xmit ECHO ACC response tag x%x xri x%x\n", @@ -5062,15 +5054,13 @@ lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) uint8_t *pcmd; struct lpfc_iocbq *elsiocb; struct lpfc_nodelist *ndlp; - uint16_t oxid; - uint16_t rxid; + uint16_t xri; uint32_t cmdsize; mb = &pmb->u.mb; ndlp = (struct lpfc_nodelist *) pmb->context2; - rxid = (uint16_t) ((unsigned long)(pmb->context1) & 0xffff); - oxid = (uint16_t) (((unsigned long)(pmb->context1) >> 16) & 0xffff); + xri = (uint16_t) ((unsigned long)(pmb->context1)); pmb->context1 = NULL; pmb->context2 = NULL; @@ -5092,8 +5082,7 @@ lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) return; icmd = &elsiocb->iocb; - icmd->ulpContext = rxid; - icmd->unsli3.rcvsli3.ox_id = oxid; + icmd->ulpContext = xri; pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); *((uint32_t *) (pcmd)) = ELS_CMD_ACC; @@ -5148,16 +5137,13 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) uint8_t *pcmd; struct lpfc_iocbq *elsiocb; struct lpfc_nodelist *ndlp; - uint16_t status; - uint16_t oxid; - uint16_t rxid; + uint16_t xri, status; uint32_t cmdsize; mb = &pmb->u.mb; ndlp = (struct lpfc_nodelist *) pmb->context2; - rxid = (uint16_t) ((unsigned long)(pmb->context1) & 0xffff); - oxid = (uint16_t) (((unsigned long)(pmb->context1) >> 16) & 0xffff); + xri = (uint16_t) ((unsigned long)(pmb->context1)); pmb->context1 = NULL; pmb->context2 = NULL; @@ -5179,8 +5165,7 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) return; icmd = &elsiocb->iocb; - icmd->ulpContext = rxid; - icmd->unsli3.rcvsli3.ox_id = oxid; + icmd->ulpContext = xri; pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); *((uint32_t *) (pcmd)) = ELS_CMD_ACC; @@ -5253,9 +5238,8 @@ lpfc_els_rcv_rls(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC); if (mbox) { lpfc_read_lnk_stat(phba, mbox); - mbox->context1 = (void *)((unsigned long) - ((cmdiocb->iocb.unsli3.rcvsli3.ox_id << 16) | - cmdiocb->iocb.ulpContext)); /* rx_id */ + mbox->context1 = + (void *)((unsigned long) cmdiocb->iocb.ulpContext); mbox->context2 = lpfc_nlp_get(ndlp); mbox->vport = vport; mbox->mbox_cmpl = lpfc_els_rsp_rls_acc; @@ -5330,8 +5314,7 @@ lpfc_els_rcv_rtv(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, pcmd += sizeof(uint32_t); /* Skip past command */ /* use the command's xri in the response */ - elsiocb->iocb.ulpContext = cmdiocb->iocb.ulpContext; /* Xri / rx_id */ - elsiocb->iocb.unsli3.rcvsli3.ox_id = cmdiocb->iocb.unsli3.rcvsli3.ox_id; + elsiocb->iocb.ulpContext = cmdiocb->iocb.ulpContext; rtv_rsp = (struct RTV_RSP *)pcmd; @@ -5416,9 +5399,8 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC); if (mbox) { lpfc_read_lnk_stat(phba, mbox); - mbox->context1 = (void *)((unsigned long) - ((cmdiocb->iocb.unsli3.rcvsli3.ox_id << 16) | - cmdiocb->iocb.ulpContext)); /* rx_id */ + mbox->context1 = + (void *)((unsigned long) cmdiocb->iocb.ulpContext); mbox->context2 = lpfc_nlp_get(ndlp); mbox->vport = vport; mbox->mbox_cmpl = lpfc_els_rsp_rps_acc; @@ -5572,8 +5554,7 @@ lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize, icmd = &elsiocb->iocb; oldcmd = &oldiocb->iocb; - icmd->ulpContext = oldcmd->ulpContext; /* Xri / rx_id */ - icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id; + icmd->ulpContext = oldcmd->ulpContext; /* Xri */ pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt); *((uint32_t *) (pcmd)) = ELS_CMD_ACC; @@ -6605,7 +6586,7 @@ lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi) { struct lpfc_vport *vport; unsigned long flags; - int i = 0; + int i; /* The physical ports are always vpi 0 - translate is unnecessary. */ if (vpi > 0) { @@ -6628,7 +6609,7 @@ lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi) spin_lock_irqsave(&phba->hbalock, flags); list_for_each_entry(vport, &phba->port_list, listentry) { - if (vport->vpi == i) { + if (vport->vpi == vpi) { spin_unlock_irqrestore(&phba->hbalock, flags); return vport; } @@ -7806,7 +7787,6 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba, { uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri); uint16_t rxid = bf_get(lpfc_wcqe_xa_remote_xid, axri); - uint16_t lxri = 0; struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; unsigned long iflag = 0; @@ -7835,12 +7815,7 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba, } } spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); - lxri = lpfc_sli4_xri_inrange(phba, xri); - if (lxri == NO_XRI) { - spin_unlock_irqrestore(&phba->hbalock, iflag); - return; - } - sglq_entry = __lpfc_get_active_sglq(phba, lxri); + sglq_entry = __lpfc_get_active_sglq(phba, xri); if (!sglq_entry || (sglq_entry->sli4_xritag != xri)) { spin_unlock_irqrestore(&phba->hbalock, iflag); return; diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index bef17e3e419a..18d0dbfda2bc 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -2247,6 +2247,7 @@ read_next_fcf: spin_lock_irq(&phba->hbalock); phba->fcf.fcf_flag |= FCF_REDISC_FOV; spin_unlock_irq(&phba->hbalock); + lpfc_sli4_mbox_cmd_free(phba, mboxq); lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST); return; @@ -2644,7 +2645,6 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) vport->vpi_state |= LPFC_VPI_REGISTERED; vport->fc_flag |= FC_VFI_REGISTERED; vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; - vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; spin_unlock_irq(shost->host_lock); if (vport->port_state == LPFC_FABRIC_CFG_LINK) { diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index df53d1075574..9059524cf225 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -3470,16 +3470,11 @@ typedef struct { or CMD_IOCB_RCV_SEQ64_CX (0xB5) */ struct rcv_sli3 { + uint32_t word8Rsvd; #ifdef __BIG_ENDIAN_BITFIELD - uint16_t ox_id; - uint16_t seq_cnt; - uint16_t vpi; uint16_t word9Rsvd; #else /* __LITTLE_ENDIAN */ - uint16_t seq_cnt; - uint16_t ox_id; - uint16_t word9Rsvd; uint16_t vpi; #endif diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 7f8003b5181e..11e26a26b5d1 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -170,8 +170,15 @@ struct lpfc_sli_intf { #define LPFC_PCI_FUNC3 3 #define LPFC_PCI_FUNC4 4 -/* SLI4 interface type-2 PDEV_CTL register */ +/* SLI4 interface type-2 control register offsets */ +#define LPFC_CTL_PORT_SEM_OFFSET 0x400 +#define LPFC_CTL_PORT_STA_OFFSET 0x404 +#define LPFC_CTL_PORT_CTL_OFFSET 0x408 +#define LPFC_CTL_PORT_ER1_OFFSET 0x40C +#define LPFC_CTL_PORT_ER2_OFFSET 0x410 #define LPFC_CTL_PDEV_CTL_OFFSET 0x414 + +/* Some SLI4 interface type-2 PDEV_CTL register bits */ #define LPFC_CTL_PDEV_CTL_DRST 0x00000001 #define LPFC_CTL_PDEV_CTL_FRST 0x00000002 #define LPFC_CTL_PDEV_CTL_DD 0x00000004 @@ -330,7 +337,6 @@ struct lpfc_cqe { #define CQE_CODE_RELEASE_WQE 0x2 #define CQE_CODE_RECEIVE 0x4 #define CQE_CODE_XRI_ABORTED 0x5 -#define CQE_CODE_RECEIVE_V1 0x9 /* completion queue entry for wqe completions */ struct lpfc_wcqe_complete { @@ -434,10 +440,7 @@ struct lpfc_rcqe { #define FC_STATUS_RQ_BUF_LEN_EXCEEDED 0x11 /* payload truncated */ #define FC_STATUS_INSUFF_BUF_NEED_BUF 0x12 /* Insufficient buffers */ #define FC_STATUS_INSUFF_BUF_FRM_DISC 0x13 /* Frame Discard */ - uint32_t word1; -#define lpfc_rcqe_fcf_id_v1_SHIFT 0 -#define lpfc_rcqe_fcf_id_v1_MASK 0x0000003F -#define lpfc_rcqe_fcf_id_v1_WORD word1 + uint32_t reserved1; uint32_t word2; #define lpfc_rcqe_length_SHIFT 16 #define lpfc_rcqe_length_MASK 0x0000FFFF @@ -448,9 +451,6 @@ struct lpfc_rcqe { #define lpfc_rcqe_fcf_id_SHIFT 0 #define lpfc_rcqe_fcf_id_MASK 0x0000003F #define lpfc_rcqe_fcf_id_WORD word2 -#define lpfc_rcqe_rq_id_v1_SHIFT 0 -#define lpfc_rcqe_rq_id_v1_MASK 0x0000FFFF -#define lpfc_rcqe_rq_id_v1_WORD word2 uint32_t word3; #define lpfc_rcqe_valid_SHIFT lpfc_cqe_valid_SHIFT #define lpfc_rcqe_valid_MASK lpfc_cqe_valid_MASK @@ -515,7 +515,7 @@ struct lpfc_register { /* The following BAR0 register sets are defined for if_type 0 and 2 UCNAs. */ #define LPFC_SLI_INTF 0x0058 -#define LPFC_CTL_PORT_SEM_OFFSET 0x400 +#define LPFC_SLIPORT_IF2_SMPHR 0x0400 #define lpfc_port_smphr_perr_SHIFT 31 #define lpfc_port_smphr_perr_MASK 0x1 #define lpfc_port_smphr_perr_WORD word0 @@ -575,7 +575,7 @@ struct lpfc_register { #define LPFC_POST_STAGE_PORT_READY 0xC000 #define LPFC_POST_STAGE_PORT_UE 0xF000 -#define LPFC_CTL_PORT_STA_OFFSET 0x404 +#define LPFC_SLIPORT_STATUS 0x0404 #define lpfc_sliport_status_err_SHIFT 31 #define lpfc_sliport_status_err_MASK 0x1 #define lpfc_sliport_status_err_WORD word0 @@ -593,7 +593,7 @@ struct lpfc_register { #define lpfc_sliport_status_rdy_WORD word0 #define MAX_IF_TYPE_2_RESETS 1000 -#define LPFC_CTL_PORT_CTL_OFFSET 0x408 +#define LPFC_SLIPORT_CNTRL 0x0408 #define lpfc_sliport_ctrl_end_SHIFT 30 #define lpfc_sliport_ctrl_end_MASK 0x1 #define lpfc_sliport_ctrl_end_WORD word0 @@ -604,8 +604,8 @@ struct lpfc_register { #define lpfc_sliport_ctrl_ip_WORD word0 #define LPFC_SLIPORT_INIT_PORT 1 -#define LPFC_CTL_PORT_ER1_OFFSET 0x40C -#define LPFC_CTL_PORT_ER2_OFFSET 0x410 +#define LPFC_SLIPORT_ERR_1 0x040C +#define LPFC_SLIPORT_ERR_2 0x0410 /* The following Registers apply to SLI4 if_type 0 UCNAs. They typically * reside in BAR 2. @@ -3198,8 +3198,6 @@ struct lpfc_grp_hdr { #define lpfc_grp_hdr_id_MASK 0x000000FF #define lpfc_grp_hdr_id_WORD word2 uint8_t rev_name[128]; - uint8_t date[12]; - uint8_t revision[32]; }; #define FCP_COMMAND 0x0 diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 027b797c9916..148b98ddbb1d 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -2927,8 +2927,6 @@ void lpfc_host_attrib_init(struct Scsi_Host *shost) sizeof fc_host_symbolic_name(shost)); fc_host_supported_speeds(shost) = 0; - if (phba->lmt & LMT_16Gb) - fc_host_supported_speeds(shost) |= FC_PORTSPEED_16GBIT; if (phba->lmt & LMT_10Gb) fc_host_supported_speeds(shost) |= FC_PORTSPEED_10GBIT; if (phba->lmt & LMT_8Gb) @@ -3649,7 +3647,7 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba, " tag 0x%x\n", acqe_fip->index, acqe_fip->event_tag); vport = lpfc_find_vport_by_vpid(phba, - acqe_fip->index); + acqe_fip->index - phba->vpi_base); ndlp = lpfc_sli4_perform_vport_cvl(vport); if (!ndlp) break; @@ -4036,34 +4034,6 @@ lpfc_reset_hba(struct lpfc_hba *phba) lpfc_unblock_mgmt_io(phba); } -/** - * lpfc_sli_sriov_nr_virtfn_get - Get the number of sr-iov virtual functions - * @phba: pointer to lpfc hba data structure. - * - * This function enables the PCI SR-IOV virtual functions to a physical - * function. It invokes the PCI SR-IOV api with the @nr_vfn provided to - * enable the number of virtual functions to the physical function. As - * not all devices support SR-IOV, the return code from the pci_enable_sriov() - * API call does not considered as an error condition for most of the device. - **/ -uint16_t -lpfc_sli_sriov_nr_virtfn_get(struct lpfc_hba *phba) -{ - struct pci_dev *pdev = phba->pcidev; - uint16_t nr_virtfn; - int pos; - - if (!pdev->is_physfn) - return 0; - - pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); - if (pos == 0) - return 0; - - pci_read_config_word(pdev, pos + PCI_SRIOV_TOTAL_VF, &nr_virtfn); - return nr_virtfn; -} - /** * lpfc_sli_probe_sriov_nr_virtfn - Enable a number of sr-iov virtual functions * @phba: pointer to lpfc hba data structure. @@ -4079,17 +4049,8 @@ int lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *phba, int nr_vfn) { struct pci_dev *pdev = phba->pcidev; - uint16_t max_nr_vfn; int rc; - max_nr_vfn = lpfc_sli_sriov_nr_virtfn_get(phba); - if (nr_vfn > max_nr_vfn) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "3057 Requested vfs (%d) greater than " - "supported vfs (%d)", nr_vfn, max_nr_vfn); - return -EINVAL; - } - rc = pci_enable_sriov(pdev, nr_vfn); if (rc) { lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, @@ -4555,7 +4516,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) } } - return 0; + return rc; out_free_fcp_eq_hdl: kfree(phba->sli4_hba.fcp_eq_hdl); @@ -5005,14 +4966,17 @@ out_free_mem: * @phba: pointer to lpfc hba data structure. * * This routine is invoked to post rpi header templates to the - * port for those SLI4 ports that do not support extents. This routine + * HBA consistent with the SLI-4 interface spec. This routine * posts a PAGE_SIZE memory region to the port to hold up to - * PAGE_SIZE modulo 64 rpi context headers. This is an initialization routine - * and should be called only when interrupts are disabled. + * PAGE_SIZE modulo 64 rpi context headers. + * No locks are held here because this is an initialization routine + * called only from probe or lpfc_online when interrupts are not + * enabled and the driver is reinitializing the device. * * Return codes * 0 - successful - * -ERROR - otherwise. + * -ENOMEM - No available memory + * -EIO - The mailbox failed to complete successfully. **/ int lpfc_sli4_init_rpi_hdrs(struct lpfc_hba *phba) @@ -5723,22 +5687,17 @@ lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba, uint32_t if_type) break; case LPFC_SLI_INTF_IF_TYPE_2: phba->sli4_hba.u.if_type2.ERR1regaddr = - phba->sli4_hba.conf_regs_memmap_p + - LPFC_CTL_PORT_ER1_OFFSET; + phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_ERR_1; phba->sli4_hba.u.if_type2.ERR2regaddr = - phba->sli4_hba.conf_regs_memmap_p + - LPFC_CTL_PORT_ER2_OFFSET; + phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_ERR_2; phba->sli4_hba.u.if_type2.CTRLregaddr = - phba->sli4_hba.conf_regs_memmap_p + - LPFC_CTL_PORT_CTL_OFFSET; + phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_CNTRL; phba->sli4_hba.u.if_type2.STATUSregaddr = - phba->sli4_hba.conf_regs_memmap_p + - LPFC_CTL_PORT_STA_OFFSET; + phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_STATUS; phba->sli4_hba.SLIINTFregaddr = phba->sli4_hba.conf_regs_memmap_p + LPFC_SLI_INTF; phba->sli4_hba.PSMPHRregaddr = - phba->sli4_hba.conf_regs_memmap_p + - LPFC_CTL_PORT_SEM_OFFSET; + phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_IF2_SMPHR; phba->sli4_hba.RQDBregaddr = phba->sli4_hba.conf_regs_memmap_p + LPFC_RQ_DOORBELL; phba->sli4_hba.WQDBregaddr = @@ -8900,11 +8859,11 @@ lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw) return -EINVAL; } lpfc_decode_firmware_rev(phba, fwrev, 1); - if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) { + if (strncmp(fwrev, image->rev_name, strnlen(fwrev, 16))) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "3023 Updating Firmware. Current Version:%s " "New Version:%s\n", - fwrev, image->revision); + fwrev, image->rev_name); for (i = 0; i < LPFC_MBX_WR_CONFIG_MAX_BDE; i++) { dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); @@ -8933,9 +8892,9 @@ lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw) fw->size - offset); break; } + temp_offset += SLI4_PAGE_SIZE; memcpy(dmabuf->virt, fw->data + temp_offset, SLI4_PAGE_SIZE); - temp_offset += SLI4_PAGE_SIZE; } rc = lpfc_wr_object(phba, &dma_buffer_list, (fw->size - offset), &offset); @@ -9524,13 +9483,6 @@ lpfc_io_slot_reset_s4(struct pci_dev *pdev) } pci_restore_state(pdev); - - /* - * As the new kernel behavior of pci_restore_state() API call clears - * device saved_state flag, need to save the restored state again. - */ - pci_save_state(pdev); - if (pdev->is_busmaster) pci_set_master(pdev); diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 83450cc5c4d3..556767028353 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c @@ -2031,7 +2031,7 @@ lpfc_init_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport) bf_set(lpfc_init_vfi_vp, init_vfi, 1); bf_set(lpfc_init_vfi_vfi, init_vfi, vport->phba->sli4_hba.vfi_ids[vport->vfi]); - bf_set(lpfc_init_vfi_vpi, init_vfi, + bf_set(lpfc_init_vpi_vpi, init_vfi, vport->phba->vpi_ids[vport->vpi]); bf_set(lpfc_init_vfi_fcfi, init_vfi, vport->phba->fcf.fcfi); diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index eadd241eeff1..3ccc97496ebf 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -1302,13 +1302,13 @@ lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc, case SCSI_PROT_NORMAL: default: lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "9063 BLKGRD: Bad op/guard:%d/IP combination\n", - scsi_get_prot_op(sc)); + "9063 BLKGRD: Bad op/guard:%d/%d combination\n", + scsi_get_prot_op(sc), guard_type); ret = 1; break; } - } else { + } else if (guard_type == SHOST_DIX_GUARD_CRC) { switch (scsi_get_prot_op(sc)) { case SCSI_PROT_READ_STRIP: case SCSI_PROT_WRITE_INSERT: @@ -1324,18 +1324,17 @@ lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc, case SCSI_PROT_READ_INSERT: case SCSI_PROT_WRITE_STRIP: - *txop = BG_OP_IN_CRC_OUT_NODIF; - *rxop = BG_OP_IN_NODIF_OUT_CRC; - break; - case SCSI_PROT_NORMAL: default: lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "9075 BLKGRD: Bad op/guard:%d/CRC combination\n", - scsi_get_prot_op(sc)); + "9075 BLKGRD: Bad op/guard:%d/%d combination\n", + scsi_get_prot_op(sc), guard_type); ret = 1; break; } + } else { + /* unsupported format */ + BUG(); } return ret; @@ -1353,6 +1352,45 @@ lpfc_cmd_blksize(struct scsi_cmnd *sc) return sc->device->sector_size; } +/** + * lpfc_get_cmd_dif_parms - Extract DIF parameters from SCSI command + * @sc: in: SCSI command + * @apptagmask: out: app tag mask + * @apptagval: out: app tag value + * @reftag: out: ref tag (reference tag) + * + * Description: + * Extract DIF parameters from the command if possible. Otherwise, + * use default parameters. + * + **/ +static inline void +lpfc_get_cmd_dif_parms(struct scsi_cmnd *sc, uint16_t *apptagmask, + uint16_t *apptagval, uint32_t *reftag) +{ + struct scsi_dif_tuple *spt; + unsigned char op = scsi_get_prot_op(sc); + unsigned int protcnt = scsi_prot_sg_count(sc); + static int cnt; + + if (protcnt && (op == SCSI_PROT_WRITE_STRIP || + op == SCSI_PROT_WRITE_PASS)) { + + cnt++; + spt = page_address(sg_page(scsi_prot_sglist(sc))) + + scsi_prot_sglist(sc)[0].offset; + *apptagmask = 0; + *apptagval = 0; + *reftag = cpu_to_be32(spt->ref_tag); + + } else { + /* SBC defines ref tag to be lower 32bits of LBA */ + *reftag = (uint32_t) (0xffffffff & scsi_get_lba(sc)); + *apptagmask = 0; + *apptagval = 0; + } +} + /* * This function sets up buffer list for protection groups of * type LPFC_PG_TYPE_NO_DIF @@ -1389,8 +1427,9 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc, dma_addr_t physaddr; int i = 0, num_bde = 0, status; int datadir = sc->sc_data_direction; - uint32_t reftag; unsigned blksize; + uint32_t reftag; + uint16_t apptagmask, apptagval; uint8_t txop, rxop; status = lpfc_sc_to_bg_opcodes(phba, sc, &txop, &rxop); @@ -1399,16 +1438,17 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc, /* extract some info from the scsi command for pde*/ blksize = lpfc_cmd_blksize(sc); - reftag = scsi_get_lba(sc) & 0xffffffff; + lpfc_get_cmd_dif_parms(sc, &apptagmask, &apptagval, &reftag); /* setup PDE5 with what we have */ pde5 = (struct lpfc_pde5 *) bpl; memset(pde5, 0, sizeof(struct lpfc_pde5)); bf_set(pde5_type, pde5, LPFC_PDE5_DESCRIPTOR); + pde5->reftag = reftag; /* Endianness conversion if necessary for PDE5 */ pde5->word0 = cpu_to_le32(pde5->word0); - pde5->reftag = cpu_to_le32(reftag); + pde5->reftag = cpu_to_le32(pde5->reftag); /* advance bpl and increment bde count */ num_bde++; @@ -1423,10 +1463,10 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc, if (datadir == DMA_FROM_DEVICE) { bf_set(pde6_ce, pde6, 1); bf_set(pde6_re, pde6, 1); + bf_set(pde6_ae, pde6, 1); } bf_set(pde6_ai, pde6, 1); - bf_set(pde6_ae, pde6, 0); - bf_set(pde6_apptagval, pde6, 0); + bf_set(pde6_apptagval, pde6, apptagval); /* Endianness conversion if necessary for PDE6 */ pde6->word0 = cpu_to_le32(pde6->word0); @@ -1511,6 +1551,7 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, unsigned char pgdone = 0, alldone = 0; unsigned blksize; uint32_t reftag; + uint16_t apptagmask, apptagval; uint8_t txop, rxop; int num_bde = 0; @@ -1530,7 +1571,7 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, /* extract some info from the scsi command */ blksize = lpfc_cmd_blksize(sc); - reftag = scsi_get_lba(sc) & 0xffffffff; + lpfc_get_cmd_dif_parms(sc, &apptagmask, &apptagval, &reftag); split_offset = 0; do { @@ -1538,10 +1579,11 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, pde5 = (struct lpfc_pde5 *) bpl; memset(pde5, 0, sizeof(struct lpfc_pde5)); bf_set(pde5_type, pde5, LPFC_PDE5_DESCRIPTOR); + pde5->reftag = reftag; /* Endianness conversion if necessary for PDE5 */ pde5->word0 = cpu_to_le32(pde5->word0); - pde5->reftag = cpu_to_le32(reftag); + pde5->reftag = cpu_to_le32(pde5->reftag); /* advance bpl and increment bde count */ num_bde++; @@ -1555,9 +1597,9 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, bf_set(pde6_oprx, pde6, rxop); bf_set(pde6_ce, pde6, 1); bf_set(pde6_re, pde6, 1); + bf_set(pde6_ae, pde6, 1); bf_set(pde6_ai, pde6, 1); - bf_set(pde6_ae, pde6, 0); - bf_set(pde6_apptagval, pde6, 0); + bf_set(pde6_apptagval, pde6, apptagval); /* Endianness conversion if necessary for PDE6 */ pde6->word0 = cpu_to_le32(pde6->word0); @@ -1579,8 +1621,8 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, memset(pde7, 0, sizeof(struct lpfc_pde7)); bf_set(pde7_type, pde7, LPFC_PDE7_DESCRIPTOR); - pde7->addrHigh = le32_to_cpu(putPaddrHigh(protphysaddr)); - pde7->addrLow = le32_to_cpu(putPaddrLow(protphysaddr)); + pde7->addrHigh = le32_to_cpu(putPaddrLow(protphysaddr)); + pde7->addrLow = le32_to_cpu(putPaddrHigh(protphysaddr)); protgrp_blks = protgroup_len / 8; protgrp_bytes = protgrp_blks * blksize; @@ -1590,7 +1632,7 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, protgroup_remainder = 0x1000 - (pde7->addrLow & 0xfff); protgroup_offset += protgroup_remainder; protgrp_blks = protgroup_remainder / 8; - protgrp_bytes = protgrp_blks * blksize; + protgrp_bytes = protgroup_remainder * blksize; } else { protgroup_offset = 0; curr_prot++; @@ -1964,21 +2006,16 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd, if (lpfc_bgs_get_hi_water_mark_present(bgstat)) { /* * setup sense data descriptor 0 per SPC-4 as an information - * field, and put the failing LBA in it. - * This code assumes there was also a guard/app/ref tag error - * indication. + * field, and put the failing LBA in it */ - cmd->sense_buffer[7] = 0xc; /* Additional sense length */ - cmd->sense_buffer[8] = 0; /* Information descriptor type */ - cmd->sense_buffer[9] = 0xa; /* Additional descriptor length */ - cmd->sense_buffer[10] = 0x80; /* Validity bit */ + cmd->sense_buffer[8] = 0; /* Information */ + cmd->sense_buffer[9] = 0xa; /* Add. length */ bghm /= cmd->device->sector_size; failing_sector = scsi_get_lba(cmd); failing_sector += bghm; - /* Descriptor Information */ - put_unaligned_be64(failing_sector, &cmd->sense_buffer[12]); + put_unaligned_be64(failing_sector, &cmd->sense_buffer[10]); } if (!ret) { diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 5b28ea1d72c5..98999bbd8cbf 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -560,7 +560,7 @@ __lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL); if (rrq) { rrq->send_rrq = send_rrq; - rrq->xritag = xritag; + rrq->xritag = phba->sli4_hba.xri_ids[xritag]; rrq->rrq_stop_time = jiffies + HZ * (phba->fc_ratov + 1); rrq->ndlp = ndlp; rrq->nlp_DID = ndlp->nlp_DID; @@ -2452,8 +2452,7 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, /* search continue save q for same XRI */ list_for_each_entry(iocbq, &pring->iocb_continue_saveq, clist) { - if (iocbq->iocb.unsli3.rcvsli3.ox_id == - saveq->iocb.unsli3.rcvsli3.ox_id) { + if (iocbq->iocb.ulpContext == saveq->iocb.ulpContext) { list_add_tail(&saveq->list, &iocbq->list); found = 1; break; @@ -3356,7 +3355,6 @@ lpfc_sli_handle_slow_ring_event_s4(struct lpfc_hba *phba, irspiocbq); break; case CQE_CODE_RECEIVE: - case CQE_CODE_RECEIVE_V1: dmabuf = container_of(cq_event, struct hbq_dmabuf, cq_event); lpfc_sli4_handle_received_buffer(phba, dmabuf); @@ -5839,7 +5837,6 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) "Advanced Error Reporting (AER)\n"); phba->cfg_aer_support = 0; } - rc = 0; } if (!(phba->hba_flag & HBA_FCOE_MODE)) { @@ -7321,12 +7318,12 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, bf_set(wqe_qosd, &wqe->els_req.wqe_com, 1); bf_set(wqe_lenloc, &wqe->els_req.wqe_com, LPFC_WQE_LENLOC_NONE); bf_set(wqe_ebde_cnt, &wqe->els_req.wqe_com, 0); - break; + break; case CMD_XMIT_SEQUENCE64_CX: bf_set(wqe_ctxt_tag, &wqe->xmit_sequence.wqe_com, iocbq->iocb.un.ulpWord[3]); bf_set(wqe_rcvoxid, &wqe->xmit_sequence.wqe_com, - iocbq->iocb.unsli3.rcvsli3.ox_id); + iocbq->iocb.ulpContext); /* The entire sequence is transmitted for this IOCB */ xmit_len = total_len; cmnd = CMD_XMIT_SEQUENCE64_CR; @@ -7344,7 +7341,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, bf_set(wqe_ebde_cnt, &wqe->xmit_sequence.wqe_com, 0); wqe->xmit_sequence.xmit_len = xmit_len; command_type = OTHER_COMMAND; - break; + break; case CMD_XMIT_BCAST64_CN: /* word3 iocb=iotag32 wqe=seq_payload_len */ wqe->xmit_bcast64.seq_payload_len = xmit_len; @@ -7358,7 +7355,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, bf_set(wqe_lenloc, &wqe->xmit_bcast64.wqe_com, LPFC_WQE_LENLOC_WORD3); bf_set(wqe_ebde_cnt, &wqe->xmit_bcast64.wqe_com, 0); - break; + break; case CMD_FCP_IWRITE64_CR: command_type = FCP_COMMAND_DATA_OUT; /* word3 iocb=iotag wqe=payload_offset_len */ @@ -7378,7 +7375,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, LPFC_WQE_LENLOC_WORD4); bf_set(wqe_ebde_cnt, &wqe->fcp_iwrite.wqe_com, 0); bf_set(wqe_pu, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpPU); - break; + break; case CMD_FCP_IREAD64_CR: /* word3 iocb=iotag wqe=payload_offset_len */ /* Add the FCP_CMD and FCP_RSP sizes to get the offset */ @@ -7397,7 +7394,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, LPFC_WQE_LENLOC_WORD4); bf_set(wqe_ebde_cnt, &wqe->fcp_iread.wqe_com, 0); bf_set(wqe_pu, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpPU); - break; + break; case CMD_FCP_ICMND64_CR: /* word3 iocb=IO_TAG wqe=reserved */ wqe->fcp_icmd.rsrvd3 = 0; @@ -7410,7 +7407,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, bf_set(wqe_lenloc, &wqe->fcp_icmd.wqe_com, LPFC_WQE_LENLOC_NONE); bf_set(wqe_ebde_cnt, &wqe->fcp_icmd.wqe_com, 0); - break; + break; case CMD_GEN_REQUEST64_CR: /* For this command calculate the xmit length of the * request bde. @@ -7445,7 +7442,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, bf_set(wqe_lenloc, &wqe->gen_req.wqe_com, LPFC_WQE_LENLOC_NONE); bf_set(wqe_ebde_cnt, &wqe->gen_req.wqe_com, 0); command_type = OTHER_COMMAND; - break; + break; case CMD_XMIT_ELS_RSP64_CX: ndlp = (struct lpfc_nodelist *)iocbq->context1; /* words0-2 BDE memcpy */ @@ -7460,7 +7457,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, ((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l)); bf_set(wqe_pu, &wqe->xmit_els_rsp.wqe_com, iocbq->iocb.ulpPU); bf_set(wqe_rcvoxid, &wqe->xmit_els_rsp.wqe_com, - iocbq->iocb.unsli3.rcvsli3.ox_id); + iocbq->iocb.ulpContext); if (!iocbq->iocb.ulpCt_h && iocbq->iocb.ulpCt_l) bf_set(wqe_ctxt_tag, &wqe->xmit_els_rsp.wqe_com, phba->vpi_ids[iocbq->vport->vpi]); @@ -7473,7 +7470,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, bf_set(wqe_rsp_temp_rpi, &wqe->xmit_els_rsp, phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]); command_type = OTHER_COMMAND; - break; + break; case CMD_CLOSE_XRI_CN: case CMD_ABORT_XRI_CN: case CMD_ABORT_XRI_CX: @@ -7512,7 +7509,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, cmnd = CMD_ABORT_XRI_CX; command_type = OTHER_COMMAND; xritag = 0; - break; + break; case CMD_XMIT_BLS_RSP64_CX: /* As BLS ABTS RSP WQE is very different from other WQEs, * we re-construct this WQE here based on information in @@ -7556,7 +7553,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, bf_get(lpfc_rsn_code, &iocbq->iocb.un.bls_rsp)); } - break; + break; case CMD_XRI_ABORTED_CX: case CMD_CREATE_XRI_CR: /* Do we expect to use this? */ case CMD_IOCB_FCP_IBIDIR64_CR: /* bidirectional xfer */ @@ -7568,7 +7565,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, "2014 Invalid command 0x%x\n", iocbq->iocb.ulpCommand); return IOCB_ERROR; - break; + break; } bf_set(wqe_xri_tag, &wqe->generic.wqe_com, xritag); @@ -10484,14 +10481,10 @@ lpfc_sli4_sp_handle_rcqe(struct lpfc_hba *phba, struct lpfc_rcqe *rcqe) struct lpfc_queue *hrq = phba->sli4_hba.hdr_rq; struct lpfc_queue *drq = phba->sli4_hba.dat_rq; struct hbq_dmabuf *dma_buf; - uint32_t status, rq_id; + uint32_t status; unsigned long iflags; - if (bf_get(lpfc_cqe_code, rcqe) == CQE_CODE_RECEIVE_V1) - rq_id = bf_get(lpfc_rcqe_rq_id_v1, rcqe); - else - rq_id = bf_get(lpfc_rcqe_rq_id, rcqe); - if (rq_id != hrq->queue_id) + if (bf_get(lpfc_rcqe_rq_id, rcqe) != hrq->queue_id) goto out; status = bf_get(lpfc_rcqe_status, rcqe); @@ -10570,7 +10563,6 @@ lpfc_sli4_sp_handle_cqe(struct lpfc_hba *phba, struct lpfc_queue *cq, (struct sli4_wcqe_xri_aborted *)&cqevt); break; case CQE_CODE_RECEIVE: - case CQE_CODE_RECEIVE_V1: /* Process the RQ event */ phba->last_completion_time = jiffies; workposted = lpfc_sli4_sp_handle_rcqe(phba, @@ -12353,18 +12345,19 @@ lpfc_sli4_post_sgl(struct lpfc_hba *phba, } /** - * lpfc_sli4_alloc_xri - Get an available rpi in the device's range + * lpfc_sli4_init_rpi_hdrs - Post the rpi header memory region to the port * @phba: pointer to lpfc hba data structure. * * This routine is invoked to post rpi header templates to the - * HBA consistent with the SLI-4 interface spec. This routine - * posts a SLI4_PAGE_SIZE memory region to the port to hold up to - * SLI4_PAGE_SIZE modulo 64 rpi context headers. + * port for those SLI4 ports that do not support extents. This routine + * posts a PAGE_SIZE memory region to the port to hold up to + * PAGE_SIZE modulo 64 rpi context headers. This is an initialization routine + * and should be called only when interrupts are disabled. * - * Returns - * A nonzero rpi defined as rpi_base <= rpi < max_rpi if successful - * LPFC_RPI_ALLOC_ERROR if no rpis are available. - **/ + * Return codes + * 0 - successful + * -ERROR - otherwise. + */ uint16_t lpfc_sli4_alloc_xri(struct lpfc_hba *phba) { @@ -13413,7 +13406,7 @@ lpfc_sli4_seq_abort_rsp_cmpl(struct lpfc_hba *phba, * This function validates the xri maps to the known range of XRIs allocated an * used by the driver. **/ -uint16_t +static uint16_t lpfc_sli4_xri_inrange(struct lpfc_hba *phba, uint16_t xri) { @@ -13650,12 +13643,10 @@ lpfc_seq_complete(struct hbq_dmabuf *dmabuf) static struct lpfc_iocbq * lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) { - struct hbq_dmabuf *hbq_buf; struct lpfc_dmabuf *d_buf, *n_buf; struct lpfc_iocbq *first_iocbq, *iocbq; struct fc_frame_header *fc_hdr; uint32_t sid; - uint32_t len, tot_len; struct ulp_bde64 *pbde; fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt; @@ -13664,7 +13655,6 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) lpfc_update_rcv_time_stamp(vport); /* get the Remote Port's SID */ sid = sli4_sid_from_fc_hdr(fc_hdr); - tot_len = 0; /* Get an iocbq struct to fill in. */ first_iocbq = lpfc_sli_get_iocbq(vport->phba); if (first_iocbq) { @@ -13672,12 +13662,9 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) first_iocbq->iocb.unsli3.rcvsli3.acc_len = 0; first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS; first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX; - first_iocbq->iocb.ulpContext = NO_XRI; - first_iocbq->iocb.unsli3.rcvsli3.ox_id = - be16_to_cpu(fc_hdr->fh_ox_id); - /* iocbq is prepped for internal consumption. Physical vpi. */ - first_iocbq->iocb.unsli3.rcvsli3.vpi = - vport->phba->vpi_ids[vport->vpi]; + first_iocbq->iocb.ulpContext = be16_to_cpu(fc_hdr->fh_ox_id); + /* iocbq is prepped for internal consumption. Logical vpi. */ + first_iocbq->iocb.unsli3.rcvsli3.vpi = vport->vpi; /* put the first buffer into the first IOCBq */ first_iocbq->context2 = &seq_dmabuf->dbuf; first_iocbq->context3 = NULL; @@ -13685,9 +13672,9 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) first_iocbq->iocb.un.cont64[0].tus.f.bdeSize = LPFC_DATA_BUF_SIZE; first_iocbq->iocb.un.rcvels.remoteID = sid; - tot_len = bf_get(lpfc_rcqe_length, + first_iocbq->iocb.unsli3.rcvsli3.acc_len += + bf_get(lpfc_rcqe_length, &seq_dmabuf->cq_event.cqe.rcqe_cmpl); - first_iocbq->iocb.unsli3.rcvsli3.acc_len = tot_len; } iocbq = first_iocbq; /* @@ -13705,13 +13692,9 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) pbde = (struct ulp_bde64 *) &iocbq->iocb.unsli3.sli3Words[4]; pbde->tus.f.bdeSize = LPFC_DATA_BUF_SIZE; - - /* We need to get the size out of the right CQE */ - hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf); - len = bf_get(lpfc_rcqe_length, - &hbq_buf->cq_event.cqe.rcqe_cmpl); - iocbq->iocb.unsli3.rcvsli3.acc_len += len; - tot_len += len; + first_iocbq->iocb.unsli3.rcvsli3.acc_len += + bf_get(lpfc_rcqe_length, + &seq_dmabuf->cq_event.cqe.rcqe_cmpl); } else { iocbq = lpfc_sli_get_iocbq(vport->phba); if (!iocbq) { @@ -13729,14 +13712,9 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) iocbq->iocb.ulpBdeCount = 1; iocbq->iocb.un.cont64[0].tus.f.bdeSize = LPFC_DATA_BUF_SIZE; - - /* We need to get the size out of the right CQE */ - hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf); - len = bf_get(lpfc_rcqe_length, - &hbq_buf->cq_event.cqe.rcqe_cmpl); - tot_len += len; - iocbq->iocb.unsli3.rcvsli3.acc_len = tot_len; - + first_iocbq->iocb.unsli3.rcvsli3.acc_len += + bf_get(lpfc_rcqe_length, + &seq_dmabuf->cq_event.cqe.rcqe_cmpl); iocbq->iocb.un.rcvels.remoteID = sid; list_add_tail(&iocbq->list, &first_iocbq->list); } @@ -13809,13 +13787,7 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba, lpfc_in_buf_free(phba, &dmabuf->dbuf); return; } - if ((bf_get(lpfc_cqe_code, - &dmabuf->cq_event.cqe.rcqe_cmpl) == CQE_CODE_RECEIVE_V1)) - fcfi = bf_get(lpfc_rcqe_fcf_id_v1, - &dmabuf->cq_event.cqe.rcqe_cmpl); - else - fcfi = bf_get(lpfc_rcqe_fcf_id, - &dmabuf->cq_event.cqe.rcqe_cmpl); + fcfi = bf_get(lpfc_rcqe_fcf_id, &dmabuf->cq_event.cqe.rcqe_cmpl); vport = lpfc_fc_frame_to_vport(phba, fc_hdr, fcfi); if (!vport || !(vport->vpi_state & LPFC_VPI_REGISTERED)) { /* throw out the frame */ diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 88387c1c2dcc..4b1703554a26 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -81,8 +81,6 @@ (fc_hdr)->fh_f_ctl[1] << 8 | \ (fc_hdr)->fh_f_ctl[2]) -#define LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT 12000 - enum lpfc_sli4_queue_type { LPFC_EQ, LPFC_GCQ, diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 931cb11083ca..2d8cdce7b2f5 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1906,6 +1906,7 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd) static enum blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd) { + struct megasas_cmd *cmd = (struct megasas_cmd *)scmd->SCp.ptr; struct megasas_instance *instance; unsigned long flags; @@ -1914,7 +1915,7 @@ blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd) return BLK_EH_NOT_HANDLED; } - instance = (struct megasas_instance *)scmd->device->host->hostdata; + instance = cmd->instance; if (!(instance->flag & MEGASAS_FW_BUSY)) { /* FW is busy, throttle IO */ spin_lock_irqsave(instance->host->host_lock, flags); @@ -4052,6 +4053,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) spin_lock_init(&instance->cmd_pool_lock); spin_lock_init(&instance->hba_lock); spin_lock_init(&instance->completion_lock); + spin_lock_init(&poll_aen_lock); mutex_init(&instance->aen_mutex); mutex_init(&instance->reset_mutex); @@ -5379,8 +5381,6 @@ static int __init megasas_init(void) printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION, MEGASAS_EXT_VERSION); - spin_lock_init(&poll_aen_lock); - support_poll_for_event = 2; support_device_change = 1; diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 679fe6a773b6..efa0255491c2 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -66,8 +66,6 @@ static MPT_CALLBACK mpt_callbacks[MPT_MAX_CALLBACKS]; #define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */ -#define MAX_HBA_QUEUE_DEPTH 30000 -#define MAX_CHAIN_DEPTH 100000 static int max_queue_depth = -1; module_param(max_queue_depth, int, 0); MODULE_PARM_DESC(max_queue_depth, " max controller queue depth "); @@ -96,7 +94,7 @@ module_param(diag_buffer_enable, int, 0); MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers " "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)"); -static int mpt2sas_fwfault_debug; +int mpt2sas_fwfault_debug; MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault " "and halt firmware - (default=0)"); @@ -859,7 +857,7 @@ _base_interrupt(int irq, void *bus_id) completed_cmds = 0; cb_idx = 0xFF; do { - rd.word = le64_to_cpu(rpf->Words); + rd.word = rpf->Words; if (rd.u.low == UINT_MAX || rd.u.high == UINT_MAX) goto out; reply = 0; @@ -908,7 +906,7 @@ _base_interrupt(int irq, void *bus_id) next: - rpf->Words = cpu_to_le64(ULLONG_MAX); + rpf->Words = ULLONG_MAX; ioc->reply_post_host_index = (ioc->reply_post_host_index == (ioc->reply_post_queue_depth - 1)) ? 0 : ioc->reply_post_host_index + 1; @@ -1083,6 +1081,41 @@ _base_config_dma_addressing(struct MPT2SAS_ADAPTER *ioc, struct pci_dev *pdev) return 0; } +/** + * _base_save_msix_table - backup msix vector table + * @ioc: per adapter object + * + * This address an errata where diag reset clears out the table + */ +static void +_base_save_msix_table(struct MPT2SAS_ADAPTER *ioc) +{ + int i; + + if (!ioc->msix_enable || ioc->msix_table_backup == NULL) + return; + + for (i = 0; i < ioc->msix_vector_count; i++) + ioc->msix_table_backup[i] = ioc->msix_table[i]; +} + +/** + * _base_restore_msix_table - this restores the msix vector table + * @ioc: per adapter object + * + */ +static void +_base_restore_msix_table(struct MPT2SAS_ADAPTER *ioc) +{ + int i; + + if (!ioc->msix_enable || ioc->msix_table_backup == NULL) + return; + + for (i = 0; i < ioc->msix_vector_count; i++) + ioc->msix_table[i] = ioc->msix_table_backup[i]; +} + /** * _base_check_enable_msix - checks MSIX capabable. * @ioc: per adapter object @@ -1095,14 +1128,7 @@ _base_check_enable_msix(struct MPT2SAS_ADAPTER *ioc) { int base; u16 message_control; - - - /* Check whether controller SAS2008 B0 controller, - if it is SAS2008 B0 controller use IO-APIC instead of MSIX */ - if (ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2008 && - ioc->pdev->revision == 0x01) { - return -EINVAL; - } + u32 msix_table_offset; base = pci_find_capability(ioc->pdev, PCI_CAP_ID_MSIX); if (!base) { @@ -1115,8 +1141,14 @@ _base_check_enable_msix(struct MPT2SAS_ADAPTER *ioc) pci_read_config_word(ioc->pdev, base + 2, &message_control); ioc->msix_vector_count = (message_control & 0x3FF) + 1; + /* get msix table */ + pci_read_config_dword(ioc->pdev, base + 4, &msix_table_offset); + msix_table_offset &= 0xFFFFFFF8; + ioc->msix_table = (u32 *)((void *)ioc->chip + msix_table_offset); + dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "msix is supported, " - "vector_count(%d)\n", ioc->name, ioc->msix_vector_count)); + "vector_count(%d), table_offset(0x%08x), table(%p)\n", ioc->name, + ioc->msix_vector_count, msix_table_offset, ioc->msix_table)); return 0; } @@ -1130,6 +1162,8 @@ _base_disable_msix(struct MPT2SAS_ADAPTER *ioc) { if (ioc->msix_enable) { pci_disable_msix(ioc->pdev); + kfree(ioc->msix_table_backup); + ioc->msix_table_backup = NULL; ioc->msix_enable = 0; } } @@ -1155,6 +1189,14 @@ _base_enable_msix(struct MPT2SAS_ADAPTER *ioc) if (_base_check_enable_msix(ioc) != 0) goto try_ioapic; + ioc->msix_table_backup = kcalloc(ioc->msix_vector_count, + sizeof(u32), GFP_KERNEL); + if (!ioc->msix_table_backup) { + dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "allocation for " + "msix_table_backup failed!!!\n", ioc->name)); + goto try_ioapic; + } + memset(&entries, 0, sizeof(struct msix_entry)); r = pci_enable_msix(ioc->pdev, &entries, 1); if (r) { @@ -1698,11 +1740,9 @@ _base_display_dell_branding(struct MPT2SAS_ADAPTER *ioc) static void _base_display_intel_branding(struct MPT2SAS_ADAPTER *ioc) { - if (ioc->pdev->subsystem_vendor != PCI_VENDOR_ID_INTEL) - return; + if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_INTEL && + ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2008) { - switch (ioc->pdev->device) { - case MPI2_MFGPAGE_DEVID_SAS2008: switch (ioc->pdev->subsystem_device) { case MPT2SAS_INTEL_RMS2LL080_SSDID: printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, @@ -1712,20 +1752,7 @@ _base_display_intel_branding(struct MPT2SAS_ADAPTER *ioc) printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, MPT2SAS_INTEL_RMS2LL040_BRANDING); break; - default: - break; - } - case MPI2_MFGPAGE_DEVID_SAS2308_2: - switch (ioc->pdev->subsystem_device) { - case MPT2SAS_INTEL_RS25GB008_SSDID: - printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, - MPT2SAS_INTEL_RS25GB008_BRANDING); - break; - default: - break; } - default: - break; } } @@ -1790,9 +1817,7 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) char desc[16]; u8 revision; u32 iounit_pg1_flags; - u32 bios_version; - bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion); pci_read_config_byte(ioc->pdev, PCI_CLASS_REVISION, &revision); strncpy(desc, ioc->manu_pg0.ChipName, 16); printk(MPT2SAS_INFO_FMT "%s: FWVersion(%02d.%02d.%02d.%02d), " @@ -1803,10 +1828,10 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8, ioc->facts.FWVersion.Word & 0x000000FF, revision, - (bios_version & 0xFF000000) >> 24, - (bios_version & 0x00FF0000) >> 16, - (bios_version & 0x0000FF00) >> 8, - bios_version & 0x000000FF); + (ioc->bios_pg3.BiosVersion & 0xFF000000) >> 24, + (ioc->bios_pg3.BiosVersion & 0x00FF0000) >> 16, + (ioc->bios_pg3.BiosVersion & 0x0000FF00) >> 8, + ioc->bios_pg3.BiosVersion & 0x000000FF); _base_display_dell_branding(ioc); _base_display_intel_branding(ioc); @@ -2107,6 +2132,8 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc) } if (ioc->chain_dma_pool) pci_pool_destroy(ioc->chain_dma_pool); + } + if (ioc->chain_lookup) { free_pages((ulong)ioc->chain_lookup, ioc->chain_pages); ioc->chain_lookup = NULL; } @@ -2123,8 +2150,10 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc) static int _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) { - struct mpt2sas_facts *facts; + Mpi2IOCFactsReply_t *facts; + u32 queue_size, queue_diff; u16 max_sge_elements; + u16 num_of_reply_frames; u16 chains_needed_per_io; u32 sz, total_sz; u32 retry_sz; @@ -2147,15 +2176,11 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) } /* command line tunables for max controller queue depth */ - if (max_queue_depth != -1 && max_queue_depth != 0) { - max_request_credit = min_t(u16, max_queue_depth + - ioc->hi_priority_depth + ioc->internal_depth, - facts->RequestCredit); - if (max_request_credit > MAX_HBA_QUEUE_DEPTH) - max_request_credit = MAX_HBA_QUEUE_DEPTH; - } else - max_request_credit = min_t(u16, facts->RequestCredit, - MAX_HBA_QUEUE_DEPTH); + if (max_queue_depth != -1) + max_request_credit = (max_queue_depth < facts->RequestCredit) + ? max_queue_depth : facts->RequestCredit; + else + max_request_credit = facts->RequestCredit; ioc->hba_queue_depth = max_request_credit; ioc->hi_priority_depth = facts->HighPriorityCredit; @@ -2196,25 +2221,50 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) } ioc->chains_needed_per_io = chains_needed_per_io; - /* reply free queue sizing - taking into account for 64 FW events */ - ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64; + /* reply free queue sizing - taking into account for events */ + num_of_reply_frames = ioc->hba_queue_depth + 32; - /* align the reply post queue on the next 16 count boundary */ - if (!ioc->reply_free_queue_depth % 16) - ioc->reply_post_queue_depth = ioc->reply_free_queue_depth + 16; - else - ioc->reply_post_queue_depth = ioc->reply_free_queue_depth + - 32 - (ioc->reply_free_queue_depth % 16); - if (ioc->reply_post_queue_depth > - facts->MaxReplyDescriptorPostQueueDepth) { - ioc->reply_post_queue_depth = min_t(u16, - (facts->MaxReplyDescriptorPostQueueDepth - - (facts->MaxReplyDescriptorPostQueueDepth % 16)), - (ioc->hba_queue_depth - (ioc->hba_queue_depth % 16))); - ioc->reply_free_queue_depth = ioc->reply_post_queue_depth - 16; - ioc->hba_queue_depth = ioc->reply_free_queue_depth - 64; - } + /* number of replies frames can't be a multiple of 16 */ + /* decrease number of reply frames by 1 */ + if (!(num_of_reply_frames % 16)) + num_of_reply_frames--; + + /* calculate number of reply free queue entries + * (must be multiple of 16) + */ + + /* (we know reply_free_queue_depth is not a multiple of 16) */ + queue_size = num_of_reply_frames; + queue_size += 16 - (queue_size % 16); + ioc->reply_free_queue_depth = queue_size; + + /* reply descriptor post queue sizing */ + /* this size should be the number of request frames + number of reply + * frames + */ + queue_size = ioc->hba_queue_depth + num_of_reply_frames + 1; + /* round up to 16 byte boundary */ + if (queue_size % 16) + queue_size += 16 - (queue_size % 16); + + /* check against IOC maximum reply post queue depth */ + if (queue_size > facts->MaxReplyDescriptorPostQueueDepth) { + queue_diff = queue_size - + facts->MaxReplyDescriptorPostQueueDepth; + + /* round queue_diff up to multiple of 16 */ + if (queue_diff % 16) + queue_diff += 16 - (queue_diff % 16); + + /* adjust hba_queue_depth, reply_free_queue_depth, + * and queue_size + */ + ioc->hba_queue_depth -= (queue_diff / 2); + ioc->reply_free_queue_depth -= (queue_diff / 2); + queue_size = facts->MaxReplyDescriptorPostQueueDepth; + } + ioc->reply_post_queue_depth = queue_size; dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scatter gather: " "sge_in_main_msg(%d), sge_per_chain(%d), sge_per_io(%d), " @@ -2228,7 +2278,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) /* set the scsi host can_queue depth * with some internal commands that could be outstanding */ - ioc->shost->can_queue = ioc->scsiio_depth; + ioc->shost->can_queue = ioc->scsiio_depth - (2); dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsi host: " "can_queue depth (%d)\n", ioc->name, ioc->shost->can_queue)); @@ -2300,12 +2350,15 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) "depth(%d)\n", ioc->name, ioc->request, ioc->scsiio_depth)); - ioc->chain_depth = min_t(u32, ioc->chain_depth, MAX_CHAIN_DEPTH); - sz = ioc->chain_depth * sizeof(struct chain_tracker); - ioc->chain_pages = get_order(sz); - - ioc->chain_lookup = (struct chain_tracker *)__get_free_pages( - GFP_KERNEL, ioc->chain_pages); + /* loop till the allocation succeeds */ + do { + sz = ioc->chain_depth * sizeof(struct chain_tracker); + ioc->chain_pages = get_order(sz); + ioc->chain_lookup = (struct chain_tracker *)__get_free_pages( + GFP_KERNEL, ioc->chain_pages); + if (ioc->chain_lookup == NULL) + ioc->chain_depth -= 100; + } while (ioc->chain_lookup == NULL); ioc->chain_dma_pool = pci_pool_create("chain pool", ioc->pdev, ioc->request_sz, 16, 0); if (!ioc->chain_dma_pool) { @@ -2730,7 +2783,7 @@ _base_handshake_req_reply_wait(struct MPT2SAS_ADAPTER *ioc, int request_bytes, int i; u8 failed; u16 dummy; - __le32 *mfp; + u32 *mfp; /* make sure doorbell is not in use */ if ((readl(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) { @@ -2818,7 +2871,7 @@ _base_handshake_req_reply_wait(struct MPT2SAS_ADAPTER *ioc, int request_bytes, writel(0, &ioc->chip->HostInterruptStatus); if (ioc->logging_level & MPT_DEBUG_INIT) { - mfp = (__le32 *)reply; + mfp = (u32 *)reply; printk(KERN_INFO "\toffset:data\n"); for (i = 0; i < reply_bytes/4; i++) printk(KERN_INFO "\t[0x%02x]:%08x\n", i*4, @@ -3044,8 +3097,7 @@ static int _base_get_port_facts(struct MPT2SAS_ADAPTER *ioc, int port, int sleep_flag) { Mpi2PortFactsRequest_t mpi_request; - Mpi2PortFactsReply_t mpi_reply; - struct mpt2sas_port_facts *pfacts; + Mpi2PortFactsReply_t mpi_reply, *pfacts; int mpi_reply_sz, mpi_request_sz, r; dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, @@ -3066,7 +3118,7 @@ _base_get_port_facts(struct MPT2SAS_ADAPTER *ioc, int port, int sleep_flag) } pfacts = &ioc->pfacts[port]; - memset(pfacts, 0, sizeof(struct mpt2sas_port_facts)); + memset(pfacts, 0, sizeof(Mpi2PortFactsReply_t)); pfacts->PortNumber = mpi_reply.PortNumber; pfacts->VP_ID = mpi_reply.VP_ID; pfacts->VF_ID = mpi_reply.VF_ID; @@ -3087,8 +3139,7 @@ static int _base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) { Mpi2IOCFactsRequest_t mpi_request; - Mpi2IOCFactsReply_t mpi_reply; - struct mpt2sas_facts *facts; + Mpi2IOCFactsReply_t mpi_reply, *facts; int mpi_reply_sz, mpi_request_sz, r; dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, @@ -3108,7 +3159,7 @@ _base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) } facts = &ioc->facts; - memset(facts, 0, sizeof(struct mpt2sas_facts)); + memset(facts, 0, sizeof(Mpi2IOCFactsReply_t)); facts->MsgVersion = le16_to_cpu(mpi_reply.MsgVersion); facts->HeaderVersion = le16_to_cpu(mpi_reply.HeaderVersion); facts->VP_ID = mpi_reply.VP_ID; @@ -3174,6 +3225,17 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) mpi_request.MsgVersion = cpu_to_le16(MPI2_VERSION); mpi_request.HeaderVersion = cpu_to_le16(MPI2_HEADER_VERSION); + /* In MPI Revision I (0xA), the SystemReplyFrameSize(offset 0x18) was + * removed and made reserved. For those with older firmware will need + * this fix. It was decided that the Reply and Request frame sizes are + * the same. + */ + if ((ioc->facts.HeaderVersion >> 8) < 0xA) { + mpi_request.Reserved7 = cpu_to_le16(ioc->reply_sz); +/* mpi_request.SystemReplyFrameSize = + * cpu_to_le16(ioc->reply_sz); + */ + } mpi_request.SystemRequestFrameSize = cpu_to_le16(ioc->request_sz/4); mpi_request.ReplyDescriptorPostQueueDepth = @@ -3181,17 +3243,25 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) mpi_request.ReplyFreeQueueDepth = cpu_to_le16(ioc->reply_free_queue_depth); +#if BITS_PER_LONG > 32 mpi_request.SenseBufferAddressHigh = - cpu_to_le32((u64)ioc->sense_dma >> 32); + cpu_to_le32(ioc->sense_dma >> 32); mpi_request.SystemReplyAddressHigh = - cpu_to_le32((u64)ioc->reply_dma >> 32); + cpu_to_le32(ioc->reply_dma >> 32); mpi_request.SystemRequestFrameBaseAddress = - cpu_to_le64((u64)ioc->request_dma); + cpu_to_le64(ioc->request_dma); mpi_request.ReplyFreeQueueAddress = - cpu_to_le64((u64)ioc->reply_free_dma); + cpu_to_le64(ioc->reply_free_dma); mpi_request.ReplyDescriptorPostQueueAddress = - cpu_to_le64((u64)ioc->reply_post_free_dma); - + cpu_to_le64(ioc->reply_post_free_dma); +#else + mpi_request.SystemRequestFrameBaseAddress = + cpu_to_le32(ioc->request_dma); + mpi_request.ReplyFreeQueueAddress = + cpu_to_le32(ioc->reply_free_dma); + mpi_request.ReplyDescriptorPostQueueAddress = + cpu_to_le32(ioc->reply_post_free_dma); +#endif /* This time stamp specifies number of milliseconds * since epoch ~ midnight January 1, 1970. @@ -3201,10 +3271,10 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) (current_time.tv_usec / 1000)); if (ioc->logging_level & MPT_DEBUG_INIT) { - __le32 *mfp; + u32 *mfp; int i; - mfp = (__le32 *)&mpi_request; + mfp = (u32 *)&mpi_request; printk(KERN_INFO "\toffset:data\n"); for (i = 0; i < sizeof(Mpi2IOCInitRequest_t)/4; i++) printk(KERN_INFO "\t[0x%02x]:%08x\n", i*4, @@ -3443,6 +3513,9 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) u32 hcb_size; printk(MPT2SAS_INFO_FMT "sending diag reset !!\n", ioc->name); + + _base_save_msix_table(ioc); + drsprintk(ioc, printk(MPT2SAS_INFO_FMT "clear interrupts\n", ioc->name)); @@ -3538,6 +3611,7 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) goto out; } + _base_restore_msix_table(ioc); printk(MPT2SAS_INFO_FMT "diag reset: SUCCESS\n", ioc->name); return 0; @@ -3685,7 +3759,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) /* initialize Reply Post Free Queue */ for (i = 0; i < ioc->reply_post_queue_depth; i++) - ioc->reply_post_free[i].Words = cpu_to_le64(ULLONG_MAX); + ioc->reply_post_free[i].Words = ULLONG_MAX; r = _base_send_ioc_init(ioc, sleep_flag); if (r) @@ -3789,7 +3863,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) goto out_free_resources; ioc->pfacts = kcalloc(ioc->facts.NumberOfPorts, - sizeof(struct mpt2sas_port_facts), GFP_KERNEL); + sizeof(Mpi2PortFactsReply_t), GFP_KERNEL); if (!ioc->pfacts) { r = -ENOMEM; goto out_free_resources; diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index e1735f99f238..dcc289c25459 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h @@ -161,15 +161,12 @@ "Intel Integrated RAID Module RMS2LL080" #define MPT2SAS_INTEL_RMS2LL040_BRANDING \ "Intel Integrated RAID Module RMS2LL040" -#define MPT2SAS_INTEL_RS25GB008_BRANDING \ - "Intel(R) RAID Controller RS25GB008" /* * Intel HBA SSDIDs */ #define MPT2SAS_INTEL_RMS2LL080_SSDID 0x350E #define MPT2SAS_INTEL_RMS2LL040_SSDID 0x350F -#define MPT2SAS_INTEL_RS25GB008_SSDID 0x3000 /* @@ -544,53 +541,6 @@ struct _tr_list { typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr); -/* IOC Facts and Port Facts converted from little endian to cpu */ -union mpi2_version_union { - MPI2_VERSION_STRUCT Struct; - u32 Word; -}; - -struct mpt2sas_facts { - u16 MsgVersion; - u16 HeaderVersion; - u8 IOCNumber; - u8 VP_ID; - u8 VF_ID; - u16 IOCExceptions; - u16 IOCStatus; - u32 IOCLogInfo; - u8 MaxChainDepth; - u8 WhoInit; - u8 NumberOfPorts; - u8 MaxMSIxVectors; - u16 RequestCredit; - u16 ProductID; - u32 IOCCapabilities; - union mpi2_version_union FWVersion; - u16 IOCRequestFrameSize; - u16 Reserved3; - u16 MaxInitiators; - u16 MaxTargets; - u16 MaxSasExpanders; - u16 MaxEnclosures; - u16 ProtocolFlags; - u16 HighPriorityCredit; - u16 MaxReplyDescriptorPostQueueDepth; - u8 ReplyFrameSize; - u8 MaxVolumes; - u16 MaxDevHandle; - u16 MaxPersistentEntries; - u16 MinDevHandle; -}; - -struct mpt2sas_port_facts { - u8 PortNumber; - u8 VP_ID; - u8 VF_ID; - u8 PortType; - u16 MaxPostedCmdBuffers; -}; - /** * struct MPT2SAS_ADAPTER - per adapter struct * @list: ioc_list @@ -626,6 +576,8 @@ struct mpt2sas_port_facts { * @wait_for_port_enable_to_complete: * @msix_enable: flag indicating msix is enabled * @msix_vector_count: number msix vectors + * @msix_table: virt address to the msix table + * @msix_table_backup: backup msix table * @scsi_io_cb_idx: shost generated commands * @tm_cb_idx: task management commands * @scsih_cb_idx: scsih internal commands @@ -766,6 +718,8 @@ struct MPT2SAS_ADAPTER { u8 msix_enable; u16 msix_vector_count; + u32 *msix_table; + u32 *msix_table_backup; u32 ioc_reset_count; /* internal commands, callback index */ @@ -795,8 +749,8 @@ struct MPT2SAS_ADAPTER { u32 event_masks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS]; /* static config pages */ - struct mpt2sas_facts facts; - struct mpt2sas_port_facts *pfacts; + Mpi2IOCFactsReply_t facts; + Mpi2PortFactsReply_t *pfacts; Mpi2ManufacturingPage0_t manu_pg0; Mpi2BiosPage2_t bios_pg2; Mpi2BiosPage3_t bios_pg3; @@ -886,7 +840,7 @@ struct MPT2SAS_ADAPTER { /* reply free queue */ u16 reply_free_queue_depth; - __le32 *reply_free; + u32 *reply_free; dma_addr_t reply_free_dma; struct dma_pool *reply_free_dma_pool; u32 reply_free_host_index; diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c index d1c3bba7e936..437c2d94c45a 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c +++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c @@ -2706,13 +2706,13 @@ static DEVICE_ATTR(ioc_reset_count, S_IRUGO, _ctl_ioc_reset_count_show, NULL); struct DIAG_BUFFER_START { - __le32 Size; - __le32 DiagVersion; + u32 Size; + u32 DiagVersion; u8 BufferType; u8 Reserved[3]; - __le32 Reserved1; - __le32 Reserved2; - __le32 Reserved3; + u32 Reserved1; + u32 Reserved2; + u32 Reserved3; }; /** * _ctl_host_trace_buffer_size_show - host buffer size (trace only) diff --git a/drivers/scsi/mpt2sas/mpt2sas_debug.h b/drivers/scsi/mpt2sas/mpt2sas_debug.h index 9731f8e661bf..3dcddfeb6f4c 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_debug.h +++ b/drivers/scsi/mpt2sas/mpt2sas_debug.h @@ -164,7 +164,7 @@ static inline void _debug_dump_mf(void *mpi_request, int sz) { int i; - __le32 *mfp = (__le32 *)mpi_request; + u32 *mfp = (u32 *)mpi_request; printk(KERN_INFO "mf:\n\t"); for (i = 0; i < sz; i++) { diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index aa51195a7312..a7dbc6825f5f 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -974,8 +974,8 @@ _scsih_get_chain_buffer_tracker(struct MPT2SAS_ADAPTER *ioc, u16 smid) spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); if (list_empty(&ioc->free_chain_list)) { spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); - dfailprintk(ioc, printk(MPT2SAS_WARN_FMT "chain buffers not " - "available\n", ioc->name)); + printk(MPT2SAS_WARN_FMT "chain buffers not available\n", + ioc->name); return NULL; } chain_req = list_entry(ioc->free_chain_list.next, @@ -1956,7 +1956,7 @@ _scsih_slave_configure(struct scsi_device *sdev) case MPI2_RAID_VOL_TYPE_RAID1E: qdepth = MPT2SAS_RAID_QUEUE_DEPTH; if (ioc->manu_pg10.OEMIdentifier && - (le32_to_cpu(ioc->manu_pg10.GenericFlags0) & + (ioc->manu_pg10.GenericFlags0 & MFG10_GF0_R10_DISPLAY) && !(raid_device->num_pds % 2)) r_level = "RAID10"; @@ -3698,7 +3698,7 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) return 0; } - if (ioc->pci_error_recovery || ioc->remove_host) { + if (ioc->pci_error_recovery) { scmd->result = DID_NO_CONNECT << 16; scmd->scsi_done(scmd); return 0; @@ -4145,7 +4145,7 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) /* insert into event log */ sz = offsetof(Mpi2EventNotificationReply_t, EventData) + sizeof(Mpi2EventDataSasDeviceStatusChange_t); - event_reply = kzalloc(sz, GFP_ATOMIC); + event_reply = kzalloc(sz, GFP_KERNEL); if (!event_reply) { printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); @@ -4598,7 +4598,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) Mpi2SasEnclosurePage0_t enclosure_pg0; u32 ioc_status; u16 parent_handle; - u64 sas_address, sas_address_parent = 0; + __le64 sas_address, sas_address_parent = 0; int i; unsigned long flags; struct _sas_port *mpt2sas_port = NULL; @@ -5404,7 +5404,7 @@ _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc, { struct MPT2SAS_TARGET *target_priv_data; struct _sas_device *sas_device; - u64 sas_address; + __le64 sas_address; unsigned long flags; Mpi2EventDataSasDeviceStatusChange_t *event_data = fw_event->event_data; @@ -6425,7 +6425,6 @@ _scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid, } else sas_target_priv_data = NULL; raid_device->responding = 1; - spin_unlock_irqrestore(&ioc->raid_device_lock, flags); starget_printk(KERN_INFO, raid_device->starget, "handle(0x%04x), wwid(0x%016llx)\n", handle, (unsigned long long)raid_device->wwid); @@ -6436,16 +6435,16 @@ _scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid, */ _scsih_init_warpdrive_properties(ioc, raid_device); if (raid_device->handle == handle) - return; + goto out; printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", raid_device->handle); raid_device->handle = handle; if (sas_target_priv_data) sas_target_priv_data->handle = handle; - return; + goto out; } } - + out: spin_unlock_irqrestore(&ioc->raid_device_lock, flags); } @@ -6567,7 +6566,7 @@ _scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc) Mpi2ExpanderPage0_t expander_pg0; Mpi2ConfigReply_t mpi_reply; u16 ioc_status; - u64 sas_address; + __le64 sas_address; u16 handle; printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__); @@ -7212,7 +7211,7 @@ _scsih_remove(struct pci_dev *pdev) } sas_remove_host(shost); - mpt2sas_base_detach(ioc); + _scsih_shutdown(pdev); list_del(&ioc->list); scsi_remove_host(shost); scsi_host_put(shost); @@ -7320,27 +7319,22 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc) /* SAS Device List */ list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list, list) { + spin_lock_irqsave(&ioc->sas_device_lock, flags); + list_move_tail(&sas_device->list, &ioc->sas_device_list); + spin_unlock_irqrestore(&ioc->sas_device_lock, flags); if (ioc->hide_drives) continue; if (!mpt2sas_transport_port_add(ioc, sas_device->handle, sas_device->sas_address_parent)) { - list_del(&sas_device->list); - kfree(sas_device); - continue; + _scsih_sas_device_remove(ioc, sas_device); } else if (!sas_device->starget) { mpt2sas_transport_port_remove(ioc, sas_device->sas_address, sas_device->sas_address_parent); - list_del(&sas_device->list); - kfree(sas_device); - continue; - + _scsih_sas_device_remove(ioc, sas_device); } - spin_lock_irqsave(&ioc->sas_device_lock, flags); - list_move_tail(&sas_device->list, &ioc->sas_device_list); - spin_unlock_irqrestore(&ioc->sas_device_lock, flags); } } @@ -7511,7 +7505,7 @@ _scsih_suspend(struct pci_dev *pdev, pm_message_t state) { struct Scsi_Host *shost = pci_get_drvdata(pdev); struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); - pci_power_t device_state; + u32 device_state; mpt2sas_base_stop_watchdog(ioc); scsi_block_requests(shost); @@ -7538,7 +7532,7 @@ _scsih_resume(struct pci_dev *pdev) { struct Scsi_Host *shost = pci_get_drvdata(pdev); struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); - pci_power_t device_state = pdev->current_state; + u32 device_state = pdev->current_state; int r; printk(MPT2SAS_INFO_FMT "pdev=0x%p, slot=%s, previous " diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c index 15c798026217..cb1cdecbe0f8 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_transport.c +++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c @@ -299,6 +299,7 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc, void *data_out = NULL; dma_addr_t data_out_dma; u32 sz; + u64 *sas_address_le; u16 wait_state_count; if (ioc->shost_recovery || ioc->pci_error_recovery) { @@ -371,7 +372,8 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc, mpi_request->PhysicalPort = 0xFF; mpi_request->VF_ID = 0; /* TODO */ mpi_request->VP_ID = 0; - mpi_request->SASAddress = cpu_to_le64(sas_address); + sas_address_le = (u64 *)&mpi_request->SASAddress; + *sas_address_le = cpu_to_le64(sas_address); mpi_request->RequestDataLength = cpu_to_le16(sizeof(struct rep_manu_request)); psge = &mpi_request->SGL; @@ -1047,14 +1049,14 @@ struct phy_error_log_reply{ u8 function; /* 0x11 */ u8 function_result; u8 response_length; - __be16 expander_change_count; + u16 expander_change_count; u8 reserved_1[3]; u8 phy_identifier; u8 reserved_2[2]; - __be32 invalid_dword; - __be32 running_disparity_error; - __be32 loss_of_dword_sync; - __be32 phy_reset_problem; + u32 invalid_dword; + u32 running_disparity_error; + u32 loss_of_dword_sync; + u32 phy_reset_problem; }; /** @@ -1083,6 +1085,7 @@ _transport_get_expander_phy_error_log(struct MPT2SAS_ADAPTER *ioc, void *data_out = NULL; dma_addr_t data_out_dma; u32 sz; + u64 *sas_address_le; u16 wait_state_count; if (ioc->shost_recovery || ioc->pci_error_recovery) { @@ -1157,7 +1160,8 @@ _transport_get_expander_phy_error_log(struct MPT2SAS_ADAPTER *ioc, mpi_request->PhysicalPort = 0xFF; mpi_request->VF_ID = 0; /* TODO */ mpi_request->VP_ID = 0; - mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); + sas_address_le = (u64 *)&mpi_request->SASAddress; + *sas_address_le = cpu_to_le64(phy->identify.sas_address); mpi_request->RequestDataLength = cpu_to_le16(sizeof(struct phy_error_log_request)); psge = &mpi_request->SGL; @@ -1402,6 +1406,7 @@ _transport_expander_phy_control(struct MPT2SAS_ADAPTER *ioc, void *data_out = NULL; dma_addr_t data_out_dma; u32 sz; + u64 *sas_address_le; u16 wait_state_count; if (ioc->shost_recovery) { @@ -1481,7 +1486,8 @@ _transport_expander_phy_control(struct MPT2SAS_ADAPTER *ioc, mpi_request->PhysicalPort = 0xFF; mpi_request->VF_ID = 0; /* TODO */ mpi_request->VP_ID = 0; - mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); + sas_address_le = (u64 *)&mpi_request->SASAddress; + *sas_address_le = cpu_to_le64(phy->identify.sas_address); mpi_request->RequestDataLength = cpu_to_le16(sizeof(struct phy_error_log_request)); psge = &mpi_request->SGL; @@ -1908,7 +1914,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, mpi_request->PhysicalPort = 0xFF; mpi_request->VF_ID = 0; /* TODO */ mpi_request->VP_ID = 0; - mpi_request->SASAddress = (rphy) ? + *((u64 *)&mpi_request->SASAddress) = (rphy) ? cpu_to_le64(rphy->identify.sas_address) : cpu_to_le64(ioc->sas_hba.sas_address); mpi_request->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4); diff --git a/drivers/scsi/mvsas/mv_94xx.h b/drivers/scsi/mvsas/mv_94xx.h index d72aa6182bc5..8835befe2c0e 100644 --- a/drivers/scsi/mvsas/mv_94xx.h +++ b/drivers/scsi/mvsas/mv_94xx.h @@ -193,11 +193,21 @@ struct mvs_prd { #define SPI_ADDR_VLD_94XX (1U << 1) #define SPI_CTRL_SpiStart_94XX (1U << 0) +#define mv_ffc(x) ffz(x) + static inline int mv_ffc64(u64 v) { - u64 x = ~v; - return x ? __ffs64(x) : -1; + int i; + i = mv_ffc((u32)v); + if (i >= 0) + return i; + i = mv_ffc((u32)(v>>32)); + + if (i != 0) + return 32 + i; + + return -1; } #define r_reg_set_enable(i) \ diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h index efc6965ca67f..1367d8b9350d 100644 --- a/drivers/scsi/mvsas/mv_sas.h +++ b/drivers/scsi/mvsas/mv_sas.h @@ -73,7 +73,7 @@ extern struct kmem_cache *mvs_task_list_cache; #define DEV_IS_EXPANDER(type) \ ((type == EDGE_DEV) || (type == FANOUT_DEV)) -#define bit(n) ((u64)1 << n) +#define bit(n) ((u32)1 << n) #define for_each_phy(__lseq_mask, __mc, __lseq) \ for ((__mc) = (__lseq_mask), (__lseq) = 0; \ diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c index d4ed9eb52657..b31a8e3841d7 100644 --- a/drivers/scsi/osd/osd_uld.c +++ b/drivers/scsi/osd/osd_uld.c @@ -69,10 +69,10 @@ #ifndef SCSI_OSD_MAJOR # define SCSI_OSD_MAJOR 260 #endif -#define SCSI_OSD_MAX_MINOR MINORMASK +#define SCSI_OSD_MAX_MINOR 64 static const char osd_name[] = "osd"; -static const char *osd_version_string = "open-osd 0.2.1"; +static const char *osd_version_string = "open-osd 0.2.0"; MODULE_AUTHOR("Boaz Harrosh "); MODULE_DESCRIPTION("open-osd Upper-Layer-Driver osd.ko"); diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index d079f9a3c6b3..fca6a8953070 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -3871,9 +3871,6 @@ static long pmcraid_ioctl_passthrough( pmcraid_err("couldn't build passthrough ioadls\n"); goto out_free_buffer; } - } else if (request_size < 0) { - rc = -EINVAL; - goto out_free_buffer; } /* If data is being written into the device, copy the data from user diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index b2df2f9097b1..920b76bfbb93 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -3822,12 +3822,15 @@ qla2x00_loop_resync(scsi_qla_host_t *vha) req = vha->req; rsp = req->rsp; + atomic_set(&vha->loop_state, LOOP_UPDATE); clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags); if (vha->flags.online) { if (!(rval = qla2x00_fw_ready(vha))) { /* Wait at most MAX_TARGET RSCNs for a stable link. */ wait_time = 256; do { + atomic_set(&vha->loop_state, LOOP_UPDATE); + /* Issue a marker after FW becomes ready. */ qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL); diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index e0fa877a58df..1b60a95adb50 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -736,6 +736,7 @@ skip_rio: vha->flags.rscn_queue_overflow = 1; } + atomic_set(&vha->loop_state, LOOP_UPDATE); atomic_set(&vha->loop_down_timer, 0); vha->flags.management_server_logged_in = 0; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 7e78020b355d..f461925a9dfc 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1240,9 +1240,10 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) qla2x00_sp_compl(ha, sp); } else { ctx = sp->ctx; - if (ctx->type == SRB_ELS_CMD_RPT || - ctx->type == SRB_ELS_CMD_HST || - ctx->type == SRB_CT_CMD) { + if (ctx->type == SRB_LOGIN_CMD || + ctx->type == SRB_LOGOUT_CMD) { + ctx->u.iocb_cmd->free(sp); + } else { struct fc_bsg_job *bsg_job = ctx->u.bsg_job; if (bsg_job->request->msgcode @@ -1254,8 +1255,6 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) kfree(sp->ctx); mempool_free(sp, ha->srb_mempool); - } else { - ctx->u.iocb_cmd->free(sp); } } } @@ -3406,9 +3405,9 @@ qla2x00_do_dpc(void *data) base_vha->host_no)); } - if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, - &base_vha->dpc_flags)) { + if (test_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags)) { qla2x00_update_fcports(base_vha); + clear_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags); } if (test_bit(ISP_QUIESCE_NEEDED, &base_vha->dpc_flags)) { diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index cf8dfab9489f..82e9e5c0476e 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -197,7 +197,6 @@ static struct { {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"IBM", "2105", NULL, BLIST_RETRY_HWERROR}, {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN}, - {"IOMEGA", "ZIP", NULL, BLIST_NOTQ | BLIST_NOLUN}, {"IOMEGA", "Io20S *F", NULL, BLIST_KEY}, {"INSITE", "Floptical F*8I", NULL, BLIST_KEY}, {"INSITE", "I325VM", NULL, BLIST_KEY}, @@ -244,7 +243,6 @@ static struct { {"Tornado-", "F4", "*", BLIST_NOREPORTLUN}, {"TOSHIBA", "CDROM", NULL, BLIST_ISROM}, {"TOSHIBA", "CD-ROM", NULL, BLIST_ISROM}, - {"Traxdata", "CDR4120", NULL, BLIST_NOLUN}, /* locks up */ {"USB2.0", "SMARTMEDIA/XD", NULL, BLIST_FORCELUN | BLIST_INQUIRY_36}, {"WangDAT", "Model 2600", "01.7", BLIST_SELECT_NO_ATN}, {"WangDAT", "Model 3200", "02.2", BLIST_SELECT_NO_ATN}, diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 198e4cda1e68..a4b9cdbaaa0b 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -41,8 +41,6 @@ #include -static void scsi_eh_done(struct scsi_cmnd *scmd); - #define SENSE_TIMEOUT (10*HZ) /* @@ -242,14 +240,6 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) if (! scsi_command_normalize_sense(scmd, &sshdr)) return FAILED; /* no valid sense data */ - if (scmd->cmnd[0] == TEST_UNIT_READY && scmd->scsi_done != scsi_eh_done) - /* - * nasty: for mid-layer issued TURs, we need to return the - * actual sense data without any recovery attempt. For eh - * issued ones, we need to try to recover and interpret - */ - return SUCCESS; - if (scsi_sense_is_deferred(&sshdr)) return NEEDS_RETRY; @@ -1675,20 +1665,6 @@ static void scsi_restart_operations(struct Scsi_Host *shost) * requests are started. */ scsi_run_host_queues(shost); - - /* - * if eh is active and host_eh_scheduled is pending we need to re-run - * recovery. we do this check after scsi_run_host_queues() to allow - * everything pent up since the last eh run a chance to make forward - * progress before we sync again. Either we'll immediately re-run - * recovery or scsi_device_unbusy() will wake us again when these - * pending commands complete. - */ - spin_lock_irqsave(shost->host_lock, flags); - if (shost->host_eh_scheduled) - if (scsi_host_set_state(shost, SHOST_RECOVERY)) - WARN_ON(scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY)); - spin_unlock_irqrestore(shost->host_lock, flags); } /** diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index dd454c4f99aa..ec1803a48723 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -213,8 +213,6 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, int ret = DRIVER_ERROR << 24; req = blk_get_request(sdev->request_queue, write, __GFP_WAIT); - if (!req) - return ret; if (bufflen && blk_rq_map_kern(sdev->request_queue, req, buffer, bufflen, __GFP_WAIT)) @@ -481,26 +479,15 @@ void scsi_requeue_run_queue(struct work_struct *work) */ static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd) { - struct scsi_device *sdev = cmd->device; struct request *req = cmd->request; unsigned long flags; - /* - * We need to hold a reference on the device to avoid the queue being - * killed after the unlock and before scsi_run_queue is invoked which - * may happen because scsi_unprep_request() puts the command which - * releases its reference on the device. - */ - get_device(&sdev->sdev_gendev); - spin_lock_irqsave(q->queue_lock, flags); scsi_unprep_request(req); blk_requeue_request(q, req); spin_unlock_irqrestore(q->queue_lock, flags); scsi_run_queue(q); - - put_device(&sdev->sdev_gendev); } void scsi_next_command(struct scsi_cmnd *cmd) @@ -1391,19 +1378,16 @@ static int scsi_lld_busy(struct request_queue *q) { struct scsi_device *sdev = q->queuedata; struct Scsi_Host *shost; + struct scsi_target *starget; if (!sdev) return 0; shost = sdev->host; + starget = scsi_target(sdev); - /* - * Ignore host/starget busy state. - * Since block layer does not have a concept of fairness across - * multiple queues, congestion of host/starget needs to be handled - * in SCSI layer. - */ - if (scsi_host_in_recovery(shost) || scsi_device_is_busy(sdev)) + if (scsi_host_in_recovery(shost) || scsi_host_is_busy(shost) || + scsi_target_is_busy(starget) || scsi_device_is_busy(sdev)) return 1; return 0; @@ -1421,8 +1405,6 @@ static void scsi_kill_request(struct request *req, struct request_queue *q) blk_start_request(req); - scmd_printk(KERN_INFO, cmd, "killing request\n"); - sdev = cmd->device; starget = scsi_target(sdev); shost = sdev->host; @@ -1504,6 +1486,7 @@ static void scsi_request_fn(struct request_queue *q) struct request *req; if (!sdev) { + printk("scsi: killing requests for dead queue\n"); while ((req = blk_peek_request(q)) != NULL) scsi_kill_request(req, q); return; @@ -1712,15 +1695,6 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev) void scsi_free_queue(struct request_queue *q) { - unsigned long flags; - - WARN_ON(q->queuedata); - - /* cause scsi_request_fn() to kill all non-finished requests */ - spin_lock_irqsave(q->queue_lock, flags); - q->request_fn(q); - spin_unlock_irqrestore(q->queue_lock, flags); - blk_cleanup_queue(q); } diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c index 122a5a2020ad..d70e91ae60af 100644 --- a/drivers/scsi/scsi_pm.c +++ b/drivers/scsi/scsi_pm.c @@ -6,7 +6,6 @@ */ #include -#include #include #include @@ -69,19 +68,6 @@ static int scsi_bus_resume_common(struct device *dev) return err; } -static int scsi_bus_prepare(struct device *dev) -{ - if (scsi_is_sdev_device(dev)) { - /* sd probing uses async_schedule. Wait until it finishes. */ - async_synchronize_full(); - - } else if (scsi_is_host_device(dev)) { - /* Wait until async scanning is finished */ - scsi_complete_async_scans(); - } - return 0; -} - static int scsi_bus_suspend(struct device *dev) { return scsi_bus_suspend_common(dev, PMSG_SUSPEND); @@ -100,7 +86,6 @@ static int scsi_bus_poweroff(struct device *dev) #else /* CONFIG_PM_SLEEP */ #define scsi_bus_resume_common NULL -#define scsi_bus_prepare NULL #define scsi_bus_suspend NULL #define scsi_bus_freeze NULL #define scsi_bus_poweroff NULL @@ -209,7 +194,6 @@ void scsi_autopm_put_host(struct Scsi_Host *shost) #endif /* CONFIG_PM_RUNTIME */ const struct dev_pm_ops scsi_bus_pm_ops = { - .prepare = scsi_bus_prepare, .suspend = scsi_bus_suspend, .resume = scsi_bus_resume_common, .freeze = scsi_bus_freeze, diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 5b475d0832cb..2a588955423a 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -110,7 +110,6 @@ extern void scsi_exit_procfs(void); #endif /* CONFIG_PROC_FS */ /* scsi_scan.c */ -extern int scsi_complete_async_scans(void); extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int, unsigned int, unsigned int, int); extern void scsi_forget_host(struct Scsi_Host *); diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index c6c80c9c9601..44e8ca398efa 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -319,7 +319,10 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, return sdev; out_device_destroy: - __scsi_remove_device(sdev); + scsi_device_set_state(sdev, SDEV_DEL); + transport_destroy_device(&sdev->sdev_gendev); + put_device(&sdev->sdev_dev); + put_device(&sdev->sdev_gendev); out: if (display_failure_msg) printk(ALLOC_FAILURE_MSG, __func__); @@ -776,16 +779,6 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, sdev->model = (char *) (sdev->inquiry + 16); sdev->rev = (char *) (sdev->inquiry + 32); - if (strncmp(sdev->vendor, "ATA ", 8) == 0) { - /* - * sata emulation layer device. This is a hack to work around - * the SATL power management specifications which state that - * when the SATL detects the device has gone into standby - * mode, it shall respond with NOT READY. - */ - sdev->allow_restart = 1; - } - if (*bflags & BLIST_ISROM) { sdev->type = TYPE_ROM; sdev->removable = 1; @@ -1720,9 +1713,6 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost) { struct scsi_device *sdev; shost_for_each_device(sdev, shost) { - /* target removed before the device could be added */ - if (sdev->sdev_state == SDEV_DEL) - continue; if (!scsi_host_scan_allowed(shost) || scsi_sysfs_add_sdev(sdev) != 0) __scsi_remove_device(sdev); @@ -1828,7 +1818,6 @@ static void scsi_finish_async_scan(struct async_scan_data *data) } spin_unlock(&async_scan_lock); - scsi_autopm_put_host(shost); scsi_host_put(shost); kfree(data); } @@ -1855,6 +1844,7 @@ static int do_scan_async(void *_data) do_scsi_scan_host(shost); scsi_finish_async_scan(data); + scsi_autopm_put_host(shost); return 0; } @@ -1882,7 +1872,7 @@ void scsi_scan_host(struct Scsi_Host *shost) p = kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no); if (IS_ERR(p)) do_scan_async(data); - /* scsi_autopm_put_host(shost) is called in scsi_finish_async_scan() */ + /* scsi_autopm_put_host(shost) is called in do_scan_async() */ } EXPORT_SYMBOL(scsi_scan_host); diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 51d823f5465a..e0bd3f790fca 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -962,6 +962,7 @@ static void __scsi_remove_target(struct scsi_target *starget) struct scsi_device *sdev; spin_lock_irqsave(shost->host_lock, flags); + starget->reap_ref++; restart: list_for_each_entry(sdev, &shost->__devices, siblings) { if (sdev->channel != starget->channel || @@ -975,6 +976,14 @@ static void __scsi_remove_target(struct scsi_target *starget) goto restart; } spin_unlock_irqrestore(shost->host_lock, flags); + scsi_target_reap(starget); +} + +static int __remove_child (struct device * dev, void * data) +{ + if (scsi_is_target_device(dev)) + __scsi_remove_target(to_scsi_target(dev)); + return 0; } /** @@ -987,32 +996,14 @@ static void __scsi_remove_target(struct scsi_target *starget) */ void scsi_remove_target(struct device *dev) { - struct Scsi_Host *shost = dev_to_shost(dev->parent); - struct scsi_target *starget, *last = NULL; - unsigned long flags; - - /* remove targets being careful to lookup next entry before - * deleting the last - */ - spin_lock_irqsave(shost->host_lock, flags); - list_for_each_entry(starget, &shost->__targets, siblings) { - if (starget->state == STARGET_DEL) - continue; - if (starget->dev.parent == dev || &starget->dev == dev) { - /* assuming new targets arrive at the end */ - starget->reap_ref++; - spin_unlock_irqrestore(shost->host_lock, flags); - if (last) - scsi_target_reap(last); - last = starget; - __scsi_remove_target(starget); - spin_lock_irqsave(shost->host_lock, flags); - } + if (scsi_is_target_device(dev)) { + __scsi_remove_target(to_scsi_target(dev)); + return; } - spin_unlock_irqrestore(shost->host_lock, flags); - if (last) - scsi_target_reap(last); + get_device(dev); + device_for_each_child(dev, NULL, __remove_child); + put_device(dev); } EXPORT_SYMBOL(scsi_remove_target); diff --git a/drivers/scsi/scsi_wait_scan.c b/drivers/scsi/scsi_wait_scan.c index ae7814874618..74708fcaf82f 100644 --- a/drivers/scsi/scsi_wait_scan.c +++ b/drivers/scsi/scsi_wait_scan.c @@ -12,7 +12,7 @@ #include #include -#include "scsi_priv.h" +#include static int __init wait_scan_init(void) { diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 515ec6d64fb4..953773cb26d9 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1073,10 +1073,6 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode, SCSI_LOG_IOCTL(1, printk("sd_ioctl: disk=%s, cmd=0x%x\n", disk->disk_name, cmd)); - error = scsi_verify_blk_ioctl(bdev, cmd); - if (error < 0) - return error; - /* * If we are in the middle of error recovery, don't let anyone * else try and use this device. Also, if error recovery fails, it @@ -1099,7 +1095,7 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode, error = scsi_ioctl(sdp, cmd, p); break; default: - error = scsi_cmd_blk_ioctl(bdev, mode, cmd, p); + error = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, p); if (error != -ENOTTY) break; error = scsi_ioctl(sdp, cmd, p); @@ -1269,11 +1265,6 @@ static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { struct scsi_device *sdev = scsi_disk(bdev->bd_disk)->device; - int ret; - - ret = scsi_verify_blk_ioctl(bdev, cmd); - if (ret < 0) - return -ENOIOCTLCMD; /* * If we are in the middle of error recovery, don't let anyone @@ -1285,6 +1276,8 @@ static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode, return -ENODEV; if (sdev->host->hostt->compat_ioctl) { + int ret; + ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg); return ret; @@ -2826,6 +2819,10 @@ static int __init init_sd(void) if (err) goto err_out; + err = scsi_register_driver(&sd_template.gendrv); + if (err) + goto err_out_class; + sd_cdb_cache = kmem_cache_create("sd_ext_cdb", SD_EXT_CDB_SIZE, 0, 0, NULL); if (!sd_cdb_cache) { @@ -2839,15 +2836,8 @@ static int __init init_sd(void) goto err_out_cache; } - err = scsi_register_driver(&sd_template.gendrv); - if (err) - goto err_out_driver; - return 0; -err_out_driver: - mempool_destroy(sd_cdb_pool); - err_out_cache: kmem_cache_destroy(sd_cdb_cache); @@ -2870,10 +2860,10 @@ static void __exit exit_sd(void) SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n")); - scsi_unregister_driver(&sd_template.gendrv); mempool_destroy(sd_cdb_pool); kmem_cache_destroy(sd_cdb_cache); + scsi_unregister_driver(&sd_template.gendrv); class_unregister(&sd_disk_class); for (i = 0; i < SD_MAJORS; i++) diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index eba183c428cf..eb7a3e85304f 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -160,10 +160,6 @@ static unsigned char *ses_get_page2_descriptor(struct enclosure_device *edev, return NULL; } -/* For device slot and array device slot elements, byte 3 bit 6 - * is "fault sensed" while byte 3 bit 5 is "fault reqstd". As this - * code stands these bits are shifted 4 positions right so in - * sysfs they will appear as bits 2 and 1 respectively. Strange. */ static void ses_get_fault(struct enclosure_device *edev, struct enclosure_component *ecomp) { @@ -185,7 +181,7 @@ static int ses_set_fault(struct enclosure_device *edev, /* zero is disabled */ break; case ENCLOSURE_SETTING_ENABLED: - desc[3] = 0x20; + desc[2] = 0x02; break; default: /* SES doesn't do the SGPIO blink settings */ diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 5fc97d2ba2fd..4778e2707168 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -221,33 +221,14 @@ static unsigned int sr_check_events(struct cdrom_device_info *cdi, return 0; events = sr_get_events(cd->device); - cd->get_event_changed |= events & DISK_EVENT_MEDIA_CHANGE; - - /* - * If earlier GET_EVENT_STATUS_NOTIFICATION and TUR did not agree - * for several times in a row. We rely on TUR only for this likely - * broken device, to prevent generating incorrect media changed - * events for every open(). - */ - if (cd->ignore_get_event) { - events &= ~DISK_EVENT_MEDIA_CHANGE; - goto do_tur; - } - /* * GET_EVENT_STATUS_NOTIFICATION is enough unless MEDIA_CHANGE * is being cleared. Note that there are devices which hang * if asked to execute TUR repeatedly. */ - if (cd->device->changed) { - events |= DISK_EVENT_MEDIA_CHANGE; - cd->device->changed = 0; - cd->tur_changed = true; - } - if (!(clearing & DISK_EVENT_MEDIA_CHANGE)) - return events; -do_tur: + goto skip_tur; + /* let's see whether the media is there with TUR */ last_present = cd->media_present; ret = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr); @@ -261,31 +242,12 @@ do_tur: (scsi_sense_valid(&sshdr) && sshdr.asc != 0x3a); if (last_present != cd->media_present) - cd->device->changed = 1; - + events |= DISK_EVENT_MEDIA_CHANGE; +skip_tur: if (cd->device->changed) { events |= DISK_EVENT_MEDIA_CHANGE; cd->device->changed = 0; - cd->tur_changed = true; - } - - if (cd->ignore_get_event) - return events; - - /* check whether GET_EVENT is reporting spurious MEDIA_CHANGE */ - if (!cd->tur_changed) { - if (cd->get_event_changed) { - if (cd->tur_mismatch++ > 8) { - sdev_printk(KERN_WARNING, cd->device, - "GET_EVENT and TUR disagree continuously, suppress GET_EVENT events\n"); - cd->ignore_get_event = true; - } - } else { - cd->tur_mismatch = 0; - } } - cd->tur_changed = false; - cd->get_event_changed = false; return events; } diff --git a/drivers/scsi/sr.h b/drivers/scsi/sr.h index 37c8f6b17510..e036f1dc83c8 100644 --- a/drivers/scsi/sr.h +++ b/drivers/scsi/sr.h @@ -41,13 +41,6 @@ typedef struct scsi_cd { unsigned readcd_known:1; /* drive supports READ_CD (0xbe) */ unsigned readcd_cdda:1; /* reading audio data using READ_CD */ unsigned media_present:1; /* media is present */ - - /* GET_EVENT spurious event handling, blk layer guarantees exclusion */ - int tur_mismatch; /* nr of get_event TUR mismatches */ - bool tur_changed:1; /* changed according to TUR */ - bool get_event_changed:1; /* changed according to GET_EVENT */ - bool ignore_get_event:1; /* GET_EVENT is unreliable, use TUR */ - struct cdrom_device_info cdi; /* We hold gendisk and scsi_device references on probe and use * the refs on this kref to decide when to release them */ diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 9b28f39bac26..1871b8ae83ae 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -462,16 +462,14 @@ static void st_scsi_execute_end(struct request *req, int uptodate) { struct st_request *SRpnt = req->end_io_data; struct scsi_tape *STp = SRpnt->stp; - struct bio *tmp; STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors; STp->buffer->cmdstat.residual = req->resid_len; - tmp = SRpnt->bio; if (SRpnt->waiting) complete(SRpnt->waiting); - blk_rq_unmap_user(tmp); + blk_rq_unmap_user(SRpnt->bio); __blk_put_request(req->q, req); } diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 36d1ed7817eb..b4543f575f46 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -839,10 +839,6 @@ static void sym53c8xx_slave_destroy(struct scsi_device *sdev) struct sym_lcb *lp = sym_lp(tp, sdev->lun); unsigned long flags; - /* if slave_alloc returned before allocating a sym_lcb, return */ - if (!lp) - return; - spin_lock_irqsave(np->s.host->host_lock, flags); if (lp->busy_itlq || lp->busy_itl) { diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index b423fe92a785..2e13a14bba3f 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -318,7 +318,7 @@ struct spi_device *spi_alloc_device(struct spi_master *master) } spi->master = master; - spi->dev.parent = &master->dev; + spi->dev.parent = dev; spi->dev.bus = &spi_bus_type; spi->dev.release = spidev_release; device_initialize(&spi->dev); diff --git a/drivers/spi/spi_fsl_spi.c b/drivers/spi/spi_fsl_spi.c index a725b07276e6..7963c9b49566 100644 --- a/drivers/spi/spi_fsl_spi.c +++ b/drivers/spi/spi_fsl_spi.c @@ -139,12 +139,10 @@ static void fsl_spi_change_mode(struct spi_device *spi) static void fsl_spi_chipselect(struct spi_device *spi, int value) { struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); - struct fsl_spi_platform_data *pdata; + struct fsl_spi_platform_data *pdata = spi->dev.parent->platform_data; bool pol = spi->mode & SPI_CS_HIGH; struct spi_mpc8xxx_cs *cs = spi->controller_state; - pdata = spi->dev.parent->parent->platform_data; - if (value == BITBANG_CS_INACTIVE) { if (pdata->cs_control) pdata->cs_control(spi, !pol); @@ -936,7 +934,7 @@ err: static void fsl_spi_cs_control(struct spi_device *spi, bool on) { - struct device *dev = spi->dev.parent->parent; + struct device *dev = spi->dev.parent; struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data); u16 cs = spi->chip_select; int gpio = pinfo->gpios[cs]; diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index c828151c419e..d6620ad309ce 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c @@ -516,14 +516,10 @@ static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc) static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc) { - struct ssb_device *pdev = pc->dev; - struct ssb_bus *bus = pdev->bus; - - if (bus->bustype == SSB_BUSTYPE_PCI) - ssb_pcicore_fix_sprom_core_index(pc); + ssb_pcicore_fix_sprom_core_index(pc); /* Disable PCI interrupts. */ - ssb_write32(pdev, SSB_INTVEC, 0); + ssb_write32(pc->dev, SSB_INTVEC, 0); /* Additional PCIe always once-executed workarounds */ if (pc->dev->id.coreid == SSB_DEV_PCIE) { diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 11a4b5b35963..196284dc2f36 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -70,8 +70,6 @@ source "drivers/staging/rts_pstor/Kconfig" source "drivers/staging/frontier/Kconfig" -source "drivers/staging/android/Kconfig" - source "drivers/staging/pohmelfs/Kconfig" source "drivers/staging/phison/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index ae62e923e1b8..fa41b9c23783 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -29,7 +29,6 @@ obj-$(CONFIG_R8712U) += rtl8712/ obj-$(CONFIG_RTS_PSTOR) += rts_pstor/ obj-$(CONFIG_SPECTRA) += spectra/ obj-$(CONFIG_TRANZPORT) += frontier/ -obj-$(CONFIG_ANDROID) += android/ obj-$(CONFIG_POHMELFS) += pohmelfs/ obj-$(CONFIG_IDE_PHISON) += phison/ obj-$(CONFIG_LINE6_USB) += line6/ diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig deleted file mode 100644 index 247194992374..000000000000 --- a/drivers/staging/android/Kconfig +++ /dev/null @@ -1,95 +0,0 @@ -menu "Android" - -config ANDROID - bool "Android Drivers" - default N - ---help--- - Enable support for various drivers needed on the Android platform - -if ANDROID - -config ANDROID_BINDER_IPC - bool "Android Binder IPC Driver" - default n - -config ANDROID_LOGGER - tristate "Android log driver" - default n - -config ANDROID_RAM_CONSOLE - bool "Android RAM buffer console" - default n - -config ANDROID_RAM_CONSOLE_ENABLE_VERBOSE - bool "Enable verbose console messages on Android RAM console" - default y - depends on ANDROID_RAM_CONSOLE - -menuconfig ANDROID_RAM_CONSOLE_ERROR_CORRECTION - bool "Android RAM Console Enable error correction" - default n - depends on ANDROID_RAM_CONSOLE - depends on !ANDROID_RAM_CONSOLE_EARLY_INIT - select REED_SOLOMON - select REED_SOLOMON_ENC8 - select REED_SOLOMON_DEC8 - -if ANDROID_RAM_CONSOLE_ERROR_CORRECTION - -config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE - int "Android RAM Console Data data size" - default 128 - help - Must be a power of 2. - -config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE - int "Android RAM Console ECC size" - default 16 - -config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE - int "Android RAM Console Symbol size" - default 8 - -config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL - hex "Android RAM Console Polynomial" - default 0x19 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 4) - default 0x29 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 5) - default 0x61 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 6) - default 0x89 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 7) - default 0x11d if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 8) - -endif # ANDROID_RAM_CONSOLE_ERROR_CORRECTION - -config ANDROID_RAM_CONSOLE_EARLY_INIT - bool "Start Android RAM console early" - default n - depends on ANDROID_RAM_CONSOLE - -config ANDROID_RAM_CONSOLE_EARLY_ADDR - hex "Android RAM console virtual address" - default 0 - depends on ANDROID_RAM_CONSOLE_EARLY_INIT - -config ANDROID_RAM_CONSOLE_EARLY_SIZE - hex "Android RAM console buffer size" - default 0 - depends on ANDROID_RAM_CONSOLE_EARLY_INIT - -config ANDROID_TIMED_OUTPUT - bool "Timed output class driver" - default y - -config ANDROID_TIMED_GPIO - tristate "Android timed gpio driver" - depends on GENERIC_GPIO && ANDROID_TIMED_OUTPUT - default n - -config ANDROID_LOW_MEMORY_KILLER - bool "Android Low Memory Killer" - default N - ---help--- - Register processes to be killed when memory is low - -endif # if ANDROID - -endmenu diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile deleted file mode 100644 index 8e057e626d11..000000000000 --- a/drivers/staging/android/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o -obj-$(CONFIG_ANDROID_LOGGER) += logger.o -obj-$(CONFIG_ANDROID_RAM_CONSOLE) += ram_console.o -obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o -obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o -obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c deleted file mode 100644 index e13b4c483407..000000000000 --- a/drivers/staging/android/binder.c +++ /dev/null @@ -1,3600 +0,0 @@ -/* binder.c - * - * Android IPC Subsystem - * - * Copyright (C) 2007-2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "binder.h" - -static DEFINE_MUTEX(binder_lock); -static DEFINE_MUTEX(binder_deferred_lock); - -static HLIST_HEAD(binder_procs); -static HLIST_HEAD(binder_deferred_list); -static HLIST_HEAD(binder_dead_nodes); - -static struct dentry *binder_debugfs_dir_entry_root; -static struct dentry *binder_debugfs_dir_entry_proc; -static struct binder_node *binder_context_mgr_node; -static uid_t binder_context_mgr_uid = -1; -static int binder_last_id; -static struct workqueue_struct *binder_deferred_workqueue; - -#define BINDER_DEBUG_ENTRY(name) \ -static int binder_##name##_open(struct inode *inode, struct file *file) \ -{ \ - return single_open(file, binder_##name##_show, inode->i_private); \ -} \ -\ -static const struct file_operations binder_##name##_fops = { \ - .owner = THIS_MODULE, \ - .open = binder_##name##_open, \ - .read = seq_read, \ - .llseek = seq_lseek, \ - .release = single_release, \ -} - -static int binder_proc_show(struct seq_file *m, void *unused); -BINDER_DEBUG_ENTRY(proc); - -/* This is only defined in include/asm-arm/sizes.h */ -#ifndef SZ_1K -#define SZ_1K 0x400 -#endif - -#ifndef SZ_4M -#define SZ_4M 0x400000 -#endif - -#define FORBIDDEN_MMAP_FLAGS (VM_WRITE) - -#define BINDER_SMALL_BUF_SIZE (PAGE_SIZE * 64) - -enum { - BINDER_DEBUG_USER_ERROR = 1U << 0, - BINDER_DEBUG_FAILED_TRANSACTION = 1U << 1, - BINDER_DEBUG_DEAD_TRANSACTION = 1U << 2, - BINDER_DEBUG_OPEN_CLOSE = 1U << 3, - BINDER_DEBUG_DEAD_BINDER = 1U << 4, - BINDER_DEBUG_DEATH_NOTIFICATION = 1U << 5, - BINDER_DEBUG_READ_WRITE = 1U << 6, - BINDER_DEBUG_USER_REFS = 1U << 7, - BINDER_DEBUG_THREADS = 1U << 8, - BINDER_DEBUG_TRANSACTION = 1U << 9, - BINDER_DEBUG_TRANSACTION_COMPLETE = 1U << 10, - BINDER_DEBUG_FREE_BUFFER = 1U << 11, - BINDER_DEBUG_INTERNAL_REFS = 1U << 12, - BINDER_DEBUG_BUFFER_ALLOC = 1U << 13, - BINDER_DEBUG_PRIORITY_CAP = 1U << 14, - BINDER_DEBUG_BUFFER_ALLOC_ASYNC = 1U << 15, -}; -static uint32_t binder_debug_mask = BINDER_DEBUG_USER_ERROR | - BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION; -module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO); - -static int binder_debug_no_lock; -module_param_named(proc_no_lock, binder_debug_no_lock, bool, S_IWUSR | S_IRUGO); - -static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait); -static int binder_stop_on_user_error; - -static int binder_set_stop_on_user_error(const char *val, - struct kernel_param *kp) -{ - int ret; - ret = param_set_int(val, kp); - if (binder_stop_on_user_error < 2) - wake_up(&binder_user_error_wait); - return ret; -} -module_param_call(stop_on_user_error, binder_set_stop_on_user_error, - param_get_int, &binder_stop_on_user_error, S_IWUSR | S_IRUGO); - -#define binder_debug(mask, x...) \ - do { \ - if (binder_debug_mask & mask) \ - printk(KERN_INFO x); \ - } while (0) - -#define binder_user_error(x...) \ - do { \ - if (binder_debug_mask & BINDER_DEBUG_USER_ERROR) \ - printk(KERN_INFO x); \ - if (binder_stop_on_user_error) \ - binder_stop_on_user_error = 2; \ - } while (0) - -enum binder_stat_types { - BINDER_STAT_PROC, - BINDER_STAT_THREAD, - BINDER_STAT_NODE, - BINDER_STAT_REF, - BINDER_STAT_DEATH, - BINDER_STAT_TRANSACTION, - BINDER_STAT_TRANSACTION_COMPLETE, - BINDER_STAT_COUNT -}; - -struct binder_stats { - int br[_IOC_NR(BR_FAILED_REPLY) + 1]; - int bc[_IOC_NR(BC_DEAD_BINDER_DONE) + 1]; - int obj_created[BINDER_STAT_COUNT]; - int obj_deleted[BINDER_STAT_COUNT]; -}; - -static struct binder_stats binder_stats; - -static inline void binder_stats_deleted(enum binder_stat_types type) -{ - binder_stats.obj_deleted[type]++; -} - -static inline void binder_stats_created(enum binder_stat_types type) -{ - binder_stats.obj_created[type]++; -} - -struct binder_transaction_log_entry { - int debug_id; - int call_type; - int from_proc; - int from_thread; - int target_handle; - int to_proc; - int to_thread; - int to_node; - int data_size; - int offsets_size; -}; -struct binder_transaction_log { - int next; - int full; - struct binder_transaction_log_entry entry[32]; -}; -static struct binder_transaction_log binder_transaction_log; -static struct binder_transaction_log binder_transaction_log_failed; - -static struct binder_transaction_log_entry *binder_transaction_log_add( - struct binder_transaction_log *log) -{ - struct binder_transaction_log_entry *e; - e = &log->entry[log->next]; - memset(e, 0, sizeof(*e)); - log->next++; - if (log->next == ARRAY_SIZE(log->entry)) { - log->next = 0; - log->full = 1; - } - return e; -} - -struct binder_work { - struct list_head entry; - enum { - BINDER_WORK_TRANSACTION = 1, - BINDER_WORK_TRANSACTION_COMPLETE, - BINDER_WORK_NODE, - BINDER_WORK_DEAD_BINDER, - BINDER_WORK_DEAD_BINDER_AND_CLEAR, - BINDER_WORK_CLEAR_DEATH_NOTIFICATION, - } type; -}; - -struct binder_node { - int debug_id; - struct binder_work work; - union { - struct rb_node rb_node; - struct hlist_node dead_node; - }; - struct binder_proc *proc; - struct hlist_head refs; - int internal_strong_refs; - int local_weak_refs; - int local_strong_refs; - void __user *ptr; - void __user *cookie; - unsigned has_strong_ref:1; - unsigned pending_strong_ref:1; - unsigned has_weak_ref:1; - unsigned pending_weak_ref:1; - unsigned has_async_transaction:1; - unsigned accept_fds:1; - unsigned min_priority:8; - struct list_head async_todo; -}; - -struct binder_ref_death { - struct binder_work work; - void __user *cookie; -}; - -struct binder_ref { - /* Lookups needed: */ - /* node + proc => ref (transaction) */ - /* desc + proc => ref (transaction, inc/dec ref) */ - /* node => refs + procs (proc exit) */ - int debug_id; - struct rb_node rb_node_desc; - struct rb_node rb_node_node; - struct hlist_node node_entry; - struct binder_proc *proc; - struct binder_node *node; - uint32_t desc; - int strong; - int weak; - struct binder_ref_death *death; -}; - -struct binder_buffer { - struct list_head entry; /* free and allocated entries by addesss */ - struct rb_node rb_node; /* free entry by size or allocated entry */ - /* by address */ - unsigned free:1; - unsigned allow_user_free:1; - unsigned async_transaction:1; - unsigned debug_id:29; - - struct binder_transaction *transaction; - - struct binder_node *target_node; - size_t data_size; - size_t offsets_size; - uint8_t data[0]; -}; - -enum binder_deferred_state { - BINDER_DEFERRED_PUT_FILES = 0x01, - BINDER_DEFERRED_FLUSH = 0x02, - BINDER_DEFERRED_RELEASE = 0x04, -}; - -struct binder_proc { - struct hlist_node proc_node; - struct rb_root threads; - struct rb_root nodes; - struct rb_root refs_by_desc; - struct rb_root refs_by_node; - int pid; - struct vm_area_struct *vma; - struct task_struct *tsk; - struct files_struct *files; - struct hlist_node deferred_work_node; - int deferred_work; - void *buffer; - ptrdiff_t user_buffer_offset; - - struct list_head buffers; - struct rb_root free_buffers; - struct rb_root allocated_buffers; - size_t free_async_space; - - struct page **pages; - size_t buffer_size; - uint32_t buffer_free; - struct list_head todo; - wait_queue_head_t wait; - struct binder_stats stats; - struct list_head delivered_death; - int max_threads; - int requested_threads; - int requested_threads_started; - int ready_threads; - long default_priority; - struct dentry *debugfs_entry; -}; - -enum { - BINDER_LOOPER_STATE_REGISTERED = 0x01, - BINDER_LOOPER_STATE_ENTERED = 0x02, - BINDER_LOOPER_STATE_EXITED = 0x04, - BINDER_LOOPER_STATE_INVALID = 0x08, - BINDER_LOOPER_STATE_WAITING = 0x10, - BINDER_LOOPER_STATE_NEED_RETURN = 0x20 -}; - -struct binder_thread { - struct binder_proc *proc; - struct rb_node rb_node; - int pid; - int looper; - struct binder_transaction *transaction_stack; - struct list_head todo; - uint32_t return_error; /* Write failed, return error code in read buf */ - uint32_t return_error2; /* Write failed, return error code in read */ - /* buffer. Used when sending a reply to a dead process that */ - /* we are also waiting on */ - wait_queue_head_t wait; - struct binder_stats stats; -}; - -struct binder_transaction { - int debug_id; - struct binder_work work; - struct binder_thread *from; - struct binder_transaction *from_parent; - struct binder_proc *to_proc; - struct binder_thread *to_thread; - struct binder_transaction *to_parent; - unsigned need_reply:1; - /* unsigned is_dead:1; */ /* not used at the moment */ - - struct binder_buffer *buffer; - unsigned int code; - unsigned int flags; - long priority; - long saved_priority; - uid_t sender_euid; -}; - -static void -binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer); - -/* - * copied from get_unused_fd_flags - */ -int task_get_unused_fd_flags(struct binder_proc *proc, int flags) -{ - struct files_struct *files = proc->files; - int fd, error; - struct fdtable *fdt; - unsigned long rlim_cur; - unsigned long irqs; - - if (files == NULL) - return -ESRCH; - - error = -EMFILE; - spin_lock(&files->file_lock); - -repeat: - fdt = files_fdtable(files); - fd = find_next_zero_bit(fdt->open_fds->fds_bits, fdt->max_fds, - files->next_fd); - - /* - * N.B. For clone tasks sharing a files structure, this test - * will limit the total number of files that can be opened. - */ - rlim_cur = 0; - if (lock_task_sighand(proc->tsk, &irqs)) { - rlim_cur = proc->tsk->signal->rlim[RLIMIT_NOFILE].rlim_cur; - unlock_task_sighand(proc->tsk, &irqs); - } - if (fd >= rlim_cur) - goto out; - - /* Do we need to expand the fd array or fd set? */ - error = expand_files(files, fd); - if (error < 0) - goto out; - - if (error) { - /* - * If we needed to expand the fs array we - * might have blocked - try again. - */ - error = -EMFILE; - goto repeat; - } - - FD_SET(fd, fdt->open_fds); - if (flags & O_CLOEXEC) - FD_SET(fd, fdt->close_on_exec); - else - FD_CLR(fd, fdt->close_on_exec); - files->next_fd = fd + 1; -#if 1 - /* Sanity check */ - if (fdt->fd[fd] != NULL) { - printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd); - fdt->fd[fd] = NULL; - } -#endif - error = fd; - -out: - spin_unlock(&files->file_lock); - return error; -} - -/* - * copied from fd_install - */ -static void task_fd_install( - struct binder_proc *proc, unsigned int fd, struct file *file) -{ - struct files_struct *files = proc->files; - struct fdtable *fdt; - - if (files == NULL) - return; - - spin_lock(&files->file_lock); - fdt = files_fdtable(files); - BUG_ON(fdt->fd[fd] != NULL); - rcu_assign_pointer(fdt->fd[fd], file); - spin_unlock(&files->file_lock); -} - -/* - * copied from __put_unused_fd in open.c - */ -static void __put_unused_fd(struct files_struct *files, unsigned int fd) -{ - struct fdtable *fdt = files_fdtable(files); - __FD_CLR(fd, fdt->open_fds); - if (fd < files->next_fd) - files->next_fd = fd; -} - -/* - * copied from sys_close - */ -static long task_close_fd(struct binder_proc *proc, unsigned int fd) -{ - struct file *filp; - struct files_struct *files = proc->files; - struct fdtable *fdt; - int retval; - - if (files == NULL) - return -ESRCH; - - spin_lock(&files->file_lock); - fdt = files_fdtable(files); - if (fd >= fdt->max_fds) - goto out_unlock; - filp = fdt->fd[fd]; - if (!filp) - goto out_unlock; - rcu_assign_pointer(fdt->fd[fd], NULL); - FD_CLR(fd, fdt->close_on_exec); - __put_unused_fd(files, fd); - spin_unlock(&files->file_lock); - retval = filp_close(filp, files); - - /* can't restart close syscall because file table entry was cleared */ - if (unlikely(retval == -ERESTARTSYS || - retval == -ERESTARTNOINTR || - retval == -ERESTARTNOHAND || - retval == -ERESTART_RESTARTBLOCK)) - retval = -EINTR; - - return retval; - -out_unlock: - spin_unlock(&files->file_lock); - return -EBADF; -} - -static void binder_set_nice(long nice) -{ - long min_nice; - if (can_nice(current, nice)) { - set_user_nice(current, nice); - return; - } - min_nice = 20 - current->signal->rlim[RLIMIT_NICE].rlim_cur; - binder_debug(BINDER_DEBUG_PRIORITY_CAP, - "binder: %d: nice value %ld not allowed use " - "%ld instead\n", current->pid, nice, min_nice); - set_user_nice(current, min_nice); - if (min_nice < 20) - return; - binder_user_error("binder: %d RLIMIT_NICE not set\n", current->pid); -} - -static size_t binder_buffer_size(struct binder_proc *proc, - struct binder_buffer *buffer) -{ - if (list_is_last(&buffer->entry, &proc->buffers)) - return proc->buffer + proc->buffer_size - (void *)buffer->data; - else - return (size_t)list_entry(buffer->entry.next, - struct binder_buffer, entry) - (size_t)buffer->data; -} - -static void binder_insert_free_buffer(struct binder_proc *proc, - struct binder_buffer *new_buffer) -{ - struct rb_node **p = &proc->free_buffers.rb_node; - struct rb_node *parent = NULL; - struct binder_buffer *buffer; - size_t buffer_size; - size_t new_buffer_size; - - BUG_ON(!new_buffer->free); - - new_buffer_size = binder_buffer_size(proc, new_buffer); - - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: add free buffer, size %zd, " - "at %p\n", proc->pid, new_buffer_size, new_buffer); - - while (*p) { - parent = *p; - buffer = rb_entry(parent, struct binder_buffer, rb_node); - BUG_ON(!buffer->free); - - buffer_size = binder_buffer_size(proc, buffer); - - if (new_buffer_size < buffer_size) - p = &parent->rb_left; - else - p = &parent->rb_right; - } - rb_link_node(&new_buffer->rb_node, parent, p); - rb_insert_color(&new_buffer->rb_node, &proc->free_buffers); -} - -static void binder_insert_allocated_buffer(struct binder_proc *proc, - struct binder_buffer *new_buffer) -{ - struct rb_node **p = &proc->allocated_buffers.rb_node; - struct rb_node *parent = NULL; - struct binder_buffer *buffer; - - BUG_ON(new_buffer->free); - - while (*p) { - parent = *p; - buffer = rb_entry(parent, struct binder_buffer, rb_node); - BUG_ON(buffer->free); - - if (new_buffer < buffer) - p = &parent->rb_left; - else if (new_buffer > buffer) - p = &parent->rb_right; - else - BUG(); - } - rb_link_node(&new_buffer->rb_node, parent, p); - rb_insert_color(&new_buffer->rb_node, &proc->allocated_buffers); -} - -static struct binder_buffer *binder_buffer_lookup(struct binder_proc *proc, - void __user *user_ptr) -{ - struct rb_node *n = proc->allocated_buffers.rb_node; - struct binder_buffer *buffer; - struct binder_buffer *kern_ptr; - - kern_ptr = user_ptr - proc->user_buffer_offset - - offsetof(struct binder_buffer, data); - - while (n) { - buffer = rb_entry(n, struct binder_buffer, rb_node); - BUG_ON(buffer->free); - - if (kern_ptr < buffer) - n = n->rb_left; - else if (kern_ptr > buffer) - n = n->rb_right; - else - return buffer; - } - return NULL; -} - -static int binder_update_page_range(struct binder_proc *proc, int allocate, - void *start, void *end, - struct vm_area_struct *vma) -{ - void *page_addr; - unsigned long user_page_addr; - struct vm_struct tmp_area; - struct page **page; - struct mm_struct *mm; - - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: %s pages %p-%p\n", proc->pid, - allocate ? "allocate" : "free", start, end); - - if (end <= start) - return 0; - - if (vma) - mm = NULL; - else - mm = get_task_mm(proc->tsk); - - if (mm) { - down_write(&mm->mmap_sem); - vma = proc->vma; - } - - if (allocate == 0) - goto free_range; - - if (vma == NULL) { - printk(KERN_ERR "binder: %d: binder_alloc_buf failed to " - "map pages in userspace, no vma\n", proc->pid); - goto err_no_vma; - } - - for (page_addr = start; page_addr < end; page_addr += PAGE_SIZE) { - int ret; - struct page **page_array_ptr; - page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE]; - - BUG_ON(*page); - *page = alloc_page(GFP_KERNEL | __GFP_ZERO); - if (*page == NULL) { - printk(KERN_ERR "binder: %d: binder_alloc_buf failed " - "for page at %p\n", proc->pid, page_addr); - goto err_alloc_page_failed; - } - tmp_area.addr = page_addr; - tmp_area.size = PAGE_SIZE + PAGE_SIZE /* guard page? */; - page_array_ptr = page; - ret = map_vm_area(&tmp_area, PAGE_KERNEL, &page_array_ptr); - if (ret) { - printk(KERN_ERR "binder: %d: binder_alloc_buf failed " - "to map page at %p in kernel\n", - proc->pid, page_addr); - goto err_map_kernel_failed; - } - user_page_addr = - (uintptr_t)page_addr + proc->user_buffer_offset; - ret = vm_insert_page(vma, user_page_addr, page[0]); - if (ret) { - printk(KERN_ERR "binder: %d: binder_alloc_buf failed " - "to map page at %lx in userspace\n", - proc->pid, user_page_addr); - goto err_vm_insert_page_failed; - } - /* vm_insert_page does not seem to increment the refcount */ - } - if (mm) { - up_write(&mm->mmap_sem); - mmput(mm); - } - return 0; - -free_range: - for (page_addr = end - PAGE_SIZE; page_addr >= start; - page_addr -= PAGE_SIZE) { - page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE]; - if (vma) - zap_page_range(vma, (uintptr_t)page_addr + - proc->user_buffer_offset, PAGE_SIZE, NULL); -err_vm_insert_page_failed: - unmap_kernel_range((unsigned long)page_addr, PAGE_SIZE); -err_map_kernel_failed: - __free_page(*page); - *page = NULL; -err_alloc_page_failed: - ; - } -err_no_vma: - if (mm) { - up_write(&mm->mmap_sem); - mmput(mm); - } - return -ENOMEM; -} - -static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, - size_t data_size, - size_t offsets_size, int is_async) -{ - struct rb_node *n = proc->free_buffers.rb_node; - struct binder_buffer *buffer; - size_t buffer_size; - struct rb_node *best_fit = NULL; - void *has_page_addr; - void *end_page_addr; - size_t size; - - if (proc->vma == NULL) { - printk(KERN_ERR "binder: %d: binder_alloc_buf, no vma\n", - proc->pid); - return NULL; - } - - size = ALIGN(data_size, sizeof(void *)) + - ALIGN(offsets_size, sizeof(void *)); - - if (size < data_size || size < offsets_size) { - binder_user_error("binder: %d: got transaction with invalid " - "size %zd-%zd\n", proc->pid, data_size, offsets_size); - return NULL; - } - - if (is_async && - proc->free_async_space < size + sizeof(struct binder_buffer)) { - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: binder_alloc_buf size %zd" - "failed, no async space left\n", proc->pid, size); - return NULL; - } - - while (n) { - buffer = rb_entry(n, struct binder_buffer, rb_node); - BUG_ON(!buffer->free); - buffer_size = binder_buffer_size(proc, buffer); - - if (size < buffer_size) { - best_fit = n; - n = n->rb_left; - } else if (size > buffer_size) - n = n->rb_right; - else { - best_fit = n; - break; - } - } - if (best_fit == NULL) { - printk(KERN_ERR "binder: %d: binder_alloc_buf size %zd failed, " - "no address space\n", proc->pid, size); - return NULL; - } - if (n == NULL) { - buffer = rb_entry(best_fit, struct binder_buffer, rb_node); - buffer_size = binder_buffer_size(proc, buffer); - } - - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: binder_alloc_buf size %zd got buff" - "er %p size %zd\n", proc->pid, size, buffer, buffer_size); - - has_page_addr = - (void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK); - if (n == NULL) { - if (size + sizeof(struct binder_buffer) + 4 >= buffer_size) - buffer_size = size; /* no room for other buffers */ - else - buffer_size = size + sizeof(struct binder_buffer); - } - end_page_addr = - (void *)PAGE_ALIGN((uintptr_t)buffer->data + buffer_size); - if (end_page_addr > has_page_addr) - end_page_addr = has_page_addr; - if (binder_update_page_range(proc, 1, - (void *)PAGE_ALIGN((uintptr_t)buffer->data), end_page_addr, NULL)) - return NULL; - - rb_erase(best_fit, &proc->free_buffers); - buffer->free = 0; - binder_insert_allocated_buffer(proc, buffer); - if (buffer_size != size) { - struct binder_buffer *new_buffer = (void *)buffer->data + size; - list_add(&new_buffer->entry, &buffer->entry); - new_buffer->free = 1; - binder_insert_free_buffer(proc, new_buffer); - } - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: binder_alloc_buf size %zd got " - "%p\n", proc->pid, size, buffer); - buffer->data_size = data_size; - buffer->offsets_size = offsets_size; - buffer->async_transaction = is_async; - if (is_async) { - proc->free_async_space -= size + sizeof(struct binder_buffer); - binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, - "binder: %d: binder_alloc_buf size %zd " - "async free %zd\n", proc->pid, size, - proc->free_async_space); - } - - return buffer; -} - -static void *buffer_start_page(struct binder_buffer *buffer) -{ - return (void *)((uintptr_t)buffer & PAGE_MASK); -} - -static void *buffer_end_page(struct binder_buffer *buffer) -{ - return (void *)(((uintptr_t)(buffer + 1) - 1) & PAGE_MASK); -} - -static void binder_delete_free_buffer(struct binder_proc *proc, - struct binder_buffer *buffer) -{ - struct binder_buffer *prev, *next = NULL; - int free_page_end = 1; - int free_page_start = 1; - - BUG_ON(proc->buffers.next == &buffer->entry); - prev = list_entry(buffer->entry.prev, struct binder_buffer, entry); - BUG_ON(!prev->free); - if (buffer_end_page(prev) == buffer_start_page(buffer)) { - free_page_start = 0; - if (buffer_end_page(prev) == buffer_end_page(buffer)) - free_page_end = 0; - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: merge free, buffer %p " - "share page with %p\n", proc->pid, buffer, prev); - } - - if (!list_is_last(&buffer->entry, &proc->buffers)) { - next = list_entry(buffer->entry.next, - struct binder_buffer, entry); - if (buffer_start_page(next) == buffer_end_page(buffer)) { - free_page_end = 0; - if (buffer_start_page(next) == - buffer_start_page(buffer)) - free_page_start = 0; - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: merge free, buffer" - " %p share page with %p\n", proc->pid, - buffer, prev); - } - } - list_del(&buffer->entry); - if (free_page_start || free_page_end) { - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: merge free, buffer %p do " - "not share page%s%s with with %p or %p\n", - proc->pid, buffer, free_page_start ? "" : " end", - free_page_end ? "" : " start", prev, next); - binder_update_page_range(proc, 0, free_page_start ? - buffer_start_page(buffer) : buffer_end_page(buffer), - (free_page_end ? buffer_end_page(buffer) : - buffer_start_page(buffer)) + PAGE_SIZE, NULL); - } -} - -static void binder_free_buf(struct binder_proc *proc, - struct binder_buffer *buffer) -{ - size_t size, buffer_size; - - buffer_size = binder_buffer_size(proc, buffer); - - size = ALIGN(buffer->data_size, sizeof(void *)) + - ALIGN(buffer->offsets_size, sizeof(void *)); - - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: binder_free_buf %p size %zd buffer" - "_size %zd\n", proc->pid, buffer, size, buffer_size); - - BUG_ON(buffer->free); - BUG_ON(size > buffer_size); - BUG_ON(buffer->transaction != NULL); - BUG_ON((void *)buffer < proc->buffer); - BUG_ON((void *)buffer > proc->buffer + proc->buffer_size); - - if (buffer->async_transaction) { - proc->free_async_space += size + sizeof(struct binder_buffer); - - binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, - "binder: %d: binder_free_buf size %zd " - "async free %zd\n", proc->pid, size, - proc->free_async_space); - } - - binder_update_page_range(proc, 0, - (void *)PAGE_ALIGN((uintptr_t)buffer->data), - (void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK), - NULL); - rb_erase(&buffer->rb_node, &proc->allocated_buffers); - buffer->free = 1; - if (!list_is_last(&buffer->entry, &proc->buffers)) { - struct binder_buffer *next = list_entry(buffer->entry.next, - struct binder_buffer, entry); - if (next->free) { - rb_erase(&next->rb_node, &proc->free_buffers); - binder_delete_free_buffer(proc, next); - } - } - if (proc->buffers.next != &buffer->entry) { - struct binder_buffer *prev = list_entry(buffer->entry.prev, - struct binder_buffer, entry); - if (prev->free) { - binder_delete_free_buffer(proc, buffer); - rb_erase(&prev->rb_node, &proc->free_buffers); - buffer = prev; - } - } - binder_insert_free_buffer(proc, buffer); -} - -static struct binder_node *binder_get_node(struct binder_proc *proc, - void __user *ptr) -{ - struct rb_node *n = proc->nodes.rb_node; - struct binder_node *node; - - while (n) { - node = rb_entry(n, struct binder_node, rb_node); - - if (ptr < node->ptr) - n = n->rb_left; - else if (ptr > node->ptr) - n = n->rb_right; - else - return node; - } - return NULL; -} - -static struct binder_node *binder_new_node(struct binder_proc *proc, - void __user *ptr, - void __user *cookie) -{ - struct rb_node **p = &proc->nodes.rb_node; - struct rb_node *parent = NULL; - struct binder_node *node; - - while (*p) { - parent = *p; - node = rb_entry(parent, struct binder_node, rb_node); - - if (ptr < node->ptr) - p = &(*p)->rb_left; - else if (ptr > node->ptr) - p = &(*p)->rb_right; - else - return NULL; - } - - node = kzalloc(sizeof(*node), GFP_KERNEL); - if (node == NULL) - return NULL; - binder_stats_created(BINDER_STAT_NODE); - rb_link_node(&node->rb_node, parent, p); - rb_insert_color(&node->rb_node, &proc->nodes); - node->debug_id = ++binder_last_id; - node->proc = proc; - node->ptr = ptr; - node->cookie = cookie; - node->work.type = BINDER_WORK_NODE; - INIT_LIST_HEAD(&node->work.entry); - INIT_LIST_HEAD(&node->async_todo); - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d:%d node %d u%p c%p created\n", - proc->pid, current->pid, node->debug_id, - node->ptr, node->cookie); - return node; -} - -static int binder_inc_node(struct binder_node *node, int strong, int internal, - struct list_head *target_list) -{ - if (strong) { - if (internal) { - if (target_list == NULL && - node->internal_strong_refs == 0 && - !(node == binder_context_mgr_node && - node->has_strong_ref)) { - printk(KERN_ERR "binder: invalid inc strong " - "node for %d\n", node->debug_id); - return -EINVAL; - } - node->internal_strong_refs++; - } else - node->local_strong_refs++; - if (!node->has_strong_ref && target_list) { - list_del_init(&node->work.entry); - list_add_tail(&node->work.entry, target_list); - } - } else { - if (!internal) - node->local_weak_refs++; - if (!node->has_weak_ref && list_empty(&node->work.entry)) { - if (target_list == NULL) { - printk(KERN_ERR "binder: invalid inc weak node " - "for %d\n", node->debug_id); - return -EINVAL; - } - list_add_tail(&node->work.entry, target_list); - } - } - return 0; -} - -static int binder_dec_node(struct binder_node *node, int strong, int internal) -{ - if (strong) { - if (internal) - node->internal_strong_refs--; - else - node->local_strong_refs--; - if (node->local_strong_refs || node->internal_strong_refs) - return 0; - } else { - if (!internal) - node->local_weak_refs--; - if (node->local_weak_refs || !hlist_empty(&node->refs)) - return 0; - } - if (node->proc && (node->has_strong_ref || node->has_weak_ref)) { - if (list_empty(&node->work.entry)) { - list_add_tail(&node->work.entry, &node->proc->todo); - wake_up_interruptible(&node->proc->wait); - } - } else { - if (hlist_empty(&node->refs) && !node->local_strong_refs && - !node->local_weak_refs) { - list_del_init(&node->work.entry); - if (node->proc) { - rb_erase(&node->rb_node, &node->proc->nodes); - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: refless node %d deleted\n", - node->debug_id); - } else { - hlist_del(&node->dead_node); - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: dead node %d deleted\n", - node->debug_id); - } - kfree(node); - binder_stats_deleted(BINDER_STAT_NODE); - } - } - - return 0; -} - - -static struct binder_ref *binder_get_ref(struct binder_proc *proc, - uint32_t desc) -{ - struct rb_node *n = proc->refs_by_desc.rb_node; - struct binder_ref *ref; - - while (n) { - ref = rb_entry(n, struct binder_ref, rb_node_desc); - - if (desc < ref->desc) - n = n->rb_left; - else if (desc > ref->desc) - n = n->rb_right; - else - return ref; - } - return NULL; -} - -static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc, - struct binder_node *node) -{ - struct rb_node *n; - struct rb_node **p = &proc->refs_by_node.rb_node; - struct rb_node *parent = NULL; - struct binder_ref *ref, *new_ref; - - while (*p) { - parent = *p; - ref = rb_entry(parent, struct binder_ref, rb_node_node); - - if (node < ref->node) - p = &(*p)->rb_left; - else if (node > ref->node) - p = &(*p)->rb_right; - else - return ref; - } - new_ref = kzalloc(sizeof(*ref), GFP_KERNEL); - if (new_ref == NULL) - return NULL; - binder_stats_created(BINDER_STAT_REF); - new_ref->debug_id = ++binder_last_id; - new_ref->proc = proc; - new_ref->node = node; - rb_link_node(&new_ref->rb_node_node, parent, p); - rb_insert_color(&new_ref->rb_node_node, &proc->refs_by_node); - - new_ref->desc = (node == binder_context_mgr_node) ? 0 : 1; - for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) { - ref = rb_entry(n, struct binder_ref, rb_node_desc); - if (ref->desc > new_ref->desc) - break; - new_ref->desc = ref->desc + 1; - } - - p = &proc->refs_by_desc.rb_node; - while (*p) { - parent = *p; - ref = rb_entry(parent, struct binder_ref, rb_node_desc); - - if (new_ref->desc < ref->desc) - p = &(*p)->rb_left; - else if (new_ref->desc > ref->desc) - p = &(*p)->rb_right; - else - BUG(); - } - rb_link_node(&new_ref->rb_node_desc, parent, p); - rb_insert_color(&new_ref->rb_node_desc, &proc->refs_by_desc); - if (node) { - hlist_add_head(&new_ref->node_entry, &node->refs); - - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d new ref %d desc %d for " - "node %d\n", proc->pid, new_ref->debug_id, - new_ref->desc, node->debug_id); - } else { - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d new ref %d desc %d for " - "dead node\n", proc->pid, new_ref->debug_id, - new_ref->desc); - } - return new_ref; -} - -static void binder_delete_ref(struct binder_ref *ref) -{ - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d delete ref %d desc %d for " - "node %d\n", ref->proc->pid, ref->debug_id, - ref->desc, ref->node->debug_id); - - rb_erase(&ref->rb_node_desc, &ref->proc->refs_by_desc); - rb_erase(&ref->rb_node_node, &ref->proc->refs_by_node); - if (ref->strong) - binder_dec_node(ref->node, 1, 1); - hlist_del(&ref->node_entry); - binder_dec_node(ref->node, 0, 1); - if (ref->death) { - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: %d delete ref %d desc %d " - "has death notification\n", ref->proc->pid, - ref->debug_id, ref->desc); - list_del(&ref->death->work.entry); - kfree(ref->death); - binder_stats_deleted(BINDER_STAT_DEATH); - } - kfree(ref); - binder_stats_deleted(BINDER_STAT_REF); -} - -static int binder_inc_ref(struct binder_ref *ref, int strong, - struct list_head *target_list) -{ - int ret; - if (strong) { - if (ref->strong == 0) { - ret = binder_inc_node(ref->node, 1, 1, target_list); - if (ret) - return ret; - } - ref->strong++; - } else { - if (ref->weak == 0) { - ret = binder_inc_node(ref->node, 0, 1, target_list); - if (ret) - return ret; - } - ref->weak++; - } - return 0; -} - - -static int binder_dec_ref(struct binder_ref *ref, int strong) -{ - if (strong) { - if (ref->strong == 0) { - binder_user_error("binder: %d invalid dec strong, " - "ref %d desc %d s %d w %d\n", - ref->proc->pid, ref->debug_id, - ref->desc, ref->strong, ref->weak); - return -EINVAL; - } - ref->strong--; - if (ref->strong == 0) { - int ret; - ret = binder_dec_node(ref->node, strong, 1); - if (ret) - return ret; - } - } else { - if (ref->weak == 0) { - binder_user_error("binder: %d invalid dec weak, " - "ref %d desc %d s %d w %d\n", - ref->proc->pid, ref->debug_id, - ref->desc, ref->strong, ref->weak); - return -EINVAL; - } - ref->weak--; - } - if (ref->strong == 0 && ref->weak == 0) - binder_delete_ref(ref); - return 0; -} - -static void binder_pop_transaction(struct binder_thread *target_thread, - struct binder_transaction *t) -{ - if (target_thread) { - BUG_ON(target_thread->transaction_stack != t); - BUG_ON(target_thread->transaction_stack->from != target_thread); - target_thread->transaction_stack = - target_thread->transaction_stack->from_parent; - t->from = NULL; - } - t->need_reply = 0; - if (t->buffer) - t->buffer->transaction = NULL; - kfree(t); - binder_stats_deleted(BINDER_STAT_TRANSACTION); -} - -static void binder_send_failed_reply(struct binder_transaction *t, - uint32_t error_code) -{ - struct binder_thread *target_thread; - BUG_ON(t->flags & TF_ONE_WAY); - while (1) { - target_thread = t->from; - if (target_thread) { - if (target_thread->return_error != BR_OK && - target_thread->return_error2 == BR_OK) { - target_thread->return_error2 = - target_thread->return_error; - target_thread->return_error = BR_OK; - } - if (target_thread->return_error == BR_OK) { - binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "binder: send failed reply for " - "transaction %d to %d:%d\n", - t->debug_id, target_thread->proc->pid, - target_thread->pid); - - binder_pop_transaction(target_thread, t); - target_thread->return_error = error_code; - wake_up_interruptible(&target_thread->wait); - } else { - printk(KERN_ERR "binder: reply failed, target " - "thread, %d:%d, has error code %d " - "already\n", target_thread->proc->pid, - target_thread->pid, - target_thread->return_error); - } - return; - } else { - struct binder_transaction *next = t->from_parent; - - binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "binder: send failed reply " - "for transaction %d, target dead\n", - t->debug_id); - - binder_pop_transaction(target_thread, t); - if (next == NULL) { - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: reply failed," - " no target thread at root\n"); - return; - } - t = next; - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: reply failed, no target " - "thread -- retry %d\n", t->debug_id); - } - } -} - -static void binder_transaction_buffer_release(struct binder_proc *proc, - struct binder_buffer *buffer, - size_t *failed_at) -{ - size_t *offp, *off_end; - int debug_id = buffer->debug_id; - - binder_debug(BINDER_DEBUG_TRANSACTION, - "binder: %d buffer release %d, size %zd-%zd, failed at %p\n", - proc->pid, buffer->debug_id, - buffer->data_size, buffer->offsets_size, failed_at); - - if (buffer->target_node) - binder_dec_node(buffer->target_node, 1, 0); - - offp = (size_t *)(buffer->data + ALIGN(buffer->data_size, sizeof(void *))); - if (failed_at) - off_end = failed_at; - else - off_end = (void *)offp + buffer->offsets_size; - for (; offp < off_end; offp++) { - struct flat_binder_object *fp; - if (*offp > buffer->data_size - sizeof(*fp) || - buffer->data_size < sizeof(*fp) || - !IS_ALIGNED(*offp, sizeof(void *))) { - printk(KERN_ERR "binder: transaction release %d bad" - "offset %zd, size %zd\n", debug_id, - *offp, buffer->data_size); - continue; - } - fp = (struct flat_binder_object *)(buffer->data + *offp); - switch (fp->type) { - case BINDER_TYPE_BINDER: - case BINDER_TYPE_WEAK_BINDER: { - struct binder_node *node = binder_get_node(proc, fp->binder); - if (node == NULL) { - printk(KERN_ERR "binder: transaction release %d" - " bad node %p\n", debug_id, fp->binder); - break; - } - binder_debug(BINDER_DEBUG_TRANSACTION, - " node %d u%p\n", - node->debug_id, node->ptr); - binder_dec_node(node, fp->type == BINDER_TYPE_BINDER, 0); - } break; - case BINDER_TYPE_HANDLE: - case BINDER_TYPE_WEAK_HANDLE: { - struct binder_ref *ref = binder_get_ref(proc, fp->handle); - if (ref == NULL) { - printk(KERN_ERR "binder: transaction release %d" - " bad handle %ld\n", debug_id, - fp->handle); - break; - } - binder_debug(BINDER_DEBUG_TRANSACTION, - " ref %d desc %d (node %d)\n", - ref->debug_id, ref->desc, ref->node->debug_id); - binder_dec_ref(ref, fp->type == BINDER_TYPE_HANDLE); - } break; - - case BINDER_TYPE_FD: - binder_debug(BINDER_DEBUG_TRANSACTION, - " fd %ld\n", fp->handle); - if (failed_at) - task_close_fd(proc, fp->handle); - break; - - default: - printk(KERN_ERR "binder: transaction release %d bad " - "object type %lx\n", debug_id, fp->type); - break; - } - } -} - -static void binder_transaction(struct binder_proc *proc, - struct binder_thread *thread, - struct binder_transaction_data *tr, int reply) -{ - struct binder_transaction *t; - struct binder_work *tcomplete; - size_t *offp, *off_end; - struct binder_proc *target_proc; - struct binder_thread *target_thread = NULL; - struct binder_node *target_node = NULL; - struct list_head *target_list; - wait_queue_head_t *target_wait; - struct binder_transaction *in_reply_to = NULL; - struct binder_transaction_log_entry *e; - uint32_t return_error; - - e = binder_transaction_log_add(&binder_transaction_log); - e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY); - e->from_proc = proc->pid; - e->from_thread = thread->pid; - e->target_handle = tr->target.handle; - e->data_size = tr->data_size; - e->offsets_size = tr->offsets_size; - - if (reply) { - in_reply_to = thread->transaction_stack; - if (in_reply_to == NULL) { - binder_user_error("binder: %d:%d got reply transaction " - "with no transaction stack\n", - proc->pid, thread->pid); - return_error = BR_FAILED_REPLY; - goto err_empty_call_stack; - } - binder_set_nice(in_reply_to->saved_priority); - if (in_reply_to->to_thread != thread) { - binder_user_error("binder: %d:%d got reply transaction " - "with bad transaction stack," - " transaction %d has target %d:%d\n", - proc->pid, thread->pid, in_reply_to->debug_id, - in_reply_to->to_proc ? - in_reply_to->to_proc->pid : 0, - in_reply_to->to_thread ? - in_reply_to->to_thread->pid : 0); - return_error = BR_FAILED_REPLY; - in_reply_to = NULL; - goto err_bad_call_stack; - } - thread->transaction_stack = in_reply_to->to_parent; - target_thread = in_reply_to->from; - if (target_thread == NULL) { - return_error = BR_DEAD_REPLY; - goto err_dead_binder; - } - if (target_thread->transaction_stack != in_reply_to) { - binder_user_error("binder: %d:%d got reply transaction " - "with bad target transaction stack %d, " - "expected %d\n", - proc->pid, thread->pid, - target_thread->transaction_stack ? - target_thread->transaction_stack->debug_id : 0, - in_reply_to->debug_id); - return_error = BR_FAILED_REPLY; - in_reply_to = NULL; - target_thread = NULL; - goto err_dead_binder; - } - target_proc = target_thread->proc; - } else { - if (tr->target.handle) { - struct binder_ref *ref; - ref = binder_get_ref(proc, tr->target.handle); - if (ref == NULL) { - binder_user_error("binder: %d:%d got " - "transaction to invalid handle\n", - proc->pid, thread->pid); - return_error = BR_FAILED_REPLY; - goto err_invalid_target_handle; - } - target_node = ref->node; - } else { - target_node = binder_context_mgr_node; - if (target_node == NULL) { - return_error = BR_DEAD_REPLY; - goto err_no_context_mgr_node; - } - } - e->to_node = target_node->debug_id; - target_proc = target_node->proc; - if (target_proc == NULL) { - return_error = BR_DEAD_REPLY; - goto err_dead_binder; - } - if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) { - struct binder_transaction *tmp; - tmp = thread->transaction_stack; - if (tmp->to_thread != thread) { - binder_user_error("binder: %d:%d got new " - "transaction with bad transaction stack" - ", transaction %d has target %d:%d\n", - proc->pid, thread->pid, tmp->debug_id, - tmp->to_proc ? tmp->to_proc->pid : 0, - tmp->to_thread ? - tmp->to_thread->pid : 0); - return_error = BR_FAILED_REPLY; - goto err_bad_call_stack; - } - while (tmp) { - if (tmp->from && tmp->from->proc == target_proc) - target_thread = tmp->from; - tmp = tmp->from_parent; - } - } - } - if (target_thread) { - e->to_thread = target_thread->pid; - target_list = &target_thread->todo; - target_wait = &target_thread->wait; - } else { - target_list = &target_proc->todo; - target_wait = &target_proc->wait; - } - e->to_proc = target_proc->pid; - - /* TODO: reuse incoming transaction for reply */ - t = kzalloc(sizeof(*t), GFP_KERNEL); - if (t == NULL) { - return_error = BR_FAILED_REPLY; - goto err_alloc_t_failed; - } - binder_stats_created(BINDER_STAT_TRANSACTION); - - tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL); - if (tcomplete == NULL) { - return_error = BR_FAILED_REPLY; - goto err_alloc_tcomplete_failed; - } - binder_stats_created(BINDER_STAT_TRANSACTION_COMPLETE); - - t->debug_id = ++binder_last_id; - e->debug_id = t->debug_id; - - if (reply) - binder_debug(BINDER_DEBUG_TRANSACTION, - "binder: %d:%d BC_REPLY %d -> %d:%d, " - "data %p-%p size %zd-%zd\n", - proc->pid, thread->pid, t->debug_id, - target_proc->pid, target_thread->pid, - tr->data.ptr.buffer, tr->data.ptr.offsets, - tr->data_size, tr->offsets_size); - else - binder_debug(BINDER_DEBUG_TRANSACTION, - "binder: %d:%d BC_TRANSACTION %d -> " - "%d - node %d, data %p-%p size %zd-%zd\n", - proc->pid, thread->pid, t->debug_id, - target_proc->pid, target_node->debug_id, - tr->data.ptr.buffer, tr->data.ptr.offsets, - tr->data_size, tr->offsets_size); - - if (!reply && !(tr->flags & TF_ONE_WAY)) - t->from = thread; - else - t->from = NULL; - t->sender_euid = proc->tsk->cred->euid; - t->to_proc = target_proc; - t->to_thread = target_thread; - t->code = tr->code; - t->flags = tr->flags; - t->priority = task_nice(current); - t->buffer = binder_alloc_buf(target_proc, tr->data_size, - tr->offsets_size, !reply && (t->flags & TF_ONE_WAY)); - if (t->buffer == NULL) { - return_error = BR_FAILED_REPLY; - goto err_binder_alloc_buf_failed; - } - t->buffer->allow_user_free = 0; - t->buffer->debug_id = t->debug_id; - t->buffer->transaction = t; - t->buffer->target_node = target_node; - if (target_node) - binder_inc_node(target_node, 1, 0, NULL); - - offp = (size_t *)(t->buffer->data + ALIGN(tr->data_size, sizeof(void *))); - - if (copy_from_user(t->buffer->data, tr->data.ptr.buffer, tr->data_size)) { - binder_user_error("binder: %d:%d got transaction with invalid " - "data ptr\n", proc->pid, thread->pid); - return_error = BR_FAILED_REPLY; - goto err_copy_data_failed; - } - if (copy_from_user(offp, tr->data.ptr.offsets, tr->offsets_size)) { - binder_user_error("binder: %d:%d got transaction with invalid " - "offsets ptr\n", proc->pid, thread->pid); - return_error = BR_FAILED_REPLY; - goto err_copy_data_failed; - } - if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) { - binder_user_error("binder: %d:%d got transaction with " - "invalid offsets size, %zd\n", - proc->pid, thread->pid, tr->offsets_size); - return_error = BR_FAILED_REPLY; - goto err_bad_offset; - } - off_end = (void *)offp + tr->offsets_size; - for (; offp < off_end; offp++) { - struct flat_binder_object *fp; - if (*offp > t->buffer->data_size - sizeof(*fp) || - t->buffer->data_size < sizeof(*fp) || - !IS_ALIGNED(*offp, sizeof(void *))) { - binder_user_error("binder: %d:%d got transaction with " - "invalid offset, %zd\n", - proc->pid, thread->pid, *offp); - return_error = BR_FAILED_REPLY; - goto err_bad_offset; - } - fp = (struct flat_binder_object *)(t->buffer->data + *offp); - switch (fp->type) { - case BINDER_TYPE_BINDER: - case BINDER_TYPE_WEAK_BINDER: { - struct binder_ref *ref; - struct binder_node *node = binder_get_node(proc, fp->binder); - if (node == NULL) { - node = binder_new_node(proc, fp->binder, fp->cookie); - if (node == NULL) { - return_error = BR_FAILED_REPLY; - goto err_binder_new_node_failed; - } - node->min_priority = fp->flags & FLAT_BINDER_FLAG_PRIORITY_MASK; - node->accept_fds = !!(fp->flags & FLAT_BINDER_FLAG_ACCEPTS_FDS); - } - if (fp->cookie != node->cookie) { - binder_user_error("binder: %d:%d sending u%p " - "node %d, cookie mismatch %p != %p\n", - proc->pid, thread->pid, - fp->binder, node->debug_id, - fp->cookie, node->cookie); - goto err_binder_get_ref_for_node_failed; - } - ref = binder_get_ref_for_node(target_proc, node); - if (ref == NULL) { - return_error = BR_FAILED_REPLY; - goto err_binder_get_ref_for_node_failed; - } - if (fp->type == BINDER_TYPE_BINDER) - fp->type = BINDER_TYPE_HANDLE; - else - fp->type = BINDER_TYPE_WEAK_HANDLE; - fp->handle = ref->desc; - binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE, - &thread->todo); - - binder_debug(BINDER_DEBUG_TRANSACTION, - " node %d u%p -> ref %d desc %d\n", - node->debug_id, node->ptr, ref->debug_id, - ref->desc); - } break; - case BINDER_TYPE_HANDLE: - case BINDER_TYPE_WEAK_HANDLE: { - struct binder_ref *ref = binder_get_ref(proc, fp->handle); - if (ref == NULL) { - binder_user_error("binder: %d:%d got " - "transaction with invalid " - "handle, %ld\n", proc->pid, - thread->pid, fp->handle); - return_error = BR_FAILED_REPLY; - goto err_binder_get_ref_failed; - } - if (ref->node->proc == target_proc) { - if (fp->type == BINDER_TYPE_HANDLE) - fp->type = BINDER_TYPE_BINDER; - else - fp->type = BINDER_TYPE_WEAK_BINDER; - fp->binder = ref->node->ptr; - fp->cookie = ref->node->cookie; - binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL); - binder_debug(BINDER_DEBUG_TRANSACTION, - " ref %d desc %d -> node %d u%p\n", - ref->debug_id, ref->desc, ref->node->debug_id, - ref->node->ptr); - } else { - struct binder_ref *new_ref; - new_ref = binder_get_ref_for_node(target_proc, ref->node); - if (new_ref == NULL) { - return_error = BR_FAILED_REPLY; - goto err_binder_get_ref_for_node_failed; - } - fp->handle = new_ref->desc; - binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL); - binder_debug(BINDER_DEBUG_TRANSACTION, - " ref %d desc %d -> ref %d desc %d (node %d)\n", - ref->debug_id, ref->desc, new_ref->debug_id, - new_ref->desc, ref->node->debug_id); - } - } break; - - case BINDER_TYPE_FD: { - int target_fd; - struct file *file; - - if (reply) { - if (!(in_reply_to->flags & TF_ACCEPT_FDS)) { - binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n", - proc->pid, thread->pid, fp->handle); - return_error = BR_FAILED_REPLY; - goto err_fd_not_allowed; - } - } else if (!target_node->accept_fds) { - binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n", - proc->pid, thread->pid, fp->handle); - return_error = BR_FAILED_REPLY; - goto err_fd_not_allowed; - } - - file = fget(fp->handle); - if (file == NULL) { - binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n", - proc->pid, thread->pid, fp->handle); - return_error = BR_FAILED_REPLY; - goto err_fget_failed; - } - target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC); - if (target_fd < 0) { - fput(file); - return_error = BR_FAILED_REPLY; - goto err_get_unused_fd_failed; - } - task_fd_install(target_proc, target_fd, file); - binder_debug(BINDER_DEBUG_TRANSACTION, - " fd %ld -> %d\n", fp->handle, target_fd); - /* TODO: fput? */ - fp->handle = target_fd; - } break; - - default: - binder_user_error("binder: %d:%d got transactio" - "n with invalid object type, %lx\n", - proc->pid, thread->pid, fp->type); - return_error = BR_FAILED_REPLY; - goto err_bad_object_type; - } - } - if (reply) { - BUG_ON(t->buffer->async_transaction != 0); - binder_pop_transaction(target_thread, in_reply_to); - } else if (!(t->flags & TF_ONE_WAY)) { - BUG_ON(t->buffer->async_transaction != 0); - t->need_reply = 1; - t->from_parent = thread->transaction_stack; - thread->transaction_stack = t; - } else { - BUG_ON(target_node == NULL); - BUG_ON(t->buffer->async_transaction != 1); - if (target_node->has_async_transaction) { - target_list = &target_node->async_todo; - target_wait = NULL; - } else - target_node->has_async_transaction = 1; - } - t->work.type = BINDER_WORK_TRANSACTION; - list_add_tail(&t->work.entry, target_list); - tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE; - list_add_tail(&tcomplete->entry, &thread->todo); - if (target_wait) - wake_up_interruptible(target_wait); - return; - -err_get_unused_fd_failed: -err_fget_failed: -err_fd_not_allowed: -err_binder_get_ref_for_node_failed: -err_binder_get_ref_failed: -err_binder_new_node_failed: -err_bad_object_type: -err_bad_offset: -err_copy_data_failed: - binder_transaction_buffer_release(target_proc, t->buffer, offp); - t->buffer->transaction = NULL; - binder_free_buf(target_proc, t->buffer); -err_binder_alloc_buf_failed: - kfree(tcomplete); - binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); -err_alloc_tcomplete_failed: - kfree(t); - binder_stats_deleted(BINDER_STAT_TRANSACTION); -err_alloc_t_failed: -err_bad_call_stack: -err_empty_call_stack: -err_dead_binder: -err_invalid_target_handle: -err_no_context_mgr_node: - binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "binder: %d:%d transaction failed %d, size %zd-%zd\n", - proc->pid, thread->pid, return_error, - tr->data_size, tr->offsets_size); - - { - struct binder_transaction_log_entry *fe; - fe = binder_transaction_log_add(&binder_transaction_log_failed); - *fe = *e; - } - - BUG_ON(thread->return_error != BR_OK); - if (in_reply_to) { - thread->return_error = BR_TRANSACTION_COMPLETE; - binder_send_failed_reply(in_reply_to, return_error); - } else - thread->return_error = return_error; -} - -int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, - void __user *buffer, int size, signed long *consumed) -{ - uint32_t cmd; - void __user *ptr = buffer + *consumed; - void __user *end = buffer + size; - - while (ptr < end && thread->return_error == BR_OK) { - if (get_user(cmd, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) { - binder_stats.bc[_IOC_NR(cmd)]++; - proc->stats.bc[_IOC_NR(cmd)]++; - thread->stats.bc[_IOC_NR(cmd)]++; - } - switch (cmd) { - case BC_INCREFS: - case BC_ACQUIRE: - case BC_RELEASE: - case BC_DECREFS: { - uint32_t target; - struct binder_ref *ref; - const char *debug_string; - - if (get_user(target, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (target == 0 && binder_context_mgr_node && - (cmd == BC_INCREFS || cmd == BC_ACQUIRE)) { - ref = binder_get_ref_for_node(proc, - binder_context_mgr_node); - if (ref->desc != target) { - binder_user_error("binder: %d:" - "%d tried to acquire " - "reference to desc 0, " - "got %d instead\n", - proc->pid, thread->pid, - ref->desc); - } - } else - ref = binder_get_ref(proc, target); - if (ref == NULL) { - binder_user_error("binder: %d:%d refcou" - "nt change on invalid ref %d\n", - proc->pid, thread->pid, target); - break; - } - switch (cmd) { - case BC_INCREFS: - debug_string = "IncRefs"; - binder_inc_ref(ref, 0, NULL); - break; - case BC_ACQUIRE: - debug_string = "Acquire"; - binder_inc_ref(ref, 1, NULL); - break; - case BC_RELEASE: - debug_string = "Release"; - binder_dec_ref(ref, 1); - break; - case BC_DECREFS: - default: - debug_string = "DecRefs"; - binder_dec_ref(ref, 0); - break; - } - binder_debug(BINDER_DEBUG_USER_REFS, - "binder: %d:%d %s ref %d desc %d s %d w %d for node %d\n", - proc->pid, thread->pid, debug_string, ref->debug_id, - ref->desc, ref->strong, ref->weak, ref->node->debug_id); - break; - } - case BC_INCREFS_DONE: - case BC_ACQUIRE_DONE: { - void __user *node_ptr; - void *cookie; - struct binder_node *node; - - if (get_user(node_ptr, (void * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - if (get_user(cookie, (void * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - node = binder_get_node(proc, node_ptr); - if (node == NULL) { - binder_user_error("binder: %d:%d " - "%s u%p no match\n", - proc->pid, thread->pid, - cmd == BC_INCREFS_DONE ? - "BC_INCREFS_DONE" : - "BC_ACQUIRE_DONE", - node_ptr); - break; - } - if (cookie != node->cookie) { - binder_user_error("binder: %d:%d %s u%p node %d" - " cookie mismatch %p != %p\n", - proc->pid, thread->pid, - cmd == BC_INCREFS_DONE ? - "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE", - node_ptr, node->debug_id, - cookie, node->cookie); - break; - } - if (cmd == BC_ACQUIRE_DONE) { - if (node->pending_strong_ref == 0) { - binder_user_error("binder: %d:%d " - "BC_ACQUIRE_DONE node %d has " - "no pending acquire request\n", - proc->pid, thread->pid, - node->debug_id); - break; - } - node->pending_strong_ref = 0; - } else { - if (node->pending_weak_ref == 0) { - binder_user_error("binder: %d:%d " - "BC_INCREFS_DONE node %d has " - "no pending increfs request\n", - proc->pid, thread->pid, - node->debug_id); - break; - } - node->pending_weak_ref = 0; - } - binder_dec_node(node, cmd == BC_ACQUIRE_DONE, 0); - binder_debug(BINDER_DEBUG_USER_REFS, - "binder: %d:%d %s node %d ls %d lw %d\n", - proc->pid, thread->pid, - cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE", - node->debug_id, node->local_strong_refs, node->local_weak_refs); - break; - } - case BC_ATTEMPT_ACQUIRE: - printk(KERN_ERR "binder: BC_ATTEMPT_ACQUIRE not supported\n"); - return -EINVAL; - case BC_ACQUIRE_RESULT: - printk(KERN_ERR "binder: BC_ACQUIRE_RESULT not supported\n"); - return -EINVAL; - - case BC_FREE_BUFFER: { - void __user *data_ptr; - struct binder_buffer *buffer; - - if (get_user(data_ptr, (void * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - - buffer = binder_buffer_lookup(proc, data_ptr); - if (buffer == NULL) { - binder_user_error("binder: %d:%d " - "BC_FREE_BUFFER u%p no match\n", - proc->pid, thread->pid, data_ptr); - break; - } - if (!buffer->allow_user_free) { - binder_user_error("binder: %d:%d " - "BC_FREE_BUFFER u%p matched " - "unreturned buffer\n", - proc->pid, thread->pid, data_ptr); - break; - } - binder_debug(BINDER_DEBUG_FREE_BUFFER, - "binder: %d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n", - proc->pid, thread->pid, data_ptr, buffer->debug_id, - buffer->transaction ? "active" : "finished"); - - if (buffer->transaction) { - buffer->transaction->buffer = NULL; - buffer->transaction = NULL; - } - if (buffer->async_transaction && buffer->target_node) { - BUG_ON(!buffer->target_node->has_async_transaction); - if (list_empty(&buffer->target_node->async_todo)) - buffer->target_node->has_async_transaction = 0; - else - list_move_tail(buffer->target_node->async_todo.next, &thread->todo); - } - binder_transaction_buffer_release(proc, buffer, NULL); - binder_free_buf(proc, buffer); - break; - } - - case BC_TRANSACTION: - case BC_REPLY: { - struct binder_transaction_data tr; - - if (copy_from_user(&tr, ptr, sizeof(tr))) - return -EFAULT; - ptr += sizeof(tr); - binder_transaction(proc, thread, &tr, cmd == BC_REPLY); - break; - } - - case BC_REGISTER_LOOPER: - binder_debug(BINDER_DEBUG_THREADS, - "binder: %d:%d BC_REGISTER_LOOPER\n", - proc->pid, thread->pid); - if (thread->looper & BINDER_LOOPER_STATE_ENTERED) { - thread->looper |= BINDER_LOOPER_STATE_INVALID; - binder_user_error("binder: %d:%d ERROR:" - " BC_REGISTER_LOOPER called " - "after BC_ENTER_LOOPER\n", - proc->pid, thread->pid); - } else if (proc->requested_threads == 0) { - thread->looper |= BINDER_LOOPER_STATE_INVALID; - binder_user_error("binder: %d:%d ERROR:" - " BC_REGISTER_LOOPER called " - "without request\n", - proc->pid, thread->pid); - } else { - proc->requested_threads--; - proc->requested_threads_started++; - } - thread->looper |= BINDER_LOOPER_STATE_REGISTERED; - break; - case BC_ENTER_LOOPER: - binder_debug(BINDER_DEBUG_THREADS, - "binder: %d:%d BC_ENTER_LOOPER\n", - proc->pid, thread->pid); - if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) { - thread->looper |= BINDER_LOOPER_STATE_INVALID; - binder_user_error("binder: %d:%d ERROR:" - " BC_ENTER_LOOPER called after " - "BC_REGISTER_LOOPER\n", - proc->pid, thread->pid); - } - thread->looper |= BINDER_LOOPER_STATE_ENTERED; - break; - case BC_EXIT_LOOPER: - binder_debug(BINDER_DEBUG_THREADS, - "binder: %d:%d BC_EXIT_LOOPER\n", - proc->pid, thread->pid); - thread->looper |= BINDER_LOOPER_STATE_EXITED; - break; - - case BC_REQUEST_DEATH_NOTIFICATION: - case BC_CLEAR_DEATH_NOTIFICATION: { - uint32_t target; - void __user *cookie; - struct binder_ref *ref; - struct binder_ref_death *death; - - if (get_user(target, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (get_user(cookie, (void __user * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - ref = binder_get_ref(proc, target); - if (ref == NULL) { - binder_user_error("binder: %d:%d %s " - "invalid ref %d\n", - proc->pid, thread->pid, - cmd == BC_REQUEST_DEATH_NOTIFICATION ? - "BC_REQUEST_DEATH_NOTIFICATION" : - "BC_CLEAR_DEATH_NOTIFICATION", - target); - break; - } - - binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION, - "binder: %d:%d %s %p ref %d desc %d s %d w %d for node %d\n", - proc->pid, thread->pid, - cmd == BC_REQUEST_DEATH_NOTIFICATION ? - "BC_REQUEST_DEATH_NOTIFICATION" : - "BC_CLEAR_DEATH_NOTIFICATION", - cookie, ref->debug_id, ref->desc, - ref->strong, ref->weak, ref->node->debug_id); - - if (cmd == BC_REQUEST_DEATH_NOTIFICATION) { - if (ref->death) { - binder_user_error("binder: %d:%" - "d BC_REQUEST_DEATH_NOTI" - "FICATION death notific" - "ation already set\n", - proc->pid, thread->pid); - break; - } - death = kzalloc(sizeof(*death), GFP_KERNEL); - if (death == NULL) { - thread->return_error = BR_ERROR; - binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "binder: %d:%d " - "BC_REQUEST_DEATH_NOTIFICATION failed\n", - proc->pid, thread->pid); - break; - } - binder_stats_created(BINDER_STAT_DEATH); - INIT_LIST_HEAD(&death->work.entry); - death->cookie = cookie; - ref->death = death; - if (ref->node->proc == NULL) { - ref->death->work.type = BINDER_WORK_DEAD_BINDER; - if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { - list_add_tail(&ref->death->work.entry, &thread->todo); - } else { - list_add_tail(&ref->death->work.entry, &proc->todo); - wake_up_interruptible(&proc->wait); - } - } - } else { - if (ref->death == NULL) { - binder_user_error("binder: %d:%" - "d BC_CLEAR_DEATH_NOTIFI" - "CATION death notificat" - "ion not active\n", - proc->pid, thread->pid); - break; - } - death = ref->death; - if (death->cookie != cookie) { - binder_user_error("binder: %d:%" - "d BC_CLEAR_DEATH_NOTIFI" - "CATION death notificat" - "ion cookie mismatch " - "%p != %p\n", - proc->pid, thread->pid, - death->cookie, cookie); - break; - } - ref->death = NULL; - if (list_empty(&death->work.entry)) { - death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; - if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { - list_add_tail(&death->work.entry, &thread->todo); - } else { - list_add_tail(&death->work.entry, &proc->todo); - wake_up_interruptible(&proc->wait); - } - } else { - BUG_ON(death->work.type != BINDER_WORK_DEAD_BINDER); - death->work.type = BINDER_WORK_DEAD_BINDER_AND_CLEAR; - } - } - } break; - case BC_DEAD_BINDER_DONE: { - struct binder_work *w; - void __user *cookie; - struct binder_ref_death *death = NULL; - if (get_user(cookie, (void __user * __user *)ptr)) - return -EFAULT; - - ptr += sizeof(void *); - list_for_each_entry(w, &proc->delivered_death, entry) { - struct binder_ref_death *tmp_death = container_of(w, struct binder_ref_death, work); - if (tmp_death->cookie == cookie) { - death = tmp_death; - break; - } - } - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: %d:%d BC_DEAD_BINDER_DONE %p found %p\n", - proc->pid, thread->pid, cookie, death); - if (death == NULL) { - binder_user_error("binder: %d:%d BC_DEAD" - "_BINDER_DONE %p not found\n", - proc->pid, thread->pid, cookie); - break; - } - - list_del_init(&death->work.entry); - if (death->work.type == BINDER_WORK_DEAD_BINDER_AND_CLEAR) { - death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; - if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { - list_add_tail(&death->work.entry, &thread->todo); - } else { - list_add_tail(&death->work.entry, &proc->todo); - wake_up_interruptible(&proc->wait); - } - } - } break; - - default: - printk(KERN_ERR "binder: %d:%d unknown command %d\n", - proc->pid, thread->pid, cmd); - return -EINVAL; - } - *consumed = ptr - buffer; - } - return 0; -} - -void binder_stat_br(struct binder_proc *proc, struct binder_thread *thread, - uint32_t cmd) -{ - if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.br)) { - binder_stats.br[_IOC_NR(cmd)]++; - proc->stats.br[_IOC_NR(cmd)]++; - thread->stats.br[_IOC_NR(cmd)]++; - } -} - -static int binder_has_proc_work(struct binder_proc *proc, - struct binder_thread *thread) -{ - return !list_empty(&proc->todo) || - (thread->looper & BINDER_LOOPER_STATE_NEED_RETURN); -} - -static int binder_has_thread_work(struct binder_thread *thread) -{ - return !list_empty(&thread->todo) || thread->return_error != BR_OK || - (thread->looper & BINDER_LOOPER_STATE_NEED_RETURN); -} - -static int binder_thread_read(struct binder_proc *proc, - struct binder_thread *thread, - void __user *buffer, int size, - signed long *consumed, int non_block) -{ - void __user *ptr = buffer + *consumed; - void __user *end = buffer + size; - - int ret = 0; - int wait_for_proc_work; - - if (*consumed == 0) { - if (put_user(BR_NOOP, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - } - -retry: - wait_for_proc_work = thread->transaction_stack == NULL && - list_empty(&thread->todo); - - if (thread->return_error != BR_OK && ptr < end) { - if (thread->return_error2 != BR_OK) { - if (put_user(thread->return_error2, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (ptr == end) - goto done; - thread->return_error2 = BR_OK; - } - if (put_user(thread->return_error, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - thread->return_error = BR_OK; - goto done; - } - - - thread->looper |= BINDER_LOOPER_STATE_WAITING; - if (wait_for_proc_work) - proc->ready_threads++; - mutex_unlock(&binder_lock); - if (wait_for_proc_work) { - if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED | - BINDER_LOOPER_STATE_ENTERED))) { - binder_user_error("binder: %d:%d ERROR: Thread waiting " - "for process work before calling BC_REGISTER_" - "LOOPER or BC_ENTER_LOOPER (state %x)\n", - proc->pid, thread->pid, thread->looper); - wait_event_interruptible(binder_user_error_wait, - binder_stop_on_user_error < 2); - } - binder_set_nice(proc->default_priority); - if (non_block) { - if (!binder_has_proc_work(proc, thread)) - ret = -EAGAIN; - } else - ret = wait_event_interruptible_exclusive(proc->wait, binder_has_proc_work(proc, thread)); - } else { - if (non_block) { - if (!binder_has_thread_work(thread)) - ret = -EAGAIN; - } else - ret = wait_event_interruptible(thread->wait, binder_has_thread_work(thread)); - } - mutex_lock(&binder_lock); - if (wait_for_proc_work) - proc->ready_threads--; - thread->looper &= ~BINDER_LOOPER_STATE_WAITING; - - if (ret) - return ret; - - while (1) { - uint32_t cmd; - struct binder_transaction_data tr; - struct binder_work *w; - struct binder_transaction *t = NULL; - - if (!list_empty(&thread->todo)) - w = list_first_entry(&thread->todo, struct binder_work, entry); - else if (!list_empty(&proc->todo) && wait_for_proc_work) - w = list_first_entry(&proc->todo, struct binder_work, entry); - else { - if (ptr - buffer == 4 && !(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN)) /* no data added */ - goto retry; - break; - } - - if (end - ptr < sizeof(tr) + 4) - break; - - switch (w->type) { - case BINDER_WORK_TRANSACTION: { - t = container_of(w, struct binder_transaction, work); - } break; - case BINDER_WORK_TRANSACTION_COMPLETE: { - cmd = BR_TRANSACTION_COMPLETE; - if (put_user(cmd, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - - binder_stat_br(proc, thread, cmd); - binder_debug(BINDER_DEBUG_TRANSACTION_COMPLETE, - "binder: %d:%d BR_TRANSACTION_COMPLETE\n", - proc->pid, thread->pid); - - list_del(&w->entry); - kfree(w); - binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); - } break; - case BINDER_WORK_NODE: { - struct binder_node *node = container_of(w, struct binder_node, work); - uint32_t cmd = BR_NOOP; - const char *cmd_name; - int strong = node->internal_strong_refs || node->local_strong_refs; - int weak = !hlist_empty(&node->refs) || node->local_weak_refs || strong; - if (weak && !node->has_weak_ref) { - cmd = BR_INCREFS; - cmd_name = "BR_INCREFS"; - node->has_weak_ref = 1; - node->pending_weak_ref = 1; - node->local_weak_refs++; - } else if (strong && !node->has_strong_ref) { - cmd = BR_ACQUIRE; - cmd_name = "BR_ACQUIRE"; - node->has_strong_ref = 1; - node->pending_strong_ref = 1; - node->local_strong_refs++; - } else if (!strong && node->has_strong_ref) { - cmd = BR_RELEASE; - cmd_name = "BR_RELEASE"; - node->has_strong_ref = 0; - } else if (!weak && node->has_weak_ref) { - cmd = BR_DECREFS; - cmd_name = "BR_DECREFS"; - node->has_weak_ref = 0; - } - if (cmd != BR_NOOP) { - if (put_user(cmd, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (put_user(node->ptr, (void * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - if (put_user(node->cookie, (void * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - - binder_stat_br(proc, thread, cmd); - binder_debug(BINDER_DEBUG_USER_REFS, - "binder: %d:%d %s %d u%p c%p\n", - proc->pid, thread->pid, cmd_name, node->debug_id, node->ptr, node->cookie); - } else { - list_del_init(&w->entry); - if (!weak && !strong) { - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d:%d node %d u%p c%p deleted\n", - proc->pid, thread->pid, node->debug_id, - node->ptr, node->cookie); - rb_erase(&node->rb_node, &proc->nodes); - kfree(node); - binder_stats_deleted(BINDER_STAT_NODE); - } else { - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d:%d node %d u%p c%p state unchanged\n", - proc->pid, thread->pid, node->debug_id, node->ptr, - node->cookie); - } - } - } break; - case BINDER_WORK_DEAD_BINDER: - case BINDER_WORK_DEAD_BINDER_AND_CLEAR: - case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: { - struct binder_ref_death *death; - uint32_t cmd; - - death = container_of(w, struct binder_ref_death, work); - if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) - cmd = BR_CLEAR_DEATH_NOTIFICATION_DONE; - else - cmd = BR_DEAD_BINDER; - if (put_user(cmd, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (put_user(death->cookie, (void * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION, - "binder: %d:%d %s %p\n", - proc->pid, thread->pid, - cmd == BR_DEAD_BINDER ? - "BR_DEAD_BINDER" : - "BR_CLEAR_DEATH_NOTIFICATION_DONE", - death->cookie); - - if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) { - list_del(&w->entry); - kfree(death); - binder_stats_deleted(BINDER_STAT_DEATH); - } else - list_move(&w->entry, &proc->delivered_death); - if (cmd == BR_DEAD_BINDER) - goto done; /* DEAD_BINDER notifications can cause transactions */ - } break; - } - - if (!t) - continue; - - BUG_ON(t->buffer == NULL); - if (t->buffer->target_node) { - struct binder_node *target_node = t->buffer->target_node; - tr.target.ptr = target_node->ptr; - tr.cookie = target_node->cookie; - t->saved_priority = task_nice(current); - if (t->priority < target_node->min_priority && - !(t->flags & TF_ONE_WAY)) - binder_set_nice(t->priority); - else if (!(t->flags & TF_ONE_WAY) || - t->saved_priority > target_node->min_priority) - binder_set_nice(target_node->min_priority); - cmd = BR_TRANSACTION; - } else { - tr.target.ptr = NULL; - tr.cookie = NULL; - cmd = BR_REPLY; - } - tr.code = t->code; - tr.flags = t->flags; - tr.sender_euid = t->sender_euid; - - if (t->from) { - struct task_struct *sender = t->from->proc->tsk; - tr.sender_pid = task_tgid_nr_ns(sender, - current->nsproxy->pid_ns); - } else { - tr.sender_pid = 0; - } - - tr.data_size = t->buffer->data_size; - tr.offsets_size = t->buffer->offsets_size; - tr.data.ptr.buffer = (void *)t->buffer->data + - proc->user_buffer_offset; - tr.data.ptr.offsets = tr.data.ptr.buffer + - ALIGN(t->buffer->data_size, - sizeof(void *)); - - if (put_user(cmd, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (copy_to_user(ptr, &tr, sizeof(tr))) - return -EFAULT; - ptr += sizeof(tr); - - binder_stat_br(proc, thread, cmd); - binder_debug(BINDER_DEBUG_TRANSACTION, - "binder: %d:%d %s %d %d:%d, cmd %d" - "size %zd-%zd ptr %p-%p\n", - proc->pid, thread->pid, - (cmd == BR_TRANSACTION) ? "BR_TRANSACTION" : - "BR_REPLY", - t->debug_id, t->from ? t->from->proc->pid : 0, - t->from ? t->from->pid : 0, cmd, - t->buffer->data_size, t->buffer->offsets_size, - tr.data.ptr.buffer, tr.data.ptr.offsets); - - list_del(&t->work.entry); - t->buffer->allow_user_free = 1; - if (cmd == BR_TRANSACTION && !(t->flags & TF_ONE_WAY)) { - t->to_parent = thread->transaction_stack; - t->to_thread = thread; - thread->transaction_stack = t; - } else { - t->buffer->transaction = NULL; - kfree(t); - binder_stats_deleted(BINDER_STAT_TRANSACTION); - } - break; - } - -done: - - *consumed = ptr - buffer; - if (proc->requested_threads + proc->ready_threads == 0 && - proc->requested_threads_started < proc->max_threads && - (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | - BINDER_LOOPER_STATE_ENTERED)) /* the user-space code fails to */ - /*spawn a new thread if we leave this out */) { - proc->requested_threads++; - binder_debug(BINDER_DEBUG_THREADS, - "binder: %d:%d BR_SPAWN_LOOPER\n", - proc->pid, thread->pid); - if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer)) - return -EFAULT; - } - return 0; -} - -static void binder_release_work(struct list_head *list) -{ - struct binder_work *w; - while (!list_empty(list)) { - w = list_first_entry(list, struct binder_work, entry); - list_del_init(&w->entry); - switch (w->type) { - case BINDER_WORK_TRANSACTION: { - struct binder_transaction *t; - - t = container_of(w, struct binder_transaction, work); - if (t->buffer->target_node && !(t->flags & TF_ONE_WAY)) - binder_send_failed_reply(t, BR_DEAD_REPLY); - } break; - case BINDER_WORK_TRANSACTION_COMPLETE: { - kfree(w); - binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); - } break; - default: - break; - } - } - -} - -static struct binder_thread *binder_get_thread(struct binder_proc *proc) -{ - struct binder_thread *thread = NULL; - struct rb_node *parent = NULL; - struct rb_node **p = &proc->threads.rb_node; - - while (*p) { - parent = *p; - thread = rb_entry(parent, struct binder_thread, rb_node); - - if (current->pid < thread->pid) - p = &(*p)->rb_left; - else if (current->pid > thread->pid) - p = &(*p)->rb_right; - else - break; - } - if (*p == NULL) { - thread = kzalloc(sizeof(*thread), GFP_KERNEL); - if (thread == NULL) - return NULL; - binder_stats_created(BINDER_STAT_THREAD); - thread->proc = proc; - thread->pid = current->pid; - init_waitqueue_head(&thread->wait); - INIT_LIST_HEAD(&thread->todo); - rb_link_node(&thread->rb_node, parent, p); - rb_insert_color(&thread->rb_node, &proc->threads); - thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN; - thread->return_error = BR_OK; - thread->return_error2 = BR_OK; - } - return thread; -} - -static int binder_free_thread(struct binder_proc *proc, - struct binder_thread *thread) -{ - struct binder_transaction *t; - struct binder_transaction *send_reply = NULL; - int active_transactions = 0; - - rb_erase(&thread->rb_node, &proc->threads); - t = thread->transaction_stack; - if (t && t->to_thread == thread) - send_reply = t; - while (t) { - active_transactions++; - binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, - "binder: release %d:%d transaction %d " - "%s, still active\n", proc->pid, thread->pid, - t->debug_id, - (t->to_thread == thread) ? "in" : "out"); - - if (t->to_thread == thread) { - t->to_proc = NULL; - t->to_thread = NULL; - if (t->buffer) { - t->buffer->transaction = NULL; - t->buffer = NULL; - } - t = t->to_parent; - } else if (t->from == thread) { - t->from = NULL; - t = t->from_parent; - } else - BUG(); - } - if (send_reply) - binder_send_failed_reply(send_reply, BR_DEAD_REPLY); - binder_release_work(&thread->todo); - kfree(thread); - binder_stats_deleted(BINDER_STAT_THREAD); - return active_transactions; -} - -static unsigned int binder_poll(struct file *filp, - struct poll_table_struct *wait) -{ - struct binder_proc *proc = filp->private_data; - struct binder_thread *thread = NULL; - int wait_for_proc_work; - - mutex_lock(&binder_lock); - thread = binder_get_thread(proc); - - wait_for_proc_work = thread->transaction_stack == NULL && - list_empty(&thread->todo) && thread->return_error == BR_OK; - mutex_unlock(&binder_lock); - - if (wait_for_proc_work) { - if (binder_has_proc_work(proc, thread)) - return POLLIN; - poll_wait(filp, &proc->wait, wait); - if (binder_has_proc_work(proc, thread)) - return POLLIN; - } else { - if (binder_has_thread_work(thread)) - return POLLIN; - poll_wait(filp, &thread->wait, wait); - if (binder_has_thread_work(thread)) - return POLLIN; - } - return 0; -} - -static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - int ret; - struct binder_proc *proc = filp->private_data; - struct binder_thread *thread; - unsigned int size = _IOC_SIZE(cmd); - void __user *ubuf = (void __user *)arg; - - /*printk(KERN_INFO "binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/ - - ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); - if (ret) - return ret; - - mutex_lock(&binder_lock); - thread = binder_get_thread(proc); - if (thread == NULL) { - ret = -ENOMEM; - goto err; - } - - switch (cmd) { - case BINDER_WRITE_READ: { - struct binder_write_read bwr; - if (size != sizeof(struct binder_write_read)) { - ret = -EINVAL; - goto err; - } - if (copy_from_user(&bwr, ubuf, sizeof(bwr))) { - ret = -EFAULT; - goto err; - } - binder_debug(BINDER_DEBUG_READ_WRITE, - "binder: %d:%d write %ld at %08lx, read %ld at %08lx\n", - proc->pid, thread->pid, bwr.write_size, bwr.write_buffer, - bwr.read_size, bwr.read_buffer); - - if (bwr.write_size > 0) { - ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed); - if (ret < 0) { - bwr.read_consumed = 0; - if (copy_to_user(ubuf, &bwr, sizeof(bwr))) - ret = -EFAULT; - goto err; - } - } - if (bwr.read_size > 0) { - ret = binder_thread_read(proc, thread, (void __user *)bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK); - if (!list_empty(&proc->todo)) - wake_up_interruptible(&proc->wait); - if (ret < 0) { - if (copy_to_user(ubuf, &bwr, sizeof(bwr))) - ret = -EFAULT; - goto err; - } - } - binder_debug(BINDER_DEBUG_READ_WRITE, - "binder: %d:%d wrote %ld of %ld, read return %ld of %ld\n", - proc->pid, thread->pid, bwr.write_consumed, bwr.write_size, - bwr.read_consumed, bwr.read_size); - if (copy_to_user(ubuf, &bwr, sizeof(bwr))) { - ret = -EFAULT; - goto err; - } - break; - } - case BINDER_SET_MAX_THREADS: - if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) { - ret = -EINVAL; - goto err; - } - break; - case BINDER_SET_CONTEXT_MGR: - if (binder_context_mgr_node != NULL) { - printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already set\n"); - ret = -EBUSY; - goto err; - } - if (binder_context_mgr_uid != -1) { - if (binder_context_mgr_uid != current->cred->euid) { - printk(KERN_ERR "binder: BINDER_SET_" - "CONTEXT_MGR bad uid %d != %d\n", - current->cred->euid, - binder_context_mgr_uid); - ret = -EPERM; - goto err; - } - } else - binder_context_mgr_uid = current->cred->euid; - binder_context_mgr_node = binder_new_node(proc, NULL, NULL); - if (binder_context_mgr_node == NULL) { - ret = -ENOMEM; - goto err; - } - binder_context_mgr_node->local_weak_refs++; - binder_context_mgr_node->local_strong_refs++; - binder_context_mgr_node->has_strong_ref = 1; - binder_context_mgr_node->has_weak_ref = 1; - break; - case BINDER_THREAD_EXIT: - binder_debug(BINDER_DEBUG_THREADS, "binder: %d:%d exit\n", - proc->pid, thread->pid); - binder_free_thread(proc, thread); - thread = NULL; - break; - case BINDER_VERSION: - if (size != sizeof(struct binder_version)) { - ret = -EINVAL; - goto err; - } - if (put_user(BINDER_CURRENT_PROTOCOL_VERSION, &((struct binder_version *)ubuf)->protocol_version)) { - ret = -EINVAL; - goto err; - } - break; - default: - ret = -EINVAL; - goto err; - } - ret = 0; -err: - if (thread) - thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN; - mutex_unlock(&binder_lock); - wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); - if (ret && ret != -ERESTARTSYS) - printk(KERN_INFO "binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret); - return ret; -} - -static void binder_vma_open(struct vm_area_struct *vma) -{ - struct binder_proc *proc = vma->vm_private_data; - binder_debug(BINDER_DEBUG_OPEN_CLOSE, - "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", - proc->pid, vma->vm_start, vma->vm_end, - (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, - (unsigned long)pgprot_val(vma->vm_page_prot)); - dump_stack(); -} - -static void binder_vma_close(struct vm_area_struct *vma) -{ - struct binder_proc *proc = vma->vm_private_data; - binder_debug(BINDER_DEBUG_OPEN_CLOSE, - "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", - proc->pid, vma->vm_start, vma->vm_end, - (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, - (unsigned long)pgprot_val(vma->vm_page_prot)); - proc->vma = NULL; - binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES); -} - -static struct vm_operations_struct binder_vm_ops = { - .open = binder_vma_open, - .close = binder_vma_close, -}; - -static int binder_mmap(struct file *filp, struct vm_area_struct *vma) -{ - int ret; - struct vm_struct *area; - struct binder_proc *proc = filp->private_data; - const char *failure_string; - struct binder_buffer *buffer; - - if ((vma->vm_end - vma->vm_start) > SZ_4M) - vma->vm_end = vma->vm_start + SZ_4M; - - binder_debug(BINDER_DEBUG_OPEN_CLOSE, - "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", - proc->pid, vma->vm_start, vma->vm_end, - (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, - (unsigned long)pgprot_val(vma->vm_page_prot)); - - if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) { - ret = -EPERM; - failure_string = "bad vm_flags"; - goto err_bad_arg; - } - vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE; - - if (proc->buffer) { - ret = -EBUSY; - failure_string = "already mapped"; - goto err_already_mapped; - } - - area = get_vm_area(vma->vm_end - vma->vm_start, VM_IOREMAP); - if (area == NULL) { - ret = -ENOMEM; - failure_string = "get_vm_area"; - goto err_get_vm_area_failed; - } - proc->buffer = area->addr; - proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer; - -#ifdef CONFIG_CPU_CACHE_VIPT - if (cache_is_vipt_aliasing()) { - while (CACHE_COLOUR((vma->vm_start ^ (uint32_t)proc->buffer))) { - printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p bad alignment\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer); - vma->vm_start += PAGE_SIZE; - } - } -#endif - proc->pages = kzalloc(sizeof(proc->pages[0]) * ((vma->vm_end - vma->vm_start) / PAGE_SIZE), GFP_KERNEL); - if (proc->pages == NULL) { - ret = -ENOMEM; - failure_string = "alloc page array"; - goto err_alloc_pages_failed; - } - proc->buffer_size = vma->vm_end - vma->vm_start; - - vma->vm_ops = &binder_vm_ops; - vma->vm_private_data = proc; - - if (binder_update_page_range(proc, 1, proc->buffer, proc->buffer + PAGE_SIZE, vma)) { - ret = -ENOMEM; - failure_string = "alloc small buf"; - goto err_alloc_small_buf_failed; - } - buffer = proc->buffer; - INIT_LIST_HEAD(&proc->buffers); - list_add(&buffer->entry, &proc->buffers); - buffer->free = 1; - binder_insert_free_buffer(proc, buffer); - proc->free_async_space = proc->buffer_size / 2; - barrier(); - proc->files = get_files_struct(current); - proc->vma = vma; - - /*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n", - proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/ - return 0; - -err_alloc_small_buf_failed: - kfree(proc->pages); - proc->pages = NULL; -err_alloc_pages_failed: - vfree(proc->buffer); - proc->buffer = NULL; -err_get_vm_area_failed: -err_already_mapped: -err_bad_arg: - printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n", - proc->pid, vma->vm_start, vma->vm_end, failure_string, ret); - return ret; -} - -static int binder_open(struct inode *nodp, struct file *filp) -{ - struct binder_proc *proc; - - binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n", - current->group_leader->pid, current->pid); - - proc = kzalloc(sizeof(*proc), GFP_KERNEL); - if (proc == NULL) - return -ENOMEM; - get_task_struct(current); - proc->tsk = current; - INIT_LIST_HEAD(&proc->todo); - init_waitqueue_head(&proc->wait); - proc->default_priority = task_nice(current); - mutex_lock(&binder_lock); - binder_stats_created(BINDER_STAT_PROC); - hlist_add_head(&proc->proc_node, &binder_procs); - proc->pid = current->group_leader->pid; - INIT_LIST_HEAD(&proc->delivered_death); - filp->private_data = proc; - mutex_unlock(&binder_lock); - - if (binder_debugfs_dir_entry_proc) { - char strbuf[11]; - snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); - proc->debugfs_entry = debugfs_create_file(strbuf, S_IRUGO, - binder_debugfs_dir_entry_proc, proc, &binder_proc_fops); - } - - return 0; -} - -static int binder_flush(struct file *filp, fl_owner_t id) -{ - struct binder_proc *proc = filp->private_data; - - binder_defer_work(proc, BINDER_DEFERRED_FLUSH); - - return 0; -} - -static void binder_deferred_flush(struct binder_proc *proc) -{ - struct rb_node *n; - int wake_count = 0; - for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) { - struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node); - thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN; - if (thread->looper & BINDER_LOOPER_STATE_WAITING) { - wake_up_interruptible(&thread->wait); - wake_count++; - } - } - wake_up_interruptible_all(&proc->wait); - - binder_debug(BINDER_DEBUG_OPEN_CLOSE, - "binder_flush: %d woke %d threads\n", proc->pid, - wake_count); -} - -static int binder_release(struct inode *nodp, struct file *filp) -{ - struct binder_proc *proc = filp->private_data; - debugfs_remove(proc->debugfs_entry); - binder_defer_work(proc, BINDER_DEFERRED_RELEASE); - - return 0; -} - -static void binder_deferred_release(struct binder_proc *proc) -{ - struct hlist_node *pos; - struct binder_transaction *t; - struct rb_node *n; - int threads, nodes, incoming_refs, outgoing_refs, buffers, active_transactions, page_count; - - BUG_ON(proc->vma); - BUG_ON(proc->files); - - hlist_del(&proc->proc_node); - if (binder_context_mgr_node && binder_context_mgr_node->proc == proc) { - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder_release: %d context_mgr_node gone\n", - proc->pid); - binder_context_mgr_node = NULL; - } - - threads = 0; - active_transactions = 0; - while ((n = rb_first(&proc->threads))) { - struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node); - threads++; - active_transactions += binder_free_thread(proc, thread); - } - nodes = 0; - incoming_refs = 0; - while ((n = rb_first(&proc->nodes))) { - struct binder_node *node = rb_entry(n, struct binder_node, rb_node); - - nodes++; - rb_erase(&node->rb_node, &proc->nodes); - list_del_init(&node->work.entry); - if (hlist_empty(&node->refs)) { - kfree(node); - binder_stats_deleted(BINDER_STAT_NODE); - } else { - struct binder_ref *ref; - int death = 0; - - node->proc = NULL; - node->local_strong_refs = 0; - node->local_weak_refs = 0; - hlist_add_head(&node->dead_node, &binder_dead_nodes); - - hlist_for_each_entry(ref, pos, &node->refs, node_entry) { - incoming_refs++; - if (ref->death) { - death++; - if (list_empty(&ref->death->work.entry)) { - ref->death->work.type = BINDER_WORK_DEAD_BINDER; - list_add_tail(&ref->death->work.entry, &ref->proc->todo); - wake_up_interruptible(&ref->proc->wait); - } else - BUG(); - } - } - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: node %d now dead, " - "refs %d, death %d\n", node->debug_id, - incoming_refs, death); - } - } - outgoing_refs = 0; - while ((n = rb_first(&proc->refs_by_desc))) { - struct binder_ref *ref = rb_entry(n, struct binder_ref, - rb_node_desc); - outgoing_refs++; - binder_delete_ref(ref); - } - binder_release_work(&proc->todo); - buffers = 0; - - while ((n = rb_first(&proc->allocated_buffers))) { - struct binder_buffer *buffer = rb_entry(n, struct binder_buffer, - rb_node); - t = buffer->transaction; - if (t) { - t->buffer = NULL; - buffer->transaction = NULL; - printk(KERN_ERR "binder: release proc %d, " - "transaction %d, not freed\n", - proc->pid, t->debug_id); - /*BUG();*/ - } - binder_free_buf(proc, buffer); - buffers++; - } - - binder_stats_deleted(BINDER_STAT_PROC); - - page_count = 0; - if (proc->pages) { - int i; - for (i = 0; i < proc->buffer_size / PAGE_SIZE; i++) { - if (proc->pages[i]) { - void *page_addr = proc->buffer + i * PAGE_SIZE; - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder_release: %d: " - "page %d at %p not freed\n", - proc->pid, i, - page_addr); - unmap_kernel_range((unsigned long)page_addr, - PAGE_SIZE); - __free_page(proc->pages[i]); - page_count++; - } - } - kfree(proc->pages); - vfree(proc->buffer); - } - - put_task_struct(proc->tsk); - - binder_debug(BINDER_DEBUG_OPEN_CLOSE, - "binder_release: %d threads %d, nodes %d (ref %d), " - "refs %d, active transactions %d, buffers %d, " - "pages %d\n", - proc->pid, threads, nodes, incoming_refs, outgoing_refs, - active_transactions, buffers, page_count); - - kfree(proc); -} - -static void binder_deferred_func(struct work_struct *work) -{ - struct binder_proc *proc; - struct files_struct *files; - - int defer; - do { - mutex_lock(&binder_lock); - mutex_lock(&binder_deferred_lock); - if (!hlist_empty(&binder_deferred_list)) { - proc = hlist_entry(binder_deferred_list.first, - struct binder_proc, deferred_work_node); - hlist_del_init(&proc->deferred_work_node); - defer = proc->deferred_work; - proc->deferred_work = 0; - } else { - proc = NULL; - defer = 0; - } - mutex_unlock(&binder_deferred_lock); - - files = NULL; - if (defer & BINDER_DEFERRED_PUT_FILES) { - files = proc->files; - if (files) - proc->files = NULL; - } - - if (defer & BINDER_DEFERRED_FLUSH) - binder_deferred_flush(proc); - - if (defer & BINDER_DEFERRED_RELEASE) - binder_deferred_release(proc); /* frees proc */ - - mutex_unlock(&binder_lock); - if (files) - put_files_struct(files); - } while (proc); -} -static DECLARE_WORK(binder_deferred_work, binder_deferred_func); - -static void -binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer) -{ - mutex_lock(&binder_deferred_lock); - proc->deferred_work |= defer; - if (hlist_unhashed(&proc->deferred_work_node)) { - hlist_add_head(&proc->deferred_work_node, - &binder_deferred_list); - queue_work(binder_deferred_workqueue, &binder_deferred_work); - } - mutex_unlock(&binder_deferred_lock); -} - -static void print_binder_transaction(struct seq_file *m, const char *prefix, - struct binder_transaction *t) -{ - seq_printf(m, - "%s %d: %p from %d:%d to %d:%d code %x flags %x pri %ld r%d", - prefix, t->debug_id, t, - t->from ? t->from->proc->pid : 0, - t->from ? t->from->pid : 0, - t->to_proc ? t->to_proc->pid : 0, - t->to_thread ? t->to_thread->pid : 0, - t->code, t->flags, t->priority, t->need_reply); - if (t->buffer == NULL) { - seq_puts(m, " buffer free\n"); - return; - } - if (t->buffer->target_node) - seq_printf(m, " node %d", - t->buffer->target_node->debug_id); - seq_printf(m, " size %zd:%zd data %p\n", - t->buffer->data_size, t->buffer->offsets_size, - t->buffer->data); -} - -static void print_binder_buffer(struct seq_file *m, const char *prefix, - struct binder_buffer *buffer) -{ - seq_printf(m, "%s %d: %p size %zd:%zd %s\n", - prefix, buffer->debug_id, buffer->data, - buffer->data_size, buffer->offsets_size, - buffer->transaction ? "active" : "delivered"); -} - -static void print_binder_work(struct seq_file *m, const char *prefix, - const char *transaction_prefix, - struct binder_work *w) -{ - struct binder_node *node; - struct binder_transaction *t; - - switch (w->type) { - case BINDER_WORK_TRANSACTION: - t = container_of(w, struct binder_transaction, work); - print_binder_transaction(m, transaction_prefix, t); - break; - case BINDER_WORK_TRANSACTION_COMPLETE: - seq_printf(m, "%stransaction complete\n", prefix); - break; - case BINDER_WORK_NODE: - node = container_of(w, struct binder_node, work); - seq_printf(m, "%snode work %d: u%p c%p\n", - prefix, node->debug_id, node->ptr, node->cookie); - break; - case BINDER_WORK_DEAD_BINDER: - seq_printf(m, "%shas dead binder\n", prefix); - break; - case BINDER_WORK_DEAD_BINDER_AND_CLEAR: - seq_printf(m, "%shas cleared dead binder\n", prefix); - break; - case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: - seq_printf(m, "%shas cleared death notification\n", prefix); - break; - default: - seq_printf(m, "%sunknown work: type %d\n", prefix, w->type); - break; - } -} - -static void print_binder_thread(struct seq_file *m, - struct binder_thread *thread, - int print_always) -{ - struct binder_transaction *t; - struct binder_work *w; - size_t start_pos = m->count; - size_t header_pos; - - seq_printf(m, " thread %d: l %02x\n", thread->pid, thread->looper); - header_pos = m->count; - t = thread->transaction_stack; - while (t) { - if (t->from == thread) { - print_binder_transaction(m, - " outgoing transaction", t); - t = t->from_parent; - } else if (t->to_thread == thread) { - print_binder_transaction(m, - " incoming transaction", t); - t = t->to_parent; - } else { - print_binder_transaction(m, " bad transaction", t); - t = NULL; - } - } - list_for_each_entry(w, &thread->todo, entry) { - print_binder_work(m, " ", " pending transaction", w); - } - if (!print_always && m->count == header_pos) - m->count = start_pos; -} - -static void print_binder_node(struct seq_file *m, struct binder_node *node) -{ - struct binder_ref *ref; - struct hlist_node *pos; - struct binder_work *w; - int count; - - count = 0; - hlist_for_each_entry(ref, pos, &node->refs, node_entry) - count++; - - seq_printf(m, " node %d: u%p c%p hs %d hw %d ls %d lw %d is %d iw %d", - node->debug_id, node->ptr, node->cookie, - node->has_strong_ref, node->has_weak_ref, - node->local_strong_refs, node->local_weak_refs, - node->internal_strong_refs, count); - if (count) { - seq_puts(m, " proc"); - hlist_for_each_entry(ref, pos, &node->refs, node_entry) - seq_printf(m, " %d", ref->proc->pid); - } - seq_puts(m, "\n"); - list_for_each_entry(w, &node->async_todo, entry) - print_binder_work(m, " ", - " pending async transaction", w); -} - -static void print_binder_ref(struct seq_file *m, struct binder_ref *ref) -{ - seq_printf(m, " ref %d: desc %d %snode %d s %d w %d d %p\n", - ref->debug_id, ref->desc, ref->node->proc ? "" : "dead ", - ref->node->debug_id, ref->strong, ref->weak, ref->death); -} - -static void print_binder_proc(struct seq_file *m, - struct binder_proc *proc, int print_all) -{ - struct binder_work *w; - struct rb_node *n; - size_t start_pos = m->count; - size_t header_pos; - - seq_printf(m, "proc %d\n", proc->pid); - header_pos = m->count; - - for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) - print_binder_thread(m, rb_entry(n, struct binder_thread, - rb_node), print_all); - for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) { - struct binder_node *node = rb_entry(n, struct binder_node, - rb_node); - if (print_all || node->has_async_transaction) - print_binder_node(m, node); - } - if (print_all) { - for (n = rb_first(&proc->refs_by_desc); - n != NULL; - n = rb_next(n)) - print_binder_ref(m, rb_entry(n, struct binder_ref, - rb_node_desc)); - } - for (n = rb_first(&proc->allocated_buffers); n != NULL; n = rb_next(n)) - print_binder_buffer(m, " buffer", - rb_entry(n, struct binder_buffer, rb_node)); - list_for_each_entry(w, &proc->todo, entry) - print_binder_work(m, " ", " pending transaction", w); - list_for_each_entry(w, &proc->delivered_death, entry) { - seq_puts(m, " has delivered dead binder\n"); - break; - } - if (!print_all && m->count == header_pos) - m->count = start_pos; -} - -static const char *binder_return_strings[] = { - "BR_ERROR", - "BR_OK", - "BR_TRANSACTION", - "BR_REPLY", - "BR_ACQUIRE_RESULT", - "BR_DEAD_REPLY", - "BR_TRANSACTION_COMPLETE", - "BR_INCREFS", - "BR_ACQUIRE", - "BR_RELEASE", - "BR_DECREFS", - "BR_ATTEMPT_ACQUIRE", - "BR_NOOP", - "BR_SPAWN_LOOPER", - "BR_FINISHED", - "BR_DEAD_BINDER", - "BR_CLEAR_DEATH_NOTIFICATION_DONE", - "BR_FAILED_REPLY" -}; - -static const char *binder_command_strings[] = { - "BC_TRANSACTION", - "BC_REPLY", - "BC_ACQUIRE_RESULT", - "BC_FREE_BUFFER", - "BC_INCREFS", - "BC_ACQUIRE", - "BC_RELEASE", - "BC_DECREFS", - "BC_INCREFS_DONE", - "BC_ACQUIRE_DONE", - "BC_ATTEMPT_ACQUIRE", - "BC_REGISTER_LOOPER", - "BC_ENTER_LOOPER", - "BC_EXIT_LOOPER", - "BC_REQUEST_DEATH_NOTIFICATION", - "BC_CLEAR_DEATH_NOTIFICATION", - "BC_DEAD_BINDER_DONE" -}; - -static const char *binder_objstat_strings[] = { - "proc", - "thread", - "node", - "ref", - "death", - "transaction", - "transaction_complete" -}; - -static void print_binder_stats(struct seq_file *m, const char *prefix, - struct binder_stats *stats) -{ - int i; - - BUILD_BUG_ON(ARRAY_SIZE(stats->bc) != - ARRAY_SIZE(binder_command_strings)); - for (i = 0; i < ARRAY_SIZE(stats->bc); i++) { - if (stats->bc[i]) - seq_printf(m, "%s%s: %d\n", prefix, - binder_command_strings[i], stats->bc[i]); - } - - BUILD_BUG_ON(ARRAY_SIZE(stats->br) != - ARRAY_SIZE(binder_return_strings)); - for (i = 0; i < ARRAY_SIZE(stats->br); i++) { - if (stats->br[i]) - seq_printf(m, "%s%s: %d\n", prefix, - binder_return_strings[i], stats->br[i]); - } - - BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != - ARRAY_SIZE(binder_objstat_strings)); - BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != - ARRAY_SIZE(stats->obj_deleted)); - for (i = 0; i < ARRAY_SIZE(stats->obj_created); i++) { - if (stats->obj_created[i] || stats->obj_deleted[i]) - seq_printf(m, "%s%s: active %d total %d\n", prefix, - binder_objstat_strings[i], - stats->obj_created[i] - stats->obj_deleted[i], - stats->obj_created[i]); - } -} - -static void print_binder_proc_stats(struct seq_file *m, - struct binder_proc *proc) -{ - struct binder_work *w; - struct rb_node *n; - int count, strong, weak; - - seq_printf(m, "proc %d\n", proc->pid); - count = 0; - for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) - count++; - seq_printf(m, " threads: %d\n", count); - seq_printf(m, " requested threads: %d+%d/%d\n" - " ready threads %d\n" - " free async space %zd\n", proc->requested_threads, - proc->requested_threads_started, proc->max_threads, - proc->ready_threads, proc->free_async_space); - count = 0; - for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) - count++; - seq_printf(m, " nodes: %d\n", count); - count = 0; - strong = 0; - weak = 0; - for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) { - struct binder_ref *ref = rb_entry(n, struct binder_ref, - rb_node_desc); - count++; - strong += ref->strong; - weak += ref->weak; - } - seq_printf(m, " refs: %d s %d w %d\n", count, strong, weak); - - count = 0; - for (n = rb_first(&proc->allocated_buffers); n != NULL; n = rb_next(n)) - count++; - seq_printf(m, " buffers: %d\n", count); - - count = 0; - list_for_each_entry(w, &proc->todo, entry) { - switch (w->type) { - case BINDER_WORK_TRANSACTION: - count++; - break; - default: - break; - } - } - seq_printf(m, " pending transactions: %d\n", count); - - print_binder_stats(m, " ", &proc->stats); -} - - -static int binder_state_show(struct seq_file *m, void *unused) -{ - struct binder_proc *proc; - struct hlist_node *pos; - struct binder_node *node; - int do_lock = !binder_debug_no_lock; - - if (do_lock) - mutex_lock(&binder_lock); - - seq_puts(m, "binder state:\n"); - - if (!hlist_empty(&binder_dead_nodes)) - seq_puts(m, "dead nodes:\n"); - hlist_for_each_entry(node, pos, &binder_dead_nodes, dead_node) - print_binder_node(m, node); - - hlist_for_each_entry(proc, pos, &binder_procs, proc_node) - print_binder_proc(m, proc, 1); - if (do_lock) - mutex_unlock(&binder_lock); - return 0; -} - -static int binder_stats_show(struct seq_file *m, void *unused) -{ - struct binder_proc *proc; - struct hlist_node *pos; - int do_lock = !binder_debug_no_lock; - - if (do_lock) - mutex_lock(&binder_lock); - - seq_puts(m, "binder stats:\n"); - - print_binder_stats(m, "", &binder_stats); - - hlist_for_each_entry(proc, pos, &binder_procs, proc_node) - print_binder_proc_stats(m, proc); - if (do_lock) - mutex_unlock(&binder_lock); - return 0; -} - -static int binder_transactions_show(struct seq_file *m, void *unused) -{ - struct binder_proc *proc; - struct hlist_node *pos; - int do_lock = !binder_debug_no_lock; - - if (do_lock) - mutex_lock(&binder_lock); - - seq_puts(m, "binder transactions:\n"); - hlist_for_each_entry(proc, pos, &binder_procs, proc_node) - print_binder_proc(m, proc, 0); - if (do_lock) - mutex_unlock(&binder_lock); - return 0; -} - -static int binder_proc_show(struct seq_file *m, void *unused) -{ - struct binder_proc *proc = m->private; - int do_lock = !binder_debug_no_lock; - - if (do_lock) - mutex_lock(&binder_lock); - seq_puts(m, "binder proc state:\n"); - print_binder_proc(m, proc, 1); - if (do_lock) - mutex_unlock(&binder_lock); - return 0; -} - -static void print_binder_transaction_log_entry(struct seq_file *m, - struct binder_transaction_log_entry *e) -{ - seq_printf(m, - "%d: %s from %d:%d to %d:%d node %d handle %d size %d:%d\n", - e->debug_id, (e->call_type == 2) ? "reply" : - ((e->call_type == 1) ? "async" : "call "), e->from_proc, - e->from_thread, e->to_proc, e->to_thread, e->to_node, - e->target_handle, e->data_size, e->offsets_size); -} - -static int binder_transaction_log_show(struct seq_file *m, void *unused) -{ - struct binder_transaction_log *log = m->private; - int i; - - if (log->full) { - for (i = log->next; i < ARRAY_SIZE(log->entry); i++) - print_binder_transaction_log_entry(m, &log->entry[i]); - } - for (i = 0; i < log->next; i++) - print_binder_transaction_log_entry(m, &log->entry[i]); - return 0; -} - -static const struct file_operations binder_fops = { - .owner = THIS_MODULE, - .poll = binder_poll, - .unlocked_ioctl = binder_ioctl, - .mmap = binder_mmap, - .open = binder_open, - .flush = binder_flush, - .release = binder_release, -}; - -static struct miscdevice binder_miscdev = { - .minor = MISC_DYNAMIC_MINOR, - .name = "binder", - .fops = &binder_fops -}; - -BINDER_DEBUG_ENTRY(state); -BINDER_DEBUG_ENTRY(stats); -BINDER_DEBUG_ENTRY(transactions); -BINDER_DEBUG_ENTRY(transaction_log); - -static int __init binder_init(void) -{ - int ret; - - binder_deferred_workqueue = create_singlethread_workqueue("binder"); - if (!binder_deferred_workqueue) - return -ENOMEM; - - binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL); - if (binder_debugfs_dir_entry_root) - binder_debugfs_dir_entry_proc = debugfs_create_dir("proc", - binder_debugfs_dir_entry_root); - ret = misc_register(&binder_miscdev); - if (binder_debugfs_dir_entry_root) { - debugfs_create_file("state", - S_IRUGO, - binder_debugfs_dir_entry_root, - NULL, - &binder_state_fops); - debugfs_create_file("stats", - S_IRUGO, - binder_debugfs_dir_entry_root, - NULL, - &binder_stats_fops); - debugfs_create_file("transactions", - S_IRUGO, - binder_debugfs_dir_entry_root, - NULL, - &binder_transactions_fops); - debugfs_create_file("transaction_log", - S_IRUGO, - binder_debugfs_dir_entry_root, - &binder_transaction_log, - &binder_transaction_log_fops); - debugfs_create_file("failed_transaction_log", - S_IRUGO, - binder_debugfs_dir_entry_root, - &binder_transaction_log_failed, - &binder_transaction_log_fops); - } - return ret; -} - -device_initcall(binder_init); - -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/android/binder.h b/drivers/staging/android/binder.h deleted file mode 100644 index 863ae1ad5d55..000000000000 --- a/drivers/staging/android/binder.h +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (C) 2008 Google, Inc. - * - * Based on, but no longer compatible with, the original - * OpenBinder.org binder driver interface, which is: - * - * Copyright (c) 2005 Palmsource, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _LINUX_BINDER_H -#define _LINUX_BINDER_H - -#include - -#define B_PACK_CHARS(c1, c2, c3, c4) \ - ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4)) -#define B_TYPE_LARGE 0x85 - -enum { - BINDER_TYPE_BINDER = B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE), - BINDER_TYPE_WEAK_BINDER = B_PACK_CHARS('w', 'b', '*', B_TYPE_LARGE), - BINDER_TYPE_HANDLE = B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE), - BINDER_TYPE_WEAK_HANDLE = B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE), - BINDER_TYPE_FD = B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE), -}; - -enum { - FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff, - FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100, -}; - -/* - * This is the flattened representation of a Binder object for transfer - * between processes. The 'offsets' supplied as part of a binder transaction - * contains offsets into the data where these structures occur. The Binder - * driver takes care of re-writing the structure type and data as it moves - * between processes. - */ -struct flat_binder_object { - /* 8 bytes for large_flat_header. */ - unsigned long type; - unsigned long flags; - - /* 8 bytes of data. */ - union { - void *binder; /* local object */ - signed long handle; /* remote object */ - }; - - /* extra data associated with local object */ - void *cookie; -}; - -/* - * On 64-bit platforms where user code may run in 32-bits the driver must - * translate the buffer (and local binder) addresses apropriately. - */ - -struct binder_write_read { - signed long write_size; /* bytes to write */ - signed long write_consumed; /* bytes consumed by driver */ - unsigned long write_buffer; - signed long read_size; /* bytes to read */ - signed long read_consumed; /* bytes consumed by driver */ - unsigned long read_buffer; -}; - -/* Use with BINDER_VERSION, driver fills in fields. */ -struct binder_version { - /* driver protocol version -- increment with incompatible change */ - signed long protocol_version; -}; - -/* This is the current protocol version. */ -#define BINDER_CURRENT_PROTOCOL_VERSION 7 - -#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read) -#define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, int64_t) -#define BINDER_SET_MAX_THREADS _IOW('b', 5, size_t) -#define BINDER_SET_IDLE_PRIORITY _IOW('b', 6, int) -#define BINDER_SET_CONTEXT_MGR _IOW('b', 7, int) -#define BINDER_THREAD_EXIT _IOW('b', 8, int) -#define BINDER_VERSION _IOWR('b', 9, struct binder_version) - -/* - * NOTE: Two special error codes you should check for when calling - * in to the driver are: - * - * EINTR -- The operation has been interupted. This should be - * handled by retrying the ioctl() until a different error code - * is returned. - * - * ECONNREFUSED -- The driver is no longer accepting operations - * from your process. That is, the process is being destroyed. - * You should handle this by exiting from your process. Note - * that once this error code is returned, all further calls to - * the driver from any thread will return this same code. - */ - -enum transaction_flags { - TF_ONE_WAY = 0x01, /* this is a one-way call: async, no return */ - TF_ROOT_OBJECT = 0x04, /* contents are the component's root object */ - TF_STATUS_CODE = 0x08, /* contents are a 32-bit status code */ - TF_ACCEPT_FDS = 0x10, /* allow replies with file descriptors */ -}; - -struct binder_transaction_data { - /* The first two are only used for bcTRANSACTION and brTRANSACTION, - * identifying the target and contents of the transaction. - */ - union { - size_t handle; /* target descriptor of command transaction */ - void *ptr; /* target descriptor of return transaction */ - } target; - void *cookie; /* target object cookie */ - unsigned int code; /* transaction command */ - - /* General information about the transaction. */ - unsigned int flags; - pid_t sender_pid; - uid_t sender_euid; - size_t data_size; /* number of bytes of data */ - size_t offsets_size; /* number of bytes of offsets */ - - /* If this transaction is inline, the data immediately - * follows here; otherwise, it ends with a pointer to - * the data buffer. - */ - union { - struct { - /* transaction data */ - const void *buffer; - /* offsets from buffer to flat_binder_object structs */ - const void *offsets; - } ptr; - uint8_t buf[8]; - } data; -}; - -struct binder_ptr_cookie { - void *ptr; - void *cookie; -}; - -struct binder_pri_desc { - int priority; - int desc; -}; - -struct binder_pri_ptr_cookie { - int priority; - void *ptr; - void *cookie; -}; - -enum BinderDriverReturnProtocol { - BR_ERROR = _IOR('r', 0, int), - /* - * int: error code - */ - - BR_OK = _IO('r', 1), - /* No parameters! */ - - BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data), - BR_REPLY = _IOR('r', 3, struct binder_transaction_data), - /* - * binder_transaction_data: the received command. - */ - - BR_ACQUIRE_RESULT = _IOR('r', 4, int), - /* - * not currently supported - * int: 0 if the last bcATTEMPT_ACQUIRE was not successful. - * Else the remote object has acquired a primary reference. - */ - - BR_DEAD_REPLY = _IO('r', 5), - /* - * The target of the last transaction (either a bcTRANSACTION or - * a bcATTEMPT_ACQUIRE) is no longer with us. No parameters. - */ - - BR_TRANSACTION_COMPLETE = _IO('r', 6), - /* - * No parameters... always refers to the last transaction requested - * (including replies). Note that this will be sent even for - * asynchronous transactions. - */ - - BR_INCREFS = _IOR('r', 7, struct binder_ptr_cookie), - BR_ACQUIRE = _IOR('r', 8, struct binder_ptr_cookie), - BR_RELEASE = _IOR('r', 9, struct binder_ptr_cookie), - BR_DECREFS = _IOR('r', 10, struct binder_ptr_cookie), - /* - * void *: ptr to binder - * void *: cookie for binder - */ - - BR_ATTEMPT_ACQUIRE = _IOR('r', 11, struct binder_pri_ptr_cookie), - /* - * not currently supported - * int: priority - * void *: ptr to binder - * void *: cookie for binder - */ - - BR_NOOP = _IO('r', 12), - /* - * No parameters. Do nothing and examine the next command. It exists - * primarily so that we can replace it with a BR_SPAWN_LOOPER command. - */ - - BR_SPAWN_LOOPER = _IO('r', 13), - /* - * No parameters. The driver has determined that a process has no - * threads waiting to service incomming transactions. When a process - * receives this command, it must spawn a new service thread and - * register it via bcENTER_LOOPER. - */ - - BR_FINISHED = _IO('r', 14), - /* - * not currently supported - * stop threadpool thread - */ - - BR_DEAD_BINDER = _IOR('r', 15, void *), - /* - * void *: cookie - */ - BR_CLEAR_DEATH_NOTIFICATION_DONE = _IOR('r', 16, void *), - /* - * void *: cookie - */ - - BR_FAILED_REPLY = _IO('r', 17), - /* - * The the last transaction (either a bcTRANSACTION or - * a bcATTEMPT_ACQUIRE) failed (e.g. out of memory). No parameters. - */ -}; - -enum BinderDriverCommandProtocol { - BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data), - BC_REPLY = _IOW('c', 1, struct binder_transaction_data), - /* - * binder_transaction_data: the sent command. - */ - - BC_ACQUIRE_RESULT = _IOW('c', 2, int), - /* - * not currently supported - * int: 0 if the last BR_ATTEMPT_ACQUIRE was not successful. - * Else you have acquired a primary reference on the object. - */ - - BC_FREE_BUFFER = _IOW('c', 3, int), - /* - * void *: ptr to transaction data received on a read - */ - - BC_INCREFS = _IOW('c', 4, int), - BC_ACQUIRE = _IOW('c', 5, int), - BC_RELEASE = _IOW('c', 6, int), - BC_DECREFS = _IOW('c', 7, int), - /* - * int: descriptor - */ - - BC_INCREFS_DONE = _IOW('c', 8, struct binder_ptr_cookie), - BC_ACQUIRE_DONE = _IOW('c', 9, struct binder_ptr_cookie), - /* - * void *: ptr to binder - * void *: cookie for binder - */ - - BC_ATTEMPT_ACQUIRE = _IOW('c', 10, struct binder_pri_desc), - /* - * not currently supported - * int: priority - * int: descriptor - */ - - BC_REGISTER_LOOPER = _IO('c', 11), - /* - * No parameters. - * Register a spawned looper thread with the device. - */ - - BC_ENTER_LOOPER = _IO('c', 12), - BC_EXIT_LOOPER = _IO('c', 13), - /* - * No parameters. - * These two commands are sent as an application-level thread - * enters and exits the binder loop, respectively. They are - * used so the binder can have an accurate count of the number - * of looping threads it has available. - */ - - BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14, struct binder_ptr_cookie), - /* - * void *: ptr to binder - * void *: cookie - */ - - BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15, struct binder_ptr_cookie), - /* - * void *: ptr to binder - * void *: cookie - */ - - BC_DEAD_BINDER_DONE = _IOW('c', 16, void *), - /* - * void *: cookie - */ -}; - -#endif /* _LINUX_BINDER_H */ - diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c deleted file mode 100644 index 649372814a89..000000000000 --- a/drivers/staging/android/logger.c +++ /dev/null @@ -1,761 +0,0 @@ -/* - * drivers/misc/logger.c - * - * A Logging Subsystem - * - * Copyright (C) 2007-2008 Google, Inc. - * - * Robert Love - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "logger.h" - -#include - -/* - * struct logger_log - represents a specific log, such as 'main' or 'radio' - * - * This structure lives from module insertion until module removal, so it does - * not need additional reference counting. The structure is protected by the - * mutex 'mutex'. - */ -struct logger_log { - unsigned char *buffer;/* the ring buffer itself */ - struct miscdevice misc; /* misc device representing the log */ - wait_queue_head_t wq; /* wait queue for readers */ - struct list_head readers; /* this log's readers */ - struct mutex mutex; /* mutex protecting buffer */ - size_t w_off; /* current write head offset */ - size_t head; /* new readers start here */ - size_t size; /* size of the log */ -}; - -/* - * struct logger_reader - a logging device open for reading - * - * This object lives from open to release, so we don't need additional - * reference counting. The structure is protected by log->mutex. - */ -struct logger_reader { - struct logger_log *log; /* associated log */ - struct list_head list; /* entry in logger_log's list */ - size_t r_off; /* current read head offset */ - bool r_all; /* reader can read all entries */ - int r_ver; /* reader ABI version */ -}; - -/* logger_offset - returns index 'n' into the log via (optimized) modulus */ -#define logger_offset(n) ((n) & (log->size - 1)) - -/* - * file_get_log - Given a file structure, return the associated log - * - * This isn't aesthetic. We have several goals: - * - * 1) Need to quickly obtain the associated log during an I/O operation - * 2) Readers need to maintain state (logger_reader) - * 3) Writers need to be very fast (open() should be a near no-op) - * - * In the reader case, we can trivially go file->logger_reader->logger_log. - * For a writer, we don't want to maintain a logger_reader, so we just go - * file->logger_log. Thus what file->private_data points at depends on whether - * or not the file was opened for reading. This function hides that dirtiness. - */ -static inline struct logger_log *file_get_log(struct file *file) -{ - if (file->f_mode & FMODE_READ) { - struct logger_reader *reader = file->private_data; - return reader->log; - } else - return file->private_data; -} - -/* - * get_entry_header - returns a pointer to the logger_entry header within - * 'log' starting at offset 'off'. A temporary logger_entry 'scratch' must - * be provided. Typically the return value will be a pointer within - * 'logger->buf'. However, a pointer to 'scratch' may be returned if - * the log entry spans the end and beginning of the circular buffer. - */ -static struct logger_entry *get_entry_header(struct logger_log *log, - size_t off, struct logger_entry *scratch) -{ - size_t len = min(sizeof(struct logger_entry), log->size - off); - if (len != sizeof(struct logger_entry)) { - memcpy(((void *) scratch), log->buffer + off, len); - memcpy(((void *) scratch) + len, log->buffer, - sizeof(struct logger_entry) - len); - return scratch; - } - - return (struct logger_entry *) (log->buffer + off); -} - -/* - * get_entry_msg_len - Grabs the length of the message of the entry - * starting from from 'off'. - * - * Caller needs to hold log->mutex. - */ -static __u32 get_entry_msg_len(struct logger_log *log, size_t off) -{ - struct logger_entry scratch; - struct logger_entry *entry; - - entry = get_entry_header(log, off, &scratch); - return entry->len; -} - -static size_t get_user_hdr_len(int ver) -{ - if (ver < 2) - return sizeof(struct user_logger_entry_compat); - else - return sizeof(struct logger_entry); -} - -static ssize_t copy_header_to_user(int ver, struct logger_entry *entry, - char __user *buf) -{ - void *hdr; - size_t hdr_len; - struct user_logger_entry_compat v1; - - if (ver < 2) { - v1.len = entry->len; - v1.__pad = 0; - v1.pid = entry->pid; - v1.tid = entry->tid; - v1.sec = entry->sec; - v1.nsec = entry->nsec; - hdr = &v1; - hdr_len = sizeof(struct user_logger_entry_compat); - } else { - hdr = entry; - hdr_len = sizeof(struct logger_entry); - } - - return copy_to_user(buf, hdr, hdr_len); -} - -/* - * do_read_log_to_user - reads exactly 'count' bytes from 'log' into the - * user-space buffer 'buf'. Returns 'count' on success. - * - * Caller must hold log->mutex. - */ -static ssize_t do_read_log_to_user(struct logger_log *log, - struct logger_reader *reader, - char __user *buf, - size_t count) -{ - struct logger_entry scratch; - struct logger_entry *entry; - size_t len; - size_t msg_start; - - /* - * First, copy the header to userspace, using the version of - * the header requested - */ - entry = get_entry_header(log, reader->r_off, &scratch); - if (copy_header_to_user(reader->r_ver, entry, buf)) - return -EFAULT; - - count -= get_user_hdr_len(reader->r_ver); - buf += get_user_hdr_len(reader->r_ver); - msg_start = logger_offset(reader->r_off + sizeof(struct logger_entry)); - - /* - * We read from the msg in two disjoint operations. First, we read from - * the current msg head offset up to 'count' bytes or to the end of - * the log, whichever comes first. - */ - len = min(count, log->size - msg_start); - if (copy_to_user(buf, log->buffer + msg_start, len)) - return -EFAULT; - - /* - * Second, we read any remaining bytes, starting back at the head of - * the log. - */ - if (count != len) - if (copy_to_user(buf + len, log->buffer, count - len)) - return -EFAULT; - - reader->r_off = logger_offset(reader->r_off + - sizeof(struct logger_entry) + count); - - return count + get_user_hdr_len(reader->r_ver); -} - -/* - * get_next_entry_by_uid - Starting at 'off', returns an offset into - * 'log->buffer' which contains the first entry readable by 'euid' - */ -static size_t get_next_entry_by_uid(struct logger_log *log, - size_t off, uid_t euid) -{ - while (off != log->w_off) { - struct logger_entry *entry; - struct logger_entry scratch; - size_t next_len; - - entry = get_entry_header(log, off, &scratch); - - if (entry->euid == euid) - return off; - - next_len = sizeof(struct logger_entry) + entry->len; - off = logger_offset(off + next_len); - } - - return off; -} - -/* - * logger_read - our log's read() method - * - * Behavior: - * - * - O_NONBLOCK works - * - If there are no log entries to read, blocks until log is written to - * - Atomically reads exactly one log entry - * - * Will set errno to EINVAL if read - * buffer is insufficient to hold next entry. - */ -static ssize_t logger_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - struct logger_reader *reader = file->private_data; - struct logger_log *log = reader->log; - ssize_t ret; - DEFINE_WAIT(wait); - -start: - while (1) { - prepare_to_wait(&log->wq, &wait, TASK_INTERRUPTIBLE); - - mutex_lock(&log->mutex); - ret = (log->w_off == reader->r_off); - mutex_unlock(&log->mutex); - if (!ret) - break; - - if (file->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - break; - } - - if (signal_pending(current)) { - ret = -EINTR; - break; - } - - schedule(); - } - - finish_wait(&log->wq, &wait); - if (ret) - return ret; - - mutex_lock(&log->mutex); - - if (!reader->r_all) - reader->r_off = get_next_entry_by_uid(log, - reader->r_off, current_euid()); - - /* is there still something to read or did we race? */ - if (unlikely(log->w_off == reader->r_off)) { - mutex_unlock(&log->mutex); - goto start; - } - - /* get the size of the next entry */ - ret = get_user_hdr_len(reader->r_ver) + - get_entry_msg_len(log, reader->r_off); - if (count < ret) { - ret = -EINVAL; - goto out; - } - - /* get exactly one entry from the log */ - ret = do_read_log_to_user(log, reader, buf, ret); - -out: - mutex_unlock(&log->mutex); - - return ret; -} - -/* - * get_next_entry - return the offset of the first valid entry at least 'len' - * bytes after 'off'. - * - * Caller must hold log->mutex. - */ -static size_t get_next_entry(struct logger_log *log, size_t off, size_t len) -{ - size_t count = 0; - - do { - size_t nr = sizeof(struct logger_entry) + - get_entry_msg_len(log, off); - off = logger_offset(off + nr); - count += nr; - } while (count < len); - - return off; -} - -/* - * clock_interval - is a < c < b in mod-space? Put another way, does the line - * from a to b cross c? - */ -static inline int clock_interval(size_t a, size_t b, size_t c) -{ - if (b < a) { - if (a < c || b >= c) - return 1; - } else { - if (a < c && b >= c) - return 1; - } - - return 0; -} - -/* - * fix_up_readers - walk the list of all readers and "fix up" any who were - * lapped by the writer; also do the same for the default "start head". - * We do this by "pulling forward" the readers and start head to the first - * entry after the new write head. - * - * The caller needs to hold log->mutex. - */ -static void fix_up_readers(struct logger_log *log, size_t len) -{ - size_t old = log->w_off; - size_t new = logger_offset(old + len); - struct logger_reader *reader; - - if (clock_interval(old, new, log->head)) - log->head = get_next_entry(log, log->head, len); - - list_for_each_entry(reader, &log->readers, list) - if (clock_interval(old, new, reader->r_off)) - reader->r_off = get_next_entry(log, reader->r_off, len); -} - -/* - * do_write_log - writes 'len' bytes from 'buf' to 'log' - * - * The caller needs to hold log->mutex. - */ -static void do_write_log(struct logger_log *log, const void *buf, size_t count) -{ - size_t len; - - len = min(count, log->size - log->w_off); - memcpy(log->buffer + log->w_off, buf, len); - - if (count != len) - memcpy(log->buffer, buf + len, count - len); - - log->w_off = logger_offset(log->w_off + count); - -} - -/* - * do_write_log_user - writes 'len' bytes from the user-space buffer 'buf' to - * the log 'log' - * - * The caller needs to hold log->mutex. - * - * Returns 'count' on success, negative error code on failure. - */ -static ssize_t do_write_log_from_user(struct logger_log *log, - const void __user *buf, size_t count) -{ - size_t len; - - len = min(count, log->size - log->w_off); - if (len && copy_from_user(log->buffer + log->w_off, buf, len)) - return -EFAULT; - - if (count != len) - if (copy_from_user(log->buffer, buf + len, count - len)) - return -EFAULT; - - log->w_off = logger_offset(log->w_off + count); - - return count; -} - -/* - * logger_aio_write - our write method, implementing support for write(), - * writev(), and aio_write(). Writes are our fast path, and we try to optimize - * them above all else. - */ -ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, - unsigned long nr_segs, loff_t ppos) -{ - struct logger_log *log = file_get_log(iocb->ki_filp); - size_t orig = log->w_off; - struct logger_entry header; - struct timespec now; - ssize_t ret = 0; - - now = current_kernel_time(); - - header.pid = current->tgid; - header.tid = current->pid; - header.sec = now.tv_sec; - header.nsec = now.tv_nsec; - header.euid = current_euid(); - header.len = min_t(size_t, iocb->ki_left, LOGGER_ENTRY_MAX_PAYLOAD); - header.hdr_size = sizeof(struct logger_entry); - - /* null writes succeed, return zero */ - if (unlikely(!header.len)) - return 0; - - mutex_lock(&log->mutex); - - /* - * Fix up any readers, pulling them forward to the first readable - * entry after (what will be) the new write offset. We do this now - * because if we partially fail, we can end up with clobbered log - * entries that encroach on readable buffer. - */ - fix_up_readers(log, sizeof(struct logger_entry) + header.len); - - do_write_log(log, &header, sizeof(struct logger_entry)); - - while (nr_segs-- > 0) { - size_t len; - ssize_t nr; - - /* figure out how much of this vector we can keep */ - len = min_t(size_t, iov->iov_len, header.len - ret); - - /* write out this segment's payload */ - nr = do_write_log_from_user(log, iov->iov_base, len); - if (unlikely(nr < 0)) { - log->w_off = orig; - mutex_unlock(&log->mutex); - return nr; - } - - iov++; - ret += nr; - } - - mutex_unlock(&log->mutex); - - /* wake up any blocked readers */ - wake_up_interruptible(&log->wq); - - return ret; -} - -static struct logger_log *get_log_from_minor(int); - -/* - * logger_open - the log's open() file operation - * - * Note how near a no-op this is in the write-only case. Keep it that way! - */ -static int logger_open(struct inode *inode, struct file *file) -{ - struct logger_log *log; - int ret; - - ret = nonseekable_open(inode, file); - if (ret) - return ret; - - log = get_log_from_minor(MINOR(inode->i_rdev)); - if (!log) - return -ENODEV; - - if (file->f_mode & FMODE_READ) { - struct logger_reader *reader; - - reader = kmalloc(sizeof(struct logger_reader), GFP_KERNEL); - if (!reader) - return -ENOMEM; - - reader->log = log; - reader->r_ver = 1; - reader->r_all = in_egroup_p(inode->i_gid) || - capable(CAP_SYSLOG); - - INIT_LIST_HEAD(&reader->list); - - mutex_lock(&log->mutex); - reader->r_off = log->head; - list_add_tail(&reader->list, &log->readers); - mutex_unlock(&log->mutex); - - file->private_data = reader; - } else - file->private_data = log; - - return 0; -} - -/* - * logger_release - the log's release file operation - * - * Note this is a total no-op in the write-only case. Keep it that way! - */ -static int logger_release(struct inode *ignored, struct file *file) -{ - if (file->f_mode & FMODE_READ) { - struct logger_reader *reader = file->private_data; - struct logger_log *log = reader->log; - - mutex_lock(&log->mutex); - list_del(&reader->list); - mutex_unlock(&log->mutex); - - kfree(reader); - } - - return 0; -} - -/* - * logger_poll - the log's poll file operation, for poll/select/epoll - * - * Note we always return POLLOUT, because you can always write() to the log. - * Note also that, strictly speaking, a return value of POLLIN does not - * guarantee that the log is readable without blocking, as there is a small - * chance that the writer can lap the reader in the interim between poll() - * returning and the read() request. - */ -static unsigned int logger_poll(struct file *file, poll_table *wait) -{ - struct logger_reader *reader; - struct logger_log *log; - unsigned int ret = POLLOUT | POLLWRNORM; - - if (!(file->f_mode & FMODE_READ)) - return ret; - - reader = file->private_data; - log = reader->log; - - poll_wait(file, &log->wq, wait); - - mutex_lock(&log->mutex); - if (!reader->r_all) - reader->r_off = get_next_entry_by_uid(log, - reader->r_off, current_euid()); - - if (log->w_off != reader->r_off) - ret |= POLLIN | POLLRDNORM; - mutex_unlock(&log->mutex); - - return ret; -} - -static long logger_set_version(struct logger_reader *reader, void __user *arg) -{ - int version; - if (copy_from_user(&version, arg, sizeof(int))) - return -EFAULT; - - if ((version < 1) || (version > 2)) - return -EINVAL; - - reader->r_ver = version; - return 0; -} - -static long logger_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct logger_log *log = file_get_log(file); - struct logger_reader *reader; - long ret = -EINVAL; - void __user *argp = (void __user *) arg; - - mutex_lock(&log->mutex); - - switch (cmd) { - case LOGGER_GET_LOG_BUF_SIZE: - ret = log->size; - break; - case LOGGER_GET_LOG_LEN: - if (!(file->f_mode & FMODE_READ)) { - ret = -EBADF; - break; - } - reader = file->private_data; - if (log->w_off >= reader->r_off) - ret = log->w_off - reader->r_off; - else - ret = (log->size - reader->r_off) + log->w_off; - break; - case LOGGER_GET_NEXT_ENTRY_LEN: - if (!(file->f_mode & FMODE_READ)) { - ret = -EBADF; - break; - } - reader = file->private_data; - - if (!reader->r_all) - reader->r_off = get_next_entry_by_uid(log, - reader->r_off, current_euid()); - - if (log->w_off != reader->r_off) - ret = get_user_hdr_len(reader->r_ver) + - get_entry_msg_len(log, reader->r_off); - else - ret = 0; - break; - case LOGGER_FLUSH_LOG: - if (!(file->f_mode & FMODE_WRITE)) { - ret = -EBADF; - break; - } - list_for_each_entry(reader, &log->readers, list) - reader->r_off = log->w_off; - log->head = log->w_off; - ret = 0; - break; - case LOGGER_GET_VERSION: - if (!(file->f_mode & FMODE_READ)) { - ret = -EBADF; - break; - } - reader = file->private_data; - ret = reader->r_ver; - break; - case LOGGER_SET_VERSION: - if (!(file->f_mode & FMODE_READ)) { - ret = -EBADF; - break; - } - reader = file->private_data; - ret = logger_set_version(reader, argp); - break; - } - - mutex_unlock(&log->mutex); - - return ret; -} - -static const struct file_operations logger_fops = { - .owner = THIS_MODULE, - .read = logger_read, - .aio_write = logger_aio_write, - .poll = logger_poll, - .unlocked_ioctl = logger_ioctl, - .compat_ioctl = logger_ioctl, - .open = logger_open, - .release = logger_release, -}; - -/* - * Defines a log structure with name 'NAME' and a size of 'SIZE' bytes, which - * must be a power of two, and greater than - * (LOGGER_ENTRY_MAX_PAYLOAD + sizeof(struct logger_entry)). - */ -#define DEFINE_LOGGER_DEVICE(VAR, NAME, SIZE) \ -static unsigned char _buf_ ## VAR[SIZE]; \ -static struct logger_log VAR = { \ - .buffer = _buf_ ## VAR, \ - .misc = { \ - .minor = MISC_DYNAMIC_MINOR, \ - .name = NAME, \ - .fops = &logger_fops, \ - .parent = NULL, \ - }, \ - .wq = __WAIT_QUEUE_HEAD_INITIALIZER(VAR .wq), \ - .readers = LIST_HEAD_INIT(VAR .readers), \ - .mutex = __MUTEX_INITIALIZER(VAR .mutex), \ - .w_off = 0, \ - .head = 0, \ - .size = SIZE, \ -}; - -DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, 256*1024) -DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, 256*1024) -DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, 256*1024) -DEFINE_LOGGER_DEVICE(log_system, LOGGER_LOG_SYSTEM, 256*1024) - -static struct logger_log *get_log_from_minor(int minor) -{ - if (log_main.misc.minor == minor) - return &log_main; - if (log_events.misc.minor == minor) - return &log_events; - if (log_radio.misc.minor == minor) - return &log_radio; - if (log_system.misc.minor == minor) - return &log_system; - return NULL; -} - -static int __init init_log(struct logger_log *log) -{ - int ret; - - ret = misc_register(&log->misc); - if (unlikely(ret)) { - printk(KERN_ERR "logger: failed to register misc " - "device for log '%s'!\n", log->misc.name); - return ret; - } - - printk(KERN_INFO "logger: created %luK log '%s'\n", - (unsigned long) log->size >> 10, log->misc.name); - - return 0; -} - -static int __init logger_init(void) -{ - int ret; - - ret = init_log(&log_main); - if (unlikely(ret)) - goto out; - - ret = init_log(&log_events); - if (unlikely(ret)) - goto out; - - ret = init_log(&log_radio); - if (unlikely(ret)) - goto out; - - ret = init_log(&log_system); - if (unlikely(ret)) - goto out; - -out: - return ret; -} -device_initcall(logger_init); diff --git a/drivers/staging/android/logger.h b/drivers/staging/android/logger.h deleted file mode 100644 index 3f612a3b101c..000000000000 --- a/drivers/staging/android/logger.h +++ /dev/null @@ -1,70 +0,0 @@ -/* include/linux/logger.h - * - * Copyright (C) 2007-2008 Google, Inc. - * Author: Robert Love - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _LINUX_LOGGER_H -#define _LINUX_LOGGER_H - -#include -#include - -/* - * The userspace structure for version 1 of the logger_entry ABI. - * This structure is returned to userspace unless the caller requests - * an upgrade to a newer ABI version. - */ -struct user_logger_entry_compat { - __u16 len; /* length of the payload */ - __u16 __pad; /* no matter what, we get 2 bytes of padding */ - __s32 pid; /* generating process's pid */ - __s32 tid; /* generating process's tid */ - __s32 sec; /* seconds since Epoch */ - __s32 nsec; /* nanoseconds */ - char msg[0]; /* the entry's payload */ -}; - -/* - * The structure for version 2 of the logger_entry ABI. - * This structure is returned to userspace if ioctl(LOGGER_SET_VERSION) - * is called with version >= 2 - */ -struct logger_entry { - __u16 len; /* length of the payload */ - __u16 hdr_size; /* sizeof(struct logger_entry_v2) */ - __s32 pid; /* generating process's pid */ - __s32 tid; /* generating process's tid */ - __s32 sec; /* seconds since Epoch */ - __s32 nsec; /* nanoseconds */ - uid_t euid; /* effective UID of logger */ - char msg[0]; /* the entry's payload */ -}; - -#define LOGGER_LOG_RADIO "log_radio" /* radio-related messages */ -#define LOGGER_LOG_EVENTS "log_events" /* system/hardware events */ -#define LOGGER_LOG_SYSTEM "log_system" /* system/framework messages */ -#define LOGGER_LOG_MAIN "log_main" /* everything else */ - -#define LOGGER_ENTRY_MAX_PAYLOAD 4076 - -#define __LOGGERIO 0xAE - -#define LOGGER_GET_LOG_BUF_SIZE _IO(__LOGGERIO, 1) /* size of log */ -#define LOGGER_GET_LOG_LEN _IO(__LOGGERIO, 2) /* used log len */ -#define LOGGER_GET_NEXT_ENTRY_LEN _IO(__LOGGERIO, 3) /* next entry len */ -#define LOGGER_FLUSH_LOG _IO(__LOGGERIO, 4) /* flush log */ -#define LOGGER_GET_VERSION _IO(__LOGGERIO, 5) /* abi version */ -#define LOGGER_SET_VERSION _IO(__LOGGERIO, 6) /* abi version */ - -#endif /* _LINUX_LOGGER_H */ diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c deleted file mode 100644 index 86d51959b29f..000000000000 --- a/drivers/staging/android/lowmemorykiller.c +++ /dev/null @@ -1,213 +0,0 @@ -/* drivers/misc/lowmemorykiller.c - * - * The lowmemorykiller driver lets user-space specify a set of memory thresholds - * where processes with a range of oom_adj values will get killed. Specify the - * minimum oom_adj values in /sys/module/lowmemorykiller/parameters/adj and the - * number of free pages in /sys/module/lowmemorykiller/parameters/minfree. Both - * files take a comma separated list of numbers in ascending order. - * - * For example, write "0,8" to /sys/module/lowmemorykiller/parameters/adj and - * "1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill processes - * with a oom_adj value of 8 or higher when the free memory drops below 4096 pages - * and kill processes with a oom_adj value of 0 or higher when the free memory - * drops below 1024 pages. - * - * The driver considers memory used for caches to be free, but if a large - * percentage of the cached memory is locked this can be very inaccurate - * and processes may not get killed until the normal oom killer is triggered. - * - * Copyright (C) 2007-2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include - -static uint32_t lowmem_debug_level = 2; -static int lowmem_adj[6] = { - 0, - 1, - 6, - 12, -}; -static int lowmem_adj_size = 4; -static size_t lowmem_minfree[6] = { - 3 * 512, /* 6MB */ - 2 * 1024, /* 8MB */ - 4 * 1024, /* 16MB */ - 16 * 1024, /* 64MB */ -}; -static int lowmem_minfree_size = 4; - -static struct task_struct *lowmem_deathpending; -static unsigned long lowmem_deathpending_timeout; - -#define lowmem_print(level, x...) \ - do { \ - if (lowmem_debug_level >= (level)) \ - printk(x); \ - } while (0) - -static int -task_notify_func(struct notifier_block *self, unsigned long val, void *data); - -static struct notifier_block task_nb = { - .notifier_call = task_notify_func, -}; - -static int -task_notify_func(struct notifier_block *self, unsigned long val, void *data) -{ - struct task_struct *task = data; - - if (task == lowmem_deathpending) - lowmem_deathpending = NULL; - - return NOTIFY_OK; -} - -static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) -{ - struct task_struct *p; - struct task_struct *selected = NULL; - int rem = 0; - int tasksize; - int i; - int min_adj = OOM_ADJUST_MAX + 1; - int selected_tasksize = 0; - int selected_oom_adj; - int array_size = ARRAY_SIZE(lowmem_adj); - int other_free = global_page_state(NR_FREE_PAGES); - int other_file = global_page_state(NR_FILE_PAGES) - - global_page_state(NR_SHMEM); - - /* - * If we already have a death outstanding, then - * bail out right away; indicating to vmscan - * that we have nothing further to offer on - * this pass. - * - */ - if (lowmem_deathpending && - time_before_eq(jiffies, lowmem_deathpending_timeout)) - return 0; - - if (lowmem_adj_size < array_size) - array_size = lowmem_adj_size; - if (lowmem_minfree_size < array_size) - array_size = lowmem_minfree_size; - for (i = 0; i < array_size; i++) { - if (other_free < lowmem_minfree[i] && - other_file < lowmem_minfree[i]) { - min_adj = lowmem_adj[i]; - break; - } - } - if (sc->nr_to_scan > 0) - lowmem_print(3, "lowmem_shrink %lu, %x, ofree %d %d, ma %d\n", - sc->nr_to_scan, sc->gfp_mask, other_free, other_file, - min_adj); - rem = global_page_state(NR_ACTIVE_ANON) + - global_page_state(NR_ACTIVE_FILE) + - global_page_state(NR_INACTIVE_ANON) + - global_page_state(NR_INACTIVE_FILE); - if (sc->nr_to_scan <= 0 || min_adj == OOM_ADJUST_MAX + 1) { - lowmem_print(5, "lowmem_shrink %lu, %x, return %d\n", - sc->nr_to_scan, sc->gfp_mask, rem); - return rem; - } - selected_oom_adj = min_adj; - - read_lock(&tasklist_lock); - for_each_process(p) { - struct mm_struct *mm; - struct signal_struct *sig; - int oom_adj; - - task_lock(p); - mm = p->mm; - sig = p->signal; - if (!mm || !sig) { - task_unlock(p); - continue; - } - oom_adj = sig->oom_adj; - if (oom_adj < min_adj) { - task_unlock(p); - continue; - } - tasksize = get_mm_rss(mm); - task_unlock(p); - if (tasksize <= 0) - continue; - if (selected) { - if (oom_adj < selected_oom_adj) - continue; - if (oom_adj == selected_oom_adj && - tasksize <= selected_tasksize) - continue; - } - selected = p; - selected_tasksize = tasksize; - selected_oom_adj = oom_adj; - lowmem_print(2, "select %d (%s), adj %d, size %d, to kill\n", - p->pid, p->comm, oom_adj, tasksize); - } - if (selected) { - lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n", - selected->pid, selected->comm, - selected_oom_adj, selected_tasksize); - lowmem_deathpending = selected; - lowmem_deathpending_timeout = jiffies + HZ; - force_sig(SIGKILL, selected); - rem -= selected_tasksize; - } - lowmem_print(4, "lowmem_shrink %lu, %x, return %d\n", - sc->nr_to_scan, sc->gfp_mask, rem); - read_unlock(&tasklist_lock); - return rem; -} - -static struct shrinker lowmem_shrinker = { - .shrink = lowmem_shrink, - .seeks = DEFAULT_SEEKS * 16 -}; - -static int __init lowmem_init(void) -{ - task_free_register(&task_nb); - register_shrinker(&lowmem_shrinker); - return 0; -} - -static void __exit lowmem_exit(void) -{ - unregister_shrinker(&lowmem_shrinker); - task_free_unregister(&task_nb); -} - -module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR); -module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size, - S_IRUGO | S_IWUSR); -module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size, - S_IRUGO | S_IWUSR); -module_param_named(debug_level, lowmem_debug_level, uint, S_IRUGO | S_IWUSR); - -module_init(lowmem_init); -module_exit(lowmem_exit); - -MODULE_LICENSE("GPL"); - diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c deleted file mode 100644 index b278d62e4b89..000000000000 --- a/drivers/staging/android/ram_console.c +++ /dev/null @@ -1,443 +0,0 @@ -/* drivers/android/ram_console.c - * - * Copyright (C) 2007-2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -#include -#endif - -struct ram_console_buffer { - uint32_t sig; - uint32_t start; - uint32_t size; - uint8_t data[0]; -}; - -#define RAM_CONSOLE_SIG (0x43474244) /* DBGC */ - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT -static char __initdata - ram_console_old_log_init_buffer[CONFIG_ANDROID_RAM_CONSOLE_EARLY_SIZE]; -#endif -static char *ram_console_old_log; -static size_t ram_console_old_log_size; - -static struct ram_console_buffer *ram_console_buffer; -static size_t ram_console_buffer_size; -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -static char *ram_console_par_buffer; -static struct rs_control *ram_console_rs_decoder; -static int ram_console_corrected_bytes; -static int ram_console_bad_blocks; -#define ECC_BLOCK_SIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE -#define ECC_SIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE -#define ECC_SYMSIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE -#define ECC_POLY CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL -#endif - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -static void ram_console_encode_rs8(uint8_t *data, size_t len, uint8_t *ecc) -{ - int i; - uint16_t par[ECC_SIZE]; - /* Initialize the parity buffer */ - memset(par, 0, sizeof(par)); - encode_rs8(ram_console_rs_decoder, data, len, par, 0); - for (i = 0; i < ECC_SIZE; i++) - ecc[i] = par[i]; -} - -static int ram_console_decode_rs8(void *data, size_t len, uint8_t *ecc) -{ - int i; - uint16_t par[ECC_SIZE]; - for (i = 0; i < ECC_SIZE; i++) - par[i] = ecc[i]; - return decode_rs8(ram_console_rs_decoder, data, par, len, - NULL, 0, NULL, 0, NULL); -} -#endif - -static void ram_console_update(const char *s, unsigned int count) -{ - struct ram_console_buffer *buffer = ram_console_buffer; -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - uint8_t *buffer_end = buffer->data + ram_console_buffer_size; - uint8_t *block; - uint8_t *par; - int size = ECC_BLOCK_SIZE; -#endif - memcpy(buffer->data + buffer->start, s, count); -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - block = buffer->data + (buffer->start & ~(ECC_BLOCK_SIZE - 1)); - par = ram_console_par_buffer + - (buffer->start / ECC_BLOCK_SIZE) * ECC_SIZE; - do { - if (block + ECC_BLOCK_SIZE > buffer_end) - size = buffer_end - block; - ram_console_encode_rs8(block, size, par); - block += ECC_BLOCK_SIZE; - par += ECC_SIZE; - } while (block < buffer->data + buffer->start + count); -#endif -} - -static void ram_console_update_header(void) -{ -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - struct ram_console_buffer *buffer = ram_console_buffer; - uint8_t *par; - par = ram_console_par_buffer + - DIV_ROUND_UP(ram_console_buffer_size, ECC_BLOCK_SIZE) * ECC_SIZE; - ram_console_encode_rs8((uint8_t *)buffer, sizeof(*buffer), par); -#endif -} - -static void -ram_console_write(struct console *console, const char *s, unsigned int count) -{ - int rem; - struct ram_console_buffer *buffer = ram_console_buffer; - - if (count > ram_console_buffer_size) { - s += count - ram_console_buffer_size; - count = ram_console_buffer_size; - } - rem = ram_console_buffer_size - buffer->start; - if (rem < count) { - ram_console_update(s, rem); - s += rem; - count -= rem; - buffer->start = 0; - buffer->size = ram_console_buffer_size; - } - ram_console_update(s, count); - - buffer->start += count; - if (buffer->size < ram_console_buffer_size) - buffer->size += count; - ram_console_update_header(); -} - -static struct console ram_console = { - .name = "ram", - .write = ram_console_write, - .flags = CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME, - .index = -1, -}; - -void ram_console_enable_console(int enabled) -{ - if (enabled) - ram_console.flags |= CON_ENABLED; - else - ram_console.flags &= ~CON_ENABLED; -} - -static void __init -ram_console_save_old(struct ram_console_buffer *buffer, const char *bootinfo, - char *dest) -{ - size_t old_log_size = buffer->size; - size_t bootinfo_size = 0; - size_t total_size = old_log_size; - char *ptr; - const char *bootinfo_label = "Boot info:\n"; - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - uint8_t *block; - uint8_t *par; - char strbuf[80]; - int strbuf_len = 0; - - block = buffer->data; - par = ram_console_par_buffer; - while (block < buffer->data + buffer->size) { - int numerr; - int size = ECC_BLOCK_SIZE; - if (block + size > buffer->data + ram_console_buffer_size) - size = buffer->data + ram_console_buffer_size - block; - numerr = ram_console_decode_rs8(block, size, par); - if (numerr > 0) { -#if 0 - printk(KERN_INFO "ram_console: error in block %p, %d\n", - block, numerr); -#endif - ram_console_corrected_bytes += numerr; - } else if (numerr < 0) { -#if 0 - printk(KERN_INFO "ram_console: uncorrectable error in " - "block %p\n", block); -#endif - ram_console_bad_blocks++; - } - block += ECC_BLOCK_SIZE; - par += ECC_SIZE; - } - if (ram_console_corrected_bytes || ram_console_bad_blocks) - strbuf_len = snprintf(strbuf, sizeof(strbuf), - "\n%d Corrected bytes, %d unrecoverable blocks\n", - ram_console_corrected_bytes, ram_console_bad_blocks); - else - strbuf_len = snprintf(strbuf, sizeof(strbuf), - "\nNo errors detected\n"); - if (strbuf_len >= sizeof(strbuf)) - strbuf_len = sizeof(strbuf) - 1; - total_size += strbuf_len; -#endif - - if (bootinfo) - bootinfo_size = strlen(bootinfo) + strlen(bootinfo_label); - total_size += bootinfo_size; - - if (dest == NULL) { - dest = kmalloc(total_size, GFP_KERNEL); - if (dest == NULL) { - printk(KERN_ERR - "ram_console: failed to allocate buffer\n"); - return; - } - } - - ram_console_old_log = dest; - ram_console_old_log_size = total_size; - memcpy(ram_console_old_log, - &buffer->data[buffer->start], buffer->size - buffer->start); - memcpy(ram_console_old_log + buffer->size - buffer->start, - &buffer->data[0], buffer->start); - ptr = ram_console_old_log + old_log_size; -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - memcpy(ptr, strbuf, strbuf_len); - ptr += strbuf_len; -#endif - if (bootinfo) { - memcpy(ptr, bootinfo_label, strlen(bootinfo_label)); - ptr += strlen(bootinfo_label); - memcpy(ptr, bootinfo, bootinfo_size); - ptr += bootinfo_size; - } -} - -static int __init ram_console_init(struct ram_console_buffer *buffer, - size_t buffer_size, const char *bootinfo, - char *old_buf) -{ -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - int numerr; - uint8_t *par; -#endif - ram_console_buffer = buffer; - ram_console_buffer_size = - buffer_size - sizeof(struct ram_console_buffer); - - if (ram_console_buffer_size > buffer_size) { - pr_err("ram_console: buffer %p, invalid size %zu, " - "datasize %zu\n", buffer, buffer_size, - ram_console_buffer_size); - return 0; - } - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - ram_console_buffer_size -= (DIV_ROUND_UP(ram_console_buffer_size, - ECC_BLOCK_SIZE) + 1) * ECC_SIZE; - - if (ram_console_buffer_size > buffer_size) { - pr_err("ram_console: buffer %p, invalid size %zu, " - "non-ecc datasize %zu\n", - buffer, buffer_size, ram_console_buffer_size); - return 0; - } - - ram_console_par_buffer = buffer->data + ram_console_buffer_size; - - - /* first consecutive root is 0 - * primitive element to generate roots = 1 - */ - ram_console_rs_decoder = init_rs(ECC_SYMSIZE, ECC_POLY, 0, 1, ECC_SIZE); - if (ram_console_rs_decoder == NULL) { - printk(KERN_INFO "ram_console: init_rs failed\n"); - return 0; - } - - ram_console_corrected_bytes = 0; - ram_console_bad_blocks = 0; - - par = ram_console_par_buffer + - DIV_ROUND_UP(ram_console_buffer_size, ECC_BLOCK_SIZE) * ECC_SIZE; - - numerr = ram_console_decode_rs8(buffer, sizeof(*buffer), par); - if (numerr > 0) { - printk(KERN_INFO "ram_console: error in header, %d\n", numerr); - ram_console_corrected_bytes += numerr; - } else if (numerr < 0) { - printk(KERN_INFO - "ram_console: uncorrectable error in header\n"); - ram_console_bad_blocks++; - } -#endif - - if (buffer->sig == RAM_CONSOLE_SIG) { - if (buffer->size > ram_console_buffer_size - || buffer->start > buffer->size) - printk(KERN_INFO "ram_console: found existing invalid " - "buffer, size %d, start %d\n", - buffer->size, buffer->start); - else { - printk(KERN_INFO "ram_console: found existing buffer, " - "size %d, start %d\n", - buffer->size, buffer->start); - ram_console_save_old(buffer, bootinfo, old_buf); - } - } else { - printk(KERN_INFO "ram_console: no valid data in buffer " - "(sig = 0x%08x)\n", buffer->sig); - } - - buffer->sig = RAM_CONSOLE_SIG; - buffer->start = 0; - buffer->size = 0; - - register_console(&ram_console); -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE - console_verbose(); -#endif - return 0; -} - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT -static int __init ram_console_early_init(void) -{ - return ram_console_init((struct ram_console_buffer *) - CONFIG_ANDROID_RAM_CONSOLE_EARLY_ADDR, - CONFIG_ANDROID_RAM_CONSOLE_EARLY_SIZE, - NULL, - ram_console_old_log_init_buffer); -} -#else -static int ram_console_driver_probe(struct platform_device *pdev) -{ - struct resource *res = pdev->resource; - size_t start; - size_t buffer_size; - void *buffer; - const char *bootinfo = NULL; - struct ram_console_platform_data *pdata = pdev->dev.platform_data; - - if (res == NULL || pdev->num_resources != 1 || - !(res->flags & IORESOURCE_MEM)) { - printk(KERN_ERR "ram_console: invalid resource, %p %d flags " - "%lx\n", res, pdev->num_resources, res ? res->flags : 0); - return -ENXIO; - } - buffer_size = res->end - res->start + 1; - start = res->start; - printk(KERN_INFO "ram_console: got buffer at %zx, size %zx\n", - start, buffer_size); - buffer = ioremap(res->start, buffer_size); - if (buffer == NULL) { - printk(KERN_ERR "ram_console: failed to map memory\n"); - return -ENOMEM; - } - - if (pdata) - bootinfo = pdata->bootinfo; - - return ram_console_init(buffer, buffer_size, bootinfo, NULL/* allocate */); -} - -static struct platform_driver ram_console_driver = { - .probe = ram_console_driver_probe, - .driver = { - .name = "ram_console", - }, -}; - -static int __init ram_console_module_init(void) -{ - int err; - err = platform_driver_register(&ram_console_driver); - return err; -} -#endif - -static ssize_t ram_console_read_old(struct file *file, char __user *buf, - size_t len, loff_t *offset) -{ - loff_t pos = *offset; - ssize_t count; - - if (pos >= ram_console_old_log_size) - return 0; - - count = min(len, (size_t)(ram_console_old_log_size - pos)); - if (copy_to_user(buf, ram_console_old_log + pos, count)) - return -EFAULT; - - *offset += count; - return count; -} - -static const struct file_operations ram_console_file_ops = { - .owner = THIS_MODULE, - .read = ram_console_read_old, -}; - -static int __init ram_console_late_init(void) -{ - struct proc_dir_entry *entry; - - if (ram_console_old_log == NULL) - return 0; -#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT - ram_console_old_log = kmalloc(ram_console_old_log_size, GFP_KERNEL); - if (ram_console_old_log == NULL) { - printk(KERN_ERR - "ram_console: failed to allocate buffer for old log\n"); - ram_console_old_log_size = 0; - return 0; - } - memcpy(ram_console_old_log, - ram_console_old_log_init_buffer, ram_console_old_log_size); -#endif - entry = create_proc_entry("last_kmsg", S_IFREG | S_IRUGO, NULL); - if (!entry) { - printk(KERN_ERR "ram_console: failed to create proc entry\n"); - kfree(ram_console_old_log); - ram_console_old_log = NULL; - return 0; - } - - entry->proc_fops = &ram_console_file_ops; - entry->size = ram_console_old_log_size; - return 0; -} - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT -console_initcall(ram_console_early_init); -#else -postcore_initcall(ram_console_module_init); -#endif -late_initcall(ram_console_late_init); - diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c deleted file mode 100644 index a64481c3e86d..000000000000 --- a/drivers/staging/android/timed_gpio.c +++ /dev/null @@ -1,176 +0,0 @@ -/* drivers/misc/timed_gpio.c - * - * Copyright (C) 2008 Google, Inc. - * Author: Mike Lockwood - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include - -#include "timed_output.h" -#include "timed_gpio.h" - - -struct timed_gpio_data { - struct timed_output_dev dev; - struct hrtimer timer; - spinlock_t lock; - unsigned gpio; - int max_timeout; - u8 active_low; -}; - -static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer) -{ - struct timed_gpio_data *data = - container_of(timer, struct timed_gpio_data, timer); - - gpio_direction_output(data->gpio, data->active_low ? 1 : 0); - return HRTIMER_NORESTART; -} - -static int gpio_get_time(struct timed_output_dev *dev) -{ - struct timed_gpio_data *data = - container_of(dev, struct timed_gpio_data, dev); - - if (hrtimer_active(&data->timer)) { - ktime_t r = hrtimer_get_remaining(&data->timer); - struct timeval t = ktime_to_timeval(r); - return t.tv_sec * 1000 + t.tv_usec / 1000; - } else - return 0; -} - -static void gpio_enable(struct timed_output_dev *dev, int value) -{ - struct timed_gpio_data *data = - container_of(dev, struct timed_gpio_data, dev); - unsigned long flags; - - spin_lock_irqsave(&data->lock, flags); - - /* cancel previous timer and set GPIO according to value */ - hrtimer_cancel(&data->timer); - gpio_direction_output(data->gpio, data->active_low ? !value : !!value); - - if (value > 0) { - if (value > data->max_timeout) - value = data->max_timeout; - - hrtimer_start(&data->timer, - ktime_set(value / 1000, (value % 1000) * 1000000), - HRTIMER_MODE_REL); - } - - spin_unlock_irqrestore(&data->lock, flags); -} - -static int timed_gpio_probe(struct platform_device *pdev) -{ - struct timed_gpio_platform_data *pdata = pdev->dev.platform_data; - struct timed_gpio *cur_gpio; - struct timed_gpio_data *gpio_data, *gpio_dat; - int i, j, ret = 0; - - if (!pdata) - return -EBUSY; - - gpio_data = kzalloc(sizeof(struct timed_gpio_data) * pdata->num_gpios, - GFP_KERNEL); - if (!gpio_data) - return -ENOMEM; - - for (i = 0; i < pdata->num_gpios; i++) { - cur_gpio = &pdata->gpios[i]; - gpio_dat = &gpio_data[i]; - - hrtimer_init(&gpio_dat->timer, CLOCK_MONOTONIC, - HRTIMER_MODE_REL); - gpio_dat->timer.function = gpio_timer_func; - spin_lock_init(&gpio_dat->lock); - - gpio_dat->dev.name = cur_gpio->name; - gpio_dat->dev.get_time = gpio_get_time; - gpio_dat->dev.enable = gpio_enable; - ret = gpio_request(cur_gpio->gpio, cur_gpio->name); - if (ret >= 0) { - ret = timed_output_dev_register(&gpio_dat->dev); - if (ret < 0) - gpio_free(cur_gpio->gpio); - } - if (ret < 0) { - for (j = 0; j < i; j++) { - timed_output_dev_unregister(&gpio_data[i].dev); - gpio_free(gpio_data[i].gpio); - } - kfree(gpio_data); - return ret; - } - - gpio_dat->gpio = cur_gpio->gpio; - gpio_dat->max_timeout = cur_gpio->max_timeout; - gpio_dat->active_low = cur_gpio->active_low; - gpio_direction_output(gpio_dat->gpio, gpio_dat->active_low); - } - - platform_set_drvdata(pdev, gpio_data); - - return 0; -} - -static int timed_gpio_remove(struct platform_device *pdev) -{ - struct timed_gpio_platform_data *pdata = pdev->dev.platform_data; - struct timed_gpio_data *gpio_data = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < pdata->num_gpios; i++) { - timed_output_dev_unregister(&gpio_data[i].dev); - gpio_free(gpio_data[i].gpio); - } - - kfree(gpio_data); - - return 0; -} - -static struct platform_driver timed_gpio_driver = { - .probe = timed_gpio_probe, - .remove = timed_gpio_remove, - .driver = { - .name = TIMED_GPIO_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init timed_gpio_init(void) -{ - return platform_driver_register(&timed_gpio_driver); -} - -static void __exit timed_gpio_exit(void) -{ - platform_driver_unregister(&timed_gpio_driver); -} - -module_init(timed_gpio_init); -module_exit(timed_gpio_exit); - -MODULE_AUTHOR("Mike Lockwood "); -MODULE_DESCRIPTION("timed gpio driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/android/timed_gpio.h b/drivers/staging/android/timed_gpio.h deleted file mode 100644 index a0e15f8be3f7..000000000000 --- a/drivers/staging/android/timed_gpio.h +++ /dev/null @@ -1,33 +0,0 @@ -/* include/linux/timed_gpio.h - * - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * -*/ - -#ifndef _LINUX_TIMED_GPIO_H -#define _LINUX_TIMED_GPIO_H - -#define TIMED_GPIO_NAME "timed-gpio" - -struct timed_gpio { - const char *name; - unsigned gpio; - int max_timeout; - u8 active_low; -}; - -struct timed_gpio_platform_data { - int num_gpios; - struct timed_gpio *gpios; -}; - -#endif diff --git a/drivers/staging/android/timed_output.c b/drivers/staging/android/timed_output.c deleted file mode 100644 index f373422308e0..000000000000 --- a/drivers/staging/android/timed_output.c +++ /dev/null @@ -1,123 +0,0 @@ -/* drivers/misc/timed_output.c - * - * Copyright (C) 2009 Google, Inc. - * Author: Mike Lockwood - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include - -#include "timed_output.h" - -static struct class *timed_output_class; -static atomic_t device_count; - -static ssize_t enable_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct timed_output_dev *tdev = dev_get_drvdata(dev); - int remaining = tdev->get_time(tdev); - - return sprintf(buf, "%d\n", remaining); -} - -static ssize_t enable_store( - struct device *dev, struct device_attribute *attr, - const char *buf, size_t size) -{ - struct timed_output_dev *tdev = dev_get_drvdata(dev); - int value; - - if (sscanf(buf, "%d", &value) != 1) - return -EINVAL; - - tdev->enable(tdev, value); - - return size; -} - -static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store); - -static int create_timed_output_class(void) -{ - if (!timed_output_class) { - timed_output_class = class_create(THIS_MODULE, "timed_output"); - if (IS_ERR(timed_output_class)) - return PTR_ERR(timed_output_class); - atomic_set(&device_count, 0); - } - - return 0; -} - -int timed_output_dev_register(struct timed_output_dev *tdev) -{ - int ret; - - if (!tdev || !tdev->name || !tdev->enable || !tdev->get_time) - return -EINVAL; - - ret = create_timed_output_class(); - if (ret < 0) - return ret; - - tdev->index = atomic_inc_return(&device_count); - tdev->dev = device_create(timed_output_class, NULL, - MKDEV(0, tdev->index), NULL, tdev->name); - if (IS_ERR(tdev->dev)) - return PTR_ERR(tdev->dev); - - ret = device_create_file(tdev->dev, &dev_attr_enable); - if (ret < 0) - goto err_create_file; - - dev_set_drvdata(tdev->dev, tdev); - tdev->state = 0; - return 0; - -err_create_file: - device_destroy(timed_output_class, MKDEV(0, tdev->index)); - printk(KERN_ERR "timed_output: Failed to register driver %s\n", - tdev->name); - - return ret; -} -EXPORT_SYMBOL_GPL(timed_output_dev_register); - -void timed_output_dev_unregister(struct timed_output_dev *tdev) -{ - device_remove_file(tdev->dev, &dev_attr_enable); - device_destroy(timed_output_class, MKDEV(0, tdev->index)); - dev_set_drvdata(tdev->dev, NULL); -} -EXPORT_SYMBOL_GPL(timed_output_dev_unregister); - -static int __init timed_output_init(void) -{ - return create_timed_output_class(); -} - -static void __exit timed_output_exit(void) -{ - class_destroy(timed_output_class); -} - -module_init(timed_output_init); -module_exit(timed_output_exit); - -MODULE_AUTHOR("Mike Lockwood "); -MODULE_DESCRIPTION("timed output class driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/android/timed_output.h b/drivers/staging/android/timed_output.h deleted file mode 100644 index ec907ab2ff54..000000000000 --- a/drivers/staging/android/timed_output.h +++ /dev/null @@ -1,37 +0,0 @@ -/* include/linux/timed_output.h - * - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * -*/ - -#ifndef _LINUX_TIMED_OUTPUT_H -#define _LINUX_TIMED_OUTPUT_H - -struct timed_output_dev { - const char *name; - - /* enable the output and set the timer */ - void (*enable)(struct timed_output_dev *sdev, int timeout); - - /* returns the current number of milliseconds remaining on the timer */ - int (*get_time)(struct timed_output_dev *sdev); - - /* private data */ - struct device *dev; - int index; - int state; -}; - -extern int timed_output_dev_register(struct timed_output_dev *dev); -extern void timed_output_dev_unregister(struct timed_output_dev *dev); - -#endif diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c index 63bafbb0980f..7bb7da7959a2 100644 --- a/drivers/staging/asus_oled/asus_oled.c +++ b/drivers/staging/asus_oled/asus_oled.c @@ -355,14 +355,7 @@ static void send_data(struct asus_oled_dev *odev) static int append_values(struct asus_oled_dev *odev, uint8_t val, size_t count) { - odev->last_val = val; - - if (val == 0) { - odev->buf_offs += count; - return 0; - } - - while (count-- > 0) { + while (count-- > 0 && val) { size_t x = odev->buf_offs % odev->width; size_t y = odev->buf_offs / odev->width; size_t i; @@ -413,6 +406,7 @@ static int append_values(struct asus_oled_dev *odev, uint8_t val, size_t count) ; } + odev->last_val = val; odev->buf_offs++; } @@ -811,9 +805,10 @@ error: static void __exit asus_oled_exit(void) { - usb_deregister(&oled_driver); class_remove_file(oled_class, &class_attr_version.attr); class_destroy(oled_class); + + usb_deregister(&oled_driver); } module_init(asus_oled_init); diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 62487a769000..48dd9e363596 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -954,13 +954,9 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, const char *filename; const struct firmware *fw_entry; u32 fw_entry_size; - u8 **buf; - size_t *buf_len; switch (file) { case AR6K_OTP_FILE: - buf = &ar->fw_otp; - buf_len = &ar->fw_otp_len; if (ar->arVersion.target_ver == AR6003_REV1_VERSION) { filename = AR6003_REV1_OTP_FILE; } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { @@ -974,8 +970,6 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, break; case AR6K_FIRMWARE_FILE: - buf = &ar->fw; - buf_len = &ar->fw_len; if (ar->arVersion.target_ver == AR6003_REV1_VERSION) { filename = AR6003_REV1_FIRMWARE_FILE; } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { @@ -1034,8 +1028,6 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, break; case AR6K_PATCH_FILE: - buf = &ar->fw_patch; - buf_len = &ar->fw_patch_len; if (ar->arVersion.target_ver == AR6003_REV1_VERSION) { filename = AR6003_REV1_PATCH_FILE; } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { @@ -1049,8 +1041,6 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, break; case AR6K_BOARD_DATA_FILE: - buf = &ar->fw_data; - buf_len = &ar->fw_data_len; if (ar->arVersion.target_ver == AR6003_REV1_VERSION) { filename = AR6003_REV1_BOARD_DATA_FILE; } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { @@ -1067,29 +1057,23 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown file type: %d\n", file)); return A_ERROR; } - - if (*buf == NULL) { - if ((A_REQUEST_FIRMWARE(&fw_entry, filename, ((struct device *)ar->osDevInfo.pOSDevice))) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to get %s\n", filename)); - return A_ENOENT; - } - - *buf = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL); - *buf_len = fw_entry->size; - A_RELEASE_FIRMWARE(fw_entry); + if ((A_REQUEST_FIRMWARE(&fw_entry, filename, ((struct device *)ar->osDevInfo.pOSDevice))) != 0) + { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to get %s\n", filename)); + return A_ENOENT; } #ifdef SOFTMAC_FILE_USED - if (file==AR6K_BOARD_DATA_FILE && *buf_len) { - ar6000_softmac_update(ar, *buf, *buf_len); + if (file==AR6K_BOARD_DATA_FILE && fw_entry->data) { + ar6000_softmac_update(ar, (u8 *)fw_entry->data, fw_entry->size); } #endif - fw_entry_size = *buf_len; + fw_entry_size = fw_entry->size; /* Load extended board data for AR6003 */ - if ((file==AR6K_BOARD_DATA_FILE) && *buf) { + if ((file==AR6K_BOARD_DATA_FILE) && (fw_entry->data)) { u32 board_ext_address; u32 board_ext_data_size; u32 board_data_size; @@ -1105,13 +1089,14 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board extended Data download address: 0x%x\n", board_ext_address)); /* check whether the target has allocated memory for extended board data and file contains extended board data */ - if ((board_ext_address) && (*buf_len == (board_data_size + board_ext_data_size))) { + if ((board_ext_address) && (fw_entry->size == (board_data_size + board_ext_data_size))) { u32 param; - status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (u8 *)(*buf + board_data_size), board_ext_data_size); + status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (u8 *)(fw_entry->data + board_data_size), board_ext_data_size); if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); + A_RELEASE_FIRMWARE(fw_entry); return A_ERROR; } @@ -1125,16 +1110,17 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, } if (compressed) { - status = BMIFastDownload(ar->arHifDevice, address, *buf, fw_entry_size); + status = BMIFastDownload(ar->arHifDevice, address, (u8 *)fw_entry->data, fw_entry_size); } else { - status = BMIWriteMemory(ar->arHifDevice, address, *buf, fw_entry_size); + status = BMIWriteMemory(ar->arHifDevice, address, (u8 *)fw_entry->data, fw_entry_size); } if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); + A_RELEASE_FIRMWARE(fw_entry); return A_ERROR; } - + A_RELEASE_FIRMWARE(fw_entry); return 0; } @@ -2102,11 +2088,6 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister) ar6000_remove_ap_interface(); #endif /*CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ - kfree(ar->fw_otp); - kfree(ar->fw); - kfree(ar->fw_patch); - kfree(ar->fw_data); - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("-ar6000_destroy \n")); } @@ -6198,7 +6179,6 @@ int ar6000_create_ap_interface(struct ar6_softc *ar, char *ap_ifname) ether_setup(dev); init_netdev(dev, ap_ifname); - dev->priv_flags &= ~IFF_TX_SKB_SHARING; if (register_netdev(dev)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: register_netdev failed\n")); diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index 32e319782f27..d3a774dbb7e8 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -867,31 +867,26 @@ ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status) AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status)); - if (!ar->scan_request) - return; - - if ((status == A_ECANCELED) || (status == A_EBUSY)) { - cfg80211_scan_done(ar->scan_request, true); - goto out; - } - - /* Translate data to cfg80211 mgmt format */ - wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy); + if(ar->scan_request) + { + /* Translate data to cfg80211 mgmt format */ + if (ar->arWmi) + wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy); - cfg80211_scan_done(ar->scan_request, false); + cfg80211_scan_done(ar->scan_request, + ((status & A_ECANCELED) || (status & A_EBUSY)) ? true : false); - if(ar->scan_request->n_ssids && - ar->scan_request->ssids[0].ssid_len) { + if(ar->scan_request->n_ssids && + ar->scan_request->ssids[0].ssid_len) { u8 i; for (i = 0; i < ar->scan_request->n_ssids; i++) { - wmi_probedSsid_cmd(ar->arWmi, i+1, DISABLE_SSID_FLAG, - 0, NULL); + wmi_probedSsid_cmd(ar->arWmi, i+1, DISABLE_SSID_FLAG, + 0, NULL); } + } + ar->scan_request = NULL; } - -out: - ar->scan_request = NULL; } static int diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 2911ea00a817..22453b0873e4 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -651,15 +651,6 @@ struct ar6_softc { void *arApDev; #endif u8 arAutoAuthStage; - - u8 *fw_otp; - size_t fw_otp_len; - u8 *fw; - size_t fw_len; - u8 *fw_patch; - size_t fw_patch_len; - u8 *fw_data; - size_t fw_data_len; }; #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index aa0d12742791..6c6236c969b7 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -449,6 +449,11 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__, info->qos ? "true" : "false"); } + if (changed & BSS_CHANGED_IDLE) { + /* Idle changed for this BSS/interface */ + wiphy_err(wiphy, "%s: BSS idle: %s (implement)\n", __func__, + info->idle ? "true" : "false"); + } return; } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 934e7f9a8673..453492610613 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -143,6 +143,7 @@ static bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw); static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw); static void wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init); static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw); +static void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool want, mbool flags); static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw); static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw); static u32 wlc_wlintrsoff(struct wlc_info *wlc); @@ -2724,7 +2725,7 @@ void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask) W_REG(&wlc_hw->regs->macintmask, wlc->macintmask); } -void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool on, mbool flags) +static void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool on, mbool flags) { u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h index a2a4e7328ee4..a5dccc273ac5 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h @@ -103,7 +103,6 @@ extern void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk); extern void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw); extern void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags); extern void wlc_bmac_reset(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool want, mbool flags); extern void wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, bool mute); extern int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c index 99250e29461f..4b4a31eff90c 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -6145,7 +6145,6 @@ wlc_recvctl(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p) { int len_mpdu; struct ieee80211_rx_status rx_status; - struct ieee80211_hdr *hdr; memset(&rx_status, 0, sizeof(rx_status)); prep_mac80211_status(wlc, rxh, p, &rx_status); @@ -6155,13 +6154,6 @@ wlc_recvctl(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p) skb_pull(p, D11_PHY_HDR_LEN); __skb_trim(p, len_mpdu); - /* unmute transmit */ - if (wlc->hw->suspended_fifos) { - hdr = (struct ieee80211_hdr *)p->data; - if (ieee80211_is_beacon(hdr->frame_control)) - wlc_bmac_mute(wlc->hw, false, 0); - } - memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status)); ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p); return; diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 727b207d8d75..20008a4376e8 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -424,7 +424,6 @@ config COMEDI_ADQ12B config COMEDI_NI_AT_A2150 tristate "NI AT-A2150 ISA card support" - select COMEDI_FC depends on COMEDI_NI_COMMON depends on VIRT_TO_BUS default N diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 39be6732aee6..e7e72b8d8cde 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -138,9 +138,6 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, if (cmd == COMEDI_DEVCONFIG) { rc = do_devconfig_ioctl(dev, (struct comedi_devconfig __user *)arg); - if (rc == 0) - /* Evade comedi_auto_unconfig(). */ - dev_file_info->hardware_device = NULL; goto done; } @@ -283,7 +280,7 @@ static int do_devconfig_ioctl(struct comedi_device *dev, if (ret == 0) { if (!try_module_get(dev->driver->module)) { comedi_device_detach(dev); - ret = -ENOSYS; + return -ENOSYS; } } @@ -386,8 +383,8 @@ static int do_devinfo_ioctl(struct comedi_device *dev, /* fill devinfo structure */ devinfo.version_code = COMEDI_VERSION_CODE; devinfo.n_subdevs = dev->n_subdevices; - strlcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN); - strlcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN); + memcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN); + memcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN); if (read_subdev) devinfo.read_subdevice = read_subdev - dev->subdevices; @@ -846,7 +843,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, ret = -EAGAIN; break; } - ret = s->async->inttrig(dev, s, data[0]); + ret = s->async->inttrig(dev, s, insn->data[0]); if (ret >= 0) ret = 1; break; @@ -1091,6 +1088,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, goto cleanup; } + kfree(async->cmd.chanlist); async->cmd = user_cmd; async->cmd.data = NULL; /* load channel/gain list */ @@ -1434,21 +1432,7 @@ static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s) return ret; } - -static void comedi_vm_open(struct vm_area_struct *area) -{ - struct comedi_async *async; - struct comedi_device *dev; - - async = area->vm_private_data; - dev = async->subdevice->device; - - mutex_lock(&dev->mutex); - async->mmap_count++; - mutex_unlock(&dev->mutex); -} - -static void comedi_vm_close(struct vm_area_struct *area) +static void comedi_unmap(struct vm_area_struct *area) { struct comedi_async *async; struct comedi_device *dev; @@ -1462,13 +1446,15 @@ static void comedi_vm_close(struct vm_area_struct *area) } static struct vm_operations_struct comedi_vm_ops = { - .open = comedi_vm_open, - .close = comedi_vm_close, + .close = comedi_unmap, }; static int comedi_mmap(struct file *file, struct vm_area_struct *vma) { const unsigned minor = iminor(file->f_dentry->d_inode); + struct comedi_device_file_info *dev_file_info = + comedi_get_device_file_info(minor); + struct comedi_device *dev = dev_file_info->device; struct comedi_async *async = NULL; unsigned long start = vma->vm_start; unsigned long size; @@ -1476,15 +1462,6 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) int i; int retval; struct comedi_subdevice *s; - struct comedi_device_file_info *dev_file_info; - struct comedi_device *dev; - - dev_file_info = comedi_get_device_file_info(minor); - if (dev_file_info == NULL) - return -ENODEV; - dev = dev_file_info->device; - if (dev == NULL) - return -ENODEV; mutex_lock(&dev->mutex); if (!dev->attached) { @@ -1551,17 +1528,11 @@ static unsigned int comedi_poll(struct file *file, poll_table * wait) { unsigned int mask = 0; const unsigned minor = iminor(file->f_dentry->d_inode); + struct comedi_device_file_info *dev_file_info = + comedi_get_device_file_info(minor); + struct comedi_device *dev = dev_file_info->device; struct comedi_subdevice *read_subdev; struct comedi_subdevice *write_subdev; - struct comedi_device_file_info *dev_file_info; - struct comedi_device *dev; - dev_file_info = comedi_get_device_file_info(minor); - - if (dev_file_info == NULL) - return -ENODEV; - dev = dev_file_info->device; - if (dev == NULL) - return -ENODEV; mutex_lock(&dev->mutex); if (!dev->attached) { @@ -1607,15 +1578,9 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, int n, m, count = 0, retval = 0; DECLARE_WAITQUEUE(wait, current); const unsigned minor = iminor(file->f_dentry->d_inode); - struct comedi_device_file_info *dev_file_info; - struct comedi_device *dev; - dev_file_info = comedi_get_device_file_info(minor); - - if (dev_file_info == NULL) - return -ENODEV; - dev = dev_file_info->device; - if (dev == NULL) - return -ENODEV; + struct comedi_device_file_info *dev_file_info = + comedi_get_device_file_info(minor); + struct comedi_device *dev = dev_file_info->device; if (!dev->attached) { DPRINTK("no driver configured on comedi%i\n", dev->minor); @@ -1675,11 +1640,11 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, retval = -EAGAIN; break; } - schedule(); if (signal_pending(current)) { retval = -ERESTARTSYS; break; } + schedule(); if (!s->busy) break; if (s->busy != file) { @@ -1718,15 +1683,9 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, int n, m, count = 0, retval = 0; DECLARE_WAITQUEUE(wait, current); const unsigned minor = iminor(file->f_dentry->d_inode); - struct comedi_device_file_info *dev_file_info; - struct comedi_device *dev; - dev_file_info = comedi_get_device_file_info(minor); - - if (dev_file_info == NULL) - return -ENODEV; - dev = dev_file_info->device; - if (dev == NULL) - return -ENODEV; + struct comedi_device_file_info *dev_file_info = + comedi_get_device_file_info(minor); + struct comedi_device *dev = dev_file_info->device; if (!dev->attached) { DPRINTK("no driver configured on comedi%i\n", dev->minor); @@ -1782,11 +1741,11 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, retval = -EAGAIN; break; } - schedule(); if (signal_pending(current)) { retval = -ERESTARTSYS; break; } + schedule(); if (!s->busy) { retval = 0; break; @@ -1835,8 +1794,6 @@ void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s) if (async) { comedi_reset_async_buf(async); async->inttrig = NULL; - kfree(async->cmd.chanlist); - async->cmd.chanlist = NULL; } else { printk(KERN_ERR "BUG: (?) do_become_nonbusy called with async=0\n"); @@ -1928,17 +1885,11 @@ ok: static int comedi_close(struct inode *inode, struct file *file) { const unsigned minor = iminor(inode); + struct comedi_device_file_info *dev_file_info = + comedi_get_device_file_info(minor); + struct comedi_device *dev = dev_file_info->device; struct comedi_subdevice *s = NULL; int i; - struct comedi_device_file_info *dev_file_info; - struct comedi_device *dev; - dev_file_info = comedi_get_device_file_info(minor); - - if (dev_file_info == NULL) - return -ENODEV; - dev = dev_file_info->device; - if (dev == NULL) - return -ENODEV; mutex_lock(&dev->mutex); @@ -1972,15 +1923,10 @@ static int comedi_close(struct inode *inode, struct file *file) static int comedi_fasync(int fd, struct file *file, int on) { const unsigned minor = iminor(file->f_dentry->d_inode); - struct comedi_device_file_info *dev_file_info; - struct comedi_device *dev; - dev_file_info = comedi_get_device_file_info(minor); + struct comedi_device_file_info *dev_file_info = + comedi_get_device_file_info(minor); - if (dev_file_info == NULL) - return -ENODEV; - dev = dev_file_info->device; - if (dev == NULL) - return -ENODEV; + struct comedi_device *dev = dev_file_info->device; return fasync_helper(fd, file, on, &dev->async_queue); } @@ -2210,7 +2156,6 @@ int comedi_alloc_board_minor(struct device *hardware_device) kfree(info); return -ENOMEM; } - info->hardware_device = hardware_device; comedi_device_init(info->device); spin_lock_irqsave(&comedi_file_info_table_lock, flags); for (i = 0; i < COMEDI_NUM_BOARD_MINORS; ++i) { @@ -2300,23 +2245,6 @@ void comedi_free_board_minor(unsigned minor) } } -int comedi_find_board_minor(struct device *hardware_device) -{ - int minor; - struct comedi_device_file_info *info; - - for (minor = 0; minor < COMEDI_NUM_BOARD_MINORS; minor++) { - spin_lock(&comedi_file_info_table_lock); - info = comedi_file_info_table[minor]; - if (info && info->hardware_device == hardware_device) { - spin_unlock(&comedi_file_info_table_lock); - return minor; - } - spin_unlock(&comedi_file_info_table_lock); - } - return -ENODEV; -} - int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s) { diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 5f2745e59747..68aa9176d249 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -237,7 +237,6 @@ struct comedi_device_file_info { struct comedi_device *device; struct comedi_subdevice *read_subdevice; struct comedi_subdevice *write_subdevice; - struct device *hardware_device; }; #ifdef CONFIG_COMEDI_DEBUG diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index f9b028604cbe..6d60e91b3a85 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -819,14 +819,25 @@ static int comedi_auto_config(struct device *hardware_device, int minor; struct comedi_device_file_info *dev_file_info; int retval; + unsigned *private_data = NULL; - if (!comedi_autoconfig) + if (!comedi_autoconfig) { + dev_set_drvdata(hardware_device, NULL); return 0; + } minor = comedi_alloc_board_minor(hardware_device); if (minor < 0) return minor; + private_data = kmalloc(sizeof(unsigned), GFP_KERNEL); + if (private_data == NULL) { + retval = -ENOMEM; + goto cleanup; + } + *private_data = minor; + dev_set_drvdata(hardware_device, private_data); + dev_file_info = comedi_get_device_file_info(minor); memset(&it, 0, sizeof(it)); @@ -839,22 +850,25 @@ static int comedi_auto_config(struct device *hardware_device, retval = comedi_device_attach(dev_file_info->device, &it); mutex_unlock(&dev_file_info->device->mutex); - if (retval < 0) +cleanup: + if (retval < 0) { + kfree(private_data); comedi_free_board_minor(minor); + } return retval; } static void comedi_auto_unconfig(struct device *hardware_device) { - int minor; - - if (hardware_device == NULL) - return; - minor = comedi_find_board_minor(hardware_device); - if (minor < 0) + unsigned *minor = (unsigned *)dev_get_drvdata(hardware_device); + if (minor == NULL) return; - BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS); - comedi_free_board_minor(minor); + + BUG_ON(*minor >= COMEDI_NUM_BOARD_MINORS); + + comedi_free_board_minor(*minor); + dev_set_drvdata(hardware_device, NULL); + kfree(minor); } int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name) diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index b4311bf66e6d..48246cd50d47 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -470,7 +470,7 @@ static int pc236_detach(struct comedi_device *dev) { printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, PC236_DRIVER_NAME); - if (dev->iobase) + if (devpriv) pc236_intr_disable(dev); if (dev->irq) diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 2567f9ab4167..a804742b8022 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -461,7 +461,7 @@ static int waveform_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { devpriv->timer_running = 0; - del_timer_sync(&devpriv->timer); + del_timer(&devpriv->timer); return 0; } diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 966b6936443a..3141dc80fe74 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -655,7 +655,7 @@ static int das08jr_ao_winsn(struct comedi_device *dev, int chan; lsb = data[0] & 0xff; - msb = (data[0] >> 8) & 0xff; + msb = (data[0] >> 8) & 0xf; chan = CR_CHAN(insn->chanspec); diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index c8b7eed07f9b..8d98cf412709 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -913,7 +913,7 @@ static int jr3_pci_attach(struct comedi_device *dev, } /* Reset DSP card */ - writel(0, &devpriv->iobase->channel[0].reset); + devpriv->iobase->channel[0].reset = 0; result = comedi_load_firmware(dev, "jr3pci.idm", jr3_download_firmware); printk("Firmare load %d\n", result); diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index c72128f30f17..23fc64b9988e 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2370,7 +2370,7 @@ static int s626_enc_insn_config(struct comedi_device *dev, /* (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]); */ k->SetMode(dev, k, Setup, TRUE); - Preload(dev, k, data[0]); + Preload(dev, k, *(insn->data)); k->PulseIndex(dev, k); SetLatchSource(dev, k, valueSrclatch); k->SetEnable(dev, k, (uint16_t) (enab != 0)); diff --git a/drivers/staging/comedi/internal.h b/drivers/staging/comedi/internal.h index 4208fb4cf0ff..434ce3433368 100644 --- a/drivers/staging/comedi/internal.h +++ b/drivers/staging/comedi/internal.h @@ -7,7 +7,6 @@ int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); int comedi_alloc_board_minor(struct device *hardware_device); void comedi_free_board_minor(unsigned minor); -int comedi_find_board_minor(struct device *hardware_device); void comedi_reset_async_buf(struct comedi_async *async); int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size); diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index d971bab87e99..f655e59a9a8f 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -212,7 +212,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, if (ret != 0) goto Cleanup; - t = wait_for_completion_timeout(&openInfo->waitevent, 5*HZ); + t = wait_for_completion_timeout(&openInfo->waitevent, HZ); if (t == 0) { err = -ETIMEDOUT; goto errorout; diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index e2e7d057f6a0..957d61ee4ceb 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -773,7 +773,7 @@ int vmbus_request_offers(void) goto cleanup; } - t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ); + t = wait_for_completion_timeout(&msginfo->waitevent, HZ); if (t == 0) { ret = -ETIMEDOUT; goto cleanup; diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index 91c65ad35099..37bbf770ef11 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -135,7 +135,7 @@ int vmbus_connect(void) } /* Wait for the connection response */ - t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ); + t = wait_for_completion_timeout(&msginfo->waitevent, HZ); if (t == 0) { spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); diff --git a/drivers/staging/hv/hyperv_storage.h b/drivers/staging/hv/hyperv_storage.h index 5af82f4235bd..a01f9a07c988 100644 --- a/drivers/staging/hv/hyperv_storage.h +++ b/drivers/staging/hv/hyperv_storage.h @@ -218,7 +218,6 @@ struct vstor_packet { #define STORVSC_MAX_LUNS_PER_TARGET 64 #define STORVSC_MAX_TARGETS 1 #define STORVSC_MAX_CHANNELS 1 -#define STORVSC_MAX_CMD_LEN 16 struct hv_storvsc_request; diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index 4742b684ca2d..41cbb26eccbf 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -270,7 +270,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) goto cleanup; } - t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ); + t = wait_for_completion_timeout(&net_device->channel_init_wait, HZ); BUG_ON(t == 0); @@ -513,7 +513,7 @@ static int netvsc_connect_vsp(struct hv_device *device) if (ret != 0) goto cleanup; - t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ); + t = wait_for_completion_timeout(&net_device->channel_init_wait, HZ); if (t == 0) { ret = -ETIMEDOUT; diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c index b47ebb3513fb..60ebdb1b6082 100644 --- a/drivers/staging/hv/rndis_filter.c +++ b/drivers/staging/hv/rndis_filter.c @@ -467,7 +467,7 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid, if (ret != 0) goto Cleanup; - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); + t = wait_for_completion_timeout(&request->wait_event, HZ); if (t == 0) { ret = -ETIMEDOUT; goto Cleanup; @@ -543,7 +543,7 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev, if (ret != 0) goto Cleanup; - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); + t = wait_for_completion_timeout(&request->wait_event, HZ); if (t == 0) { ret = -1; @@ -600,7 +600,7 @@ static int rndis_filter_init_device(struct rndis_device *dev) } - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); + t = wait_for_completion_timeout(&request->wait_event, HZ); if (t == 0) { ret = -ETIMEDOUT; diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 302978611943..06cd3276813c 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -135,7 +135,7 @@ static int storvsc_channel_init(struct hv_device *device) if (ret != 0) goto cleanup; - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); + t = wait_for_completion_timeout(&request->wait_event, HZ); if (t == 0) { ret = -ETIMEDOUT; goto cleanup; @@ -163,7 +163,7 @@ static int storvsc_channel_init(struct hv_device *device) if (ret != 0) goto cleanup; - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); + t = wait_for_completion_timeout(&request->wait_event, HZ); if (t == 0) { ret = -ETIMEDOUT; goto cleanup; @@ -192,7 +192,7 @@ static int storvsc_channel_init(struct hv_device *device) if (ret != 0) goto cleanup; - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); + t = wait_for_completion_timeout(&request->wait_event, HZ); if (t == 0) { ret = -ETIMEDOUT; goto cleanup; @@ -222,7 +222,7 @@ static int storvsc_channel_init(struct hv_device *device) if (ret != 0) goto cleanup; - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); + t = wait_for_completion_timeout(&request->wait_event, HZ); if (t == 0) { ret = -ETIMEDOUT; goto cleanup; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 734076b41bf4..942cc5f98db1 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -393,7 +393,7 @@ static int storvsc_host_reset(struct hv_device *device) if (ret != 0) goto cleanup; - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); + t = wait_for_completion_timeout(&request->wait_event, HZ); if (t == 0) { ret = -ETIMEDOUT; goto cleanup; @@ -729,8 +729,6 @@ static int storvsc_probe(struct hv_device *device) host->max_id = STORVSC_MAX_TARGETS; /* max # of channels */ host->max_channel = STORVSC_MAX_CHANNELS - 1; - /* max cmd length */ - host->max_cmd_len = STORVSC_MAX_CMD_LEN; /* Register the HBA and start the scsi bus scan */ ret = scsi_add_host(host, &device->device); diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c index a1176d913125..dd9a3bb6aa01 100644 --- a/drivers/staging/iio/magnetometer/hmc5843.c +++ b/drivers/staging/iio/magnetometer/hmc5843.c @@ -520,9 +520,7 @@ static int hmc5843_detect(struct i2c_client *client, /* Called when we have found a new HMC5843. */ static void hmc5843_init_client(struct i2c_client *client) { - struct iio_dev *indio_dev = i2c_get_clientdata(client); - struct hmc5843_data *data = iio_priv(indio_dev); - + struct hmc5843_data *data = i2c_get_clientdata(client); hmc5843_set_meas_conf(client, data->meas_conf); hmc5843_set_rate(client, data->rate); hmc5843_configure(client, data->operating_mode); diff --git a/drivers/staging/lirc/lirc_serial.c b/drivers/staging/lirc/lirc_serial.c index 21cbc9ae79c9..805df913bb6e 100644 --- a/drivers/staging/lirc/lirc_serial.c +++ b/drivers/staging/lirc/lirc_serial.c @@ -836,22 +836,25 @@ static int hardware_init_port(void) return 0; } -static int __devinit lirc_serial_probe(struct platform_device *dev) +static int init_port(void) { int i, nlow, nhigh, result; result = request_irq(irq, irq_handler, IRQF_DISABLED | (share_irq ? IRQF_SHARED : 0), LIRC_DRIVER_NAME, (void *)&hardware); - if (result < 0) { - if (result == -EBUSY) - printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", - irq); - else if (result == -EINVAL) - printk(KERN_ERR LIRC_DRIVER_NAME - ": Bad irq number or handler\n"); - return result; - } + + switch (result) { + case -EBUSY: + printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq); + return -EBUSY; + case -EINVAL: + printk(KERN_ERR LIRC_DRIVER_NAME + ": Bad irq number or handler\n"); + return -EINVAL; + default: + break; + }; /* Reserve io region. */ /* @@ -872,14 +875,11 @@ static int __devinit lirc_serial_probe(struct platform_device *dev) ": or compile the serial port driver as module and\n"); printk(KERN_WARNING LIRC_DRIVER_NAME ": make sure this module is loaded first\n"); - result = -EBUSY; - goto exit_free_irq; + return -EBUSY; } - if (hardware_init_port() < 0) { - result = -EINVAL; - goto exit_release_region; - } + if (hardware_init_port() < 0) + return -EINVAL; /* Initialize pulse/space widths */ init_timing_params(duty_cycle, freq); @@ -911,28 +911,6 @@ static int __devinit lirc_serial_probe(struct platform_device *dev) dprintk("Interrupt %d, port %04x obtained\n", irq, io); return 0; - -exit_release_region: - if (iommap != 0) - release_mem_region(iommap, 8 << ioshift); - else - release_region(io, 8); -exit_free_irq: - free_irq(irq, (void *)&hardware); - - return result; -} - -static int __devexit lirc_serial_remove(struct platform_device *dev) -{ - free_irq(irq, (void *)&hardware); - - if (iommap != 0) - release_mem_region(iommap, 8 << ioshift); - else - release_region(io, 8); - - return 0; } static int set_use_inc(void *data) @@ -1098,6 +1076,16 @@ static struct lirc_driver driver = { static struct platform_device *lirc_serial_dev; +static int __devinit lirc_serial_probe(struct platform_device *dev) +{ + return 0; +} + +static int __devexit lirc_serial_remove(struct platform_device *dev) +{ + return 0; +} + static int lirc_serial_suspend(struct platform_device *dev, pm_message_t state) { @@ -1124,8 +1112,10 @@ static int lirc_serial_resume(struct platform_device *dev) { unsigned long flags; - if (hardware_init_port() < 0) + if (hardware_init_port() < 0) { + lirc_serial_exit(); return -EINVAL; + } spin_lock_irqsave(&hardware[type].lock, flags); /* Enable Interrupt */ @@ -1198,6 +1188,10 @@ static int __init lirc_serial_init_module(void) { int result; + result = lirc_serial_init(); + if (result) + return result; + switch (type) { case LIRC_HOMEBREW: case LIRC_IRDEO: @@ -1217,7 +1211,8 @@ static int __init lirc_serial_init_module(void) break; #endif default: - return -EINVAL; + result = -EINVAL; + goto exit_serial_exit; } if (!softcarrier) { switch (type) { @@ -1233,26 +1228,37 @@ static int __init lirc_serial_init_module(void) } } - result = lirc_serial_init(); - if (result) - return result; - + result = init_port(); + if (result < 0) + goto exit_serial_exit; driver.features = hardware[type].features; driver.dev = &lirc_serial_dev->dev; driver.minor = lirc_register_driver(&driver); if (driver.minor < 0) { printk(KERN_ERR LIRC_DRIVER_NAME ": register_chrdev failed!\n"); - lirc_serial_exit(); - return -EIO; + result = -EIO; + goto exit_release; } return 0; +exit_release: + release_region(io, 8); +exit_serial_exit: + lirc_serial_exit(); + return result; } static void __exit lirc_serial_exit_module(void) { - lirc_unregister_driver(driver.minor); lirc_serial_exit(); + + free_irq(irq, (void *)&hardware); + + if (iommap != 0) + release_mem_region(iommap, 8 << ioshift); + else + release_region(io, 8); + lirc_unregister_driver(driver.minor); dprintk("cleaned up module\n"); } diff --git a/drivers/staging/lirc/lirc_sir.c b/drivers/staging/lirc/lirc_sir.c index 39bb66b79fe4..0d3864594b12 100644 --- a/drivers/staging/lirc/lirc_sir.c +++ b/drivers/staging/lirc/lirc_sir.c @@ -53,7 +53,6 @@ #include #include #include -#include #ifdef LIRC_ON_SA1100 #include #ifdef CONFIG_SA1100_COLLIE @@ -489,11 +488,9 @@ static struct lirc_driver driver = { .owner = THIS_MODULE, }; -static struct platform_device *lirc_sir_dev; static int init_chrdev(void) { - driver.dev = &lirc_sir_dev->dev; driver.minor = lirc_register_driver(&driver); if (driver.minor < 0) { printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n"); @@ -1219,71 +1216,20 @@ static int init_lirc_sir(void) return 0; } -static int __devinit lirc_sir_probe(struct platform_device *dev) -{ - return 0; -} - -static int __devexit lirc_sir_remove(struct platform_device *dev) -{ - return 0; -} - -static struct platform_driver lirc_sir_driver = { - .probe = lirc_sir_probe, - .remove = __devexit_p(lirc_sir_remove), - .driver = { - .name = "lirc_sir", - .owner = THIS_MODULE, - }, -}; static int __init lirc_sir_init(void) { int retval; - retval = platform_driver_register(&lirc_sir_driver); - if (retval) { - printk(KERN_ERR LIRC_DRIVER_NAME ": Platform driver register " - "failed!\n"); - return -ENODEV; - } - - lirc_sir_dev = platform_device_alloc("lirc_dev", 0); - if (!lirc_sir_dev) { - printk(KERN_ERR LIRC_DRIVER_NAME ": Platform device alloc " - "failed!\n"); - retval = -ENOMEM; - goto pdev_alloc_fail; - } - - retval = platform_device_add(lirc_sir_dev); - if (retval) { - printk(KERN_ERR LIRC_DRIVER_NAME ": Platform device add " - "failed!\n"); - retval = -ENODEV; - goto pdev_add_fail; - } - retval = init_chrdev(); if (retval < 0) - goto fail; - + return retval; retval = init_lirc_sir(); if (retval) { drop_chrdev(); - goto fail; + return retval; } - return 0; - -fail: - platform_device_del(lirc_sir_dev); -pdev_add_fail: - platform_device_put(lirc_sir_dev); -pdev_alloc_fail: - platform_driver_unregister(&lirc_sir_driver); - return retval; } static void __exit lirc_sir_exit(void) @@ -1291,8 +1237,6 @@ static void __exit lirc_sir_exit(void) drop_hardware(); drop_chrdev(); drop_port(); - platform_device_unregister(lirc_sir_dev); - platform_driver_unregister(&lirc_sir_driver); printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n"); } diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c index 02fafecd4773..ca098cabc2bc 100644 --- a/drivers/staging/quatech_usb2/quatech_usb2.c +++ b/drivers/staging/quatech_usb2/quatech_usb2.c @@ -916,10 +916,9 @@ static int qt2_ioctl(struct tty_struct *tty, dbg("%s() port %d, cmd == TIOCMIWAIT enter", __func__, port->number); prev_msr_value = port_extra->shadowMSR & QT2_SERIAL_MSR_MASK; - barrier(); - __set_current_state(TASK_INTERRUPTIBLE); while (1) { add_wait_queue(&port_extra->wait, &wait); + set_current_state(TASK_INTERRUPTIBLE); schedule(); dbg("%s(): port %d, cmd == TIOCMIWAIT here\n", __func__, port->number); @@ -927,12 +926,9 @@ static int qt2_ioctl(struct tty_struct *tty, /* see if a signal woke us up */ if (signal_pending(current)) return -ERESTARTSYS; - set_current_state(TASK_INTERRUPTIBLE); msr_value = port_extra->shadowMSR & QT2_SERIAL_MSR_MASK; - if (msr_value == prev_msr_value) { - __set_current_state(TASK_RUNNING); + if (msr_value == prev_msr_value) return -EIO; /* no change - error */ - } if ((arg & TIOCM_RNG && ((prev_msr_value & QT2_SERIAL_MSR_RI) == (msr_value & QT2_SERIAL_MSR_RI))) || @@ -945,7 +941,6 @@ static int qt2_ioctl(struct tty_struct *tty, (arg & TIOCM_CTS && ((prev_msr_value & QT2_SERIAL_MSR_CTS) == (msr_value & QT2_SERIAL_MSR_CTS)))) { - __set_current_state(TASK_RUNNING); return 0; } } /* end inifinite while */ diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index cd98f89079be..58d800f1b5ee 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -4532,7 +4532,6 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, u8 unit = 0; int ret = -ENODEV; unsigned long pmem_start, pmem_len, pmem_flags; - u8 revisionid; RT_TRACE(COMP_INIT,"Configuring chip resources\n"); @@ -4593,11 +4592,6 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, pci_write_config_byte(pdev, 0x41, 0x00); - pci_read_config_byte(pdev, 0x08, &revisionid); - /* If the revisionid is 0x10, the device uses rtl8192se. */ - if (pdev->device == 0x8192 && revisionid == 0x10) - goto fail1; - pci_read_config_byte(pdev, 0x05, &unit); pci_write_config_byte(pdev, 0x05, unit & (~0x04)); diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c index 4bb5fffca5b9..6766f468639f 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware.c +++ b/drivers/staging/rtl8192u/r819xU_firmware.c @@ -399,7 +399,10 @@ download_firmware_fail: } -MODULE_FIRMWARE("RTL8192U/boot.img"); -MODULE_FIRMWARE("RTL8192U/main.img"); -MODULE_FIRMWARE("RTL8192U/data.img"); + + + + + + diff --git a/drivers/staging/rtl8712/recv_linux.c b/drivers/staging/rtl8712/recv_linux.c index 30a9c62a8238..1f0949ed7ee0 100644 --- a/drivers/staging/rtl8712/recv_linux.c +++ b/drivers/staging/rtl8712/recv_linux.c @@ -113,8 +113,13 @@ void r8712_recv_indicatepkt(struct _adapter *padapter, if (skb == NULL) goto _recv_indicatepkt_drop; skb->data = precv_frame->u.hdr.rx_data; +#ifdef NET_SKBUFF_DATA_USES_OFFSET + skb->tail = (sk_buff_data_t)(precv_frame->u.hdr.rx_tail - + precv_frame->u.hdr.rx_head); +#else + skb->tail = (sk_buff_data_t)precv_frame->u.hdr.rx_tail; +#endif skb->len = precv_frame->u.hdr.len; - skb_set_tail_pointer(skb, skb->len); if ((pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1)) skb->ip_summed = CHECKSUM_UNNECESSARY; else diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index af28a62c4e58..21ce2af447b5 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -62,8 +62,6 @@ static struct usb_device_id rtl871x_usb_id_tbl[] = { {USB_DEVICE(0x0B05, 0x1791)}, /* 11n mode disable */ /* Belkin */ {USB_DEVICE(0x050D, 0x945A)}, - /* ISY IWL - Belkin clone */ - {USB_DEVICE(0x050D, 0x11F1)}, /* Corega */ {USB_DEVICE(0x07AA, 0x0047)}, /* D-Link */ @@ -88,8 +86,6 @@ static struct usb_device_id rtl871x_usb_id_tbl[] = { {USB_DEVICE(0x0DF6, 0x0045)}, {USB_DEVICE(0x0DF6, 0x0059)}, /* 11n mode disable */ {USB_DEVICE(0x0DF6, 0x004B)}, - {USB_DEVICE(0x0DF6, 0x005B)}, - {USB_DEVICE(0x0DF6, 0x005D)}, {USB_DEVICE(0x0DF6, 0x0063)}, /* Sweex */ {USB_DEVICE(0x177F, 0x0154)}, diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 48aa61eb9c74..12f5eba0355c 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -24,6 +24,7 @@ static int debug; #define DRIVER_DESC "Quatech USB to Serial Driver" #define USB_VENDOR_ID_QUATECH 0x061d /* Quatech VID */ +#define QUATECH_SSU100 0xC020 /* SSU100 */ #define QUATECH_SSU200 0xC030 /* SSU200 */ #define QUATECH_DSU100 0xC040 /* DSU100 */ #define QUATECH_DSU200 0xC050 /* DSU200 */ @@ -126,6 +127,7 @@ static int debug; #define RS232_MODE 0x00 static const struct usb_device_id serqt_id_table[] = { + {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU100)}, {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU200)}, {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU100)}, {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU200)}, @@ -773,6 +775,7 @@ static int qt_startup(struct usb_serial *serial) } switch (serial->dev->descriptor.idProduct) { + case QUATECH_SSU100: case QUATECH_DSU100: case QUATECH_QSU100: case QUATECH_ESU100A: diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index 59a6d4da873b..42fcf7e9cb64 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -1855,7 +1855,7 @@ static void speakup_bits(struct vc_data *vc) static int handle_goto(struct vc_data *vc, u_char type, u_char ch, u_short key) { - static u_char goto_buf[8]; + static u_char *goto_buf = "\0\0\0\0\0\0"; static int num; int maxlen, go_pos; char *cp; diff --git a/drivers/staging/speakup/speakup_soft.c b/drivers/staging/speakup/speakup_soft.c index e76a882243a3..a2c3dc4098b9 100644 --- a/drivers/staging/speakup/speakup_soft.c +++ b/drivers/staging/speakup/speakup_soft.c @@ -40,7 +40,7 @@ static int softsynth_is_alive(struct spk_synth *synth); static unsigned char get_index(void); static struct miscdevice synth_device; -static int init_pos; +static int initialized; static int misc_registered; static struct var_t vars[] = { @@ -194,7 +194,7 @@ static int softsynth_close(struct inode *inode, struct file *fp) unsigned long flags; spk_lock(flags); synth_soft.alive = 0; - init_pos = 0; + initialized = 0; spk_unlock(flags); /* Make sure we let applications go before leaving */ speakup_start_ttys(); @@ -239,8 +239,13 @@ static ssize_t softsynth_read(struct file *fp, char *buf, size_t count, ch = '\x18'; } else if (synth_buffer_empty()) { break; - } else if (init[init_pos]) { - ch = init[init_pos++]; + } else if (!initialized) { + if (*init) { + ch = *init; + init++; + } else { + initialized = 1; + } } else { ch = synth_buffer_getc(); } diff --git a/drivers/staging/speakup/synth.c b/drivers/staging/speakup/synth.c index 7843111555e7..c241074a4b5e 100644 --- a/drivers/staging/speakup/synth.c +++ b/drivers/staging/speakup/synth.c @@ -342,7 +342,7 @@ int synth_init(char *synth_name) mutex_lock(&spk_mutex); /* First, check if we already have it loaded. */ - for (i = 0; i < MAXSYNTHS && synths[i] != NULL; i++) + for (i = 0; synths[i] != NULL && i < MAXSYNTHS; i++) if (strcmp(synths[i]->name, synth_name) == 0) synth = synths[i]; @@ -423,7 +423,7 @@ int synth_add(struct spk_synth *in_synth) int i; int status = 0; mutex_lock(&spk_mutex); - for (i = 0; i < MAXSYNTHS && synths[i] != NULL; i++) + for (i = 0; synths[i] != NULL && i < MAXSYNTHS; i++) /* synth_remove() is responsible for rotating the array down */ if (in_synth == synths[i]) { mutex_unlock(&spk_mutex); diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c index 1547cf232508..433a3b6207d6 100644 --- a/drivers/staging/usbip/usbip_common.c +++ b/drivers/staging/usbip/usbip_common.c @@ -761,25 +761,26 @@ EXPORT_SYMBOL_GPL(usbip_recv_iso); * buffer and iso packets need to be stored and be in propeper endian in urb * before calling this function */ -void usbip_pad_iso(struct usbip_device *ud, struct urb *urb) +int usbip_pad_iso(struct usbip_device *ud, struct urb *urb) { int np = urb->number_of_packets; int i; + int ret; int actualoffset = urb->actual_length; if (!usb_pipeisoc(urb->pipe)) - return; + return 0; /* if no packets or length of data is 0, then nothing to unpack */ if (np == 0 || urb->actual_length == 0) - return; + return 0; /* * if actual_length is transfer_buffer_length then no padding is * present. */ if (urb->actual_length == urb->transfer_buffer_length) - return; + return 0; /* * loop over all packets from last to first (to prevent overwritting @@ -791,6 +792,8 @@ void usbip_pad_iso(struct usbip_device *ud, struct urb *urb) urb->transfer_buffer + actualoffset, urb->iso_frame_desc[i].actual_length); } + + return ret; } EXPORT_SYMBOL_GPL(usbip_pad_iso); diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h index 072743ece5e3..4a641c552b78 100644 --- a/drivers/staging/usbip/usbip_common.h +++ b/drivers/staging/usbip/usbip_common.h @@ -327,7 +327,7 @@ int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb); /* some members of urb must be substituted before. */ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb); /* some members of urb must be substituted before. */ -void usbip_pad_iso(struct usbip_device *ud, struct urb *urb); +int usbip_pad_iso(struct usbip_device *ud, struct urb *urb); void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen); /* usbip_event.c */ diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index 76d7485f4e23..a76e8fa69b6e 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -846,9 +846,9 @@ static void vhci_shutdown_connection(struct usbip_device *ud) } /* kill threads related to this sdev, if v.c. exists */ - if (vdev->ud.tcp_rx && !task_is_dead(vdev->ud.tcp_rx)) + if (vdev->ud.tcp_rx) kthread_stop(vdev->ud.tcp_rx); - if (vdev->ud.tcp_tx && !task_is_dead(vdev->ud.tcp_tx)) + if (vdev->ud.tcp_tx) kthread_stop(vdev->ud.tcp_tx); pr_info("stop threads\n"); diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c index c851433f5df4..e42ce9dab7ac 100644 --- a/drivers/staging/usbip/vhci_rx.c +++ b/drivers/staging/usbip/vhci_rx.c @@ -68,7 +68,6 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, { struct usbip_device *ud = &vdev->ud; struct urb *urb; - unsigned long flags; spin_lock(&vdev->priv_lock); urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum); @@ -94,16 +93,17 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, return; /* restore the padding in iso packets */ - usbip_pad_iso(ud, urb); + if (usbip_pad_iso(ud, urb) < 0) + return; if (usbip_dbg_flag_vhci_rx) usbip_dump_urb(urb); usbip_dbg_vhci_rx("now giveback urb %p\n", urb); - spin_lock_irqsave(&the_controller->lock, flags); + spin_lock(&the_controller->lock); usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); - spin_unlock_irqrestore(&the_controller->lock, flags); + spin_unlock(&the_controller->lock); usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); @@ -141,7 +141,6 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, { struct vhci_unlink *unlink; struct urb *urb; - unsigned long flags; usbip_dump_header(pdu); @@ -171,9 +170,9 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, urb->status = pdu->u.ret_unlink.status; pr_info("urb->status %d\n", urb->status); - spin_lock_irqsave(&the_controller->lock, flags); + spin_lock(&the_controller->lock); usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); - spin_unlock_irqrestore(&the_controller->lock, flags); + spin_unlock(&the_controller->lock); usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); diff --git a/drivers/staging/vt6656/bssdb.h b/drivers/staging/vt6656/bssdb.h index 991ce3eecd8d..a8f97ebb659b 100644 --- a/drivers/staging/vt6656/bssdb.h +++ b/drivers/staging/vt6656/bssdb.h @@ -92,6 +92,7 @@ typedef struct tagSRSNCapObject { } SRSNCapObject, *PSRSNCapObject; // BSS info(AP) +#pragma pack(1) typedef struct tagKnownBSS { // BSS info BOOL bActive; diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index 5918ef7038b3..cb817ced5184 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -200,7 +200,7 @@ s_vProcessRxMACHeader ( } else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) { cbHeaderSize += 6; pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); - if ((*pwType == cpu_to_be16(ETH_P_IPX)) || + if ((*pwType == cpu_to_le16(ETH_P_IPX)) || (*pwType == cpu_to_le16(0xF380))) { cbHeaderSize -= 8; pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); @@ -1256,7 +1256,7 @@ static BOOL s_bHandleRxEncryption ( PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc *pdwRxTSC47_16 = cpu_to_le32(*(PDWORD)(pbyIV + 4)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %x\n", *pdwRxTSC47_16); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16); if (byDecMode == KEY_CTL_TKIP) { *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV)); } else { @@ -1367,7 +1367,7 @@ static BOOL s_bHostWepRxEncryption ( PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc *pdwRxTSC47_16 = cpu_to_le32(*(PDWORD)(pbyIV + 4)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %x\n", *pdwRxTSC47_16); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16); if (byDecMode == KEY_CTL_TKIP) { *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV)); diff --git a/drivers/staging/vt6656/int.h b/drivers/staging/vt6656/int.h index c731b120d986..3176c8d08d6d 100644 --- a/drivers/staging/vt6656/int.h +++ b/drivers/staging/vt6656/int.h @@ -34,6 +34,7 @@ #include "device.h" /*--------------------- Export Definitions -------------------------*/ +#pragma pack(1) typedef struct tagSINTData { BYTE byTSR0; BYTE byPkt0; diff --git a/drivers/staging/vt6656/iocmd.h b/drivers/staging/vt6656/iocmd.h index ae6e2d237b20..22710cef751d 100644 --- a/drivers/staging/vt6656/iocmd.h +++ b/drivers/staging/vt6656/iocmd.h @@ -95,12 +95,13 @@ typedef enum tagWZONETYPE { // Ioctl interface structure // Command structure // +#pragma pack(1) typedef struct tagSCmdRequest { u8 name[16]; void *data; u16 wResult; u16 wCmdCode; -} __packed SCmdRequest, *PSCmdRequest; +} SCmdRequest, *PSCmdRequest; // // Scan @@ -110,7 +111,7 @@ typedef struct tagSCmdScan { u8 ssid[SSID_MAXLEN + 2]; -} __packed SCmdScan, *PSCmdScan; +} SCmdScan, *PSCmdScan; // // BSS Join @@ -125,7 +126,7 @@ typedef struct tagSCmdBSSJoin { BOOL bPSEnable; BOOL bShareKeyAuth; -} __packed SCmdBSSJoin, *PSCmdBSSJoin; +} SCmdBSSJoin, *PSCmdBSSJoin; // // Zonetype Setting @@ -136,7 +137,7 @@ typedef struct tagSCmdZoneTypeSet { BOOL bWrite; WZONETYPE ZoneType; -} __packed SCmdZoneTypeSet, *PSCmdZoneTypeSet; +} SCmdZoneTypeSet, *PSCmdZoneTypeSet; typedef struct tagSWPAResult { char ifname[100]; @@ -144,7 +145,7 @@ typedef struct tagSWPAResult { u8 key_mgmt; u8 eap_type; BOOL authenticated; -} __packed SWPAResult, *PSWPAResult; +} SWPAResult, *PSWPAResult; typedef struct tagSCmdStartAP { @@ -156,7 +157,7 @@ typedef struct tagSCmdStartAP { BOOL bShareKeyAuth; u8 byBasicRate; -} __packed SCmdStartAP, *PSCmdStartAP; +} SCmdStartAP, *PSCmdStartAP; typedef struct tagSCmdSetWEP { @@ -166,7 +167,7 @@ typedef struct tagSCmdSetWEP { BOOL bWepKeyAvailable[WEP_NKEYS]; u32 auWepKeyLength[WEP_NKEYS]; -} __packed SCmdSetWEP, *PSCmdSetWEP; +} SCmdSetWEP, *PSCmdSetWEP; typedef struct tagSBSSIDItem { @@ -179,14 +180,14 @@ typedef struct tagSBSSIDItem { BOOL bWEPOn; u32 uRSSI; -} __packed SBSSIDItem; +} SBSSIDItem; typedef struct tagSBSSIDList { u32 uItem; SBSSIDItem sBSSIDList[0]; -} __packed SBSSIDList, *PSBSSIDList; +} SBSSIDList, *PSBSSIDList; typedef struct tagSNodeItem { @@ -207,7 +208,7 @@ typedef struct tagSNodeItem { u32 uTxAttempts; u16 wFailureRatio; -} __packed SNodeItem; +} SNodeItem; typedef struct tagSNodeList { @@ -215,7 +216,7 @@ typedef struct tagSNodeList { u32 uItem; SNodeItem sNodeList[0]; -} __packed SNodeList, *PSNodeList; +} SNodeList, *PSNodeList; typedef struct tagSCmdLinkStatus { @@ -228,7 +229,7 @@ typedef struct tagSCmdLinkStatus { u32 uChannel; u32 uLinkRate; -} __packed SCmdLinkStatus, *PSCmdLinkStatus; +} SCmdLinkStatus, *PSCmdLinkStatus; // // 802.11 counter @@ -246,7 +247,7 @@ typedef struct tagSDot11MIBCount { u32 ReceivedFragmentCount; u32 MulticastReceivedFrameCount; u32 FCSErrorCount; -} __packed SDot11MIBCount, *PSDot11MIBCount; +} SDot11MIBCount, *PSDot11MIBCount; @@ -354,13 +355,13 @@ typedef struct tagSStatMIBCount { u32 ullTxBroadcastBytes[2]; u32 ullTxMulticastBytes[2]; u32 ullTxDirectedBytes[2]; -} __packed SStatMIBCount, *PSStatMIBCount; +} SStatMIBCount, *PSStatMIBCount; typedef struct tagSCmdValue { u32 dwValue; -} __packed SCmdValue, *PSCmdValue; +} SCmdValue, *PSCmdValue; // // hostapd & viawget ioctl related @@ -430,7 +431,7 @@ struct viawget_hostapd_param { u8 ssid[32]; } scan_req; } u; -} __packed; +}; /*--------------------- Export Classes ----------------------------*/ diff --git a/drivers/staging/vt6656/iowpa.h b/drivers/staging/vt6656/iowpa.h index 2522ddec718d..959c8868f6e2 100644 --- a/drivers/staging/vt6656/iowpa.h +++ b/drivers/staging/vt6656/iowpa.h @@ -67,11 +67,12 @@ enum { +#pragma pack(1) typedef struct viawget_wpa_header { u8 type; u16 req_ie_len; u16 resp_ie_len; -} __packed viawget_wpa_header; +} viawget_wpa_header; struct viawget_wpa_param { u32 cmd; @@ -112,8 +113,9 @@ struct viawget_wpa_param { u8 *buf; } scan_results; } u; -} __packed; +}; +#pragma pack(1) struct viawget_scan_result { u8 bssid[6]; u8 ssid[32]; @@ -128,7 +130,7 @@ struct viawget_scan_result { int noise; int level; int maxrate; -} __packed; +}; /*--------------------- Export Classes ----------------------------*/ diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index fd93e837c707..27bb523c8a97 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -223,7 +223,7 @@ BOOL KeybSetKey( PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyIndex, - u32 uKeyLength, + unsigned long uKeyLength, PQWORD pKeyRSC, PBYTE pbyKey, BYTE byKeyDecMode @@ -235,8 +235,7 @@ BOOL KeybSetKey( PSKeyItem pKey; unsigned int uKeyIdx; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO - "Enter KeybSetKey: %X\n", dwKeyIndex); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetKey: %lX\n", dwKeyIndex); j = (MAX_KEY_TABLE-1); for (i=0;i<(MAX_KEY_TABLE-1);i++) { @@ -262,9 +261,7 @@ BOOL KeybSetKey( if ((dwKeyIndex & TRANSMIT_KEY) != 0) { // Group transmit key pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO - "Group transmit key(R)[%X]: %d\n", - pTable->KeyTable[i].dwGTKeyIndex, i); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i); } pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4); @@ -305,12 +302,9 @@ BOOL KeybSetKey( } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n ", - pKey->dwTSC47_16); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", - pKey->wTSC15_0); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n ", - pKey->dwKeyIndex); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex); return (TRUE); } @@ -332,9 +326,7 @@ BOOL KeybSetKey( if ((dwKeyIndex & TRANSMIT_KEY) != 0) { // Group transmit key pTable->KeyTable[j].dwGTKeyIndex = dwKeyIndex; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO - "Group transmit key(N)[%X]: %d\n", - pTable->KeyTable[j].dwGTKeyIndex, j); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(N)[%lX]: %d\n", pTable->KeyTable[j].dwGTKeyIndex, j); } pTable->KeyTable[j].wKeyCtl &= 0xFF0F; // clear group key control filed pTable->KeyTable[j].wKeyCtl |= (byKeyDecMode << 4); @@ -375,11 +367,9 @@ BOOL KeybSetKey( } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n ", - pKey->dwTSC47_16); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n ", - pKey->dwKeyIndex); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex); return (TRUE); } @@ -607,8 +597,7 @@ BOOL KeybGetTransmitKey(PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyType, DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]); } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %X\n", - pTable->KeyTable[i].dwGTKeyIndex); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %lX\n", pTable->KeyTable[i].dwGTKeyIndex); return (TRUE); } @@ -675,7 +664,7 @@ BOOL KeybSetDefaultKey( void *pDeviceHandler, PSKeyManagement pTable, DWORD dwKeyIndex, - u32 uKeyLength, + unsigned long uKeyLength, PQWORD pKeyRSC, PBYTE pbyKey, BYTE byKeyDecMode @@ -704,10 +693,7 @@ BOOL KeybSetDefaultKey( if ((dwKeyIndex & TRANSMIT_KEY) != 0) { // Group transmit key pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = dwKeyIndex; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO - "Group transmit key(R)[%X]: %d\n", - pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex, - MAX_KEY_TABLE-1); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex, MAX_KEY_TABLE-1); } pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl &= 0x7F00; // clear all key control filed @@ -758,11 +744,9 @@ BOOL KeybSetDefaultKey( } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n", - pKey->dwTSC47_16); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n", pKey->dwTSC47_16); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n", pKey->wTSC15_0); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n", - pKey->dwKeyIndex); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n", pKey->dwKeyIndex); return (TRUE); } @@ -788,7 +772,7 @@ BOOL KeybSetAllGroupKey( void *pDeviceHandler, PSKeyManagement pTable, DWORD dwKeyIndex, - u32 uKeyLength, + unsigned long uKeyLength, PQWORD pKeyRSC, PBYTE pbyKey, BYTE byKeyDecMode @@ -800,8 +784,7 @@ BOOL KeybSetAllGroupKey( PSKeyItem pKey; unsigned int uKeyIdx; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %X\n", - dwKeyIndex); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex); if ((dwKeyIndex & PAIRWISE_KEY) != 0) { // Pairwise key @@ -818,9 +801,7 @@ BOOL KeybSetAllGroupKey( if ((dwKeyIndex & TRANSMIT_KEY) != 0) { // Group transmit key pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO - "Group transmit key(R)[%X]: %d\n", - pTable->KeyTable[i].dwGTKeyIndex, i); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i); } pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h index bd35d39621ae..f749c7a027d3 100644 --- a/drivers/staging/vt6656/key.h +++ b/drivers/staging/vt6656/key.h @@ -58,7 +58,7 @@ typedef struct tagSKeyItem { BOOL bKeyValid; - u32 uKeyLength; + unsigned long uKeyLength; BYTE abyKey[MAX_KEY_LEN]; QWORD KeyRSC; DWORD dwTSC47_16; @@ -107,7 +107,7 @@ BOOL KeybSetKey( PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyIndex, - u32 uKeyLength, + unsigned long uKeyLength, PQWORD pKeyRSC, PBYTE pbyKey, BYTE byKeyDecMode @@ -146,7 +146,7 @@ BOOL KeybSetDefaultKey( void *pDeviceHandler, PSKeyManagement pTable, DWORD dwKeyIndex, - u32 uKeyLength, + unsigned long uKeyLength, PQWORD pKeyRSC, PBYTE pbyKey, BYTE byKeyDecMode @@ -156,7 +156,7 @@ BOOL KeybSetAllGroupKey( void *pDeviceHandler, PSKeyManagement pTable, DWORD dwKeyIndex, - u32 uKeyLength, + unsigned long uKeyLength, PQWORD pKeyRSC, PBYTE pbyKey, BYTE byKeyDecMode diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c index 0636d8248254..26c19d1408c4 100644 --- a/drivers/staging/vt6656/mac.c +++ b/drivers/staging/vt6656/mac.c @@ -262,8 +262,7 @@ BYTE pbyData[24]; dwData1 <<= 16; dwData1 |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %X,"\ - " KeyCtl:%X\n", wOffset, dwData1, wKeyCtl); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData1, wKeyCtl); //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); //VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); @@ -280,8 +279,7 @@ BYTE pbyData[24]; dwData2 <<= 8; dwData2 |= *(pbyAddr+0); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2. wOffset: %d, Data: %X\n", - wOffset, dwData2); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2. wOffset: %d, Data: %lX\n", wOffset, dwData2); //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); //VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index ce459d50c5b4..e18efd43e3e0 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -222,7 +222,7 @@ DEVICE_PARAM(b80211hEnable, "802.11h mode"); // Static vars definitions // -static struct usb_device_id vt6656_table[] = { +static struct usb_device_id vt6656_table[] __devinitdata = { {USB_DEVICE(VNT_USB_VENDOR_ID, VNT_USB_PRODUCT_ID)}, {} }; diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c index 8cf0881888b2..3fd0478a9a54 100644 --- a/drivers/staging/vt6656/rf.c +++ b/drivers/staging/vt6656/rf.c @@ -769,9 +769,6 @@ BYTE byPwr = pDevice->byCCKPwr; return TRUE; } - if (uCH == 0) - return -EINVAL; - switch (uRATE) { case RATE_1M: case RATE_2M: diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index 3beb126e90f8..9b64b102f55c 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -377,8 +377,7 @@ s_vFillTxKey ( *(pbyIVHead+3) = (BYTE)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV // Append IV&ExtIV after Mac Header *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %x\n", - *pdwExtIV); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV); } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { pTransmitKey->wTSC15_0++; @@ -1702,7 +1701,7 @@ s_bPacketToWirelessUsb( // 802.1H if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) { if (pDevice->dwDiagRefCount == 0) { - if ((psEthHeader->wType == cpu_to_be16(ETH_P_IPX)) || + if ((psEthHeader->wType == cpu_to_le16(ETH_P_IPX)) || (psEthHeader->wType == cpu_to_le16(0xF380))) { memcpy((PBYTE) (pbyPayloadHead), abySNAP_Bridgetunnel, 6); @@ -1754,8 +1753,7 @@ s_bPacketToWirelessUsb( MIC_vAppend((PBYTE)&(psEthHeader->abyDstAddr[0]), 12); dwMIC_Priority = 0; MIC_vAppend((PBYTE)&dwMIC_Priority, 4); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %X, %X\n", - dwMICKey0, dwMICKey1); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1); /////////////////////////////////////////////////////////////////// @@ -2637,8 +2635,7 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb) { MIC_vAppend((PBYTE)&(sEthHeader.abyDstAddr[0]), 12); dwMIC_Priority = 0; MIC_vAppend((PBYTE)&dwMIC_Priority, 4); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY:"\ - " %X, %X\n", dwMICKey0, dwMICKey1); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1); uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen; @@ -2658,8 +2655,7 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%x, %x\n", - *pdwMIC_L, *pdwMIC_R); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R); } @@ -2844,10 +2840,10 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) Packet_Type = skb->data[ETH_HLEN+1]; Descriptor_type = skb->data[ETH_HLEN+1+1+2]; Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]); - if (pDevice->sTxEthHeader.wType == cpu_to_be16(ETH_P_PAE)) { - /* 802.1x OR eapol-key challenge frame transfer */ - if (((Protocol_Version == 1) || (Protocol_Version == 2)) && - (Packet_Type == 3)) { + if (pDevice->sTxEthHeader.wType == cpu_to_le16(ETH_P_PAE)) { + /* 802.1x OR eapol-key challenge frame transfer */ + if (((Protocol_Version == 1) || (Protocol_Version == 2)) && + (Packet_Type == 3)) { bTxeapol_key = TRUE; if(!(Key_info & BIT3) && //WPA or RSN group-key challenge (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key @@ -2993,19 +2989,19 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) } } - if (pDevice->sTxEthHeader.wType == cpu_to_be16(ETH_P_PAE)) { - if (pDevice->byBBType != BB_TYPE_11A) { - pDevice->wCurrentRate = RATE_1M; - pDevice->byACKRate = RATE_1M; - pDevice->byTopCCKBasicRate = RATE_1M; - pDevice->byTopOFDMBasicRate = RATE_6M; - } else { - pDevice->wCurrentRate = RATE_6M; - pDevice->byACKRate = RATE_6M; - pDevice->byTopCCKBasicRate = RATE_1M; - pDevice->byTopOFDMBasicRate = RATE_6M; - } - } + if (pDevice->sTxEthHeader.wType == cpu_to_le16(ETH_P_PAE)) { + if (pDevice->byBBType != BB_TYPE_11A) { + pDevice->wCurrentRate = RATE_1M; + pDevice->byACKRate = RATE_1M; + pDevice->byTopCCKBasicRate = RATE_1M; + pDevice->byTopOFDMBasicRate = RATE_6M; + } else { + pDevice->wCurrentRate = RATE_6M; + pDevice->byACKRate = RATE_6M; + pDevice->byTopCCKBasicRate = RATE_1M; + pDevice->byTopOFDMBasicRate = RATE_6M; + } + } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n", @@ -3021,7 +3017,7 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) if (bNeedEncryption == TRUE) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType)); - if ((pDevice->sTxEthHeader.wType) == cpu_to_be16(ETH_P_PAE)) { + if ((pDevice->sTxEthHeader.wType) == cpu_to_le16(ETH_P_PAE)) { bNeedEncryption = FALSE; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType)); if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { @@ -3033,8 +3029,7 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n"); } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n", - pTransmitKey->dwKeyIndex); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex); bNeedEncryption = TRUE; } } @@ -3048,8 +3043,7 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) if (pDevice->bEnableHostWEP) { if ((uNodeIndex != 0) && (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n", - pTransmitKey->dwKeyIndex); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex); bNeedEncryption = TRUE; } } diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index dfbf74713a80..8e9450ef3997 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -29,8 +29,6 @@ #ifndef __TTYPE_H__ #define __TTYPE_H__ -#include - /******* Common definitions and typedefs ***********************************/ typedef int BOOL; @@ -44,17 +42,17 @@ typedef int BOOL; /****** Simple typedefs ***************************************************/ -typedef u8 BYTE; -typedef u16 WORD; -typedef u32 DWORD; +typedef unsigned char BYTE; // 8-bit +typedef unsigned short WORD; // 16-bit +typedef unsigned long DWORD; // 32-bit // QWORD is for those situation that we want // an 8-byte-aligned 8 byte long structure // which is NOT really a floating point number. typedef union tagUQuadWord { struct { - u32 dwLowDword; - u32 dwHighDword; + DWORD dwLowDword; + DWORD dwHighDword; } u; double DoNotUseThisField; } UQuadWord; @@ -62,8 +60,8 @@ typedef UQuadWord QWORD; // 64-bit /****** Common pointer types ***********************************************/ -typedef u32 ULONG_PTR; -typedef u32 DWORD_PTR; +typedef unsigned long ULONG_PTR; // 32-bit +typedef unsigned long DWORD_PTR; // 32-bit // boolean pointer diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index 31fb96a54cff..78ea121b7e2e 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -316,19 +316,17 @@ s_MgrMakeProbeRequest( return pTxPacket; } -void vCommandTimerWait(void *hDeviceContext, unsigned long MSecond) +void vCommandTimerWait(void *hDeviceContext, unsigned int MSecond) { - PSDevice pDevice = (PSDevice)hDeviceContext; - - init_timer(&pDevice->sTimerCommand); - - pDevice->sTimerCommand.data = (unsigned long)pDevice; - pDevice->sTimerCommand.function = (TimerFunction)vRunCommand; - pDevice->sTimerCommand.expires = RUN_AT((MSecond * HZ) / 1000); - - add_timer(&pDevice->sTimerCommand); + PSDevice pDevice = (PSDevice)hDeviceContext; - return; + init_timer(&pDevice->sTimerCommand); + pDevice->sTimerCommand.data = (unsigned long)pDevice; + pDevice->sTimerCommand.function = (TimerFunction)vRunCommand; + // RUN_AT :1 msec ~= (HZ/1024) + pDevice->sTimerCommand.expires = (unsigned int)RUN_AT((MSecond * HZ) >> 10); + add_timer(&pDevice->sTimerCommand); + return; } void vRunCommand(void *hDeviceContext) diff --git a/drivers/staging/vt6656/wpa2.h b/drivers/staging/vt6656/wpa2.h index c359252a6b0e..46c295905b48 100644 --- a/drivers/staging/vt6656/wpa2.h +++ b/drivers/staging/vt6656/wpa2.h @@ -45,8 +45,8 @@ typedef struct tagsPMKIDInfo { } PMKIDInfo, *PPMKIDInfo; typedef struct tagSPMKIDCache { - u32 BSSIDInfoCount; - PMKIDInfo BSSIDInfo[MAX_PMKID_CACHE]; + unsigned long BSSIDInfoCount; + PMKIDInfo BSSIDInfo[MAX_PMKID_CACHE]; } SPMKIDCache, *PSPMKIDCache; diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index 02f9eb83680f..3724e1e67ec2 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c @@ -24,7 +24,7 @@ MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION("0.1"); -static const struct usb_device_id wb35_table[] = { +static const struct usb_device_id wb35_table[] __devinitconst = { { USB_DEVICE(0x0416, 0x0035) }, { USB_DEVICE(0x18E8, 0x6201) }, { USB_DEVICE(0x18E8, 0x6206) }, diff --git a/drivers/switch/Kconfig b/drivers/switch/Kconfig deleted file mode 100644 index 52385914b9ae..000000000000 --- a/drivers/switch/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -menuconfig SWITCH - tristate "Switch class support" - help - Say Y here to enable switch class support. This allows - monitoring switches by userspace via sysfs and uevent. - -if SWITCH - -config SWITCH_GPIO - tristate "GPIO Swith support" - depends on GENERIC_GPIO - help - Say Y here to enable GPIO based switch support. - -endif # SWITCH diff --git a/drivers/switch/Makefile b/drivers/switch/Makefile deleted file mode 100644 index f7606ed4a719..000000000000 --- a/drivers/switch/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# Switch Class Driver -obj-$(CONFIG_SWITCH) += switch_class.o -obj-$(CONFIG_SWITCH_GPIO) += switch_gpio.o - diff --git a/drivers/switch/switch_class.c b/drivers/switch/switch_class.c deleted file mode 100644 index cd2456a3cbd8..000000000000 --- a/drivers/switch/switch_class.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * drivers/switch/switch_class.c - * - * Copyright (C) 2008 Google, Inc. - * Author: Mike Lockwood - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -struct class *switch_class; -static atomic_t device_count; - -static ssize_t state_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct switch_dev *sdev = (struct switch_dev *) - dev_get_drvdata(dev); - - if (sdev->print_state) { - int ret = sdev->print_state(sdev, buf); - if (ret >= 0) - return ret; - } - return sprintf(buf, "%d\n", sdev->state); -} - -static ssize_t name_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct switch_dev *sdev = (struct switch_dev *) - dev_get_drvdata(dev); - - if (sdev->print_name) { - int ret = sdev->print_name(sdev, buf); - if (ret >= 0) - return ret; - } - return sprintf(buf, "%s\n", sdev->name); -} - -static DEVICE_ATTR(state, S_IRUGO | S_IWUSR, state_show, NULL); -static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, name_show, NULL); - -void switch_set_state(struct switch_dev *sdev, int state) -{ - char name_buf[120]; - char state_buf[120]; - char timestamp_buf[120]; - char *prop_buf; - char *envp[4]; - int env_offset = 0; - int length; - - if (sdev->state != state) { - sdev->state = state; - - prop_buf = (char *)get_zeroed_page(GFP_KERNEL); - if (prop_buf) { - length = name_show(sdev->dev, NULL, prop_buf); - if (length > 0) { - if (prop_buf[length - 1] == '\n') - prop_buf[length - 1] = 0; - snprintf(name_buf, sizeof(name_buf), - "SWITCH_NAME=%s", prop_buf); - envp[env_offset++] = name_buf; - } - length = state_show(sdev->dev, NULL, prop_buf); - if (length > 0) { - if (prop_buf[length - 1] == '\n') - prop_buf[length - 1] = 0; - snprintf(state_buf, sizeof(state_buf), - "SWITCH_STATE=%s", prop_buf); - envp[env_offset++] = state_buf; - } - snprintf(timestamp_buf, sizeof(timestamp_buf), - "SWITCH_TIME=%llu", ktime_to_ns(ktime_get())); - envp[env_offset++] = timestamp_buf; - envp[env_offset] = NULL; - kobject_uevent_env(&sdev->dev->kobj, KOBJ_CHANGE, envp); - free_page((unsigned long)prop_buf); - } else { - printk(KERN_ERR "out of memory in switch_set_state\n"); - kobject_uevent(&sdev->dev->kobj, KOBJ_CHANGE); - } - } -} -EXPORT_SYMBOL_GPL(switch_set_state); - -static int create_switch_class(void) -{ - if (!switch_class) { - switch_class = class_create(THIS_MODULE, "switch"); - if (IS_ERR(switch_class)) - return PTR_ERR(switch_class); - atomic_set(&device_count, 0); - } - - return 0; -} - -int switch_dev_register(struct switch_dev *sdev) -{ - int ret; - - if (!switch_class) { - ret = create_switch_class(); - if (ret < 0) - return ret; - } - - sdev->index = atomic_inc_return(&device_count); - sdev->dev = device_create(switch_class, NULL, - MKDEV(0, sdev->index), NULL, sdev->name); - if (IS_ERR(sdev->dev)) - return PTR_ERR(sdev->dev); - - ret = device_create_file(sdev->dev, &dev_attr_state); - if (ret < 0) - goto err_create_file_1; - ret = device_create_file(sdev->dev, &dev_attr_name); - if (ret < 0) - goto err_create_file_2; - - dev_set_drvdata(sdev->dev, sdev); - sdev->state = 0; - return 0; - -err_create_file_2: - device_remove_file(sdev->dev, &dev_attr_state); -err_create_file_1: - device_destroy(switch_class, MKDEV(0, sdev->index)); - printk(KERN_ERR "switch: Failed to register driver %s\n", sdev->name); - - return ret; -} -EXPORT_SYMBOL_GPL(switch_dev_register); - -void switch_dev_unregister(struct switch_dev *sdev) -{ - device_remove_file(sdev->dev, &dev_attr_name); - device_remove_file(sdev->dev, &dev_attr_state); - device_destroy(switch_class, MKDEV(0, sdev->index)); - dev_set_drvdata(sdev->dev, NULL); -} -EXPORT_SYMBOL_GPL(switch_dev_unregister); - -static int __init switch_class_init(void) -{ - return create_switch_class(); -} - -static void __exit switch_class_exit(void) -{ - class_destroy(switch_class); -} - -module_init(switch_class_init); -module_exit(switch_class_exit); - -MODULE_AUTHOR("Mike Lockwood "); -MODULE_DESCRIPTION("Switch class driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/switch/switch_gpio.c b/drivers/switch/switch_gpio.c deleted file mode 100644 index 7e9faa211e48..000000000000 --- a/drivers/switch/switch_gpio.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * drivers/switch/switch_gpio.c - * - * Copyright (C) 2008 Google, Inc. - * Author: Mike Lockwood - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct gpio_switch_data { - struct switch_dev sdev; - unsigned gpio; - const char *name_on; - const char *name_off; - const char *state_on; - const char *state_off; - int irq; - struct work_struct work; -}; - -static void gpio_switch_work(struct work_struct *work) -{ - int state; - struct gpio_switch_data *data = - container_of(work, struct gpio_switch_data, work); - - state = gpio_get_value(data->gpio); - switch_set_state(&data->sdev, state); -} - -static irqreturn_t gpio_irq_handler(int irq, void *dev_id) -{ - struct gpio_switch_data *switch_data = - (struct gpio_switch_data *)dev_id; - - schedule_work(&switch_data->work); - return IRQ_HANDLED; -} - -static ssize_t switch_gpio_print_state(struct switch_dev *sdev, char *buf) -{ - struct gpio_switch_data *switch_data = - container_of(sdev, struct gpio_switch_data, sdev); - const char *state; - if (switch_get_state(sdev)) - state = switch_data->state_on; - else - state = switch_data->state_off; - - if (state) - return sprintf(buf, "%s\n", state); - return -1; -} - -static int gpio_switch_probe(struct platform_device *pdev) -{ - struct gpio_switch_platform_data *pdata = pdev->dev.platform_data; - struct gpio_switch_data *switch_data; - int ret = 0; - - if (!pdata) - return -EBUSY; - - switch_data = kzalloc(sizeof(struct gpio_switch_data), GFP_KERNEL); - if (!switch_data) - return -ENOMEM; - - switch_data->sdev.name = pdata->name; - switch_data->gpio = pdata->gpio; - switch_data->name_on = pdata->name_on; - switch_data->name_off = pdata->name_off; - switch_data->state_on = pdata->state_on; - switch_data->state_off = pdata->state_off; - switch_data->sdev.print_state = switch_gpio_print_state; - - ret = switch_dev_register(&switch_data->sdev); - if (ret < 0) - goto err_switch_dev_register; - - ret = gpio_request(switch_data->gpio, pdev->name); - if (ret < 0) - goto err_request_gpio; - - ret = gpio_direction_input(switch_data->gpio); - if (ret < 0) - goto err_set_gpio_input; - - INIT_WORK(&switch_data->work, gpio_switch_work); - - switch_data->irq = gpio_to_irq(switch_data->gpio); - if (switch_data->irq < 0) { - ret = switch_data->irq; - goto err_detect_irq_num_failed; - } - - ret = request_irq(switch_data->irq, gpio_irq_handler, - IRQF_TRIGGER_LOW, pdev->name, switch_data); - if (ret < 0) - goto err_request_irq; - - /* Perform initial detection */ - gpio_switch_work(&switch_data->work); - - return 0; - -err_request_irq: -err_detect_irq_num_failed: -err_set_gpio_input: - gpio_free(switch_data->gpio); -err_request_gpio: - switch_dev_unregister(&switch_data->sdev); -err_switch_dev_register: - kfree(switch_data); - - return ret; -} - -static int __devexit gpio_switch_remove(struct platform_device *pdev) -{ - struct gpio_switch_data *switch_data = platform_get_drvdata(pdev); - - cancel_work_sync(&switch_data->work); - gpio_free(switch_data->gpio); - switch_dev_unregister(&switch_data->sdev); - kfree(switch_data); - - return 0; -} - -static struct platform_driver gpio_switch_driver = { - .probe = gpio_switch_probe, - .remove = __devexit_p(gpio_switch_remove), - .driver = { - .name = "switch-gpio", - .owner = THIS_MODULE, - }, -}; - -static int __init gpio_switch_init(void) -{ - return platform_driver_register(&gpio_switch_driver); -} - -static void __exit gpio_switch_exit(void) -{ - platform_driver_unregister(&gpio_switch_driver); -} - -module_init(gpio_switch_init); -module_exit(gpio_switch_exit); - -MODULE_AUTHOR("Mike Lockwood "); -MODULE_DESCRIPTION("GPIO Switch driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index f7c3cfbbabac..70c2e7fa6664 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -127,24 +127,6 @@ static struct se_cmd *tcm_loop_allocate_core_cmd( set_host_byte(sc, DID_NO_CONNECT); return NULL; } - /* - * Because some userspace code via scsi-generic do not memset their - * associated read buffers, go ahead and do that here for type - * SCF_SCSI_CONTROL_SG_IO_CDB. Also note that this is currently - * guaranteed to be a single SGL for SCF_SCSI_CONTROL_SG_IO_CDB - * by target core in transport_generic_allocate_tasks() -> - * transport_generic_cmd_sequencer(). - */ - if (se_cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB && - se_cmd->data_direction == DMA_FROM_DEVICE) { - struct scatterlist *sg = scsi_sglist(sc); - unsigned char *buf = kmap(sg_page(sg)) + sg->offset; - - if (buf != NULL) { - memset(buf, 0, sg->length); - kunmap(sg_page(sg)); - } - } transport_device_setup_cmd(se_cmd); return se_cmd; @@ -905,9 +887,6 @@ static int tcm_loop_queue_data_in(struct se_cmd *se_cmd) sc->result = SAM_STAT_GOOD; set_host_byte(sc, DID_OK); - if ((se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) || - (se_cmd->se_cmd_flags & SCF_UNDERFLOW_BIT)) - scsi_set_resid(sc, se_cmd->residual_count); sc->scsi_done(sc); return 0; } @@ -933,9 +912,6 @@ static int tcm_loop_queue_status(struct se_cmd *se_cmd) sc->result = se_cmd->scsi_status; set_host_byte(sc, DID_OK); - if ((se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) || - (se_cmd->se_cmd_flags & SCF_UNDERFLOW_BIT)) - scsi_set_resid(sc, se_cmd->residual_count); sc->scsi_done(sc); return 0; } diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index c9674059213e..47abb42d9c36 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -61,30 +60,10 @@ int core_emulate_report_target_port_groups(struct se_cmd *cmd) unsigned char *buf = (unsigned char *)T_TASK(cmd)->t_task_buf; u32 rd_len = 0, off = 4; /* Skip over RESERVED area to first Target port group descriptor */ - /* - * Need at least 4 bytes of response data or else we can't - * even fit the return data length. - */ - if (cmd->data_length < 4) { - pr_warn("REPORT TARGET PORT GROUPS allocation length %u" - " too small\n", cmd->data_length); - return -EINVAL; - } spin_lock(&T10_ALUA(su_dev)->tg_pt_gps_lock); list_for_each_entry(tg_pt_gp, &T10_ALUA(su_dev)->tg_pt_gps_list, tg_pt_gp_list) { - /* - * Check if the Target port group and Target port descriptor list - * based on tg_pt_gp_members count will fit into the response payload. - * Otherwise, bump rd_len to let the initiator know we have exceeded - * the allocation length and the response is truncated. - */ - if ((off + 8 + (tg_pt_gp->tg_pt_gp_members * 4)) > - cmd->data_length) { - rd_len += 8 + (tg_pt_gp->tg_pt_gp_members * 4); - continue; - } /* * PREF: Preferred target port bit, determine if this * bit should be set for port group. @@ -239,7 +218,8 @@ int core_emulate_set_target_port_groups(struct se_cmd *cmd) * changed. */ if (primary) { - tg_pt_id = get_unaligned_be16(ptr + 2); + tg_pt_id = ((ptr[2] << 8) & 0xff); + tg_pt_id |= (ptr[3] & 0xff); /* * Locate the matching target port group ID from * the global tg_pt_gp list @@ -280,7 +260,8 @@ int core_emulate_set_target_port_groups(struct se_cmd *cmd) * the Target Port in question for the the incoming * SET_TARGET_PORT_GROUPS op. */ - rtpi = get_unaligned_be16(ptr + 2); + rtpi = ((ptr[2] << 8) & 0xff); + rtpi |= (ptr[3] & 0xff); /* * Locate the matching relative target port identifer * for the struct se_device storage object. diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c index 05584010e70e..7f19c8b7b84c 100644 --- a/drivers/target/target_core_cdb.c +++ b/drivers/target/target_core_cdb.c @@ -83,18 +83,6 @@ target_emulate_inquiry_std(struct se_cmd *cmd) buf[1] = 0x80; buf[2] = dev->transport->get_device_rev(dev); - /* - * NORMACA and HISUP = 0, RESPONSE DATA FORMAT = 2 - * - * SPC4 says: - * A RESPONSE DATA FORMAT field set to 2h indicates that the - * standard INQUIRY data is in the format defined in this - * standard. Response data format values less than 2h are - * obsolete. Response data format values greater than 2h are - * reserved. - */ - buf[3] = 2; - /* * Enable SCCS and TPGS fields for Emulated ALUA */ @@ -106,7 +94,7 @@ target_emulate_inquiry_std(struct se_cmd *cmd) return 0; } - buf[7] = 0x2; /* CmdQue=1 */ + buf[7] = 0x32; /* Sync=1 and CmdQue=1 */ /* * Do not include vendor, product, reversion info in INQUIRY diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 26f4d5b2cbe4..25c1f49a7d8b 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -3234,8 +3234,7 @@ static int __init target_core_init_configfs(void) if (ret < 0) goto out; - ret = core_dev_setup_virtual_lun0(); - if (ret < 0) + if (core_dev_setup_virtual_lun0() < 0) goto out; return 0; diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 98e12d31c9c2..b662db3a320b 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -471,7 +471,6 @@ static int core_scsi3_pr_seq_non_holder( case READ_MEDIA_SERIAL_NUMBER: case REPORT_LUNS: case REQUEST_SENSE: - case PERSISTENT_RESERVE_IN: ret = 0; /*/ Allowed CDBs */ break; default: @@ -3080,7 +3079,7 @@ static int core_scsi3_pro_preempt( if (!(calling_it_nexus)) core_scsi3_ua_allocate(pr_reg_nacl, pr_res_mapped_lun, 0x2A, - ASCQ_2AH_REGISTRATIONS_PREEMPTED); + ASCQ_2AH_RESERVATIONS_PREEMPTED); } spin_unlock(&pr_tmpl->registration_lock); /* @@ -3192,7 +3191,7 @@ static int core_scsi3_pro_preempt( * additional sense code set to REGISTRATIONS PREEMPTED; */ core_scsi3_ua_allocate(pr_reg_nacl, pr_res_mapped_lun, 0x2A, - ASCQ_2AH_REGISTRATIONS_PREEMPTED); + ASCQ_2AH_RESERVATIONS_PREEMPTED); } spin_unlock(&pr_tmpl->registration_lock); /* diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 910c8b0cd731..4b9b7169bdd9 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -2777,15 +2777,10 @@ static inline u32 transport_get_sectors_6( /* * Everything else assume TYPE_DISK Sector CDB location. - * Use 8-bit sector value. SBC-3 says: - * - * A TRANSFER LENGTH field set to zero specifies that 256 - * logical blocks shall be written. Any other value - * specifies the number of logical blocks that shall be - * written. + * Use 8-bit sector value. */ type_disk: - return cdb[4] ? : 256; + return (u32)cdb[4]; } static inline u32 transport_get_sectors_10( @@ -3672,20 +3667,15 @@ static int transport_generic_cmd_sequencer( /* Returns CHECK_CONDITION + INVALID_CDB_FIELD */ goto out_invalid_cdb_field; } - /* - * For the overflow case keep the existing fabric provided - * ->data_length. Otherwise for the underflow case, reset - * ->data_length to the smaller SCSI expected data transfer - * length. - */ + if (size > cmd->data_length) { cmd->se_cmd_flags |= SCF_OVERFLOW_BIT; cmd->residual_count = (size - cmd->data_length); } else { cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; cmd->residual_count = (cmd->data_length - size); - cmd->data_length = size; } + cmd->data_length = size; } transport_set_supported_SAM_opcode(cmd); @@ -5673,8 +5663,6 @@ int transport_send_check_condition_and_sense( case TCM_SECTOR_COUNT_TOO_MANY: /* CURRENT ERROR */ buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ILLEGAL REQUEST */ buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; /* INVALID COMMAND OPERATION CODE */ @@ -5683,7 +5671,6 @@ int transport_send_check_condition_and_sense( case TCM_UNKNOWN_MODE_PAGE: /* CURRENT ERROR */ buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ILLEGAL REQUEST */ buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; /* INVALID FIELD IN CDB */ @@ -5692,7 +5679,6 @@ int transport_send_check_condition_and_sense( case TCM_CHECK_CONDITION_ABORT_CMD: /* CURRENT ERROR */ buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ABORTED COMMAND */ buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; /* BUS DEVICE RESET FUNCTION OCCURRED */ @@ -5702,7 +5688,6 @@ int transport_send_check_condition_and_sense( case TCM_INCORRECT_AMOUNT_OF_DATA: /* CURRENT ERROR */ buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ABORTED COMMAND */ buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; /* WRITE ERROR */ @@ -5713,25 +5698,22 @@ int transport_send_check_condition_and_sense( case TCM_INVALID_CDB_FIELD: /* CURRENT ERROR */ buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; - /* ILLEGAL REQUEST */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; + /* ABORTED COMMAND */ + buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; /* INVALID FIELD IN CDB */ buffer[offset+SPC_ASC_KEY_OFFSET] = 0x24; break; case TCM_INVALID_PARAMETER_LIST: /* CURRENT ERROR */ buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; - /* ILLEGAL REQUEST */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; + /* ABORTED COMMAND */ + buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; /* INVALID FIELD IN PARAMETER LIST */ buffer[offset+SPC_ASC_KEY_OFFSET] = 0x26; break; case TCM_UNEXPECTED_UNSOLICITED_DATA: /* CURRENT ERROR */ buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ABORTED COMMAND */ buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; /* WRITE ERROR */ @@ -5742,7 +5724,6 @@ int transport_send_check_condition_and_sense( case TCM_SERVICE_CRC_ERROR: /* CURRENT ERROR */ buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ABORTED COMMAND */ buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; /* PROTOCOL SERVICE CRC ERROR */ @@ -5753,7 +5734,6 @@ int transport_send_check_condition_and_sense( case TCM_SNACK_REJECTED: /* CURRENT ERROR */ buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ABORTED COMMAND */ buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; /* READ ERROR */ @@ -5764,7 +5744,6 @@ int transport_send_check_condition_and_sense( case TCM_WRITE_PROTECTED: /* CURRENT ERROR */ buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; /* DATA PROTECT */ buffer[offset+SPC_SENSE_KEY_OFFSET] = DATA_PROTECT; /* WRITE PROTECTED */ @@ -5773,7 +5752,6 @@ int transport_send_check_condition_and_sense( case TCM_CHECK_CONDITION_UNIT_ATTENTION: /* CURRENT ERROR */ buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; /* UNIT ATTENTION */ buffer[offset+SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; core_scsi3_ua_for_check_condition(cmd, &asc, &ascq); @@ -5783,7 +5761,6 @@ int transport_send_check_condition_and_sense( case TCM_CHECK_CONDITION_NOT_READY: /* CURRENT ERROR */ buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; /* Not Ready */ buffer[offset+SPC_SENSE_KEY_OFFSET] = NOT_READY; transport_get_sense_codes(cmd, &asc, &ascq); @@ -5794,7 +5771,6 @@ int transport_send_check_condition_and_sense( default: /* CURRENT ERROR */ buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ILLEGAL REQUEST */ buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; /* LOGICAL UNIT COMMUNICATION FAILURE */ diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index 3c3fa84e9eff..b2a106729d49 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c @@ -371,12 +371,10 @@ static void ft_send_resp_status(struct fc_lport *lport, fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_DD_CMD_STATUS, 0); sp = fr_seq(fp); - if (sp) { + if (sp) lport->tt.seq_send(lport, sp, fp); - lport->tt.exch_done(sp); - } else { + else lport->tt.frame_send(lport, fp); - } } /* diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c index 9a084b8d1975..7491e21cc6ae 100644 --- a/drivers/target/tcm_fc/tfc_sess.c +++ b/drivers/target/tcm_fc/tfc_sess.c @@ -64,8 +64,7 @@ static struct ft_tport *ft_tport_create(struct fc_lport *lport) struct ft_tport *tport; int i; - tport = rcu_dereference_protected(lport->prov[FC_TYPE_FCP], - lockdep_is_held(&ft_lport_lock)); + tport = rcu_dereference(lport->prov[FC_TYPE_FCP]); if (tport && tport->tpg) return tport; @@ -393,11 +392,11 @@ static int ft_prli_locked(struct fc_rport_priv *rdata, u32 spp_len, tport = ft_tport_create(rdata->local_port); if (!tport) - goto not_target; /* not a target for this local port */ + return 0; /* not a target for this local port */ acl = ft_acl_get(tport->tpg, rdata); if (!acl) - goto not_target; /* no target for this remote */ + return 0; if (!rspp) goto fill; @@ -434,18 +433,12 @@ static int ft_prli_locked(struct fc_rport_priv *rdata, u32 spp_len, /* * OR in our service parameters with other provider (initiator), if any. + * TBD XXX - indicate RETRY capability? */ fill: fcp_parm = ntohl(spp->spp_params); - fcp_parm &= ~FCP_SPPF_RETRY; spp->spp_params = htonl(fcp_parm | FCP_SPPF_TARG_FCN); return FC_SPP_RESP_ACK; - -not_target: - fcp_parm = ntohl(spp->spp_params); - fcp_parm &= ~FCP_SPPF_TARG_FCN; - spp->spp_params = htonl(fcp_parm); - return 0; } /** @@ -474,6 +467,7 @@ static void ft_sess_rcu_free(struct rcu_head *rcu) { struct ft_sess *sess = container_of(rcu, struct ft_sess, rcu); + transport_deregister_session(sess->se_sess); kfree(sess); } @@ -481,7 +475,6 @@ static void ft_sess_free(struct kref *kref) { struct ft_sess *sess = container_of(kref, struct ft_sess, kref); - transport_deregister_session(sess->se_sess); call_rcu(&sess->rcu, ft_sess_rcu_free); } diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c index e1abb45c3cfe..d5f923bcdffe 100644 --- a/drivers/telephony/ixj.c +++ b/drivers/telephony/ixj.c @@ -3190,12 +3190,12 @@ static void ixj_write_cid(IXJ *j) ixj_fsk_alloc(j); - strlcpy(sdmf1, j->cid_send.month, sizeof(sdmf1)); - strlcat(sdmf1, j->cid_send.day, sizeof(sdmf1)); - strlcat(sdmf1, j->cid_send.hour, sizeof(sdmf1)); - strlcat(sdmf1, j->cid_send.min, sizeof(sdmf1)); - strlcpy(sdmf2, j->cid_send.number, sizeof(sdmf2)); - strlcpy(sdmf3, j->cid_send.name, sizeof(sdmf3)); + strcpy(sdmf1, j->cid_send.month); + strcat(sdmf1, j->cid_send.day); + strcat(sdmf1, j->cid_send.hour); + strcat(sdmf1, j->cid_send.min); + strcpy(sdmf2, j->cid_send.number); + strcpy(sdmf3, j->cid_send.name); len1 = strlen(sdmf1); len2 = strlen(sdmf2); @@ -3340,12 +3340,12 @@ static void ixj_write_cidcw(IXJ *j) ixj_pre_cid(j); } j->flags.cidcw_ack = 0; - strlcpy(sdmf1, j->cid_send.month, sizeof(sdmf1)); - strlcat(sdmf1, j->cid_send.day, sizeof(sdmf1)); - strlcat(sdmf1, j->cid_send.hour, sizeof(sdmf1)); - strlcat(sdmf1, j->cid_send.min, sizeof(sdmf1)); - strlcpy(sdmf2, j->cid_send.number, sizeof(sdmf2)); - strlcpy(sdmf3, j->cid_send.name, sizeof(sdmf3)); + strcpy(sdmf1, j->cid_send.month); + strcat(sdmf1, j->cid_send.day); + strcat(sdmf1, j->cid_send.hour); + strcat(sdmf1, j->cid_send.min); + strcpy(sdmf2, j->cid_send.number); + strcpy(sdmf3, j->cid_send.name); len1 = strlen(sdmf1); len2 = strlen(sdmf2); diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 34111486baac..220579592c20 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -1113,10 +1113,8 @@ static int set_serial_info(struct async_struct * info, (new_serial.close_delay != state->close_delay) || (new_serial.xmit_fifo_size != state->xmit_fifo_size) || ((new_serial.flags & ~ASYNC_USR_MASK) != - (state->flags & ~ASYNC_USR_MASK))) { - tty_unlock(); + (state->flags & ~ASYNC_USR_MASK))) return -EPERM; - } state->flags = ((state->flags & ~ASYNC_USR_MASK) | (new_serial.flags & ASYNC_USR_MASK)); info->flags = ((info->flags & ~ASYNC_USR_MASK) | diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index aa84555048ba..e9cba13ee800 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -163,10 +163,8 @@ static void hvc_console_print(struct console *co, const char *b, } else { r = cons_ops[index]->put_chars(vtermnos[index], c, i); if (r <= 0) { - /* throw away characters on error - * but spin in case of -EAGAIN */ - if (r != -EAGAIN) - i = 0; + /* throw away chars on error */ + i = 0; } else if (r > 0) { i -= r; if (i > 0) @@ -450,7 +448,7 @@ static int hvc_push(struct hvc_struct *hp) n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf); if (n <= 0) { - if (n == 0 || n == -EAGAIN) { + if (n == 0) { hp->do_wakeup = 1; return 0; } diff --git a/drivers/tty/hvc/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c index 44fbebab5075..435f6facbc23 100644 --- a/drivers/tty/hvc/hvc_dcc.c +++ b/drivers/tty/hvc/hvc_dcc.c @@ -46,7 +46,6 @@ static inline char __dcc_getchar(void) asm volatile("mrc p14, 0, %0, c0, c5, 0 @ read comms data reg" : "=r" (__c)); - isb(); return __c; } @@ -56,7 +55,6 @@ static inline void __dcc_putchar(char c) asm volatile("mcr p14, 0, %0, c0, c5, 0 @ write a char" : /* no output register */ : "r" (c)); - isb(); } static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count) diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 8f82f7ab3541..ba679ce0a774 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c @@ -1330,7 +1330,7 @@ static void moxa_start(struct tty_struct *tty) if (ch == NULL) return; - if (!test_bit(TXSTOPPED, &ch->statusflags)) + if (!(ch->statusflags & TXSTOPPED)) return; MoxaPortTxEnable(ch); diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index fee6bedee8a2..19b4ae052af8 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -842,7 +842,7 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, /* dlci->skb is locked by tx_lock */ if (dlci->skb == NULL) { - dlci->skb = skb_dequeue_tail(&dlci->skb_list); + dlci->skb = skb_dequeue(&dlci->skb_list); if (dlci->skb == NULL) return 0; first = 1; @@ -866,11 +866,8 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, /* FIXME: need a timer or something to kick this so it can't get stuck with no work outstanding and no buffer free */ - if (msg == NULL) { - skb_queue_tail(&dlci->skb_list, dlci->skb); - dlci->skb = NULL; + if (msg == NULL) return -ENOMEM; - } dp = msg->data; if (dlci->adaption == 4) { /* Interruptible framed (Packetised Data) */ @@ -1155,8 +1152,6 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command, u8 *data, int clen) { u8 buf[1]; - unsigned long flags; - switch (command) { case CMD_CLD: { struct gsm_dlci *dlci = gsm->dlci[0]; @@ -1182,9 +1177,7 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command, gsm->constipated = 0; gsm_control_reply(gsm, CMD_FCOFF, NULL, 0); /* Kick the link in case it is idling */ - spin_lock_irqsave(&gsm->tx_lock, flags); gsm_data_kick(gsm); - spin_unlock_irqrestore(&gsm->tx_lock, flags); break; case CMD_MSC: /* Out of band modem line change indicator for a DLCI */ @@ -1830,6 +1823,10 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c) break; case GSM_FCS: /* FCS follows the packet */ gsm->received_fcs = c; + if (c == GSM0_SOF) { + gsm->state = GSM_SEARCH; + break; + } gsm_queue(gsm); gsm->state = GSM_SSOF; break; @@ -2276,12 +2273,12 @@ static void gsmld_write_wakeup(struct tty_struct *tty) /* Queue poll */ clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); - spin_lock_irqsave(&gsm->tx_lock, flags); gsm_data_kick(gsm); if (gsm->tx_bytes < TX_THRESH_LO) { + spin_lock_irqsave(&gsm->tx_lock, flags); gsm_dlci_data_sweep(gsm); + spin_unlock_irqrestore(&gsm->tx_lock, flags); } - spin_unlock_irqrestore(&gsm->tx_lock, flags); } /** diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index d7164bfe8225..c3954fbf6ac4 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1728,8 +1728,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, do_it_again: - if (WARN_ON(!tty->read_buf)) - return -EAGAIN; + BUG_ON(!tty->read_buf); c = job_control(tty, file); if (c < 0) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index e18604b3fc7d..98b6e3bdb000 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -446,19 +446,8 @@ static inline void legacy_pty_init(void) { } int pty_limit = NR_UNIX98_PTY_DEFAULT; static int pty_limit_min; static int pty_limit_max = NR_UNIX98_PTY_MAX; -static int tty_count; static int pty_count; -static inline void pty_inc_count(void) -{ - pty_count = (++tty_count) / 2; -} - -static inline void pty_dec_count(void) -{ - pty_count = (--tty_count) / 2; -} - static struct cdev ptmx_cdev; static struct ctl_table pty_table[] = { @@ -553,7 +542,6 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, static void pty_unix98_shutdown(struct tty_struct *tty) { - tty_driver_remove_tty(tty->driver, tty); /* We have our own method as we don't use the tty index */ kfree(tty->termios); } @@ -600,8 +588,7 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) */ tty_driver_kref_get(driver); tty->count++; - pty_inc_count(); /* tty */ - pty_inc_count(); /* tty->link */ + pty_count++; return 0; err_free_mem: deinitialize_tty_struct(o_tty); @@ -615,7 +602,7 @@ err_free_tty: static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) { - pty_dec_count(); + pty_count--; } static const struct tty_operations ptm_unix98_ops = { @@ -670,18 +657,12 @@ static int ptmx_open(struct inode *inode, struct file *filp) nonseekable_open(inode, filp); - retval = tty_alloc_file(filp); - if (retval) - return retval; - /* find a device that is not in use. */ tty_lock(); index = devpts_new_index(inode); tty_unlock(); - if (index < 0) { - retval = index; - goto err_file; - } + if (index < 0) + return index; mutex_lock(&tty_mutex); tty_lock(); @@ -695,27 +676,27 @@ static int ptmx_open(struct inode *inode, struct file *filp) set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ - tty_add_file(tty, filp); + retval = tty_add_file(tty, filp); + if (retval) + goto out; retval = devpts_pty_new(inode, tty->link); if (retval) - goto err_release; + goto out1; retval = ptm_driver->ops->open(tty, filp); if (retval) - goto err_release; - + goto out2; +out1: tty_unlock(); - return 0; -err_release: + return retval; +out2: tty_unlock(); tty_release(inode, filp); return retval; out: devpts_kill_index(inode, index); tty_unlock(); -err_file: - tty_free_file(filp); return retval; } diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index 7f50999eebc2..b4129f53fb1b 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c @@ -81,7 +81,7 @@ static unsigned int skip_txen_test; /* force skip of txen test at init time */ #define DEBUG_INTR(fmt...) do { } while (0) #endif -#define PASS_LIMIT 512 +#define PASS_LIMIT 256 #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) @@ -1107,7 +1107,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) */ DEBUG_AUTOCONF("Xscale "); up->port.type = PORT_XSCALE; - up->capabilities |= UART_CAP_UUE | UART_CAP_RTOIE; + up->capabilities |= UART_CAP_UUE; return; } } else { @@ -1819,8 +1819,6 @@ static void serial8250_backup_timeout(unsigned long data) unsigned int iir, ier = 0, lsr; unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); - /* * Must disable interrupts or else we risk racing with the interrupt * based handler. @@ -1838,8 +1836,10 @@ static void serial8250_backup_timeout(unsigned long data) * the "Diva" UART used on the management processor on many HP * ia64 and parisc boxes. */ + spin_lock_irqsave(&up->port.lock, flags); lsr = serial_in(up, UART_LSR); up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; + spin_unlock_irqrestore(&up->port.lock, flags); if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) && (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) && (lsr & UART_LSR_THRE)) { @@ -1848,13 +1848,11 @@ static void serial8250_backup_timeout(unsigned long data) } if (!(iir & UART_IIR_NO_INT)) - transmit_chars(up); + serial8250_handle_port(up); if (is_real_interrupt(up->port.irq)) serial_out(up, UART_IER, ier); - spin_unlock_irqrestore(&up->port.lock, flags); - /* Standard timer interval plus 0.2s to keep the port running */ mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port) + HZ / 5); diff --git a/drivers/tty/serial/8250_pci.c b/drivers/tty/serial/8250_pci.c index 3411ed35f1d7..f41b4259ecdd 100644 --- a/drivers/tty/serial/8250_pci.c +++ b/drivers/tty/serial/8250_pci.c @@ -1011,8 +1011,6 @@ static int pci_eg20t_init(struct pci_dev *dev) #define PCI_SUBDEVICE_ID_OCTPRO422 0x0208 #define PCI_SUBDEVICE_ID_POCTAL232 0x0308 #define PCI_SUBDEVICE_ID_POCTAL422 0x0408 -#define PCI_SUBDEVICE_ID_SIIG_DUAL_00 0x2500 -#define PCI_SUBDEVICE_ID_SIIG_DUAL_30 0x2530 #define PCI_VENDOR_ID_ADVANTECH 0x13fe #define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66 #define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620 @@ -1461,61 +1459,51 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .vendor = PCI_VENDOR_ID_INTEL, .device = 0x8811, .init = pci_eg20t_init, - .setup = pci_default_setup, }, { .vendor = PCI_VENDOR_ID_INTEL, .device = 0x8812, .init = pci_eg20t_init, - .setup = pci_default_setup, }, { .vendor = PCI_VENDOR_ID_INTEL, .device = 0x8813, .init = pci_eg20t_init, - .setup = pci_default_setup, }, { .vendor = PCI_VENDOR_ID_INTEL, .device = 0x8814, .init = pci_eg20t_init, - .setup = pci_default_setup, }, { .vendor = 0x10DB, .device = 0x8027, .init = pci_eg20t_init, - .setup = pci_default_setup, }, { .vendor = 0x10DB, .device = 0x8028, .init = pci_eg20t_init, - .setup = pci_default_setup, }, { .vendor = 0x10DB, .device = 0x8029, .init = pci_eg20t_init, - .setup = pci_default_setup, }, { .vendor = 0x10DB, .device = 0x800C, .init = pci_eg20t_init, - .setup = pci_default_setup, }, { .vendor = 0x10DB, .device = 0x800D, .init = pci_eg20t_init, - .setup = pci_default_setup, }, { .vendor = 0x10DB, .device = 0x800D, .init = pci_eg20t_init, - .setup = pci_default_setup, }, /* * Cronyx Omega PCI (PLX-chip based) @@ -3011,11 +2999,8 @@ static struct pci_device_id serial_pci_tbl[] = { * For now just used the hex ID 0x950a. */ { PCI_VENDOR_ID_OXSEMI, 0x950a, - PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_00, - 0, 0, pbn_b0_2_115200 }, - { PCI_VENDOR_ID_OXSEMI, 0x950a, - PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_30, - 0, 0, pbn_b0_2_115200 }, + PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_SERIAL, 0, 0, + pbn_b0_2_115200 }, { PCI_VENDOR_ID_OXSEMI, 0x950a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_2_1130000 }, @@ -3901,17 +3886,13 @@ static struct pci_device_id serial_pci_tbl[] = { 0, 0, pbn_b0_1_115200 }, /* - * Best Connectivity and Rosewill PCI Multi I/O cards + * Best Connectivity PCI Multi I/O cards */ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, 0xA000, 0x1000, 0, 0, pbn_b0_1_115200 }, - { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, - 0xA000, 0x3002, - 0, 0, pbn_b0_bt_2_115200 }, - { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, 0xA000, 0x3004, 0, 0, pbn_b0_bt_4_115200 }, diff --git a/drivers/tty/serial/8250_pnp.c b/drivers/tty/serial/8250_pnp.c index a2f236510ff1..fc301f6722e1 100644 --- a/drivers/tty/serial/8250_pnp.c +++ b/drivers/tty/serial/8250_pnp.c @@ -109,9 +109,6 @@ static const struct pnp_device_id pnp_dev_table[] = { /* IBM */ /* IBM Thinkpad 701 Internal Modem Voice */ { "IBM0033", 0 }, - /* Intermec */ - /* Intermec CV60 touchscreen port */ - { "PNP4972", 0 }, /* Intertex */ /* Intertex 28k8 33k6 Voice EXT PnP */ { "IXDC801", 0 }, diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 9789293a8441..636144cea932 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1419,7 +1419,7 @@ config SERIAL_SC26XX config SERIAL_SC26XX_CONSOLE bool "Console on SC2681/SC2692 serial port" - depends on SERIAL_SC26XX=y + depends on SERIAL_SC26XX select SERIAL_CORE_CONSOLE help Support for Console on SC2681/SC2692 serial ports. @@ -1585,7 +1585,7 @@ config SERIAL_IFX6X60 Support for the IFX6x60 modem devices on Intel MID platforms. config SERIAL_PCH_UART - tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) UART" + tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) UART" depends on PCI select SERIAL_CORE help @@ -1593,12 +1593,12 @@ config SERIAL_PCH_UART which is an IOH(Input/Output Hub) for x86 embedded processor. Enabling PCH_DMA, this PCH UART works as DMA mode. - This driver also can be used for LAPIS Semiconductor IOH(Input/ - Output Hub), ML7213, ML7223 and ML7831. - ML7213 IOH is for IVI(In-Vehicle Infotainment) use, ML7223 IOH is - for MP(Media Phone) use and ML7831 IOH is for general purpose use. - ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series. - ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH. + This driver also can be used for OKI SEMICONDUCTOR IOH(Input/ + Output Hub), ML7213 and ML7223. + ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is + for MP(Media Phone) use. + ML7213/ML7223 is companion chip for Intel Atom E6xx series. + ML7213/ML7223 is completely compatible for Intel EG20T PCH. config SERIAL_MSM_SMD bool "Enable tty device interface for some SMD ports" diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 37db1d5898e0..50bc5a5ac653 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -555,7 +555,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res_mem) port->mapbase = res_mem->start; - else if (platp) + else if (platp->mapbase) port->mapbase = platp->mapbase; else return -EINVAL; @@ -563,7 +563,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res_irq) port->irq = res_irq->start; - else if (platp) + else if (platp->irq) port->irq = platp->irq; /* Check platform data first so we can override device node data */ diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 7cbb3679b804..f5f6831b0a64 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1376,10 +1376,6 @@ static int pl011_startup(struct uart_port *port) uap->port.uartclk = clk_get_rate(uap->clk); - /* Clear pending error and receive interrupts */ - writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS | - UART011_RTIS | UART011_RXIS, uap->port.membase + UART011_ICR); - /* * Allocate the IRQ */ @@ -1414,6 +1410,10 @@ static int pl011_startup(struct uart_port *port) cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; writew(cr, uap->port.membase + UART011_CR); + /* Clear pending error interrupts */ + writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS, + uap->port.membase + UART011_ICR); + /* * initialise the old status of the modem signals */ @@ -1428,9 +1428,6 @@ static int pl011_startup(struct uart_port *port) * as well. */ spin_lock_irq(&uap->port.lock); - /* Clear out any spuriously appearing RX interrupts */ - writew(UART011_RTIS | UART011_RXIS, - uap->port.membase + UART011_ICR); uap->im = UART011_RTIM; if (!pl011_dma_rx_running(uap)) uap->im |= UART011_RXIM; @@ -1620,26 +1617,13 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, old_cr &= ~ST_UART011_CR_OVSFACT; } - /* - * Workaround for the ST Micro oversampling variants to - * increase the bitrate slightly, by lowering the divisor, - * to avoid delayed sampling of start bit at high speeds, - * else we see data corruption. - */ - if (uap->vendor->oversampling) { - if ((baud >= 3000000) && (baud < 3250000) && (quot > 1)) - quot -= 1; - else if ((baud > 3250000) && (quot > 2)) - quot -= 2; - } /* Set baud rate */ writew(quot & 0x3f, port->membase + UART011_FBRD); writew(quot >> 6, port->membase + UART011_IBRD); /* * ----------v----------v----------v----------v----- - * NOTE: lcrh_tx and lcrh_rx MUST BE WRITTEN AFTER - * UART011_FBRD & UART011_IBRD. + * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L * ----------^----------^----------^----------^----- */ writew(lcr_h, port->membase + uap->lcrh_rx); @@ -1749,19 +1733,9 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) { struct uart_amba_port *uap = amba_ports[co->index]; unsigned int status, old_cr, new_cr; - unsigned long flags; - int locked = 1; clk_enable(uap->clk); - local_irq_save(flags); - if (uap->port.sysrq) - locked = 0; - else if (oops_in_progress) - locked = spin_trylock(&uap->port.lock); - else - spin_lock(&uap->port.lock); - /* * First save the CR then disable the interrupts */ @@ -1781,10 +1755,6 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) } while (status & UART01x_FR_BUSY); writew(old_cr, uap->port.membase + UART011_CR); - if (locked) - spin_unlock(&uap->port.lock); - local_irq_restore(flags); - clk_disable(uap->clk); } @@ -1936,10 +1906,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) uap->port.line = i; pl011_dma_probe(uap); - /* Ensure interrupts from this UART are masked and cleared */ - writew(0, uap->port.membase + UART011_IMSC); - writew(0xffff, uap->port.membase + UART011_ICR); - snprintf(uap->type, sizeof(uap->type), "PL011 rev%u", amba_rev(dev)); amba_ports[i] = uap; diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index b989495c763e..af9b7814965a 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -199,9 +199,8 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) { struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); unsigned int mode; - unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + spin_lock(&port->lock); /* Disable interrupts */ UART_PUT_IDR(port, atmel_port->tx_done_mask); @@ -232,7 +231,7 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) /* Enable interrupts */ UART_PUT_IER(port, atmel_port->tx_done_mask); - spin_unlock_irqrestore(&port->lock, flags); + spin_unlock(&port->lock); } diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 836fe2731234..e6c3dbd781d6 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -154,9 +154,10 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) port->x_char = 0; return IRQ_HANDLED; } - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) - goto disable_tx_irq; + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { + clps711xuart_stop_tx(port); + return IRQ_HANDLED; + } count = port->fifosize >> 1; do { @@ -170,11 +171,8 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); - if (uart_circ_empty(xmit)) { - disable_tx_irq: - disable_irq_nosync(TX_IRQ(port)); - tx_enabled(port) = 0; - } + if (uart_circ_empty(xmit)) + clps711xuart_stop_tx(port); return IRQ_HANDLED; } diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index 58be715913cd..225123b37f19 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c @@ -4450,7 +4450,7 @@ static int __init rs_init(void) #if defined(CONFIG_ETRAX_RS485) #if defined(CONFIG_ETRAX_RS485_ON_PA) - if (cris_io_interface_allocate_pins(if_serial_0, 'a', rs485_pa_bit, + if (cris_io_interface_allocate_pins(if_ser0, 'a', rs485_pa_bit, rs485_pa_bit)) { printk(KERN_CRIT "ETRAX100LX serial: Could not allocate " "RS485 pin\n"); @@ -4459,7 +4459,7 @@ static int __init rs_init(void) } #endif #if defined(CONFIG_ETRAX_RS485_ON_PORT_G) - if (cris_io_interface_allocate_pins(if_serial_0, 'g', rs485_pa_bit, + if (cris_io_interface_allocate_pins(if_ser0, 'g', rs485_pa_bit, rs485_port_g_bit)) { printk(KERN_CRIT "ETRAX100LX serial: Could not allocate " "RS485 pin\n"); diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 5d0d4f61cfb5..5315525220fb 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -551,7 +551,6 @@ static void ifx_port_shutdown(struct tty_port *port) container_of(port, struct ifx_spi_device, tty_port); mrdy_set_low(ifx_dev); - del_timer(&ifx_dev->spi_timer); clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags); tasklet_kill(&ifx_dev->io_work_tasklet); } diff --git a/drivers/tty/serial/jsm/jsm.h b/drivers/tty/serial/jsm/jsm.h index 5b837e749c16..b704c8ce0d71 100644 --- a/drivers/tty/serial/jsm/jsm.h +++ b/drivers/tty/serial/jsm/jsm.h @@ -183,8 +183,10 @@ struct jsm_board /* Our Read/Error/Write queue sizes */ #define RQUEUEMASK 0x1FFF /* 8 K - 1 */ #define EQUEUEMASK 0x1FFF /* 8 K - 1 */ +#define WQUEUEMASK 0x0FFF /* 4 K - 1 */ #define RQUEUESIZE (RQUEUEMASK + 1) #define EQUEUESIZE RQUEUESIZE +#define WQUEUESIZE (WQUEUEMASK + 1) /************************************************************************ @@ -224,6 +226,10 @@ struct jsm_channel { u16 ch_e_head; /* Head location of the error queue */ u16 ch_e_tail; /* Tail location of the error queue */ + u8 *ch_wqueue; /* Our write queue buffer - malloc'ed */ + u16 ch_w_head; /* Head location of the write queue */ + u16 ch_w_tail; /* Tail location of the write queue */ + u64 ch_rxcount; /* total of data received so far */ u64 ch_txcount; /* total of data transmitted so far */ @@ -372,6 +378,7 @@ extern int jsm_debug; * Prototypes for non-static functions used in more than one module * *************************************************************************/ +int jsm_tty_write(struct uart_port *port); int jsm_tty_init(struct jsm_board *); int jsm_uart_port_init(struct jsm_board *); int jsm_remove_uart_port(struct jsm_board *); diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c index 6c12d94e6d3f..96da17868cf3 100644 --- a/drivers/tty/serial/jsm/jsm_driver.c +++ b/drivers/tty/serial/jsm/jsm_driver.c @@ -211,6 +211,7 @@ static void __devexit jsm_remove_one(struct pci_dev *pdev) if (brd->channels[i]) { kfree(brd->channels[i]->ch_rqueue); kfree(brd->channels[i]->ch_equeue); + kfree(brd->channels[i]->ch_wqueue); kfree(brd->channels[i]); } } @@ -269,7 +270,6 @@ static void jsm_io_resume(struct pci_dev *pdev) struct jsm_board *brd = pci_get_drvdata(pdev); pci_restore_state(pdev); - pci_save_state(pdev); jsm_uart_port_init(brd); } diff --git a/drivers/tty/serial/jsm/jsm_neo.c b/drivers/tty/serial/jsm/jsm_neo.c index bd6e84699e11..4538c3e3646e 100644 --- a/drivers/tty/serial/jsm/jsm_neo.c +++ b/drivers/tty/serial/jsm/jsm_neo.c @@ -496,15 +496,12 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch) int s; int qlen; u32 len_written = 0; - struct circ_buf *circ; if (!ch) return; - circ = &ch->uart_port.state->xmit; - /* No data to write to the UART */ - if (uart_circ_empty(circ)) + if (ch->ch_w_tail == ch->ch_w_head) return; /* If port is "stopped", don't send any data to the UART */ @@ -520,10 +517,11 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch) if (ch->ch_cached_lsr & UART_LSR_THRE) { ch->ch_cached_lsr &= ~(UART_LSR_THRE); - writeb(circ->buf[circ->tail], &ch->ch_neo_uart->txrx); + writeb(ch->ch_wqueue[ch->ch_w_tail], &ch->ch_neo_uart->txrx); jsm_printk(WRITE, INFO, &ch->ch_bd->pci_dev, - "Tx data: %x\n", circ->buf[circ->head]); - circ->tail = (circ->tail + 1) & (UART_XMIT_SIZE - 1); + "Tx data: %x\n", ch->ch_wqueue[ch->ch_w_head]); + ch->ch_w_tail++; + ch->ch_w_tail &= WQUEUEMASK; ch->ch_txcount++; } return; @@ -538,36 +536,36 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch) n = UART_17158_TX_FIFOSIZE - ch->ch_t_tlevel; /* cache head and tail of queue */ - head = circ->head & (UART_XMIT_SIZE - 1); - tail = circ->tail & (UART_XMIT_SIZE - 1); - qlen = uart_circ_chars_pending(circ); + head = ch->ch_w_head & WQUEUEMASK; + tail = ch->ch_w_tail & WQUEUEMASK; + qlen = (head - tail) & WQUEUEMASK; /* Find minimum of the FIFO space, versus queue length */ n = min(n, qlen); while (n > 0) { - s = ((head >= tail) ? head : UART_XMIT_SIZE) - tail; + s = ((head >= tail) ? head : WQUEUESIZE) - tail; s = min(s, n); if (s <= 0) break; - memcpy_toio(&ch->ch_neo_uart->txrxburst, circ->buf + tail, s); + memcpy_toio(&ch->ch_neo_uart->txrxburst, ch->ch_wqueue + tail, s); /* Add and flip queue if needed */ - tail = (tail + s) & (UART_XMIT_SIZE - 1); + tail = (tail + s) & WQUEUEMASK; n -= s; ch->ch_txcount += s; len_written += s; } /* Update the final tail */ - circ->tail = tail & (UART_XMIT_SIZE - 1); + ch->ch_w_tail = tail & WQUEUEMASK; if (len_written >= ch->ch_t_tlevel) ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); - if (uart_circ_empty(circ)) + if (!jsm_tty_write(&ch->uart_port)) uart_write_wakeup(&ch->uart_port); } @@ -948,6 +946,7 @@ static void neo_param(struct jsm_channel *ch) if ((ch->ch_c_cflag & (CBAUD)) == 0) { ch->ch_r_head = ch->ch_r_tail = 0; ch->ch_e_head = ch->ch_e_tail = 0; + ch->ch_w_head = ch->ch_w_tail = 0; neo_flush_uart_write(ch); neo_flush_uart_read(ch); diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 434bd881fcae..7a4a914ecff0 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c @@ -118,19 +118,6 @@ static void jsm_tty_set_mctrl(struct uart_port *port, unsigned int mctrl) udelay(10); } -/* - * jsm_tty_write() - * - * Take data from the user or kernel and send it out to the FEP. - * In here exists all the Transparent Print magic as well. - */ -static void jsm_tty_write(struct uart_port *port) -{ - struct jsm_channel *channel; - channel = container_of(port, struct jsm_channel, uart_port); - channel->ch_bd->bd_ops->copy_data_from_queue_to_uart(channel); -} - static void jsm_tty_start_tx(struct uart_port *port) { struct jsm_channel *channel = (struct jsm_channel *)port; @@ -229,6 +216,14 @@ static int jsm_tty_open(struct uart_port *port) return -ENOMEM; } } + if (!channel->ch_wqueue) { + channel->ch_wqueue = kzalloc(WQUEUESIZE, GFP_KERNEL); + if (!channel->ch_wqueue) { + jsm_printk(INIT, ERR, &channel->ch_bd->pci_dev, + "unable to allocate write queue buf"); + return -ENOMEM; + } + } channel->ch_flags &= ~(CH_OPENING); /* @@ -242,6 +237,7 @@ static int jsm_tty_open(struct uart_port *port) */ channel->ch_r_head = channel->ch_r_tail = 0; channel->ch_e_head = channel->ch_e_tail = 0; + channel->ch_w_head = channel->ch_w_tail = 0; brd->bd_ops->flush_uart_write(channel); brd->bd_ops->flush_uart_read(channel); @@ -840,3 +836,75 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) } } } + +/* + * jsm_tty_write() + * + * Take data from the user or kernel and send it out to the FEP. + * In here exists all the Transparent Print magic as well. + */ +int jsm_tty_write(struct uart_port *port) +{ + int bufcount; + int data_count = 0,data_count1 =0; + u16 head; + u16 tail; + u16 tmask; + u32 remain; + int temp_tail = port->state->xmit.tail; + struct jsm_channel *channel = (struct jsm_channel *)port; + + tmask = WQUEUEMASK; + head = (channel->ch_w_head) & tmask; + tail = (channel->ch_w_tail) & tmask; + + if ((bufcount = tail - head - 1) < 0) + bufcount += WQUEUESIZE; + + bufcount = min(bufcount, 56); + remain = WQUEUESIZE - head; + + data_count = 0; + if (bufcount >= remain) { + bufcount -= remain; + while ((port->state->xmit.head != temp_tail) && + (data_count < remain)) { + channel->ch_wqueue[head++] = + port->state->xmit.buf[temp_tail]; + + temp_tail++; + temp_tail &= (UART_XMIT_SIZE - 1); + data_count++; + } + if (data_count == remain) head = 0; + } + + data_count1 = 0; + if (bufcount > 0) { + remain = bufcount; + while ((port->state->xmit.head != temp_tail) && + (data_count1 < remain)) { + channel->ch_wqueue[head++] = + port->state->xmit.buf[temp_tail]; + + temp_tail++; + temp_tail &= (UART_XMIT_SIZE - 1); + data_count1++; + + } + } + + port->state->xmit.tail = temp_tail; + + data_count += data_count1; + if (data_count) { + head &= tmask; + channel->ch_w_head = head; + } + + if (data_count) { + channel->ch_bd->bd_ops->copy_data_from_queue_to_uart(channel); + } + + return data_count; +} diff --git a/drivers/tty/serial/max3107-aava.c b/drivers/tty/serial/max3107-aava.c index d73aadd7a9ad..a1fe304f2f52 100644 --- a/drivers/tty/serial/max3107-aava.c +++ b/drivers/tty/serial/max3107-aava.c @@ -340,5 +340,5 @@ module_exit(max3107_exit); MODULE_DESCRIPTION("MAX3107 driver"); MODULE_AUTHOR("Aavamobile"); -MODULE_ALIAS("spi:aava-max3107"); +MODULE_ALIAS("aava-max3107-spi"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/tty/serial/max3107.c b/drivers/tty/serial/max3107.c index a8164601c0ea..750b4f627315 100644 --- a/drivers/tty/serial/max3107.c +++ b/drivers/tty/serial/max3107.c @@ -1209,5 +1209,5 @@ module_exit(max3107_exit); MODULE_DESCRIPTION("MAX3107 driver"); MODULE_AUTHOR("Aavamobile"); -MODULE_ALIAS("spi:max3107"); +MODULE_ALIAS("max3107-spi"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index 23bc743f2a22..a764bf99743b 100644 --- a/drivers/tty/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c @@ -917,4 +917,4 @@ module_init(serial_m3110_init); module_exit(serial_m3110_exit); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:max3110-uart"); +MODULE_ALIAS("max3110-uart"); diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 5b3d063a4aa1..7e02c9c344fe 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -368,8 +368,6 @@ static void mxs_auart_settermios(struct uart_port *u, writel(ctrl, u->membase + AUART_LINECTRL); writel(ctrl2, u->membase + AUART_CTRL2); - - uart_update_timeout(u, termios->c_cflag, baud); } static irqreturn_t mxs_auart_irq_handle(int irq, void *context) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 6d3ec14bf229..47cadf474149 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -806,7 +806,8 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, serial_omap_set_mctrl(&up->port, up->port.mctrl); /* Software Flow Control Configuration */ - serial_omap_configure_xonxoff(up, termios); + if (termios->c_iflag & (IXON | IXOFF)) + serial_omap_configure_xonxoff(up, termios); spin_unlock_irqrestore(&up->port.lock, flags); dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->pdev->id); diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 73038baa8b67..465210930890 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -256,8 +256,6 @@ enum pch_uart_num_t { pch_ml7213_uart2, pch_ml7223_uart0, pch_ml7223_uart1, - pch_ml7831_uart0, - pch_ml7831_uart1, }; static struct pch_uart_driver_data drv_dat[] = { @@ -270,8 +268,6 @@ static struct pch_uart_driver_data drv_dat[] = { [pch_ml7213_uart2] = {PCH_UART_2LINE, 2}, [pch_ml7223_uart0] = {PCH_UART_8LINE, 0}, [pch_ml7223_uart1] = {PCH_UART_2LINE, 1}, - [pch_ml7831_uart0] = {PCH_UART_8LINE, 0}, - [pch_ml7831_uart1] = {PCH_UART_2LINE, 1}, }; static unsigned int default_baud = 9600; @@ -602,8 +598,7 @@ static void pch_request_dma(struct uart_port *port) dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - dma_dev = pci_get_bus_and_slot(priv->pdev->bus->number, - PCI_DEVFN(0xa, 0)); /* Get DMA's dev + dma_dev = pci_get_bus_and_slot(2, PCI_DEVFN(0xa, 0)); /* Get DMA's dev information */ /* Set Tx DMA */ param = &priv->param_tx; @@ -630,7 +625,6 @@ static void pch_request_dma(struct uart_port *port) dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Rx)\n", __func__); dma_release_channel(priv->chan_tx); - priv->chan_tx = NULL; return; } @@ -658,8 +652,7 @@ static void pch_dma_rx_complete(void *arg) tty_flip_buffer_push(tty); tty_kref_put(tty); async_tx_ack(priv->desc_rx); - pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT | - PCH_UART_HAL_RX_ERR_INT); + pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT); } static void pch_dma_tx_complete(void *arg) @@ -714,8 +707,7 @@ static int handle_rx_to(struct eg20t_port *priv) int rx_size; int ret; if (!priv->start_rx) { - pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT | - PCH_UART_HAL_RX_ERR_INT); + pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT); return 0; } buf = &priv->rxbuf; @@ -977,13 +969,11 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) case PCH_UART_IID_RDR: /* Received Data Ready */ if (priv->use_dma) { pch_uart_hal_disable_interrupt(priv, - PCH_UART_HAL_RX_INT | - PCH_UART_HAL_RX_ERR_INT); + PCH_UART_HAL_RX_INT); ret = dma_handle_rx(priv); if (!ret) pch_uart_hal_enable_interrupt(priv, - PCH_UART_HAL_RX_INT | - PCH_UART_HAL_RX_ERR_INT); + PCH_UART_HAL_RX_INT); } else { ret = handle_rx(priv); } @@ -1109,8 +1099,7 @@ static void pch_uart_stop_rx(struct uart_port *port) struct eg20t_port *priv; priv = container_of(port, struct eg20t_port, port); priv->start_rx = 0; - pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT | - PCH_UART_HAL_RX_ERR_INT); + pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT); priv->int_dis_flag = 1; } @@ -1166,7 +1155,6 @@ static int pch_uart_startup(struct uart_port *port) break; case 16: fifo_size = PCH_UART_HAL_FIFO16; - break; case 1: default: fifo_size = PCH_UART_HAL_FIFO_DIS; @@ -1204,8 +1192,7 @@ static int pch_uart_startup(struct uart_port *port) pch_request_dma(port); priv->start_rx = 1; - pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT | - PCH_UART_HAL_RX_ERR_INT); + pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT); uart_update_timeout(port, CS8, default_baud); return 0; @@ -1225,7 +1212,8 @@ static void pch_uart_shutdown(struct uart_port *port) dev_err(priv->port.dev, "pch_uart_hal_set_fifo Failed(ret=%d)\n", ret); - pch_free_dma(port); + if (priv->use_dma_flag) + pch_free_dma(port); free_irq(priv->port.irq, priv); } @@ -1263,7 +1251,7 @@ static void pch_uart_set_termios(struct uart_port *port, stb = PCH_UART_HAL_STB1; if (termios->c_cflag & PARENB) { - if (termios->c_cflag & PARODD) + if (!(termios->c_cflag & PARODD)) parity = PCH_UART_HAL_PARITY_ODD; else parity = PCH_UART_HAL_PARITY_EVEN; @@ -1289,7 +1277,6 @@ static void pch_uart_set_termios(struct uart_port *port, if (rtn) goto out; - pch_uart_set_mctrl(&priv->port, priv->port.mctrl); /* Don't rewrite B0 */ if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); @@ -1361,11 +1348,9 @@ static int pch_uart_verify_port(struct uart_port *port, __func__); return -EOPNOTSUPP; #endif + priv->use_dma = 1; priv->use_dma_flag = 1; dev_info(priv->port.dev, "PCH UART : Use DMA Mode\n"); - if (!priv->use_dma) - pch_request_dma(port); - priv->use_dma = 1; } return 0; @@ -1560,10 +1545,6 @@ static DEFINE_PCI_DEVICE_TABLE(pch_uart_pci_id) = { .driver_data = pch_ml7223_uart0}, {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800D), .driver_data = pch_ml7223_uart1}, - {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8811), - .driver_data = pch_ml7831_uart0}, - {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8812), - .driver_data = pch_ml7831_uart1}, {0,}, }; diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 81243a62dd59..4302e6e3768e 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -100,16 +100,6 @@ static inline void receive_chars(struct uart_pxa_port *up, int *status) int max_count = 256; do { - /* work around Errata #20 according to - * Intel(R) PXA27x Processor Family - * Specification Update (May 2005) - * - * Step 2 - * Disable the Reciever Time Out Interrupt via IER[RTOEI] - */ - up->ier &= ~UART_IER_RTOIE; - serial_out(up, UART_IER, up->ier); - ch = serial_in(up, UART_RX); flag = TTY_NORMAL; up->port.icount.rx++; @@ -166,16 +156,6 @@ static inline void receive_chars(struct uart_pxa_port *up, int *status) *status = serial_in(up, UART_LSR); } while ((*status & UART_LSR_DR) && (max_count-- > 0)); tty_flip_buffer_push(tty); - - /* work around Errata #20 according to - * Intel(R) PXA27x Processor Family - * Specification Update (May 2005) - * - * Step 6: - * No more data in FIFO: Re-enable RTO interrupt via IER[RTOIE] - */ - up->ier |= UART_IER_RTOIE; - serial_out(up, UART_IER, up->ier); } static void transmit_chars(struct uart_pxa_port *up) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 2a106a94cdd0..db7912cb7ae0 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -91,9 +91,6 @@ static void __uart_start(struct tty_struct *tty) struct uart_state *state = tty->driver_data; struct uart_port *port = state->uart_port; - if (port->ops->wake_peer) - port->ops->wake_peer(port); - if (!uart_circ_empty(&state->xmit) && state->xmit.buf && !tty->stopped && !tty->hw_stopped) port->ops->start_tx(port); @@ -2006,8 +2003,6 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) if (port->tty && port->tty->termios && termios.c_cflag == 0) termios = *(port->tty->termios); - if (console_suspend_enabled) - uart_change_pm(state, 0); uport->ops->set_termios(uport, &termios, NULL); if (console_suspend_enabled) console_start(uport->cons); @@ -2328,7 +2323,6 @@ void uart_unregister_driver(struct uart_driver *drv) tty_unregister_driver(p); put_tty_driver(p); kfree(drv->state); - drv->state = NULL; drv->tty_driver = NULL; } diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index bead17e5634a..ebd8629c108d 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -953,20 +953,17 @@ static void sci_dma_tx_complete(void *arg) port->icount.tx += sg_dma_len(&s->sg_tx); async_tx_ack(s->desc_tx); + s->cookie_tx = -EINVAL; s->desc_tx = NULL; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); if (!uart_circ_empty(xmit)) { - s->cookie_tx = 0; schedule_work(&s->work_tx); - } else { - s->cookie_tx = -EINVAL; - if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { - u16 ctrl = sci_in(port, SCSCR); - sci_out(port, SCSCR, ctrl & ~SCSCR_TIE); - } + } else if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { + u16 ctrl = sci_in(port, SCSCR); + sci_out(port, SCSCR, ctrl & ~SCSCR_TIE); } spin_unlock_irqrestore(&port->lock, flags); @@ -1228,10 +1225,8 @@ static void sci_start_tx(struct uart_port *port) } if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) && - s->cookie_tx < 0) { - s->cookie_tx = 0; + s->cookie_tx < 0) schedule_work(&s->work_tx); - } #endif if (!s->chan_tx || port->type == PORT_SCIFA || port->type == PORT_SCIFB) { diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index b44aef078f10..6556f7452ba6 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -193,7 +193,8 @@ static inline struct tty_struct *file_tty(struct file *file) return ((struct tty_file_private *)file->private_data)->tty; } -int tty_alloc_file(struct file *file) +/* Associate a new file with the tty structure */ +int tty_add_file(struct tty_struct *tty, struct file *file) { struct tty_file_private *priv; @@ -201,36 +202,15 @@ int tty_alloc_file(struct file *file) if (!priv) return -ENOMEM; - file->private_data = priv; - - return 0; -} - -/* Associate a new file with the tty structure */ -void tty_add_file(struct tty_struct *tty, struct file *file) -{ - struct tty_file_private *priv = file->private_data; - priv->tty = tty; priv->file = file; + file->private_data = priv; spin_lock(&tty_files_lock); list_add(&priv->list, &tty->tty_files); spin_unlock(&tty_files_lock); -} - -/** - * tty_free_file - free file->private_data - * - * This shall be used only for fail path handling when tty_add_file was not - * called yet. - */ -void tty_free_file(struct file *file) -{ - struct tty_file_private *priv = file->private_data; - file->private_data = NULL; - kfree(priv); + return 0; } /* Delete file from its tty */ @@ -241,7 +221,8 @@ void tty_del_file(struct file *file) spin_lock(&tty_files_lock); list_del(&priv->list); spin_unlock(&tty_files_lock); - tty_free_file(file); + file->private_data = NULL; + kfree(priv); } @@ -1313,7 +1294,8 @@ static int tty_driver_install_tty(struct tty_driver *driver, * * Locking: tty_mutex for now */ -void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *tty) +static void tty_driver_remove_tty(struct tty_driver *driver, + struct tty_struct *tty) { if (driver->ops->remove) driver->ops->remove(driver, tty); @@ -1830,10 +1812,6 @@ static int tty_open(struct inode *inode, struct file *filp) nonseekable_open(inode, filp); retry_open: - retval = tty_alloc_file(filp); - if (retval) - return -ENOMEM; - noctty = filp->f_flags & O_NOCTTY; index = -1; retval = 0; @@ -1846,7 +1824,6 @@ retry_open: if (!tty) { tty_unlock(); mutex_unlock(&tty_mutex); - tty_free_file(filp); return -ENXIO; } driver = tty_driver_kref_get(tty->driver); @@ -1879,7 +1856,6 @@ retry_open: } tty_unlock(); mutex_unlock(&tty_mutex); - tty_free_file(filp); return -ENODEV; } @@ -1887,7 +1863,6 @@ retry_open: if (!driver) { tty_unlock(); mutex_unlock(&tty_mutex); - tty_free_file(filp); return -ENODEV; } got_driver: @@ -1898,8 +1873,6 @@ got_driver: if (IS_ERR(tty)) { tty_unlock(); mutex_unlock(&tty_mutex); - tty_driver_kref_put(driver); - tty_free_file(filp); return PTR_ERR(tty); } } @@ -1915,11 +1888,15 @@ got_driver: tty_driver_kref_put(driver); if (IS_ERR(tty)) { tty_unlock(); - tty_free_file(filp); return PTR_ERR(tty); } - tty_add_file(tty, filp); + retval = tty_add_file(tty, filp); + if (retval) { + tty_unlock(); + tty_release(inode, filp); + return retval; + } check_tty_count(tty, "tty_open"); if (tty->driver->type == TTY_DRIVER_TYPE_PTY && diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index a76c808afadc..ef925d581713 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -36,7 +36,6 @@ #include #include -#include /* * This guards the refcounted line discipline lists. The lock @@ -549,16 +548,15 @@ static void tty_ldisc_flush_works(struct tty_struct *tty) /** * tty_ldisc_wait_idle - wait for the ldisc to become idle * @tty: tty to wait for - * @timeout: for how long to wait at most * * Wait for the line discipline to become idle. The discipline must * have been halted for this to guarantee it remains idle. */ -static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) +static int tty_ldisc_wait_idle(struct tty_struct *tty) { - long ret; + int ret; ret = wait_event_timeout(tty_ldisc_idle, - atomic_read(&tty->ldisc->users) == 1, timeout); + atomic_read(&tty->ldisc->users) == 1, 5 * HZ); if (ret < 0) return ret; return ret > 0 ? 0 : -EBUSY; @@ -668,7 +666,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) tty_ldisc_flush_works(tty); - retval = tty_ldisc_wait_idle(tty, 5 * HZ); + retval = tty_ldisc_wait_idle(tty); tty_lock(); mutex_lock(&tty->ldisc_mutex); @@ -765,6 +763,8 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc) if (IS_ERR(ld)) return -1; + WARN_ON_ONCE(tty_ldisc_wait_idle(tty)); + tty_ldisc_close(tty, tty->ldisc); tty_ldisc_put(tty->ldisc); tty->ldisc = NULL; @@ -839,7 +839,7 @@ void tty_ldisc_hangup(struct tty_struct *tty) tty_unlock(); cancel_work_sync(&tty->buf.work); mutex_unlock(&tty->ldisc_mutex); -retry: + tty_lock(); mutex_lock(&tty->ldisc_mutex); @@ -848,22 +848,6 @@ retry: it means auditing a lot of other paths so this is a FIXME */ if (tty->ldisc) { /* Not yet closed */ - if (atomic_read(&tty->ldisc->users) != 1) { - char cur_n[TASK_COMM_LEN], tty_n[64]; - long timeout = 3 * HZ; - tty_unlock(); - - while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { - timeout = MAX_SCHEDULE_TIMEOUT; - printk_ratelimited(KERN_WARNING - "%s: waiting (%s) for %s took too long, but we keep waiting...\n", - __func__, get_task_comm(cur_n, current), - tty_name(tty, tty_n)); - } - mutex_unlock(&tty->ldisc_mutex); - goto retry; - } - if (reset == 0) { if (!tty_ldisc_reinit(tty, tty->termios->c_line)) diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index a4aaca0e014d..33d37d230f8f 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -227,6 +227,7 @@ int tty_port_block_til_ready(struct tty_port *port, int do_clocal = 0, retval; unsigned long flags; DEFINE_WAIT(wait); + int cd; /* block if port is in the process of being closed */ if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { @@ -283,14 +284,11 @@ int tty_port_block_til_ready(struct tty_port *port, retval = -ERESTARTSYS; break; } - /* - * Probe the carrier. For devices with no carrier detect - * tty_port_carrier_raised will always return true. - * Never ask drivers if CLOCAL is set, this causes troubles - * on some hardware. - */ + /* Probe the carrier. For devices with no carrier detect this + will always return true */ + cd = tty_port_carrier_raised(port); if (!(port->flags & ASYNC_CLOSING) && - (do_clocal || tty_port_carrier_raised(port))) + (do_clocal || cd)) break; if (signal_pending(current)) { retval = -ERESTARTSYS; diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index f3438083a285..45d3e80156d4 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c @@ -516,7 +516,6 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) int err = 0, err1, i; struct uni_pagedir *p, *q; - /* Save original vc_unipagdir_loc in case we allocate a new one */ p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; if (p->readonly) return -EIO; @@ -529,57 +528,26 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) err1 = con_clear_unimap(vc, NULL); if (err1) return err1; - /* - * Since refcount was > 1, con_clear_unimap() allocated a - * a new uni_pagedir for this vc. Re: p != q - */ q = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; - - /* - * uni_pgdir is a 32*32*64 table with rows allocated - * when its first entry is added. The unicode value must - * still be incremented for empty rows. We are copying - * entries from "p" (old) to "q" (new). - */ - l = 0; /* unicode value */ - for (i = 0; i < 32; i++) + for (i = 0, l = 0; i < 32; i++) if ((p1 = p->uni_pgdir[i])) for (j = 0; j < 32; j++) - if ((p2 = p1[j])) { + if ((p2 = p1[j])) for (k = 0; k < 64; k++, l++) if (p2[k] != 0xffff) { - /* - * Found one, copy entry for unicode - * l with fontpos value p2[k]. - */ err1 = con_insert_unipair(q, l, p2[k]); if (err1) { p->refcount++; *vc->vc_uni_pagedir_loc = (unsigned long)p; con_release_unimap(q); kfree(q); - return err1; + return err1; } - } - } else { - /* Account for row of 64 empty entries */ - l += 64; - } - else - /* Account for empty table */ - l += 32 * 64; - - /* - * Finished copying font table, set vc_uni_pagedir to new table - */ - p = q; - } else if (p == dflt) { + } + p = q; + } else if (p == dflt) dflt = NULL; - } - - /* - * Insert user specified unicode pairs into new table. - */ + while (ct--) { unsigned short unicode, fontpos; __get_user(unicode, &list->unicode); @@ -589,14 +557,11 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) list++; } - /* - * Merge with fontmaps of any other virtual consoles. - */ if (con_unify_unimap(vc, p)) return err; for (i = 0; i <= 3; i++) - set_inverse_transl(vc, p, i); /* Update inverse translations */ + set_inverse_transl(vc, p, i); /* Update all inverse translations */ set_inverse_trans_unicode(vc, p); return err; diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 65447c5f91d7..5e096f43bcea 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -1463,6 +1463,7 @@ compat_kdfontop_ioctl(struct compat_console_font_op __user *fontop, if (!perm && op->op != KD_FONT_OP_GET) return -EPERM; op->data = compat_ptr(((struct compat_console_font_op *)op)->data); + op->flags |= KD_FONT_FLAG_OLD; i = con_font_op(vc, op); if (i) return i; diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 84e69ea2309b..dac7676ce21b 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -498,14 +498,6 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) usb_autopm_put_interface(acm->control); - /* - * Unthrottle device in case the TTY was closed while throttled. - */ - spin_lock_irq(&acm->read_lock); - acm->throttled = 0; - acm->throttle_req = 0; - spin_unlock_irq(&acm->read_lock); - if (acm_submit_read_urbs(acm, GFP_KERNEL)) goto bail_out; @@ -547,6 +539,7 @@ static void acm_port_down(struct acm *acm) { int i; + mutex_lock(&open_mutex); if (acm->dev) { usb_autopm_get_interface(acm->control); acm_set_control(acm, acm->ctrlout = 0); @@ -558,23 +551,14 @@ static void acm_port_down(struct acm *acm) acm->control->needs_remote_wakeup = 0; usb_autopm_put_interface(acm->control); } + mutex_unlock(&open_mutex); } static void acm_tty_hangup(struct tty_struct *tty) { - struct acm *acm; - - mutex_lock(&open_mutex); - acm = tty->driver_data; - - if (!acm) - goto out; - + struct acm *acm = tty->driver_data; tty_port_hangup(&acm->port); acm_port_down(acm); - -out: - mutex_unlock(&open_mutex); } static void acm_tty_close(struct tty_struct *tty, struct file *filp) @@ -585,9 +569,8 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) shutdown */ if (!acm) return; - - mutex_lock(&open_mutex); if (tty_port_close_start(&acm->port, tty, filp) == 0) { + mutex_lock(&open_mutex); if (!acm->dev) { tty_port_tty_set(&acm->port, NULL); acm_tty_unregister(acm); @@ -599,7 +582,6 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) acm_port_down(acm); tty_port_close_end(&acm->port, tty); tty_port_tty_set(&acm->port, NULL); - mutex_unlock(&open_mutex); } static int acm_tty_write(struct tty_struct *tty, @@ -760,6 +742,10 @@ static const __u32 acm_tty_speed[] = { 2500000, 3000000, 3500000, 4000000 }; +static const __u8 acm_tty_size[] = { + 5, 6, 7, 8 +}; + static void acm_tty_set_termios(struct tty_struct *tty, struct ktermios *termios_old) { @@ -776,21 +762,7 @@ static void acm_tty_set_termios(struct tty_struct *tty, newline.bParityType = termios->c_cflag & PARENB ? (termios->c_cflag & PARODD ? 1 : 2) + (termios->c_cflag & CMSPAR ? 2 : 0) : 0; - switch (termios->c_cflag & CSIZE) { - case CS5: - newline.bDataBits = 5; - break; - case CS6: - newline.bDataBits = 6; - break; - case CS7: - newline.bDataBits = 7; - break; - case CS8: - default: - newline.bDataBits = 8; - break; - } + newline.bDataBits = acm_tty_size[(termios->c_cflag & CSIZE) >> 4]; /* FIXME: Needs to clear unsupported bits in the termios */ acm->clocal = ((termios->c_cflag & CLOCAL) != 0); @@ -1053,8 +1025,7 @@ skip_normal_probe: } - if (data_interface->cur_altsetting->desc.bNumEndpoints < 2 || - control_interface->cur_altsetting->desc.bNumEndpoints == 0) + if (data_interface->cur_altsetting->desc.bNumEndpoints < 2) return -EINVAL; epctrl = &control_interface->cur_altsetting->endpoint[0].desc; @@ -1182,7 +1153,7 @@ made_compressed_probe: if (usb_endpoint_xfer_int(epwrite)) usb_fill_int_urb(snd->urb, usb_dev, - usb_sndintpipe(usb_dev, epwrite->bEndpointAddress), + usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval); else usb_fill_bulk_urb(snd->urb, usb_dev, @@ -1210,8 +1181,6 @@ made_compressed_probe: i = device_create_file(&intf->dev, &dev_attr_wCountryCodes); if (i < 0) { kfree(acm->country_codes); - acm->country_codes = NULL; - acm->country_code_size = 0; goto skip_countries; } @@ -1220,8 +1189,6 @@ made_compressed_probe: if (i < 0) { device_remove_file(&intf->dev, &dev_attr_wCountryCodes); kfree(acm->country_codes); - acm->country_codes = NULL; - acm->country_code_size = 0; goto skip_countries; } } @@ -1489,16 +1456,6 @@ static const struct usb_device_id acm_ids[] = { }, { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */ }, - /* Motorola H24 HSPA module: */ - { USB_DEVICE(0x22b8, 0x2d91) }, /* modem */ - { USB_DEVICE(0x22b8, 0x2d92) }, /* modem + diagnostics */ - { USB_DEVICE(0x22b8, 0x2d93) }, /* modem + AT port */ - { USB_DEVICE(0x22b8, 0x2d95) }, /* modem + AT port + diagnostics */ - { USB_DEVICE(0x22b8, 0x2d96) }, /* modem + NMEA */ - { USB_DEVICE(0x22b8, 0x2d97) }, /* modem + diagnostics + NMEA */ - { USB_DEVICE(0x22b8, 0x2d99) }, /* modem + AT port + NMEA */ - { USB_DEVICE(0x22b8, 0x2d9a) }, /* modem + AT port + diagnostics + NMEA */ - { USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */ .driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on data interface instead of @@ -1506,12 +1463,6 @@ static const struct usb_device_id acm_ids[] = { Maybe we should define a new quirk for this. */ }, - { USB_DEVICE(0x0572, 0x1340), /* Conexant CX93010-2x UCMxx */ - .driver_info = NO_UNION_NORMAL, - }, - { USB_DEVICE(0x05f9, 0x4002), /* PSC Scanning, Magellan 800i */ - .driver_info = NO_UNION_NORMAL, - }, { USB_DEVICE(0x1bbb, 0x0003), /* Alcatel OT-I650 */ .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ }, @@ -1583,9 +1534,6 @@ static const struct usb_device_id acm_ids[] = { { NOKIA_PCSUITE_ACM_INFO(0x03cd), }, /* Nokia C7 */ { SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */ - /* Support for Owen devices */ - { USB_DEVICE(0x03eb, 0x0030), }, /* Owen SI30 */ - /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ /* Support Lego NXT using pbLua firmware */ diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 8a72e054fd10..2b9ff518b509 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -57,8 +57,6 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); #define WDM_MAX 16 -/* CDC-WMC r1.1 requires wMaxCommand to be "at least 256 decimal (0x100)" */ -#define WDM_DEFAULT_BUFSIZE 256 static DEFINE_MUTEX(wdm_mutex); @@ -90,8 +88,7 @@ struct wdm_device { int count; dma_addr_t shandle; dma_addr_t ihandle; - struct mutex wlock; - struct mutex rlock; + struct mutex lock; wait_queue_head_t wait; struct work_struct rxwork; int werr; @@ -108,9 +105,8 @@ static void wdm_out_callback(struct urb *urb) spin_lock(&desc->iuspin); desc->werr = urb->status; spin_unlock(&desc->iuspin); - kfree(desc->outbuf); - desc->outbuf = NULL; clear_bit(WDM_IN_USE, &desc->flags); + kfree(desc->outbuf); wake_up(&desc->wait); } @@ -313,7 +309,7 @@ static ssize_t wdm_write if (we < 0) return -EIO; - buf = kmalloc(count, GFP_KERNEL); + desc->outbuf = buf = kmalloc(count, GFP_KERNEL); if (!buf) { rv = -ENOMEM; goto outnl; @@ -327,7 +323,7 @@ static ssize_t wdm_write } /* concurrent writes and disconnect */ - r = mutex_lock_interruptible(&desc->wlock); + r = mutex_lock_interruptible(&desc->lock); rv = -ERESTARTSYS; if (r) { kfree(buf); @@ -377,12 +373,10 @@ static ssize_t wdm_write req->wIndex = desc->inum; req->wLength = cpu_to_le16(count); set_bit(WDM_IN_USE, &desc->flags); - desc->outbuf = buf; rv = usb_submit_urb(desc->command, GFP_KERNEL); if (rv < 0) { kfree(buf); - desc->outbuf = NULL; clear_bit(WDM_IN_USE, &desc->flags); dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv); } else { @@ -392,7 +386,7 @@ static ssize_t wdm_write out: usb_autopm_put_interface(desc->intf); outnp: - mutex_unlock(&desc->wlock); + mutex_unlock(&desc->lock); outnl: return rv < 0 ? rv : count; } @@ -400,17 +394,16 @@ outnl: static ssize_t wdm_read (struct file *file, char __user *buffer, size_t count, loff_t *ppos) { - int rv, cntr; + int rv, cntr = 0; int i = 0; struct wdm_device *desc = file->private_data; - rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */ + rv = mutex_lock_interruptible(&desc->lock); /*concurrent reads */ if (rv < 0) return -ERESTARTSYS; - cntr = ACCESS_ONCE(desc->length); - if (cntr == 0) { + if (desc->length == 0) { desc->read = 0; retry: if (test_bit(WDM_DISCONNECTING, &desc->flags)) { @@ -457,25 +450,20 @@ retry: goto retry; } if (!desc->reslength) { /* zero length read */ - dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__); - clear_bit(WDM_READ, &desc->flags); spin_unlock_irq(&desc->iuspin); goto retry; } - cntr = desc->length; + clear_bit(WDM_READ, &desc->flags); spin_unlock_irq(&desc->iuspin); } - if (cntr > count) - cntr = count; + cntr = count > desc->length ? desc->length : count; rv = copy_to_user(buffer, desc->ubuf, cntr); if (rv > 0) { rv = -EFAULT; goto err; } - spin_lock_irq(&desc->iuspin); - for (i = 0; i < desc->length - cntr; i++) desc->ubuf[i] = desc->ubuf[i + cntr]; @@ -483,13 +471,10 @@ retry: /* in case we had outstanding data */ if (!desc->length) clear_bit(WDM_READ, &desc->flags); - - spin_unlock_irq(&desc->iuspin); - rv = cntr; err: - mutex_unlock(&desc->rlock); + mutex_unlock(&desc->lock); return rv; } @@ -513,7 +498,7 @@ static unsigned int wdm_poll(struct file *file, struct poll_table_struct *wait) spin_lock_irqsave(&desc->iuspin, flags); if (test_bit(WDM_DISCONNECTING, &desc->flags)) { - mask = POLLHUP | POLLERR; + mask = POLLERR; spin_unlock_irqrestore(&desc->iuspin, flags); goto desc_out; } @@ -555,8 +540,7 @@ static int wdm_open(struct inode *inode, struct file *file) } intf->needs_remote_wakeup = 1; - /* using write lock to protect desc->count */ - mutex_lock(&desc->wlock); + mutex_lock(&desc->lock); if (!desc->count++) { desc->werr = 0; desc->rerr = 0; @@ -569,7 +553,7 @@ static int wdm_open(struct inode *inode, struct file *file) } else { rv = 0; } - mutex_unlock(&desc->wlock); + mutex_unlock(&desc->lock); usb_autopm_put_interface(desc->intf); out: mutex_unlock(&wdm_mutex); @@ -581,11 +565,9 @@ static int wdm_release(struct inode *inode, struct file *file) struct wdm_device *desc = file->private_data; mutex_lock(&wdm_mutex); - - /* using write lock to protect desc->count */ - mutex_lock(&desc->wlock); + mutex_lock(&desc->lock); desc->count--; - mutex_unlock(&desc->wlock); + mutex_unlock(&desc->lock); if (!desc->count) { dev_dbg(&desc->intf->dev, "wdm_release: cleanup"); @@ -648,7 +630,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) struct usb_cdc_dmm_desc *dmhd; u8 *buffer = intf->altsetting->extra; int buflen = intf->altsetting->extralen; - u16 maxcom = WDM_DEFAULT_BUFSIZE; + u16 maxcom = 0; if (!buffer) goto out; @@ -683,8 +665,7 @@ next_desc: desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); if (!desc) goto out; - mutex_init(&desc->rlock); - mutex_init(&desc->wlock); + mutex_init(&desc->lock); spin_lock_init(&desc->iuspin); init_waitqueue_head(&desc->wait); desc->wMaxCommand = maxcom; @@ -735,7 +716,7 @@ next_desc: goto err; desc->inbuf = usb_alloc_coherent(interface_to_usbdev(intf), - desc->wMaxCommand, + desc->bMaxPacketSize0, GFP_KERNEL, &desc->response->transfer_dma); if (!desc->inbuf) @@ -798,13 +779,11 @@ static void wdm_disconnect(struct usb_interface *intf) /* to terminate pending flushes */ clear_bit(WDM_IN_USE, &desc->flags); spin_unlock_irqrestore(&desc->iuspin, flags); - wake_up_all(&desc->wait); - mutex_lock(&desc->rlock); - mutex_lock(&desc->wlock); + mutex_lock(&desc->lock); kill_urbs(desc); cancel_work_sync(&desc->rxwork); - mutex_unlock(&desc->wlock); - mutex_unlock(&desc->rlock); + mutex_unlock(&desc->lock); + wake_up_all(&desc->wait); if (!desc->count) cleanup(desc); mutex_unlock(&wdm_mutex); @@ -819,10 +798,8 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); /* if this is an autosuspend the caller does the locking */ - if (!(message.event & PM_EVENT_AUTO)) { - mutex_lock(&desc->rlock); - mutex_lock(&desc->wlock); - } + if (!(message.event & PM_EVENT_AUTO)) + mutex_lock(&desc->lock); spin_lock_irq(&desc->iuspin); if ((message.event & PM_EVENT_AUTO) && @@ -838,10 +815,8 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) kill_urbs(desc); cancel_work_sync(&desc->rxwork); } - if (!(message.event & PM_EVENT_AUTO)) { - mutex_unlock(&desc->wlock); - mutex_unlock(&desc->rlock); - } + if (!(message.event & PM_EVENT_AUTO)) + mutex_unlock(&desc->lock); return rv; } @@ -879,8 +854,7 @@ static int wdm_pre_reset(struct usb_interface *intf) { struct wdm_device *desc = usb_get_intfdata(intf); - mutex_lock(&desc->rlock); - mutex_lock(&desc->wlock); + mutex_lock(&desc->lock); kill_urbs(desc); /* @@ -902,8 +876,7 @@ static int wdm_post_reset(struct usb_interface *intf) int rv; rv = recover_from_urb_loss(desc); - mutex_unlock(&desc->wlock); - mutex_unlock(&desc->rlock); + mutex_unlock(&desc->lock); return 0; } diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 3f94ac34dce3..385acb895ab3 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -268,7 +268,7 @@ usbtmc_abort_bulk_in_status: dev_err(dev, "usb_bulk_msg returned %d\n", rv); goto exit; } - } while ((actual == max_size) && + } while ((actual = max_size) && (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN)); if (actual == max_size) { diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 26678cadfb21..c962608b4b9a 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -123,11 +123,10 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, } if (usb_endpoint_xfer_isoc(&ep->desc)) - max_tx = (desc->bMaxBurst + 1) * (desc->bmAttributes + 1) * - le16_to_cpu(ep->desc.wMaxPacketSize); + max_tx = ep->desc.wMaxPacketSize * (desc->bMaxBurst + 1) * + (desc->bmAttributes + 1); else if (usb_endpoint_xfer_int(&ep->desc)) - max_tx = le16_to_cpu(ep->desc.wMaxPacketSize) * - (desc->bMaxBurst + 1); + max_tx = ep->desc.wMaxPacketSize * (desc->bMaxBurst + 1); else max_tx = 999999; if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) { @@ -135,10 +134,10 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, "config %d interface %d altsetting %d ep %d: " "setting to %d\n", usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int", - le16_to_cpu(desc->wBytesPerInterval), + desc->wBytesPerInterval, cfgno, inum, asnum, ep->desc.bEndpointAddress, max_tx); - ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx); + ep->ss_ep_comp.wBytesPerInterval = max_tx; } } diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index ca98341a21b9..0149c0976e9c 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c @@ -624,7 +624,7 @@ static ssize_t usb_device_read(struct file *file, char __user *buf, /* print devices for all busses */ list_for_each_entry(bus, &usb_bus_list, bus_list) { /* recurse through all children of the root hub */ - if (!bus_to_hcd(bus)->rh_registered) + if (!bus->root_hub) continue; usb_lock_device(bus->root_hub); ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 4d1f996b9875..37518dfdeb98 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -292,14 +292,17 @@ static struct async *async_getcompleted(struct dev_state *ps) static struct async *async_getpending(struct dev_state *ps, void __user *userurb) { + unsigned long flags; struct async *as; + spin_lock_irqsave(&ps->lock, flags); list_for_each_entry(as, &ps->async_pending, asynclist) if (as->userurb == userurb) { list_del_init(&as->asynclist); + spin_unlock_irqrestore(&ps->lock, flags); return as; } - + spin_unlock_irqrestore(&ps->lock, flags); return NULL; } @@ -354,7 +357,6 @@ static void cancel_bulk_urbs(struct dev_state *ps, unsigned bulk_addr) __releases(ps->lock) __acquires(ps->lock) { - struct urb *urb; struct async *as; /* Mark all the pending URBs that match bulk_addr, up to but not @@ -377,11 +379,8 @@ __acquires(ps->lock) list_for_each_entry(as, &ps->async_pending, asynclist) { if (as->bulk_status == AS_UNLINK) { as->bulk_status = 0; /* Only once */ - urb = as->urb; - usb_get_urb(urb); spin_unlock(&ps->lock); /* Allow completions */ - usb_unlink_urb(urb); - usb_put_urb(urb); + usb_unlink_urb(as->urb); spin_lock(&ps->lock); goto rescan; } @@ -408,7 +407,7 @@ static void async_completed(struct urb *urb) sinfo.si_errno = as->status; sinfo.si_code = SI_ASYNCIO; sinfo.si_addr = as->userurb; - pid = get_pid(as->pid); + pid = as->pid; uid = as->uid; euid = as->euid; secid = as->secid; @@ -423,18 +422,15 @@ static void async_completed(struct urb *urb) cancel_bulk_urbs(ps, as->bulk_addr); spin_unlock(&ps->lock); - if (signr) { + if (signr) kill_pid_info_as_uid(sinfo.si_signo, &sinfo, pid, uid, euid, secid); - put_pid(pid); - } wake_up(&ps->wait); } static void destroy_async(struct dev_state *ps, struct list_head *list) { - struct urb *urb; struct async *as; unsigned long flags; @@ -442,13 +438,10 @@ static void destroy_async(struct dev_state *ps, struct list_head *list) while (!list_empty(list)) { as = list_entry(list->next, struct async, asynclist); list_del_init(&as->asynclist); - urb = as->urb; - usb_get_urb(urb); /* drop the spinlock so the completion handler can run */ spin_unlock_irqrestore(&ps->lock, flags); - usb_kill_urb(urb); - usb_put_urb(urb); + usb_kill_urb(as->urb); spin_lock_irqsave(&ps->lock, flags); } spin_unlock_irqrestore(&ps->lock, flags); @@ -614,10 +607,9 @@ static int findintfep(struct usb_device *dev, unsigned int ep) } static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, - unsigned int request, unsigned int index) + unsigned int index) { int ret = 0; - struct usb_host_interface *alt_setting; if (ps->dev->state != USB_STATE_UNAUTHENTICATED && ps->dev->state != USB_STATE_ADDRESS @@ -626,19 +618,6 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype)) return 0; - /* - * check for the special corner case 'get_device_id' in the printer - * class specification, where wIndex is (interface << 8 | altsetting) - * instead of just interface - */ - if (requesttype == 0xa1 && request == 0) { - alt_setting = usb_find_alt_setting(ps->dev->actconfig, - index >> 8, index & 0xff); - if (alt_setting - && alt_setting->desc.bInterfaceClass == USB_CLASS_PRINTER) - index >>= 8; - } - index &= 0xff; switch (requesttype & USB_RECIP_MASK) { case USB_RECIP_ENDPOINT: @@ -791,8 +770,7 @@ static int proc_control(struct dev_state *ps, void __user *arg) if (copy_from_user(&ctrl, arg, sizeof(ctrl))) return -EFAULT; - ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.bRequest, - ctrl.wIndex); + ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.wIndex); if (ret) return ret; wLength = ctrl.wLength; /* To suppress 64k PAGE_SIZE warning */ @@ -1122,7 +1100,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, kfree(dr); return -EINVAL; } - ret = check_ctrlrecip(ps, dr->bRequestType, dr->bRequest, + ret = check_ctrlrecip(ps, dr->bRequestType, le16_to_cpup(&dr->wIndex)); if (ret) { kfree(dr); @@ -1357,24 +1335,12 @@ static int proc_submiturb(struct dev_state *ps, void __user *arg) static int proc_unlinkurb(struct dev_state *ps, void __user *arg) { - struct urb *urb; struct async *as; - unsigned long flags; - spin_lock_irqsave(&ps->lock, flags); as = async_getpending(ps, arg); - if (!as) { - spin_unlock_irqrestore(&ps->lock, flags); + if (!as) return -EINVAL; - } - - urb = as->urb; - usb_get_urb(urb); - spin_unlock_irqrestore(&ps->lock, flags); - - usb_kill_urb(urb); - usb_put_urb(urb); - + usb_kill_urb(as->urb); return 0; } @@ -1557,14 +1523,10 @@ static int processcompl_compat(struct async *as, void __user * __user *arg) void __user *addr = as->userurb; unsigned int i; - if (as->userbuffer && urb->actual_length) { - if (urb->number_of_packets > 0) /* Isochronous */ - i = urb->transfer_buffer_length; - else /* Non-Isoc */ - i = urb->actual_length; - if (copy_to_user(as->userbuffer, urb->transfer_buffer, i)) + if (as->userbuffer && urb->actual_length) + if (copy_to_user(as->userbuffer, urb->transfer_buffer, + urb->actual_length)) return -EFAULT; - } if (put_user(as->status, &userurb->status)) return -EFAULT; if (put_user(urb->actual_length, &userurb->actual_length)) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 75b4bc03e2e1..34e3da5aa72a 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1583,7 +1583,7 @@ int usb_autopm_get_interface_async(struct usb_interface *intf) dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", __func__, atomic_read(&intf->dev.power.usage_count), status); - if (status > 0 || status == -EINPROGRESS) + if (status > 0) status = 0; return status; } @@ -1668,11 +1668,6 @@ int usb_runtime_suspend(struct device *dev) return -EAGAIN; status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); - - /* Allow a retry if autosuspend failed temporarily */ - if (status == -EAGAIN || status == -EBUSY) - usb_mark_last_busy(udev); - /* The PM core reacts badly unless the return code is 0, * -EAGAIN, or -EBUSY, so always return -EBUSY on an error. */ diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 6c1642b382fd..ce22f4a84ed0 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -187,10 +187,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) return -ENODEV; dev->current_state = PCI_D0; - /* The xHCI driver supports MSI and MSI-X, - * so don't fail if the BIOS doesn't provide a legacy IRQ. - */ - if (!dev->irq && (driver->flags & HCD_MASK) != HCD_USB3) { + if (!dev->irq) { dev_err(&dev->dev, "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", pci_name(dev)); diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 9d5af9bb990c..ace9f8442e5d 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -977,7 +977,10 @@ static int register_root_hub(struct usb_hcd *hcd) if (retval) { dev_err (parent_dev, "can't register root hub for %s, %d\n", dev_name(&usb_dev->dev), retval); - } else { + } + mutex_unlock(&usb_bus_list_lock); + + if (retval == 0) { spin_lock_irq (&hcd_root_hub_lock); hcd->rh_registered = 1; spin_unlock_irq (&hcd_root_hub_lock); @@ -986,7 +989,6 @@ static int register_root_hub(struct usb_hcd *hcd) if (HCD_DEAD(hcd)) usb_hc_died (hcd); /* This time clean up */ } - mutex_unlock(&usb_bus_list_lock); return retval; } @@ -1385,10 +1387,11 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, ret = -EAGAIN; else urb->transfer_flags |= URB_DMA_MAP_SG; - urb->num_mapped_sgs = n; - if (n != urb->num_sgs) + if (n != urb->num_sgs) { + urb->num_sgs = n; urb->transfer_flags |= URB_DMA_SG_COMBINED; + } } else if (urb->sg) { struct scatterlist *sg = urb->sg; urb->transfer_dma = dma_map_page( @@ -1761,8 +1764,6 @@ int usb_hcd_alloc_bandwidth(struct usb_device *udev, struct usb_interface *iface = usb_ifnum_to_if(udev, cur_alt->desc.bInterfaceNumber); - if (!iface) - return -EINVAL; if (iface->resetting_device) { /* * The USB core just reset the device, so the xHCI host @@ -2433,10 +2434,8 @@ int usb_add_hcd(struct usb_hcd *hcd, && device_can_wakeup(&hcd->self.root_hub->dev)) dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); - /* enable irqs just before we start the controller, - * if the BIOS provides legacy PCI irqs. - */ - if (usb_hcd_is_primary_hcd(hcd) && irqnum) { + /* enable irqs just before we start the controller */ + if (usb_hcd_is_primary_hcd(hcd)) { retval = usb_hcd_request_irqs(hcd, irqnum, irqflags); if (retval) goto err_request_irq; diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index be9cac6e3b9e..a428aa080a36 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -482,16 +481,13 @@ static void hub_tt_work(struct work_struct *work) int limit = 100; spin_lock_irqsave (&hub->tt.lock, flags); - while (!list_empty(&hub->tt.clear_list)) { + while (--limit && !list_empty (&hub->tt.clear_list)) { struct list_head *next; struct usb_tt_clear *clear; struct usb_device *hdev = hub->hdev; const struct hc_driver *drv; int status; - if (!hub->quiescing && --limit < 0) - break; - next = hub->tt.clear_list.next; clear = list_entry (next, struct usb_tt_clear, clear_list); list_del (&clear->clear_list); @@ -709,26 +705,10 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) if (type == HUB_INIT3) goto init3; - /* The superspeed hub except for root hub has to use Hub Depth - * value as an offset into the route string to locate the bits - * it uses to determine the downstream port number. So hub driver - * should send a set hub depth request to superspeed hub after - * the superspeed hub is set configuration in initialization or - * reset procedure. - * - * After a resume, port power should still be on. + /* After a resume, port power should still be on. * For any other type of activation, turn it on. */ if (type != HUB_RESUME) { - if (hdev->parent && hub_is_superspeed(hdev)) { - ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), - HUB_SET_DEPTH, USB_RT_HUB, - hdev->level - 1, 0, NULL, 0, - USB_CTRL_SET_TIMEOUT); - if (ret < 0) - dev_err(hub->intfdev, - "set hub depth failed\n"); - } /* Speed up system boot by using a delayed_work for the * hub's initial power-up delays. This is pretty awkward @@ -833,12 +813,6 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) USB_PORT_FEAT_C_PORT_LINK_STATE); } - if ((portchange & USB_PORT_STAT_C_BH_RESET) && - hub_is_superspeed(hub->hdev)) { - need_debounce_delay = true; - clear_port_feature(hub->hdev, port1, - USB_PORT_FEAT_C_BH_PORT_RESET); - } /* We can forget about a "removed" device when there's a * physical disconnect or the connect status changes. */ @@ -955,7 +929,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) if (hub->has_indicators) cancel_delayed_work_sync(&hub->leds); if (hub->tt.hub) - flush_work_sync(&hub->tt.clear_work); + cancel_work_sync(&hub->tt.clear_work); } /* caller has locked the hub device */ @@ -1007,6 +981,18 @@ static int hub_configure(struct usb_hub *hub, goto fail; } + if (hub_is_superspeed(hdev) && (hdev->parent != NULL)) { + ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), + HUB_SET_DEPTH, USB_RT_HUB, + hdev->level - 1, 0, NULL, 0, + USB_CTRL_SET_TIMEOUT); + + if (ret < 0) { + message = "can't set hub depth"; + goto fail; + } + } + /* Request the entire hub descriptor. * hub->descriptor can handle USB_MAXCHILDREN ports, * but the hub can/will return fewer bytes here. @@ -1648,6 +1634,7 @@ void usb_disconnect(struct usb_device **pdev) { struct usb_device *udev = *pdev; int i; + struct usb_hcd *hcd = bus_to_hcd(udev->bus); if (!udev) { pr_debug ("%s nodev\n", __func__); @@ -1675,7 +1662,9 @@ void usb_disconnect(struct usb_device **pdev) * so that the hardware is now fully quiesced. */ dev_dbg (&udev->dev, "unregistering device\n"); + mutex_lock(hcd->bandwidth_mutex); usb_disable_device(udev, 0); + mutex_unlock(hcd->bandwidth_mutex); usb_hcd_synchronize_unlinks(udev); usb_remove_ep_devs(&udev->ep0); @@ -1906,14 +1895,6 @@ int usb_new_device(struct usb_device *udev) /* Tell the world! */ announce_device(udev); - if (udev->serial) - add_device_randomness(udev->serial, strlen(udev->serial)); - if (udev->product) - add_device_randomness(udev->product, strlen(udev->product)); - if (udev->manufacturer) - add_device_randomness(udev->manufacturer, - strlen(udev->manufacturer)); - device_enable_async_suspend(&udev->dev); /* Register the device. The device driver is responsible * for configuring the device and invoking the add-device @@ -2050,7 +2031,7 @@ static unsigned hub_is_wusb(struct usb_hub *hub) #define HUB_ROOT_RESET_TIME 50 /* times are in msec */ #define HUB_SHORT_RESET_TIME 10 #define HUB_LONG_RESET_TIME 200 -#define HUB_RESET_TIMEOUT 800 +#define HUB_RESET_TIMEOUT 500 static int hub_port_wait_reset(struct usb_hub *hub, int port1, struct usb_device *udev, unsigned int delay) @@ -2413,7 +2394,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) static int finish_port_resume(struct usb_device *udev) { int status = 0; - u16 devstatus = 0; + u16 devstatus; /* caller owns the udev device lock */ dev_dbg(&udev->dev, "%s\n", @@ -2458,13 +2439,7 @@ static int finish_port_resume(struct usb_device *udev) if (status) { dev_dbg(&udev->dev, "gone after usb resume? status %d\n", status); - /* - * There are a few quirky devices which violate the standard - * by claiming to have remote wakeup enabled after a reset, - * which crash if the feature is cleared, hence check for - * udev->reset_resume - */ - } else if (udev->actconfig && !udev->reset_resume) { + } else if (udev->actconfig) { le16_to_cpus(&devstatus); if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) { status = usb_control_msg(udev, diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 3c84a03273a4..0b5ec234c787 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -308,8 +308,7 @@ static void sg_complete(struct urb *urb) retval = usb_unlink_urb(io->urbs [i]); if (retval != -EINPROGRESS && retval != -ENODEV && - retval != -EBUSY && - retval != -EIDRM) + retval != -EBUSY) dev_err(&io->dev->dev, "%s, unlink --> %d\n", __func__, retval); @@ -318,6 +317,7 @@ static void sg_complete(struct urb *urb) } spin_lock(&io->lock); } + urb->dev = NULL; /* on the last completion, signal usb_sg_wait() */ io->bytes += urb->actual_length; @@ -524,6 +524,7 @@ void usb_sg_wait(struct usb_sg_request *io) case -ENXIO: /* hc didn't queue this one */ case -EAGAIN: case -ENOMEM: + io->urbs[i]->dev = NULL; retval = 0; yield(); break; @@ -541,6 +542,7 @@ void usb_sg_wait(struct usb_sg_request *io) /* fail any uncompleted urbs */ default: + io->urbs[i]->dev = NULL; io->urbs[i]->status = retval; dev_dbg(&io->dev->dev, "%s, submit --> %d\n", __func__, retval); @@ -591,10 +593,7 @@ void usb_sg_cancel(struct usb_sg_request *io) if (!io->urbs [i]->dev) continue; retval = usb_unlink_urb(io->urbs [i]); - if (retval != -EINPROGRESS - && retval != -ENODEV - && retval != -EBUSY - && retval != -EIDRM) + if (retval != -EINPROGRESS && retval != -EBUSY) dev_warn(&io->dev->dev, "%s, unlink --> %d\n", __func__, retval); } @@ -1136,6 +1135,8 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf, * Deallocates hcd/hardware state for the endpoints (nuking all or most * pending urbs) and usbcore state for the interfaces, so that usbcore * must usb_set_configuration() before any interfaces could be used. + * + * Must be called with hcd->bandwidth_mutex held. */ void usb_disable_device(struct usb_device *dev, int skip_ep0) { @@ -1188,9 +1189,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) usb_disable_endpoint(dev, i + USB_DIR_IN, false); } /* Remove endpoints from the host controller internal state */ - mutex_lock(hcd->bandwidth_mutex); usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); - mutex_unlock(hcd->bandwidth_mutex); /* Second pass: remove endpoint pointers */ } for (i = skip_ep0; i < 16; ++i) { @@ -1750,6 +1749,7 @@ free_interfaces: /* if it's already configured, clear out old state first. * getting rid of old interfaces means unbinding their drivers. */ + mutex_lock(hcd->bandwidth_mutex); if (dev->state != USB_STATE_ADDRESS) usb_disable_device(dev, 1); /* Skip ep0 */ @@ -1762,7 +1762,6 @@ free_interfaces: * host controller will not allow submissions to dropped endpoints. If * this call fails, the device state is unchanged. */ - mutex_lock(hcd->bandwidth_mutex); ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); if (ret < 0) { mutex_unlock(hcd->bandwidth_mutex); @@ -1770,8 +1769,28 @@ free_interfaces: goto free_interfaces; } - /* - * Initialize the new interface structures and the + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_SET_CONFIGURATION, 0, configuration, 0, + NULL, 0, USB_CTRL_SET_TIMEOUT); + if (ret < 0) { + /* All the old state is gone, so what else can we do? + * The device is probably useless now anyway. + */ + cp = NULL; + } + + dev->actconfig = cp; + if (!cp) { + usb_set_device_state(dev, USB_STATE_ADDRESS); + usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); + mutex_unlock(hcd->bandwidth_mutex); + usb_autosuspend_device(dev); + goto free_interfaces; + } + mutex_unlock(hcd->bandwidth_mutex); + usb_set_device_state(dev, USB_STATE_CONFIGURED); + + /* Initialize the new interface structures and the * hc/hcd/usbcore interface/endpoint state. */ for (i = 0; i < nintf; ++i) { @@ -1783,6 +1802,7 @@ free_interfaces: intfc = cp->intf_cache[i]; intf->altsetting = intfc->altsetting; intf->num_altsetting = intfc->num_altsetting; + intf->intf_assoc = find_iad(dev, cp, i); kref_get(&intfc->ref); alt = usb_altnum_to_altsetting(intf, 0); @@ -1795,8 +1815,6 @@ free_interfaces: if (!alt) alt = &intf->altsetting[0]; - intf->intf_assoc = - find_iad(dev, cp, alt->desc.bInterfaceNumber); intf->cur_altsetting = alt; usb_enable_interface(dev, intf, true); intf->dev.parent = &dev->dev; @@ -1815,35 +1833,6 @@ free_interfaces: } kfree(new_interfaces); - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - USB_REQ_SET_CONFIGURATION, 0, configuration, 0, - NULL, 0, USB_CTRL_SET_TIMEOUT); - if (ret < 0 && cp) { - /* - * All the old state is gone, so what else can we do? - * The device is probably useless now anyway. - */ - usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); - for (i = 0; i < nintf; ++i) { - usb_disable_interface(dev, cp->interface[i], true); - put_device(&cp->interface[i]->dev); - cp->interface[i] = NULL; - } - cp = NULL; - } - - dev->actconfig = cp; - mutex_unlock(hcd->bandwidth_mutex); - - if (!cp) { - usb_set_device_state(dev, USB_STATE_ADDRESS); - - /* Leave LPM disabled while the device is unconfigured. */ - usb_autosuspend_device(dev); - return ret; - } - usb_set_device_state(dev, USB_STATE_CONFIGURED); - if (cp->string == NULL && !(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS)) cp->string = usb_cache_string(dev, cp->desc.iConfiguration); diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 8b2a9d83090e..81ce6a8e1d94 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -38,54 +38,6 @@ static const struct usb_device_id usb_quirk_list[] = { /* Creative SB Audigy 2 NX */ { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Logitech Webcam C200 */ - { USB_DEVICE(0x046d, 0x0802), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C250 */ - { USB_DEVICE(0x046d, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C300 */ - { USB_DEVICE(0x046d, 0x0805), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam B/C500 */ - { USB_DEVICE(0x046d, 0x0807), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C600 */ - { USB_DEVICE(0x046d, 0x0808), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam Pro 9000 */ - { USB_DEVICE(0x046d, 0x0809), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C905 */ - { USB_DEVICE(0x046d, 0x080a), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C210 */ - { USB_DEVICE(0x046d, 0x0819), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C260 */ - { USB_DEVICE(0x046d, 0x081a), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C310 */ - { USB_DEVICE(0x046d, 0x081b), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C910 */ - { USB_DEVICE(0x046d, 0x0821), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C160 */ - { USB_DEVICE(0x046d, 0x0824), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C270 */ - { USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Quickcam Pro 9000 */ - { USB_DEVICE(0x046d, 0x0990), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Quickcam E3500 */ - { USB_DEVICE(0x046d, 0x09a4), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Quickcam Vision Pro */ - { USB_DEVICE(0x046d, 0x09a6), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Logitech Harmony 700-series */ { USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT }, @@ -96,10 +48,6 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x04b4, 0x0526), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS }, - /* Microchip Joss Optical infrared touchboard device */ - { USB_DEVICE(0x04d8, 0x000c), .driver_info = - USB_QUIRK_CONFIG_INTF_STRINGS }, - /* Samsung Android phone modem - ID conflict with SPH-I500 */ { USB_DEVICE(0x04e8, 0x6601), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS }, @@ -121,15 +69,6 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x06a3, 0x0006), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS }, - /* Guillemot Webcam Hercules Dualpix Exchange (2nd ID) */ - { USB_DEVICE(0x06f8, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Guillemot Webcam Hercules Dualpix Exchange*/ - { USB_DEVICE(0x06f8, 0x3005), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Midiman M-Audio Keystation 88es */ - { USB_DEVICE(0x0763, 0x0192), .driver_info = USB_QUIRK_RESET_RESUME }, - /* M-Systems Flash Disk Pioneers */ { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index 347bb058e1ee..1fc8f1249806 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c @@ -450,7 +450,7 @@ static int dbgp_ehci_startup(void) writel(FLAG_CF, &ehci_regs->configured_flag); /* Wait until the controller is no longer halted */ - loop = 1000; + loop = 10; do { status = readl(&ehci_regs->status); if (!(status & STS_HALT)) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index aca160e0d943..029e288805b6 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -544,7 +544,7 @@ config USB_LANGWELL select USB_GADGET_SELECTED config USB_GADGET_EG20T - tristate "Intel EG20T PCH/OKI SEMICONDUCTOR IOH(ML7213/ML7831) UDC" + boolean "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH UDC" depends on PCI select USB_GADGET_DUALSPEED help @@ -562,9 +562,8 @@ config USB_GADGET_EG20T This driver also can be used for OKI SEMICONDUCTOR's ML7213 which is for IVI(In-Vehicle Infotainment) use. - ML7831 is for general purpose use. - ML7213/ML7831 is companion chip for Intel Atom E6xx series. - ML7213/ML7831 is completely compatible for Intel EG20T PCH. + ML7213 is companion chip for Intel Atom E6xx series. + ML7213 is completely compatible for Intel EG20T PCH. config USB_EG20T tristate @@ -936,14 +935,6 @@ config USB_G_PRINTER For more information, see Documentation/usb/gadget_printer.txt which includes sample code for accessing the device file. -config USB_G_ANDROID - boolean "Android Gadget" - depends on SWITCH - help - The Android gadget driver supports multiple USB functions. - The functions can be configured via a board file and may be - enabled and disabled dynamically. - config USB_CDC_COMPOSITE tristate "CDC Composite Device (Ethernet and ACM)" depends on NET diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index ab17a4cadba6..4fe92b18a055 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -49,7 +49,6 @@ g_dbgp-y := dbgp.o g_nokia-y := nokia.o g_webcam-y := webcam.o g_ncm-y := ncm.o -g_android-y := android.o obj-$(CONFIG_USB_ZERO) += g_zero.o obj-$(CONFIG_USB_AUDIO) += g_audio.o @@ -68,4 +67,3 @@ obj-$(CONFIG_USB_G_MULTI) += g_multi.o obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o obj-$(CONFIG_USB_G_NCM) += g_ncm.o -obj-$(CONFIG_USB_G_ANDROID) += g_android.o diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c deleted file mode 100644 index 1236d6f593d3..000000000000 --- a/drivers/usb/gadget/android.c +++ /dev/null @@ -1,1349 +0,0 @@ -/* - * Gadget Driver for Android - * - * Copyright (C) 2008 Google, Inc. - * Author: Mike Lockwood - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -/* #define DEBUG */ -/* #define VERBOSE_DEBUG */ - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "gadget_chips.h" - -/* - * Kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a "gcc --combine ... part1.c part2.c part3.c ... " build would. - */ -#include "usbstring.c" -#include "config.c" -#include "epautoconf.c" -#include "composite.c" - -#include "f_audio_source.c" -#include "f_mass_storage.c" -#include "u_serial.c" -#include "f_acm.c" -#include "f_adb.c" -#include "f_mtp.c" -#include "f_accessory.c" -#define USB_ETH_RNDIS y -#include "f_rndis.c" -#include "rndis.c" -#include "u_ether.c" - -MODULE_AUTHOR("Mike Lockwood"); -MODULE_DESCRIPTION("Android Composite USB Driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION("1.0"); - -static const char longname[] = "Gadget Android"; - -/* Default vendor and product IDs, overridden by userspace */ -#define VENDOR_ID 0x18D1 -#define PRODUCT_ID 0x0001 - -struct android_usb_function { - char *name; - void *config; - - struct device *dev; - char *dev_name; - struct device_attribute **attributes; - - /* for android_dev.enabled_functions */ - struct list_head enabled_list; - - /* Optional: initialization during gadget bind */ - int (*init)(struct android_usb_function *, struct usb_composite_dev *); - /* Optional: cleanup during gadget unbind */ - void (*cleanup)(struct android_usb_function *); - /* Optional: called when the function is added the list of - * enabled functions */ - void (*enable)(struct android_usb_function *); - /* Optional: called when it is removed */ - void (*disable)(struct android_usb_function *); - - int (*bind_config)(struct android_usb_function *, struct usb_configuration *); - - /* Optional: called when the configuration is removed */ - void (*unbind_config)(struct android_usb_function *, struct usb_configuration *); - /* Optional: handle ctrl requests before the device is configured */ - int (*ctrlrequest)(struct android_usb_function *, - struct usb_composite_dev *, - const struct usb_ctrlrequest *); -}; - -struct android_dev { - struct android_usb_function **functions; - struct list_head enabled_functions; - struct usb_composite_dev *cdev; - struct device *dev; - - bool enabled; - int disable_depth; - struct mutex mutex; - bool connected; - bool sw_connected; - struct work_struct work; -}; - -static struct class *android_class; -static struct android_dev *_android_dev; -static int android_bind_config(struct usb_configuration *c); -static void android_unbind_config(struct usb_configuration *c); - -/* string IDs are assigned dynamically */ -#define STRING_MANUFACTURER_IDX 0 -#define STRING_PRODUCT_IDX 1 -#define STRING_SERIAL_IDX 2 - -static char manufacturer_string[256]; -static char product_string[256]; -static char serial_string[256]; - -/* String Table */ -static struct usb_string strings_dev[] = { - [STRING_MANUFACTURER_IDX].s = manufacturer_string, - [STRING_PRODUCT_IDX].s = product_string, - [STRING_SERIAL_IDX].s = serial_string, - { } /* end of list */ -}; - -static struct usb_gadget_strings stringtab_dev = { - .language = 0x0409, /* en-us */ - .strings = strings_dev, -}; - -static struct usb_gadget_strings *dev_strings[] = { - &stringtab_dev, - NULL, -}; - -static struct usb_device_descriptor device_desc = { - .bLength = sizeof(device_desc), - .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = __constant_cpu_to_le16(0x0200), - .bDeviceClass = USB_CLASS_PER_INTERFACE, - .idVendor = __constant_cpu_to_le16(VENDOR_ID), - .idProduct = __constant_cpu_to_le16(PRODUCT_ID), - .bcdDevice = __constant_cpu_to_le16(0xffff), - .bNumConfigurations = 1, -}; - -static struct usb_configuration android_config_driver = { - .label = "android", - .unbind = android_unbind_config, - .bConfigurationValue = 1, -}; - -static void android_work(struct work_struct *data) -{ - struct android_dev *dev = container_of(data, struct android_dev, work); - struct usb_composite_dev *cdev = dev->cdev; - char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL }; - char *connected[2] = { "USB_STATE=CONNECTED", NULL }; - char *configured[2] = { "USB_STATE=CONFIGURED", NULL }; - char **uevent_envp = NULL; - unsigned long flags; - - spin_lock_irqsave(&cdev->lock, flags); - if (cdev->config) - uevent_envp = configured; - else if (dev->connected != dev->sw_connected) - uevent_envp = dev->connected ? connected : disconnected; - dev->sw_connected = dev->connected; - spin_unlock_irqrestore(&cdev->lock, flags); - - if (uevent_envp) { - kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE, uevent_envp); - pr_info("%s: sent uevent %s\n", __func__, uevent_envp[0]); - } else { - pr_info("%s: did not send uevent (%d %d %p)\n", __func__, - dev->connected, dev->sw_connected, cdev->config); - } -} - -static void android_enable(struct android_dev *dev) -{ - struct usb_composite_dev *cdev = dev->cdev; - - BUG_ON(!mutex_is_locked(&dev->mutex)); - BUG_ON(!dev->disable_depth); - - if (--dev->disable_depth == 0) { - usb_add_config(cdev, &android_config_driver, - android_bind_config); - usb_gadget_connect(cdev->gadget); - } -} - -static void android_disable(struct android_dev *dev) -{ - struct usb_composite_dev *cdev = dev->cdev; - - BUG_ON(!mutex_is_locked(&dev->mutex)); - - if (dev->disable_depth++ == 0) { - usb_gadget_disconnect(cdev->gadget); - /* Cancel pending control requests */ - usb_ep_dequeue(cdev->gadget->ep0, cdev->req); - usb_remove_config(cdev, &android_config_driver); - } -} - -/*-------------------------------------------------------------------------*/ -/* Supported functions initialization */ - -struct adb_data { - bool opened; - bool enabled; -}; - -static int adb_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev) -{ - f->config = kzalloc(sizeof(struct adb_data), GFP_KERNEL); - if (!f->config) - return -ENOMEM; - - return adb_setup(); -} - -static void adb_function_cleanup(struct android_usb_function *f) -{ - adb_cleanup(); - kfree(f->config); -} - -static int adb_function_bind_config(struct android_usb_function *f, struct usb_configuration *c) -{ - return adb_bind_config(c); -} - -static void adb_android_function_enable(struct android_usb_function *f) -{ - struct android_dev *dev = _android_dev; - struct adb_data *data = f->config; - - data->enabled = true; - - /* Disable the gadget until adbd is ready */ - if (!data->opened) - android_disable(dev); -} - -static void adb_android_function_disable(struct android_usb_function *f) -{ - struct android_dev *dev = _android_dev; - struct adb_data *data = f->config; - - data->enabled = false; - - /* Balance the disable that was called in closed_callback */ - if (!data->opened) - android_enable(dev); -} - -static struct android_usb_function adb_function = { - .name = "adb", - .enable = adb_android_function_enable, - .disable = adb_android_function_disable, - .init = adb_function_init, - .cleanup = adb_function_cleanup, - .bind_config = adb_function_bind_config, -}; - -static void adb_ready_callback(void) -{ - struct android_dev *dev = _android_dev; - struct adb_data *data = adb_function.config; - - mutex_lock(&dev->mutex); - - data->opened = true; - - if (data->enabled) - android_enable(dev); - - mutex_unlock(&dev->mutex); -} - -static void adb_closed_callback(void) -{ - struct android_dev *dev = _android_dev; - struct adb_data *data = adb_function.config; - - mutex_lock(&dev->mutex); - - data->opened = false; - - if (data->enabled) - android_disable(dev); - - mutex_unlock(&dev->mutex); -} - - -#define MAX_ACM_INSTANCES 4 -struct acm_function_config { - int instances; -}; - -static int acm_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev) -{ - f->config = kzalloc(sizeof(struct acm_function_config), GFP_KERNEL); - if (!f->config) - return -ENOMEM; - - return gserial_setup(cdev->gadget, MAX_ACM_INSTANCES); -} - -static void acm_function_cleanup(struct android_usb_function *f) -{ - gserial_cleanup(); - kfree(f->config); - f->config = NULL; -} - -static int acm_function_bind_config(struct android_usb_function *f, struct usb_configuration *c) -{ - int i; - int ret = 0; - struct acm_function_config *config = f->config; - - for (i = 0; i < config->instances; i++) { - ret = acm_bind_config(c, i); - if (ret) { - pr_err("Could not bind acm%u config\n", i); - break; - } - } - - return ret; -} - -static ssize_t acm_instances_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct android_usb_function *f = dev_get_drvdata(dev); - struct acm_function_config *config = f->config; - return sprintf(buf, "%d\n", config->instances); -} - -static ssize_t acm_instances_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - struct android_usb_function *f = dev_get_drvdata(dev); - struct acm_function_config *config = f->config; - int value; - - sscanf(buf, "%d", &value); - if (value > MAX_ACM_INSTANCES) - value = MAX_ACM_INSTANCES; - config->instances = value; - return size; -} - -static DEVICE_ATTR(instances, S_IRUGO | S_IWUSR, acm_instances_show, acm_instances_store); -static struct device_attribute *acm_function_attributes[] = { &dev_attr_instances, NULL }; - -static struct android_usb_function acm_function = { - .name = "acm", - .init = acm_function_init, - .cleanup = acm_function_cleanup, - .bind_config = acm_function_bind_config, - .attributes = acm_function_attributes, -}; - - -static int mtp_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev) -{ - return mtp_setup(); -} - -static void mtp_function_cleanup(struct android_usb_function *f) -{ - mtp_cleanup(); -} - -static int mtp_function_bind_config(struct android_usb_function *f, struct usb_configuration *c) -{ - return mtp_bind_config(c, false); -} - -static int ptp_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev) -{ - /* nothing to do - initialization is handled by mtp_function_init */ - return 0; -} - -static void ptp_function_cleanup(struct android_usb_function *f) -{ - /* nothing to do - cleanup is handled by mtp_function_cleanup */ -} - -static int ptp_function_bind_config(struct android_usb_function *f, struct usb_configuration *c) -{ - return mtp_bind_config(c, true); -} - -static int mtp_function_ctrlrequest(struct android_usb_function *f, - struct usb_composite_dev *cdev, - const struct usb_ctrlrequest *c) -{ - return mtp_ctrlrequest(cdev, c); -} - -static struct android_usb_function mtp_function = { - .name = "mtp", - .init = mtp_function_init, - .cleanup = mtp_function_cleanup, - .bind_config = mtp_function_bind_config, - .ctrlrequest = mtp_function_ctrlrequest, -}; - -/* PTP function is same as MTP with slightly different interface descriptor */ -static struct android_usb_function ptp_function = { - .name = "ptp", - .init = ptp_function_init, - .cleanup = ptp_function_cleanup, - .bind_config = ptp_function_bind_config, -}; - - -struct rndis_function_config { - u8 ethaddr[ETH_ALEN]; - u32 vendorID; - char manufacturer[256]; - bool wceis; -}; - -static int rndis_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev) -{ - f->config = kzalloc(sizeof(struct rndis_function_config), GFP_KERNEL); - if (!f->config) - return -ENOMEM; - return 0; -} - -static void rndis_function_cleanup(struct android_usb_function *f) -{ - kfree(f->config); - f->config = NULL; -} - -static int rndis_function_bind_config(struct android_usb_function *f, - struct usb_configuration *c) -{ - int ret; - struct rndis_function_config *rndis = f->config; - - if (!rndis) { - pr_err("%s: rndis_pdata\n", __func__); - return -1; - } - - pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__, - rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2], - rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]); - - ret = gether_setup_name(c->cdev->gadget, rndis->ethaddr, "rndis"); - if (ret) { - pr_err("%s: gether_setup failed\n", __func__); - return ret; - } - - if (rndis->wceis) { - /* "Wireless" RNDIS; auto-detected by Windows */ - rndis_iad_descriptor.bFunctionClass = - USB_CLASS_WIRELESS_CONTROLLER; - rndis_iad_descriptor.bFunctionSubClass = 0x01; - rndis_iad_descriptor.bFunctionProtocol = 0x03; - rndis_control_intf.bInterfaceClass = - USB_CLASS_WIRELESS_CONTROLLER; - rndis_control_intf.bInterfaceSubClass = 0x01; - rndis_control_intf.bInterfaceProtocol = 0x03; - } - - return rndis_bind_config(c, rndis->ethaddr, rndis->vendorID, - rndis->manufacturer); -} - -static void rndis_function_unbind_config(struct android_usb_function *f, - struct usb_configuration *c) -{ - gether_cleanup(); -} - -static ssize_t rndis_manufacturer_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct android_usb_function *f = dev_get_drvdata(dev); - struct rndis_function_config *config = f->config; - return sprintf(buf, "%s\n", config->manufacturer); -} - -static ssize_t rndis_manufacturer_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - struct android_usb_function *f = dev_get_drvdata(dev); - struct rndis_function_config *config = f->config; - - if (size >= sizeof(config->manufacturer)) - return -EINVAL; - if (sscanf(buf, "%s", config->manufacturer) == 1) - return size; - return -1; -} - -static DEVICE_ATTR(manufacturer, S_IRUGO | S_IWUSR, rndis_manufacturer_show, - rndis_manufacturer_store); - -static ssize_t rndis_wceis_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct android_usb_function *f = dev_get_drvdata(dev); - struct rndis_function_config *config = f->config; - return sprintf(buf, "%d\n", config->wceis); -} - -static ssize_t rndis_wceis_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - struct android_usb_function *f = dev_get_drvdata(dev); - struct rndis_function_config *config = f->config; - int value; - - if (sscanf(buf, "%d", &value) == 1) { - config->wceis = value; - return size; - } - return -EINVAL; -} - -static DEVICE_ATTR(wceis, S_IRUGO | S_IWUSR, rndis_wceis_show, - rndis_wceis_store); - -static ssize_t rndis_ethaddr_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct android_usb_function *f = dev_get_drvdata(dev); - struct rndis_function_config *rndis = f->config; - return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", - rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2], - rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]); -} - -static ssize_t rndis_ethaddr_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - struct android_usb_function *f = dev_get_drvdata(dev); - struct rndis_function_config *rndis = f->config; - - if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", - (int *)&rndis->ethaddr[0], (int *)&rndis->ethaddr[1], - (int *)&rndis->ethaddr[2], (int *)&rndis->ethaddr[3], - (int *)&rndis->ethaddr[4], (int *)&rndis->ethaddr[5]) == 6) - return size; - return -EINVAL; -} - -static DEVICE_ATTR(ethaddr, S_IRUGO | S_IWUSR, rndis_ethaddr_show, - rndis_ethaddr_store); - -static ssize_t rndis_vendorID_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct android_usb_function *f = dev_get_drvdata(dev); - struct rndis_function_config *config = f->config; - return sprintf(buf, "%04x\n", config->vendorID); -} - -static ssize_t rndis_vendorID_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - struct android_usb_function *f = dev_get_drvdata(dev); - struct rndis_function_config *config = f->config; - int value; - - if (sscanf(buf, "%04x", &value) == 1) { - config->vendorID = value; - return size; - } - return -EINVAL; -} - -static DEVICE_ATTR(vendorID, S_IRUGO | S_IWUSR, rndis_vendorID_show, - rndis_vendorID_store); - -static struct device_attribute *rndis_function_attributes[] = { - &dev_attr_manufacturer, - &dev_attr_wceis, - &dev_attr_ethaddr, - &dev_attr_vendorID, - NULL -}; - -static struct android_usb_function rndis_function = { - .name = "rndis", - .init = rndis_function_init, - .cleanup = rndis_function_cleanup, - .bind_config = rndis_function_bind_config, - .unbind_config = rndis_function_unbind_config, - .attributes = rndis_function_attributes, -}; - - -struct mass_storage_function_config { - struct fsg_config fsg; - struct fsg_common *common; -}; - -static int mass_storage_function_init(struct android_usb_function *f, - struct usb_composite_dev *cdev) -{ - struct mass_storage_function_config *config; - struct fsg_common *common; - int err; - - config = kzalloc(sizeof(struct mass_storage_function_config), - GFP_KERNEL); - if (!config) - return -ENOMEM; - - config->fsg.nluns = 1; - config->fsg.luns[0].removable = 1; - - common = fsg_common_init(NULL, cdev, &config->fsg); - if (IS_ERR(common)) { - kfree(config); - return PTR_ERR(common); - } - - err = sysfs_create_link(&f->dev->kobj, - &common->luns[0].dev.kobj, - "lun"); - if (err) { - kfree(config); - return err; - } - - config->common = common; - f->config = config; - return 0; -} - -static void mass_storage_function_cleanup(struct android_usb_function *f) -{ - kfree(f->config); - f->config = NULL; -} - -static int mass_storage_function_bind_config(struct android_usb_function *f, - struct usb_configuration *c) -{ - struct mass_storage_function_config *config = f->config; - return fsg_bind_config(c->cdev, c, config->common); -} - -static ssize_t mass_storage_inquiry_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct android_usb_function *f = dev_get_drvdata(dev); - struct mass_storage_function_config *config = f->config; - return sprintf(buf, "%s\n", config->common->inquiry_string); -} - -static ssize_t mass_storage_inquiry_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - struct android_usb_function *f = dev_get_drvdata(dev); - struct mass_storage_function_config *config = f->config; - if (size >= sizeof(config->common->inquiry_string)) - return -EINVAL; - if (sscanf(buf, "%s", config->common->inquiry_string) != 1) - return -EINVAL; - return size; -} - -static DEVICE_ATTR(inquiry_string, S_IRUGO | S_IWUSR, - mass_storage_inquiry_show, - mass_storage_inquiry_store); - -static struct device_attribute *mass_storage_function_attributes[] = { - &dev_attr_inquiry_string, - NULL -}; - -static struct android_usb_function mass_storage_function = { - .name = "mass_storage", - .init = mass_storage_function_init, - .cleanup = mass_storage_function_cleanup, - .bind_config = mass_storage_function_bind_config, - .attributes = mass_storage_function_attributes, -}; - - -static int accessory_function_init(struct android_usb_function *f, - struct usb_composite_dev *cdev) -{ - return acc_setup(); -} - -static void accessory_function_cleanup(struct android_usb_function *f) -{ - acc_cleanup(); -} - -static int accessory_function_bind_config(struct android_usb_function *f, - struct usb_configuration *c) -{ - return acc_bind_config(c); -} - -static int accessory_function_ctrlrequest(struct android_usb_function *f, - struct usb_composite_dev *cdev, - const struct usb_ctrlrequest *c) -{ - return acc_ctrlrequest(cdev, c); -} - -static struct android_usb_function accessory_function = { - .name = "accessory", - .init = accessory_function_init, - .cleanup = accessory_function_cleanup, - .bind_config = accessory_function_bind_config, - .ctrlrequest = accessory_function_ctrlrequest, -}; - -static int audio_source_function_init(struct android_usb_function *f, - struct usb_composite_dev *cdev) -{ - struct audio_source_config *config; - - config = kzalloc(sizeof(struct audio_source_config), GFP_KERNEL); - if (!config) - return -ENOMEM; - config->card = -1; - config->device = -1; - f->config = config; - return 0; -} - -static void audio_source_function_cleanup(struct android_usb_function *f) -{ - kfree(f->config); -} - -static int audio_source_function_bind_config(struct android_usb_function *f, - struct usb_configuration *c) -{ - struct audio_source_config *config = f->config; - - return audio_source_bind_config(c, config); -} - -static void audio_source_function_unbind_config(struct android_usb_function *f, - struct usb_configuration *c) -{ - struct audio_source_config *config = f->config; - - config->card = -1; - config->device = -1; -} - -static ssize_t audio_source_pcm_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct android_usb_function *f = dev_get_drvdata(dev); - struct audio_source_config *config = f->config; - - /* print PCM card and device numbers */ - return sprintf(buf, "%d %d\n", config->card, config->device); -} - -static DEVICE_ATTR(pcm, S_IRUGO | S_IWUSR, audio_source_pcm_show, NULL); - -static struct device_attribute *audio_source_function_attributes[] = { - &dev_attr_pcm, - NULL -}; - -static struct android_usb_function audio_source_function = { - .name = "audio_source", - .init = audio_source_function_init, - .cleanup = audio_source_function_cleanup, - .bind_config = audio_source_function_bind_config, - .unbind_config = audio_source_function_unbind_config, - .attributes = audio_source_function_attributes, -}; - -static struct android_usb_function *supported_functions[] = { - &adb_function, - &acm_function, - &mtp_function, - &ptp_function, - &rndis_function, - &mass_storage_function, - &accessory_function, - &audio_source_function, - NULL -}; - - -static int android_init_functions(struct android_usb_function **functions, - struct usb_composite_dev *cdev) -{ - struct android_dev *dev = _android_dev; - struct android_usb_function *f; - struct device_attribute **attrs; - struct device_attribute *attr; - int err; - int index = 0; - - for (; (f = *functions++); index++) { - f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name); - f->dev = device_create(android_class, dev->dev, - MKDEV(0, index), f, f->dev_name); - if (IS_ERR(f->dev)) { - pr_err("%s: Failed to create dev %s", __func__, - f->dev_name); - err = PTR_ERR(f->dev); - goto err_create; - } - - if (f->init) { - err = f->init(f, cdev); - if (err) { - pr_err("%s: Failed to init %s", __func__, - f->name); - goto err_out; - } - } - - attrs = f->attributes; - if (attrs) { - while ((attr = *attrs++) && !err) - err = device_create_file(f->dev, attr); - } - if (err) { - pr_err("%s: Failed to create function %s attributes", - __func__, f->name); - goto err_out; - } - } - return 0; - -err_out: - device_destroy(android_class, f->dev->devt); -err_create: - kfree(f->dev_name); - return err; -} - -static void android_cleanup_functions(struct android_usb_function **functions) -{ - struct android_usb_function *f; - - while (*functions) { - f = *functions++; - - if (f->dev) { - device_destroy(android_class, f->dev->devt); - kfree(f->dev_name); - } - - if (f->cleanup) - f->cleanup(f); - } -} - -static int -android_bind_enabled_functions(struct android_dev *dev, - struct usb_configuration *c) -{ - struct android_usb_function *f; - int ret; - - list_for_each_entry(f, &dev->enabled_functions, enabled_list) { - ret = f->bind_config(f, c); - if (ret) { - pr_err("%s: %s failed", __func__, f->name); - return ret; - } - } - return 0; -} - -static void -android_unbind_enabled_functions(struct android_dev *dev, - struct usb_configuration *c) -{ - struct android_usb_function *f; - - list_for_each_entry(f, &dev->enabled_functions, enabled_list) { - if (f->unbind_config) - f->unbind_config(f, c); - } -} - -static int android_enable_function(struct android_dev *dev, char *name) -{ - struct android_usb_function **functions = dev->functions; - struct android_usb_function *f; - while ((f = *functions++)) { - if (!strcmp(name, f->name)) { - list_add_tail(&f->enabled_list, &dev->enabled_functions); - return 0; - } - } - return -EINVAL; -} - -/*-------------------------------------------------------------------------*/ -/* /sys/class/android_usb/android%d/ interface */ - -static ssize_t -functions_show(struct device *pdev, struct device_attribute *attr, char *buf) -{ - struct android_dev *dev = dev_get_drvdata(pdev); - struct android_usb_function *f; - char *buff = buf; - - mutex_lock(&dev->mutex); - - list_for_each_entry(f, &dev->enabled_functions, enabled_list) - buff += sprintf(buff, "%s,", f->name); - - mutex_unlock(&dev->mutex); - - if (buff != buf) - *(buff-1) = '\n'; - return buff - buf; -} - -static ssize_t -functions_store(struct device *pdev, struct device_attribute *attr, - const char *buff, size_t size) -{ - struct android_dev *dev = dev_get_drvdata(pdev); - char *name; - char buf[256], *b; - int err; - - mutex_lock(&dev->mutex); - - if (dev->enabled) { - mutex_unlock(&dev->mutex); - return -EBUSY; - } - - INIT_LIST_HEAD(&dev->enabled_functions); - - strncpy(buf, buff, sizeof(buf)); - b = strim(buf); - - while (b) { - name = strsep(&b, ","); - if (name) { - err = android_enable_function(dev, name); - if (err) - pr_err("android_usb: Cannot enable '%s'", name); - } - } - - mutex_unlock(&dev->mutex); - - return size; -} - -static ssize_t enable_show(struct device *pdev, struct device_attribute *attr, - char *buf) -{ - struct android_dev *dev = dev_get_drvdata(pdev); - return sprintf(buf, "%d\n", dev->enabled); -} - -static ssize_t enable_store(struct device *pdev, struct device_attribute *attr, - const char *buff, size_t size) -{ - struct android_dev *dev = dev_get_drvdata(pdev); - struct usb_composite_dev *cdev = dev->cdev; - struct android_usb_function *f; - int enabled = 0; - - mutex_lock(&dev->mutex); - - sscanf(buff, "%d", &enabled); - if (enabled && !dev->enabled) { - /* update values in composite driver's copy of device descriptor */ - cdev->desc.idVendor = device_desc.idVendor; - cdev->desc.idProduct = device_desc.idProduct; - cdev->desc.bcdDevice = device_desc.bcdDevice; - cdev->desc.bDeviceClass = device_desc.bDeviceClass; - cdev->desc.bDeviceSubClass = device_desc.bDeviceSubClass; - cdev->desc.bDeviceProtocol = device_desc.bDeviceProtocol; - list_for_each_entry(f, &dev->enabled_functions, enabled_list) { - if (f->enable) - f->enable(f); - } - android_enable(dev); - dev->enabled = true; - } else if (!enabled && dev->enabled) { - android_disable(dev); - list_for_each_entry(f, &dev->enabled_functions, enabled_list) { - if (f->disable) - f->disable(f); - } - dev->enabled = false; - } else { - pr_err("android_usb: already %s\n", - dev->enabled ? "enabled" : "disabled"); - } - - mutex_unlock(&dev->mutex); - return size; -} - -static ssize_t state_show(struct device *pdev, struct device_attribute *attr, - char *buf) -{ - struct android_dev *dev = dev_get_drvdata(pdev); - struct usb_composite_dev *cdev = dev->cdev; - char *state = "DISCONNECTED"; - unsigned long flags; - - if (!cdev) - goto out; - - spin_lock_irqsave(&cdev->lock, flags); - if (cdev->config) - state = "CONFIGURED"; - else if (dev->connected) - state = "CONNECTED"; - spin_unlock_irqrestore(&cdev->lock, flags); -out: - return sprintf(buf, "%s\n", state); -} - -#define DESCRIPTOR_ATTR(field, format_string) \ -static ssize_t \ -field ## _show(struct device *dev, struct device_attribute *attr, \ - char *buf) \ -{ \ - return sprintf(buf, format_string, device_desc.field); \ -} \ -static ssize_t \ -field ## _store(struct device *dev, struct device_attribute *attr, \ - const char *buf, size_t size) \ -{ \ - int value; \ - if (sscanf(buf, format_string, &value) == 1) { \ - device_desc.field = value; \ - return size; \ - } \ - return -1; \ -} \ -static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store); - -#define DESCRIPTOR_STRING_ATTR(field, buffer) \ -static ssize_t \ -field ## _show(struct device *dev, struct device_attribute *attr, \ - char *buf) \ -{ \ - return sprintf(buf, "%s", buffer); \ -} \ -static ssize_t \ -field ## _store(struct device *dev, struct device_attribute *attr, \ - const char *buf, size_t size) \ -{ \ - if (size >= sizeof(buffer)) return -EINVAL; \ - return strlcpy(buffer, buf, sizeof(buffer)); \ -} \ -static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store); - - -DESCRIPTOR_ATTR(idVendor, "%04x\n") -DESCRIPTOR_ATTR(idProduct, "%04x\n") -DESCRIPTOR_ATTR(bcdDevice, "%04x\n") -DESCRIPTOR_ATTR(bDeviceClass, "%d\n") -DESCRIPTOR_ATTR(bDeviceSubClass, "%d\n") -DESCRIPTOR_ATTR(bDeviceProtocol, "%d\n") -DESCRIPTOR_STRING_ATTR(iManufacturer, manufacturer_string) -DESCRIPTOR_STRING_ATTR(iProduct, product_string) -DESCRIPTOR_STRING_ATTR(iSerial, serial_string) - -static DEVICE_ATTR(functions, S_IRUGO | S_IWUSR, functions_show, functions_store); -static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store); -static DEVICE_ATTR(state, S_IRUGO, state_show, NULL); - -static struct device_attribute *android_usb_attributes[] = { - &dev_attr_idVendor, - &dev_attr_idProduct, - &dev_attr_bcdDevice, - &dev_attr_bDeviceClass, - &dev_attr_bDeviceSubClass, - &dev_attr_bDeviceProtocol, - &dev_attr_iManufacturer, - &dev_attr_iProduct, - &dev_attr_iSerial, - &dev_attr_functions, - &dev_attr_enable, - &dev_attr_state, - NULL -}; - -/*-------------------------------------------------------------------------*/ -/* Composite driver */ - -static int android_bind_config(struct usb_configuration *c) -{ - struct android_dev *dev = _android_dev; - int ret = 0; - - ret = android_bind_enabled_functions(dev, c); - if (ret) - return ret; - - return 0; -} - -static void android_unbind_config(struct usb_configuration *c) -{ - struct android_dev *dev = _android_dev; - - android_unbind_enabled_functions(dev, c); -} - -static int android_bind(struct usb_composite_dev *cdev) -{ - struct android_dev *dev = _android_dev; - struct usb_gadget *gadget = cdev->gadget; - int gcnum, id, ret; - - usb_gadget_disconnect(gadget); - - ret = android_init_functions(dev->functions, cdev); - if (ret) - return ret; - - /* Allocate string descriptor numbers ... note that string - * contents can be overridden by the composite_dev glue. - */ - id = usb_string_id(cdev); - if (id < 0) - return id; - strings_dev[STRING_MANUFACTURER_IDX].id = id; - device_desc.iManufacturer = id; - - id = usb_string_id(cdev); - if (id < 0) - return id; - strings_dev[STRING_PRODUCT_IDX].id = id; - device_desc.iProduct = id; - - /* Default strings - should be updated by userspace */ - strncpy(manufacturer_string, "Android", sizeof(manufacturer_string) - 1); - strncpy(product_string, "Android", sizeof(product_string) - 1); - strncpy(serial_string, "0123456789ABCDEF", sizeof(serial_string) - 1); - - id = usb_string_id(cdev); - if (id < 0) - return id; - strings_dev[STRING_SERIAL_IDX].id = id; - device_desc.iSerialNumber = id; - - gcnum = usb_gadget_controller_number(gadget); - if (gcnum >= 0) - device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); - else { - /* gadget zero is so simple (for now, no altsettings) that - * it SHOULD NOT have problems with bulk-capable hardware. - * so just warn about unrcognized controllers -- don't panic. - * - * things like configuration and altsetting numbering - * can need hardware-specific attention though. - */ - pr_warning("%s: controller '%s' not recognized\n", - longname, gadget->name); - device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); - } - - dev->cdev = cdev; - - return 0; -} - -static int android_usb_unbind(struct usb_composite_dev *cdev) -{ - struct android_dev *dev = _android_dev; - - cancel_work_sync(&dev->work); - android_cleanup_functions(dev->functions); - return 0; -} - -static struct usb_composite_driver android_usb_driver = { - .name = "android_usb", - .dev = &device_desc, - .strings = dev_strings, - .unbind = android_usb_unbind, -}; - -static int -android_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *c) -{ - struct android_dev *dev = _android_dev; - struct usb_composite_dev *cdev = get_gadget_data(gadget); - struct usb_request *req = cdev->req; - struct android_usb_function *f; - int value = -EOPNOTSUPP; - unsigned long flags; - - req->zero = 0; - req->complete = composite_setup_complete; - req->length = 0; - gadget->ep0->driver_data = cdev; - - list_for_each_entry(f, &dev->enabled_functions, enabled_list) { - if (f->ctrlrequest) { - value = f->ctrlrequest(f, cdev, c); - if (value >= 0) - break; - } - } - - /* Special case the accessory function. - * It needs to handle control requests before it is enabled. - */ - if (value < 0) - value = acc_ctrlrequest(cdev, c); - - if (value < 0) - value = composite_setup(gadget, c); - - spin_lock_irqsave(&cdev->lock, flags); - if (!dev->connected) { - dev->connected = 1; - schedule_work(&dev->work); - } - else if (c->bRequest == USB_REQ_SET_CONFIGURATION && cdev->config) { - schedule_work(&dev->work); - } - spin_unlock_irqrestore(&cdev->lock, flags); - - return value; -} - -static void android_disconnect(struct usb_gadget *gadget) -{ - struct android_dev *dev = _android_dev; - struct usb_composite_dev *cdev = get_gadget_data(gadget); - unsigned long flags; - - composite_disconnect(gadget); - /* accessory HID support can be active while the - accessory function is not actually enabled, - so we need to inform it when we are disconnected. - */ - acc_disconnect(); - - spin_lock_irqsave(&cdev->lock, flags); - dev->connected = 0; - schedule_work(&dev->work); - spin_unlock_irqrestore(&cdev->lock, flags); -} - -static int android_create_device(struct android_dev *dev) -{ - struct device_attribute **attrs = android_usb_attributes; - struct device_attribute *attr; - int err; - - dev->dev = device_create(android_class, NULL, - MKDEV(0, 0), NULL, "android0"); - if (IS_ERR(dev->dev)) - return PTR_ERR(dev->dev); - - dev_set_drvdata(dev->dev, dev); - - while ((attr = *attrs++)) { - err = device_create_file(dev->dev, attr); - if (err) { - device_destroy(android_class, dev->dev->devt); - return err; - } - } - return 0; -} - - -static int __init init(void) -{ - struct android_dev *dev; - int err; - - android_class = class_create(THIS_MODULE, "android_usb"); - if (IS_ERR(android_class)) - return PTR_ERR(android_class); - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - dev->disable_depth = 1; - dev->functions = supported_functions; - INIT_LIST_HEAD(&dev->enabled_functions); - INIT_WORK(&dev->work, android_work); - mutex_init(&dev->mutex); - - err = android_create_device(dev); - if (err) { - class_destroy(android_class); - kfree(dev); - return err; - } - - _android_dev = dev; - - /* Override composite driver functions */ - composite_driver.setup = android_setup; - composite_driver.disconnect = android_disconnect; - - return usb_composite_probe(&android_usb_driver, android_bind); -} -module_init(init); - -static void __exit cleanup(void) -{ - usb_composite_unregister(&android_usb_driver); - class_destroy(android_class); - kfree(_android_dev); - _android_dev = NULL; -} -module_exit(cleanup); diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 1d88a80086a3..5cbb1a41c223 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -476,7 +476,6 @@ static int set_config(struct usb_composite_dev *cdev, power = c->bMaxPower ? (2 * c->bMaxPower) : CONFIG_USB_GADGET_VBUS_DRAW; done: usb_gadget_vbus_draw(gadget, power); - if (result >= 0 && cdev->delayed_status) result = USB_GADGET_DELAYED_STATUS; return result; @@ -524,7 +523,6 @@ int usb_add_config(struct usb_composite_dev *cdev, INIT_LIST_HEAD(&config->functions); config->next_interface_id = 0; - memset(config->interface, '\0', sizeof(config->interface)); status = bind(config); if (status < 0) { @@ -564,46 +562,6 @@ done: return status; } -static int unbind_config(struct usb_composite_dev *cdev, - struct usb_configuration *config) -{ - while (!list_empty(&config->functions)) { - struct usb_function *f; - - f = list_first_entry(&config->functions, - struct usb_function, list); - list_del(&f->list); - if (f->unbind) { - DBG(cdev, "unbind function '%s'/%p\n", f->name, f); - f->unbind(config, f); - /* may free memory for "f" */ - } - } - if (config->unbind) { - DBG(cdev, "unbind config '%s'/%p\n", config->label, config); - config->unbind(config); - /* may free memory for "c" */ - } - return 0; -} - -int usb_remove_config(struct usb_composite_dev *cdev, - struct usb_configuration *config) -{ - unsigned long flags; - - spin_lock_irqsave(&cdev->lock, flags); - - if (cdev->config == config) - reset_config(cdev); - - list_del(&config->list); - - spin_unlock_irqrestore(&cdev->lock, flags); - - return unbind_config(cdev, config); -} - /*-------------------------------------------------------------------------*/ /* We support strings in multiple languages ... string descriptor zero @@ -1083,10 +1041,28 @@ composite_unbind(struct usb_gadget *gadget) while (!list_empty(&cdev->configs)) { struct usb_configuration *c; + c = list_first_entry(&cdev->configs, struct usb_configuration, list); + while (!list_empty(&c->functions)) { + struct usb_function *f; + + f = list_first_entry(&c->functions, + struct usb_function, list); + list_del(&f->list); + if (f->unbind) { + DBG(cdev, "unbind function '%s'/%p\n", + f->name, f); + f->unbind(c, f); + /* may free memory for "f" */ + } + } list_del(&c->list); - unbind_config(cdev, c); + if (c->unbind) { + DBG(cdev, "unbind config '%s'/%p\n", c->label, c); + c->unbind(c); + /* may free memory for "c" */ + } } if (composite->unbind) composite->unbind(cdev); diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 90977fc04ea4..d3dcabc1a5fc 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -122,7 +122,10 @@ static const char ep0name [] = "ep0"; static const char *const ep_name [] = { ep0name, /* everyone has ep0 */ - /* act like a pxa250: fifteen fixed function endpoints */ + /* act like a net2280: high speed, six configurable endpoints */ + "ep-a", "ep-b", "ep-c", "ep-d", "ep-e", "ep-f", + + /* or like pxa250: fifteen fixed function endpoints */ "ep1in-bulk", "ep2out-bulk", "ep3in-iso", "ep4out-iso", "ep5in-int", "ep6in-bulk", "ep7out-bulk", "ep8in-iso", "ep9out-iso", "ep10in-int", "ep11in-bulk", "ep12out-bulk", "ep13in-iso", "ep14out-iso", @@ -130,10 +133,6 @@ static const char *const ep_name [] = { /* or like sa1100: two fixed function endpoints */ "ep1out-bulk", "ep2in-bulk", - - /* and now some generic EPs so we have enough in multi config */ - "ep3out", "ep4in", "ep5out", "ep6out", "ep7in", "ep8out", "ep9in", - "ep10out", "ep11out", "ep12in", "ep13out", "ep14in", "ep15out", }; #define DUMMY_ENDPOINTS ARRAY_SIZE(ep_name) diff --git a/drivers/usb/gadget/f_accessory.c b/drivers/usb/gadget/f_accessory.c deleted file mode 100644 index 1df88a6bf7ec..000000000000 --- a/drivers/usb/gadget/f_accessory.c +++ /dev/null @@ -1,1176 +0,0 @@ -/* - * Gadget Function Driver for Android USB accessories - * - * Copyright (C) 2011 Google, Inc. - * Author: Mike Lockwood - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -/* #define DEBUG */ -/* #define VERBOSE_DEBUG */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define BULK_BUFFER_SIZE 16384 -#define ACC_STRING_SIZE 256 - -#define PROTOCOL_VERSION 2 - -/* String IDs */ -#define INTERFACE_STRING_INDEX 0 - -/* number of tx and rx requests to allocate */ -#define TX_REQ_MAX 4 -#define RX_REQ_MAX 2 - -struct acc_hid_dev { - struct list_head list; - struct hid_device *hid; - struct acc_dev *dev; - /* accessory defined ID */ - int id; - /* HID report descriptor */ - u8 *report_desc; - /* length of HID report descriptor */ - int report_desc_len; - /* number of bytes of report_desc we have received so far */ - int report_desc_offset; -}; - -struct acc_dev { - struct usb_function function; - struct usb_composite_dev *cdev; - spinlock_t lock; - - struct usb_ep *ep_in; - struct usb_ep *ep_out; - - /* set to 1 when we connect */ - int online:1; - /* Set to 1 when we disconnect. - * Not cleared until our file is closed. - */ - int disconnected:1; - - /* strings sent by the host */ - char manufacturer[ACC_STRING_SIZE]; - char model[ACC_STRING_SIZE]; - char description[ACC_STRING_SIZE]; - char version[ACC_STRING_SIZE]; - char uri[ACC_STRING_SIZE]; - char serial[ACC_STRING_SIZE]; - - /* for acc_complete_set_string */ - int string_index; - - /* set to 1 if we have a pending start request */ - int start_requested; - - int audio_mode; - - /* synchronize access to our device file */ - atomic_t open_excl; - - struct list_head tx_idle; - - wait_queue_head_t read_wq; - wait_queue_head_t write_wq; - struct usb_request *rx_req[RX_REQ_MAX]; - int rx_done; - - /* delayed work for handling ACCESSORY_START */ - struct delayed_work start_work; - - /* worker for registering and unregistering hid devices */ - struct work_struct hid_work; - - /* list of active HID devices */ - struct list_head hid_list; - - /* list of new HID devices to register */ - struct list_head new_hid_list; - - /* list of dead HID devices to unregister */ - struct list_head dead_hid_list; -}; - -static struct usb_interface_descriptor acc_interface_desc = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = USB_SUBCLASS_VENDOR_SPEC, - .bInterfaceProtocol = 0, -}; - -static struct usb_endpoint_descriptor acc_highspeed_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor acc_highspeed_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor acc_fullspeed_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_endpoint_descriptor acc_fullspeed_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_descriptor_header *fs_acc_descs[] = { - (struct usb_descriptor_header *) &acc_interface_desc, - (struct usb_descriptor_header *) &acc_fullspeed_in_desc, - (struct usb_descriptor_header *) &acc_fullspeed_out_desc, - NULL, -}; - -static struct usb_descriptor_header *hs_acc_descs[] = { - (struct usb_descriptor_header *) &acc_interface_desc, - (struct usb_descriptor_header *) &acc_highspeed_in_desc, - (struct usb_descriptor_header *) &acc_highspeed_out_desc, - NULL, -}; - -static struct usb_string acc_string_defs[] = { - [INTERFACE_STRING_INDEX].s = "Android Accessory Interface", - { }, /* end of list */ -}; - -static struct usb_gadget_strings acc_string_table = { - .language = 0x0409, /* en-US */ - .strings = acc_string_defs, -}; - -static struct usb_gadget_strings *acc_strings[] = { - &acc_string_table, - NULL, -}; - -/* temporary variable used between acc_open() and acc_gadget_bind() */ -static struct acc_dev *_acc_dev; - -static inline struct acc_dev *func_to_dev(struct usb_function *f) -{ - return container_of(f, struct acc_dev, function); -} - -static struct usb_request *acc_request_new(struct usb_ep *ep, int buffer_size) -{ - struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL); - if (!req) - return NULL; - - /* now allocate buffers for the requests */ - req->buf = kmalloc(buffer_size, GFP_KERNEL); - if (!req->buf) { - usb_ep_free_request(ep, req); - return NULL; - } - - return req; -} - -static void acc_request_free(struct usb_request *req, struct usb_ep *ep) -{ - if (req) { - kfree(req->buf); - usb_ep_free_request(ep, req); - } -} - -/* add a request to the tail of a list */ -static void req_put(struct acc_dev *dev, struct list_head *head, - struct usb_request *req) -{ - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - list_add_tail(&req->list, head); - spin_unlock_irqrestore(&dev->lock, flags); -} - -/* remove a request from the head of a list */ -static struct usb_request *req_get(struct acc_dev *dev, struct list_head *head) -{ - unsigned long flags; - struct usb_request *req; - - spin_lock_irqsave(&dev->lock, flags); - if (list_empty(head)) { - req = 0; - } else { - req = list_first_entry(head, struct usb_request, list); - list_del(&req->list); - } - spin_unlock_irqrestore(&dev->lock, flags); - return req; -} - -static void acc_set_disconnected(struct acc_dev *dev) -{ - dev->online = 0; - dev->disconnected = 1; -} - -static void acc_complete_in(struct usb_ep *ep, struct usb_request *req) -{ - struct acc_dev *dev = _acc_dev; - - if (req->status != 0) - acc_set_disconnected(dev); - - req_put(dev, &dev->tx_idle, req); - - wake_up(&dev->write_wq); -} - -static void acc_complete_out(struct usb_ep *ep, struct usb_request *req) -{ - struct acc_dev *dev = _acc_dev; - - dev->rx_done = 1; - if (req->status != 0) - acc_set_disconnected(dev); - - wake_up(&dev->read_wq); -} - -static void acc_complete_set_string(struct usb_ep *ep, struct usb_request *req) -{ - struct acc_dev *dev = ep->driver_data; - char *string_dest = NULL; - int length = req->actual; - - if (req->status != 0) { - pr_err("acc_complete_set_string, err %d\n", req->status); - return; - } - - switch (dev->string_index) { - case ACCESSORY_STRING_MANUFACTURER: - string_dest = dev->manufacturer; - break; - case ACCESSORY_STRING_MODEL: - string_dest = dev->model; - break; - case ACCESSORY_STRING_DESCRIPTION: - string_dest = dev->description; - break; - case ACCESSORY_STRING_VERSION: - string_dest = dev->version; - break; - case ACCESSORY_STRING_URI: - string_dest = dev->uri; - break; - case ACCESSORY_STRING_SERIAL: - string_dest = dev->serial; - break; - } - if (string_dest) { - unsigned long flags; - - if (length >= ACC_STRING_SIZE) - length = ACC_STRING_SIZE - 1; - - spin_lock_irqsave(&dev->lock, flags); - memcpy(string_dest, req->buf, length); - /* ensure zero termination */ - string_dest[length] = 0; - spin_unlock_irqrestore(&dev->lock, flags); - } else { - pr_err("unknown accessory string index %d\n", - dev->string_index); - } -} - -static void acc_complete_set_hid_report_desc(struct usb_ep *ep, - struct usb_request *req) -{ - struct acc_hid_dev *hid = req->context; - struct acc_dev *dev = hid->dev; - int length = req->actual; - - if (req->status != 0) { - pr_err("acc_complete_set_hid_report_desc, err %d\n", - req->status); - return; - } - - memcpy(hid->report_desc + hid->report_desc_offset, req->buf, length); - hid->report_desc_offset += length; - if (hid->report_desc_offset == hid->report_desc_len) { - /* After we have received the entire report descriptor - * we schedule work to initialize the HID device - */ - schedule_work(&dev->hid_work); - } -} - -static void acc_complete_send_hid_event(struct usb_ep *ep, - struct usb_request *req) -{ - struct acc_hid_dev *hid = req->context; - int length = req->actual; - - if (req->status != 0) { - pr_err("acc_complete_send_hid_event, err %d\n", req->status); - return; - } - - hid_report_raw_event(hid->hid, HID_INPUT_REPORT, req->buf, length, 1); -} - -static int acc_hid_parse(struct hid_device *hid) -{ - struct acc_hid_dev *hdev = hid->driver_data; - - hid_parse_report(hid, hdev->report_desc, hdev->report_desc_len); - return 0; -} - -static int acc_hid_start(struct hid_device *hid) -{ - return 0; -} - -static void acc_hid_stop(struct hid_device *hid) -{ -} - -static int acc_hid_open(struct hid_device *hid) -{ - return 0; -} - -static void acc_hid_close(struct hid_device *hid) -{ -} - -static struct hid_ll_driver acc_hid_ll_driver = { - .parse = acc_hid_parse, - .start = acc_hid_start, - .stop = acc_hid_stop, - .open = acc_hid_open, - .close = acc_hid_close, -}; - -static struct acc_hid_dev *acc_hid_new(struct acc_dev *dev, - int id, int desc_len) -{ - struct acc_hid_dev *hdev; - - hdev = kzalloc(sizeof(*hdev), GFP_ATOMIC); - if (!hdev) - return NULL; - hdev->report_desc = kzalloc(desc_len, GFP_ATOMIC); - if (!hdev->report_desc) { - kfree(hdev); - return NULL; - } - hdev->dev = dev; - hdev->id = id; - hdev->report_desc_len = desc_len; - - return hdev; -} - -static struct acc_hid_dev *acc_hid_get(struct list_head *list, int id) -{ - struct acc_hid_dev *hid; - - list_for_each_entry(hid, list, list) { - if (hid->id == id) - return hid; - } - return NULL; -} - -static int acc_register_hid(struct acc_dev *dev, int id, int desc_length) -{ - struct acc_hid_dev *hid; - unsigned long flags; - - /* report descriptor length must be > 0 */ - if (desc_length <= 0) - return -EINVAL; - - spin_lock_irqsave(&dev->lock, flags); - /* replace HID if one already exists with this ID */ - hid = acc_hid_get(&dev->hid_list, id); - if (!hid) - hid = acc_hid_get(&dev->new_hid_list, id); - if (hid) - list_move(&hid->list, &dev->dead_hid_list); - - hid = acc_hid_new(dev, id, desc_length); - if (!hid) { - spin_unlock_irqrestore(&dev->lock, flags); - return -ENOMEM; - } - - list_add(&hid->list, &dev->new_hid_list); - spin_unlock_irqrestore(&dev->lock, flags); - - /* schedule work to register the HID device */ - schedule_work(&dev->hid_work); - return 0; -} - -static int acc_unregister_hid(struct acc_dev *dev, int id) -{ - struct acc_hid_dev *hid; - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - hid = acc_hid_get(&dev->hid_list, id); - if (!hid) - hid = acc_hid_get(&dev->new_hid_list, id); - if (!hid) { - spin_unlock_irqrestore(&dev->lock, flags); - return -EINVAL; - } - - list_move(&hid->list, &dev->dead_hid_list); - spin_unlock_irqrestore(&dev->lock, flags); - - schedule_work(&dev->hid_work); - return 0; -} - -static int __init create_bulk_endpoints(struct acc_dev *dev, - struct usb_endpoint_descriptor *in_desc, - struct usb_endpoint_descriptor *out_desc) -{ - struct usb_composite_dev *cdev = dev->cdev; - struct usb_request *req; - struct usb_ep *ep; - int i; - - DBG(cdev, "create_bulk_endpoints dev: %p\n", dev); - - ep = usb_ep_autoconfig(cdev->gadget, in_desc); - if (!ep) { - DBG(cdev, "usb_ep_autoconfig for ep_in failed\n"); - return -ENODEV; - } - DBG(cdev, "usb_ep_autoconfig for ep_in got %s\n", ep->name); - ep->driver_data = dev; /* claim the endpoint */ - dev->ep_in = ep; - - ep = usb_ep_autoconfig(cdev->gadget, out_desc); - if (!ep) { - DBG(cdev, "usb_ep_autoconfig for ep_out failed\n"); - return -ENODEV; - } - DBG(cdev, "usb_ep_autoconfig for ep_out got %s\n", ep->name); - ep->driver_data = dev; /* claim the endpoint */ - dev->ep_out = ep; - - ep = usb_ep_autoconfig(cdev->gadget, out_desc); - if (!ep) { - DBG(cdev, "usb_ep_autoconfig for ep_out failed\n"); - return -ENODEV; - } - DBG(cdev, "usb_ep_autoconfig for ep_out got %s\n", ep->name); - ep->driver_data = dev; /* claim the endpoint */ - dev->ep_out = ep; - - /* now allocate requests for our endpoints */ - for (i = 0; i < TX_REQ_MAX; i++) { - req = acc_request_new(dev->ep_in, BULK_BUFFER_SIZE); - if (!req) - goto fail; - req->complete = acc_complete_in; - req_put(dev, &dev->tx_idle, req); - } - for (i = 0; i < RX_REQ_MAX; i++) { - req = acc_request_new(dev->ep_out, BULK_BUFFER_SIZE); - if (!req) - goto fail; - req->complete = acc_complete_out; - dev->rx_req[i] = req; - } - - return 0; - -fail: - pr_err("acc_bind() could not allocate requests\n"); - while ((req = req_get(dev, &dev->tx_idle))) - acc_request_free(req, dev->ep_in); - for (i = 0; i < RX_REQ_MAX; i++) - acc_request_free(dev->rx_req[i], dev->ep_out); - return -1; -} - -static ssize_t acc_read(struct file *fp, char __user *buf, - size_t count, loff_t *pos) -{ - struct acc_dev *dev = fp->private_data; - struct usb_request *req; - int r = count, xfer; - int ret = 0; - - pr_debug("acc_read(%d)\n", count); - - if (dev->disconnected) - return -ENODEV; - - if (count > BULK_BUFFER_SIZE) - count = BULK_BUFFER_SIZE; - - /* we will block until we're online */ - pr_debug("acc_read: waiting for online\n"); - ret = wait_event_interruptible(dev->read_wq, dev->online); - if (ret < 0) { - r = ret; - goto done; - } - -requeue_req: - /* queue a request */ - req = dev->rx_req[0]; - req->length = count; - dev->rx_done = 0; - ret = usb_ep_queue(dev->ep_out, req, GFP_KERNEL); - if (ret < 0) { - r = -EIO; - goto done; - } else { - pr_debug("rx %p queue\n", req); - } - - /* wait for a request to complete */ - ret = wait_event_interruptible(dev->read_wq, dev->rx_done); - if (ret < 0) { - r = ret; - usb_ep_dequeue(dev->ep_out, req); - goto done; - } - if (dev->online) { - /* If we got a 0-len packet, throw it back and try again. */ - if (req->actual == 0) - goto requeue_req; - - pr_debug("rx %p %d\n", req, req->actual); - xfer = (req->actual < count) ? req->actual : count; - r = xfer; - if (copy_to_user(buf, req->buf, xfer)) - r = -EFAULT; - } else - r = -EIO; - -done: - pr_debug("acc_read returning %d\n", r); - return r; -} - -static ssize_t acc_write(struct file *fp, const char __user *buf, - size_t count, loff_t *pos) -{ - struct acc_dev *dev = fp->private_data; - struct usb_request *req = 0; - int r = count, xfer; - int ret; - - pr_debug("acc_write(%d)\n", count); - - if (!dev->online || dev->disconnected) - return -ENODEV; - - while (count > 0) { - if (!dev->online) { - pr_debug("acc_write dev->error\n"); - r = -EIO; - break; - } - - /* get an idle tx request to use */ - req = 0; - ret = wait_event_interruptible(dev->write_wq, - ((req = req_get(dev, &dev->tx_idle)) || !dev->online)); - if (!req) { - r = ret; - break; - } - - if (count > BULK_BUFFER_SIZE) - xfer = BULK_BUFFER_SIZE; - else - xfer = count; - if (copy_from_user(req->buf, buf, xfer)) { - r = -EFAULT; - break; - } - - req->length = xfer; - ret = usb_ep_queue(dev->ep_in, req, GFP_KERNEL); - if (ret < 0) { - pr_debug("acc_write: xfer error %d\n", ret); - r = -EIO; - break; - } - - buf += xfer; - count -= xfer; - - /* zero this so we don't try to free it on error exit */ - req = 0; - } - - if (req) - req_put(dev, &dev->tx_idle, req); - - pr_debug("acc_write returning %d\n", r); - return r; -} - -static long acc_ioctl(struct file *fp, unsigned code, unsigned long value) -{ - struct acc_dev *dev = fp->private_data; - char *src = NULL; - int ret; - - switch (code) { - case ACCESSORY_GET_STRING_MANUFACTURER: - src = dev->manufacturer; - break; - case ACCESSORY_GET_STRING_MODEL: - src = dev->model; - break; - case ACCESSORY_GET_STRING_DESCRIPTION: - src = dev->description; - break; - case ACCESSORY_GET_STRING_VERSION: - src = dev->version; - break; - case ACCESSORY_GET_STRING_URI: - src = dev->uri; - break; - case ACCESSORY_GET_STRING_SERIAL: - src = dev->serial; - break; - case ACCESSORY_IS_START_REQUESTED: - return dev->start_requested; - case ACCESSORY_GET_AUDIO_MODE: - return dev->audio_mode; - } - if (!src) - return -EINVAL; - - ret = strlen(src) + 1; - if (copy_to_user((void __user *)value, src, ret)) - ret = -EFAULT; - return ret; -} - -static int acc_open(struct inode *ip, struct file *fp) -{ - printk(KERN_INFO "acc_open\n"); - if (atomic_xchg(&_acc_dev->open_excl, 1)) - return -EBUSY; - - _acc_dev->disconnected = 0; - fp->private_data = _acc_dev; - return 0; -} - -static int acc_release(struct inode *ip, struct file *fp) -{ - printk(KERN_INFO "acc_release\n"); - - WARN_ON(!atomic_xchg(&_acc_dev->open_excl, 0)); - _acc_dev->disconnected = 0; - return 0; -} - -/* file operations for /dev/usb_accessory */ -static const struct file_operations acc_fops = { - .owner = THIS_MODULE, - .read = acc_read, - .write = acc_write, - .unlocked_ioctl = acc_ioctl, - .open = acc_open, - .release = acc_release, -}; - -static int acc_hid_probe(struct hid_device *hdev, - const struct hid_device_id *id) -{ - int ret; - - ret = hid_parse(hdev); - if (ret) - return ret; - return hid_hw_start(hdev, HID_CONNECT_DEFAULT); -} - -static struct miscdevice acc_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "usb_accessory", - .fops = &acc_fops, -}; - -static const struct hid_device_id acc_hid_table[] = { - { HID_USB_DEVICE(HID_ANY_ID, HID_ANY_ID) }, - { } -}; - -static struct hid_driver acc_hid_driver = { - .name = "USB accessory", - .id_table = acc_hid_table, - .probe = acc_hid_probe, -}; - -static int acc_ctrlrequest(struct usb_composite_dev *cdev, - const struct usb_ctrlrequest *ctrl) -{ - struct acc_dev *dev = _acc_dev; - int value = -EOPNOTSUPP; - struct acc_hid_dev *hid; - int offset; - u8 b_requestType = ctrl->bRequestType; - u8 b_request = ctrl->bRequest; - u16 w_index = le16_to_cpu(ctrl->wIndex); - u16 w_value = le16_to_cpu(ctrl->wValue); - u16 w_length = le16_to_cpu(ctrl->wLength); - unsigned long flags; - -/* - printk(KERN_INFO "acc_ctrlrequest " - "%02x.%02x v%04x i%04x l%u\n", - b_requestType, b_request, - w_value, w_index, w_length); -*/ - - if (b_requestType == (USB_DIR_OUT | USB_TYPE_VENDOR)) { - if (b_request == ACCESSORY_START) { - dev->start_requested = 1; - schedule_delayed_work( - &dev->start_work, msecs_to_jiffies(10)); - value = 0; - } else if (b_request == ACCESSORY_SEND_STRING) { - dev->string_index = w_index; - cdev->gadget->ep0->driver_data = dev; - cdev->req->complete = acc_complete_set_string; - value = w_length; - } else if (b_request == ACCESSORY_SET_AUDIO_MODE && - w_index == 0 && w_length == 0) { - dev->audio_mode = w_value; - value = 0; - } else if (b_request == ACCESSORY_REGISTER_HID) { - value = acc_register_hid(dev, w_value, w_index); - } else if (b_request == ACCESSORY_UNREGISTER_HID) { - value = acc_unregister_hid(dev, w_value); - } else if (b_request == ACCESSORY_SET_HID_REPORT_DESC) { - spin_lock_irqsave(&dev->lock, flags); - hid = acc_hid_get(&dev->new_hid_list, w_value); - spin_unlock_irqrestore(&dev->lock, flags); - if (!hid) { - value = -EINVAL; - goto err; - } - offset = w_index; - if (offset != hid->report_desc_offset - || offset + w_length > hid->report_desc_len) { - value = -EINVAL; - goto err; - } - cdev->req->context = hid; - cdev->req->complete = acc_complete_set_hid_report_desc; - value = w_length; - } else if (b_request == ACCESSORY_SEND_HID_EVENT) { - spin_lock_irqsave(&dev->lock, flags); - hid = acc_hid_get(&dev->hid_list, w_value); - spin_unlock_irqrestore(&dev->lock, flags); - if (!hid) { - value = -EINVAL; - goto err; - } - cdev->req->context = hid; - cdev->req->complete = acc_complete_send_hid_event; - value = w_length; - } - } else if (b_requestType == (USB_DIR_IN | USB_TYPE_VENDOR)) { - if (b_request == ACCESSORY_GET_PROTOCOL) { - *((u16 *)cdev->req->buf) = PROTOCOL_VERSION; - value = sizeof(u16); - - /* clear strings left over from a previous session */ - memset(dev->manufacturer, 0, sizeof(dev->manufacturer)); - memset(dev->model, 0, sizeof(dev->model)); - memset(dev->description, 0, sizeof(dev->description)); - memset(dev->version, 0, sizeof(dev->version)); - memset(dev->uri, 0, sizeof(dev->uri)); - memset(dev->serial, 0, sizeof(dev->serial)); - dev->start_requested = 0; - dev->audio_mode = 0; - } - } - - if (value >= 0) { - cdev->req->zero = 0; - cdev->req->length = value; - value = usb_ep_queue(cdev->gadget->ep0, cdev->req, GFP_ATOMIC); - if (value < 0) - ERROR(cdev, "%s setup response queue error\n", - __func__); - } - -err: - if (value == -EOPNOTSUPP) - VDBG(cdev, - "unknown class-specific control req " - "%02x.%02x v%04x i%04x l%u\n", - ctrl->bRequestType, ctrl->bRequest, - w_value, w_index, w_length); - return value; -} - -static int -acc_function_bind(struct usb_configuration *c, struct usb_function *f) -{ - struct usb_composite_dev *cdev = c->cdev; - struct acc_dev *dev = func_to_dev(f); - int id; - int ret; - - DBG(cdev, "acc_function_bind dev: %p\n", dev); - - ret = hid_register_driver(&acc_hid_driver); - if (ret) - return ret; - - dev->start_requested = 0; - - /* allocate interface ID(s) */ - id = usb_interface_id(c, f); - if (id < 0) - return id; - acc_interface_desc.bInterfaceNumber = id; - - /* allocate endpoints */ - ret = create_bulk_endpoints(dev, &acc_fullspeed_in_desc, - &acc_fullspeed_out_desc); - if (ret) - return ret; - - /* support high speed hardware */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - acc_highspeed_in_desc.bEndpointAddress = - acc_fullspeed_in_desc.bEndpointAddress; - acc_highspeed_out_desc.bEndpointAddress = - acc_fullspeed_out_desc.bEndpointAddress; - } - - DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", - gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", - f->name, dev->ep_in->name, dev->ep_out->name); - return 0; -} - -static void -kill_all_hid_devices(struct acc_dev *dev) -{ - struct acc_hid_dev *hid; - struct list_head *entry, *temp; - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - list_for_each_safe(entry, temp, &dev->hid_list) { - hid = list_entry(entry, struct acc_hid_dev, list); - list_del(&hid->list); - list_add(&hid->list, &dev->dead_hid_list); - } - list_for_each_safe(entry, temp, &dev->new_hid_list) { - hid = list_entry(entry, struct acc_hid_dev, list); - list_del(&hid->list); - list_add(&hid->list, &dev->dead_hid_list); - } - spin_unlock_irqrestore(&dev->lock, flags); - - schedule_work(&dev->hid_work); -} - -static void -acc_hid_unbind(struct acc_dev *dev) -{ - hid_unregister_driver(&acc_hid_driver); - kill_all_hid_devices(dev); -} - -static void -acc_function_unbind(struct usb_configuration *c, struct usb_function *f) -{ - struct acc_dev *dev = func_to_dev(f); - struct usb_request *req; - int i; - - while ((req = req_get(dev, &dev->tx_idle))) - acc_request_free(req, dev->ep_in); - for (i = 0; i < RX_REQ_MAX; i++) - acc_request_free(dev->rx_req[i], dev->ep_out); - - acc_hid_unbind(dev); -} - -static void acc_start_work(struct work_struct *data) -{ - char *envp[2] = { "ACCESSORY=START", NULL }; - kobject_uevent_env(&acc_device.this_device->kobj, KOBJ_CHANGE, envp); -} - -static int acc_hid_init(struct acc_hid_dev *hdev) -{ - struct hid_device *hid; - int ret; - - hid = hid_allocate_device(); - if (IS_ERR(hid)) - return PTR_ERR(hid); - - hid->ll_driver = &acc_hid_ll_driver; - hid->dev.parent = acc_device.this_device; - - hid->bus = BUS_USB; - hid->vendor = HID_ANY_ID; - hid->product = HID_ANY_ID; - hid->driver_data = hdev; - ret = hid_add_device(hid); - if (ret) { - pr_err("can't add hid device: %d\n", ret); - hid_destroy_device(hid); - return ret; - } - - hdev->hid = hid; - return 0; -} - -static void acc_hid_delete(struct acc_hid_dev *hid) -{ - kfree(hid->report_desc); - kfree(hid); -} - -static void acc_hid_work(struct work_struct *data) -{ - struct acc_dev *dev = _acc_dev; - struct list_head *entry, *temp; - struct acc_hid_dev *hid; - struct list_head new_list, dead_list; - unsigned long flags; - - INIT_LIST_HEAD(&new_list); - - spin_lock_irqsave(&dev->lock, flags); - - /* copy hids that are ready for initialization to new_list */ - list_for_each_safe(entry, temp, &dev->new_hid_list) { - hid = list_entry(entry, struct acc_hid_dev, list); - if (hid->report_desc_offset == hid->report_desc_len) - list_move(&hid->list, &new_list); - } - - if (list_empty(&dev->dead_hid_list)) { - INIT_LIST_HEAD(&dead_list); - } else { - /* move all of dev->dead_hid_list to dead_list */ - dead_list.prev = dev->dead_hid_list.prev; - dead_list.next = dev->dead_hid_list.next; - dead_list.next->prev = &dead_list; - dead_list.prev->next = &dead_list; - INIT_LIST_HEAD(&dev->dead_hid_list); - } - - spin_unlock_irqrestore(&dev->lock, flags); - - /* register new HID devices */ - list_for_each_safe(entry, temp, &new_list) { - hid = list_entry(entry, struct acc_hid_dev, list); - if (acc_hid_init(hid)) { - pr_err("can't add HID device %p\n", hid); - acc_hid_delete(hid); - } else { - spin_lock_irqsave(&dev->lock, flags); - list_move(&hid->list, &dev->hid_list); - spin_unlock_irqrestore(&dev->lock, flags); - } - } - - /* remove dead HID devices */ - list_for_each_safe(entry, temp, &dead_list) { - hid = list_entry(entry, struct acc_hid_dev, list); - list_del(&hid->list); - if (hid->hid) - hid_destroy_device(hid->hid); - acc_hid_delete(hid); - } -} - -static int acc_function_set_alt(struct usb_function *f, - unsigned intf, unsigned alt) -{ - struct acc_dev *dev = func_to_dev(f); - struct usb_composite_dev *cdev = f->config->cdev; - int ret; - - DBG(cdev, "acc_function_set_alt intf: %d alt: %d\n", intf, alt); - ret = usb_ep_enable(dev->ep_in, - ep_choose(cdev->gadget, - &acc_highspeed_in_desc, - &acc_fullspeed_in_desc)); - if (ret) - return ret; - ret = usb_ep_enable(dev->ep_out, - ep_choose(cdev->gadget, - &acc_highspeed_out_desc, - &acc_fullspeed_out_desc)); - if (ret) { - usb_ep_disable(dev->ep_in); - return ret; - } - - dev->online = 1; - - /* readers may be blocked waiting for us to go online */ - wake_up(&dev->read_wq); - return 0; -} - -static void acc_function_disable(struct usb_function *f) -{ - struct acc_dev *dev = func_to_dev(f); - struct usb_composite_dev *cdev = dev->cdev; - - DBG(cdev, "acc_function_disable\n"); - acc_set_disconnected(dev); - usb_ep_disable(dev->ep_in); - usb_ep_disable(dev->ep_out); - - /* readers may be blocked waiting for us to go online */ - wake_up(&dev->read_wq); - - VDBG(cdev, "%s disabled\n", dev->function.name); -} - -static int acc_bind_config(struct usb_configuration *c) -{ - struct acc_dev *dev = _acc_dev; - int ret; - - printk(KERN_INFO "acc_bind_config\n"); - - /* allocate a string ID for our interface */ - if (acc_string_defs[INTERFACE_STRING_INDEX].id == 0) { - ret = usb_string_id(c->cdev); - if (ret < 0) - return ret; - acc_string_defs[INTERFACE_STRING_INDEX].id = ret; - acc_interface_desc.iInterface = ret; - } - - dev->cdev = c->cdev; - dev->function.name = "accessory"; - dev->function.strings = acc_strings, - dev->function.descriptors = fs_acc_descs; - dev->function.hs_descriptors = hs_acc_descs; - dev->function.bind = acc_function_bind; - dev->function.unbind = acc_function_unbind; - dev->function.set_alt = acc_function_set_alt; - dev->function.disable = acc_function_disable; - - return usb_add_function(c, &dev->function); -} - -static int acc_setup(void) -{ - struct acc_dev *dev; - int ret; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - spin_lock_init(&dev->lock); - init_waitqueue_head(&dev->read_wq); - init_waitqueue_head(&dev->write_wq); - atomic_set(&dev->open_excl, 0); - INIT_LIST_HEAD(&dev->tx_idle); - INIT_LIST_HEAD(&dev->hid_list); - INIT_LIST_HEAD(&dev->new_hid_list); - INIT_LIST_HEAD(&dev->dead_hid_list); - INIT_DELAYED_WORK(&dev->start_work, acc_start_work); - INIT_WORK(&dev->hid_work, acc_hid_work); - - /* _acc_dev must be set before calling usb_gadget_register_driver */ - _acc_dev = dev; - - ret = misc_register(&acc_device); - if (ret) - goto err; - - return 0; - -err: - kfree(dev); - pr_err("USB accessory gadget driver failed to initialize\n"); - return ret; -} - -static void acc_disconnect(void) -{ - /* unregister all HID devices if USB is disconnected */ - kill_all_hid_devices(_acc_dev); -} - -static void acc_cleanup(void) -{ - misc_deregister(&acc_device); - kfree(_acc_dev); - _acc_dev = NULL; -} diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index 68b1a8e86c0a..bd6226cbae86 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -405,10 +405,10 @@ static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) usb_ep_disable(acm->notify); } else { VDBG(cdev, "init acm ctrl interface %d\n", intf); + acm->notify_desc = ep_choose(cdev->gadget, + acm->hs.notify, + acm->fs.notify); } - acm->notify_desc = ep_choose(cdev->gadget, - acm->hs.notify, - acm->fs.notify); usb_ep_enable(acm->notify, acm->notify_desc); acm->notify->driver_data = acm; @@ -418,11 +418,11 @@ static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) gserial_disconnect(&acm->port); } else { DBG(cdev, "activate acm ttyGS%d\n", acm->port_num); + acm->port.in_desc = ep_choose(cdev->gadget, + acm->hs.in, acm->fs.in); + acm->port.out_desc = ep_choose(cdev->gadget, + acm->hs.out, acm->fs.out); } - acm->port.in_desc = ep_choose(cdev->gadget, - acm->hs.in, acm->fs.in); - acm->port.out_desc = ep_choose(cdev->gadget, - acm->hs.out, acm->fs.out); gserial_connect(&acm->port, acm->port_num); } else @@ -697,7 +697,6 @@ acm_unbind(struct usb_configuration *c, struct usb_function *f) usb_free_descriptors(f->hs_descriptors); usb_free_descriptors(f->descriptors); gs_free_req(acm->notify, acm->notify_req); - kfree(acm->port.func.name); kfree(acm); } @@ -769,11 +768,7 @@ int acm_bind_config(struct usb_configuration *c, u8 port_num) acm->port.disconnect = acm_disconnect; acm->port.send_break = acm_send_break; - acm->port.func.name = kasprintf(GFP_KERNEL, "acm%u", port_num); - if (!acm->port.func.name) { - kfree(acm); - return -ENOMEM; - } + acm->port.func.name = "acm"; acm->port.func.strings = acm_strings; /* descriptors are per-instance copies */ acm->port.func.bind = acm_bind; diff --git a/drivers/usb/gadget/f_adb.c b/drivers/usb/gadget/f_adb.c deleted file mode 100644 index 1c0166c6df21..000000000000 --- a/drivers/usb/gadget/f_adb.c +++ /dev/null @@ -1,614 +0,0 @@ -/* - * Gadget Driver for Android ADB - * - * Copyright (C) 2008 Google, Inc. - * Author: Mike Lockwood - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ADB_BULK_BUFFER_SIZE 4096 - -/* number of tx requests to allocate */ -#define TX_REQ_MAX 4 - -static const char adb_shortname[] = "android_adb"; - -struct adb_dev { - struct usb_function function; - struct usb_composite_dev *cdev; - spinlock_t lock; - - struct usb_ep *ep_in; - struct usb_ep *ep_out; - - int online; - int error; - - atomic_t read_excl; - atomic_t write_excl; - atomic_t open_excl; - - struct list_head tx_idle; - - wait_queue_head_t read_wq; - wait_queue_head_t write_wq; - struct usb_request *rx_req; - int rx_done; -}; - -static struct usb_interface_descriptor adb_interface_desc = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bNumEndpoints = 2, - .bInterfaceClass = 0xFF, - .bInterfaceSubClass = 0x42, - .bInterfaceProtocol = 1, -}; - -static struct usb_endpoint_descriptor adb_highspeed_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor adb_highspeed_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor adb_fullspeed_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_endpoint_descriptor adb_fullspeed_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_descriptor_header *fs_adb_descs[] = { - (struct usb_descriptor_header *) &adb_interface_desc, - (struct usb_descriptor_header *) &adb_fullspeed_in_desc, - (struct usb_descriptor_header *) &adb_fullspeed_out_desc, - NULL, -}; - -static struct usb_descriptor_header *hs_adb_descs[] = { - (struct usb_descriptor_header *) &adb_interface_desc, - (struct usb_descriptor_header *) &adb_highspeed_in_desc, - (struct usb_descriptor_header *) &adb_highspeed_out_desc, - NULL, -}; - -static void adb_ready_callback(void); -static void adb_closed_callback(void); - -/* temporary variable used between adb_open() and adb_gadget_bind() */ -static struct adb_dev *_adb_dev; - -static inline struct adb_dev *func_to_adb(struct usb_function *f) -{ - return container_of(f, struct adb_dev, function); -} - - -static struct usb_request *adb_request_new(struct usb_ep *ep, int buffer_size) -{ - struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL); - if (!req) - return NULL; - - /* now allocate buffers for the requests */ - req->buf = kmalloc(buffer_size, GFP_KERNEL); - if (!req->buf) { - usb_ep_free_request(ep, req); - return NULL; - } - - return req; -} - -static void adb_request_free(struct usb_request *req, struct usb_ep *ep) -{ - if (req) { - kfree(req->buf); - usb_ep_free_request(ep, req); - } -} - -static inline int adb_lock(atomic_t *excl) -{ - if (atomic_inc_return(excl) == 1) { - return 0; - } else { - atomic_dec(excl); - return -1; - } -} - -static inline void adb_unlock(atomic_t *excl) -{ - atomic_dec(excl); -} - -/* add a request to the tail of a list */ -void adb_req_put(struct adb_dev *dev, struct list_head *head, - struct usb_request *req) -{ - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - list_add_tail(&req->list, head); - spin_unlock_irqrestore(&dev->lock, flags); -} - -/* remove a request from the head of a list */ -struct usb_request *adb_req_get(struct adb_dev *dev, struct list_head *head) -{ - unsigned long flags; - struct usb_request *req; - - spin_lock_irqsave(&dev->lock, flags); - if (list_empty(head)) { - req = 0; - } else { - req = list_first_entry(head, struct usb_request, list); - list_del(&req->list); - } - spin_unlock_irqrestore(&dev->lock, flags); - return req; -} - -static void adb_complete_in(struct usb_ep *ep, struct usb_request *req) -{ - struct adb_dev *dev = _adb_dev; - - if (req->status != 0) - dev->error = 1; - - adb_req_put(dev, &dev->tx_idle, req); - - wake_up(&dev->write_wq); -} - -static void adb_complete_out(struct usb_ep *ep, struct usb_request *req) -{ - struct adb_dev *dev = _adb_dev; - - dev->rx_done = 1; - if (req->status != 0) - dev->error = 1; - - wake_up(&dev->read_wq); -} - -static int adb_create_bulk_endpoints(struct adb_dev *dev, - struct usb_endpoint_descriptor *in_desc, - struct usb_endpoint_descriptor *out_desc) -{ - struct usb_composite_dev *cdev = dev->cdev; - struct usb_request *req; - struct usb_ep *ep; - int i; - - DBG(cdev, "create_bulk_endpoints dev: %p\n", dev); - - ep = usb_ep_autoconfig(cdev->gadget, in_desc); - if (!ep) { - DBG(cdev, "usb_ep_autoconfig for ep_in failed\n"); - return -ENODEV; - } - DBG(cdev, "usb_ep_autoconfig for ep_in got %s\n", ep->name); - ep->driver_data = dev; /* claim the endpoint */ - dev->ep_in = ep; - - ep = usb_ep_autoconfig(cdev->gadget, out_desc); - if (!ep) { - DBG(cdev, "usb_ep_autoconfig for ep_out failed\n"); - return -ENODEV; - } - DBG(cdev, "usb_ep_autoconfig for adb ep_out got %s\n", ep->name); - ep->driver_data = dev; /* claim the endpoint */ - dev->ep_out = ep; - - /* now allocate requests for our endpoints */ - req = adb_request_new(dev->ep_out, ADB_BULK_BUFFER_SIZE); - if (!req) - goto fail; - req->complete = adb_complete_out; - dev->rx_req = req; - - for (i = 0; i < TX_REQ_MAX; i++) { - req = adb_request_new(dev->ep_in, ADB_BULK_BUFFER_SIZE); - if (!req) - goto fail; - req->complete = adb_complete_in; - adb_req_put(dev, &dev->tx_idle, req); - } - - return 0; - -fail: - printk(KERN_ERR "adb_bind() could not allocate requests\n"); - return -1; -} - -static ssize_t adb_read(struct file *fp, char __user *buf, - size_t count, loff_t *pos) -{ - struct adb_dev *dev = fp->private_data; - struct usb_request *req; - int r = count, xfer; - int ret; - - pr_debug("adb_read(%d)\n", count); - if (!_adb_dev) - return -ENODEV; - - if (count > ADB_BULK_BUFFER_SIZE) - return -EINVAL; - - if (adb_lock(&dev->read_excl)) - return -EBUSY; - - /* we will block until we're online */ - while (!(dev->online || dev->error)) { - pr_debug("adb_read: waiting for online state\n"); - ret = wait_event_interruptible(dev->read_wq, - (dev->online || dev->error)); - if (ret < 0) { - adb_unlock(&dev->read_excl); - return ret; - } - } - if (dev->error) { - r = -EIO; - goto done; - } - -requeue_req: - /* queue a request */ - req = dev->rx_req; - req->length = count; - dev->rx_done = 0; - ret = usb_ep_queue(dev->ep_out, req, GFP_ATOMIC); - if (ret < 0) { - pr_debug("adb_read: failed to queue req %p (%d)\n", req, ret); - r = -EIO; - dev->error = 1; - goto done; - } else { - pr_debug("rx %p queue\n", req); - } - - /* wait for a request to complete */ - ret = wait_event_interruptible(dev->read_wq, dev->rx_done); - if (ret < 0) { - dev->error = 1; - r = ret; - usb_ep_dequeue(dev->ep_out, req); - goto done; - } - if (!dev->error) { - /* If we got a 0-len packet, throw it back and try again. */ - if (req->actual == 0) - goto requeue_req; - - pr_debug("rx %p %d\n", req, req->actual); - xfer = (req->actual < count) ? req->actual : count; - if (copy_to_user(buf, req->buf, xfer)) - r = -EFAULT; - - } else - r = -EIO; - -done: - adb_unlock(&dev->read_excl); - pr_debug("adb_read returning %d\n", r); - return r; -} - -static ssize_t adb_write(struct file *fp, const char __user *buf, - size_t count, loff_t *pos) -{ - struct adb_dev *dev = fp->private_data; - struct usb_request *req = 0; - int r = count, xfer; - int ret; - - if (!_adb_dev) - return -ENODEV; - pr_debug("adb_write(%d)\n", count); - - if (adb_lock(&dev->write_excl)) - return -EBUSY; - - while (count > 0) { - if (dev->error) { - pr_debug("adb_write dev->error\n"); - r = -EIO; - break; - } - - /* get an idle tx request to use */ - req = 0; - ret = wait_event_interruptible(dev->write_wq, - (req = adb_req_get(dev, &dev->tx_idle)) || dev->error); - - if (ret < 0) { - r = ret; - break; - } - - if (req != 0) { - if (count > ADB_BULK_BUFFER_SIZE) - xfer = ADB_BULK_BUFFER_SIZE; - else - xfer = count; - if (copy_from_user(req->buf, buf, xfer)) { - r = -EFAULT; - break; - } - - req->length = xfer; - ret = usb_ep_queue(dev->ep_in, req, GFP_ATOMIC); - if (ret < 0) { - pr_debug("adb_write: xfer error %d\n", ret); - dev->error = 1; - r = -EIO; - break; - } - - buf += xfer; - count -= xfer; - - /* zero this so we don't try to free it on error exit */ - req = 0; - } - } - - if (req) - adb_req_put(dev, &dev->tx_idle, req); - - adb_unlock(&dev->write_excl); - pr_debug("adb_write returning %d\n", r); - return r; -} - -static int adb_open(struct inode *ip, struct file *fp) -{ - pr_info("adb_open\n"); - if (!_adb_dev) - return -ENODEV; - - if (adb_lock(&_adb_dev->open_excl)) - return -EBUSY; - - fp->private_data = _adb_dev; - - /* clear the error latch */ - _adb_dev->error = 0; - - adb_ready_callback(); - - return 0; -} - -static int adb_release(struct inode *ip, struct file *fp) -{ - pr_info("adb_release\n"); - - adb_closed_callback(); - - adb_unlock(&_adb_dev->open_excl); - return 0; -} - -/* file operations for ADB device /dev/android_adb */ -static struct file_operations adb_fops = { - .owner = THIS_MODULE, - .read = adb_read, - .write = adb_write, - .open = adb_open, - .release = adb_release, -}; - -static struct miscdevice adb_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = adb_shortname, - .fops = &adb_fops, -}; - - - - -static int -adb_function_bind(struct usb_configuration *c, struct usb_function *f) -{ - struct usb_composite_dev *cdev = c->cdev; - struct adb_dev *dev = func_to_adb(f); - int id; - int ret; - - dev->cdev = cdev; - DBG(cdev, "adb_function_bind dev: %p\n", dev); - - /* allocate interface ID(s) */ - id = usb_interface_id(c, f); - if (id < 0) - return id; - adb_interface_desc.bInterfaceNumber = id; - - /* allocate endpoints */ - ret = adb_create_bulk_endpoints(dev, &adb_fullspeed_in_desc, - &adb_fullspeed_out_desc); - if (ret) - return ret; - - /* support high speed hardware */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - adb_highspeed_in_desc.bEndpointAddress = - adb_fullspeed_in_desc.bEndpointAddress; - adb_highspeed_out_desc.bEndpointAddress = - adb_fullspeed_out_desc.bEndpointAddress; - } - - DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", - gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", - f->name, dev->ep_in->name, dev->ep_out->name); - return 0; -} - -static void -adb_function_unbind(struct usb_configuration *c, struct usb_function *f) -{ - struct adb_dev *dev = func_to_adb(f); - struct usb_request *req; - - - dev->online = 0; - dev->error = 1; - - wake_up(&dev->read_wq); - - adb_request_free(dev->rx_req, dev->ep_out); - while ((req = adb_req_get(dev, &dev->tx_idle))) - adb_request_free(req, dev->ep_in); -} - -static int adb_function_set_alt(struct usb_function *f, - unsigned intf, unsigned alt) -{ - struct adb_dev *dev = func_to_adb(f); - struct usb_composite_dev *cdev = f->config->cdev; - int ret; - - DBG(cdev, "adb_function_set_alt intf: %d alt: %d\n", intf, alt); - ret = usb_ep_enable(dev->ep_in, - ep_choose(cdev->gadget, - &adb_highspeed_in_desc, - &adb_fullspeed_in_desc)); - if (ret) - return ret; - ret = usb_ep_enable(dev->ep_out, - ep_choose(cdev->gadget, - &adb_highspeed_out_desc, - &adb_fullspeed_out_desc)); - if (ret) { - usb_ep_disable(dev->ep_in); - return ret; - } - dev->online = 1; - - /* readers may be blocked waiting for us to go online */ - wake_up(&dev->read_wq); - return 0; -} - -static void adb_function_disable(struct usb_function *f) -{ - struct adb_dev *dev = func_to_adb(f); - struct usb_composite_dev *cdev = dev->cdev; - - DBG(cdev, "adb_function_disable cdev %p\n", cdev); - dev->online = 0; - dev->error = 1; - usb_ep_disable(dev->ep_in); - usb_ep_disable(dev->ep_out); - - /* readers may be blocked waiting for us to go online */ - wake_up(&dev->read_wq); - - VDBG(cdev, "%s disabled\n", dev->function.name); -} - -static int adb_bind_config(struct usb_configuration *c) -{ - struct adb_dev *dev = _adb_dev; - - printk(KERN_INFO "adb_bind_config\n"); - - dev->cdev = c->cdev; - dev->function.name = "adb"; - dev->function.descriptors = fs_adb_descs; - dev->function.hs_descriptors = hs_adb_descs; - dev->function.bind = adb_function_bind; - dev->function.unbind = adb_function_unbind; - dev->function.set_alt = adb_function_set_alt; - dev->function.disable = adb_function_disable; - - return usb_add_function(c, &dev->function); -} - -static int adb_setup(void) -{ - struct adb_dev *dev; - int ret; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - spin_lock_init(&dev->lock); - - init_waitqueue_head(&dev->read_wq); - init_waitqueue_head(&dev->write_wq); - - atomic_set(&dev->open_excl, 0); - atomic_set(&dev->read_excl, 0); - atomic_set(&dev->write_excl, 0); - - INIT_LIST_HEAD(&dev->tx_idle); - - _adb_dev = dev; - - ret = misc_register(&adb_device); - if (ret) - goto err; - - return 0; - -err: - kfree(dev); - printk(KERN_ERR "adb gadget driver failed to initialize\n"); - return ret; -} - -static void adb_cleanup(void) -{ - misc_deregister(&adb_device); - - kfree(_adb_dev); - _adb_dev = NULL; -} diff --git a/drivers/usb/gadget/f_audio_source.c b/drivers/usb/gadget/f_audio_source.c deleted file mode 100644 index c5dbf7180fdb..000000000000 --- a/drivers/usb/gadget/f_audio_source.c +++ /dev/null @@ -1,821 +0,0 @@ -/* - * Gadget Function Driver for USB audio source device - * - * Copyright (C) 2012 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include - -#define SAMPLE_RATE 44100 -#define FRAMES_PER_MSEC (SAMPLE_RATE / 1000) - -#define IN_EP_MAX_PACKET_SIZE 384 - -/* Number of requests to allocate */ -#define IN_EP_REQ_COUNT 4 - -#define AUDIO_AC_INTERFACE 0 -#define AUDIO_AS_INTERFACE 1 -#define AUDIO_NUM_INTERFACES 2 - -/* B.3.1 Standard AC Interface Descriptor */ -static struct usb_interface_descriptor ac_interface_desc = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bNumEndpoints = 0, - .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, -}; - -DECLARE_UAC_AC_HEADER_DESCRIPTOR(2); - -#define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(AUDIO_NUM_INTERFACES) -/* 1 input terminal, 1 output terminal and 1 feature unit */ -#define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH \ - + UAC_DT_INPUT_TERMINAL_SIZE + UAC_DT_OUTPUT_TERMINAL_SIZE \ - + UAC_DT_FEATURE_UNIT_SIZE(0)) -/* B.3.2 Class-Specific AC Interface Descriptor */ -static struct uac1_ac_header_descriptor_2 ac_header_desc = { - .bLength = UAC_DT_AC_HEADER_LENGTH, - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubtype = UAC_HEADER, - .bcdADC = __constant_cpu_to_le16(0x0100), - .wTotalLength = __constant_cpu_to_le16(UAC_DT_TOTAL_LENGTH), - .bInCollection = AUDIO_NUM_INTERFACES, - .baInterfaceNr = { - [0] = AUDIO_AC_INTERFACE, - [1] = AUDIO_AS_INTERFACE, - } -}; - -#define INPUT_TERMINAL_ID 1 -static struct uac_input_terminal_descriptor input_terminal_desc = { - .bLength = UAC_DT_INPUT_TERMINAL_SIZE, - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubtype = UAC_INPUT_TERMINAL, - .bTerminalID = INPUT_TERMINAL_ID, - .wTerminalType = UAC_INPUT_TERMINAL_MICROPHONE, - .bAssocTerminal = 0, - .wChannelConfig = 0x3, -}; - -DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(0); - -#define FEATURE_UNIT_ID 2 -static struct uac_feature_unit_descriptor_0 feature_unit_desc = { - .bLength = UAC_DT_FEATURE_UNIT_SIZE(0), - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubtype = UAC_FEATURE_UNIT, - .bUnitID = FEATURE_UNIT_ID, - .bSourceID = INPUT_TERMINAL_ID, - .bControlSize = 2, -}; - -#define OUTPUT_TERMINAL_ID 3 -static struct uac1_output_terminal_descriptor output_terminal_desc = { - .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, - .bTerminalID = OUTPUT_TERMINAL_ID, - .wTerminalType = UAC_TERMINAL_STREAMING, - .bAssocTerminal = FEATURE_UNIT_ID, - .bSourceID = FEATURE_UNIT_ID, -}; - -/* B.4.1 Standard AS Interface Descriptor */ -static struct usb_interface_descriptor as_interface_alt_0_desc = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bAlternateSetting = 0, - .bNumEndpoints = 0, - .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, -}; - -static struct usb_interface_descriptor as_interface_alt_1_desc = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bAlternateSetting = 1, - .bNumEndpoints = 1, - .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, -}; - -/* B.4.2 Class-Specific AS Interface Descriptor */ -static struct uac1_as_header_descriptor as_header_desc = { - .bLength = UAC_DT_AS_HEADER_SIZE, - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubtype = UAC_AS_GENERAL, - .bTerminalLink = INPUT_TERMINAL_ID, - .bDelay = 1, - .wFormatTag = UAC_FORMAT_TYPE_I_PCM, -}; - -DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1); - -static struct uac_format_type_i_discrete_descriptor_1 as_type_i_desc = { - .bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubtype = UAC_FORMAT_TYPE, - .bFormatType = UAC_FORMAT_TYPE_I, - .bSubframeSize = 2, - .bBitResolution = 16, - .bSamFreqType = 1, -}; - -/* Standard ISO IN Endpoint Descriptor for highspeed */ -static struct usb_endpoint_descriptor hs_as_in_ep_desc = { - .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_SYNC_SYNC - | USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = __constant_cpu_to_le16(IN_EP_MAX_PACKET_SIZE), - .bInterval = 4, /* poll 1 per millisecond */ -}; - -/* Standard ISO IN Endpoint Descriptor for highspeed */ -static struct usb_endpoint_descriptor fs_as_in_ep_desc = { - .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_SYNC_SYNC - | USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = __constant_cpu_to_le16(IN_EP_MAX_PACKET_SIZE), - .bInterval = 1, /* poll 1 per millisecond */ -}; - -/* Class-specific AS ISO OUT Endpoint Descriptor */ -static struct uac_iso_endpoint_descriptor as_iso_in_desc = { - .bLength = UAC_ISO_ENDPOINT_DESC_SIZE, - .bDescriptorType = USB_DT_CS_ENDPOINT, - .bDescriptorSubtype = UAC_EP_GENERAL, - .bmAttributes = 1, - .bLockDelayUnits = 1, - .wLockDelay = __constant_cpu_to_le16(1), -}; - -static struct usb_descriptor_header *hs_audio_desc[] = { - (struct usb_descriptor_header *)&ac_interface_desc, - (struct usb_descriptor_header *)&ac_header_desc, - - (struct usb_descriptor_header *)&input_terminal_desc, - (struct usb_descriptor_header *)&output_terminal_desc, - (struct usb_descriptor_header *)&feature_unit_desc, - - (struct usb_descriptor_header *)&as_interface_alt_0_desc, - (struct usb_descriptor_header *)&as_interface_alt_1_desc, - (struct usb_descriptor_header *)&as_header_desc, - - (struct usb_descriptor_header *)&as_type_i_desc, - - (struct usb_descriptor_header *)&hs_as_in_ep_desc, - (struct usb_descriptor_header *)&as_iso_in_desc, - NULL, -}; - -static struct usb_descriptor_header *fs_audio_desc[] = { - (struct usb_descriptor_header *)&ac_interface_desc, - (struct usb_descriptor_header *)&ac_header_desc, - - (struct usb_descriptor_header *)&input_terminal_desc, - (struct usb_descriptor_header *)&output_terminal_desc, - (struct usb_descriptor_header *)&feature_unit_desc, - - (struct usb_descriptor_header *)&as_interface_alt_0_desc, - (struct usb_descriptor_header *)&as_interface_alt_1_desc, - (struct usb_descriptor_header *)&as_header_desc, - - (struct usb_descriptor_header *)&as_type_i_desc, - - (struct usb_descriptor_header *)&fs_as_in_ep_desc, - (struct usb_descriptor_header *)&as_iso_in_desc, - NULL, -}; - -static struct snd_pcm_hardware audio_hw_info = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_BATCH | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER, - - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .channels_min = 2, - .channels_max = 2, - .rate_min = SAMPLE_RATE, - .rate_max = SAMPLE_RATE, - - .buffer_bytes_max = 1024 * 1024, - .period_bytes_min = 64, - .period_bytes_max = 512 * 1024, - .periods_min = 2, - .periods_max = 1024, -}; - -/*-------------------------------------------------------------------------*/ - -struct audio_source_config { - int card; - int device; -}; - -struct audio_dev { - struct usb_function func; - struct snd_card *card; - struct snd_pcm *pcm; - struct snd_pcm_substream *substream; - - struct list_head idle_reqs; - struct usb_ep *in_ep; - - spinlock_t lock; - - /* beginning, end and current position in our buffer */ - void *buffer_start; - void *buffer_end; - void *buffer_pos; - - /* byte size of a "period" */ - unsigned int period; - /* bytes sent since last call to snd_pcm_period_elapsed */ - unsigned int period_offset; - /* time we started playing */ - ktime_t start_time; - /* number of frames sent since start_time */ - s64 frames_sent; -}; - -static inline struct audio_dev *func_to_audio(struct usb_function *f) -{ - return container_of(f, struct audio_dev, func); -} - -/*-------------------------------------------------------------------------*/ - -static struct usb_request *audio_request_new(struct usb_ep *ep, int buffer_size) -{ - struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL); - if (!req) - return NULL; - - req->buf = kmalloc(buffer_size, GFP_KERNEL); - if (!req->buf) { - usb_ep_free_request(ep, req); - return NULL; - } - req->length = buffer_size; - return req; -} - -static void audio_request_free(struct usb_request *req, struct usb_ep *ep) -{ - if (req) { - kfree(req->buf); - usb_ep_free_request(ep, req); - } -} - -static void audio_req_put(struct audio_dev *audio, struct usb_request *req) -{ - unsigned long flags; - - spin_lock_irqsave(&audio->lock, flags); - list_add_tail(&req->list, &audio->idle_reqs); - spin_unlock_irqrestore(&audio->lock, flags); -} - -static struct usb_request *audio_req_get(struct audio_dev *audio) -{ - unsigned long flags; - struct usb_request *req; - - spin_lock_irqsave(&audio->lock, flags); - if (list_empty(&audio->idle_reqs)) { - req = 0; - } else { - req = list_first_entry(&audio->idle_reqs, struct usb_request, - list); - list_del(&req->list); - } - spin_unlock_irqrestore(&audio->lock, flags); - return req; -} - -/* send the appropriate number of packets to match our bitrate */ -static void audio_send(struct audio_dev *audio) -{ - struct snd_pcm_runtime *runtime; - struct usb_request *req; - int length, length1, length2, ret; - s64 msecs; - s64 frames; - ktime_t now; - - /* audio->substream will be null if we have been closed */ - if (!audio->substream) - return; - /* audio->buffer_pos will be null if we have been stopped */ - if (!audio->buffer_pos) - return; - - runtime = audio->substream->runtime; - - /* compute number of frames to send */ - now = ktime_get(); - msecs = ktime_to_ns(now) - ktime_to_ns(audio->start_time); - do_div(msecs, 1000000); - frames = msecs * SAMPLE_RATE; - do_div(frames, 1000); - - /* Readjust our frames_sent if we fall too far behind. - * If we get too far behind it is better to drop some frames than - * to keep sending data too fast in an attempt to catch up. - */ - if (frames - audio->frames_sent > 10 * FRAMES_PER_MSEC) - audio->frames_sent = frames - FRAMES_PER_MSEC; - - frames -= audio->frames_sent; - - /* We need to send something to keep the pipeline going */ - if (frames <= 0) - frames = FRAMES_PER_MSEC; - - while (frames > 0) { - req = audio_req_get(audio); - if (!req) - break; - - length = frames_to_bytes(runtime, frames); - if (length > IN_EP_MAX_PACKET_SIZE) - length = IN_EP_MAX_PACKET_SIZE; - - if (audio->buffer_pos + length > audio->buffer_end) - length1 = audio->buffer_end - audio->buffer_pos; - else - length1 = length; - memcpy(req->buf, audio->buffer_pos, length1); - if (length1 < length) { - /* Wrap around and copy remaining length - * at beginning of buffer. - */ - length2 = length - length1; - memcpy(req->buf + length1, audio->buffer_start, - length2); - audio->buffer_pos = audio->buffer_start + length2; - } else { - audio->buffer_pos += length1; - if (audio->buffer_pos >= audio->buffer_end) - audio->buffer_pos = audio->buffer_start; - } - - req->length = length; - ret = usb_ep_queue(audio->in_ep, req, GFP_ATOMIC); - if (ret < 0) { - pr_err("usb_ep_queue failed ret: %d\n", ret); - audio_req_put(audio, req); - break; - } - - frames -= bytes_to_frames(runtime, length); - audio->frames_sent += bytes_to_frames(runtime, length); - } -} - -static void audio_control_complete(struct usb_ep *ep, struct usb_request *req) -{ - /* nothing to do here */ -} - -static void audio_data_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct audio_dev *audio = req->context; - - pr_debug("audio_data_complete req->status %d req->actual %d\n", - req->status, req->actual); - - audio_req_put(audio, req); - - if (!audio->buffer_start || req->status) - return; - - audio->period_offset += req->actual; - if (audio->period_offset >= audio->period) { - snd_pcm_period_elapsed(audio->substream); - audio->period_offset = 0; - } - audio_send(audio); -} - -static int audio_set_endpoint_req(struct usb_function *f, - const struct usb_ctrlrequest *ctrl) -{ - int value = -EOPNOTSUPP; - u16 ep = le16_to_cpu(ctrl->wIndex); - u16 len = le16_to_cpu(ctrl->wLength); - u16 w_value = le16_to_cpu(ctrl->wValue); - - pr_debug("bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", - ctrl->bRequest, w_value, len, ep); - - switch (ctrl->bRequest) { - case UAC_SET_CUR: - case UAC_SET_MIN: - case UAC_SET_MAX: - case UAC_SET_RES: - value = len; - break; - default: - break; - } - - return value; -} - -static int audio_get_endpoint_req(struct usb_function *f, - const struct usb_ctrlrequest *ctrl) -{ - struct usb_composite_dev *cdev = f->config->cdev; - int value = -EOPNOTSUPP; - u8 ep = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); - u16 len = le16_to_cpu(ctrl->wLength); - u16 w_value = le16_to_cpu(ctrl->wValue); - u8 *buf = cdev->req->buf; - - pr_debug("bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", - ctrl->bRequest, w_value, len, ep); - - if (w_value == UAC_EP_CS_ATTR_SAMPLE_RATE << 8) { - switch (ctrl->bRequest) { - case UAC_GET_CUR: - case UAC_GET_MIN: - case UAC_GET_MAX: - case UAC_GET_RES: - /* return our sample rate */ - buf[0] = (u8)SAMPLE_RATE; - buf[1] = (u8)(SAMPLE_RATE >> 8); - buf[2] = (u8)(SAMPLE_RATE >> 16); - value = 3; - break; - default: - break; - } - } - - return value; -} - -static int -audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) -{ - struct usb_composite_dev *cdev = f->config->cdev; - struct usb_request *req = cdev->req; - int value = -EOPNOTSUPP; - u16 w_index = le16_to_cpu(ctrl->wIndex); - u16 w_value = le16_to_cpu(ctrl->wValue); - u16 w_length = le16_to_cpu(ctrl->wLength); - - /* composite driver infrastructure handles everything; interface - * activation uses set_alt(). - */ - switch (ctrl->bRequestType) { - case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: - value = audio_set_endpoint_req(f, ctrl); - break; - - case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: - value = audio_get_endpoint_req(f, ctrl); - break; - } - - /* respond with data transfer or status phase? */ - if (value >= 0) { - pr_debug("audio req%02x.%02x v%04x i%04x l%d\n", - ctrl->bRequestType, ctrl->bRequest, - w_value, w_index, w_length); - req->zero = 0; - req->length = value; - req->complete = audio_control_complete; - value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); - if (value < 0) - pr_err("audio response on err %d\n", value); - } - - /* device either stalls (value < 0) or reports success */ - return value; -} - -static int audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) -{ - struct audio_dev *audio = func_to_audio(f); - - pr_debug("audio_set_alt intf %d, alt %d\n", intf, alt); - usb_ep_enable(audio->in_ep, &fs_as_in_ep_desc); - return 0; -} - -static void audio_disable(struct usb_function *f) -{ - struct audio_dev *audio = func_to_audio(f); - - pr_debug("audio_disable\n"); - usb_ep_disable(audio->in_ep); -} - -/*-------------------------------------------------------------------------*/ - -static void audio_build_desc(struct audio_dev *audio) -{ - u8 *sam_freq; - int rate; - - /* Set channel numbers */ - input_terminal_desc.bNrChannels = 2; - as_type_i_desc.bNrChannels = 2; - - /* Set sample rates */ - rate = SAMPLE_RATE; - sam_freq = as_type_i_desc.tSamFreq[0]; - memcpy(sam_freq, &rate, 3); -} - -/* audio function driver setup/binding */ -static int -audio_bind(struct usb_configuration *c, struct usb_function *f) -{ - struct usb_composite_dev *cdev = c->cdev; - struct audio_dev *audio = func_to_audio(f); - int status; - struct usb_ep *ep; - struct usb_request *req; - int i; - - audio_build_desc(audio); - - /* allocate instance-specific interface IDs, and patch descriptors */ - status = usb_interface_id(c, f); - if (status < 0) - goto fail; - ac_interface_desc.bInterfaceNumber = status; - - status = usb_interface_id(c, f); - if (status < 0) - goto fail; - as_interface_alt_0_desc.bInterfaceNumber = status; - as_interface_alt_1_desc.bInterfaceNumber = status; - - status = -ENODEV; - - /* allocate our endpoint */ - ep = usb_ep_autoconfig(cdev->gadget, &fs_as_in_ep_desc); - if (!ep) - goto fail; - audio->in_ep = ep; - ep->driver_data = audio; /* claim */ - - if (gadget_is_dualspeed(c->cdev->gadget)) - hs_as_in_ep_desc.bEndpointAddress = - fs_as_in_ep_desc.bEndpointAddress; - - f->descriptors = fs_audio_desc; - f->hs_descriptors = hs_audio_desc; - - for (i = 0, status = 0; i < IN_EP_REQ_COUNT && status == 0; i++) { - req = audio_request_new(ep, IN_EP_MAX_PACKET_SIZE); - if (req) { - req->context = audio; - req->complete = audio_data_complete; - audio_req_put(audio, req); - } else - status = -ENOMEM; - } - -fail: - return status; -} - -static void -audio_unbind(struct usb_configuration *c, struct usb_function *f) -{ - struct audio_dev *audio = func_to_audio(f); - struct usb_request *req; - - while ((req = audio_req_get(audio))) - audio_request_free(req, audio->in_ep); - - snd_card_free_when_closed(audio->card); - audio->card = NULL; - audio->pcm = NULL; - audio->substream = NULL; - audio->in_ep = NULL; -} - -static void audio_pcm_playback_start(struct audio_dev *audio) -{ - audio->start_time = ktime_get(); - audio->frames_sent = 0; - audio_send(audio); -} - -static void audio_pcm_playback_stop(struct audio_dev *audio) -{ - unsigned long flags; - - spin_lock_irqsave(&audio->lock, flags); - audio->buffer_start = 0; - audio->buffer_end = 0; - audio->buffer_pos = 0; - spin_unlock_irqrestore(&audio->lock, flags); -} - -static int audio_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct audio_dev *audio = substream->private_data; - - runtime->private_data = audio; - runtime->hw = audio_hw_info; - snd_pcm_limit_hw_rates(runtime); - runtime->hw.channels_max = 2; - - audio->substream = substream; - return 0; -} - -static int audio_pcm_close(struct snd_pcm_substream *substream) -{ - struct audio_dev *audio = substream->private_data; - unsigned long flags; - - spin_lock_irqsave(&audio->lock, flags); - audio->substream = NULL; - spin_unlock_irqrestore(&audio->lock, flags); - - return 0; -} - -static int audio_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - unsigned int channels = params_channels(params); - unsigned int rate = params_rate(params); - - if (rate != SAMPLE_RATE) - return -EINVAL; - if (channels != 2) - return -EINVAL; - - return snd_pcm_lib_alloc_vmalloc_buffer(substream, - params_buffer_bytes(params)); -} - -static int audio_pcm_hw_free(struct snd_pcm_substream *substream) -{ - return snd_pcm_lib_free_vmalloc_buffer(substream); -} - -static int audio_pcm_prepare(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct audio_dev *audio = runtime->private_data; - - audio->period = snd_pcm_lib_period_bytes(substream); - audio->period_offset = 0; - audio->buffer_start = runtime->dma_area; - audio->buffer_end = audio->buffer_start - + snd_pcm_lib_buffer_bytes(substream); - audio->buffer_pos = audio->buffer_start; - - return 0; -} - -static snd_pcm_uframes_t audio_pcm_pointer(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct audio_dev *audio = runtime->private_data; - ssize_t bytes = audio->buffer_pos - audio->buffer_start; - - /* return offset of next frame to fill in our buffer */ - return bytes_to_frames(runtime, bytes); -} - -static int audio_pcm_playback_trigger(struct snd_pcm_substream *substream, - int cmd) -{ - struct audio_dev *audio = substream->runtime->private_data; - int ret = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - audio_pcm_playback_start(audio); - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - audio_pcm_playback_stop(audio); - break; - - default: - ret = -EINVAL; - } - - return ret; -} - -static struct audio_dev _audio_dev = { - .func = { - .name = "audio_source", - .bind = audio_bind, - .unbind = audio_unbind, - .set_alt = audio_set_alt, - .setup = audio_setup, - .disable = audio_disable, - }, - .lock = __SPIN_LOCK_UNLOCKED(_audio_dev.lock), - .idle_reqs = LIST_HEAD_INIT(_audio_dev.idle_reqs), -}; - -static struct snd_pcm_ops audio_playback_ops = { - .open = audio_pcm_open, - .close = audio_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = audio_pcm_hw_params, - .hw_free = audio_pcm_hw_free, - .prepare = audio_pcm_prepare, - .trigger = audio_pcm_playback_trigger, - .pointer = audio_pcm_pointer, -}; - -int audio_source_bind_config(struct usb_configuration *c, - struct audio_source_config *config) -{ - struct audio_dev *audio; - struct snd_card *card; - struct snd_pcm *pcm; - int err; - - config->card = -1; - config->device = -1; - - audio = &_audio_dev; - - err = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, - THIS_MODULE, 0, &card); - if (err) - return err; - - snd_card_set_dev(card, &c->cdev->gadget->dev); - - err = snd_pcm_new(card, "USB audio source", 0, 1, 0, &pcm); - if (err) - goto pcm_fail; - pcm->private_data = audio; - pcm->info_flags = 0; - audio->pcm = pcm; - - strlcpy(pcm->name, "USB gadget audio", sizeof(pcm->name)); - - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &audio_playback_ops); - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - NULL, 0, 64 * 1024); - - strlcpy(card->driver, "audio_source", sizeof(card->driver)); - strlcpy(card->shortname, card->driver, sizeof(card->shortname)); - strlcpy(card->longname, "USB accessory audio source", - sizeof(card->longname)); - - err = snd_card_register(card); - if (err) - goto register_fail; - - err = usb_add_function(c, &audio->func); - if (err) - goto add_fail; - - config->card = pcm->card->number; - config->device = pcm->device; - audio->card = card; - return 0; - -add_fail: -register_fail: -pcm_fail: - snd_card_free(audio->card); - return err; -} diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 1cefb9f16071..19fffccc370d 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -720,7 +720,7 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value) if (code == FUNCTIONFS_INTERFACE_REVMAP) { struct ffs_function *func = ffs->func; ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV; - } else if (gadget && gadget->ops->ioctl) { + } else if (gadget->ops->ioctl) { ret = gadget->ops->ioctl(gadget, code, value); } else { ret = -ENOTTY; diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c index 0e64a47cd6b2..b37960f9e753 100644 --- a/drivers/usb/gadget/f_loopback.c +++ b/drivers/usb/gadget/f_loopback.c @@ -373,7 +373,7 @@ int __init loopback_add(struct usb_composite_dev *cdev, bool autoresume) /* support autoresume for remote wakeup testing */ if (autoresume) - loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; /* support OTG systems */ if (gadget_is_otg(cdev->gadget)) { diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index bc2f62476cbc..efb58f9f5aa9 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2187,7 +2187,7 @@ unknown_cmnd: common->data_size_from_cmnd = 0; sprintf(unknown, "Unknown x%02x", common->cmnd[0]); reply = check_command(common, common->cmnd_size, - DATA_DIR_UNKNOWN, ~0, 0, unknown); + DATA_DIR_UNKNOWN, 0xff, 0, unknown); if (reply == 0) { common->curlun->sense_data = SS_INVALID_COMMAND; reply = -EINVAL; @@ -3052,7 +3052,7 @@ static int fsg_bind_config(struct usb_composite_dev *cdev, if (unlikely(!fsg)) return -ENOMEM; - fsg->function.name = "mass_storage"; + fsg->function.name = FSG_DRIVER_DESC; fsg->function.strings = fsg_strings_array; fsg->function.bind = fsg_bind; fsg->function.unbind = fsg_unbind; diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c deleted file mode 100644 index 2829231327d4..000000000000 --- a/drivers/usb/gadget/f_mtp.c +++ /dev/null @@ -1,1267 +0,0 @@ -/* - * Gadget Function Driver for MTP - * - * Copyright (C) 2010 Google, Inc. - * Author: Mike Lockwood - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -/* #define DEBUG */ -/* #define VERBOSE_DEBUG */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#define MTP_BULK_BUFFER_SIZE 16384 -#define INTR_BUFFER_SIZE 28 - -/* String IDs */ -#define INTERFACE_STRING_INDEX 0 - -/* values for mtp_dev.state */ -#define STATE_OFFLINE 0 /* initial state, disconnected */ -#define STATE_READY 1 /* ready for userspace calls */ -#define STATE_BUSY 2 /* processing userspace calls */ -#define STATE_CANCELED 3 /* transaction canceled by host */ -#define STATE_ERROR 4 /* error from completion routine */ - -/* number of tx and rx requests to allocate */ -#define TX_REQ_MAX 4 -#define RX_REQ_MAX 2 -#define INTR_REQ_MAX 5 - -/* ID for Microsoft MTP OS String */ -#define MTP_OS_STRING_ID 0xEE - -/* MTP class reqeusts */ -#define MTP_REQ_CANCEL 0x64 -#define MTP_REQ_GET_EXT_EVENT_DATA 0x65 -#define MTP_REQ_RESET 0x66 -#define MTP_REQ_GET_DEVICE_STATUS 0x67 - -/* constants for device status */ -#define MTP_RESPONSE_OK 0x2001 -#define MTP_RESPONSE_DEVICE_BUSY 0x2019 - -static const char mtp_shortname[] = "mtp_usb"; - -struct mtp_dev { - struct usb_function function; - struct usb_composite_dev *cdev; - spinlock_t lock; - - struct usb_ep *ep_in; - struct usb_ep *ep_out; - struct usb_ep *ep_intr; - - int state; - - /* synchronize access to our device file */ - atomic_t open_excl; - /* to enforce only one ioctl at a time */ - atomic_t ioctl_excl; - - struct list_head tx_idle; - struct list_head intr_idle; - - wait_queue_head_t read_wq; - wait_queue_head_t write_wq; - wait_queue_head_t intr_wq; - struct usb_request *rx_req[RX_REQ_MAX]; - int rx_done; - - /* for processing MTP_SEND_FILE, MTP_RECEIVE_FILE and - * MTP_SEND_FILE_WITH_HEADER ioctls on a work queue - */ - struct workqueue_struct *wq; - struct work_struct send_file_work; - struct work_struct receive_file_work; - struct file *xfer_file; - loff_t xfer_file_offset; - int64_t xfer_file_length; - unsigned xfer_send_header; - uint16_t xfer_command; - uint32_t xfer_transaction_id; - int xfer_result; -}; - -static struct usb_interface_descriptor mtp_interface_desc = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bNumEndpoints = 3, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = USB_SUBCLASS_VENDOR_SPEC, - .bInterfaceProtocol = 0, -}; - -static struct usb_interface_descriptor ptp_interface_desc = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bNumEndpoints = 3, - .bInterfaceClass = USB_CLASS_STILL_IMAGE, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 1, -}; - -static struct usb_endpoint_descriptor mtp_highspeed_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor mtp_highspeed_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor mtp_fullspeed_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_endpoint_descriptor mtp_fullspeed_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_endpoint_descriptor mtp_intr_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = __constant_cpu_to_le16(INTR_BUFFER_SIZE), - .bInterval = 6, -}; - -static struct usb_descriptor_header *fs_mtp_descs[] = { - (struct usb_descriptor_header *) &mtp_interface_desc, - (struct usb_descriptor_header *) &mtp_fullspeed_in_desc, - (struct usb_descriptor_header *) &mtp_fullspeed_out_desc, - (struct usb_descriptor_header *) &mtp_intr_desc, - NULL, -}; - -static struct usb_descriptor_header *hs_mtp_descs[] = { - (struct usb_descriptor_header *) &mtp_interface_desc, - (struct usb_descriptor_header *) &mtp_highspeed_in_desc, - (struct usb_descriptor_header *) &mtp_highspeed_out_desc, - (struct usb_descriptor_header *) &mtp_intr_desc, - NULL, -}; - -static struct usb_descriptor_header *fs_ptp_descs[] = { - (struct usb_descriptor_header *) &ptp_interface_desc, - (struct usb_descriptor_header *) &mtp_fullspeed_in_desc, - (struct usb_descriptor_header *) &mtp_fullspeed_out_desc, - (struct usb_descriptor_header *) &mtp_intr_desc, - NULL, -}; - -static struct usb_descriptor_header *hs_ptp_descs[] = { - (struct usb_descriptor_header *) &ptp_interface_desc, - (struct usb_descriptor_header *) &mtp_highspeed_in_desc, - (struct usb_descriptor_header *) &mtp_highspeed_out_desc, - (struct usb_descriptor_header *) &mtp_intr_desc, - NULL, -}; - -static struct usb_string mtp_string_defs[] = { - /* Naming interface "MTP" so libmtp will recognize us */ - [INTERFACE_STRING_INDEX].s = "MTP", - { }, /* end of list */ -}; - -static struct usb_gadget_strings mtp_string_table = { - .language = 0x0409, /* en-US */ - .strings = mtp_string_defs, -}; - -static struct usb_gadget_strings *mtp_strings[] = { - &mtp_string_table, - NULL, -}; - -/* Microsoft MTP OS String */ -static u8 mtp_os_string[] = { - 18, /* sizeof(mtp_os_string) */ - USB_DT_STRING, - /* Signature field: "MSFT100" */ - 'M', 0, 'S', 0, 'F', 0, 'T', 0, '1', 0, '0', 0, '0', 0, - /* vendor code */ - 1, - /* padding */ - 0 -}; - -/* Microsoft Extended Configuration Descriptor Header Section */ -struct mtp_ext_config_desc_header { - __le32 dwLength; - __u16 bcdVersion; - __le16 wIndex; - __u8 bCount; - __u8 reserved[7]; -}; - -/* Microsoft Extended Configuration Descriptor Function Section */ -struct mtp_ext_config_desc_function { - __u8 bFirstInterfaceNumber; - __u8 bInterfaceCount; - __u8 compatibleID[8]; - __u8 subCompatibleID[8]; - __u8 reserved[6]; -}; - -/* MTP Extended Configuration Descriptor */ -struct { - struct mtp_ext_config_desc_header header; - struct mtp_ext_config_desc_function function; -} mtp_ext_config_desc = { - .header = { - .dwLength = __constant_cpu_to_le32(sizeof(mtp_ext_config_desc)), - .bcdVersion = __constant_cpu_to_le16(0x0100), - .wIndex = __constant_cpu_to_le16(4), - .bCount = __constant_cpu_to_le16(1), - }, - .function = { - .bFirstInterfaceNumber = 0, - .bInterfaceCount = 1, - .compatibleID = { 'M', 'T', 'P' }, - }, -}; - -struct mtp_device_status { - __le16 wLength; - __le16 wCode; -}; - -/* temporary variable used between mtp_open() and mtp_gadget_bind() */ -static struct mtp_dev *_mtp_dev; - -static inline struct mtp_dev *func_to_mtp(struct usb_function *f) -{ - return container_of(f, struct mtp_dev, function); -} - -static struct usb_request *mtp_request_new(struct usb_ep *ep, int buffer_size) -{ - struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL); - if (!req) - return NULL; - - /* now allocate buffers for the requests */ - req->buf = kmalloc(buffer_size, GFP_KERNEL); - if (!req->buf) { - usb_ep_free_request(ep, req); - return NULL; - } - - return req; -} - -static void mtp_request_free(struct usb_request *req, struct usb_ep *ep) -{ - if (req) { - kfree(req->buf); - usb_ep_free_request(ep, req); - } -} - -static inline int mtp_lock(atomic_t *excl) -{ - if (atomic_inc_return(excl) == 1) { - return 0; - } else { - atomic_dec(excl); - return -1; - } -} - -static inline void mtp_unlock(atomic_t *excl) -{ - atomic_dec(excl); -} - -/* add a request to the tail of a list */ -static void mtp_req_put(struct mtp_dev *dev, struct list_head *head, - struct usb_request *req) -{ - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - list_add_tail(&req->list, head); - spin_unlock_irqrestore(&dev->lock, flags); -} - -/* remove a request from the head of a list */ -static struct usb_request -*mtp_req_get(struct mtp_dev *dev, struct list_head *head) -{ - unsigned long flags; - struct usb_request *req; - - spin_lock_irqsave(&dev->lock, flags); - if (list_empty(head)) { - req = 0; - } else { - req = list_first_entry(head, struct usb_request, list); - list_del(&req->list); - } - spin_unlock_irqrestore(&dev->lock, flags); - return req; -} - -static void mtp_complete_in(struct usb_ep *ep, struct usb_request *req) -{ - struct mtp_dev *dev = _mtp_dev; - - if (req->status != 0) - dev->state = STATE_ERROR; - - mtp_req_put(dev, &dev->tx_idle, req); - - wake_up(&dev->write_wq); -} - -static void mtp_complete_out(struct usb_ep *ep, struct usb_request *req) -{ - struct mtp_dev *dev = _mtp_dev; - - dev->rx_done = 1; - if (req->status != 0) - dev->state = STATE_ERROR; - - wake_up(&dev->read_wq); -} - -static void mtp_complete_intr(struct usb_ep *ep, struct usb_request *req) -{ - struct mtp_dev *dev = _mtp_dev; - - if (req->status != 0) - dev->state = STATE_ERROR; - - mtp_req_put(dev, &dev->intr_idle, req); - - wake_up(&dev->intr_wq); -} - -static int mtp_create_bulk_endpoints(struct mtp_dev *dev, - struct usb_endpoint_descriptor *in_desc, - struct usb_endpoint_descriptor *out_desc, - struct usb_endpoint_descriptor *intr_desc) -{ - struct usb_composite_dev *cdev = dev->cdev; - struct usb_request *req; - struct usb_ep *ep; - int i; - - DBG(cdev, "create_bulk_endpoints dev: %p\n", dev); - - ep = usb_ep_autoconfig(cdev->gadget, in_desc); - if (!ep) { - DBG(cdev, "usb_ep_autoconfig for ep_in failed\n"); - return -ENODEV; - } - DBG(cdev, "usb_ep_autoconfig for ep_in got %s\n", ep->name); - ep->driver_data = dev; /* claim the endpoint */ - dev->ep_in = ep; - - ep = usb_ep_autoconfig(cdev->gadget, out_desc); - if (!ep) { - DBG(cdev, "usb_ep_autoconfig for ep_out failed\n"); - return -ENODEV; - } - DBG(cdev, "usb_ep_autoconfig for mtp ep_out got %s\n", ep->name); - ep->driver_data = dev; /* claim the endpoint */ - dev->ep_out = ep; - - ep = usb_ep_autoconfig(cdev->gadget, out_desc); - if (!ep) { - DBG(cdev, "usb_ep_autoconfig for ep_out failed\n"); - return -ENODEV; - } - DBG(cdev, "usb_ep_autoconfig for mtp ep_out got %s\n", ep->name); - ep->driver_data = dev; /* claim the endpoint */ - dev->ep_out = ep; - - ep = usb_ep_autoconfig(cdev->gadget, intr_desc); - if (!ep) { - DBG(cdev, "usb_ep_autoconfig for ep_intr failed\n"); - return -ENODEV; - } - DBG(cdev, "usb_ep_autoconfig for mtp ep_intr got %s\n", ep->name); - ep->driver_data = dev; /* claim the endpoint */ - dev->ep_intr = ep; - - /* now allocate requests for our endpoints */ - for (i = 0; i < TX_REQ_MAX; i++) { - req = mtp_request_new(dev->ep_in, MTP_BULK_BUFFER_SIZE); - if (!req) - goto fail; - req->complete = mtp_complete_in; - mtp_req_put(dev, &dev->tx_idle, req); - } - for (i = 0; i < RX_REQ_MAX; i++) { - req = mtp_request_new(dev->ep_out, MTP_BULK_BUFFER_SIZE); - if (!req) - goto fail; - req->complete = mtp_complete_out; - dev->rx_req[i] = req; - } - for (i = 0; i < INTR_REQ_MAX; i++) { - req = mtp_request_new(dev->ep_intr, INTR_BUFFER_SIZE); - if (!req) - goto fail; - req->complete = mtp_complete_intr; - mtp_req_put(dev, &dev->intr_idle, req); - } - - return 0; - -fail: - printk(KERN_ERR "mtp_bind() could not allocate requests\n"); - return -1; -} - -static ssize_t mtp_read(struct file *fp, char __user *buf, - size_t count, loff_t *pos) -{ - struct mtp_dev *dev = fp->private_data; - struct usb_composite_dev *cdev = dev->cdev; - struct usb_request *req; - int r = count, xfer; - int ret = 0; - - DBG(cdev, "mtp_read(%d)\n", count); - - if (count > MTP_BULK_BUFFER_SIZE) - return -EINVAL; - - /* we will block until we're online */ - DBG(cdev, "mtp_read: waiting for online state\n"); - ret = wait_event_interruptible(dev->read_wq, - dev->state != STATE_OFFLINE); - if (ret < 0) { - r = ret; - goto done; - } - spin_lock_irq(&dev->lock); - if (dev->state == STATE_CANCELED) { - /* report cancelation to userspace */ - dev->state = STATE_READY; - spin_unlock_irq(&dev->lock); - return -ECANCELED; - } - dev->state = STATE_BUSY; - spin_unlock_irq(&dev->lock); - -requeue_req: - /* queue a request */ - req = dev->rx_req[0]; - req->length = count; - dev->rx_done = 0; - ret = usb_ep_queue(dev->ep_out, req, GFP_KERNEL); - if (ret < 0) { - r = -EIO; - goto done; - } else { - DBG(cdev, "rx %p queue\n", req); - } - - /* wait for a request to complete */ - ret = wait_event_interruptible(dev->read_wq, dev->rx_done); - if (ret < 0) { - r = ret; - usb_ep_dequeue(dev->ep_out, req); - goto done; - } - if (dev->state == STATE_BUSY) { - /* If we got a 0-len packet, throw it back and try again. */ - if (req->actual == 0) - goto requeue_req; - - DBG(cdev, "rx %p %d\n", req, req->actual); - xfer = (req->actual < count) ? req->actual : count; - r = xfer; - if (copy_to_user(buf, req->buf, xfer)) - r = -EFAULT; - } else - r = -EIO; - -done: - spin_lock_irq(&dev->lock); - if (dev->state == STATE_CANCELED) - r = -ECANCELED; - else if (dev->state != STATE_OFFLINE) - dev->state = STATE_READY; - spin_unlock_irq(&dev->lock); - - DBG(cdev, "mtp_read returning %d\n", r); - return r; -} - -static ssize_t mtp_write(struct file *fp, const char __user *buf, - size_t count, loff_t *pos) -{ - struct mtp_dev *dev = fp->private_data; - struct usb_composite_dev *cdev = dev->cdev; - struct usb_request *req = 0; - int r = count, xfer; - int sendZLP = 0; - int ret; - - DBG(cdev, "mtp_write(%d)\n", count); - - spin_lock_irq(&dev->lock); - if (dev->state == STATE_CANCELED) { - /* report cancelation to userspace */ - dev->state = STATE_READY; - spin_unlock_irq(&dev->lock); - return -ECANCELED; - } - if (dev->state == STATE_OFFLINE) { - spin_unlock_irq(&dev->lock); - return -ENODEV; - } - dev->state = STATE_BUSY; - spin_unlock_irq(&dev->lock); - - /* we need to send a zero length packet to signal the end of transfer - * if the transfer size is aligned to a packet boundary. - */ - if ((count & (dev->ep_in->maxpacket - 1)) == 0) { - sendZLP = 1; - } - - while (count > 0 || sendZLP) { - /* so we exit after sending ZLP */ - if (count == 0) - sendZLP = 0; - - if (dev->state != STATE_BUSY) { - DBG(cdev, "mtp_write dev->error\n"); - r = -EIO; - break; - } - - /* get an idle tx request to use */ - req = 0; - ret = wait_event_interruptible(dev->write_wq, - ((req = mtp_req_get(dev, &dev->tx_idle)) - || dev->state != STATE_BUSY)); - if (!req) { - r = ret; - break; - } - - if (count > MTP_BULK_BUFFER_SIZE) - xfer = MTP_BULK_BUFFER_SIZE; - else - xfer = count; - if (xfer && copy_from_user(req->buf, buf, xfer)) { - r = -EFAULT; - break; - } - - req->length = xfer; - ret = usb_ep_queue(dev->ep_in, req, GFP_KERNEL); - if (ret < 0) { - DBG(cdev, "mtp_write: xfer error %d\n", ret); - r = -EIO; - break; - } - - buf += xfer; - count -= xfer; - - /* zero this so we don't try to free it on error exit */ - req = 0; - } - - if (req) - mtp_req_put(dev, &dev->tx_idle, req); - - spin_lock_irq(&dev->lock); - if (dev->state == STATE_CANCELED) - r = -ECANCELED; - else if (dev->state != STATE_OFFLINE) - dev->state = STATE_READY; - spin_unlock_irq(&dev->lock); - - DBG(cdev, "mtp_write returning %d\n", r); - return r; -} - -/* read from a local file and write to USB */ -static void send_file_work(struct work_struct *data) { - struct mtp_dev *dev = container_of(data, struct mtp_dev, send_file_work); - struct usb_composite_dev *cdev = dev->cdev; - struct usb_request *req = 0; - struct mtp_data_header *header; - struct file *filp; - loff_t offset; - int64_t count; - int xfer, ret, hdr_size; - int r = 0; - int sendZLP = 0; - - /* read our parameters */ - smp_rmb(); - filp = dev->xfer_file; - offset = dev->xfer_file_offset; - count = dev->xfer_file_length; - - DBG(cdev, "send_file_work(%lld %lld)\n", offset, count); - - if (dev->xfer_send_header) { - hdr_size = sizeof(struct mtp_data_header); - count += hdr_size; - } else { - hdr_size = 0; - } - - /* we need to send a zero length packet to signal the end of transfer - * if the transfer size is aligned to a packet boundary. - */ - if ((count & (dev->ep_in->maxpacket - 1)) == 0) { - sendZLP = 1; - } - - while (count > 0 || sendZLP) { - /* so we exit after sending ZLP */ - if (count == 0) - sendZLP = 0; - - /* get an idle tx request to use */ - req = 0; - ret = wait_event_interruptible(dev->write_wq, - (req = mtp_req_get(dev, &dev->tx_idle)) - || dev->state != STATE_BUSY); - if (dev->state == STATE_CANCELED) { - r = -ECANCELED; - break; - } - if (!req) { - r = ret; - break; - } - - if (count > MTP_BULK_BUFFER_SIZE) - xfer = MTP_BULK_BUFFER_SIZE; - else - xfer = count; - - if (hdr_size) { - /* prepend MTP data header */ - header = (struct mtp_data_header *)req->buf; - header->length = __cpu_to_le32(count); - header->type = __cpu_to_le16(2); /* data packet */ - header->command = __cpu_to_le16(dev->xfer_command); - header->transaction_id = __cpu_to_le32(dev->xfer_transaction_id); - } - - ret = vfs_read(filp, req->buf + hdr_size, xfer - hdr_size, &offset); - if (ret < 0) { - r = ret; - break; - } - xfer = ret + hdr_size; - hdr_size = 0; - - req->length = xfer; - ret = usb_ep_queue(dev->ep_in, req, GFP_KERNEL); - if (ret < 0) { - DBG(cdev, "send_file_work: xfer error %d\n", ret); - dev->state = STATE_ERROR; - r = -EIO; - break; - } - - count -= xfer; - - /* zero this so we don't try to free it on error exit */ - req = 0; - } - - if (req) - mtp_req_put(dev, &dev->tx_idle, req); - - DBG(cdev, "send_file_work returning %d\n", r); - /* write the result */ - dev->xfer_result = r; - smp_wmb(); -} - -/* read from USB and write to a local file */ -static void receive_file_work(struct work_struct *data) -{ - struct mtp_dev *dev = container_of(data, struct mtp_dev, receive_file_work); - struct usb_composite_dev *cdev = dev->cdev; - struct usb_request *read_req = NULL, *write_req = NULL; - struct file *filp; - loff_t offset; - int64_t count; - int ret, cur_buf = 0; - int r = 0; - - /* read our parameters */ - smp_rmb(); - filp = dev->xfer_file; - offset = dev->xfer_file_offset; - count = dev->xfer_file_length; - - DBG(cdev, "receive_file_work(%lld)\n", count); - - while (count > 0 || write_req) { - if (count > 0) { - /* queue a request */ - read_req = dev->rx_req[cur_buf]; - cur_buf = (cur_buf + 1) % RX_REQ_MAX; - - read_req->length = (count > MTP_BULK_BUFFER_SIZE - ? MTP_BULK_BUFFER_SIZE : count); - dev->rx_done = 0; - ret = usb_ep_queue(dev->ep_out, read_req, GFP_KERNEL); - if (ret < 0) { - r = -EIO; - dev->state = STATE_ERROR; - break; - } - } - - if (write_req) { - DBG(cdev, "rx %p %d\n", write_req, write_req->actual); - ret = vfs_write(filp, write_req->buf, write_req->actual, - &offset); - DBG(cdev, "vfs_write %d\n", ret); - if (ret != write_req->actual) { - r = -EIO; - dev->state = STATE_ERROR; - break; - } - write_req = NULL; - } - - if (read_req) { - /* wait for our last read to complete */ - ret = wait_event_interruptible(dev->read_wq, - dev->rx_done || dev->state != STATE_BUSY); - if (dev->state == STATE_CANCELED) { - r = -ECANCELED; - if (!dev->rx_done) - usb_ep_dequeue(dev->ep_out, read_req); - break; - } - /* if xfer_file_length is 0xFFFFFFFF, then we read until - * we get a zero length packet - */ - if (count != 0xFFFFFFFF) - count -= read_req->actual; - if (read_req->actual < read_req->length) { - /* short packet is used to signal EOF for sizes > 4 gig */ - DBG(cdev, "got short packet\n"); - count = 0; - } - - write_req = read_req; - read_req = NULL; - } - } - - DBG(cdev, "receive_file_work returning %d\n", r); - /* write the result */ - dev->xfer_result = r; - smp_wmb(); -} - -static int mtp_send_event(struct mtp_dev *dev, struct mtp_event *event) -{ - struct usb_request *req= NULL; - int ret; - int length = event->length; - - DBG(dev->cdev, "mtp_send_event(%d)\n", event->length); - - if (length < 0 || length > INTR_BUFFER_SIZE) - return -EINVAL; - if (dev->state == STATE_OFFLINE) - return -ENODEV; - - ret = wait_event_interruptible_timeout(dev->intr_wq, - (req = mtp_req_get(dev, &dev->intr_idle)), msecs_to_jiffies(1000)); - if (!req) - return -ETIME; - - if (copy_from_user(req->buf, (void __user *)event->data, length)) { - mtp_req_put(dev, &dev->intr_idle, req); - return -EFAULT; - } - req->length = length; - ret = usb_ep_queue(dev->ep_intr, req, GFP_KERNEL); - if (ret) - mtp_req_put(dev, &dev->intr_idle, req); - - return ret; -} - -static long mtp_ioctl(struct file *fp, unsigned code, unsigned long value) -{ - struct mtp_dev *dev = fp->private_data; - struct file *filp = NULL; - int ret = -EINVAL; - - if (mtp_lock(&dev->ioctl_excl)) - return -EBUSY; - - switch (code) { - case MTP_SEND_FILE: - case MTP_RECEIVE_FILE: - case MTP_SEND_FILE_WITH_HEADER: - { - struct mtp_file_range mfr; - struct work_struct *work; - - spin_lock_irq(&dev->lock); - if (dev->state == STATE_CANCELED) { - /* report cancelation to userspace */ - dev->state = STATE_READY; - spin_unlock_irq(&dev->lock); - ret = -ECANCELED; - goto out; - } - if (dev->state == STATE_OFFLINE) { - spin_unlock_irq(&dev->lock); - ret = -ENODEV; - goto out; - } - dev->state = STATE_BUSY; - spin_unlock_irq(&dev->lock); - - if (copy_from_user(&mfr, (void __user *)value, sizeof(mfr))) { - ret = -EFAULT; - goto fail; - } - /* hold a reference to the file while we are working with it */ - filp = fget(mfr.fd); - if (!filp) { - ret = -EBADF; - goto fail; - } - - /* write the parameters */ - dev->xfer_file = filp; - dev->xfer_file_offset = mfr.offset; - dev->xfer_file_length = mfr.length; - smp_wmb(); - - if (code == MTP_SEND_FILE_WITH_HEADER) { - work = &dev->send_file_work; - dev->xfer_send_header = 1; - dev->xfer_command = mfr.command; - dev->xfer_transaction_id = mfr.transaction_id; - } else if (code == MTP_SEND_FILE) { - work = &dev->send_file_work; - dev->xfer_send_header = 0; - } else { - work = &dev->receive_file_work; - } - - /* We do the file transfer on a work queue so it will run - * in kernel context, which is necessary for vfs_read and - * vfs_write to use our buffers in the kernel address space. - */ - queue_work(dev->wq, work); - /* wait for operation to complete */ - flush_workqueue(dev->wq); - fput(filp); - - /* read the result */ - smp_rmb(); - ret = dev->xfer_result; - break; - } - case MTP_SEND_EVENT: - { - struct mtp_event event; - /* return here so we don't change dev->state below, - * which would interfere with bulk transfer state. - */ - if (copy_from_user(&event, (void __user *)value, sizeof(event))) - ret = -EFAULT; - else - ret = mtp_send_event(dev, &event); - goto out; - } - } - -fail: - spin_lock_irq(&dev->lock); - if (dev->state == STATE_CANCELED) - ret = -ECANCELED; - else if (dev->state != STATE_OFFLINE) - dev->state = STATE_READY; - spin_unlock_irq(&dev->lock); -out: - mtp_unlock(&dev->ioctl_excl); - DBG(dev->cdev, "ioctl returning %d\n", ret); - return ret; -} - -static int mtp_open(struct inode *ip, struct file *fp) -{ - printk(KERN_INFO "mtp_open\n"); - if (mtp_lock(&_mtp_dev->open_excl)) - return -EBUSY; - - /* clear any error condition */ - if (_mtp_dev->state != STATE_OFFLINE) - _mtp_dev->state = STATE_READY; - - fp->private_data = _mtp_dev; - return 0; -} - -static int mtp_release(struct inode *ip, struct file *fp) -{ - printk(KERN_INFO "mtp_release\n"); - - mtp_unlock(&_mtp_dev->open_excl); - return 0; -} - -/* file operations for /dev/mtp_usb */ -static const struct file_operations mtp_fops = { - .owner = THIS_MODULE, - .read = mtp_read, - .write = mtp_write, - .unlocked_ioctl = mtp_ioctl, - .open = mtp_open, - .release = mtp_release, -}; - -static struct miscdevice mtp_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = mtp_shortname, - .fops = &mtp_fops, -}; - -static int mtp_ctrlrequest(struct usb_composite_dev *cdev, - const struct usb_ctrlrequest *ctrl) -{ - struct mtp_dev *dev = _mtp_dev; - int value = -EOPNOTSUPP; - u16 w_index = le16_to_cpu(ctrl->wIndex); - u16 w_value = le16_to_cpu(ctrl->wValue); - u16 w_length = le16_to_cpu(ctrl->wLength); - unsigned long flags; - - VDBG(cdev, "mtp_ctrlrequest " - "%02x.%02x v%04x i%04x l%u\n", - ctrl->bRequestType, ctrl->bRequest, - w_value, w_index, w_length); - - /* Handle MTP OS string */ - if (ctrl->bRequestType == - (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE) - && ctrl->bRequest == USB_REQ_GET_DESCRIPTOR - && (w_value >> 8) == USB_DT_STRING - && (w_value & 0xFF) == MTP_OS_STRING_ID) { - value = (w_length < sizeof(mtp_os_string) - ? w_length : sizeof(mtp_os_string)); - memcpy(cdev->req->buf, mtp_os_string, value); - } else if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR) { - /* Handle MTP OS descriptor */ - DBG(cdev, "vendor request: %d index: %d value: %d length: %d\n", - ctrl->bRequest, w_index, w_value, w_length); - - if (ctrl->bRequest == 1 - && (ctrl->bRequestType & USB_DIR_IN) - && (w_index == 4 || w_index == 5)) { - value = (w_length < sizeof(mtp_ext_config_desc) ? - w_length : sizeof(mtp_ext_config_desc)); - memcpy(cdev->req->buf, &mtp_ext_config_desc, value); - } - } else if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) { - DBG(cdev, "class request: %d index: %d value: %d length: %d\n", - ctrl->bRequest, w_index, w_value, w_length); - - if (ctrl->bRequest == MTP_REQ_CANCEL && w_index == 0 - && w_value == 0) { - DBG(cdev, "MTP_REQ_CANCEL\n"); - - spin_lock_irqsave(&dev->lock, flags); - if (dev->state == STATE_BUSY) { - dev->state = STATE_CANCELED; - wake_up(&dev->read_wq); - wake_up(&dev->write_wq); - } - spin_unlock_irqrestore(&dev->lock, flags); - - /* We need to queue a request to read the remaining - * bytes, but we don't actually need to look at - * the contents. - */ - value = w_length; - } else if (ctrl->bRequest == MTP_REQ_GET_DEVICE_STATUS - && w_index == 0 && w_value == 0) { - struct mtp_device_status *status = cdev->req->buf; - status->wLength = - __constant_cpu_to_le16(sizeof(*status)); - - DBG(cdev, "MTP_REQ_GET_DEVICE_STATUS\n"); - spin_lock_irqsave(&dev->lock, flags); - /* device status is "busy" until we report - * the cancelation to userspace - */ - if (dev->state == STATE_CANCELED) - status->wCode = - __cpu_to_le16(MTP_RESPONSE_DEVICE_BUSY); - else - status->wCode = - __cpu_to_le16(MTP_RESPONSE_OK); - spin_unlock_irqrestore(&dev->lock, flags); - value = sizeof(*status); - } - } - - /* respond with data transfer or status phase? */ - if (value >= 0) { - int rc; - cdev->req->zero = value < w_length; - cdev->req->length = value; - rc = usb_ep_queue(cdev->gadget->ep0, cdev->req, GFP_ATOMIC); - if (rc < 0) - ERROR(cdev, "%s setup response queue error\n", __func__); - } - return value; -} - -static int -mtp_function_bind(struct usb_configuration *c, struct usb_function *f) -{ - struct usb_composite_dev *cdev = c->cdev; - struct mtp_dev *dev = func_to_mtp(f); - int id; - int ret; - - dev->cdev = cdev; - DBG(cdev, "mtp_function_bind dev: %p\n", dev); - - /* allocate interface ID(s) */ - id = usb_interface_id(c, f); - if (id < 0) - return id; - mtp_interface_desc.bInterfaceNumber = id; - - /* allocate endpoints */ - ret = mtp_create_bulk_endpoints(dev, &mtp_fullspeed_in_desc, - &mtp_fullspeed_out_desc, &mtp_intr_desc); - if (ret) - return ret; - - /* support high speed hardware */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - mtp_highspeed_in_desc.bEndpointAddress = - mtp_fullspeed_in_desc.bEndpointAddress; - mtp_highspeed_out_desc.bEndpointAddress = - mtp_fullspeed_out_desc.bEndpointAddress; - } - - DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", - gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", - f->name, dev->ep_in->name, dev->ep_out->name); - return 0; -} - -static void -mtp_function_unbind(struct usb_configuration *c, struct usb_function *f) -{ - struct mtp_dev *dev = func_to_mtp(f); - struct usb_request *req; - int i; - - while ((req = mtp_req_get(dev, &dev->tx_idle))) - mtp_request_free(req, dev->ep_in); - for (i = 0; i < RX_REQ_MAX; i++) - mtp_request_free(dev->rx_req[i], dev->ep_out); - while ((req = mtp_req_get(dev, &dev->intr_idle))) - mtp_request_free(req, dev->ep_intr); - dev->state = STATE_OFFLINE; -} - -static int mtp_function_set_alt(struct usb_function *f, - unsigned intf, unsigned alt) -{ - struct mtp_dev *dev = func_to_mtp(f); - struct usb_composite_dev *cdev = f->config->cdev; - int ret; - - DBG(cdev, "mtp_function_set_alt intf: %d alt: %d\n", intf, alt); - ret = usb_ep_enable(dev->ep_in, - ep_choose(cdev->gadget, - &mtp_highspeed_in_desc, - &mtp_fullspeed_in_desc)); - if (ret) - return ret; - ret = usb_ep_enable(dev->ep_out, - ep_choose(cdev->gadget, - &mtp_highspeed_out_desc, - &mtp_fullspeed_out_desc)); - if (ret) { - usb_ep_disable(dev->ep_in); - return ret; - } - ret = usb_ep_enable(dev->ep_intr, &mtp_intr_desc); - if (ret) { - usb_ep_disable(dev->ep_out); - usb_ep_disable(dev->ep_in); - return ret; - } - dev->state = STATE_READY; - - /* readers may be blocked waiting for us to go online */ - wake_up(&dev->read_wq); - return 0; -} - -static void mtp_function_disable(struct usb_function *f) -{ - struct mtp_dev *dev = func_to_mtp(f); - struct usb_composite_dev *cdev = dev->cdev; - - DBG(cdev, "mtp_function_disable\n"); - dev->state = STATE_OFFLINE; - usb_ep_disable(dev->ep_in); - usb_ep_disable(dev->ep_out); - usb_ep_disable(dev->ep_intr); - - /* readers may be blocked waiting for us to go online */ - wake_up(&dev->read_wq); - - VDBG(cdev, "%s disabled\n", dev->function.name); -} - -static int mtp_bind_config(struct usb_configuration *c, bool ptp_config) -{ - struct mtp_dev *dev = _mtp_dev; - int ret = 0; - - printk(KERN_INFO "mtp_bind_config\n"); - - /* allocate a string ID for our interface */ - if (mtp_string_defs[INTERFACE_STRING_INDEX].id == 0) { - ret = usb_string_id(c->cdev); - if (ret < 0) - return ret; - mtp_string_defs[INTERFACE_STRING_INDEX].id = ret; - mtp_interface_desc.iInterface = ret; - } - - dev->cdev = c->cdev; - dev->function.name = "mtp"; - dev->function.strings = mtp_strings; - if (ptp_config) { - dev->function.descriptors = fs_ptp_descs; - dev->function.hs_descriptors = hs_ptp_descs; - } else { - dev->function.descriptors = fs_mtp_descs; - dev->function.hs_descriptors = hs_mtp_descs; - } - dev->function.bind = mtp_function_bind; - dev->function.unbind = mtp_function_unbind; - dev->function.set_alt = mtp_function_set_alt; - dev->function.disable = mtp_function_disable; - - return usb_add_function(c, &dev->function); -} - -static int mtp_setup(void) -{ - struct mtp_dev *dev; - int ret; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - spin_lock_init(&dev->lock); - init_waitqueue_head(&dev->read_wq); - init_waitqueue_head(&dev->write_wq); - init_waitqueue_head(&dev->intr_wq); - atomic_set(&dev->open_excl, 0); - atomic_set(&dev->ioctl_excl, 0); - INIT_LIST_HEAD(&dev->tx_idle); - INIT_LIST_HEAD(&dev->intr_idle); - - dev->wq = create_singlethread_workqueue("f_mtp"); - if (!dev->wq) { - ret = -ENOMEM; - goto err1; - } - INIT_WORK(&dev->send_file_work, send_file_work); - INIT_WORK(&dev->receive_file_work, receive_file_work); - - _mtp_dev = dev; - - ret = misc_register(&mtp_device); - if (ret) - goto err2; - - return 0; - -err2: - destroy_workqueue(dev->wq); -err1: - _mtp_dev = NULL; - kfree(dev); - printk(KERN_ERR "mtp gadget driver failed to initialize\n"); - return ret; -} - -static void mtp_cleanup(void) -{ - struct mtp_dev *dev = _mtp_dev; - - if (!dev) - return; - - misc_deregister(&mtp_device); - destroy_workqueue(dev->wq); - _mtp_dev = NULL; - kfree(dev); -} diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index 459dbdead0a4..5e1495097ec3 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c @@ -541,7 +541,7 @@ int pn_bind(struct usb_configuration *c, struct usb_function *f) req = usb_ep_alloc_request(fp->out_ep, GFP_KERNEL); if (!req) - goto err_req; + goto err; req->complete = pn_rx_complete; fp->out_reqv[i] = req; @@ -550,18 +550,14 @@ int pn_bind(struct usb_configuration *c, struct usb_function *f) /* Outgoing USB requests */ fp->in_req = usb_ep_alloc_request(fp->in_ep, GFP_KERNEL); if (!fp->in_req) - goto err_req; + goto err; INFO(cdev, "USB CDC Phonet function\n"); INFO(cdev, "using %s, OUT %s, IN %s\n", cdev->gadget->name, fp->out_ep->name, fp->in_ep->name); return 0; -err_req: - for (i = 0; i < phonet_rxq_size && fp->out_reqv[i]; i++) - usb_ep_free_request(fp->out_ep, fp->out_reqv[i]); err: - if (fp->out_ep) fp->out_ep->driver_data = NULL; if (fp->in_ep) diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 96adf45d44c2..fa12ec8364ef 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include @@ -86,11 +86,8 @@ struct f_rndis { struct gether port; u8 ctrl_id, data_id; u8 ethaddr[ETH_ALEN]; - u32 vendorID; - const char *manufacturer; int config; - struct rndis_ep_descs fs; struct rndis_ep_descs hs; @@ -190,11 +187,12 @@ static struct usb_interface_assoc_descriptor rndis_iad_descriptor = { .bLength = sizeof rndis_iad_descriptor, .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, + .bFirstInterface = 0, /* XXX, hardcoded */ .bInterfaceCount = 2, // control + data .bFunctionClass = USB_CLASS_COMM, .bFunctionSubClass = USB_CDC_SUBCLASS_ETHERNET, - .bFunctionProtocol = USB_CDC_ACM_PROTO_VENDOR, + .bFunctionProtocol = USB_CDC_PROTO_NONE, /* .iFunction = DYNAMIC */ }; @@ -488,10 +486,10 @@ static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt) usb_ep_disable(rndis->notify); } else { VDBG(cdev, "init rndis ctrl %d\n", intf); + rndis->notify_desc = ep_choose(cdev->gadget, + rndis->hs.notify, + rndis->fs.notify); } - rndis->notify_desc = ep_choose(cdev->gadget, - rndis->hs.notify, - rndis->fs.notify); usb_ep_enable(rndis->notify, rndis->notify_desc); rndis->notify->driver_data = rndis; @@ -505,11 +503,11 @@ static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (!rndis->port.in) { DBG(cdev, "init rndis\n"); + rndis->port.in = ep_choose(cdev->gadget, + rndis->hs.in, rndis->fs.in); + rndis->port.out = ep_choose(cdev->gadget, + rndis->hs.out, rndis->fs.out); } - rndis->port.in = ep_choose(cdev->gadget, - rndis->hs.in, rndis->fs.in); - rndis->port.out = ep_choose(cdev->gadget, - rndis->hs.out, rndis->fs.out); /* Avoid ZLPs; they can be troublesome. */ rndis->port.is_zlp_ok = false; @@ -708,9 +706,12 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) rndis_set_param_medium(rndis->config, NDIS_MEDIUM_802_3, 0); rndis_set_host_mac(rndis->config, rndis->ethaddr); - if (rndis_set_param_vendor(rndis->config, rndis->vendorID, - rndis->manufacturer)) - goto fail; +#if 0 +// FIXME + if (rndis_set_param_vendor(rndis->config, vendorID, + manufacturer)) + goto fail0; +#endif /* NOTE: all that is done without knowing or caring about * the network link ... which is unavailable to this code @@ -785,8 +786,7 @@ static inline bool can_support_rndis(struct usb_configuration *c) * for calling @gether_cleanup() before module unload. */ int -rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], - u32 vendorID, const char *manufacturer) +rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) { struct f_rndis *rndis; int status; @@ -794,14 +794,14 @@ rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], if (!can_support_rndis(c) || !ethaddr) return -EINVAL; - /* setup RNDIS itself */ - status = rndis_init(); - if (status < 0) - return status; - /* maybe allocate device-global string IDs */ if (rndis_string_defs[0].id == 0) { + /* ... and setup RNDIS itself */ + status = rndis_init(); + if (status < 0) + return status; + /* control interface label */ status = usb_string_id(c->cdev); if (status < 0) @@ -831,8 +831,6 @@ rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], goto fail; memcpy(rndis->ethaddr, ethaddr, ETH_ALEN); - rndis->vendorID = vendorID; - rndis->manufacturer = manufacturer; /* RNDIS activates when the host changes this filter */ rndis->port.cdc_filter = 0; diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index e358130a4857..0360f56221ea 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -2553,7 +2553,7 @@ static int do_scsi_command(struct fsg_dev *fsg) fsg->data_size_from_cmnd = 0; sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]); if ((reply = check_command(fsg, fsg->cmnd_size, - DATA_DIR_UNKNOWN, ~0, 0, unknown)) == 0) { + DATA_DIR_UNKNOWN, 0xff, 0, unknown)) == 0) { fsg->curlun->sense_data = SS_INVALID_COMMAND; reply = -EINVAL; } diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 44d789d27cf3..4e4833168087 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -717,8 +717,6 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) lastreq = list_entry(ep->queue.prev, struct fsl_req, queue); lastreq->tail->next_td_ptr = cpu_to_hc32(req->head->td_dma & DTD_ADDR_MASK); - /* Ensure dTD's next dtd pointer to be updated */ - wmb(); /* Read prime bit, if 1 goto done */ if (fsl_readl(&dr_regs->endpointprime) & bitmask) goto out; @@ -769,7 +767,7 @@ out: * @is_last: return flag if it is the last dTD of the request * return: pointer to the built dTD */ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, - dma_addr_t *dma, int *is_last, gfp_t gfp_flags) + dma_addr_t *dma, int *is_last) { u32 swap_temp; struct ep_td_struct *dtd; @@ -778,7 +776,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, *length = min(req->req.length - req->req.actual, (unsigned)EP_MAX_LENGTH_TRANSFER); - dtd = dma_pool_alloc(udc_controller->td_pool, gfp_flags, dma); + dtd = dma_pool_alloc(udc_controller->td_pool, GFP_KERNEL, dma); if (dtd == NULL) return dtd; @@ -828,7 +826,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, } /* Generate dtd chain for a request */ -static int fsl_req_to_dtd(struct fsl_req *req, gfp_t gfp_flags) +static int fsl_req_to_dtd(struct fsl_req *req) { unsigned count; int is_last; @@ -837,7 +835,7 @@ static int fsl_req_to_dtd(struct fsl_req *req, gfp_t gfp_flags) dma_addr_t dma; do { - dtd = fsl_build_dtd(req, &count, &dma, &is_last, gfp_flags); + dtd = fsl_build_dtd(req, &count, &dma, &is_last); if (dtd == NULL) return -ENOMEM; @@ -911,11 +909,13 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) req->req.actual = 0; req->dtd_count = 0; + spin_lock_irqsave(&udc->lock, flags); + /* build dtds and push them to device queue */ - if (!fsl_req_to_dtd(req, gfp_flags)) { - spin_lock_irqsave(&udc->lock, flags); + if (!fsl_req_to_dtd(req)) { fsl_queue_td(ep, req); } else { + spin_unlock_irqrestore(&udc->lock, flags); return -ENOMEM; } @@ -1294,7 +1294,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction) ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); req->mapped = 1; - if (fsl_req_to_dtd(req, GFP_ATOMIC) == 0) + if (fsl_req_to_dtd(req) == 0) fsl_queue_td(ep, req); else return -ENOMEM; @@ -1378,7 +1378,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, req->mapped = 1; /* prime the data phase */ - if ((fsl_req_to_dtd(req, GFP_ATOMIC) == 0)) + if ((fsl_req_to_dtd(req) == 0)) fsl_queue_td(ep, req); else /* no mem */ goto stall; diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c index 79afa8256cb3..2523e54097bd 100644 --- a/drivers/usb/gadget/hid.c +++ b/drivers/usb/gadget/hid.c @@ -69,9 +69,9 @@ static struct usb_device_descriptor device_desc = { /* .bDeviceClass = USB_CLASS_COMM, */ /* .bDeviceSubClass = 0, */ /* .bDeviceProtocol = 0, */ - .bDeviceClass = USB_CLASS_PER_INTERFACE, - .bDeviceSubClass = 0, - .bDeviceProtocol = 0, + .bDeviceClass = 0xEF, + .bDeviceSubClass = 2, + .bDeviceProtocol = 1, /* .bMaxPacketSize0 = f(hardware) */ /* Vendor and product id can be overridden by module parameters. */ diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index febadaa2a80d..a56876aaf76c 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -1050,8 +1050,6 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) // FIXME don't call this with the spinlock held ... if (copy_to_user (buf, dev->req->buf, len)) retval = -EFAULT; - else - retval = len; clean_req (dev->gadget->ep0, dev->req); /* NOTE userspace can't yet choose to stall */ } diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 1852c8a20c3d..68dbcc3e4cc2 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -320,7 +320,6 @@ struct pch_udc_ep { * @registered: driver regsitered with system * @suspended: driver in suspended state * @connected: gadget driver associated - * @vbus_session: required vbus_session state * @set_cfg_not_acked: pending acknowledgement 4 setup * @waiting_zlp_ack: pending acknowledgement 4 ZLP * @data_requests: DMA pool for data requests @@ -347,7 +346,6 @@ struct pch_udc_dev { registered:1, suspended:1, connected:1, - vbus_session:1, set_cfg_not_acked:1, waiting_zlp_ack:1; struct pci_pool *data_requests; @@ -365,7 +363,6 @@ struct pch_udc_dev { #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 #define PCI_VENDOR_ID_ROHM 0x10DB #define PCI_DEVICE_ID_ML7213_IOH_UDC 0x801D -#define PCI_DEVICE_ID_ML7831_IOH_UDC 0x8808 static const char ep0_string[] = "ep0in"; static DEFINE_SPINLOCK(udc_stall_spinlock); /* stall spin lock */ @@ -564,29 +561,6 @@ static void pch_udc_clear_disconnect(struct pch_udc_dev *dev) pch_udc_bit_clr(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES); } -/** - * pch_udc_reconnect() - This API initializes usb device controller, - * and clear the disconnect status. - * @dev: Reference to pch_udc_regs structure - */ -static void pch_udc_init(struct pch_udc_dev *dev); -static void pch_udc_reconnect(struct pch_udc_dev *dev) -{ - pch_udc_init(dev); - - /* enable device interrupts */ - /* pch_udc_enable_interrupts() */ - pch_udc_bit_clr(dev, UDC_DEVIRQMSK_ADDR, - UDC_DEVINT_UR | UDC_DEVINT_ENUM); - - /* Clear the disconnect */ - pch_udc_bit_set(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES); - pch_udc_bit_clr(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_SD); - mdelay(1); - /* Resume USB signalling */ - pch_udc_bit_clr(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES); -} - /** * pch_udc_vbus_session() - set or clearr the disconnect status. * @dev: Reference to pch_udc_regs structure @@ -597,18 +571,10 @@ static void pch_udc_reconnect(struct pch_udc_dev *dev) static inline void pch_udc_vbus_session(struct pch_udc_dev *dev, int is_active) { - if (is_active) { - pch_udc_reconnect(dev); - dev->vbus_session = 1; - } else { - if (dev->driver && dev->driver->disconnect) { - spin_unlock(&dev->lock); - dev->driver->disconnect(&dev->gadget); - spin_lock(&dev->lock); - } + if (is_active) + pch_udc_clear_disconnect(dev); + else pch_udc_set_disconnect(dev); - dev->vbus_session = 0; - } } /** @@ -1168,17 +1134,7 @@ static int pch_udc_pcd_pullup(struct usb_gadget *gadget, int is_on) if (!gadget) return -EINVAL; dev = container_of(gadget, struct pch_udc_dev, gadget); - if (is_on) { - pch_udc_reconnect(dev); - } else { - if (dev->driver && dev->driver->disconnect) { - spin_unlock(&dev->lock); - dev->driver->disconnect(&dev->gadget); - spin_lock(&dev->lock); - } - pch_udc_set_disconnect(dev); - } - + pch_udc_vbus_session(dev, is_on); return 0; } @@ -2382,11 +2338,8 @@ static void pch_udc_svc_ur_interrupt(struct pch_udc_dev *dev) /* Complete request queue */ empty_req_queue(ep); } - if (dev->driver && dev->driver->disconnect) { - spin_unlock(&dev->lock); + if (dev->driver && dev->driver->disconnect) dev->driver->disconnect(&dev->gadget); - spin_lock(&dev->lock); - } } /** @@ -2421,11 +2374,6 @@ static void pch_udc_svc_enum_interrupt(struct pch_udc_dev *dev) pch_udc_set_dma(dev, DMA_DIR_TX); pch_udc_set_dma(dev, DMA_DIR_RX); pch_udc_ep_set_rrdy(&(dev->ep[UDC_EP0OUT_IDX])); - - /* enable device interrupts */ - pch_udc_enable_interrupts(dev, UDC_DEVINT_UR | UDC_DEVINT_US | - UDC_DEVINT_ES | UDC_DEVINT_ENUM | - UDC_DEVINT_SI | UDC_DEVINT_SC); } /** @@ -2527,24 +2475,8 @@ static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr) if (dev_intr & UDC_DEVINT_SC) pch_udc_svc_cfg_interrupt(dev); /* USB Suspend interrupt */ - if (dev_intr & UDC_DEVINT_US) { - if (dev->driver - && dev->driver->suspend) { - spin_unlock(&dev->lock); - dev->driver->suspend(&dev->gadget); - spin_lock(&dev->lock); - } - - if (dev->vbus_session == 0) { - if (dev->driver && dev->driver->disconnect) { - spin_unlock(&dev->lock); - dev->driver->disconnect(&dev->gadget); - spin_lock(&dev->lock); - } - pch_udc_reconnect(dev); - } + if (dev_intr & UDC_DEVINT_US) dev_dbg(&dev->pdev->dev, "USB_SUSPEND\n"); - } /* Clear the SOF interrupt, if enabled */ if (dev_intr & UDC_DEVINT_SOF) dev_dbg(&dev->pdev->dev, "SOF\n"); @@ -2570,14 +2502,6 @@ static irqreturn_t pch_udc_isr(int irq, void *pdev) dev_intr = pch_udc_read_device_interrupts(dev); ep_intr = pch_udc_read_ep_interrupts(dev); - /* For a hot plug, this find that the controller is hung up. */ - if (dev_intr == ep_intr) - if (dev_intr == pch_udc_readl(dev, UDC_DEVCFG_ADDR)) { - dev_dbg(&dev->pdev->dev, "UDC: Hung up\n"); - /* The controller is reset */ - pch_udc_writel(dev, UDC_SRST, UDC_SRST_ADDR); - return IRQ_HANDLED; - } if (dev_intr) /* Clear device interrupts */ pch_udc_write_device_interrupts(dev, dev_intr); @@ -2991,10 +2915,8 @@ static int pch_udc_probe(struct pci_dev *pdev, } pch_udc = dev; /* initialize the hardware */ - if (pch_udc_pcd_init(dev)) { - retval = -ENODEV; + if (pch_udc_pcd_init(dev)) goto finished; - } if (request_irq(pdev->irq, pch_udc_isr, IRQF_SHARED, KBUILD_MODNAME, dev)) { dev_err(&pdev->dev, "%s: request_irq(%d) fail\n", __func__, @@ -3049,11 +2971,6 @@ static DEFINE_PCI_DEVICE_TABLE(pch_udc_pcidev_id) = { .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, .class_mask = 0xffffffff, }, - { - PCI_DEVICE(PCI_VENDOR_ID_ROHM, PCI_DEVICE_ID_ML7831_IOH_UDC), - .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, - .class_mask = 0xffffffff, - }, { 0 }, }; diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 88a464cc96c0..271ef94668e7 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -1602,7 +1602,7 @@ cleanup(void) if (status) ERROR(dev, "usb_gadget_unregister_driver %x\n", status); - unregister_chrdev_region(g_printer_devno, 1); + unregister_chrdev_region(g_printer_devno, 2); class_destroy(usb_gadget_class); mutex_unlock(&usb_printer_gadget.lock_printer_io); } diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index bbfbde741595..d3cdffea9c8a 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -1147,15 +1147,11 @@ static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS]; #endif /* CONFIG_USB_GADGET_DEBUG_FILES */ -static bool rndis_initialized; int rndis_init(void) { u8 i; - if (rndis_initialized) - return 0; - for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { #ifdef CONFIG_USB_GADGET_DEBUG_FILES char name [20]; @@ -1182,7 +1178,6 @@ int rndis_init(void) INIT_LIST_HEAD(&(rndis_per_dev_params[i].resp_queue)); } - rndis_initialized = true; return 0; } @@ -1191,13 +1186,7 @@ void rndis_exit(void) #ifdef CONFIG_USB_GADGET_DEBUG_FILES u8 i; char name[20]; -#endif - if (!rndis_initialized) - return; - rndis_initialized = false; - -#ifdef CONFIG_USB_GADGET_DEBUG_FILES for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { sprintf(name, NAME_TEMPLATE, i); remove_proc_entry(name, NULL); diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index a872248f37df..1fa4f705b0b4 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -763,16 +763,10 @@ static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr, struct rw_semaphore *filesem = dev_get_drvdata(dev); int rc = 0; - -#ifndef CONFIG_USB_ANDROID_MASS_STORAGE - /* disabled in android because we need to allow closing the backing file - * if the media was removed - */ if (curlun->prevent_medium_removal && fsg_lun_is_open(curlun)) { LDBG(curlun, "eject attempt prevented\n"); return -EBUSY; /* "Door is locked" */ } -#endif /* Remove a trailing newline */ if (count > 0 && buf[count-1] == '\n') diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 51d572eae9ad..2ac1d2147325 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c @@ -764,26 +764,6 @@ static struct device_type gadget_type = { * Returns negative errno, or zero on success */ int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) -{ - return gether_setup_name(g, ethaddr, "usb"); -} - -/** - * gether_setup_name - initialize one ethernet-over-usb link - * @g: gadget to associated with these links - * @ethaddr: NULL, or a buffer in which the ethernet address of the - * host side of the link is recorded - * @netname: name for network device (for example, "usb") - * Context: may sleep - * - * This sets up the single network link that may be exported by a - * gadget driver using this framework. The link layer addresses are - * set up using module parameters. - * - * Returns negative errno, or zero on success - */ -int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN], - const char *netname) { struct eth_dev *dev; struct net_device *net; @@ -807,7 +787,7 @@ int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN], /* network device setup */ dev->net = net; - snprintf(net->name, sizeof(net->name), "%s%%d", netname); + strcpy(net->name, "usb%d"); if (get_ether_addr(dev_addr, net->dev_addr)) dev_warn(&g->dev, @@ -823,6 +803,12 @@ int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN], SET_ETHTOOL_OPS(net, &ops); + /* two kinds of host-initiated state changes: + * - iff DATA transfer is active, carrier is "on" + * - tx queueing enabled if open *and* carrier is "on" + */ + netif_carrier_off(net); + dev->gadget = g; SET_NETDEV_DEV(net, &g->dev); SET_NETDEV_DEVTYPE(net, &gadget_type); @@ -836,12 +822,6 @@ int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN], INFO(dev, "HOST MAC %pM\n", dev->host_mac); the_dev = dev; - - /* two kinds of host-initiated state changes: - * - iff DATA transfer is active, carrier is "on" - * - tx queueing enabled if open *and* carrier is "on" - */ - netif_carrier_off(net); } return status; @@ -963,6 +943,7 @@ void gether_disconnect(struct gether *link) struct eth_dev *dev = link->ioport; struct usb_request *req; + WARN_ON(!dev); if (!dev) return; diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h index 64b65f92168a..b56e1e7d423c 100644 --- a/drivers/usb/gadget/u_ether.h +++ b/drivers/usb/gadget/u_ether.h @@ -86,9 +86,6 @@ struct gether { /* netdev setup/teardown as directed by the gadget driver */ int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]); void gether_cleanup(void); -/* variant of gether_setup that allows customizing network device name */ -int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN], - const char *netname); /* connect/disconnect is handled by individual functions */ struct net_device *gether_connect(struct gether *); @@ -115,14 +112,12 @@ int eem_bind_config(struct usb_configuration *c); #ifdef USB_ETH_RNDIS -int rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], - u32 vendorID, const char *manufacturer); +int rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]); #else static inline int -rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], - u32 vendorID, const char *manufacturer) +rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) { return 0; } diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 3fdcc9a698f7..40f7716b31fc 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -122,7 +122,7 @@ struct gs_port { }; /* increase N_PORTS if you need more */ -#define N_PORTS 8 +#define N_PORTS 4 static struct portmaster { struct mutex lock; /* protect open/close */ struct gs_port *port; @@ -1028,7 +1028,7 @@ static const struct tty_operations gs_tty_ops = { static struct tty_driver *gs_tty_driver; -static int +static int __init gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding) { struct gs_port *port; @@ -1074,7 +1074,7 @@ gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding) * * Returns negative errno or zero. */ -int gserial_setup(struct usb_gadget *g, unsigned count) +int __init gserial_setup(struct usb_gadget *g, unsigned count) { unsigned i; struct usb_cdc_line_coding coding; diff --git a/drivers/usb/gadget/uvc.h b/drivers/usb/gadget/uvc.h index 01a23c1197f6..5b7919460fd2 100644 --- a/drivers/usb/gadget/uvc.h +++ b/drivers/usb/gadget/uvc.h @@ -29,7 +29,7 @@ struct uvc_request_data { - __s32 length; + unsigned int length; __u8 data[60]; }; diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c index 992f66b88c81..5e807f083bc8 100644 --- a/drivers/usb/gadget/uvc_v4l2.c +++ b/drivers/usb/gadget/uvc_v4l2.c @@ -41,7 +41,7 @@ uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data) if (data->length < 0) return usb_ep_set_halt(cdev->gadget->ep0); - req->length = min_t(unsigned int, uvc->event_length, data->length); + req->length = min(uvc->event_length, data->length); req->zero = data->length < uvc->event_length; req->dma = DMA_ADDR_INVALID; diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 3e2ccb0dd255..40a844c1dbb4 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -808,7 +808,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) next += temp; temp = scnprintf (next, size, "uframe %04x\n", - ehci_read_frame_index(ehci)); + ehci_readl(ehci, &ehci->regs->frame_index)); size -= temp; next += temp; diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index fc93d57609ac..f380bf97e5af 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -125,7 +125,7 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, */ if (pdata->init && pdata->init(pdev)) { retval = -ENODEV; - goto err4; + goto err3; } /* Enable USB controller, 83xx or 8536 */ @@ -216,8 +216,6 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, unsigned int port_offset) { u32 portsc; - struct usb_hcd *hcd = ehci_to_hcd(ehci); - void __iomem *non_ehci = hcd->regs; portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]); portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW); @@ -233,8 +231,6 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, portsc |= PORT_PTS_PTW; /* fall through */ case FSL_USB2_PHY_UTMI: - /* enable UTMI PHY */ - setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN); portsc |= PORT_PTS_UTMI; break; case FSL_USB2_PHY_NONE: diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h index bea5013ab7f5..491806221165 100644 --- a/drivers/usb/host/ehci-fsl.h +++ b/drivers/usb/host/ehci-fsl.h @@ -45,6 +45,5 @@ #define FSL_SOC_USB_PRICTRL 0x40c /* NOTE: big-endian */ #define FSL_SOC_USB_SICTRL 0x410 /* NOTE: big-endian */ #define FSL_SOC_USB_CTRL 0x500 /* NOTE: big-endian */ -#define CTRL_UTMI_PHY_EN (1<<9) #define SNOOP_SIZE_2GB 0x1e #endif /* _EHCI_FSL_H */ diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index f89f77f1b339..f8030ee928e8 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -94,8 +94,7 @@ static const char hcd_name [] = "ehci_hcd"; #define EHCI_IAA_MSECS 10 /* arbitrary */ #define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ -#define EHCI_SHRINK_JIFFIES (DIV_ROUND_UP(HZ, 200) + 1) - /* 200-ms async qh unlink delay */ +#define EHCI_SHRINK_FRAMES 5 /* async qh unlink delay */ /* Initial IRQ latency: faster than hw default */ static int log2_irq_thresh = 0; // 0 to 6 @@ -153,7 +152,10 @@ timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action) break; /* case TIMER_ASYNC_SHRINK: */ default: - t = EHCI_SHRINK_JIFFIES; + /* add a jiffie since we synch against the + * 8 KHz uframe counter. + */ + t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1; break; } mod_timer(&ehci->watchdog, t + jiffies); @@ -761,35 +763,6 @@ static int ehci_run (struct usb_hcd *hcd) return 0; } -static int __maybe_unused ehci_setup (struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval; - - ehci->regs = (void __iomem *)ehci->caps + - HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); - dbg_hcs_params(ehci, "reset"); - dbg_hcc_params(ehci, "reset"); - - /* cache this readonly data; minimize chip reads */ - ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); - - ehci->sbrn = HCD_USB2; - - retval = ehci_halt(ehci); - if (retval) - return retval; - - /* data structure init */ - retval = ehci_init(hcd); - if (retval) - return retval; - - ehci_reset(ehci); - - return 0; -} - /*-------------------------------------------------------------------------*/ static irqreturn_t ehci_irq (struct usb_hcd *hcd) @@ -808,13 +781,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) goto dead; } - /* - * We don't use STS_FLR, but some controllers don't like it to - * remain on, so mask it out along with the other status bits. - */ - masked_status = status & (INTR_MASK | STS_FLR); - /* Shared IRQ? */ + masked_status = status & INTR_MASK; if (!masked_status || unlikely(hcd->state == HC_STATE_HALT)) { spin_unlock(&ehci->lock); return IRQ_NONE; @@ -865,7 +833,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) pcd_status = status; /* resume root hub? */ - if (hcd->state == HC_STATE_SUSPENDED) + if (!(cmd & CMD_RUN)) usb_hcd_resume_root_hub(hcd); /* get per-port change detect bits */ @@ -1193,7 +1161,8 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep) static int ehci_get_frame (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); - return (ehci_read_frame_index(ehci) >> 3) % ehci->periodic_size; + return (ehci_readl(ehci, &ehci->regs->frame_index) >> 3) % + ehci->periodic_size; } /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index f5d7fed4a4c0..ea6184bf48d0 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -343,7 +343,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) u32 temp; u32 power_okay; int i; - unsigned long resume_needed = 0; + u8 resume_needed = 0; if (time_before (jiffies, ehci->next_statechange)) msleep(5); @@ -416,7 +416,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) if (test_bit(i, &ehci->bus_suspended) && (temp & PORT_SUSPEND)) { temp |= PORT_RESUME; - set_bit(i, &resume_needed); + resume_needed = 1; } ehci_writel(ehci, temp, &ehci->regs->port_status [i]); } @@ -431,7 +431,8 @@ static int ehci_bus_resume (struct usb_hcd *hcd) i = HCS_N_PORTS (ehci->hcs_params); while (i--) { temp = ehci_readl(ehci, &ehci->regs->port_status [i]); - if (test_bit(i, &resume_needed)) { + if (test_bit(i, &ehci->bus_suspended) && + (temp & PORT_SUSPEND)) { temp &= ~(PORT_RWC_BITS | PORT_RESUME); ehci_writel(ehci, temp, &ehci->regs->port_status [i]); ehci_vdbg (ehci, "resumed port %d\n", i + 1); @@ -890,11 +891,10 @@ static int ehci_hub_control ( * power switching; they're allowed to just limit the * current. khubd will turn the power back on. */ - if ((temp & PORT_OC) && HCS_PPC(ehci->hcs_params)) { + if (HCS_PPC (ehci->hcs_params)){ ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_POWER), status_reg); - temp = ehci_readl(ehci, status_reg); } } @@ -1120,19 +1120,7 @@ static int ehci_hub_control ( if (!selector || selector > 5) goto error; ehci_quiesce(ehci); - - /* Put all enabled ports into suspend */ - while (ports--) { - u32 __iomem *sreg = - &ehci->regs->port_status[ports]; - - temp = ehci_readl(ehci, sreg) & ~PORT_RWC_BITS; - if (temp & PORT_PE) - ehci_writel(ehci, temp | PORT_SUSPEND, - sreg); - } ehci_halt(ehci); - temp = ehci_readl(ehci, status_reg); temp |= selector << 16; ehci_writel(ehci, temp, status_reg); break; diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 175c574ec9f1..1102ce65a3a9 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -224,11 +224,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) pci_dev_put(p_smbus); } break; - case PCI_VENDOR_ID_NETMOS: - /* MosChip frame-index-register bug */ - ehci_info(ehci, "applying MosChip frame-index workaround\n"); - ehci->frame_index_bug = 1; - break; } /* optional debug port, normally in the first BAR */ @@ -357,10 +352,7 @@ static bool usb_is_intel_switchable_ehci(struct pci_dev *pdev) { return pdev->class == PCI_CLASS_SERIAL_USB_EHCI && pdev->vendor == PCI_VENDOR_ID_INTEL && - (pdev->device == 0x1E26 || - pdev->device == 0x8C2D || - pdev->device == 0x8C26 || - pdev->device == 0x9C26); + pdev->device == 0x1E26; } static void ehci_enable_xhci_companion(void) diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 08fdcfa9cc42..5d6bc624c961 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -103,7 +103,7 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd) if (!(hw->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) { unsigned is_out, epnum; - is_out = qh->is_out; + is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8)); epnum = (hc32_to_cpup(ehci, &hw->hw_info1) >> 8) & 0x0f; if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) { hw->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE); @@ -130,17 +130,9 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh) else { qtd = list_entry (qh->qtd_list.next, struct ehci_qtd, qtd_list); - /* - * first qtd may already be partially processed. - * If we come here during unlink, the QH overlay region - * might have reference to the just unlinked qtd. The - * qtd is updated in qh_completions(). Update the QH - * overlay here. - */ - if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) { - qh->hw->hw_qtd_next = qtd->hw_next; + /* first qtd may already be partially processed */ + if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) qtd = NULL; - } } if (qtd) @@ -657,7 +649,7 @@ qh_urb_transaction ( /* * data transfer stage: buffer setup */ - i = urb->num_mapped_sgs; + i = urb->num_sgs; if (len > 0 && i > 0) { sg = urb->sg; buf = sg_dma_address(sg); @@ -954,7 +946,6 @@ done: hw = qh->hw; hw->hw_info1 = cpu_to_hc32(ehci, info1); hw->hw_info2 = cpu_to_hc32(ehci, info2); - qh->is_out = !is_input; usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1); qh_refresh (ehci, qh); return qh; @@ -1003,12 +994,6 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) head->qh_next.qh = qh; head->hw->hw_next = dma; - /* - * flush qh descriptor into memory immediately, - * see comments in qh_append_tds. - * */ - ehci_sync_mem(); - qh_get(qh); qh->xacterrs = 0; qh->qh_state = QH_STATE_LINKED; @@ -1096,18 +1081,6 @@ static struct ehci_qh *qh_append_tds ( wmb (); dummy->hw_token = token; - /* - * Writing to dma coherent buffer on ARM may - * be delayed to reach memory, so HC may not see - * hw_token of dummy qtd in time, which can cause - * the qtd transaction to be executed very late, - * and degrade performance a lot. ehci_sync_mem - * is added to flush 'token' immediatelly into - * memory, so that ehci can execute the transaction - * ASAP. - * */ - ehci_sync_mem(); - urb->hcpriv = qh_get (qh); } } @@ -1258,8 +1231,6 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) prev->hw->hw_next = qh->hw->hw_next; prev->qh_next = qh->qh_next; - if (ehci->qh_scan_next == qh) - ehci->qh_scan_next = qh->qh_next.qh; wmb (); /* If the controller isn't running, we don't have to wait for it */ @@ -1285,49 +1256,53 @@ static void scan_async (struct ehci_hcd *ehci) struct ehci_qh *qh; enum ehci_timer_action action = TIMER_IO_WATCHDOG; + ehci->stamp = ehci_readl(ehci, &ehci->regs->frame_index); timer_action_done (ehci, TIMER_ASYNC_SHRINK); +rescan: stopped = !HC_IS_RUNNING(ehci_to_hcd(ehci)->state); + qh = ehci->async->qh_next.qh; + if (likely (qh != NULL)) { + do { + /* clean any finished work for this qh */ + if (!list_empty(&qh->qtd_list) && (stopped || + qh->stamp != ehci->stamp)) { + int temp; + + /* unlinks could happen here; completion + * reporting drops the lock. rescan using + * the latest schedule, but don't rescan + * qhs we already finished (no looping) + * unless the controller is stopped. + */ + qh = qh_get (qh); + qh->stamp = ehci->stamp; + temp = qh_completions (ehci, qh); + if (qh->needs_rescan) + unlink_async(ehci, qh); + qh_put (qh); + if (temp != 0) { + goto rescan; + } + } - ehci->qh_scan_next = ehci->async->qh_next.qh; - while (ehci->qh_scan_next) { - qh = ehci->qh_scan_next; - ehci->qh_scan_next = qh->qh_next.qh; - rescan: - /* clean any finished work for this qh */ - if (!list_empty(&qh->qtd_list)) { - int temp; - - /* - * Unlinks could happen here; completion reporting - * drops the lock. That's why ehci->qh_scan_next - * always holds the next qh to scan; if the next qh - * gets unlinked then ehci->qh_scan_next is adjusted - * in start_unlink_async(). + /* unlink idle entries, reducing DMA usage as well + * as HCD schedule-scanning costs. delay for any qh + * we just scanned, there's a not-unusual case that it + * doesn't stay idle for long. + * (plus, avoids some kind of re-activation race.) */ - qh = qh_get(qh); - temp = qh_completions(ehci, qh); - if (qh->needs_rescan) - unlink_async(ehci, qh); - qh->unlink_time = jiffies + EHCI_SHRINK_JIFFIES; - qh_put(qh); - if (temp != 0) - goto rescan; - } + if (list_empty(&qh->qtd_list) + && qh->qh_state == QH_STATE_LINKED) { + if (!ehci->reclaim && (stopped || + ((ehci->stamp - qh->stamp) & 0x1fff) + >= EHCI_SHRINK_FRAMES * 8)) + start_unlink_async(ehci, qh); + else + action = TIMER_ASYNC_SHRINK; + } - /* unlink idle entries, reducing DMA usage as well - * as HCD schedule-scanning costs. delay for any qh - * we just scanned, there's a not-unusual case that it - * doesn't stay idle for long. - * (plus, avoids some kind of re-activation race.) - */ - if (list_empty(&qh->qtd_list) - && qh->qh_state == QH_STATE_LINKED) { - if (!ehci->reclaim && (stopped || - time_after_eq(jiffies, qh->unlink_time))) - start_unlink_async(ehci, qh); - else - action = TIMER_ASYNC_SHRINK; - } + qh = qh->qh_next.qh; + } while (qh); } if (action == TIMER_ASYNC_SHRINK) timer_action (ehci, TIMER_ASYNC_SHRINK); diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c index 491a209c9d2f..e3374c8f7b3f 100644 --- a/drivers/usb/host/ehci-s5p.c +++ b/drivers/usb/host/ehci-s5p.c @@ -86,7 +86,6 @@ static int __devinit s5p_ehci_probe(struct platform_device *pdev) goto fail_hcd; } - s5p_ehci->hcd = hcd; s5p_ehci->clk = clk_get(&pdev->dev, "usbhost"); if (IS_ERR(s5p_ehci->clk)) { diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 53192f2e2c75..6c9fbe352f73 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -36,27 +36,6 @@ static int ehci_get_frame (struct usb_hcd *hcd); -#ifdef CONFIG_PCI - -static unsigned ehci_read_frame_index(struct ehci_hcd *ehci) -{ - unsigned uf; - - /* - * The MosChip MCS9990 controller updates its microframe counter - * a little before the frame counter, and occasionally we will read - * the invalid intermediate value. Avoid problems by checking the - * microframe number (the low-order 3 bits); if they are 0 then - * re-read the register to get the correct value. - */ - uf = ehci_readl(ehci, &ehci->regs->frame_index); - if (unlikely(ehci->frame_index_bug && ((uf & 7) == 0))) - uf = ehci_readl(ehci, &ehci->regs->frame_index); - return uf; -} - -#endif - /*-------------------------------------------------------------------------*/ /* @@ -236,7 +215,7 @@ static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask) } static const unsigned char -max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 125, 25 }; +max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 }; /* carryover low/fullspeed bandwidth that crosses uframe boundries */ static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8]) @@ -503,7 +482,7 @@ static int enable_periodic (struct ehci_hcd *ehci) ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; /* make sure ehci_work scans these */ - ehci->next_uframe = ehci_read_frame_index(ehci) + ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index) % (ehci->periodic_size << 3); if (unlikely(ehci->broken_periodic)) ehci->last_periodic_enable = ktime_get_real(); @@ -1433,7 +1412,7 @@ iso_stream_schedule ( goto fail; } - now = ehci_read_frame_index(ehci) & (mod - 1); + now = ehci_readl(ehci, &ehci->regs->frame_index) & (mod - 1); /* Typical case: reuse current schedule, stream is still active. * Hopefully there are no gaps from the host falling behind @@ -1479,36 +1458,30 @@ iso_stream_schedule ( * jump until after the queue is primed. */ else { - int done = 0; start = SCHEDULE_SLOP + (now & ~0x07); /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */ - /* find a uframe slot with enough bandwidth. - * Early uframes are more precious because full-speed - * iso IN transfers can't use late uframes, - * and therefore they should be allocated last. - */ - next = start; - start += period; - do { - start--; + /* find a uframe slot with enough bandwidth */ + next = start + period; + for (; start < next; start++) { + /* check schedule: enough space? */ if (stream->highspeed) { if (itd_slot_ok(ehci, mod, start, stream->usecs, period)) - done = 1; + break; } else { if ((start % 8) >= 6) continue; if (sitd_slot_ok(ehci, mod, stream, start, sched, period)) - done = 1; + break; } - } while (start > next && !done); + } /* no room in the schedule */ - if (!done) { + if (start == next) { ehci_dbg(ehci, "iso resched full %p (now %d max %d)\n", urb, now, now + mod); status = -ENOSPC; @@ -2306,7 +2279,7 @@ scan_periodic (struct ehci_hcd *ehci) */ now_uframe = ehci->next_uframe; if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { - clock = ehci_read_frame_index(ehci); + clock = ehci_readl(ehci, &ehci->regs->frame_index); clock_frame = (clock >> 3) & (ehci->periodic_size - 1); } else { clock = now_uframe + mod - 1; @@ -2485,7 +2458,8 @@ restart: || ehci->periodic_sched == 0) break; ehci->next_uframe = now_uframe; - now = ehci_read_frame_index(ehci) & (mod - 1); + now = ehci_readl(ehci, &ehci->regs->frame_index) & + (mod - 1); if (now_uframe == now) break; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index db0d14e47e38..bd6ff489baf9 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -75,7 +75,6 @@ struct ehci_hcd { /* one per controller */ struct ehci_qh *async; struct ehci_qh *dummy; /* For AMD quirk use */ struct ehci_qh *reclaim; - struct ehci_qh *qh_scan_next; unsigned scanning : 1; /* periodic schedule support */ @@ -118,6 +117,7 @@ struct ehci_hcd { /* one per controller */ struct timer_list iaa_watchdog; struct timer_list watchdog; unsigned long actions; + unsigned stamp; unsigned periodic_stamp; unsigned random_frame; unsigned long next_statechange; @@ -137,7 +137,6 @@ struct ehci_hcd { /* one per controller */ unsigned fs_i_thresh:1; /* Intel iso scheduling */ unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/ unsigned has_synopsys_hc_bug:1; /* Synopsys HC */ - unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */ /* required for usb32 quirk */ #define OHCI_CTRL_HCFS (3 << 6) @@ -344,7 +343,6 @@ struct ehci_qh { struct ehci_qh *reclaim; /* next to reclaim */ struct ehci_hcd *ehci; - unsigned long unlink_time; /* * Do NOT use atomic operations for QH refcounting. On some CPUs @@ -376,7 +374,6 @@ struct ehci_qh { #define NO_FRAME ((unsigned short)~0) /* pick new start */ struct usb_device *dev; /* access to TT */ - unsigned is_out:1; /* bulk or intr OUT */ unsigned clearing_tt:1; /* Clear-TT-Buf in progress */ }; @@ -737,39 +734,6 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x) #endif -/* - * Writing to dma coherent memory on ARM may be delayed via L2 - * writing buffer, so introduce the helper which can flush L2 writing - * buffer into memory immediately, especially used to flush ehci - * descriptor to memory. - * */ -#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE -static inline void ehci_sync_mem() -{ - mb(); -} -#else -static inline void ehci_sync_mem() -{ -} -#endif - -/*-------------------------------------------------------------------------*/ - -#ifdef CONFIG_PCI - -/* For working around the MosChip frame-index-register bug */ -static unsigned ehci_read_frame_index(struct ehci_hcd *ehci); - -#else - -static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci) -{ - return ehci_readl(ehci, &ehci->regs->frame_index); -} - -#endif - /*-------------------------------------------------------------------------*/ #ifndef DEBUG diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c index 2df851b4bc7c..a42ef380e917 100644 --- a/drivers/usb/host/fhci-sched.c +++ b/drivers/usb/host/fhci-sched.c @@ -1,7 +1,7 @@ /* * Freescale QUICC Engine USB Host Controller Driver * - * Copyright (c) Freescale Semicondutor, Inc. 2006, 2011. + * Copyright (c) Freescale Semicondutor, Inc. 2006. * Shlomi Gridish * Jerry Huang * Copyright (c) Logic Product Development, Inc. 2007 @@ -810,11 +810,9 @@ void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb) ed->dev_addr = usb_pipedevice(urb->pipe); ed->max_pkt_size = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); - /* setup stage */ td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, FHCI_TA_SETUP, USB_TD_TOGGLE_DATA0, urb->setup_packet, 8, 0, 0, true); - /* data stage */ if (data_len > 0) { td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, usb_pipeout(urb->pipe) ? FHCI_TA_OUT : @@ -822,18 +820,9 @@ void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb) USB_TD_TOGGLE_DATA1, data, data_len, 0, 0, true); } - - /* status stage */ - if (data_len > 0) - td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, - (usb_pipeout(urb->pipe) ? FHCI_TA_IN : - FHCI_TA_OUT), - USB_TD_TOGGLE_DATA1, data, 0, 0, 0, true); - else - td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, - FHCI_TA_IN, - USB_TD_TOGGLE_DATA1, data, 0, 0, 0, true); - + td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, + usb_pipeout(urb->pipe) ? FHCI_TA_IN : FHCI_TA_OUT, + USB_TD_TOGGLE_DATA1, data, 0, 0, 0, true); urb_state = US_CTRL_SETUP; break; case FHCI_TF_ISO: diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 840beda66dd9..55d3d5859ac5 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -1583,9 +1583,6 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int retval = 0; spin_lock_irqsave(&priv->lock, spinflags); - retval = usb_hcd_check_unlink_urb(hcd, urb, status); - if (retval) - goto out; qh = urb->ep->hcpriv; if (!qh) { diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 23107e230530..f9cf3f04b742 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -389,14 +389,17 @@ ohci_shutdown (struct usb_hcd *hcd) struct ohci_hcd *ohci; ohci = hcd_to_ohci (hcd); - ohci_writel(ohci, (u32) ~0, &ohci->regs->intrdisable); + ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); + ohci->hc_control = ohci_readl(ohci, &ohci->regs->control); - /* Software reset, after which the controller goes into SUSPEND */ - ohci_writel(ohci, OHCI_HCR, &ohci->regs->cmdstatus); - ohci_readl(ohci, &ohci->regs->cmdstatus); /* flush the writes */ - udelay(10); + /* If the SHUTDOWN quirk is set, don't put the controller in RESET */ + ohci->hc_control &= (ohci->flags & OHCI_QUIRK_SHUTDOWN ? + OHCI_CTRL_RWC | OHCI_CTRL_HCFS : + OHCI_CTRL_RWC); + ohci_writel(ohci, ohci->hc_control, &ohci->regs->control); - ohci_writel(ohci, ohci->fminterval, &ohci->regs->fminterval); + /* flush the writes */ + (void) ohci_readl (ohci, &ohci->regs->control); } static int check_ed(struct ohci_hcd *ohci, struct ed *ed) diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 2f00040fc408..9154615292db 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -356,7 +356,10 @@ static void ohci_finish_controller_resume(struct usb_hcd *hcd) msleep(20); } - usb_hcd_resume_root_hub(hcd); + /* Does the root hub have a port wakeup pending? */ + if (ohci_readl(ohci, &ohci->regs->intrstatus) & + (OHCI_INTR_RD | OHCI_INTR_RHSC)) + usb_hcd_resume_root_hub(hcd); } /* Carry out polling-, autostop-, and autoresume-related state changes */ diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index bc01b064585a..ad8166c681e2 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -175,6 +175,28 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd) return 0; } +/* nVidia controllers continue to drive Reset signalling on the bus + * even after system shutdown, wasting power. This flag tells the + * shutdown routine to leave the controller OPERATIONAL instead of RESET. + */ +static int ohci_quirk_nvidia_shutdown(struct usb_hcd *hcd) +{ + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + + /* Evidently nVidia fixed their later hardware; this is a guess at + * the changeover point. + */ +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB 0x026d + + if (pdev->device < PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB) { + ohci->flags |= OHCI_QUIRK_SHUTDOWN; + ohci_dbg(ohci, "enabled nVidia shutdown quirk\n"); + } + + return 0; +} + static void sb800_prefetch(struct ohci_hcd *ohci, int on) { struct pci_dev *pdev; @@ -238,6 +260,10 @@ static const struct pci_device_id ohci_pci_quirks[] = { PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399), .driver_data = (unsigned long)ohci_quirk_amd700, }, + { + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID), + .driver_data = (unsigned long) ohci_quirk_nvidia_shutdown, + }, /* FIXME for some of the early AMD 760 southbridges, OHCI * won't work at all. blacklist them. diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index e66eb299a272..dd24fc115e48 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -1130,25 +1130,6 @@ dl_done_list (struct ohci_hcd *ohci) while (td) { struct td *td_next = td->next_dl_td; - struct ed *ed = td->ed; - - /* - * Some OHCI controllers (NVIDIA for sure, maybe others) - * occasionally forget to add TDs to the done queue. Since - * TDs for a given endpoint are always processed in order, - * if we find a TD on the donelist then all of its - * predecessors must be finished as well. - */ - for (;;) { - struct td *td2; - - td2 = list_first_entry(&ed->td_list, struct td, - td_list); - if (td2 == td) - break; - takeback_td(ohci, td2); - } - takeback_td(ohci, td); td = td_next; } diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 0795b934d00c..35e5fd640ce7 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -403,6 +403,7 @@ struct ohci_hcd { #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ #define OHCI_QUIRK_AMD_PLL 0x200 /* AMD PLL quirk*/ #define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */ +#define OHCI_QUIRK_SHUTDOWN 0x800 /* nVidia power bug */ // there are also chip quirks/bugs in init logic struct work_struct nec_work; /* Worker for NEC quirk */ diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 0f097d366eba..fd930618c28f 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -35,9 +35,6 @@ #define OHCI_INTRSTATUS 0x0c #define OHCI_INTRENABLE 0x10 #define OHCI_INTRDISABLE 0x14 -#define OHCI_FMINTERVAL 0x34 -#define OHCI_HCFS (3 << 6) /* hc functional state */ -#define OHCI_HCR (1 << 0) /* host controller reset */ #define OHCI_OCR (1 << 3) /* ownership change request */ #define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ #define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ @@ -73,9 +70,7 @@ #define NB_PIF0_PWRDOWN_1 0x01100013 #define USB_INTEL_XUSB2PR 0xD0 -#define USB_INTEL_USB2PRM 0xD4 #define USB_INTEL_USB3_PSSEN 0xD8 -#define USB_INTEL_USB3PRM 0xDC static struct amd_chipset_info { struct pci_dev *nb_dev; @@ -468,8 +463,6 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) { void __iomem *base; u32 control; - u32 fminterval; - int cnt; if (!mmio_resource_enabled(pdev, 0)) return; @@ -502,70 +495,32 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) } #endif - /* disable interrupts */ - writel((u32) ~0, base + OHCI_INTRDISABLE); + /* reset controller, preserving RWC (and possibly IR) */ + writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL); - /* Reset the USB bus, if the controller isn't already in RESET */ - if (control & OHCI_HCFS) { - /* Go into RESET, preserving RWC (and possibly IR) */ - writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL); - readl(base + OHCI_CONTROL); - - /* drive bus reset for at least 50 ms (7.1.7.5) */ - msleep(50); - } - - /* software reset of the controller, preserving HcFmInterval */ - fminterval = readl(base + OHCI_FMINTERVAL); - writel(OHCI_HCR, base + OHCI_CMDSTATUS); - - /* reset requires max 10 us delay */ - for (cnt = 30; cnt > 0; --cnt) { /* ... allow extra time */ - if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0) - break; - udelay(1); - } - writel(fminterval, base + OHCI_FMINTERVAL); + /* + * disable interrupts + */ + writel(~(u32)0, base + OHCI_INTRDISABLE); + writel(~(u32)0, base + OHCI_INTRSTATUS); - /* Now the controller is safely in SUSPEND and nothing can wake it up */ iounmap(base); } -static const struct dmi_system_id __devinitconst ehci_dmi_nohandoff_table[] = { - { - /* Pegatron Lucid (ExoPC) */ - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "EXOPG06411"), - DMI_MATCH(DMI_BIOS_VERSION, "Lucid-CE-133"), - }, - }, - { - /* Pegatron Lucid (Ordissimo AIRIS) */ - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "M11JB"), - DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"), - }, - }, - { - /* Pegatron Lucid (Ordissimo) */ - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "Ordissimo"), - DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"), - }, - }, - { } -}; - static void __devinit ehci_bios_handoff(struct pci_dev *pdev, void __iomem *op_reg_base, u32 cap, u8 offset) { int try_handoff = 1, tried_handoff = 0; - /* The Pegatron Lucid tablet sporadically waits for 98 seconds trying - * the handoff on its unused controller. Skip it. */ + /* The Pegatron Lucid (ExoPC) tablet sporadically waits for 90 + * seconds trying the handoff on its unused controller. Skip + * it. */ if (pdev->vendor == 0x8086 && pdev->device == 0x283a) { - if (dmi_check_system(ehci_dmi_nohandoff_table)) + const char *dmi_bn = dmi_get_system_info(DMI_BOARD_NAME); + const char *dmi_bv = dmi_get_system_info(DMI_BIOS_VERSION); + if (dmi_bn && !strcmp(dmi_bn, "EXOPG06411") && + dmi_bv && !strcmp(dmi_bv, "Lucid-CE-133")) try_handoff = 0; } @@ -629,7 +584,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) void __iomem *base, *op_reg_base; u32 hcc_params, cap, val; u8 offset, cap_length; - int wait_time, count = 256/4; + int wait_time, delta, count = 256/4; if (!mmio_resource_enabled(pdev, 0)) return; @@ -675,10 +630,11 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) writel(val, op_reg_base + EHCI_USBCMD); wait_time = 2000; + delta = 100; do { writel(0x3f, op_reg_base + EHCI_USBSTS); - udelay(100); - wait_time -= 100; + udelay(delta); + wait_time -= delta; val = readl(op_reg_base + EHCI_USBSTS); if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) { break; @@ -720,30 +676,12 @@ static int handshake(void __iomem *ptr, u32 mask, u32 done, return -ETIMEDOUT; } -#define PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI 0x8C31 -#define PCI_DEVICE_ID_INTEL_LYNX_POINT_LP_XHCI 0x9C31 - -bool usb_is_intel_ppt_switchable_xhci(struct pci_dev *pdev) +bool usb_is_intel_switchable_xhci(struct pci_dev *pdev) { return pdev->class == PCI_CLASS_SERIAL_USB_XHCI && pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI; } - -/* The Intel Lynx Point chipset also has switchable ports. */ -bool usb_is_intel_lpt_switchable_xhci(struct pci_dev *pdev) -{ - return pdev->class == PCI_CLASS_SERIAL_USB_XHCI && - pdev->vendor == PCI_VENDOR_ID_INTEL && - (pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI || - pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_LP_XHCI); -} - -bool usb_is_intel_switchable_xhci(struct pci_dev *pdev) -{ - return usb_is_intel_ppt_switchable_xhci(pdev) || - usb_is_intel_lpt_switchable_xhci(pdev); -} EXPORT_SYMBOL_GPL(usb_is_intel_switchable_xhci); /* @@ -766,21 +704,12 @@ EXPORT_SYMBOL_GPL(usb_is_intel_switchable_xhci); */ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) { -#if defined(CONFIG_USB_XHCI_HCD) || defined(CONFIG_USB_XHCI_HCD_MODULE) u32 ports_available; - /* Read USB3PRM, the USB 3.0 Port Routing Mask Register - * Indicate the ports that can be changed from OS. - */ - pci_read_config_dword(xhci_pdev, USB_INTEL_USB3PRM, - &ports_available); - - dev_dbg(&xhci_pdev->dev, "Configurable ports to enable SuperSpeed: 0x%x\n", - ports_available); - + ports_available = 0xffffffff; /* Write USB3_PSSEN, the USB 3.0 Port SuperSpeed Enable - * Register, to turn on SuperSpeed terminations for the - * switchable ports. + * Register, to turn on SuperSpeed terminations for all + * available ports. */ pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, cpu_to_le32(ports_available)); @@ -790,16 +719,7 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) dev_dbg(&xhci_pdev->dev, "USB 3.0 ports that are now enabled " "under xHCI: 0x%x\n", ports_available); - /* Read XUSB2PRM, xHCI USB 2.0 Port Routing Mask Register - * Indicate the USB 2.0 ports to be controlled by the xHCI host. - */ - - pci_read_config_dword(xhci_pdev, USB_INTEL_USB2PRM, - &ports_available); - - dev_dbg(&xhci_pdev->dev, "Configurable USB 2.0 ports to hand over to xCHI: 0x%x\n", - ports_available); - + ports_available = 0xffffffff; /* Write XUSB2PR, the xHC USB 2.0 Port Routing Register, to * switch the USB 2.0 power and data lines over to the xHCI * host. @@ -811,28 +731,9 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) &ports_available); dev_dbg(&xhci_pdev->dev, "USB 2.0 ports that are now switched over " "to xHCI: 0x%x\n", ports_available); -#else - /* Don't switchover the ports if the user hasn't compiled the xHCI - * driver. Otherwise they will see "dead" USB ports that don't power - * the devices. - */ - dev_warn(&xhci_pdev->dev, - "CONFIG_USB_XHCI_HCD is turned off, " - "defaulting to EHCI.\n"); - dev_warn(&xhci_pdev->dev, - "USB 3.0 devices will work at USB 2.0 speeds.\n"); -#endif /* CONFIG_USB_XHCI_HCD || CONFIG_USB_XHCI_HCD_MODULE */ - } EXPORT_SYMBOL_GPL(usb_enable_xhci_ports); -void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) -{ - pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, 0x0); - pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, 0x0); -} -EXPORT_SYMBOL_GPL(usb_disable_xhci_ports); - /** * PCI Quirks for xHCI. * @@ -848,12 +749,12 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) void __iomem *op_reg_base; u32 val; int timeout; - int len = pci_resource_len(pdev, 0); if (!mmio_resource_enabled(pdev, 0)) return; - base = ioremap_nocache(pci_resource_start(pdev, 0), len); + base = ioremap_nocache(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); if (base == NULL) return; @@ -863,17 +764,9 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) */ ext_cap_offset = xhci_find_next_cap_offset(base, XHCI_HCC_PARAMS_OFFSET); do { - if ((ext_cap_offset + sizeof(val)) > len) { - /* We're reading garbage from the controller */ - dev_warn(&pdev->dev, - "xHCI controller failing to respond"); - return; - } - if (!ext_cap_offset) /* We've reached the end of the extended capabilities */ goto hc_init; - val = readl(base + ext_cap_offset); if (XHCI_EXT_CAPS_ID(val) == XHCI_EXT_CAPS_LEGACY) break; @@ -882,7 +775,7 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) /* If the BIOS owns the HC, signal that the OS wants it, and wait */ if (val & XHCI_HC_BIOS_OWNED) { - writel(val | XHCI_HC_OS_OWNED, base + ext_cap_offset); + writel(val & XHCI_HC_OS_OWNED, base + ext_cap_offset); /* Wait for 5 seconds with 10 microsecond polling interval */ timeout = handshake(base + ext_cap_offset, XHCI_HC_BIOS_OWNED, @@ -896,18 +789,13 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) } } - val = readl(base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); - /* Mask off (turn off) any enabled SMIs */ - val &= XHCI_LEGACY_DISABLE_SMI; - /* Mask all SMI events bits, RW1C */ - val |= XHCI_LEGACY_SMI_EVENTS; - /* Disable any BIOS SMIs and clear all SMI events*/ - writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); + /* Disable any BIOS SMIs */ + writel(XHCI_LEGACY_DISABLE_SMI, + base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); -hc_init: if (usb_is_intel_switchable_xhci(pdev)) usb_enable_xhci_ports(pdev); - +hc_init: op_reg_base = base + XHCI_HC_LENGTH(readl(base)); /* Wait for the host controller to be ready before writing any @@ -943,22 +831,6 @@ hc_init: static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev) { - /* Skip Netlogic mips SoC's internal PCI USB controller. - * This device does not need/support EHCI/OHCI handoff - */ - if (pdev->vendor == 0x184e) /* vendor Netlogic */ - return; - if (pdev->class != PCI_CLASS_SERIAL_USB_UHCI && - pdev->class != PCI_CLASS_SERIAL_USB_OHCI && - pdev->class != PCI_CLASS_SERIAL_USB_EHCI && - pdev->class != PCI_CLASS_SERIAL_USB_XHCI) - return; - - if (pci_enable_device(pdev) < 0) { - dev_warn(&pdev->dev, "Can't enable PCI device, " - "BIOS handoff failed.\n"); - return; - } if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI) quirk_usb_handoff_uhci(pdev); else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI) @@ -967,6 +839,5 @@ static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev) quirk_usb_disable_ehci(pdev); else if (pdev->class == PCI_CLASS_SERIAL_USB_XHCI) quirk_usb_handoff_xhci(pdev); - pci_disable_device(pdev); } DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index 7f69a39163ce..b1002a8ef96f 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h @@ -10,12 +10,10 @@ void usb_amd_quirk_pll_disable(void); void usb_amd_quirk_pll_enable(void); bool usb_is_intel_switchable_xhci(struct pci_dev *pdev); void usb_enable_xhci_ports(struct pci_dev *xhci_pdev); -void usb_disable_xhci_ports(struct pci_dev *xhci_pdev); #else static inline void usb_amd_quirk_pll_disable(void) {} static inline void usb_amd_quirk_pll_enable(void) {} static inline void usb_amd_dev_put(void) {} -static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {} #endif /* CONFIG_PCI */ #endif /* __LINUX_USB_PCI_QUIRKS_H */ diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 18cd76b779a8..fba99b120588 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -446,10 +446,6 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd) return IRQ_NONE; uhci_writew(uhci, status, USBSTS); /* Clear it */ - spin_lock(&uhci->lock); - if (unlikely(!uhci->is_initialized)) /* not yet configured */ - goto done; - if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) { if (status & USBSTS_HSE) dev_err(uhci_dev(uhci), "host system error, " @@ -458,6 +454,7 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd) dev_err(uhci_dev(uhci), "host controller process " "error, something bad happened!\n"); if (status & USBSTS_HCH) { + spin_lock(&uhci->lock); if (uhci->rh_state >= UHCI_RH_RUNNING) { dev_err(uhci_dev(uhci), "host controller halted, " @@ -475,15 +472,15 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd) * pending unlinks */ mod_timer(&hcd->rh_timer, jiffies); } + spin_unlock(&uhci->lock); } } - if (status & USBSTS_RD) { - spin_unlock(&uhci->lock); + if (status & USBSTS_RD) usb_hcd_poll_rh_status(hcd); - } else { + else { + spin_lock(&uhci->lock); uhci_scan_schedule(uhci); - done: spin_unlock(&uhci->lock); } @@ -661,9 +658,9 @@ static int uhci_start(struct usb_hcd *hcd) */ mb(); - spin_lock_irq(&uhci->lock); configure_hc(uhci); uhci->is_initialized = 1; + spin_lock_irq(&uhci->lock); start_rh(uhci); spin_unlock_irq(&uhci->lock); return 0; diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 82539913ad84..84ed28b34f93 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -943,7 +943,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, if (usb_pipein(urb->pipe)) status |= TD_CTRL_SPD; - i = urb->num_mapped_sgs; + i = urb->num_sgs; if (len > 0 && i > 0) { sg = urb->sg; data = sg_dma_address(sg); diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c index 76083ae92138..d6e175428618 100644 --- a/drivers/usb/host/whci/qset.c +++ b/drivers/usb/host/whci/qset.c @@ -124,7 +124,7 @@ void qset_clear(struct whc *whc, struct whc_qset *qset) { qset->td_start = qset->td_end = qset->ntds = 0; - qset->qh.link = cpu_to_le64(QH_LINK_NTDS(8) | QH_LINK_T); + qset->qh.link = cpu_to_le32(QH_LINK_NTDS(8) | QH_LINK_T); qset->qh.status = qset->qh.status & QH_STATUS_SEQ_MASK; qset->qh.err_count = 0; qset->qh.scratch[0] = 0; @@ -443,7 +443,7 @@ static int qset_add_urb_sg(struct whc *whc, struct whc_qset *qset, struct urb *u remaining = urb->transfer_buffer_length; - for_each_sg(urb->sg, sg, urb->num_mapped_sgs, i) { + for_each_sg(urb->sg, sg, urb->num_sgs, i) { dma_addr_t dma_addr; size_t dma_remaining; dma_addr_t sp, ep; @@ -561,7 +561,7 @@ static int qset_add_urb_sg_linearize(struct whc *whc, struct whc_qset *qset, remaining = urb->transfer_buffer_length; - for_each_sg(urb->sg, sg, urb->num_mapped_sgs, i) { + for_each_sg(urb->sg, sg, urb->num_sgs, i) { size_t len; size_t sg_remaining; void *orig; diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h index 4206f6bef6fb..ce5c9e51748e 100644 --- a/drivers/usb/host/xhci-ext-caps.h +++ b/drivers/usb/host/xhci-ext-caps.h @@ -62,9 +62,8 @@ /* USB Legacy Support Control and Status Register - section 7.1.2 */ /* Add this offset, plus the value of xECP in HCCPARAMS to the base address */ #define XHCI_LEGACY_CONTROL_OFFSET (0x04) -/* bits 1:3, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */ -#define XHCI_LEGACY_DISABLE_SMI ((0x7 << 1) + (0xff << 5) + (0x7 << 17)) -#define XHCI_LEGACY_SMI_EVENTS (0x7 << 29) +/* bits 1:2, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */ +#define XHCI_LEGACY_DISABLE_SMI ((0x3 << 1) + (0xff << 5) + (0x7 << 17)) /* command register values to disable interrupts and halt the HC */ /* start/stop HC execution - do not write unless HC is halted*/ diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 7520ebb44548..0be788cc2fdb 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -75,7 +75,7 @@ static void xhci_usb2_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, */ memset(port_removable, 0, sizeof(port_removable)); for (i = 0; i < ports; i++) { - portsc = xhci_readl(xhci, xhci->usb2_ports[i]); + portsc = xhci_readl(xhci, xhci->usb3_ports[i]); /* If a device is removable, PORTSC reports a 0, same as in the * hub descriptor DeviceRemovable bits. */ @@ -392,20 +392,6 @@ static int xhci_get_ports(struct usb_hcd *hcd, __le32 __iomem ***port_array) return max_ports; } -/* Test and clear port RWC bit */ -void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem **port_array, - int port_id, u32 port_bit) -{ - u32 temp; - - temp = xhci_readl(xhci, port_array[port_id]); - if (temp & port_bit) { - temp = xhci_port_state_to_neutral(temp); - temp |= port_bit; - xhci_writel(xhci, temp, port_array[port_id]); - } -} - int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength) { @@ -477,12 +463,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, && (temp & PORT_POWER)) status |= USB_PORT_STAT_SUSPEND; } - if ((temp & PORT_PLS_MASK) == XDEV_RESUME && - !DEV_SUPERSPEED(temp)) { + if ((temp & PORT_PLS_MASK) == XDEV_RESUME) { if ((temp & PORT_RESET) || !(temp & PORT_PE)) goto error; - if (time_after_eq(jiffies, - bus_state->resume_done[wIndex])) { + if (!DEV_SUPERSPEED(temp) && time_after_eq(jiffies, + bus_state->resume_done[wIndex])) { xhci_dbg(xhci, "Resume USB2 port %d\n", wIndex + 1); bus_state->resume_done[wIndex] = 0; @@ -502,14 +487,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, xhci_ring_device(xhci, slot_id); bus_state->port_c_suspend |= 1 << wIndex; bus_state->suspended_ports &= ~(1 << wIndex); - } else { - /* - * The resume has been signaling for less than - * 20ms. Report the port status as SUSPEND, - * let the usbcore check port status again - * and clear resume signaling later. - */ - status |= USB_PORT_STAT_SUSPEND; } } if ((temp & PORT_PLS_MASK) == XDEV_U0 @@ -687,7 +664,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, xhci_dbg(xhci, "PORTSC %04x\n", temp); if (temp & PORT_RESET) goto error; - if ((temp & PORT_PLS_MASK) == XDEV_U3) { + if (temp & XDEV_U3) { if ((temp & PORT_PE) == 0) goto error; @@ -775,7 +752,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) memset(buf, 0, retval); status = 0; - mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC; + mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC; spin_lock_irqsave(&xhci->lock, flags); /* For each port, did anything change? If so, set that bit in buf. */ @@ -952,8 +929,12 @@ int xhci_bus_resume(struct usb_hcd *hcd) spin_lock_irqsave(&xhci->lock, flags); /* Clear PLC */ - xhci_test_and_clear_bit(xhci, port_array, port_index, - PORT_PLC); + temp = xhci_readl(xhci, port_array[port_index]); + if (temp & PORT_PLC) { + temp = xhci_port_state_to_neutral(temp); + temp |= PORT_PLC; + xhci_writel(xhci, temp, port_array[port_index]); + } slot_id = xhci_find_slot_id_by_port(hcd, xhci, port_index + 1); diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index af65322e18cd..fcb7f7efc86d 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -81,7 +81,7 @@ static void xhci_segment_free(struct xhci_hcd *xhci, struct xhci_segment *seg) * related flags, such as End TRB, Toggle Cycle, and no snoop. */ static void xhci_link_segments(struct xhci_hcd *xhci, struct xhci_segment *prev, - struct xhci_segment *next, bool link_trbs, bool isoc) + struct xhci_segment *next, bool link_trbs) { u32 val; @@ -97,9 +97,7 @@ static void xhci_link_segments(struct xhci_hcd *xhci, struct xhci_segment *prev, val &= ~TRB_TYPE_BITMASK; val |= TRB_TYPE(TRB_LINK); /* Always set the chain bit with 0.95 hardware */ - /* Set chain bit for isoc rings on AMD 0.96 host */ - if (xhci_link_trb_quirk(xhci) || - (isoc && (xhci->quirks & XHCI_AMD_0x96_HOST))) + if (xhci_link_trb_quirk(xhci)) val |= TRB_CHAIN; prev->trbs[TRBS_PER_SEGMENT-1].link.control = cpu_to_le32(val); } @@ -114,20 +112,18 @@ void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring) struct xhci_segment *seg; struct xhci_segment *first_seg; - if (!ring) + if (!ring || !ring->first_seg) return; - if (ring->first_seg) { - first_seg = ring->first_seg; - seg = first_seg->next; - xhci_dbg(xhci, "Freeing ring at %p\n", ring); - while (seg != first_seg) { - struct xhci_segment *next = seg->next; - xhci_segment_free(xhci, seg); - seg = next; - } - xhci_segment_free(xhci, first_seg); - ring->first_seg = NULL; + first_seg = ring->first_seg; + seg = first_seg->next; + xhci_dbg(xhci, "Freeing ring at %p\n", ring); + while (seg != first_seg) { + struct xhci_segment *next = seg->next; + xhci_segment_free(xhci, seg); + seg = next; } + xhci_segment_free(xhci, first_seg); + ring->first_seg = NULL; kfree(ring); } @@ -156,7 +152,7 @@ static void xhci_initialize_ring_info(struct xhci_ring *ring) * See section 4.9.1 and figures 15 and 16. */ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, - unsigned int num_segs, bool link_trbs, bool isoc, gfp_t flags) + unsigned int num_segs, bool link_trbs, gfp_t flags) { struct xhci_ring *ring; struct xhci_segment *prev; @@ -180,21 +176,14 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, struct xhci_segment *next; next = xhci_segment_alloc(xhci, flags); - if (!next) { - prev = ring->first_seg; - while (prev) { - next = prev->next; - xhci_segment_free(xhci, prev); - prev = next; - } + if (!next) goto fail; - } - xhci_link_segments(xhci, prev, next, link_trbs, isoc); + xhci_link_segments(xhci, prev, next, link_trbs); prev = next; num_segs--; } - xhci_link_segments(xhci, prev, ring->first_seg, link_trbs, isoc); + xhci_link_segments(xhci, prev, ring->first_seg, link_trbs); if (link_trbs) { /* See section 4.9.2.1 and 6.4.4.1 */ @@ -208,7 +197,7 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, return ring; fail: - kfree(ring); + xhci_ring_free(xhci, ring); return NULL; } @@ -240,14 +229,14 @@ void xhci_free_or_cache_endpoint_ring(struct xhci_hcd *xhci, * pointers to the beginning of the ring. */ static void xhci_reinit_cached_ring(struct xhci_hcd *xhci, - struct xhci_ring *ring, bool isoc) + struct xhci_ring *ring) { struct xhci_segment *seg = ring->first_seg; do { memset(seg->trbs, 0, sizeof(union xhci_trb)*TRBS_PER_SEGMENT); /* All endpoint rings have link TRBs */ - xhci_link_segments(xhci, seg, seg->next, 1, isoc); + xhci_link_segments(xhci, seg, seg->next, 1); seg = seg->next; } while (seg != ring->first_seg); xhci_initialize_ring_info(ring); @@ -551,7 +540,7 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci, */ for (cur_stream = 1; cur_stream < num_streams; cur_stream++) { stream_info->stream_rings[cur_stream] = - xhci_ring_alloc(xhci, 1, true, false, mem_flags); + xhci_ring_alloc(xhci, 1, true, mem_flags); cur_ring = stream_info->stream_rings[cur_stream]; if (!cur_ring) goto cleanup_rings; @@ -776,7 +765,7 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, } /* Allocate endpoint 0 ring */ - dev->eps[0].ring = xhci_ring_alloc(xhci, 1, true, false, flags); + dev->eps[0].ring = xhci_ring_alloc(xhci, 1, true, flags); if (!dev->eps[0].ring) goto fail; @@ -882,6 +871,7 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud struct xhci_virt_device *dev; struct xhci_ep_ctx *ep0_ctx; struct xhci_slot_ctx *slot_ctx; + struct xhci_input_control_ctx *ctrl_ctx; u32 port_num; struct usb_device *top_dev; @@ -893,8 +883,12 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud return -EINVAL; } ep0_ctx = xhci_get_ep_ctx(xhci, dev->in_ctx, 0); + ctrl_ctx = xhci_get_input_control_ctx(xhci, dev->in_ctx); slot_ctx = xhci_get_slot_ctx(xhci, dev->in_ctx); + /* 2) New slot context and endpoint 0 context are valid*/ + ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG); + /* 3) Only the control endpoint is valid - one endpoint context */ slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | (u32) udev->route); switch (udev->speed) { @@ -1009,44 +1003,26 @@ static unsigned int xhci_parse_exponent_interval(struct usb_device *udev, } /* - * Convert bInterval expressed in microframes (in 1-255 range) to exponent of + * Convert bInterval expressed in frames (in 1-255 range) to exponent of * microframes, rounded down to nearest power of 2. */ -static unsigned int xhci_microframes_to_exponent(struct usb_device *udev, - struct usb_host_endpoint *ep, unsigned int desc_interval, - unsigned int min_exponent, unsigned int max_exponent) +static unsigned int xhci_parse_frame_interval(struct usb_device *udev, + struct usb_host_endpoint *ep) { unsigned int interval; - interval = fls(desc_interval) - 1; - interval = clamp_val(interval, min_exponent, max_exponent); - if ((1 << interval) != desc_interval) + interval = fls(8 * ep->desc.bInterval) - 1; + interval = clamp_val(interval, 3, 10); + if ((1 << interval) != 8 * ep->desc.bInterval) dev_warn(&udev->dev, "ep %#x - rounding interval to %d microframes, ep desc says %d microframes\n", ep->desc.bEndpointAddress, 1 << interval, - desc_interval); + 8 * ep->desc.bInterval); return interval; } -static unsigned int xhci_parse_microframe_interval(struct usb_device *udev, - struct usb_host_endpoint *ep) -{ - if (ep->desc.bInterval == 0) - return 0; - return xhci_microframes_to_exponent(udev, ep, - ep->desc.bInterval, 0, 15); -} - - -static unsigned int xhci_parse_frame_interval(struct usb_device *udev, - struct usb_host_endpoint *ep) -{ - return xhci_microframes_to_exponent(udev, ep, - ep->desc.bInterval * 8, 3, 10); -} - /* Return the polling or NAK interval. * * The polling interval is expressed in "microframes". If xHCI's Interval field @@ -1065,7 +1041,7 @@ static unsigned int xhci_get_endpoint_interval(struct usb_device *udev, /* Max NAK rate */ if (usb_endpoint_xfer_control(&ep->desc) || usb_endpoint_xfer_bulk(&ep->desc)) { - interval = xhci_parse_microframe_interval(udev, ep); + interval = ep->desc.bInterval; break; } /* Fall through - SS and HS isoc/int have same decoding */ @@ -1199,10 +1175,10 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, */ if (usb_endpoint_xfer_isoc(&ep->desc)) virt_dev->eps[ep_index].new_ring = - xhci_ring_alloc(xhci, 8, true, true, mem_flags); + xhci_ring_alloc(xhci, 8, true, mem_flags); else virt_dev->eps[ep_index].new_ring = - xhci_ring_alloc(xhci, 1, true, false, mem_flags); + xhci_ring_alloc(xhci, 1, true, mem_flags); if (!virt_dev->eps[ep_index].new_ring) { /* Attempt to use the ring cache */ if (virt_dev->num_rings_cached == 0) @@ -1211,8 +1187,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, virt_dev->ring_cache[virt_dev->num_rings_cached]; virt_dev->ring_cache[virt_dev->num_rings_cached] = NULL; virt_dev->num_rings_cached--; - xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring, - usb_endpoint_xfer_isoc(&ep->desc) ? true : false); + xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring); } virt_dev->eps[ep_index].skip = false; ep_ring = virt_dev->eps[ep_index].new_ring; @@ -1514,11 +1489,15 @@ void xhci_free_command(struct xhci_hcd *xhci, void xhci_mem_cleanup(struct xhci_hcd *xhci) { struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); - struct xhci_cd *cur_cd, *next_cd; int size; int i; /* Free the Event Ring Segment Table and the actual Event Ring */ + if (xhci->ir_set) { + xhci_writel(xhci, 0, &xhci->ir_set->erst_size); + xhci_write_64(xhci, 0, &xhci->ir_set->erst_base); + xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue); + } size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); if (xhci->erst.entries) pci_free_consistent(pdev, size, @@ -1530,16 +1509,11 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) xhci->event_ring = NULL; xhci_dbg(xhci, "Freed event ring\n"); - xhci->cmd_ring_reserved_trbs = 0; + xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring); if (xhci->cmd_ring) xhci_ring_free(xhci, xhci->cmd_ring); xhci->cmd_ring = NULL; xhci_dbg(xhci, "Freed command ring\n"); - list_for_each_entry_safe(cur_cd, next_cd, - &xhci->cancel_cmd_list, cancel_cmd_list) { - list_del(&cur_cd->cancel_cmd_list); - kfree(cur_cd); - } for (i = 1; i < MAX_HC_SLOTS; ++i) xhci_free_virt_device(xhci, i); @@ -1564,6 +1538,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) xhci->medium_streams_pool = NULL; xhci_dbg(xhci, "Freed medium stream array pool\n"); + xhci_write_64(xhci, 0, &xhci->op_regs->dcbaa_ptr); if (xhci->dcbaa) pci_free_consistent(pdev, sizeof(*xhci->dcbaa), xhci->dcbaa, xhci->dcbaa->dma); @@ -2026,10 +2001,9 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) goto fail; /* Set up the command ring to have one segments for now. */ - xhci->cmd_ring = xhci_ring_alloc(xhci, 1, true, false, flags); + xhci->cmd_ring = xhci_ring_alloc(xhci, 1, true, flags); if (!xhci->cmd_ring) goto fail; - INIT_LIST_HEAD(&xhci->cancel_cmd_list); xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring); xhci_dbg(xhci, "First segment DMA is 0x%llx\n", (unsigned long long)xhci->cmd_ring->first_seg->dma); @@ -2058,8 +2032,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) * the event ring segment table (ERST). Section 4.9.3. */ xhci_dbg(xhci, "// Allocating event ring\n"); - xhci->event_ring = xhci_ring_alloc(xhci, ERST_NUM_SEGS, false, false, - flags); + xhci->event_ring = xhci_ring_alloc(xhci, ERST_NUM_SEGS, false, flags); if (!xhci->event_ring) goto fail; if (xhci_check_trb_in_td_math(xhci, flags) < 0) @@ -2133,8 +2106,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) fail: xhci_warn(xhci, "Couldn't initialize memory\n"); - xhci_halt(xhci); - xhci_reset(xhci); xhci_mem_cleanup(xhci); return -ENOMEM; } diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 7998b6fc9bb7..cb16de213f64 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -28,7 +28,6 @@ /* Device for a quirk */ #define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73 #define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000 -#define PCI_DEVICE_ID_FRESCO_LOGIC_FL1400 0x1400 #define PCI_VENDOR_ID_ETRON 0x1b6f #define PCI_DEVICE_ID_ASROCK_P67 0x7023 @@ -110,10 +109,8 @@ static int xhci_pci_setup(struct usb_hcd *hcd) /* Look for vendor-specific quirks */ if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC && - (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK || - pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_FL1400)) { - if (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK && - pdev->revision == 0x0) { + pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) { + if (pdev->revision == 0x0) { xhci->quirks |= XHCI_RESET_EP_QUIRK; xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure" " endpoint cmd after reset endpoint\n"); @@ -126,15 +123,11 @@ static int xhci_pci_setup(struct usb_hcd *hcd) xhci_dbg(xhci, "QUIRK: Fresco Logic revision %u " "has broken MSI implementation\n", pdev->revision); - xhci->quirks |= XHCI_TRUST_TX_LENGTH; } if (pdev->vendor == PCI_VENDOR_ID_NEC) xhci->quirks |= XHCI_NEC_HOST; - if (pdev->vendor == PCI_VENDOR_ID_AMD && xhci->hci_version == 0x96) - xhci->quirks |= XHCI_AMD_0x96_HOST; - /* AMD PLL quirk */ if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) xhci->quirks |= XHCI_AMD_PLL_FIX; @@ -143,25 +136,12 @@ static int xhci_pci_setup(struct usb_hcd *hcd) xhci->quirks |= XHCI_SPURIOUS_SUCCESS; xhci->quirks |= XHCI_EP_LIMIT_QUIRK; xhci->limit_active_eps = 64; - /* - * PPT desktop boards DH77EB and DH77DF will power back on after - * a few seconds of being shutdown. The fix for this is to - * switch the ports from xHCI to EHCI on shutdown. We can't use - * DMI information to find those particular boards (since each - * vendor will change the board name), so we have to key off all - * PPT chipsets. - */ - xhci->quirks |= XHCI_SPURIOUS_REBOOT; - xhci->quirks |= XHCI_AVOID_BEI; } if (pdev->vendor == PCI_VENDOR_ID_ETRON && pdev->device == PCI_DEVICE_ID_ASROCK_P67) { xhci->quirks |= XHCI_RESET_ON_RESUME; xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); - xhci->quirks |= XHCI_TRUST_TX_LENGTH; } - if (pdev->vendor == PCI_VENDOR_ID_VIA) - xhci->quirks |= XHCI_RESET_ON_RESUME; /* Make sure the HC is halted. */ retval = xhci_halt(xhci); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index cb436fe12a03..70cacbbe7fb9 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -147,34 +147,25 @@ static void next_trb(struct xhci_hcd *xhci, */ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer) { + union xhci_trb *next = ++(ring->dequeue); unsigned long long addr; ring->deq_updates++; - - do { - /* - * Update the dequeue pointer further if that was a link TRB or - * we're at the end of an event ring segment (which doesn't have - * link TRBS) - */ - if (last_trb(xhci, ring, ring->deq_seg, ring->dequeue)) { - if (consumer && last_trb_on_last_seg(xhci, ring, - ring->deq_seg, ring->dequeue)) { - if (!in_interrupt()) - xhci_dbg(xhci, "Toggle cycle state " - "for ring %p = %i\n", - ring, - (unsigned int) - ring->cycle_state); - ring->cycle_state = (ring->cycle_state ? 0 : 1); - } - ring->deq_seg = ring->deq_seg->next; - ring->dequeue = ring->deq_seg->trbs; - } else { - ring->dequeue++; + /* Update the dequeue pointer further if that was a link TRB or we're at + * the end of an event ring segment (which doesn't have link TRBS) + */ + while (last_trb(xhci, ring, ring->deq_seg, next)) { + if (consumer && last_trb_on_last_seg(xhci, ring, ring->deq_seg, next)) { + ring->cycle_state = (ring->cycle_state ? 0 : 1); + if (!in_interrupt()) + xhci_dbg(xhci, "Toggle cycle state for ring %p = %i\n", + ring, + (unsigned int) ring->cycle_state); } - } while (last_trb(xhci, ring, ring->deq_seg, ring->dequeue)); - + ring->deq_seg = ring->deq_seg->next; + ring->dequeue = ring->deq_seg->trbs; + next = ring->dequeue; + } addr = (unsigned long long) xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); } @@ -196,7 +187,7 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer * prepare_transfer()? */ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, - bool consumer, bool more_trbs_coming, bool isoc) + bool consumer, bool more_trbs_coming) { u32 chain; union xhci_trb *next; @@ -223,13 +214,11 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, if (!chain && !more_trbs_coming) break; - /* If we're not dealing with 0.95 hardware or - * isoc rings on AMD 0.96 host, + /* If we're not dealing with 0.95 hardware, * carry over the chain bit of the previous TRB * (which may mean the chain bit is cleared). */ - if (!(isoc && (xhci->quirks & XHCI_AMD_0x96_HOST)) - && !xhci_link_trb_quirk(xhci)) { + if (!xhci_link_trb_quirk(xhci)) { next->link.control &= cpu_to_le32(~TRB_CHAIN); next->link.control |= @@ -311,123 +300,12 @@ static int room_on_ring(struct xhci_hcd *xhci, struct xhci_ring *ring, /* Ring the host controller doorbell after placing a command on the ring */ void xhci_ring_cmd_db(struct xhci_hcd *xhci) { - if (!(xhci->cmd_ring_state & CMD_RING_STATE_RUNNING)) - return; - xhci_dbg(xhci, "// Ding dong!\n"); xhci_writel(xhci, DB_VALUE_HOST, &xhci->dba->doorbell[0]); /* Flush PCI posted writes */ xhci_readl(xhci, &xhci->dba->doorbell[0]); } -static int xhci_abort_cmd_ring(struct xhci_hcd *xhci) -{ - u64 temp_64; - int ret; - - xhci_dbg(xhci, "Abort command ring\n"); - - if (!(xhci->cmd_ring_state & CMD_RING_STATE_RUNNING)) { - xhci_dbg(xhci, "The command ring isn't running, " - "Have the command ring been stopped?\n"); - return 0; - } - - temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); - if (!(temp_64 & CMD_RING_RUNNING)) { - xhci_dbg(xhci, "Command ring had been stopped\n"); - return 0; - } - xhci->cmd_ring_state = CMD_RING_STATE_ABORTED; - xhci_write_64(xhci, temp_64 | CMD_RING_ABORT, - &xhci->op_regs->cmd_ring); - - /* Section 4.6.1.2 of xHCI 1.0 spec says software should - * time the completion od all xHCI commands, including - * the Command Abort operation. If software doesn't see - * CRR negated in a timely manner (e.g. longer than 5 - * seconds), then it should assume that the there are - * larger problems with the xHC and assert HCRST. - */ - ret = handshake(xhci, &xhci->op_regs->cmd_ring, - CMD_RING_RUNNING, 0, 5 * 1000 * 1000); - if (ret < 0) { - xhci_err(xhci, "Stopped the command ring failed, " - "maybe the host is dead\n"); - xhci->xhc_state |= XHCI_STATE_DYING; - xhci_quiesce(xhci); - xhci_halt(xhci); - return -ESHUTDOWN; - } - - return 0; -} - -static int xhci_queue_cd(struct xhci_hcd *xhci, - struct xhci_command *command, - union xhci_trb *cmd_trb) -{ - struct xhci_cd *cd; - cd = kzalloc(sizeof(struct xhci_cd), GFP_ATOMIC); - if (!cd) - return -ENOMEM; - INIT_LIST_HEAD(&cd->cancel_cmd_list); - - cd->command = command; - cd->cmd_trb = cmd_trb; - list_add_tail(&cd->cancel_cmd_list, &xhci->cancel_cmd_list); - - return 0; -} - -/* - * Cancel the command which has issue. - * - * Some commands may hang due to waiting for acknowledgement from - * usb device. It is outside of the xHC's ability to control and - * will cause the command ring is blocked. When it occurs software - * should intervene to recover the command ring. - * See Section 4.6.1.1 and 4.6.1.2 - */ -int xhci_cancel_cmd(struct xhci_hcd *xhci, struct xhci_command *command, - union xhci_trb *cmd_trb) -{ - int retval = 0; - unsigned long flags; - - spin_lock_irqsave(&xhci->lock, flags); - - if (xhci->xhc_state & XHCI_STATE_DYING) { - xhci_warn(xhci, "Abort the command ring," - " but the xHCI is dead.\n"); - retval = -ESHUTDOWN; - goto fail; - } - - /* queue the cmd desriptor to cancel_cmd_list */ - retval = xhci_queue_cd(xhci, command, cmd_trb); - if (retval) { - xhci_warn(xhci, "Queuing command descriptor failed.\n"); - goto fail; - } - - /* abort command ring */ - retval = xhci_abort_cmd_ring(xhci); - if (retval) { - xhci_err(xhci, "Abort command ring failed\n"); - if (unlikely(retval == -ESHUTDOWN)) { - spin_unlock_irqrestore(&xhci->lock, flags); - usb_hc_died(xhci_to_hcd(xhci)->primary_hcd); - xhci_dbg(xhci, "xHCI host controller is dead.\n"); - return retval; - } - } - -fail: - spin_unlock_irqrestore(&xhci->lock, flags); - return retval; -} - void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, @@ -638,12 +516,8 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, (unsigned long long) addr); } -/* flip_cycle means flip the cycle bit of all but the first and last TRB. - * (The last TRB actually points to the ring enqueue pointer, which is not part - * of this TD.) This is used to remove partially enqueued isoc TDs from a ring. - */ static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, - struct xhci_td *cur_td, bool flip_cycle) + struct xhci_td *cur_td) { struct xhci_segment *cur_seg; union xhci_trb *cur_trb; @@ -657,12 +531,6 @@ static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, * leave the pointers intact. */ cur_trb->generic.field[3] &= cpu_to_le32(~TRB_CHAIN); - /* Flip the cycle bit (link TRBs can't be the first - * or last TRB). - */ - if (flip_cycle) - cur_trb->generic.field[3] ^= - cpu_to_le32(TRB_CYCLE); xhci_dbg(xhci, "Cancel (unchain) link TRB\n"); xhci_dbg(xhci, "Address = %p (0x%llx dma); " "in seg %p (0x%llx dma)\n", @@ -676,11 +544,6 @@ static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, cur_trb->generic.field[2] = 0; /* Preserve only the cycle bit of this TRB */ cur_trb->generic.field[3] &= cpu_to_le32(TRB_CYCLE); - /* Flip the cycle bit except on the first or last TRB */ - if (flip_cycle && cur_trb != cur_td->first_trb && - cur_trb != cur_td->last_trb) - cur_trb->generic.field[3] ^= - cpu_to_le32(TRB_CYCLE); cur_trb->generic.field[3] |= cpu_to_le32( TRB_TYPE(TRB_TR_NOOP)); xhci_dbg(xhci, "Cancel TRB %p (0x%llx dma) " @@ -859,14 +722,14 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci, cur_td->urb->stream_id, cur_td, &deq_state); else - td_to_noop(xhci, ep_ring, cur_td, false); + td_to_noop(xhci, ep_ring, cur_td); remove_finished_td: /* * The event handler won't see a completion for this TD anymore, * so remove it from the endpoint ring's TD list. Keep it in * the cancelled TD list for URB completion later. */ - list_del_init(&cur_td->td_list); + list_del(&cur_td->td_list); } last_unlinked_td = cur_td; xhci_stop_watchdog_timer_in_irq(xhci, ep); @@ -894,7 +757,7 @@ remove_finished_td: do { cur_td = list_entry(ep->cancelled_td_list.next, struct xhci_td, cancelled_td_list); - list_del_init(&cur_td->cancelled_td_list); + list_del(&cur_td->cancelled_td_list); /* Clean up the cancelled URB */ /* Doesn't matter what we pass for status, since the core will @@ -939,24 +802,23 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) struct xhci_ring *ring; struct xhci_td *cur_td; int ret, i, j; - unsigned long flags; ep = (struct xhci_virt_ep *) arg; xhci = ep->xhci; - spin_lock_irqsave(&xhci->lock, flags); + spin_lock(&xhci->lock); ep->stop_cmds_pending--; if (xhci->xhc_state & XHCI_STATE_DYING) { xhci_dbg(xhci, "Stop EP timer ran, but another timer marked " "xHCI as DYING, exiting.\n"); - spin_unlock_irqrestore(&xhci->lock, flags); + spin_unlock(&xhci->lock); return; } if (!(ep->stop_cmds_pending == 0 && (ep->ep_state & EP_HALT_PENDING))) { xhci_dbg(xhci, "Stop EP timer ran, but no command pending, " "exiting.\n"); - spin_unlock_irqrestore(&xhci->lock, flags); + spin_unlock(&xhci->lock); return; } @@ -968,11 +830,11 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) xhci->xhc_state |= XHCI_STATE_DYING; /* Disable interrupts from the host controller and start halting it */ xhci_quiesce(xhci); - spin_unlock_irqrestore(&xhci->lock, flags); + spin_unlock(&xhci->lock); ret = xhci_halt(xhci); - spin_lock_irqsave(&xhci->lock, flags); + spin_lock(&xhci->lock); if (ret < 0) { /* This is bad; the host is not responding to commands and it's * not allowing itself to be halted. At least interrupts are @@ -1003,9 +865,9 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) cur_td = list_first_entry(&ring->td_list, struct xhci_td, td_list); - list_del_init(&cur_td->td_list); + list_del(&cur_td->td_list); if (!list_empty(&cur_td->cancelled_td_list)) - list_del_init(&cur_td->cancelled_td_list); + list_del(&cur_td->cancelled_td_list); xhci_giveback_urb_in_irq(xhci, cur_td, -ESHUTDOWN, "killed"); } @@ -1014,13 +876,13 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) &temp_ep->cancelled_td_list, struct xhci_td, cancelled_td_list); - list_del_init(&cur_td->cancelled_td_list); + list_del(&cur_td->cancelled_td_list); xhci_giveback_urb_in_irq(xhci, cur_td, -ESHUTDOWN, "killed"); } } } - spin_unlock_irqrestore(&xhci->lock, flags); + spin_unlock(&xhci->lock); xhci_dbg(xhci, "Calling usb_hc_died()\n"); usb_hc_died(xhci_to_hcd(xhci)->primary_hcd); xhci_dbg(xhci, "xHCI host controller is dead.\n"); @@ -1157,20 +1019,6 @@ static void handle_reset_ep_completion(struct xhci_hcd *xhci, } } -/* Complete the command and detele it from the devcie's command queue. - */ -static void xhci_complete_cmd_in_cmd_wait_list(struct xhci_hcd *xhci, - struct xhci_command *command, u32 status) -{ - command->status = status; - list_del(&command->cmd_list); - if (command->completion) - complete(command->completion); - else - xhci_free_command(xhci, command); -} - - /* Check to see if a command in the device's command queue matches this one. * Signal the completion or free the command, and return 1. Return 0 if the * completed command isn't at the head of the command list. @@ -1189,155 +1037,15 @@ static int handle_cmd_in_cmd_wait_list(struct xhci_hcd *xhci, if (xhci->cmd_ring->dequeue != command->command_trb) return 0; - xhci_complete_cmd_in_cmd_wait_list(xhci, command, - GET_COMP_CODE(le32_to_cpu(event->status))); + command->status = GET_COMP_CODE(le32_to_cpu(event->status)); + list_del(&command->cmd_list); + if (command->completion) + complete(command->completion); + else + xhci_free_command(xhci, command); return 1; } -/* - * Finding the command trb need to be cancelled and modifying it to - * NO OP command. And if the command is in device's command wait - * list, finishing and freeing it. - * - * If we can't find the command trb, we think it had already been - * executed. - */ -static void xhci_cmd_to_noop(struct xhci_hcd *xhci, struct xhci_cd *cur_cd) -{ - struct xhci_segment *cur_seg; - union xhci_trb *cmd_trb; - u32 cycle_state; - - if (xhci->cmd_ring->dequeue == xhci->cmd_ring->enqueue) - return; - - /* find the current segment of command ring */ - cur_seg = find_trb_seg(xhci->cmd_ring->first_seg, - xhci->cmd_ring->dequeue, &cycle_state); - - if (!cur_seg) { - xhci_warn(xhci, "Command ring mismatch, dequeue = %p %llx (dma)\n", - xhci->cmd_ring->dequeue, - (unsigned long long) - xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, - xhci->cmd_ring->dequeue)); - xhci_debug_ring(xhci, xhci->cmd_ring); - xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); - return; - } - - /* find the command trb matched by cd from command ring */ - for (cmd_trb = xhci->cmd_ring->dequeue; - cmd_trb != xhci->cmd_ring->enqueue; - next_trb(xhci, xhci->cmd_ring, &cur_seg, &cmd_trb)) { - /* If the trb is link trb, continue */ - if (TRB_TYPE_LINK_LE32(cmd_trb->generic.field[3])) - continue; - - if (cur_cd->cmd_trb == cmd_trb) { - - /* If the command in device's command list, we should - * finish it and free the command structure. - */ - if (cur_cd->command) - xhci_complete_cmd_in_cmd_wait_list(xhci, - cur_cd->command, COMP_CMD_STOP); - - /* get cycle state from the origin command trb */ - cycle_state = le32_to_cpu(cmd_trb->generic.field[3]) - & TRB_CYCLE; - - /* modify the command trb to NO OP command */ - cmd_trb->generic.field[0] = 0; - cmd_trb->generic.field[1] = 0; - cmd_trb->generic.field[2] = 0; - cmd_trb->generic.field[3] = cpu_to_le32( - TRB_TYPE(TRB_CMD_NOOP) | cycle_state); - break; - } - } -} - -static void xhci_cancel_cmd_in_cd_list(struct xhci_hcd *xhci) -{ - struct xhci_cd *cur_cd, *next_cd; - - if (list_empty(&xhci->cancel_cmd_list)) - return; - - list_for_each_entry_safe(cur_cd, next_cd, - &xhci->cancel_cmd_list, cancel_cmd_list) { - xhci_cmd_to_noop(xhci, cur_cd); - list_del(&cur_cd->cancel_cmd_list); - kfree(cur_cd); - } -} - -/* - * traversing the cancel_cmd_list. If the command descriptor according - * to cmd_trb is found, the function free it and return 1, otherwise - * return 0. - */ -static int xhci_search_cmd_trb_in_cd_list(struct xhci_hcd *xhci, - union xhci_trb *cmd_trb) -{ - struct xhci_cd *cur_cd, *next_cd; - - if (list_empty(&xhci->cancel_cmd_list)) - return 0; - - list_for_each_entry_safe(cur_cd, next_cd, - &xhci->cancel_cmd_list, cancel_cmd_list) { - if (cur_cd->cmd_trb == cmd_trb) { - if (cur_cd->command) - xhci_complete_cmd_in_cmd_wait_list(xhci, - cur_cd->command, COMP_CMD_STOP); - list_del(&cur_cd->cancel_cmd_list); - kfree(cur_cd); - return 1; - } - } - - return 0; -} - -/* - * If the cmd_trb_comp_code is COMP_CMD_ABORT, we just check whether the - * trb pointed by the command ring dequeue pointer is the trb we want to - * cancel or not. And if the cmd_trb_comp_code is COMP_CMD_STOP, we will - * traverse the cancel_cmd_list to trun the all of the commands according - * to command descriptor to NO-OP trb. - */ -static int handle_stopped_cmd_ring(struct xhci_hcd *xhci, - int cmd_trb_comp_code) -{ - int cur_trb_is_good = 0; - - /* Searching the cmd trb pointed by the command ring dequeue - * pointer in command descriptor list. If it is found, free it. - */ - cur_trb_is_good = xhci_search_cmd_trb_in_cd_list(xhci, - xhci->cmd_ring->dequeue); - - if (cmd_trb_comp_code == COMP_CMD_ABORT) - xhci->cmd_ring_state = CMD_RING_STATE_STOPPED; - else if (cmd_trb_comp_code == COMP_CMD_STOP) { - /* traversing the cancel_cmd_list and canceling - * the command according to command descriptor - */ - xhci_cancel_cmd_in_cd_list(xhci); - - xhci->cmd_ring_state = CMD_RING_STATE_RUNNING; - /* - * ring command ring doorbell again to restart the - * command ring - */ - if (xhci->cmd_ring->dequeue != xhci->cmd_ring->enqueue) - xhci_ring_cmd_db(xhci); - } - return cur_trb_is_good; -} - static void handle_cmd_completion(struct xhci_hcd *xhci, struct xhci_event_cmd *event) { @@ -1363,22 +1071,6 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, xhci->error_bitmask |= 1 << 5; return; } - - if ((GET_COMP_CODE(le32_to_cpu(event->status)) == COMP_CMD_ABORT) || - (GET_COMP_CODE(le32_to_cpu(event->status)) == COMP_CMD_STOP)) { - /* If the return value is 0, we think the trb pointed by - * command ring dequeue pointer is a good trb. The good - * trb means we don't want to cancel the trb, but it have - * been stopped by host. So we should handle it normally. - * Otherwise, driver should invoke inc_deq() and return. - */ - if (handle_stopped_cmd_ring(xhci, - GET_COMP_CODE(le32_to_cpu(event->status)))) { - inc_deq(xhci, xhci->cmd_ring, false); - return; - } - } - switch (le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3]) & TRB_TYPE_BITMASK) { case TRB_TYPE(TRB_ENABLE_SLOT): @@ -1508,7 +1200,6 @@ static void handle_vendor_event(struct xhci_hcd *xhci, * * Returns a zero-based port number, which is suitable for indexing into each of * the split roothubs' port arrays and bus state arrays. - * Add one to it in order to call xhci_find_slot_id_by_port. */ static unsigned int find_faked_portnum_from_hw_portnum(struct usb_hcd *hcd, struct xhci_hcd *xhci, u32 port_id) @@ -1631,7 +1322,7 @@ static void handle_port_status(struct xhci_hcd *xhci, temp |= PORT_LINK_STROBE | XDEV_U0; xhci_writel(xhci, temp, port_array[faked_port_index]); slot_id = xhci_find_slot_id_by_port(hcd, xhci, - faked_port_index + 1); + faked_port_index); if (!slot_id) { xhci_dbg(xhci, "slot_id is zero\n"); goto cleanup; @@ -1639,8 +1330,10 @@ static void handle_port_status(struct xhci_hcd *xhci, xhci_ring_device(xhci, slot_id); xhci_dbg(xhci, "resume SS port %d finished\n", port_id); /* Clear PORT_PLC */ - xhci_test_and_clear_bit(xhci, port_array, - faked_port_index, PORT_PLC); + temp = xhci_readl(xhci, port_array[faked_port_index]); + temp = xhci_port_state_to_neutral(temp); + temp |= PORT_PLC; + xhci_writel(xhci, temp, port_array[faked_port_index]); } else { xhci_dbg(xhci, "resume HS port %d\n", port_id); bus_state->resume_done[faked_port_index] = jiffies + @@ -1651,10 +1344,6 @@ static void handle_port_status(struct xhci_hcd *xhci, } } - if (hcd->speed != HCD_USB3) - xhci_test_and_clear_bit(xhci, port_array, faked_port_index, - PORT_PLC); - cleanup: /* Update event ring dequeue pointer before dropping the lock */ inc_deq(xhci, xhci->event_ring, true); @@ -1878,10 +1567,10 @@ td_cleanup: else *status = 0; } - list_del_init(&td->td_list); + list_del(&td->td_list); /* Was this TD slated to be cancelled but completed anyway? */ if (!list_empty(&td->cancelled_td_list)) - list_del_init(&td->cancelled_td_list); + list_del(&td->cancelled_td_list); urb_priv->td_cnt++; /* Giveback the urb when all the tds are completed */ @@ -2029,12 +1718,8 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, /* handle completion code */ switch (trb_comp_code) { case COMP_SUCCESS: - if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) { - frame->status = 0; - break; - } - if ((xhci->quirks & XHCI_TRUST_TX_LENGTH)) - trb_comp_code = COMP_SHORT_TX; + frame->status = 0; + break; case COMP_SHORT_TX: frame->status = td->urb->transfer_flags & URB_SHORT_NOT_OK ? -EREMOTEIO : 0; @@ -2050,7 +1735,6 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, break; case COMP_DEV_ERR: case COMP_STALL: - case COMP_TX_ERR: frame->status = -EPROTO; skip_td = true; break; @@ -2133,16 +1817,13 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, switch (trb_comp_code) { case COMP_SUCCESS: /* Double check that the HW transferred everything. */ - if (event_trb != td->last_trb || - TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { + if (event_trb != td->last_trb) { xhci_warn(xhci, "WARN Successful completion " "on short TX\n"); if (td->urb->transfer_flags & URB_SHORT_NOT_OK) *status = -EREMOTEIO; else *status = 0; - if ((xhci->quirks & XHCI_TRUST_TX_LENGTH)) - trb_comp_code = COMP_SHORT_TX; } else { *status = 0; } @@ -2244,10 +1925,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, int status = -EINPROGRESS; struct urb_priv *urb_priv; struct xhci_ep_ctx *ep_ctx; - struct list_head *tmp; u32 trb_comp_code; int ret = 0; - int td_num = 0; slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags)); xdev = xhci->devs[slot_id]; @@ -2269,12 +1948,6 @@ static int handle_tx_event(struct xhci_hcd *xhci, return -ENODEV; } - /* Count current td numbers if ep->skip is set */ - if (ep->skip) { - list_for_each(tmp, &ep_ring->td_list) - td_num++; - } - event_dma = le64_to_cpu(event->buffer); trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len)); /* Look for common error cases */ @@ -2283,13 +1956,6 @@ static int handle_tx_event(struct xhci_hcd *xhci, * transfer type */ case COMP_SUCCESS: - if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) - break; - if (xhci->quirks & XHCI_TRUST_TX_LENGTH) - trb_comp_code = COMP_SHORT_TX; - else - xhci_warn(xhci, "WARN Successful completion on short TX: " - "needs XHCI_TRUST_TX_LENGTH quirk?\n"); case COMP_SHORT_TX: break; case COMP_STOP: @@ -2393,18 +2059,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, goto cleanup; } - /* We've skipped all the TDs on the ep ring when ep->skip set */ - if (ep->skip && td_num == 0) { - ep->skip = false; - xhci_dbg(xhci, "All tds on the ep_ring skipped. " - "Clear skip flag.\n"); - ret = 0; - goto cleanup; - } - td = list_entry(ep_ring->td_list.next, struct xhci_td, td_list); - if (ep->skip) - td_num--; /* Is this a TRB in the currently executing TD? */ event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue, @@ -2506,8 +2161,6 @@ cleanup: (trb_comp_code != COMP_STALL && trb_comp_code != COMP_BABBLE)) xhci_urb_free_priv(xhci, urb_priv); - else - kfree(urb_priv); usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); if ((urb->actual_length != urb->transfer_buffer_length && @@ -2659,7 +2312,7 @@ hw_died: u32 irq_pending; /* Acknowledge the PCI interrupt */ irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); - irq_pending |= IMAN_IP; + irq_pending |= 0x3; xhci_writel(xhci, irq_pending, &xhci->ir_set->irq_pending); } @@ -2730,7 +2383,7 @@ irqreturn_t xhci_msi_irq(int irq, struct usb_hcd *hcd) * prepare_transfer()? */ static void queue_trb(struct xhci_hcd *xhci, struct xhci_ring *ring, - bool consumer, bool more_trbs_coming, bool isoc, + bool consumer, bool more_trbs_coming, u32 field1, u32 field2, u32 field3, u32 field4) { struct xhci_generic_trb *trb; @@ -2740,7 +2393,7 @@ static void queue_trb(struct xhci_hcd *xhci, struct xhci_ring *ring, trb->field[1] = cpu_to_le32(field2); trb->field[2] = cpu_to_le32(field3); trb->field[3] = cpu_to_le32(field4); - inc_enq(xhci, ring, consumer, more_trbs_coming, isoc); + inc_enq(xhci, ring, consumer, more_trbs_coming); } /* @@ -2748,7 +2401,7 @@ static void queue_trb(struct xhci_hcd *xhci, struct xhci_ring *ring, * FIXME allocate segments if the ring is full. */ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, - u32 ep_state, unsigned int num_trbs, bool isoc, gfp_t mem_flags) + u32 ep_state, unsigned int num_trbs, gfp_t mem_flags) { /* Make sure the endpoint has been added to xHC schedule */ switch (ep_state) { @@ -2790,11 +2443,10 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, next = ring->enqueue; while (last_trb(xhci, ring, ring->enq_seg, next)) { - /* If we're not dealing with 0.95 hardware or isoc rings - * on AMD 0.96 host, clear the chain bit. + /* If we're not dealing with 0.95 hardware, + * clear the chain bit. */ - if (!xhci_link_trb_quirk(xhci) && !(isoc && - (xhci->quirks & XHCI_AMD_0x96_HOST))) + if (!xhci_link_trb_quirk(xhci)) next->link.control &= cpu_to_le32(~TRB_CHAIN); else next->link.control |= cpu_to_le32(TRB_CHAIN); @@ -2827,7 +2479,6 @@ static int prepare_transfer(struct xhci_hcd *xhci, unsigned int num_trbs, struct urb *urb, unsigned int td_index, - bool isoc, gfp_t mem_flags) { int ret; @@ -2845,7 +2496,7 @@ static int prepare_transfer(struct xhci_hcd *xhci, ret = prepare_ring(xhci, ep_ring, le32_to_cpu(ep_ctx->ep_info) & EP_STATE_MASK, - num_trbs, isoc, mem_flags); + num_trbs, mem_flags); if (ret) return ret; @@ -2857,8 +2508,11 @@ static int prepare_transfer(struct xhci_hcd *xhci, if (td_index == 0) { ret = usb_hcd_link_urb_to_ep(bus_to_hcd(urb->dev->bus), urb); - if (unlikely(ret)) + if (unlikely(ret)) { + xhci_urb_free_priv(xhci, urb_priv); + urb->hcpriv = NULL; return ret; + } } td->urb = urb; @@ -2878,7 +2532,7 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb) struct scatterlist *sg; sg = NULL; - num_sgs = urb->num_mapped_sgs; + num_sgs = urb->num_sgs; temp = urb->transfer_buffer_length; xhci_dbg(xhci, "count sg list trbs: \n"); @@ -3026,10 +2680,6 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len, { int packets_transferred; - /* One TRB with a zero-length data packet. */ - if (running_total == 0 && trb_buff_len == 0) - return 0; - /* All the TRB queueing functions don't count the current TRB in * running_total. */ @@ -3062,13 +2712,13 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, return -EINVAL; num_trbs = count_sg_trbs_needed(xhci, urb); - num_sgs = urb->num_mapped_sgs; + num_sgs = urb->num_sgs; total_packet_count = roundup(urb->transfer_buffer_length, le16_to_cpu(urb->ep->desc.wMaxPacketSize)); trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id], ep_index, urb->stream_id, - num_trbs, urb, 0, false, mem_flags); + num_trbs, urb, 0, mem_flags); if (trb_buff_len < 0) return trb_buff_len; @@ -3163,7 +2813,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, more_trbs_coming = true; else more_trbs_coming = false; - queue_trb(xhci, ep_ring, false, more_trbs_coming, false, + queue_trb(xhci, ep_ring, false, more_trbs_coming, lower_32_bits(addr), upper_32_bits(addr), length_field, @@ -3254,7 +2904,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ret = prepare_transfer(xhci, xhci->devs[slot_id], ep_index, urb->stream_id, - num_trbs, urb, 0, false, mem_flags); + num_trbs, urb, 0, mem_flags); if (ret < 0) return ret; @@ -3326,7 +2976,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, more_trbs_coming = true; else more_trbs_coming = false; - queue_trb(xhci, ep_ring, false, more_trbs_coming, false, + queue_trb(xhci, ep_ring, false, more_trbs_coming, lower_32_bits(addr), upper_32_bits(addr), length_field, @@ -3386,7 +3036,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, num_trbs++; ret = prepare_transfer(xhci, xhci->devs[slot_id], ep_index, urb->stream_id, - num_trbs, urb, 0, false, mem_flags); + num_trbs, urb, 0, mem_flags); if (ret < 0) return ret; @@ -3419,7 +3069,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, } } - queue_trb(xhci, ep_ring, false, true, false, + queue_trb(xhci, ep_ring, false, true, setup->bRequestType | setup->bRequest << 8 | le16_to_cpu(setup->wValue) << 16, le16_to_cpu(setup->wIndex) | le16_to_cpu(setup->wLength) << 16, TRB_LEN(8) | TRB_INTR_TARGET(0), @@ -3439,7 +3089,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, if (urb->transfer_buffer_length > 0) { if (setup->bRequestType & USB_DIR_IN) field |= TRB_DIR_IN; - queue_trb(xhci, ep_ring, false, true, false, + queue_trb(xhci, ep_ring, false, true, lower_32_bits(urb->transfer_dma), upper_32_bits(urb->transfer_dma), length_field, @@ -3455,7 +3105,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, field = 0; else field = TRB_DIR_IN; - queue_trb(xhci, ep_ring, false, false, false, + queue_trb(xhci, ep_ring, false, false, 0, 0, TRB_INTR_TARGET(0), @@ -3471,16 +3121,21 @@ static int count_isoc_trbs_needed(struct xhci_hcd *xhci, struct urb *urb, int i) { int num_trbs = 0; - u64 addr, td_len; + u64 addr, td_len, running_total; addr = (u64) (urb->transfer_dma + urb->iso_frame_desc[i].offset); td_len = urb->iso_frame_desc[i].length; - num_trbs = DIV_ROUND_UP(td_len + (addr & (TRB_MAX_BUFF_SIZE - 1)), - TRB_MAX_BUFF_SIZE); - if (num_trbs == 0) + running_total = TRB_MAX_BUFF_SIZE - (addr & (TRB_MAX_BUFF_SIZE - 1)); + running_total &= TRB_MAX_BUFF_SIZE - 1; + if (running_total != 0) num_trbs++; + while (running_total < td_len) { + num_trbs++; + running_total += TRB_MAX_BUFF_SIZE; + } + return num_trbs; } @@ -3579,7 +3234,6 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, start_trb = &ep_ring->enqueue->generic; start_cycle = ep_ring->cycle_state; - urb_priv = urb->hcpriv; /* Queue the first TRB, even if it's zero-length */ for (i = 0; i < num_tds; i++) { unsigned int total_packet_count; @@ -3591,11 +3245,9 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, addr = start_addr + urb->iso_frame_desc[i].offset; td_len = urb->iso_frame_desc[i].length; td_remain_len = td_len; + /* FIXME: Ignoring zero-length packets, can those happen? */ total_packet_count = roundup(td_len, le16_to_cpu(urb->ep->desc.wMaxPacketSize)); - /* A zero-length transfer still involves at least one packet. */ - if (total_packet_count == 0) - total_packet_count++; burst_count = xhci_get_burst_count(xhci, urb->dev, urb, total_packet_count); residue = xhci_get_last_burst_packet_count(xhci, @@ -3604,22 +3256,18 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, trbs_per_td = count_isoc_trbs_needed(xhci, urb, i); ret = prepare_transfer(xhci, xhci->devs[slot_id], ep_index, - urb->stream_id, trbs_per_td, urb, i, true, - mem_flags); - if (ret < 0) { - if (i == 0) - return ret; - goto cleanup; - } + urb->stream_id, trbs_per_td, urb, i, mem_flags); + if (ret < 0) + return ret; + urb_priv = urb->hcpriv; td = urb_priv->td[i]; + for (j = 0; j < trbs_per_td; j++) { u32 remainder = 0; - field = 0; + field = TRB_TBC(burst_count) | TRB_TLBPC(residue); if (first_trb) { - field = TRB_TBC(burst_count) | - TRB_TLBPC(residue); /* Queue the isoc TRB */ field |= TRB_TYPE(TRB_ISOC); /* Assume URB_ISO_ASAP is set */ @@ -3650,9 +3298,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, } else { td->last_trb = ep_ring->enqueue; field |= TRB_IOC; - if (xhci->hci_version == 0x100 && - !(xhci->quirks & - XHCI_AVOID_BEI)) { + if (xhci->hci_version == 0x100) { /* Set BEI bit except for the last td */ if (i < num_tds - 1) field |= TRB_BEI; @@ -3679,7 +3325,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, remainder | TRB_INTR_TARGET(0); - queue_trb(xhci, ep_ring, false, more_trbs_coming, true, + queue_trb(xhci, ep_ring, false, more_trbs_coming, lower_32_bits(addr), upper_32_bits(addr), length_field, @@ -3693,8 +3339,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, /* Check TD length */ if (running_total != td_len) { xhci_err(xhci, "ISOC TD length unmatch\n"); - ret = -EINVAL; - goto cleanup; + return -EINVAL; } } @@ -3707,27 +3352,6 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id, start_cycle, start_trb); return 0; -cleanup: - /* Clean up a partially enqueued isoc transfer. */ - - for (i--; i >= 0; i--) - list_del_init(&urb_priv->td[i]->td_list); - - /* Use the first TD as a temporary variable to turn the TDs we've queued - * into No-ops with a software-owned cycle bit. That way the hardware - * won't accidentally start executing bogus TDs when we partially - * overwrite them. td->first_trb and td->start_seg are already set. - */ - urb_priv->td[0]->last_trb = ep_ring->enqueue; - /* Every TRB except the first & last will have its cycle bit flipped. */ - td_to_noop(xhci, ep_ring, urb_priv->td[0], true); - - /* Reset the ring enqueue back to the first TRB and its cycle bit. */ - ep_ring->enqueue = urb_priv->td[0]->first_trb; - ep_ring->enq_seg = urb_priv->td[0]->start_seg; - ep_ring->cycle_state = start_cycle; - usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); - return ret; } /* @@ -3762,7 +3386,7 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags, * Do not insert any td of the urb to the ring if the check failed. */ ret = prepare_ring(xhci, ep_ring, le32_to_cpu(ep_ctx->ep_info) & EP_STATE_MASK, - num_trbs, true, mem_flags); + num_trbs, mem_flags); if (ret) return ret; @@ -3821,7 +3445,7 @@ static int queue_command(struct xhci_hcd *xhci, u32 field1, u32 field2, reserved_trbs++; ret = prepare_ring(xhci, xhci->cmd_ring, EP_STATE_RUNNING, - reserved_trbs, false, GFP_ATOMIC); + reserved_trbs, GFP_ATOMIC); if (ret < 0) { xhci_err(xhci, "ERR: No room for command on command ring\n"); if (command_must_succeed) @@ -3829,8 +3453,8 @@ static int queue_command(struct xhci_hcd *xhci, u32 field1, u32 field2, "unfailable commands failed.\n"); return ret; } - queue_trb(xhci, xhci->cmd_ring, false, false, false, field1, field2, - field3, field4 | xhci->cmd_ring->cycle_state); + queue_trb(xhci, xhci->cmd_ring, false, false, field1, field2, field3, + field4 | xhci->cmd_ring->cycle_state); return 0; } diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 4864b252478c..f5fe1ac301ab 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -51,7 +51,7 @@ MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB"); * handshake done). There are two failure modes: "usec" have passed (major * hardware flakeout), or the register reads as all-ones (hardware removed). */ -int handshake(struct xhci_hcd *xhci, void __iomem *ptr, +static int handshake(struct xhci_hcd *xhci, void __iomem *ptr, u32 mask, u32 done, int usec) { u32 result; @@ -104,10 +104,8 @@ int xhci_halt(struct xhci_hcd *xhci) ret = handshake(xhci, &xhci->op_regs->status, STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); - if (!ret) { + if (!ret) xhci->xhc_state |= XHCI_STATE_HALTED; - xhci->cmd_ring_state = CMD_RING_STATE_STOPPED; - } return ret; } @@ -165,7 +163,7 @@ int xhci_reset(struct xhci_hcd *xhci) xhci_writel(xhci, command, &xhci->op_regs->command); ret = handshake(xhci, &xhci->op_regs->command, - CMD_RESET, 0, 10 * 1000 * 1000); + CMD_RESET, 0, 250 * 1000); if (ret) return ret; @@ -174,8 +172,7 @@ int xhci_reset(struct xhci_hcd *xhci) * xHCI cannot write to any doorbells or operational registers other * than status until the "Controller Not Ready" flag is cleared. */ - return handshake(xhci, &xhci->op_regs->status, - STS_CNR, 0, 10 * 1000 * 1000); + return handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 250 * 1000); } /* @@ -348,8 +345,7 @@ static void xhci_event_ring_work(unsigned long arg) spin_lock_irqsave(&xhci->lock, flags); temp = xhci_readl(xhci, &xhci->op_regs->status); xhci_dbg(xhci, "op reg status = 0x%x\n", temp); - if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING) || - (xhci->xhc_state & XHCI_STATE_HALTED)) { + if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) { xhci_dbg(xhci, "HW died, polling stopped.\n"); spin_unlock_irqrestore(&xhci->lock, flags); return; @@ -392,7 +388,6 @@ static int xhci_run_finished(struct xhci_hcd *xhci) return -ENODEV; } xhci->shared_hcd->state = HC_STATE_RUNNING; - xhci->cmd_ring_state = CMD_RING_STATE_RUNNING; if (xhci->quirks & XHCI_NEC_HOST) xhci_ring_cmd_db(xhci); @@ -448,11 +443,6 @@ int xhci_run(struct usb_hcd *hcd) if (ret) { legacy_irq: - if (!pdev->irq) { - xhci_err(xhci, "No msi-x/msi found and " - "no IRQ in BIOS\n"); - return -EINVAL; - } /* fall back to legacy interrupt*/ ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, hcd->irq_descr, hcd); @@ -597,9 +587,6 @@ void xhci_shutdown(struct usb_hcd *hcd) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); - if (xhci->quirks & XHCI_SPURIOUS_REBOOT) - usb_disable_xhci_ports(to_pci_dev(hcd->self.controller)); - spin_lock_irq(&xhci->lock); xhci_halt(xhci); spin_unlock_irq(&xhci->lock); @@ -617,11 +604,11 @@ static void xhci_save_registers(struct xhci_hcd *xhci) xhci->s3.dev_nt = xhci_readl(xhci, &xhci->op_regs->dev_notification); xhci->s3.dcbaa_ptr = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); xhci->s3.config_reg = xhci_readl(xhci, &xhci->op_regs->config_reg); + xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); + xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control); xhci->s3.erst_size = xhci_readl(xhci, &xhci->ir_set->erst_size); xhci->s3.erst_base = xhci_read_64(xhci, &xhci->ir_set->erst_base); xhci->s3.erst_dequeue = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); - xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); - xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control); } static void xhci_restore_registers(struct xhci_hcd *xhci) @@ -630,11 +617,10 @@ static void xhci_restore_registers(struct xhci_hcd *xhci) xhci_writel(xhci, xhci->s3.dev_nt, &xhci->op_regs->dev_notification); xhci_write_64(xhci, xhci->s3.dcbaa_ptr, &xhci->op_regs->dcbaa_ptr); xhci_writel(xhci, xhci->s3.config_reg, &xhci->op_regs->config_reg); - xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size); - xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base); - xhci_write_64(xhci, xhci->s3.erst_dequeue, &xhci->ir_set->erst_dequeue); xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending); xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control); + xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size); + xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base); } static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci) @@ -670,10 +656,7 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci) ring = xhci->cmd_ring; seg = ring->deq_seg; do { - memset(seg->trbs, 0, - sizeof(union xhci_trb) * (TRBS_PER_SEGMENT - 1)); - seg->trbs[TRBS_PER_SEGMENT - 1].link.control &= - cpu_to_le32(~TRB_CYCLE); + memset(seg->trbs, 0, SEGMENT_SIZE); seg = seg->next; } while (seg != ring->deq_seg); @@ -723,7 +706,7 @@ int xhci_suspend(struct xhci_hcd *xhci) command &= ~CMD_RUN; xhci_writel(xhci, command, &xhci->op_regs->command); if (handshake(xhci, &xhci->op_regs->status, - STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC)) { + STS_HALT, STS_HALT, 100*100)) { xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n"); spin_unlock_irq(&xhci->lock); return -ETIMEDOUT; @@ -737,8 +720,8 @@ int xhci_suspend(struct xhci_hcd *xhci) command = xhci_readl(xhci, &xhci->op_regs->command); command |= CMD_CSS; xhci_writel(xhci, command, &xhci->op_regs->command); - if (handshake(xhci, &xhci->op_regs->status, STS_SAVE, 0, 10 * 1000)) { - xhci_warn(xhci, "WARN: xHC save state timeout\n"); + if (handshake(xhci, &xhci->op_regs->status, STS_SAVE, 0, 10*100)) { + xhci_warn(xhci, "WARN: xHC CMD_CSS timeout\n"); spin_unlock_irq(&xhci->lock); return -ETIMEDOUT; } @@ -765,7 +748,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) u32 command, temp = 0; struct usb_hcd *hcd = xhci_to_hcd(xhci); struct usb_hcd *secondary_hcd; - int retval = 0; + int retval; /* Wait a bit if either of the roothubs need to settle from the * transition into bus suspend. @@ -775,9 +758,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) xhci->bus_state[1].next_statechange)) msleep(100); - set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); - spin_lock_irq(&xhci->lock); if (xhci->quirks & XHCI_RESET_ON_RESUME) hibernated = true; @@ -793,8 +773,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) command |= CMD_CRS; xhci_writel(xhci, command, &xhci->op_regs->command); if (handshake(xhci, &xhci->op_regs->status, - STS_RESTORE, 0, 10 * 1000)) { - xhci_warn(xhci, "WARN: xHC restore state timeout\n"); + STS_RESTORE, 0, 10*100)) { + xhci_dbg(xhci, "WARN: xHC CMD_CSS timeout\n"); spin_unlock_irq(&xhci->lock); return -ETIMEDOUT; } @@ -847,13 +827,20 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) return retval; xhci_dbg(xhci, "Start the primary HCD\n"); retval = xhci_run(hcd->primary_hcd); + if (retval) + goto failed_restart; + + xhci_dbg(xhci, "Start the secondary HCD\n"); + retval = xhci_run(secondary_hcd); if (!retval) { - xhci_dbg(xhci, "Start the secondary HCD\n"); - retval = xhci_run(secondary_hcd); + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + set_bit(HCD_FLAG_HW_ACCESSIBLE, + &xhci->shared_hcd->flags); } +failed_restart: hcd->state = HC_STATE_SUSPENDED; xhci->shared_hcd->state = HC_STATE_SUSPENDED; - goto done; + return retval; } /* step 4: set Run/Stop bit */ @@ -872,14 +859,11 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) * Running endpoints by ringing their doorbells */ - spin_unlock_irq(&xhci->lock); + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); - done: - if (retval == 0) { - usb_hcd_resume_root_hub(hcd); - usb_hcd_resume_root_hub(xhci->shared_hcd); - } - return retval; + spin_unlock_irq(&xhci->lock); + return 0; } #endif /* CONFIG_PM */ @@ -955,11 +939,8 @@ static int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, return 0; } - xhci = hcd_to_xhci(hcd); - if (xhci->xhc_state & XHCI_STATE_HALTED) - return -ENODEV; - if (check_virt_dev) { + xhci = hcd_to_xhci(hcd); if (!udev->slot_id || !xhci->devs || !xhci->devs[udev->slot_id]) { printk(KERN_DEBUG "xHCI %s called with unaddressed " @@ -1100,11 +1081,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) if (urb->dev->speed == USB_SPEED_FULL) { ret = xhci_check_maxpacket(xhci, slot_id, ep_index, urb); - if (ret < 0) { - xhci_urb_free_priv(xhci, urb_priv); - urb->hcpriv = NULL; + if (ret < 0) return ret; - } } /* We have a spinlock and interrupts disabled, so we must pass @@ -1115,8 +1093,6 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) goto dying; ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); - if (ret) - goto free_priv; spin_unlock_irqrestore(&xhci->lock, flags); } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) { spin_lock_irqsave(&xhci->lock, flags); @@ -1137,8 +1113,6 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); } - if (ret) - goto free_priv; spin_unlock_irqrestore(&xhci->lock, flags); } else if (usb_endpoint_xfer_int(&urb->ep->desc)) { spin_lock_irqsave(&xhci->lock, flags); @@ -1146,8 +1120,6 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) goto dying; ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); - if (ret) - goto free_priv; spin_unlock_irqrestore(&xhci->lock, flags); } else { spin_lock_irqsave(&xhci->lock, flags); @@ -1155,22 +1127,18 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) goto dying; ret = xhci_queue_isoc_tx_prepare(xhci, GFP_ATOMIC, urb, slot_id, ep_index); - if (ret) - goto free_priv; spin_unlock_irqrestore(&xhci->lock, flags); } exit: return ret; dying: + xhci_urb_free_priv(xhci, urb_priv); + urb->hcpriv = NULL; xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for " "non-responsive xHCI host.\n", urb->ep->desc.bEndpointAddress, urb); - ret = -ESHUTDOWN; -free_priv: - xhci_urb_free_priv(xhci, urb_priv); - urb->hcpriv = NULL; spin_unlock_irqrestore(&xhci->lock, flags); - return ret; + return -ESHUTDOWN; } /* Get the right ring for the given URB. @@ -1267,13 +1235,6 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) { xhci_dbg(xhci, "HW died, freeing TD.\n"); urb_priv = urb->hcpriv; - for (i = urb_priv->td_cnt; i < urb_priv->length; i++) { - td = urb_priv->td[i]; - if (!list_empty(&td->td_list)) - list_del_init(&td->td_list); - if (!list_empty(&td->cancelled_td_list)) - list_del_init(&td->cancelled_td_list); - } usb_hcd_unlink_urb_from_ep(hcd, urb); spin_unlock_irqrestore(&xhci->lock, flags); @@ -1281,8 +1242,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) xhci_urb_free_priv(xhci, urb_priv); return ret; } - if ((xhci->xhc_state & XHCI_STATE_DYING) || - (xhci->xhc_state & XHCI_STATE_HALTED)) { + if (xhci->xhc_state & XHCI_STATE_DYING) { xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on " "non-responsive xHCI host.\n", urb->ep->desc.bEndpointAddress, urb); @@ -1581,7 +1541,6 @@ static int xhci_configure_endpoint_result(struct xhci_hcd *xhci, /* FIXME: can we allocate more resources for the HC? */ break; case COMP_BW_ERR: - case COMP_2ND_BW_ERR: dev_warn(&udev->dev, "Not enough bandwidth " "for new device state.\n"); ret = -ENOSPC; @@ -1778,7 +1737,6 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, struct completion *cmd_completion; u32 *cmd_status; struct xhci_virt_device *virt_dev; - union xhci_trb *cmd_trb; spin_lock_irqsave(&xhci->lock, flags); virt_dev = xhci->devs[udev->slot_id]; @@ -1821,7 +1779,6 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, } init_completion(cmd_completion); - cmd_trb = xhci->cmd_ring->dequeue; if (!ctx_change) ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, udev->slot_id, must_succeed); @@ -1843,17 +1800,14 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, /* Wait for the configure endpoint command to complete */ timeleft = wait_for_completion_interruptible_timeout( cmd_completion, - XHCI_CMD_DEFAULT_TIMEOUT); + USB_CTRL_SET_TIMEOUT); if (timeleft <= 0) { xhci_warn(xhci, "%s while waiting for %s command\n", timeleft == 0 ? "Timeout" : "Signal", ctx_change == 0 ? "configure endpoint" : "evaluate context"); - /* cancel the configure endpoint command */ - ret = xhci_cancel_cmd(xhci, command, cmd_trb); - if (ret < 0) - return ret; + /* FIXME cancel the configure endpoint command */ return -ETIME; } @@ -1910,12 +1864,6 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG); ctrl_ctx->add_flags &= cpu_to_le32(~EP0_FLAG); ctrl_ctx->drop_flags &= cpu_to_le32(~(SLOT_FLAG | EP0_FLAG)); - - /* Don't issue the command if there's no endpoints to update. */ - if (ctrl_ctx->add_flags == cpu_to_le32(SLOT_FLAG) && - ctrl_ctx->drop_flags == 0) - return 0; - xhci_dbg(xhci, "New Input Control Context:\n"); slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); xhci_dbg_ctx(xhci, virt_dev->in_ctx, @@ -2202,7 +2150,8 @@ static int xhci_calculate_streams_and_bitmask(struct xhci_hcd *xhci, if (ret < 0) return ret; - max_streams = usb_ss_max_streams(&eps[i]->ss_ep_comp); + max_streams = USB_SS_MAX_STREAMS( + eps[i]->ss_ep_comp.bmAttributes); if (max_streams < (*num_streams - 1)) { xhci_dbg(xhci, "Ep 0x%x only supports %u stream IDs.\n", eps[i]->desc.bEndpointAddress, @@ -2718,10 +2667,7 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) int i, ret; ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__); - /* If the host is halted due to driver unload, we still need to free the - * device. - */ - if (ret <= 0 && ret != -ENODEV) + if (ret <= 0) return; virt_dev = xhci->devs[udev->slot_id]; @@ -2735,8 +2681,7 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) spin_lock_irqsave(&xhci->lock, flags); /* Don't disable the slot if the host controller is dead. */ state = xhci_readl(xhci, &xhci->op_regs->status); - if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING) || - (xhci->xhc_state & XHCI_STATE_HALTED)) { + if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) { xhci_free_virt_device(xhci, udev->slot_id); spin_unlock_irqrestore(&xhci->lock, flags); return; @@ -2786,10 +2731,8 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) unsigned long flags; int timeleft; int ret; - union xhci_trb *cmd_trb; spin_lock_irqsave(&xhci->lock, flags); - cmd_trb = xhci->cmd_ring->dequeue; ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); if (ret) { spin_unlock_irqrestore(&xhci->lock, flags); @@ -2801,12 +2744,12 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) /* XXX: how much time for xHC slot assignment? */ timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, - XHCI_CMD_DEFAULT_TIMEOUT); + USB_CTRL_SET_TIMEOUT); if (timeleft <= 0) { xhci_warn(xhci, "%s while waiting for a slot\n", timeleft == 0 ? "Timeout" : "Signal"); - /* cancel the enable slot request */ - return xhci_cancel_cmd(xhci, NULL, cmd_trb); + /* FIXME cancel the enable slot request */ + return 0; } if (!xhci->slot_id) { @@ -2867,7 +2810,6 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) struct xhci_slot_ctx *slot_ctx; struct xhci_input_control_ctx *ctrl_ctx; u64 temp_64; - union xhci_trb *cmd_trb; if (!udev->slot_id) { xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id); @@ -2898,15 +2840,10 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) /* Otherwise, update the control endpoint ring enqueue pointer. */ else xhci_copy_ep0_dequeue_into_input_ctx(xhci, udev); - ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); - ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG); - ctrl_ctx->drop_flags = 0; - xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); spin_lock_irqsave(&xhci->lock, flags); - cmd_trb = xhci->cmd_ring->dequeue; ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, udev->slot_id); if (ret) { @@ -2919,7 +2856,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) /* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */ timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, - XHCI_CMD_DEFAULT_TIMEOUT); + USB_CTRL_SET_TIMEOUT); /* FIXME: From section 4.3.4: "Software shall be responsible for timing * the SetAddress() "recovery interval" required by USB and aborting the * command on a timeout. @@ -2927,10 +2864,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) if (timeleft <= 0) { xhci_warn(xhci, "%s while waiting for a slot\n", timeleft == 0 ? "Timeout" : "Signal"); - /* cancel the address device command */ - ret = xhci_cancel_cmd(xhci, NULL, cmd_trb); - if (ret < 0) - return ret; + /* FIXME cancel the address device command */ return -ETIME; } @@ -2987,6 +2921,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) virt_dev->address = (le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK) + 1; /* Zero the input context control for later use */ + ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); ctrl_ctx->add_flags = 0; ctrl_ctx->drop_flags = 0; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 1d728957b1ef..d8bbf5ccb10d 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -205,10 +205,6 @@ struct xhci_op_regs { #define CMD_PM_INDEX (1 << 11) /* bits 12:31 are reserved (and should be preserved on writes). */ -/* IMAN - Interrupt Management Register */ -#define IMAN_IP (1 << 1) -#define IMAN_IE (1 << 0) - /* USBSTS - USB status - status bitmasks */ /* HC not running - set to 1 when run/stop bit is cleared. */ #define STS_HALT XHCI_STS_HALT @@ -904,6 +900,7 @@ struct xhci_transfer_event { /* Invalid Stream ID Error */ #define COMP_STRID_ERR 34 /* Secondary Bandwidth Error - may be returned by a Configure Endpoint cmd */ +/* FIXME - check for this */ #define COMP_2ND_BW_ERR 35 /* Split Transaction Error */ #define COMP_SPLIT_ERR 36 @@ -1070,9 +1067,6 @@ union xhci_trb { #define TRB_MFINDEX_WRAP 39 /* TRB IDs 40-47 reserved, 48-63 is vendor-defined */ -#define TRB_TYPE_LINK_LE32(x) (((x) & cpu_to_le32(TRB_TYPE_BITMASK)) == \ - cpu_to_le32(TRB_TYPE(TRB_LINK))) - /* Nec vendor-specific command completion event. */ #define TRB_NEC_CMD_COMP 48 /* Get NEC firmware revision. */ @@ -1114,16 +1108,6 @@ struct xhci_td { union xhci_trb *last_trb; }; -/* xHCI command default timeout value */ -#define XHCI_CMD_DEFAULT_TIMEOUT (5 * HZ) - -/* command descriptor */ -struct xhci_cd { - struct list_head cancel_cmd_list; - struct xhci_command *command; - union xhci_trb *cmd_trb; -}; - struct xhci_dequeue_state { struct xhci_segment *new_deq_seg; union xhci_trb *new_deq_ptr; @@ -1265,11 +1249,6 @@ struct xhci_hcd { /* data structures */ struct xhci_device_context_array *dcbaa; struct xhci_ring *cmd_ring; - unsigned int cmd_ring_state; -#define CMD_RING_STATE_RUNNING (1 << 0) -#define CMD_RING_STATE_ABORTED (1 << 1) -#define CMD_RING_STATE_STOPPED (1 << 2) - struct list_head cancel_cmd_list; unsigned int cmd_ring_reserved_trbs; struct xhci_ring *event_ring; struct xhci_erst erst; @@ -1332,10 +1311,6 @@ struct xhci_hcd { #define XHCI_EP_LIMIT_QUIRK (1 << 5) #define XHCI_BROKEN_MSI (1 << 6) #define XHCI_RESET_ON_RESUME (1 << 7) -#define XHCI_AMD_0x96_HOST (1 << 9) -#define XHCI_TRUST_TX_LENGTH (1 << 10) -#define XHCI_SPURIOUS_REBOOT (1 << 13) -#define XHCI_AVOID_BEI (1 << 15) unsigned int num_active_eps; unsigned int limit_active_eps; /* There are two roothubs to keep track of bus suspend info for */ @@ -1504,8 +1479,6 @@ void xhci_unregister_pci(void); #endif /* xHCI host controller glue */ -int handshake(struct xhci_hcd *xhci, void __iomem *ptr, - u32 mask, u32 done, int usec); void xhci_quiesce(struct xhci_hcd *xhci); int xhci_halt(struct xhci_hcd *xhci); int xhci_reset(struct xhci_hcd *xhci); @@ -1588,14 +1561,10 @@ void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, struct xhci_dequeue_state *deq_state); void xhci_stop_endpoint_command_watchdog(unsigned long arg); -int xhci_cancel_cmd(struct xhci_hcd *xhci, struct xhci_command *command, - union xhci_trb *cmd_trb); void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, unsigned int stream_id); /* xHCI roothub code */ -void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem **port_array, - int port_id, u32 port_bit); int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength); int xhci_hub_status_data(struct usb_hcd *hcd, char *buf); diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c index 723e833b274a..fc15ad4c3139 100644 --- a/drivers/usb/misc/emi62.c +++ b/drivers/usb/misc/emi62.c @@ -259,7 +259,7 @@ wraperr: return err; } -static const struct usb_device_id id_table[] = { +static const struct usb_device_id id_table[] __devinitconst = { { USB_DEVICE(EMI62_VENDOR_ID, EMI62_PRODUCT_ID) }, { } /* Terminating entry */ }; diff --git a/drivers/usb/misc/isight_firmware.c b/drivers/usb/misc/isight_firmware.c index 8f725f651915..fe1d44319d0a 100644 --- a/drivers/usb/misc/isight_firmware.c +++ b/drivers/usb/misc/isight_firmware.c @@ -55,9 +55,8 @@ static int isight_firmware_load(struct usb_interface *intf, ptr = firmware->data; - buf[0] = 0x01; if (usb_control_msg - (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, buf, 1, + (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\1", 1, 300) != 1) { printk(KERN_ERR "Failed to initialise isight firmware loader\n"); @@ -101,9 +100,8 @@ static int isight_firmware_load(struct usb_interface *intf, } } - buf[0] = 0x00; if (usb_control_msg - (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, buf, 1, + (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\0", 1, 300) != 1) { printk(KERN_ERR "isight firmware loading completion failed\n"); ret = -ENODEV; diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c index 59689fa2f7c1..417b8f207e8b 100644 --- a/drivers/usb/misc/usbsevseg.c +++ b/drivers/usb/misc/usbsevseg.c @@ -24,7 +24,7 @@ #define VENDOR_ID 0x0fc5 #define PRODUCT_ID 0x1227 -#define MAXLEN 8 +#define MAXLEN 6 /* table of devices that work with this driver */ static const struct usb_device_id id_table[] = { diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 5707f56d8046..bb10846affc3 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -1023,10 +1023,7 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param) case 13: /* short read, resembling case 10 */ req.wValue = cpu_to_le16((USB_DT_CONFIG << 8) | 0); /* last data packet "should" be DATA1, not DATA0 */ - if (udev->speed == USB_SPEED_SUPER) - len = 1024 - 512; - else - len = 1024 - udev->descriptor.bMaxPacketSize0; + len = 1024 - udev->descriptor.bMaxPacketSize0; expected = -EREMOTEIO; break; case 14: /* short read; try to fill the last packet */ @@ -1385,15 +1382,11 @@ static int test_halt(struct usbtest_dev *tdev, int ep, struct urb *urb) static int halt_simple(struct usbtest_dev *dev) { - int ep; - int retval = 0; - struct urb *urb; - struct usb_device *udev = testdev_to_usbdev(dev); + int ep; + int retval = 0; + struct urb *urb; - if (udev->speed == USB_SPEED_SUPER) - urb = simple_alloc_urb(udev, 0, 1024); - else - urb = simple_alloc_urb(udev, 0, 512); + urb = simple_alloc_urb(testdev_to_usbdev(dev), 0, 512); if (urb == NULL) return -ENOMEM; diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c index 2504694455f3..ac5bfd619e62 100644 --- a/drivers/usb/misc/yurex.c +++ b/drivers/usb/misc/yurex.c @@ -99,7 +99,9 @@ static void yurex_delete(struct kref *kref) usb_put_dev(dev->udev); if (dev->cntl_urb) { usb_kill_urb(dev->cntl_urb); - kfree(dev->cntl_req); + if (dev->cntl_req) + usb_free_coherent(dev->udev, YUREX_BUF_SIZE, + dev->cntl_req, dev->cntl_urb->setup_dma); if (dev->cntl_buffer) usb_free_coherent(dev->udev, YUREX_BUF_SIZE, dev->cntl_buffer, dev->cntl_urb->transfer_dma); @@ -232,7 +234,9 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ } /* allocate buffer for control req */ - dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL); + dev->cntl_req = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE, + GFP_KERNEL, + &dev->cntl_urb->setup_dma); if (!dev->cntl_req) { err("Could not allocate cntl_req"); goto error; @@ -282,7 +286,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr), dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt, dev, 1); - dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; if (usb_submit_urb(dev->urb, GFP_KERNEL)) { retval = -EIO; err("Could not submitting URB"); diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index a04b2ff9dd83..a09dbd243eb3 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c @@ -1101,7 +1101,7 @@ static long mon_bin_ioctl(struct file *file, unsigned int cmd, unsigned long arg nevents = mon_bin_queued(rp); sp = (struct mon_bin_stats __user *)arg; - if (put_user(ndropped, &sp->dropped)) + if (put_user(rp->cnt_lost, &sp->dropped)) return -EFAULT; if (put_user(nevents, &sp->queued)) return -EFAULT; diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index 318fb4e8a885..149f3f310a0a 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c @@ -226,10 +226,8 @@ static int cppi_controller_stop(struct dma_controller *c) struct cppi *controller; void __iomem *tibase; int i; - struct musb *musb; controller = container_of(c, struct cppi, controller); - musb = controller->musb; tibase = controller->tibase; /* DISABLE INDIVIDUAL CHANNEL Interrupts */ @@ -291,11 +289,9 @@ cppi_channel_allocate(struct dma_controller *c, u8 index; struct cppi_channel *cppi_ch; void __iomem *tibase; - struct musb *musb; controller = container_of(c, struct cppi, controller); tibase = controller->tibase; - musb = controller->musb; /* ep0 doesn't use DMA; remember cppi indices are 0..N-1 */ index = ep->epnum - 1; @@ -343,8 +339,7 @@ static void cppi_channel_release(struct dma_channel *channel) c = container_of(channel, struct cppi_channel, channel); tibase = c->controller->tibase; if (!c->hw_ep) - dev_dbg(c->controller->musb->controller, - "releasing idle DMA channel %p\n", c); + dev_dbg(musb->controller, "releasing idle DMA channel %p\n", c); else if (!c->transmit) core_rxirq_enable(tibase, c->index + 1); @@ -362,11 +357,10 @@ cppi_dump_rx(int level, struct cppi_channel *c, const char *tag) musb_ep_select(base, c->index + 1); - dev_dbg(c->controller->musb->controller, - "RX DMA%d%s: %d left, csr %04x, " - "%08x H%08x S%08x C%08x, " - "B%08x L%08x %08x .. %08x" - "\n", + DBG(level, "RX DMA%d%s: %d left, csr %04x, " + "%08x H%08x S%08x C%08x, " + "B%08x L%08x %08x .. %08x" + "\n", c->index, tag, musb_readl(c->controller->tibase, DAVINCI_RXCPPI_BUFCNT0_REG + 4 * c->index), @@ -393,11 +387,10 @@ cppi_dump_tx(int level, struct cppi_channel *c, const char *tag) musb_ep_select(base, c->index + 1); - dev_dbg(c->controller->musb->controller, - "TX DMA%d%s: csr %04x, " - "H%08x S%08x C%08x %08x, " - "F%08x L%08x .. %08x" - "\n", + DBG(level, "TX DMA%d%s: csr %04x, " + "H%08x S%08x C%08x %08x, " + "F%08x L%08x .. %08x" + "\n", c->index, tag, musb_readw(c->hw_ep->regs, MUSB_TXCSR), @@ -1029,7 +1022,6 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch) int i; dma_addr_t safe2ack; void __iomem *regs = rx->hw_ep->regs; - struct musb *musb = cppi->musb; cppi_dump_rx(6, rx, "/K"); diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index a0232a77c05b..c71b0372786e 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2078,6 +2078,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) if (status < 0) goto fail3; + pm_runtime_put(musb->controller); + status = musb_init_debugfs(musb); if (status < 0) goto fail4; @@ -2327,7 +2329,6 @@ static void musb_restore_context(struct musb *musb) musb->context.index_regs[i].rxhubport); } } - musb_writeb(musb_base, MUSB_INDEX, musb->context.index); } static int musb_suspend(struct device *dev) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 99ceaef23327..6aeb363e63e7 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -576,15 +576,6 @@ void musb_g_tx(struct musb *musb, u8 epnum) if (request->actual == request->length) { musb_g_giveback(musb_ep, request, 0); - /* - * In the giveback function the MUSB lock is - * released and acquired after sometime. During - * this time period the INDEX register could get - * changed by the gadget_queue function especially - * on SMP systems. Reselect the INDEX to be sure - * we are reading/modifying the right registers - */ - musb_ep_select(mbase, epnum); req = musb_ep->desc ? next_request(musb_ep) : NULL; if (!req) { dev_dbg(musb->controller, "%s idle now\n", @@ -977,15 +968,6 @@ void musb_g_rx(struct musb *musb, u8 epnum) } #endif musb_g_giveback(musb_ep, request, 0); - /* - * In the giveback function the MUSB lock is - * released and acquired after sometime. During - * this time period the INDEX register could get - * changed by the gadget_queue function especially - * on SMP systems. Reselect the INDEX to be sure - * we are reading/modifying the right registers - */ - musb_ep_select(mbase, epnum); req = next_request(musb_ep); if (!req) @@ -1716,8 +1698,6 @@ static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) is_on = !!is_on; - pm_runtime_get_sync(musb->controller); - /* NOTE: this assumes we are sensing vbus; we'd rather * not pullup unless the B-session is active. */ @@ -1727,9 +1707,6 @@ static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) musb_pullup(musb, is_on); } spin_unlock_irqrestore(&musb->lock, flags); - - pm_runtime_put(musb->controller); - return 0; } diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 6958ab9b99be..c5d4c44d0ffa 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -295,8 +295,7 @@ static int musb_otg_notifications(struct notifier_block *nb, static int omap2430_musb_init(struct musb *musb) { - u32 l; - int status = 0; + u32 l, status = 0; struct device *dev = musb->controller; struct musb_hdrc_platform_data *plat = dev->platform_data; struct omap_musb_board_data *data = plat->board_data; @@ -313,7 +312,7 @@ static int omap2430_musb_init(struct musb *musb) status = pm_runtime_get_sync(dev); if (status < 0) { - dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status); + dev_err(dev, "pm_runtime_get_sync FAILED"); goto err1; } @@ -465,14 +464,14 @@ static int __init omap2430_probe(struct platform_device *pdev) goto err2; } - pm_runtime_enable(&pdev->dev); - ret = platform_device_add(musb); if (ret) { dev_err(&pdev->dev, "failed to register musb device\n"); goto err2; } + pm_runtime_enable(&pdev->dev); + return 0; err2: diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig index cd777190d54d..c66481ad98d7 100644 --- a/drivers/usb/otg/Kconfig +++ b/drivers/usb/otg/Kconfig @@ -12,14 +12,6 @@ config USB_OTG_UTILS Select this to make sure the build includes objects from the OTG infrastructure directory. -config USB_OTG_WAKELOCK - bool "Hold a wakelock when USB connected" - depends on WAKELOCK - select USB_OTG_UTILS - help - Select this to automatically hold a wakelock when USB is - connected, preventing suspend. - if USB || USB_GADGET # diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile index d2c0a7b2bf0b..566655c53331 100644 --- a/drivers/usb/otg/Makefile +++ b/drivers/usb/otg/Makefile @@ -7,8 +7,6 @@ ccflags-$(CONFIG_USB_GADGET_DEBUG) += -DDEBUG # infrastructure obj-$(CONFIG_USB_OTG_UTILS) += otg.o -obj-$(CONFIG_USB_OTG_WAKELOCK) += otg-wakelock.o -obj-$(CONFIG_USB_OTG_UTILS) += otg_id.o # transceiver drivers obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o diff --git a/drivers/usb/otg/otg-wakelock.c b/drivers/usb/otg/otg-wakelock.c deleted file mode 100644 index 2f11472dd2b3..000000000000 --- a/drivers/usb/otg/otg-wakelock.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * otg-wakelock.c - * - * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include - -#define TEMPORARY_HOLD_TIME 2000 - -static bool enabled = true; -static struct otg_transceiver *otgwl_xceiv; -static struct notifier_block otgwl_nb; - -/* - * otgwl_spinlock is held while the VBUS lock is grabbed or dropped and the - * held field is updated to match. - */ - -static DEFINE_SPINLOCK(otgwl_spinlock); - -/* - * Only one lock, but since these 3 fields are associated with each other... - */ - -struct otgwl_lock { - char name[40]; - struct wake_lock wakelock; - bool held; -}; - -/* - * VBUS present lock. Also used as a timed lock on charger - * connect/disconnect and USB host disconnect, to allow the system - * to react to the change in power. - */ - -static struct otgwl_lock vbus_lock; - -static void otgwl_hold(struct otgwl_lock *lock) -{ - if (!lock->held) { - wake_lock(&lock->wakelock); - lock->held = true; - } -} - -static void otgwl_temporary_hold(struct otgwl_lock *lock) -{ - wake_lock_timeout(&lock->wakelock, - msecs_to_jiffies(TEMPORARY_HOLD_TIME)); - lock->held = false; -} - -static void otgwl_drop(struct otgwl_lock *lock) -{ - if (lock->held) { - wake_unlock(&lock->wakelock); - lock->held = false; - } -} - -static void otgwl_handle_event(unsigned long event) -{ - unsigned long irqflags; - - spin_lock_irqsave(&otgwl_spinlock, irqflags); - - if (!enabled) { - otgwl_drop(&vbus_lock); - spin_unlock_irqrestore(&otgwl_spinlock, irqflags); - return; - } - - switch (event) { - case USB_EVENT_VBUS: - case USB_EVENT_ENUMERATED: - otgwl_hold(&vbus_lock); - break; - - case USB_EVENT_NONE: - case USB_EVENT_ID: - case USB_EVENT_CHARGER: - otgwl_temporary_hold(&vbus_lock); - break; - - default: - break; - } - - spin_unlock_irqrestore(&otgwl_spinlock, irqflags); -} - -static int otgwl_otg_notifications(struct notifier_block *nb, - unsigned long event, void *unused) -{ - otgwl_handle_event(event); - return NOTIFY_OK; -} - -static int set_enabled(const char *val, const struct kernel_param *kp) -{ - int rv = param_set_bool(val, kp); - - if (rv) - return rv; - - if (otgwl_xceiv) - otgwl_handle_event(otgwl_xceiv->last_event); - - return 0; -} - -static struct kernel_param_ops enabled_param_ops = { - .set = set_enabled, - .get = param_get_bool, -}; - -module_param_cb(enabled, &enabled_param_ops, &enabled, 0644); -MODULE_PARM_DESC(enabled, "enable wakelock when VBUS present"); - -static int __init otg_wakelock_init(void) -{ - int ret; - - otgwl_xceiv = otg_get_transceiver(); - - if (!otgwl_xceiv) { - pr_err("%s: No OTG transceiver found\n", __func__); - return -ENODEV; - } - - snprintf(vbus_lock.name, sizeof(vbus_lock.name), "vbus-%s", - dev_name(otgwl_xceiv->dev)); - wake_lock_init(&vbus_lock.wakelock, WAKE_LOCK_SUSPEND, - vbus_lock.name); - - otgwl_nb.notifier_call = otgwl_otg_notifications; - ret = otg_register_notifier(otgwl_xceiv, &otgwl_nb); - - if (ret) { - pr_err("%s: otg_register_notifier on transceiver %s" - " failed\n", __func__, - dev_name(otgwl_xceiv->dev)); - otgwl_xceiv = NULL; - wake_lock_destroy(&vbus_lock.wakelock); - return ret; - } - - otgwl_handle_event(otgwl_xceiv->last_event); - return ret; -} - -late_initcall(otg_wakelock_init); diff --git a/drivers/usb/otg/otg_id.c b/drivers/usb/otg/otg_id.c deleted file mode 100644 index 8037edbf3141..000000000000 --- a/drivers/usb/otg/otg_id.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (C) 2011 Google, Inc. - * - * Author: - * Colin Cross - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include - -static DEFINE_MUTEX(otg_id_lock); -static struct plist_head otg_id_plist = - PLIST_HEAD_INIT(otg_id_plist); -static struct otg_id_notifier_block *otg_id_active; -static bool otg_id_cancelling; -static bool otg_id_inited; -static int otg_id_suspended; -static bool otg_id_pending; - -static void otg_id_cancel(void) -{ - if (otg_id_active) { - otg_id_cancelling = true; - mutex_unlock(&otg_id_lock); - - otg_id_active->cancel(otg_id_active); - - mutex_lock(&otg_id_lock); - otg_id_cancelling = false; - } -} - -static void __otg_id_notify(void) -{ - int ret; - struct otg_id_notifier_block *otg_id_nb; - bool proxy_wait = false; - if (plist_head_empty(&otg_id_plist)) - return; - - plist_for_each_entry(otg_id_nb, &otg_id_plist, p) { - if (proxy_wait) { - if (otg_id_nb->proxy_wait) - ret = otg_id_nb->proxy_wait(otg_id_nb); - } else { - ret = otg_id_nb->detect(otg_id_nb); - } - if (ret == OTG_ID_HANDLED) { - otg_id_active = otg_id_nb; - return; - } - if (ret == OTG_ID_PROXY_WAIT) - proxy_wait = true; - - } - - WARN(1, "otg id event not handled"); - otg_id_active = NULL; -} - -int otg_id_init(void) -{ - mutex_lock(&otg_id_lock); - - otg_id_inited = true; - __otg_id_notify(); - - mutex_unlock(&otg_id_lock); - return 0; -} -late_initcall(otg_id_init); - -/** - * otg_id_register_notifier - * @otg_id_nb: notifier block containing priority and callback function - * - * Register a notifier that will be called on any USB cable state change. - * The priority determines the order the callback will be called in, a higher - * number will be called first. A callback function needs to determine the - * type of USB cable that is connected. If it can determine the type, it - * should notify the appropriate drivers (for example, call an otg notifier - * with USB_EVENT_VBUS), and return OTG_ID_HANDLED. Once a callback has - * returned OTG_ID_HANDLED, it is responsible for calling otg_id_notify() when - * the detected USB cable is disconnected. - */ -int otg_id_register_notifier(struct otg_id_notifier_block *otg_id_nb) -{ - plist_node_init(&otg_id_nb->p, otg_id_nb->priority); - - mutex_lock(&otg_id_lock); - plist_add(&otg_id_nb->p, &otg_id_plist); - - if (otg_id_inited) { - otg_id_cancel(); - __otg_id_notify(); - } - - mutex_unlock(&otg_id_lock); - - return 0; -} - -void otg_id_unregister_notifier(struct otg_id_notifier_block *otg_id_nb) -{ - mutex_lock(&otg_id_lock); - - plist_del(&otg_id_nb->p, &otg_id_plist); - - if (otg_id_inited && (otg_id_active == otg_id_nb)) { - otg_id_cancel(); - __otg_id_notify(); - } - - mutex_unlock(&otg_id_lock); -} - -/** - * otg_id_notify - * - * Notify listeners on any USB cable state change. - * - * A driver may only call otg_id_notify if it returned OTG_ID_HANDLED the last - * time it's notifier was called, and it's cancel function has not been called. - */ -void otg_id_notify(void) -{ - mutex_lock(&otg_id_lock); - - if (otg_id_cancelling) - goto out; - - if (otg_id_suspended != 0) { - otg_id_pending = true; - goto out; - } - - __otg_id_notify(); -out: - mutex_unlock(&otg_id_lock); -} - -/** - * otg_id_suspend - * - * Mark the otg_id subsystem as going into suspend. From here on out, - * any notifications will be deferred until the last otg_id client resumes. - * If there is a pending notification when calling this function, it will - * return a negative errno and expects that the caller will abort suspend. - * Returs 0 on success. - */ -int otg_id_suspend(void) -{ - int ret = 0; - - mutex_lock(&otg_id_lock); - - /* - * if there's a pending notification, tell the caller to abort suspend - */ - if (otg_id_suspended != 0 && otg_id_pending) { - pr_info("otg_id: pending notification, should abort suspend\n"); - ret = -EBUSY; - goto out; - } - - otg_id_suspended++; -out: - mutex_unlock(&otg_id_lock); - return ret; -} - -/** - * otg_id_resume - * - * Inform the otg_id subsystem that a client is resuming. If this is the - * last client to be resumed and there's a pending notification, - * otg_id_notify() is called. - */ -void otg_id_resume(void) -{ - mutex_lock(&otg_id_lock); - if (WARN(!otg_id_suspended, "unbalanced otg_id_resume\n")) - goto out; - if (--otg_id_suspended == 0) { - if (otg_id_pending) { - pr_info("otg_id: had pending notification\n"); - otg_id_pending = false; - __otg_id_notify(); - } - } -out: - mutex_unlock(&otg_id_lock); -} diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 18e875b92e00..5cdb9d912275 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -42,7 +42,7 @@ static int debug; * Version information */ -#define DRIVER_VERSION "v0.7" +#define DRIVER_VERSION "v0.6" #define DRIVER_AUTHOR "Bart Hartgers " #define DRIVER_DESC "USB ARK3116 serial/IrDA driver" #define DRIVER_DEV_DESC "ARK3116 RS232/IrDA" @@ -380,6 +380,10 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) goto err_out; } + /* setup termios */ + if (tty) + ark3116_set_termios(tty, port, NULL); + /* remove any data still left: also clears error state */ ark3116_read_reg(serial, UART_RX, buf); @@ -402,10 +406,6 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) /* enable DMA */ ark3116_write_reg(port->serial, UART_FCR, UART_FCR_DMA_SELECT); - /* setup termios */ - if (tty) - ark3116_set_termios(tty, port, NULL); - err_out: kfree(buf); return result; diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 381d00d3cdc2..fd67cc53545b 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -39,8 +39,6 @@ static void cp210x_get_termios(struct tty_struct *, struct usb_serial_port *port); static void cp210x_get_termios_port(struct usb_serial_port *port, unsigned int *cflagp, unsigned int *baudp); -static void cp210x_change_speed(struct tty_struct *, struct usb_serial_port *, - struct ktermios *); static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *, struct ktermios*); static int cp210x_tiocmget(struct tty_struct *); @@ -49,7 +47,6 @@ static int cp210x_tiocmset_port(struct usb_serial_port *port, unsigned int, unsigned int); static void cp210x_break_ctl(struct tty_struct *, int); static int cp210x_startup(struct usb_serial *); -static void cp210x_release(struct usb_serial *); static void cp210x_dtr_rts(struct usb_serial_port *p, int on); static int debug; @@ -82,7 +79,6 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */ { USB_DEVICE(0x10C4, 0x806F) }, /* IMS USB to RS422 Converter Cable */ { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */ - { USB_DEVICE(0x10C4, 0x80C4) }, /* Cygnal Integrated Products, Inc., Optris infrared thermometer */ { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ { USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */ { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ @@ -93,11 +89,9 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ - { USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */ { USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */ { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ - { USB_DEVICE(0x10C4, 0x81A9) }, /* Multiplex RC Interface */ { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */ { USB_DEVICE(0x10C4, 0x81AD) }, /* INSYS USB Modem */ { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ @@ -120,13 +114,10 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */ { USB_DEVICE(0x10C4, 0x85EA) }, /* AC-Services IBUS-IF */ { USB_DEVICE(0x10C4, 0x85EB) }, /* AC-Services CIS-IBUS */ - { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */ { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */ { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ - { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ - { USB_DEVICE(0x10C4, 0xEA80) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */ { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ { USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */ @@ -136,39 +127,22 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10CE, 0xEA6A) }, /* Silicon Labs MobiData GPRS USB Modem 100EU */ { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */ - { USB_DEVICE(0x166A, 0x0201) }, /* Clipsal 5500PACA C-Bus Pascal Automation Controller */ - { USB_DEVICE(0x166A, 0x0301) }, /* Clipsal 5800PC C-Bus Wireless PC Interface */ { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ - { USB_DEVICE(0x166A, 0x0304) }, /* Clipsal 5000CT2 C-Bus Black and White Touchscreen */ - { USB_DEVICE(0x166A, 0x0305) }, /* Clipsal C-5000CT2 C-Bus Spectrum Colour Touchscreen */ - { USB_DEVICE(0x166A, 0x0401) }, /* Clipsal L51xx C-Bus Architectural Dimmer */ - { USB_DEVICE(0x166A, 0x0101) }, /* Clipsal 5560884 C-Bus Multi-room Audio Matrix Switcher */ { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ { USB_DEVICE(0x16DC, 0x0010) }, /* W-IE-NE-R Plein & Baus GmbH PL512 Power Supply */ { USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */ { USB_DEVICE(0x16DC, 0x0012) }, /* W-IE-NE-R Plein & Baus GmbH MPOD Multi Channel Power Supply */ { USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */ - { USB_DEVICE(0x17A8, 0x0001) }, /* Kamstrup Optical Eye/3-wire */ - { USB_DEVICE(0x17A8, 0x0005) }, /* Kamstrup M-Bus Master MultiPort 250D */ { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */ { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ - { USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */ - { USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */ - { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ - { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */ - { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */ { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ { } /* Terminating Entry */ }; MODULE_DEVICE_TABLE(usb, id_table); -struct cp210x_port_private { - __u8 bInterfaceNumber; -}; - static struct usb_driver cp210x_driver = { .name = "cp210x", .probe = usb_serial_probe, @@ -194,7 +168,6 @@ static struct usb_serial_driver cp210x_device = { .tiocmget = cp210x_tiocmget, .tiocmset = cp210x_tiocmset, .attach = cp210x_startup, - .release = cp210x_release, .dtr_rts = cp210x_dtr_rts }; @@ -227,8 +200,6 @@ static struct usb_serial_driver cp210x_device = { #define CP210X_EMBED_EVENTS 0x15 #define CP210X_GET_EVENTSTATE 0x16 #define CP210X_SET_CHARS 0x19 -#define CP210X_GET_BAUDRATE 0x1D -#define CP210X_SET_BAUDRATE 0x1E /* CP210X_IFC_ENABLE */ #define UART_ENABLE 0x0001 @@ -282,7 +253,6 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, unsigned int *data, int size) { struct usb_serial *serial = port->serial; - struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); __le32 *buf; int result, i, length; @@ -298,8 +268,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, /* Issue the request, attempting to read 'size' bytes */ result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), request, REQTYPE_DEVICE_TO_HOST, 0x0000, - port_priv->bInterfaceNumber, buf, size, - USB_CTRL_GET_TIMEOUT); + 0, buf, size, 300); /* Convert data into an array of integers */ for (i = 0; i < length; i++) @@ -327,7 +296,6 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, unsigned int *data, int size) { struct usb_serial *serial = port->serial; - struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); __le32 *buf; int result, i, length; @@ -349,14 +317,12 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_DEVICE, 0x0000, - port_priv->bInterfaceNumber, buf, size, - USB_CTRL_SET_TIMEOUT); + 0, buf, size, 300); } else { result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_DEVICE, data[0], - port_priv->bInterfaceNumber, NULL, 0, - USB_CTRL_SET_TIMEOUT); + 0, NULL, 0, 300); } kfree(buf); @@ -387,8 +353,8 @@ static inline int cp210x_set_config_single(struct usb_serial_port *port, * Quantises the baud rate as per AN205 Table 1 */ static unsigned int cp210x_quantise_baudrate(unsigned int baud) { - if (baud <= 300) - baud = 300; + if (baud <= 56) baud = 0; + else if (baud <= 300) baud = 300; else if (baud <= 600) baud = 600; else if (baud <= 1200) baud = 1200; else if (baud <= 1800) baud = 1800; @@ -416,15 +382,17 @@ static unsigned int cp210x_quantise_baudrate(unsigned int baud) { else if (baud <= 491520) baud = 460800; else if (baud <= 567138) baud = 500000; else if (baud <= 670254) baud = 576000; - else if (baud < 1000000) - baud = 921600; - else if (baud > 2000000) - baud = 2000000; + else if (baud <= 1053257) baud = 921600; + else if (baud <= 1474560) baud = 1228800; + else if (baud <= 2457600) baud = 1843200; + else baud = 3686400; return baud; } static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) { + int result; + dbg("%s - port %d", __func__, port->number); if (cp210x_set_config_single(port, CP210X_IFC_ENABLE, UART_ENABLE)) { @@ -433,14 +401,13 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) return -EPROTO; } + result = usb_serial_generic_open(tty, port); + if (result) + return result; + /* Configure the termios structure */ cp210x_get_termios(tty, port); - - /* The baud rate must be initialised on cp2104 */ - if (tty) - cp210x_change_speed(tty, port, NULL); - - return usb_serial_generic_open(tty, port); + return 0; } static void cp210x_close(struct usb_serial_port *port) @@ -492,7 +459,10 @@ static void cp210x_get_termios_port(struct usb_serial_port *port, dbg("%s - port %d", __func__, port->number); - cp210x_get_config(port, CP210X_GET_BAUDRATE, &baud, 4); + cp210x_get_config(port, CP210X_GET_BAUDDIV, &baud, 2); + /* Convert to baudrate */ + if (baud) + baud = cp210x_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud); dbg("%s - baud rate = %d", __func__, baud); *baudp = baud; @@ -606,64 +576,11 @@ static void cp210x_get_termios_port(struct usb_serial_port *port, *cflagp = cflag; } -/* - * CP2101 supports the following baud rates: - * - * 300, 600, 1200, 1800, 2400, 4800, 7200, 9600, 14400, 19200, 28800, - * 38400, 56000, 57600, 115200, 128000, 230400, 460800, 921600 - * - * CP2102 and CP2103 support the following additional rates: - * - * 4000, 16000, 51200, 64000, 76800, 153600, 250000, 256000, 500000, - * 576000 - * - * The device will map a requested rate to a supported one, but the result - * of requests for rates greater than 1053257 is undefined (see AN205). - * - * CP2104, CP2105 and CP2110 support most rates up to 2M, 921k and 1M baud, - * respectively, with an error less than 1%. The actual rates are determined - * by - * - * div = round(freq / (2 x prescale x request)) - * actual = freq / (2 x prescale x div) - * - * For CP2104 and CP2105 freq is 48Mhz and prescale is 4 for request <= 365bps - * or 1 otherwise. - * For CP2110 freq is 24Mhz and prescale is 4 for request <= 300bps or 1 - * otherwise. - */ -static void cp210x_change_speed(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - u32 baud; - - baud = tty->termios->c_ospeed; - - /* This maps the requested rate to a rate valid on cp2102 or cp2103, - * or to an arbitrary rate in [1M,2M]. - * - * NOTE: B0 is not implemented. - */ - baud = cp210x_quantise_baudrate(baud); - - dbg("%s - setting baud rate to %u", __func__, baud); - if (cp210x_set_config(port, CP210X_SET_BAUDRATE, &baud, - sizeof(baud))) { - dev_warn(&port->dev, "failed to set baud rate to %u\n", baud); - if (old_termios) - baud = old_termios->c_ospeed; - else - baud = 9600; - } - - tty_encode_baud_rate(tty, baud, baud); -} - static void cp210x_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) { unsigned int cflag, old_cflag; - unsigned int bits; + unsigned int baud = 0, bits; unsigned int modem_ctl[4]; dbg("%s - port %d", __func__, port->number); @@ -674,9 +591,20 @@ static void cp210x_set_termios(struct tty_struct *tty, tty->termios->c_cflag &= ~CMSPAR; cflag = tty->termios->c_cflag; old_cflag = old_termios->c_cflag; - - if (tty->termios->c_ospeed != old_termios->c_ospeed) - cp210x_change_speed(tty, port, old_termios); + baud = cp210x_quantise_baudrate(tty_get_baud_rate(tty)); + + /* If the baud rate is to be updated*/ + if (baud != tty_termios_baud_rate(old_termios) && baud != 0) { + dbg("%s - Setting baud rate to %d baud", __func__, + baud); + if (cp210x_set_config_single(port, CP210X_SET_BAUDDIV, + ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) { + dbg("Baud rate requested not supported by device"); + baud = tty_termios_baud_rate(old_termios); + } + } + /* Report back the resulting baud rate */ + tty_encode_baud_rate(tty, baud, baud); /* If the number of data bits is to be updated */ if ((cflag & CSIZE) != (old_cflag & CSIZE)) { @@ -856,39 +784,11 @@ static void cp210x_break_ctl (struct tty_struct *tty, int break_state) static int cp210x_startup(struct usb_serial *serial) { - struct cp210x_port_private *port_priv; - int i; - /* cp210x buffers behave strangely unless device is reset */ usb_reset_device(serial->dev); - - for (i = 0; i < serial->num_ports; i++) { - port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); - if (!port_priv) - return -ENOMEM; - - memset(port_priv, 0x00, sizeof(*port_priv)); - port_priv->bInterfaceNumber = - serial->interface->cur_altsetting->desc.bInterfaceNumber; - - usb_set_serial_port_data(serial->port[i], port_priv); - } - return 0; } -static void cp210x_release(struct usb_serial *serial) -{ - struct cp210x_port_private *port_priv; - int i; - - for (i = 0; i < serial->num_ports; i++) { - port_priv = usb_get_serial_port_data(serial->port[i]); - kfree(port_priv); - usb_set_serial_port_data(serial->port[i], NULL); - } -} - static int __init cp210x_init(void) { int retval; diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 149198f671c8..2e06b90aa1f8 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -101,7 +101,6 @@ static int ftdi_jtag_probe(struct usb_serial *serial); static int ftdi_mtxorb_hack_setup(struct usb_serial *serial); static int ftdi_NDI_device_setup(struct usb_serial *serial); static int ftdi_stmclite_probe(struct usb_serial *serial); -static int ftdi_8u2232c_probe(struct usb_serial *serial); static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); @@ -129,10 +128,6 @@ static struct ftdi_sio_quirk ftdi_stmclite_quirk = { .probe = ftdi_stmclite_probe, }; -static struct ftdi_sio_quirk ftdi_8u2232c_quirk = { - .probe = ftdi_8u2232c_probe, -}; - /* * The 8U232AM has the same API as the sio except for: * - it can support MUCH higher baudrates; up to: @@ -156,7 +151,6 @@ static struct ftdi_sio_quirk ftdi_8u2232c_quirk = { * /sys/bus/usb/ftdi_sio/new_id, then send patch/report! */ static struct usb_device_id id_table_combined [] = { - { USB_DEVICE(FTDI_VID, FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CTI_MINI_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CTI_NANO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, @@ -183,11 +177,9 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) , - .driver_info = (kernel_ulong_t)&ftdi_8u2232c_quirk }, + { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, { USB_DEVICE(FTDI_VID, FTDI_4232H_PID) }, { USB_DEVICE(FTDI_VID, FTDI_232H_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_FTX_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, @@ -195,7 +187,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_THROTTLE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GATEWAY_PID) }, { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_PID) }, - { USB_DEVICE(NEWPORT_VID, NEWPORT_AGILIS_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, @@ -209,8 +200,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_XF_640_PID) }, { USB_DEVICE(FTDI_VID, FTDI_XF_642_PID) }, { USB_DEVICE(FTDI_VID, FTDI_DSS20_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_URBAN_0_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_URBAN_1_PID) }, { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) }, { USB_DEVICE(FTDI_VID, FTDI_VNHCPCUSB_D_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MTXORB_0_PID) }, @@ -537,10 +526,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_6_PID) }, { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_7_PID) }, { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_8_PID) }, - { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_1_PID) }, - { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_2_PID) }, - { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_3_PID) }, - { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_4_PID) }, { USB_DEVICE(IDTECH_VID, IDTECH_IDT1221U_PID) }, { USB_DEVICE(OCT_VID, OCT_US101_PID) }, { USB_DEVICE(OCT_VID, OCT_DK201_PID) }, @@ -583,12 +568,9 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TAVIR_STK500_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_TIAO_UMPA_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, /* * ELV devices: */ - { USB_DEVICE(FTDI_ELV_VID, FTDI_ELV_WS300_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_USR_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_MSM1_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_KL100_PID) }, @@ -675,7 +657,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) }, { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) }, { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_OMNI1509) }, { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MHAM_KW_PID) }, @@ -707,7 +688,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, { USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_NZR_SEM_USB_PID) }, { USB_DEVICE(ICOM_VID, ICOM_ID_1_PID) }, { USB_DEVICE(ICOM_VID, ICOM_OPC_U_UC_PID) }, { USB_DEVICE(ICOM_VID, ICOM_ID_RP2C1_PID) }, @@ -741,13 +721,11 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) }, { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_CT29B_PID) }, - { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_RTS01_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_PROPOX_ISPCABLEIII_PID) }, { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID), @@ -760,8 +738,6 @@ static struct usb_device_id id_table_combined [] = { .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(FTDI_VID, LMI_LM3S_ICDI_BOARD_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, @@ -808,38 +784,14 @@ static struct usb_device_id id_table_combined [] = { .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE_AND_INTERFACE_INFO(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID, - USB_CLASS_VENDOR_SPEC, - USB_SUBCLASS_VENDOR_SPEC, 0x00) }, { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) }, - { USB_DEVICE(FTDI_VID, PI_C865_PID) }, - { USB_DEVICE(FTDI_VID, PI_C857_PID) }, - { USB_DEVICE(PI_VID, PI_C866_PID) }, - { USB_DEVICE(PI_VID, PI_C663_PID) }, - { USB_DEVICE(PI_VID, PI_C725_PID) }, - { USB_DEVICE(PI_VID, PI_E517_PID) }, - { USB_DEVICE(PI_VID, PI_C863_PID) }, - { USB_DEVICE(PI_VID, PI_E861_PID) }, - { USB_DEVICE(PI_VID, PI_C867_PID) }, - { USB_DEVICE(PI_VID, PI_E609_PID) }, - { USB_DEVICE(PI_VID, PI_E709_PID) }, - { USB_DEVICE(PI_VID, PI_100F_PID) }, - { USB_DEVICE(PI_VID, PI_1011_PID) }, - { USB_DEVICE(PI_VID, PI_1012_PID) }, - { USB_DEVICE(PI_VID, PI_1013_PID) }, - { USB_DEVICE(PI_VID, PI_1014_PID) }, - { USB_DEVICE(PI_VID, PI_1015_PID) }, - { USB_DEVICE(PI_VID, PI_1016_PID) }, - { USB_DEVICE(KONDO_VID, KONDO_USB_SERIAL_PID) }, { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(FTDI_VID, TI_XDS100V2_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, { USB_DEVICE(FTDI_VID, HAMEG_HO720_PID) }, { USB_DEVICE(FTDI_VID, HAMEG_HO730_PID) }, @@ -871,18 +823,11 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LOGBOOKML_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_CINTERION_MC55I_PID) }, { USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) }, { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(ST_VID, ST_STMCLT1030_PID), .driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk }, - { USB_DEVICE(FTDI_VID, FTDI_RF_R106) }, - { USB_DEVICE(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(FTDI_VID, FTDI_LUMEL_PD12_PID) }, - /* Crucible Devices */ - { USB_DEVICE(FTDI_VID, FTDI_CT_COMET_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; @@ -905,8 +850,7 @@ static const char *ftdi_chip_name[] = { [FT232RL] = "FT232RL", [FT2232H] = "FT2232H", [FT4232H] = "FT4232H", - [FT232H] = "FT232H", - [FTX] = "FT-X" + [FT232H] = "FT232H" }; @@ -1204,8 +1148,7 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty, break; case FT232BM: /* FT232BM chip */ case FT2232C: /* FT2232C chip */ - case FT232RL: /* FT232RL chip */ - case FTX: /* FT-X series */ + case FT232RL: if (baud <= 3000000) { __u16 product_id = le16_to_cpu( port->serial->dev->descriptor.idProduct); @@ -1228,7 +1171,7 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty, case FT2232H: /* FT2232H chip */ case FT4232H: /* FT4232H chip */ case FT232H: /* FT232H chip */ - if ((baud <= 12000000) && (baud >= 1200)) { + if ((baud <= 12000000) & (baud >= 1200)) { div_value = ftdi_2232h_baud_to_divisor(baud); } else if (baud < 1200) { div_value = ftdi_232bm_baud_to_divisor(baud); @@ -1371,7 +1314,8 @@ static int set_serial_info(struct tty_struct *tty, goto check_and_exit; } - if (new_serial.baud_base != priv->baud_base) { + if ((new_serial.baud_base != priv->baud_base) && + (new_serial.baud_base < 9600)) { mutex_unlock(&priv->cfg_lock); return -EINVAL; } @@ -1491,14 +1435,10 @@ static void ftdi_determine_type(struct usb_serial_port *port) } else if (version < 0x900) { /* Assume it's an FT232RL */ priv->chip_type = FT232RL; - } else if (version < 0x1000) { + } else { /* Assume it's an FT232H */ priv->chip_type = FT232H; - } else { - /* Assume it's an FT-X series device */ - priv->chip_type = FTX; } - dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]); } @@ -1626,8 +1566,7 @@ static int create_sysfs_attrs(struct usb_serial_port *port) priv->chip_type == FT232RL || priv->chip_type == FT2232H || priv->chip_type == FT4232H || - priv->chip_type == FT232H || - priv->chip_type == FTX)) { + priv->chip_type == FT232H)) { retval = device_create_file(&port->dev, &dev_attr_latency_timer); } @@ -1649,8 +1588,7 @@ static void remove_sysfs_attrs(struct usb_serial_port *port) priv->chip_type == FT232RL || priv->chip_type == FT2232H || priv->chip_type == FT4232H || - priv->chip_type == FT232H || - priv->chip_type == FTX) { + priv->chip_type == FT232H) { device_remove_file(&port->dev, &dev_attr_latency_timer); } } @@ -1795,19 +1733,6 @@ static int ftdi_jtag_probe(struct usb_serial *serial) return 0; } -static int ftdi_8u2232c_probe(struct usb_serial *serial) -{ - struct usb_device *udev = serial->dev; - - dbg("%s", __func__); - - if ((udev->manufacturer && !strcmp(udev->manufacturer, "CALAO Systems")) || - (udev->product && !strcmp(udev->product, "BeagleBone/XDS100V2"))) - return ftdi_jtag_probe(serial); - - return 0; -} - /* * First and second port on STMCLiteadaptors is reserved for JTAG interface * and the forth port for pio @@ -1867,7 +1792,6 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port) static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) { - struct ktermios dummy; struct usb_device *dev = port->serial->dev; struct ftdi_private *priv = usb_get_serial_port_data(port); int result; @@ -1886,10 +1810,8 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) This is same behaviour as serial.c/rs_open() - Kuba */ /* ftdi_set_termios will send usb control messages */ - if (tty) { - memset(&dummy, 0, sizeof(dummy)); - ftdi_set_termios(tty, port, &dummy); - } + if (tty) + ftdi_set_termios(tty, port, tty->termios); /* Start reading from the device */ result = usb_serial_generic_open(tty, port); @@ -2135,19 +2057,13 @@ static void ftdi_set_termios(struct tty_struct *tty, cflag = termios->c_cflag; - if (old_termios->c_cflag == termios->c_cflag - && old_termios->c_ispeed == termios->c_ispeed - && old_termios->c_ospeed == termios->c_ospeed) - goto no_c_cflag_changes; - + /* FIXME -For this cut I don't care if the line is really changing or + not - so just do the change regardless - should be able to + compare old_termios and tty->termios */ /* NOTE These routines can get interrupted by ftdi_sio_read_bulk_callback - need to examine what this means - don't see any problems yet */ - if ((old_termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)) == - (termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB))) - goto no_data_parity_stop_changes; - /* Set number of data bits, parity, stop bits */ urb_value = 0; @@ -2188,7 +2104,6 @@ static void ftdi_set_termios(struct tty_struct *tty, } /* Now do the baudrate */ -no_data_parity_stop_changes: if ((cflag & CBAUD) == B0) { /* Disable flow control */ if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), @@ -2216,7 +2131,6 @@ no_data_parity_stop_changes: /* Set flow control */ /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */ -no_c_cflag_changes: if (cflag & CRTSCTS) { dbg("%s Setting to CRTSCTS flow control", __func__); if (usb_control_msg(dev, @@ -2307,7 +2221,6 @@ static int ftdi_tiocmget(struct tty_struct *tty) case FT2232H: case FT4232H: case FT232H: - case FTX: len = 2; break; default: diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index ed58c6fa8dbe..19584faa86f9 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -157,8 +157,7 @@ enum ftdi_chip_type { FT232RL = 5, FT2232H = 6, FT4232H = 7, - FT232H = 8, - FTX = 9, + FT232H = 8 }; enum ftdi_sio_baudrate { diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 97e0a6bbcd9e..19156d1049fe 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -23,15 +23,12 @@ #define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ #define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */ #define FTDI_232H_PID 0x6014 /* Single channel hi-speed device */ -#define FTDI_FTX_PID 0x6015 /* FT-X series (FT201X, FT230X, FT231X, etc) */ #define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ #define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ /*** third-party PIDs (using FTDI_VID) ***/ -#define FTDI_LUMEL_PD12_PID 0x6002 - /* * Marvell OpenRD Base, Client * http://www.open-rd.org @@ -42,13 +39,6 @@ /* www.candapter.com Ewert Energy Systems CANdapter device */ #define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ -/* - * Texas Instruments XDS100v2 JTAG / BeagleBone A3 - * http://processors.wiki.ti.com/index.php/XDS100 - * http://beagleboard.org/bone - */ -#define TI_XDS100V2_PID 0xa6d0 - #define FTDI_NXTCAM_PID 0xABB8 /* NXTCam for Mindstorms NXT */ /* US Interface Navigator (http://www.usinterface.com/) */ @@ -64,7 +54,6 @@ /* FTDI 2332C Dual channel device, side A=245 FIFO (JTAG), Side B=RS232 UART */ #define LMI_LM3S_DEVEL_BOARD_PID 0xbcd8 #define LMI_LM3S_EVAL_BOARD_PID 0xbcd9 -#define LMI_LM3S_ICDI_BOARD_PID 0xbcda #define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmbH */ @@ -75,9 +64,6 @@ #define FTDI_OPENDCC_GATEWAY_PID 0xBFDB #define FTDI_OPENDCC_GBM_PID 0xBFDC -/* NZR SEM 16+ USB (http://www.nzr.de) */ -#define FTDI_NZR_SEM_USB_PID 0xC1E0 /* NZR SEM-LOG16+ */ - /* * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) */ @@ -103,8 +89,6 @@ #define FTDI_TACTRIX_OPENPORT_13S_PID 0xCC49 /* OpenPort 1.3 Subaru */ #define FTDI_TACTRIX_OPENPORT_13U_PID 0xCC4A /* OpenPort 1.3 Universal */ -#define FTDI_DISTORTEC_JTAG_LOCK_PICK_PID 0xCFF8 - /* SCS HF Radio Modems PID's (http://www.scs-ptc.com) */ /* the VID is the standard ftdi vid (FTDI_VID) */ #define FTDI_SCS_DEVICE_0_PID 0xD010 /* SCS PTC-IIusb */ @@ -127,7 +111,6 @@ /* Propox devices */ #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 -#define FTDI_PROPOX_ISPCABLEIII_PID 0xD739 /* Lenz LI-USB Computer Interface. */ #define FTDI_LENZ_LIUSB_PID 0xD780 @@ -147,11 +130,6 @@ #define XSENS_CONVERTER_6_PID 0xD38E #define XSENS_CONVERTER_7_PID 0xD38F -/** - * Zolix (www.zolix.com.cb) product ids - */ -#define FTDI_OMNI1509 0xD491 /* Omni1509 embedded USB-serial */ - /* * NDI (www.ndigital.com) product ids */ @@ -209,7 +187,7 @@ /* * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). - * Almost all of these devices use FTDI's vendor ID (0x0403). + * All of these devices use FTDI's vendor ID (0x0403). * Further IDs taken from ELV Windows .inf file. * * The previously included PID for the UO 100 module was incorrect. @@ -217,8 +195,6 @@ * * Armin Laeuger originally sent the PID for the UM 100 module. */ -#define FTDI_ELV_VID 0x1B1F /* ELV AG */ -#define FTDI_ELV_WS300_PID 0xC006 /* eQ3 WS 300 PC II */ #define FTDI_ELV_USR_PID 0xE000 /* ELV Universal-Sound-Recorder */ #define FTDI_ELV_MSM1_PID 0xE001 /* ELV Mini-Sound-Modul */ #define FTDI_ELV_KL100_PID 0xE002 /* ELV Kfz-Leistungsmesser KL 100 */ @@ -444,11 +420,9 @@ #define PROTEGO_SPECIAL_4 0xFC73 /* special/unknown device */ /* - * Sony Ericsson product ids + * DSS-20 Sync Station for Sony Ericsson P800 */ -#define FTDI_DSS20_PID 0xFC82 /* DSS-20 Sync Station for Sony Ericsson P800 */ -#define FTDI_URBAN_0_PID 0xFC8A /* Sony Ericsson Urban, uart #0 */ -#define FTDI_URBAN_1_PID 0xFC8B /* Sony Ericsson Urban, uart #1 */ +#define FTDI_DSS20_PID 0xFC82 /* www.irtrans.de device */ #define FTDI_IRTRANS_PID 0xFC60 /* Product Id */ @@ -524,11 +498,6 @@ */ #define FTDI_TAVIR_STK500_PID 0xFA33 /* STK500 AVR programmer */ -/* - * TIAO product ids (FTDI_VID) - * http://www.tiaowiki.com/w/Main_Page - */ -#define FTDI_TIAO_UMPA_PID 0x8a98 /* TIAO/DIYGADGET USB Multi-Protocol Adapter */ /********************************/ @@ -551,19 +520,6 @@ #define ADI_GNICE_PID 0xF000 #define ADI_GNICEPLUS_PID 0xF001 -/* - * Microchip Technology, Inc. - * - * MICROCHIP_VID (0x04D8) and MICROCHIP_USB_BOARD_PID (0x000A) are - * used by single function CDC ACM class based firmware demo - * applications. The VID/PID has also been used in firmware - * emulating FTDI serial chips by: - * Hornby Elite - Digital Command Control Console - * http://www.hornby.com/hornby-dcc/controllers/ - */ -#define MICROCHIP_VID 0x04D8 -#define MICROCHIP_USB_BOARD_PID 0x000A /* CDC RS-232 Emulation Demo */ - /* * RATOC REX-USB60F */ @@ -707,10 +663,6 @@ #define SEALEVEL_2803_6_PID 0X2863 /* SeaLINK+8 (2803) Port 6 */ #define SEALEVEL_2803_7_PID 0X2873 /* SeaLINK+8 (2803) Port 7 */ #define SEALEVEL_2803_8_PID 0X2883 /* SeaLINK+8 (2803) Port 8 */ -#define SEALEVEL_2803R_1_PID 0Xa02a /* SeaLINK+8 (2803-ROHS) Port 1+2 */ -#define SEALEVEL_2803R_2_PID 0Xa02b /* SeaLINK+8 (2803-ROHS) Port 3+4 */ -#define SEALEVEL_2803R_3_PID 0Xa02c /* SeaLINK+8 (2803-ROHS) Port 5+6 */ -#define SEALEVEL_2803R_4_PID 0Xa02d /* SeaLINK+8 (2803-ROHS) Port 7+8 */ /* * JETI SPECTROMETER SPECBOS 1201 @@ -759,12 +711,6 @@ #define TTI_VID 0x103E /* Vendor Id */ #define TTI_QL355P_PID 0x03E8 /* TTi QL355P power supply */ -/* - * Newport Cooperation (www.newport.com) - */ -#define NEWPORT_VID 0x104D -#define NEWPORT_AGILIS_PID 0x3000 - /* Interbiometrics USB I/O Board */ /* Developed for Interbiometrics by Rudolf Gugler */ #define INTERBIOMETRICS_VID 0x1209 @@ -808,41 +754,6 @@ #define RTSYSTEMS_VID 0x2100 /* Vendor ID */ #define RTSYSTEMS_SERIAL_VX7_PID 0x9e52 /* Serial converter for VX-7 Radios using FT232RL */ #define RTSYSTEMS_CT29B_PID 0x9e54 /* CT29B Radio Cable */ -#define RTSYSTEMS_RTS01_PID 0x9e57 /* USB-RTS01 Radio Cable */ - - -/* - * Physik Instrumente - * http://www.physikinstrumente.com/en/products/ - */ -/* These two devices use the VID of FTDI */ -#define PI_C865_PID 0xe0a0 /* PI C-865 Piezomotor Controller */ -#define PI_C857_PID 0xe0a1 /* PI Encoder Trigger Box */ - -#define PI_VID 0x1a72 /* Vendor ID */ -#define PI_C866_PID 0x1000 /* PI C-866 Piezomotor Controller */ -#define PI_C663_PID 0x1001 /* PI C-663 Mercury-Step */ -#define PI_C725_PID 0x1002 /* PI C-725 Piezomotor Controller */ -#define PI_E517_PID 0x1005 /* PI E-517 Digital Piezo Controller Operation Module */ -#define PI_C863_PID 0x1007 /* PI C-863 */ -#define PI_E861_PID 0x1008 /* PI E-861 Piezomotor Controller */ -#define PI_C867_PID 0x1009 /* PI C-867 Piezomotor Controller */ -#define PI_E609_PID 0x100D /* PI E-609 Digital Piezo Controller */ -#define PI_E709_PID 0x100E /* PI E-709 Digital Piezo Controller */ -#define PI_100F_PID 0x100F /* PI Digital Piezo Controller */ -#define PI_1011_PID 0x1011 /* PI Digital Piezo Controller */ -#define PI_1012_PID 0x1012 /* PI Motion Controller */ -#define PI_1013_PID 0x1013 /* PI Motion Controller */ -#define PI_1014_PID 0x1014 /* PI Device */ -#define PI_1015_PID 0x1015 /* PI Device */ -#define PI_1016_PID 0x1016 /* PI Digital Servo Module */ - -/* - * Kondo Kagaku Co.Ltd. - * http://www.kondo-robot.com/EN - */ -#define KONDO_VID 0x165c -#define KONDO_USB_SERIAL_PID 0x0002 /* * Bayer Ascensia Contour blood glucose meter USB-converter cable. @@ -1248,27 +1159,4 @@ /* USB-Nano-485*/ #define FTDI_CTI_NANO_PID 0xF60B -/* - * ZeitControl cardsystems GmbH rfid-readers http://zeitconrol.de - */ -/* TagTracer MIFARE*/ -#define FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID 0xF7C0 -/* - * Rainforest Automation - */ -/* ZigBee controller */ -#define FTDI_RF_R106 0x8A28 - -/* - * Product: HCP HIT GPRS modem - * Manufacturer: HCP d.o.o. - * ATI command output: Cinterion MC55i - */ -#define FTDI_CINTERION_MC55I_PID 0xA951 - -/* - * Product: Comet Caller ID decoder - * Manufacturer: Crucible Technologies - */ -#define FTDI_CT_COMET_PID 0x8e08 diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 9f0b2bff8ee4..e4db5ad2bc55 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -215,10 +215,8 @@ retry: clear_bit(i, &port->write_urbs_free); result = usb_submit_urb(urb, GFP_ATOMIC); if (result) { - if (!port->port.console) { - dev_err(&port->dev, "%s - error submitting urb: %d\n", + dev_err(&port->dev, "%s - error submitting urb: %d\n", __func__, result); - } set_bit(i, &port->write_urbs_free); spin_lock_irqsave(&port->lock, flags); port->tx_bytes -= count; diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 8a90d58ee96d..0aac00afb5c8 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -2677,7 +2677,15 @@ cleanup: static void edge_disconnect(struct usb_serial *serial) { + int i; + struct edgeport_port *edge_port; + dbg("%s", __func__); + + for (i = 0; i < serial->num_ports; ++i) { + edge_port = usb_get_serial_port_data(serial->port[i]); + edge_remove_sysfs_attrs(edge_port->port); + } } static void edge_release(struct usb_serial *serial) @@ -2756,7 +2764,6 @@ static struct usb_serial_driver edgeport_1port_device = { .disconnect = edge_disconnect, .release = edge_release, .port_probe = edge_create_sysfs_attrs, - .port_remove = edge_remove_sysfs_attrs, .ioctl = edge_ioctl, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, @@ -2788,7 +2795,6 @@ static struct usb_serial_driver edgeport_2port_device = { .disconnect = edge_disconnect, .release = edge_release, .port_probe = edge_create_sysfs_attrs, - .port_remove = edge_remove_sysfs_attrs, .ioctl = edge_ioctl, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index d3addb2952e4..ba0d28727ccb 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -359,16 +359,13 @@ static int mct_u232_set_modem_ctrl(struct usb_serial *serial, MCT_U232_SET_REQUEST_TYPE, 0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE, WDR_TIMEOUT); - kfree(buf); - - dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr); - - if (rc < 0) { + if (rc < 0) dev_err(&serial->dev->dev, "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc); - return rc; - } - return 0; + dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr); + + kfree(buf); + return rc; } /* mct_u232_set_modem_ctrl */ static int mct_u232_get_modem_stat(struct usb_serial *serial, @@ -577,14 +574,12 @@ static void mct_u232_close(struct usb_serial_port *port) { dbg("%s port %d", __func__, port->number); - /* - * Must kill the read urb as it is actually an interrupt urb, which - * generic close thus fails to kill. - */ - usb_kill_urb(port->read_urb); - usb_kill_urb(port->interrupt_in_urb); - - usb_serial_generic_close(port); + if (port->serial->dev) { + /* shutdown our urbs */ + usb_kill_urb(port->write_urb); + usb_kill_urb(port->read_urb); + usb_kill_urb(port->interrupt_in_urb); + } } /* mct_u232_close */ diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 995e56c93bf8..7b50aa122752 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -174,7 +174,6 @@ #define CLK_MULTI_REGISTER ((__u16)(0x02)) #define CLK_START_VALUE_REGISTER ((__u16)(0x03)) -#define GPIO_REGISTER ((__u16)(0x07)) #define SERIAL_LCR_DLAB ((__u16)(0x0080)) @@ -206,7 +205,7 @@ static const struct usb_device_id moschip_port_id_table[] = { {} /* terminating entry */ }; -static const struct usb_device_id moschip_id_table_combined[] = { +static const struct usb_device_id moschip_id_table_combined[] __devinitconst = { {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, @@ -235,10 +234,12 @@ struct moschip_port { int port_num; /*Actual port number in the device(1,2,etc) */ struct urb *write_urb; /* write URB for this port */ struct urb *read_urb; /* read URB for this port */ + struct urb *int_urb; __u8 shadowLCR; /* last LCR value received */ __u8 shadowMCR; /* last MCR value received */ char open; char open_ports; + char zombie; wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ int delta_msr_cond; @@ -503,6 +504,7 @@ static void mos7840_control_callback(struct urb *urb) unsigned char *data; struct moschip_port *mos7840_port; __u8 regval = 0x0; + int result = 0; int status = urb->status; mos7840_port = urb->context; @@ -521,7 +523,7 @@ static void mos7840_control_callback(struct urb *urb) default: dbg("%s - nonzero urb status received: %d", __func__, status); - return; + goto exit; } dbg("%s urb buffer size is %d", __func__, urb->actual_length); @@ -534,6 +536,17 @@ static void mos7840_control_callback(struct urb *urb) mos7840_handle_new_msr(mos7840_port, regval); else if (mos7840_port->MsrLsr == 1) mos7840_handle_new_lsr(mos7840_port, regval); + +exit: + spin_lock(&mos7840_port->pool_lock); + if (!mos7840_port->zombie) + result = usb_submit_urb(mos7840_port->int_urb, GFP_ATOMIC); + spin_unlock(&mos7840_port->pool_lock); + if (result) { + dev_err(&urb->dev->dev, + "%s - Error %d submitting interrupt urb\n", + __func__, result); + } } static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg, @@ -641,7 +654,14 @@ static void mos7840_interrupt_callback(struct urb *urb) wreg = MODEM_STATUS_REGISTER; break; } - rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data); + spin_lock(&mos7840_port->pool_lock); + if (!mos7840_port->zombie) { + rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data); + } else { + spin_unlock(&mos7840_port->pool_lock); + return; + } + spin_unlock(&mos7840_port->pool_lock); } } } @@ -1083,25 +1103,14 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) mos7840_port->read_urb = port->read_urb; /* set up our bulk in urb */ - if ((serial->num_ports == 2) - && ((((__u16)port->number - - (__u16)(port->serial->minor)) % 2) != 0)) { - usb_fill_bulk_urb(mos7840_port->read_urb, - serial->dev, - usb_rcvbulkpipe(serial->dev, - (port->bulk_in_endpointAddress) + 2), - port->bulk_in_buffer, - mos7840_port->read_urb->transfer_buffer_length, - mos7840_bulk_in_callback, mos7840_port); - } else { - usb_fill_bulk_urb(mos7840_port->read_urb, - serial->dev, - usb_rcvbulkpipe(serial->dev, - port->bulk_in_endpointAddress), - port->bulk_in_buffer, - mos7840_port->read_urb->transfer_buffer_length, - mos7840_bulk_in_callback, mos7840_port); - } + + usb_fill_bulk_urb(mos7840_port->read_urb, + serial->dev, + usb_rcvbulkpipe(serial->dev, + port->bulk_in_endpointAddress), + port->bulk_in_buffer, + mos7840_port->read_urb->transfer_buffer_length, + mos7840_bulk_in_callback, mos7840_port); dbg("mos7840_open: bulkin endpoint is %d", port->bulk_in_endpointAddress); @@ -1170,12 +1179,9 @@ static int mos7840_chars_in_buffer(struct tty_struct *tty) } spin_lock_irqsave(&mos7840_port->pool_lock, flags); - for (i = 0; i < NUM_URBS; ++i) { - if (mos7840_port->busy[i]) { - struct urb *urb = mos7840_port->write_urb_pool[i]; - chars += urb->transfer_buffer_length; - } - } + for (i = 0; i < NUM_URBS; ++i) + if (mos7840_port->busy[i]) + chars += URB_TRANSFER_BUFFER_SIZE; spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); dbg("%s - returns %d", __func__, chars); return chars; @@ -1515,25 +1521,13 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, memcpy(urb->transfer_buffer, current_position, transfer_size); /* fill urb with data and submit */ - if ((serial->num_ports == 2) - && ((((__u16)port->number - - (__u16)(port->serial->minor)) % 2) != 0)) { - usb_fill_bulk_urb(urb, - serial->dev, - usb_sndbulkpipe(serial->dev, - (port->bulk_out_endpointAddress) + 2), - urb->transfer_buffer, - transfer_size, - mos7840_bulk_out_data_callback, mos7840_port); - } else { - usb_fill_bulk_urb(urb, - serial->dev, - usb_sndbulkpipe(serial->dev, - port->bulk_out_endpointAddress), - urb->transfer_buffer, - transfer_size, - mos7840_bulk_out_data_callback, mos7840_port); - } + usb_fill_bulk_urb(urb, + serial->dev, + usb_sndbulkpipe(serial->dev, + port->bulk_out_endpointAddress), + urb->transfer_buffer, + transfer_size, + mos7840_bulk_out_data_callback, mos7840_port); data1 = urb->transfer_buffer; dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress); @@ -1846,7 +1840,7 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port, } else { #ifdef HW_flow_control - /* setting h/w flow control bit to 0 */ + / *setting h/w flow control bit to 0 */ Data = 0xb; mos7840_port->shadowMCR = Data; status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, @@ -2316,26 +2310,19 @@ static int mos7840_ioctl(struct tty_struct *tty, static int mos7840_calc_num_ports(struct usb_serial *serial) { - __u16 Data = 0x00; - int ret = 0; - int mos7840_num_ports; - - ret = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &Data, - VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT); - - if ((Data & 0x01) == 0) { - mos7840_num_ports = 2; - serial->num_bulk_in = 2; - serial->num_bulk_out = 2; - serial->num_ports = 2; - } else { - mos7840_num_ports = 4; + int mos7840_num_ports = 0; + + dbg("numberofendpoints: cur %d, alt %d", + (int)serial->interface->cur_altsetting->desc.bNumEndpoints, + (int)serial->interface->altsetting->desc.bNumEndpoints); + if (serial->interface->cur_altsetting->desc.bNumEndpoints == 5) { + mos7840_num_ports = serial->num_ports = 2; + } else if (serial->interface->cur_altsetting->desc.bNumEndpoints == 9) { serial->num_bulk_in = 4; serial->num_bulk_out = 4; - serial->num_ports = 4; + mos7840_num_ports = serial->num_ports = 4; } - + dbg ("mos7840_num_ports = %d", mos7840_num_ports); return mos7840_num_ports; } @@ -2574,6 +2561,7 @@ error: kfree(mos7840_port->ctrl_buf); usb_free_urb(mos7840_port->control_urb); kfree(mos7840_port); + serial->port[i] = NULL; } return status; } @@ -2586,6 +2574,7 @@ error: static void mos7840_disconnect(struct usb_serial *serial) { int i; + unsigned long flags; struct moschip_port *mos7840_port; dbg("%s", " disconnect :entering.........."); @@ -2603,6 +2592,9 @@ static void mos7840_disconnect(struct usb_serial *serial) mos7840_port = mos7840_get_port_private(serial->port[i]); dbg ("mos7840_port %d = %p", i, mos7840_port); if (mos7840_port) { + spin_lock_irqsave(&mos7840_port->pool_lock, flags); + mos7840_port->zombie = 1; + spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); usb_kill_urb(mos7840_port->control_urb); } } @@ -2636,7 +2628,6 @@ static void mos7840_release(struct usb_serial *serial) mos7840_port = mos7840_get_port_private(serial->port[i]); dbg("mos7840_port %d = %p", i, mos7840_port); if (mos7840_port) { - usb_free_urb(mos7840_port->control_urb); kfree(mos7840_port->ctrl_buf); kfree(mos7840_port->dr); kfree(mos7840_port); diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 0a8c1e64b247..60f38d5e64fc 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -315,7 +315,7 @@ static int omninet_write_room(struct tty_struct *tty) int room = 0; /* Default: no room */ /* FIXME: no consistent locking for write_urb_busy */ - if (!wport->write_urb_busy) + if (wport->write_urb_busy) room = wport->bulk_out_size - OMNINET_HEADERLEN; dbg("%s - returns %d", __func__, room); diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 5d274b35582c..96423f3c8ef3 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -160,11 +160,7 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype, { struct usb_serial *serial = port->serial; int retval; - u8 *buffer; - - buffer = kzalloc(1, GFP_KERNEL); - if (!buffer) - return -ENOMEM; + u8 buffer[2]; buffer[0] = val; /* Send the message to the vendor control endpoint @@ -173,7 +169,6 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype, requesttype, USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, 0, 0, buffer, 1, 0); - kfree(buffer); return retval; } @@ -297,7 +292,7 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, if (!dr) { dev_err(&port->dev, "out of memory\n"); count = -ENOMEM; - goto error_no_dr; + goto error; } dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT; @@ -327,8 +322,6 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, return count; error: - kfree(dr); -error_no_dr: usb_free_urb(urb); error_no_urb: kfree(buffer); diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 52cd814176a7..60b25d8ea0e2 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -47,7 +47,6 @@ /* Function prototypes */ static int option_probe(struct usb_serial *serial, const struct usb_device_id *id); -static void option_release(struct usb_serial *serial); static int option_send_setup(struct usb_serial_port *port); static void option_instat_callback(struct urb *urb); @@ -80,10 +79,77 @@ static void option_instat_callback(struct urb *urb); #define OPTION_PRODUCT_GTM380_MODEM 0x7201 #define HUAWEI_VENDOR_ID 0x12D1 -#define HUAWEI_PRODUCT_E173 0x140C +#define HUAWEI_PRODUCT_E600 0x1001 +#define HUAWEI_PRODUCT_E220 0x1003 +#define HUAWEI_PRODUCT_E220BIS 0x1004 +#define HUAWEI_PRODUCT_E1401 0x1401 +#define HUAWEI_PRODUCT_E1402 0x1402 +#define HUAWEI_PRODUCT_E1403 0x1403 +#define HUAWEI_PRODUCT_E1404 0x1404 +#define HUAWEI_PRODUCT_E1405 0x1405 +#define HUAWEI_PRODUCT_E1406 0x1406 +#define HUAWEI_PRODUCT_E1407 0x1407 +#define HUAWEI_PRODUCT_E1408 0x1408 +#define HUAWEI_PRODUCT_E1409 0x1409 +#define HUAWEI_PRODUCT_E140A 0x140A +#define HUAWEI_PRODUCT_E140B 0x140B +#define HUAWEI_PRODUCT_E140C 0x140C +#define HUAWEI_PRODUCT_E140D 0x140D +#define HUAWEI_PRODUCT_E140E 0x140E +#define HUAWEI_PRODUCT_E140F 0x140F +#define HUAWEI_PRODUCT_E1410 0x1410 +#define HUAWEI_PRODUCT_E1411 0x1411 +#define HUAWEI_PRODUCT_E1412 0x1412 +#define HUAWEI_PRODUCT_E1413 0x1413 +#define HUAWEI_PRODUCT_E1414 0x1414 +#define HUAWEI_PRODUCT_E1415 0x1415 +#define HUAWEI_PRODUCT_E1416 0x1416 +#define HUAWEI_PRODUCT_E1417 0x1417 +#define HUAWEI_PRODUCT_E1418 0x1418 +#define HUAWEI_PRODUCT_E1419 0x1419 +#define HUAWEI_PRODUCT_E141A 0x141A +#define HUAWEI_PRODUCT_E141B 0x141B +#define HUAWEI_PRODUCT_E141C 0x141C +#define HUAWEI_PRODUCT_E141D 0x141D +#define HUAWEI_PRODUCT_E141E 0x141E +#define HUAWEI_PRODUCT_E141F 0x141F +#define HUAWEI_PRODUCT_E1420 0x1420 +#define HUAWEI_PRODUCT_E1421 0x1421 +#define HUAWEI_PRODUCT_E1422 0x1422 +#define HUAWEI_PRODUCT_E1423 0x1423 +#define HUAWEI_PRODUCT_E1424 0x1424 +#define HUAWEI_PRODUCT_E1425 0x1425 +#define HUAWEI_PRODUCT_E1426 0x1426 +#define HUAWEI_PRODUCT_E1427 0x1427 +#define HUAWEI_PRODUCT_E1428 0x1428 +#define HUAWEI_PRODUCT_E1429 0x1429 +#define HUAWEI_PRODUCT_E142A 0x142A +#define HUAWEI_PRODUCT_E142B 0x142B +#define HUAWEI_PRODUCT_E142C 0x142C +#define HUAWEI_PRODUCT_E142D 0x142D +#define HUAWEI_PRODUCT_E142E 0x142E +#define HUAWEI_PRODUCT_E142F 0x142F +#define HUAWEI_PRODUCT_E1430 0x1430 +#define HUAWEI_PRODUCT_E1431 0x1431 +#define HUAWEI_PRODUCT_E1432 0x1432 +#define HUAWEI_PRODUCT_E1433 0x1433 +#define HUAWEI_PRODUCT_E1434 0x1434 +#define HUAWEI_PRODUCT_E1435 0x1435 +#define HUAWEI_PRODUCT_E1436 0x1436 +#define HUAWEI_PRODUCT_E1437 0x1437 +#define HUAWEI_PRODUCT_E1438 0x1438 +#define HUAWEI_PRODUCT_E1439 0x1439 +#define HUAWEI_PRODUCT_E143A 0x143A +#define HUAWEI_PRODUCT_E143B 0x143B +#define HUAWEI_PRODUCT_E143C 0x143C +#define HUAWEI_PRODUCT_E143D 0x143D +#define HUAWEI_PRODUCT_E143E 0x143E +#define HUAWEI_PRODUCT_E143F 0x143F #define HUAWEI_PRODUCT_K4505 0x1464 #define HUAWEI_PRODUCT_K3765 0x1465 -#define HUAWEI_PRODUCT_K4605 0x14C6 +#define HUAWEI_PRODUCT_E14AC 0x14AC +#define HUAWEI_PRODUCT_ETS1220 0x1803 +#define HUAWEI_PRODUCT_E353 0x1506 #define QUANTA_VENDOR_ID 0x0408 #define QUANTA_PRODUCT_Q101 0xEA02 @@ -158,11 +224,9 @@ static void option_instat_callback(struct urb *urb); #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0x8001 #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000 #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001 -#define NOVATELWIRELESS_PRODUCT_E362 0x9010 #define NOVATELWIRELESS_PRODUCT_G1 0xA001 #define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 #define NOVATELWIRELESS_PRODUCT_G2 0xA010 -#define NOVATELWIRELESS_PRODUCT_MC551 0xB001 /* AMOI PRODUCTS */ #define AMOI_VENDOR_ID 0x1614 @@ -194,9 +258,6 @@ static void option_instat_callback(struct urb *urb); #define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181 #define DELL_PRODUCT_5730_MINICARD_VZW 0x8182 -#define DELL_PRODUCT_5800_MINICARD_VZW 0x8195 /* Novatel E362 */ -#define DELL_PRODUCT_5800_V2_MINICARD_VZW 0x8196 /* Novatel E362 */ - #define KYOCERA_VENDOR_ID 0x0c88 #define KYOCERA_PRODUCT_KPC650 0x17da #define KYOCERA_PRODUCT_KPC680 0x180a @@ -239,10 +300,6 @@ static void option_instat_callback(struct urb *urb); #define TELIT_VENDOR_ID 0x1bc7 #define TELIT_PRODUCT_UC864E 0x1003 #define TELIT_PRODUCT_UC864G 0x1004 -#define TELIT_PRODUCT_CC864_DUAL 0x1005 -#define TELIT_PRODUCT_CC864_SINGLE 0x1006 -#define TELIT_PRODUCT_DE910_DUAL 0x1010 -#define TELIT_PRODUCT_LE920 0x1200 /* ZTE PRODUCTS */ #define ZTE_VENDOR_ID 0x19d2 @@ -253,9 +310,6 @@ static void option_instat_callback(struct urb *urb); #define ZTE_PRODUCT_AC8710 0xfff1 #define ZTE_PRODUCT_AC2726 0xfff5 #define ZTE_PRODUCT_AC8710T 0xffff -#define ZTE_PRODUCT_MC2718 0xffe8 -#define ZTE_PRODUCT_AD3812 0xffeb -#define ZTE_PRODUCT_MC2716 0xffed #define BENQ_VENDOR_ID 0x04a5 #define BENQ_PRODUCT_H10 0x4068 @@ -288,8 +342,6 @@ static void option_instat_callback(struct urb *urb); /* ALCATEL PRODUCTS */ #define ALCATEL_VENDOR_ID 0x1bbb #define ALCATEL_PRODUCT_X060S_X200 0x0000 -#define ALCATEL_PRODUCT_X220_X500D 0x0017 -#define ALCATEL_PRODUCT_L100V 0x011e #define PIRELLI_VENDOR_ID 0x1266 #define PIRELLI_PRODUCT_C100_1 0x1002 @@ -360,104 +412,6 @@ static void option_instat_callback(struct urb *urb); #define SAMSUNG_VENDOR_ID 0x04e8 #define SAMSUNG_PRODUCT_GT_B3730 0x6889 -/* YUGA products www.yuga-info.com gavin.kx@qq.com */ -#define YUGA_VENDOR_ID 0x257A -#define YUGA_PRODUCT_CEM600 0x1601 -#define YUGA_PRODUCT_CEM610 0x1602 -#define YUGA_PRODUCT_CEM500 0x1603 -#define YUGA_PRODUCT_CEM510 0x1604 -#define YUGA_PRODUCT_CEM800 0x1605 -#define YUGA_PRODUCT_CEM900 0x1606 - -#define YUGA_PRODUCT_CEU818 0x1607 -#define YUGA_PRODUCT_CEU816 0x1608 -#define YUGA_PRODUCT_CEU828 0x1609 -#define YUGA_PRODUCT_CEU826 0x160A -#define YUGA_PRODUCT_CEU518 0x160B -#define YUGA_PRODUCT_CEU516 0x160C -#define YUGA_PRODUCT_CEU528 0x160D -#define YUGA_PRODUCT_CEU526 0x160F -#define YUGA_PRODUCT_CEU881 0x161F -#define YUGA_PRODUCT_CEU882 0x162F - -#define YUGA_PRODUCT_CWM600 0x2601 -#define YUGA_PRODUCT_CWM610 0x2602 -#define YUGA_PRODUCT_CWM500 0x2603 -#define YUGA_PRODUCT_CWM510 0x2604 -#define YUGA_PRODUCT_CWM800 0x2605 -#define YUGA_PRODUCT_CWM900 0x2606 - -#define YUGA_PRODUCT_CWU718 0x2607 -#define YUGA_PRODUCT_CWU716 0x2608 -#define YUGA_PRODUCT_CWU728 0x2609 -#define YUGA_PRODUCT_CWU726 0x260A -#define YUGA_PRODUCT_CWU518 0x260B -#define YUGA_PRODUCT_CWU516 0x260C -#define YUGA_PRODUCT_CWU528 0x260D -#define YUGA_PRODUCT_CWU581 0x260E -#define YUGA_PRODUCT_CWU526 0x260F -#define YUGA_PRODUCT_CWU582 0x261F -#define YUGA_PRODUCT_CWU583 0x262F - -#define YUGA_PRODUCT_CLM600 0x3601 -#define YUGA_PRODUCT_CLM610 0x3602 -#define YUGA_PRODUCT_CLM500 0x3603 -#define YUGA_PRODUCT_CLM510 0x3604 -#define YUGA_PRODUCT_CLM800 0x3605 -#define YUGA_PRODUCT_CLM900 0x3606 - -#define YUGA_PRODUCT_CLU718 0x3607 -#define YUGA_PRODUCT_CLU716 0x3608 -#define YUGA_PRODUCT_CLU728 0x3609 -#define YUGA_PRODUCT_CLU726 0x360A -#define YUGA_PRODUCT_CLU518 0x360B -#define YUGA_PRODUCT_CLU516 0x360C -#define YUGA_PRODUCT_CLU528 0x360D -#define YUGA_PRODUCT_CLU526 0x360F - -/* Viettel products */ -#define VIETTEL_VENDOR_ID 0x2262 -#define VIETTEL_PRODUCT_VT1000 0x0002 - -/* ZD Incorporated */ -#define ZD_VENDOR_ID 0x0685 -#define ZD_PRODUCT_7000 0x7000 - -/* LG products */ -#define LG_VENDOR_ID 0x1004 -#define LG_PRODUCT_L02C 0x618f - -/* MediaTek products */ -#define MEDIATEK_VENDOR_ID 0x0e8d -#define MEDIATEK_PRODUCT_DC_1COM 0x00a0 -#define MEDIATEK_PRODUCT_DC_4COM 0x00a5 -#define MEDIATEK_PRODUCT_DC_4COM2 0x00a7 -#define MEDIATEK_PRODUCT_DC_5COM 0x00a4 -#define MEDIATEK_PRODUCT_7208_1COM 0x7101 -#define MEDIATEK_PRODUCT_7208_2COM 0x7102 -#define MEDIATEK_PRODUCT_7103_2COM 0x7103 -#define MEDIATEK_PRODUCT_7106_2COM 0x7106 -#define MEDIATEK_PRODUCT_FP_1COM 0x0003 -#define MEDIATEK_PRODUCT_FP_2COM 0x0023 -#define MEDIATEK_PRODUCT_FPDC_1COM 0x0043 -#define MEDIATEK_PRODUCT_FPDC_2COM 0x0033 - -/* Cellient products */ -#define CELLIENT_VENDOR_ID 0x2692 -#define CELLIENT_PRODUCT_MEN200 0x9005 - -/* Hyundai Petatel Inc. products */ -#define PETATEL_VENDOR_ID 0x1ff4 -#define PETATEL_PRODUCT_NP10T 0x600e - -/* TP-LINK Incorporated products */ -#define TPLINK_VENDOR_ID 0x2357 -#define TPLINK_PRODUCT_MA180 0x0201 - -/* Changhong products */ -#define CHANGHONG_VENDOR_ID 0x2077 -#define CHANGHONG_PRODUCT_CH690 0x7001 - /* some devices interfaces need special handling due to a number of reasons */ enum option_blacklist_reason { OPTION_BLACKLIST_NONE = 0, @@ -465,83 +419,31 @@ enum option_blacklist_reason { OPTION_BLACKLIST_RESERVED_IF = 2 }; -#define MAX_BL_NUM 8 struct option_blacklist_info { - /* bitfield of interface numbers for OPTION_BLACKLIST_SENDSETUP */ - const unsigned long sendsetup; - /* bitfield of interface numbers for OPTION_BLACKLIST_RESERVED_IF */ - const unsigned long reserved; + const u32 infolen; /* number of interface numbers on blacklist */ + const u8 *ifaceinfo; /* pointer to the array holding the numbers */ + enum option_blacklist_reason reason; }; +static const u8 four_g_w14_no_sendsetup[] = { 0, 1 }; static const struct option_blacklist_info four_g_w14_blacklist = { - .sendsetup = BIT(0) | BIT(1), + .infolen = ARRAY_SIZE(four_g_w14_no_sendsetup), + .ifaceinfo = four_g_w14_no_sendsetup, + .reason = OPTION_BLACKLIST_SENDSETUP }; +static const u8 alcatel_x200_no_sendsetup[] = { 0, 1 }; static const struct option_blacklist_info alcatel_x200_blacklist = { - .sendsetup = BIT(0) | BIT(1), -}; - -static const struct option_blacklist_info zte_0037_blacklist = { - .sendsetup = BIT(0) | BIT(1), + .infolen = ARRAY_SIZE(alcatel_x200_no_sendsetup), + .ifaceinfo = alcatel_x200_no_sendsetup, + .reason = OPTION_BLACKLIST_SENDSETUP }; +static const u8 zte_k3765_z_no_sendsetup[] = { 0, 1, 2 }; static const struct option_blacklist_info zte_k3765_z_blacklist = { - .sendsetup = BIT(0) | BIT(1) | BIT(2), - .reserved = BIT(4), -}; - -static const struct option_blacklist_info zte_ad3812_z_blacklist = { - .sendsetup = BIT(0) | BIT(1) | BIT(2), -}; - -static const struct option_blacklist_info zte_mc2718_z_blacklist = { - .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4), -}; - -static const struct option_blacklist_info zte_mc2716_z_blacklist = { - .sendsetup = BIT(1) | BIT(2) | BIT(3), -}; - -static const struct option_blacklist_info huawei_cdc12_blacklist = { - .reserved = BIT(1) | BIT(2), -}; - -static const struct option_blacklist_info net_intf1_blacklist = { - .reserved = BIT(1), -}; - -static const struct option_blacklist_info net_intf2_blacklist = { - .reserved = BIT(2), -}; - -static const struct option_blacklist_info net_intf3_blacklist = { - .reserved = BIT(3), -}; - -static const struct option_blacklist_info net_intf4_blacklist = { - .reserved = BIT(4), -}; - -static const struct option_blacklist_info net_intf5_blacklist = { - .reserved = BIT(5), -}; - -static const struct option_blacklist_info net_intf6_blacklist = { - .reserved = BIT(6), -}; - -static const struct option_blacklist_info zte_mf626_blacklist = { - .sendsetup = BIT(0) | BIT(1), - .reserved = BIT(4), -}; - -static const struct option_blacklist_info zte_1255_blacklist = { - .reserved = BIT(3) | BIT(4), -}; - -static const struct option_blacklist_info telit_le920_blacklist = { - .sendsetup = BIT(0), - .reserved = BIT(1) | BIT(5), + .infolen = ARRAY_SIZE(zte_k3765_z_no_sendsetup), + .ifaceinfo = zte_k3765_z_no_sendsetup, + .reason = OPTION_BLACKLIST_SENDSETUP }; static const struct usb_device_id option_ids[] = { @@ -575,125 +477,77 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x01) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x02) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x03) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x04) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x05) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x06) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0A) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0B) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0D) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0E) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0F) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x10) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x12) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x13) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x14) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x15) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x17) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x18) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x19) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1A) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1B) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1C) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x31) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x32) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x33) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x34) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x35) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x36) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3A) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3B) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3D) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3E) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3F) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x48) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x49) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4A) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4B) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4C) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x61) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x62) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x63) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x64) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x65) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x66) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6A) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6B) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6D) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6E) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6F) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x78) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x79) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7A) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7B) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7C) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x01) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x02) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x03) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x04) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x05) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x06) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0A) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0B) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0D) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0E) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0F) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x10) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x12) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x13) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x14) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x15) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x17) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x18) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x19) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1A) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1B) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1C) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x31) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x32) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x33) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x34) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x35) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x36) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3A) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3B) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3D) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3E) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3F) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x48) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x49) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4A) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4B) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4C) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x61) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x62) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x63) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x64) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x65) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x66) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6A) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6B) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6D) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6E) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6F) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x78) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x79) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7A) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7B) }, - { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7C) }, - - + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1402, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1404, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1407, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140A, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140B, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140C, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140D, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140E, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140F, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1413, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1414, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1415, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1416, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141A, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141B, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141C, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141D, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141E, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141F, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1420, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1421, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1422, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1423, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1424, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1425, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1426, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1427, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1428, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1429, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142A, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142B, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142C, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142D, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142E, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142F, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1430, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1431, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1432, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1433, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1434, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1435, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1436, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1437, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1438, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1439, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143A, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143B, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143C, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, @@ -719,7 +573,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED3) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED4) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED5) }, @@ -733,9 +586,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1_M) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) }, - /* Novatel Ovation MC551 a.k.a. Verizon USB551L */ - { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, @@ -758,8 +608,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ - { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_MINICARD_VZW, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_V2_MINICARD_VZW, 0xff, 0xff, 0xff) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, @@ -786,19 +634,12 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) }, - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) }, - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920), - .driver_info = (kernel_ulong_t)&telit_le920_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0004, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0005, 0xff, 0xff, 0xff) }, @@ -813,63 +654,57 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000f, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0010, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0011, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0012, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0012, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0013, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0016, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0018, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0019, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0020, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0021, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0021, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0022, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0023, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0024, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0025, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0025, 0xff, 0xff, 0xff) }, + /* { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0026, 0xff, 0xff, 0xff) }, */ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0028, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0029, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0030, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, - 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_mf626_blacklist }, + 0xff, 0xff), .driver_info = (kernel_ulong_t)&four_g_w14_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0032, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0033, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0034, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0037, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_0037_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0037, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0038, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0039, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0040, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0042, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0042, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0043, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0044, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0048, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0049, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0049, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0050, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0051, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0052, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0052, 0xff, 0xff, 0xff) }, + /* { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0053, 0xff, 0xff, 0xff) }, */ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0054, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0055, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0055, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0056, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0057, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0058, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0058, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0061, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0062, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0063, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0063, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0064, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0065, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0066, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0067, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0069, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0076, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0077, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0078, 0xff, 0xff, 0xff) }, @@ -878,94 +713,44 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0083, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0086, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0087, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0088, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0089, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0090, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0091, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0092, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0093, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0095, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0096, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0097, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0105, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0106, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0108, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0122, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0135, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0136, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0137, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0139, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0142, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0144, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0145, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0146, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0148, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0149, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0150, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0151, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0153, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0154, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0155, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0160, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0164, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0189, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0191, 0xff, 0xff, 0xff), /* ZTE EuFi890 */ - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0196, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0197, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0199, 0xff, 0xff, 0xff), /* ZTE MF820S */ - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0200, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0201, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0254, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0257, 0xff, 0xff, 0xff), /* ZTE MF821 */ - .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0265, 0xff, 0xff, 0xff), /* ONDA MT8205 */ - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0284, 0xff, 0xff, 0xff), /* ZTE MF880 */ - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0317, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0330, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0395, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0414, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0417, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1018, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1021, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, @@ -1081,24 +866,18 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1169, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1170, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1244, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1246, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1248, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1249, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1250, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1251, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1253, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_1255_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1257, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1258, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1259, 0xff, 0xff, 0xff) }, @@ -1143,61 +922,21 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1301, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1302, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1303, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1333, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1401, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1424, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1425, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1426, 0xff, 0xff, 0xff), /* ZTE MF91 */ - .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, - 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0060, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0170, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, - + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, + 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, - { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) }, - { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) }, - { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) }, - { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ @@ -1215,9 +954,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist }, - { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D) }, - { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L100V), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), @@ -1257,80 +993,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */ { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/ - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM600) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM610) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM500) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM510) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM800) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM900) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU818) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU816) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU828) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU826) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU518) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU516) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU528) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU526) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM600) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM610) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM500) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM510) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM800) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM900) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU718) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU716) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU728) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU726) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU518) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU516) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU528) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU526) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM600) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM610) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM500) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM510) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM800) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM900) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU718) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU716) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU728) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU726) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU518) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU881) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU882) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU581) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU582) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU583) }, - { USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZD_VENDOR_ID, ZD_PRODUCT_7000, 0xff, 0xff, 0xff) }, - { USB_DEVICE(LG_VENDOR_ID, LG_PRODUCT_L02C) }, /* docomo L-02C modem */ - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a1, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a1, 0xff, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a2, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a2, 0xff, 0x02, 0x01) }, /* MediaTek MT6276M modem & app port */ - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_1COM, 0x0a, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_5COM, 0xff, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_5COM, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM, 0xff, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_7208_1COM, 0x02, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_7208_2COM, 0x02, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FP_1COM, 0x0a, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FP_2COM, 0x0a, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FPDC_1COM, 0x0a, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FPDC_2COM, 0x0a, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_7103_2COM, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_7106_2COM, 0x02, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM2, 0xff, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM2, 0xff, 0x00, 0x00) }, - { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) }, - { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T) }, - { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); @@ -1374,7 +1036,7 @@ static struct usb_serial_driver option_1port_device = { .ioctl = usb_wwan_ioctl, .attach = usb_wwan_startup, .disconnect = usb_wwan_disconnect, - .release = option_release, + .release = usb_wwan_release, .read_int_callback = option_instat_callback, #ifdef CONFIG_PM .suspend = usb_wwan_suspend, @@ -1384,6 +1046,35 @@ static struct usb_serial_driver option_1port_device = { static int debug; +/* per port private data */ + +#define N_IN_URB 4 +#define N_OUT_URB 4 +#define IN_BUFLEN 4096 +#define OUT_BUFLEN 4096 + +struct option_port_private { + /* Input endpoints and buffer for this port */ + struct urb *in_urbs[N_IN_URB]; + u8 *in_buffer[N_IN_URB]; + /* Output endpoints and buffer for this port */ + struct urb *out_urbs[N_OUT_URB]; + u8 *out_buffer[N_OUT_URB]; + unsigned long out_busy; /* Bit vector of URBs in use */ + int opened; + struct usb_anchor delayed; + + /* Settings for the port */ + int rts_state; /* Handshaking pins (outputs) */ + int dtr_state; + int cts_state; /* Handshaking pins (inputs) */ + int dsr_state; + int dcd_state; + int ri_state; + + unsigned long tx_start_time[N_OUT_URB]; +}; + /* Functions used by new usb-serial code. */ static int __init option_init(void) { @@ -1415,35 +1106,10 @@ static void __exit option_exit(void) module_init(option_init); module_exit(option_exit); -static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, - const struct option_blacklist_info *blacklist) -{ - unsigned long num; - const unsigned long *intf_list; - - if (blacklist) { - if (reason == OPTION_BLACKLIST_SENDSETUP) - intf_list = &blacklist->sendsetup; - else if (reason == OPTION_BLACKLIST_RESERVED_IF) - intf_list = &blacklist->reserved; - else { - BUG_ON(reason); - return false; - } - - for_each_set_bit(num, intf_list, MAX_BL_NUM + 1) { - if (num == ifnum) - return true; - } - } - return false; -} - static int option_probe(struct usb_serial *serial, const struct usb_device_id *id) { struct usb_wwan_intf_private *data; - /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && @@ -1456,14 +1122,11 @@ static int option_probe(struct usb_serial *serial, serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff) return -ENODEV; - /* Don't bind reserved interfaces (like network ones) which often have - * the same class/subclass/protocol as the serial interfaces. Look at - * the Windows driver .INF files for reserved interface numbers. - */ - if (is_blacklisted( - serial->interface->cur_altsetting->desc.bInterfaceNumber, - OPTION_BLACKLIST_RESERVED_IF, - (const struct option_blacklist_info *) id->driver_info)) + /* Don't bind network interfaces on Huawei K3765 & K4505 */ + if (serial->dev->descriptor.idVendor == HUAWEI_VENDOR_ID && + (serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K3765 || + serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4505) && + serial->interface->cur_altsetting->desc.bInterfaceNumber == 1) return -ENODEV; /* Don't bind network interface on Samsung GT-B3730, it is handled by a separate module */ @@ -1473,6 +1136,7 @@ static int option_probe(struct usb_serial *serial, return -ENODEV; data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); + if (!data) return -ENOMEM; data->send_setup = option_send_setup; @@ -1481,13 +1145,21 @@ static int option_probe(struct usb_serial *serial, return 0; } -static void option_release(struct usb_serial *serial) +static enum option_blacklist_reason is_blacklisted(const u8 ifnum, + const struct option_blacklist_info *blacklist) { - struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); + const u8 *info; + int i; - usb_wwan_release(serial); + if (blacklist) { + info = blacklist->ifaceinfo; - kfree(priv); + for (i = 0; i < blacklist->infolen; i++) { + if (info[i] == ifnum) + return blacklist->reason; + } + } + return OPTION_BLACKLIST_NONE; } static void option_instat_callback(struct urb *urb) @@ -1495,8 +1167,7 @@ static void option_instat_callback(struct urb *urb) int err; int status = urb->status; struct usb_serial_port *port = urb->context; - struct usb_wwan_port_private *portdata = - usb_get_serial_port_data(port); + struct option_port_private *portdata = usb_get_serial_port_data(port); dbg("%s", __func__); dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata); @@ -1557,13 +1228,14 @@ static int option_send_setup(struct usb_serial_port *port) struct usb_serial *serial = port->serial; struct usb_wwan_intf_private *intfdata = (struct usb_wwan_intf_private *) serial->private; - struct usb_wwan_port_private *portdata; + struct option_port_private *portdata; int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; int val = 0; dbg("%s", __func__); - if (is_blacklisted(ifNum, OPTION_BLACKLIST_SENDSETUP, - (struct option_blacklist_info *) intfdata->private)) { + if (is_blacklisted(ifNum, + (struct option_blacklist_info *) intfdata->private) + == OPTION_BLACKLIST_SENDSETUP) { dbg("No send_setup on blacklisted interface #%d\n", ifNum); return -EIO; } diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 5aa7172e049f..30461fcc2206 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -91,7 +91,6 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, - { USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) }, { } /* Terminating entry */ }; @@ -343,28 +342,10 @@ static void pl2303_set_termios(struct tty_struct *tty, baud = 6000000; } dbg("%s - baud set = %d", __func__, baud); - if (baud <= 115200) { - buf[0] = baud & 0xff; - buf[1] = (baud >> 8) & 0xff; - buf[2] = (baud >> 16) & 0xff; - buf[3] = (baud >> 24) & 0xff; - } else { - /* apparently the formula for higher speeds is: - * baudrate = 12M * 32 / (2^buf[1]) / buf[0] - */ - unsigned tmp = 12*1000*1000*32 / baud; - buf[3] = 0x80; - buf[2] = 0; - buf[1] = (tmp >= 256); - while (tmp >= 256) { - tmp >>= 2; - buf[1] <<= 1; - } - if (tmp > 256) { - tmp %= 256; - } - buf[0] = tmp; - } + buf[0] = baud & 0xff; + buf[1] = (baud >> 8) & 0xff; + buf[2] = (baud >> 16) & 0xff; + buf[3] = (baud >> 24) & 0xff; } /* For reference buf[4]=0 is 1 stop bits */ @@ -424,7 +405,7 @@ static void pl2303_set_termios(struct tty_struct *tty, control = priv->line_control; if ((cflag & CBAUD) == B0) priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); - else if ((old_termios->c_cflag & CBAUD) == B0) + else priv->line_control |= (CONTROL_DTR | CONTROL_RTS); if (control != priv->line_control) { control = priv->line_control; diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index c38b8c00c06f..1b025f75dafd 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -144,8 +144,3 @@ /* ADLINK ND-6530 RS232,RS485 and RS422 adapter */ #define ADLINK_VENDOR_ID 0x0b63 #define ADLINK_ND6530_PRODUCT_ID 0x6530 - -/* SMART USB Serial Adapter */ -#define SMART_VENDOR_ID 0x0b8c -#define SMART_PRODUCT_ID 0x2303 - diff --git a/drivers/usb/serial/qcaux.c b/drivers/usb/serial/qcaux.c index 87271e363fec..30b73e68a904 100644 --- a/drivers/usb/serial/qcaux.c +++ b/drivers/usb/serial/qcaux.c @@ -36,6 +36,7 @@ #define UTSTARCOM_PRODUCT_UM175_V1 0x3712 #define UTSTARCOM_PRODUCT_UM175_V2 0x3714 #define UTSTARCOM_PRODUCT_UM175_ALLTEL 0x3715 +#define PANTECH_PRODUCT_UML290_VZW 0x3718 /* CMOTECH devices */ #define CMOTECH_VENDOR_ID 0x16d8 @@ -66,9 +67,7 @@ static struct usb_device_id id_table[] = { { USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_U520, 0xff, 0x00, 0x00) }, - { USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfd, 0xff) }, /* NMEA */ - { USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfe, 0xff) }, /* WMC */ - { USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xff, 0xff) }, /* DIAG */ + { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xff, 0xff) }, { }, }; MODULE_DEVICE_TABLE(usb, id_table); diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 03d5f932d667..54a9dab1f33b 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -23,45 +23,32 @@ static int debug; -#define DEVICE_G1K(v, p) \ - USB_DEVICE(v, p), .driver_info = 1 - static const struct usb_device_id id_table[] = { - /* Gobi 1000 devices */ - {DEVICE_G1K(0x05c6, 0x9211)}, /* Acer Gobi QDL device */ - {DEVICE_G1K(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ - {DEVICE_G1K(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ - {DEVICE_G1K(0x03f0, 0x201d)}, /* HP un2400 Gobi QDL Device */ - {DEVICE_G1K(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ - {DEVICE_G1K(0x04da, 0x250c)}, /* Panasonic Gobi QDL device */ - {DEVICE_G1K(0x413c, 0x8172)}, /* Dell Gobi Modem device */ - {DEVICE_G1K(0x413c, 0x8171)}, /* Dell Gobi QDL device */ - {DEVICE_G1K(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ - {DEVICE_G1K(0x1410, 0xa008)}, /* Novatel Gobi QDL device */ - {DEVICE_G1K(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ - {DEVICE_G1K(0x0b05, 0x1774)}, /* Asus Gobi QDL device */ - {DEVICE_G1K(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */ - {DEVICE_G1K(0x19d2, 0xfff2)}, /* ONDA Gobi QDL device */ - {DEVICE_G1K(0x1557, 0x0a80)}, /* OQO Gobi QDL device */ - {DEVICE_G1K(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ - {DEVICE_G1K(0x05c6, 0x9002)}, /* Generic Gobi Modem device */ - {DEVICE_G1K(0x05c6, 0x9202)}, /* Generic Gobi Modem device */ - {DEVICE_G1K(0x05c6, 0x9203)}, /* Generic Gobi Modem device */ - {DEVICE_G1K(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ - {DEVICE_G1K(0x05c6, 0x9008)}, /* Generic Gobi QDL device */ - {DEVICE_G1K(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ - {DEVICE_G1K(0x05c6, 0x9201)}, /* Generic Gobi QDL device */ - {DEVICE_G1K(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ - {DEVICE_G1K(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ - {DEVICE_G1K(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ - {DEVICE_G1K(0x1bc7, 0x900e)}, /* Telit Gobi QDL device */ - - /* Gobi 2000 devices */ - {USB_DEVICE(0x1410, 0xa010)}, /* Novatel Gobi 2000 QDL device */ - {USB_DEVICE(0x1410, 0xa011)}, /* Novatel Gobi 2000 QDL device */ - {USB_DEVICE(0x1410, 0xa012)}, /* Novatel Gobi 2000 QDL device */ - {USB_DEVICE(0x1410, 0xa013)}, /* Novatel Gobi 2000 QDL device */ - {USB_DEVICE(0x1410, 0xa014)}, /* Novatel Gobi 2000 QDL device */ + {USB_DEVICE(0x05c6, 0x9211)}, /* Acer Gobi QDL device */ + {USB_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ + {USB_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ + {USB_DEVICE(0x03f0, 0x201d)}, /* HP un2400 Gobi QDL Device */ + {USB_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ + {USB_DEVICE(0x04da, 0x250c)}, /* Panasonic Gobi QDL device */ + {USB_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ + {USB_DEVICE(0x413c, 0x8171)}, /* Dell Gobi QDL device */ + {USB_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ + {USB_DEVICE(0x1410, 0xa008)}, /* Novatel Gobi QDL device */ + {USB_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ + {USB_DEVICE(0x0b05, 0x1774)}, /* Asus Gobi QDL device */ + {USB_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */ + {USB_DEVICE(0x19d2, 0xfff2)}, /* ONDA Gobi QDL device */ + {USB_DEVICE(0x1557, 0x0a80)}, /* OQO Gobi QDL device */ + {USB_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ + {USB_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */ + {USB_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */ + {USB_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */ + {USB_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ + {USB_DEVICE(0x05c6, 0x9008)}, /* Generic Gobi QDL device */ + {USB_DEVICE(0x05c6, 0x9201)}, /* Generic Gobi QDL device */ + {USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ + {USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ + {USB_DEVICE(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ {USB_DEVICE(0x413c, 0x8185)}, /* Dell Gobi 2000 QDL device (N0218, VU936) */ {USB_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ {USB_DEVICE(0x05c6, 0x9208)}, /* Generic Gobi 2000 QDL device */ @@ -91,29 +78,10 @@ static const struct usb_device_id id_table[] = { {USB_DEVICE(0x1199, 0x9008)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ {USB_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ {USB_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ - {USB_DEVICE(0x1199, 0x9011)}, /* Sierra Wireless Gobi 2000 Modem device (MC8305) */ {USB_DEVICE(0x16d8, 0x8001)}, /* CMDTech Gobi 2000 QDL device (VU922) */ {USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ {USB_DEVICE(0x05c6, 0x9204)}, /* Gobi 2000 QDL device */ {USB_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ - - /* Gobi 3000 devices */ - {USB_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Gobi 3000 QDL */ - {USB_DEVICE(0x05c6, 0x920c)}, /* Gobi 3000 QDL */ - {USB_DEVICE(0x05c6, 0x920d)}, /* Gobi 3000 Composite */ - {USB_DEVICE(0x1410, 0xa020)}, /* Novatel Gobi 3000 QDL */ - {USB_DEVICE(0x1410, 0xa021)}, /* Novatel Gobi 3000 Composite */ - {USB_DEVICE(0x413c, 0x8193)}, /* Dell Gobi 3000 QDL */ - {USB_DEVICE(0x413c, 0x8194)}, /* Dell Gobi 3000 Composite */ - {USB_DEVICE(0x1199, 0x9010)}, /* Sierra Wireless Gobi 3000 QDL */ - {USB_DEVICE(0x1199, 0x9012)}, /* Sierra Wireless Gobi 3000 QDL */ - {USB_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ - {USB_DEVICE(0x1199, 0x9014)}, /* Sierra Wireless Gobi 3000 QDL */ - {USB_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ - {USB_DEVICE(0x1199, 0x9018)}, /* Sierra Wireless Gobi 3000 QDL */ - {USB_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ - {USB_DEVICE(0x12D1, 0x14F0)}, /* Sony Gobi 3000 QDL */ - {USB_DEVICE(0x12D1, 0x14F1)}, /* Sony Gobi 3000 Composite */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, id_table); @@ -135,10 +103,8 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) int retval = -ENODEV; __u8 nintf; __u8 ifnum; - bool is_gobi1k = id->driver_info ? true : false; dbg("%s", __func__); - dbg("Is Gobi 1000 = %d", is_gobi1k); nintf = serial->dev->actconfig->desc.bNumInterfaces; dbg("Num Interfaces = %d", nintf); @@ -186,25 +152,15 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) case 3: case 4: - /* Composite mode; don't bind to the QMI/net interface as that - * gets handled by other drivers. - */ - - /* Gobi 1K USB layout: - * 0: serial port (doesn't respond) - * 1: serial port (doesn't respond) - * 2: AT-capable modem port - * 3: QMI/net - * - * Gobi 2K+ USB layout: - * 0: QMI/net - * 1: DM/DIAG (use libqcdm from ModemManager for communication) - * 2: AT-capable modem port - * 3: NMEA - */ - - if (ifnum == 1 && !is_gobi1k) { - dbg("Gobi 2K+ DM/DIAG interface found"); + /* Composite mode */ + /* ifnum == 0 is a broadband network adapter */ + if (ifnum == 1) { + /* + * Diagnostics Monitor (serial line 9600 8N1) + * Qualcomm DM protocol + * use "libqcdm" (ModemManager) for communication + */ + dbg("Diagnostics Monitor found"); retval = usb_set_interface(serial->dev, ifnum, 0); if (retval < 0) { dev_err(&serial->dev->dev, @@ -223,13 +179,13 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) retval = -ENODEV; kfree(data); } - } else if (ifnum==3 && !is_gobi1k) { + } else if (ifnum==3) { /* * NMEA (serial line 9600 8N1) * # echo "\$GPS_START" > /dev/ttyUSBx * # echo "\$GPS_STOP" > /dev/ttyUSBx */ - dbg("Gobi 2K+ NMEA GPS interface found"); + dbg("NMEA GPS interface found"); retval = usb_set_interface(serial->dev, ifnum, 0); if (retval < 0) { dev_err(&serial->dev->dev, diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index a159ad0c5e18..d5d136a53b61 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -171,6 +171,7 @@ static int sierra_probe(struct usb_serial *serial, { int result = 0; struct usb_device *udev; + struct sierra_intf_private *data; u8 ifnum; udev = serial->dev; @@ -198,6 +199,11 @@ static int sierra_probe(struct usb_serial *serial, return -ENODEV; } + data = serial->private = kzalloc(sizeof(struct sierra_intf_private), GFP_KERNEL); + if (!data) + return -ENOMEM; + spin_lock_init(&data->susp_lock); + return result; } @@ -215,7 +221,7 @@ static const struct sierra_iface_info typeB_interface_list = { }; /* 'blacklist' of interfaces not served by this driver */ -static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 }; +static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 }; static const struct sierra_iface_info direct_ip_interface_blacklist = { .infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces), .ifaceinfo = direct_ip_non_serial_ifaces, @@ -292,16 +298,9 @@ static const struct usb_device_id id_table[] = { /* Sierra Wireless HSPA Non-Composite Device */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */ - { USB_DEVICE(0x1199, 0x68A2), /* Sierra Wireless MC77xx in QMI mode */ - .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist - }, { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist }, - /* AT&T Direct IP LTE modems */ - { USB_DEVICE_AND_INTERFACE_INFO(0x0F3D, 0x68AA, 0xFF, 0xFF, 0xFF), - .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist - }, { USB_DEVICE(0x0f3d, 0x68A3), /* Airprime/Sierra Wireless Direct IP modems */ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist }, @@ -909,7 +908,6 @@ static void sierra_dtr_rts(struct usb_serial_port *port, int on) static int sierra_startup(struct usb_serial *serial) { struct usb_serial_port *port; - struct sierra_intf_private *intfdata; struct sierra_port_private *portdata; struct sierra_iface_info *himemoryp = NULL; int i; @@ -917,14 +915,6 @@ static int sierra_startup(struct usb_serial *serial) dev_dbg(&serial->dev->dev, "%s\n", __func__); - intfdata = kzalloc(sizeof(*intfdata), GFP_KERNEL); - if (!intfdata) - return -ENOMEM; - - spin_lock_init(&intfdata->susp_lock); - - usb_set_serial_data(serial, intfdata); - /* Set Device mode to D0 */ sierra_set_power_state(serial->dev, 0x0000); @@ -940,7 +930,7 @@ static int sierra_startup(struct usb_serial *serial) dev_dbg(&port->dev, "%s: kmalloc for " "sierra_port_private (%d) failed!\n", __func__, i); - goto err; + return -ENOMEM; } spin_lock_init(&portdata->lock); init_usb_anchor(&portdata->active); @@ -977,14 +967,6 @@ static int sierra_startup(struct usb_serial *serial) } return 0; -err: - for (--i; i >= 0; --i) { - portdata = usb_get_serial_port_data(serial->port[i]); - kfree(portdata); - } - kfree(intfdata); - - return -ENOMEM; } static void sierra_release(struct usb_serial *serial) @@ -1004,7 +986,6 @@ static void sierra_release(struct usb_serial *serial) continue; kfree(portdata); } - kfree(serial->private); } #ifdef CONFIG_PM diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 2856474123eb..ea8445689c85 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -165,7 +165,7 @@ static unsigned int product_5052_count; /* the array dimension is the number of default entries plus */ /* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */ /* null entry */ -static struct usb_device_id ti_id_table_3410[15+TI_EXTRA_VID_PID_COUNT+1] = { +static struct usb_device_id ti_id_table_3410[13+TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) }, @@ -179,8 +179,6 @@ static struct usb_device_id ti_id_table_3410[15+TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, - { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) }, - { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) }, }; static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = { @@ -190,7 +188,7 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, }; -static struct usb_device_id ti_id_table_combined[19+2*TI_EXTRA_VID_PID_COUNT+1] = { +static struct usb_device_id ti_id_table_combined[17+2*TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) }, @@ -208,8 +206,6 @@ static struct usb_device_id ti_id_table_combined[19+2*TI_EXTRA_VID_PID_COUNT+1] { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, - { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) }, - { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) }, { } }; diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h index b353e7e3d480..2aac1953993b 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.h +++ b/drivers/usb/serial/ti_usb_3410_5052.h @@ -37,7 +37,6 @@ #define TI_5152_BOOT_PRODUCT_ID 0x5152 /* no EEPROM, no firmware */ #define TI_5052_EEPROM_PRODUCT_ID 0x505A /* EEPROM, no firmware */ #define TI_5052_FIRMWARE_PRODUCT_ID 0x505F /* firmware is running */ -#define FRI2_PRODUCT_ID 0x5053 /* Fish River Island II */ /* Multi-Tech vendor and product ids */ #define MTS_VENDOR_ID 0x06E0 @@ -50,10 +49,6 @@ #define MTS_MT9234ZBA_PRODUCT_ID 0xF115 #define MTS_MT9234ZBAOLD_PRODUCT_ID 0x0319 -/* Abbott Diabetics vendor and product ids */ -#define ABBOTT_VENDOR_ID 0x1a61 -#define ABBOTT_PRODUCT_ID 0x3410 - /* Commands */ #define TI_GET_VERSION 0x01 #define TI_GET_PORT_STATUS 0x02 diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 637dfa4efb5b..1c031309ab25 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -669,14 +669,12 @@ exit: static struct usb_serial_driver *search_serial_device( struct usb_interface *iface) { - const struct usb_device_id *id = NULL; + const struct usb_device_id *id; struct usb_serial_driver *drv; - struct usb_driver *driver = to_usb_driver(iface->dev.driver); /* Check if the usb id matches a known device */ list_for_each_entry(drv, &usb_serial_driver_list, driver_list) { - if (drv->usb_driver == driver) - id = get_iface_id(drv, iface); + id = get_iface_id(drv, iface); if (id) return drv; } @@ -764,7 +762,7 @@ int usb_serial_probe(struct usb_interface *interface, if (retval) { dbg("sub driver rejected device"); - usb_serial_put(serial); + kfree(serial); module_put(type->driver.owner); return retval; } @@ -836,7 +834,7 @@ int usb_serial_probe(struct usb_interface *interface, */ if (num_bulk_in == 0 || num_bulk_out == 0) { dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); - usb_serial_put(serial); + kfree(serial); module_put(type->driver.owner); return -ENODEV; } @@ -850,7 +848,7 @@ int usb_serial_probe(struct usb_interface *interface, if (num_ports == 0) { dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n"); - usb_serial_put(serial); + kfree(serial); module_put(type->driver.owner); return -EIO; } @@ -1061,12 +1059,6 @@ int usb_serial_probe(struct usb_interface *interface, serial->attached = 1; } - /* Avoid race with tty_open and serial_install by setting the - * disconnected flag and not clearing it until all ports have been - * registered. - */ - serial->disconnected = 1; - if (get_free_serial(serial, num_ports, &minor) == NULL) { dev_err(&interface->dev, "No more free serial devices\n"); goto probe_error; @@ -1091,8 +1083,6 @@ int usb_serial_probe(struct usb_interface *interface, } } - serial->disconnected = 0; - usb_serial_console_init(debug, minor); exit: diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 59d646d207bc..5b073bcc807b 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -576,7 +576,6 @@ no_firmware: "%s: please contact support@connecttech.com\n", serial->type->description); kfree(result); - kfree(command); return -ENODEV; no_command_private: diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index dc27260068b3..97987255be75 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -199,7 +199,7 @@ config USB_STORAGE_ENE_UB6250 config USB_UAS tristate "USB Attached SCSI" - depends on USB && SCSI && BROKEN + depends on USB && SCSI help The USB Attached SCSI protocol is supported by some USB storage devices. It permits higher performance by supporting diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c index 16b0bf055eeb..105d900150c1 100644 --- a/drivers/usb/storage/initializers.c +++ b/drivers/usb/storage/initializers.c @@ -92,8 +92,8 @@ int usb_stor_ucr61s2b_init(struct us_data *us) return 0; } -/* This places the HUAWEI usb dongles in multi-port mode */ -static int usb_stor_huawei_feature_init(struct us_data *us) +/* This places the HUAWEI E220 devices in multi-port mode */ +int usb_stor_huawei_e220_init(struct us_data *us) { int result; @@ -104,75 +104,3 @@ static int usb_stor_huawei_feature_init(struct us_data *us) US_DEBUGP("Huawei mode set result is %d\n", result); return 0; } - -/* - * It will send a scsi switch command called rewind' to huawei dongle. - * When the dongle receives this command at the first time, - * it will reboot immediately. After rebooted, it will ignore this command. - * So it is unnecessary to read its response. - */ -static int usb_stor_huawei_scsi_init(struct us_data *us) -{ - int result = 0; - int act_len = 0; - struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf; - char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcbw->Tag = 0; - bcbw->DataTransferLength = 0; - bcbw->Flags = bcbw->Lun = 0; - bcbw->Length = sizeof(rewind_cmd); - memset(bcbw->CDB, 0, sizeof(bcbw->CDB)); - memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd)); - - result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw, - US_BULK_CB_WRAP_LEN, &act_len); - US_DEBUGP("transfer actual length=%d, result=%d\n", act_len, result); - return result; -} - -/* - * It tries to find the supported Huawei USB dongles. - * In Huawei, they assign the following product IDs - * for all of their mobile broadband dongles, - * including the new dongles in the future. - * So if the product ID is not included in this list, - * it means it is not Huawei's mobile broadband dongles. - */ -static int usb_stor_huawei_dongles_pid(struct us_data *us) -{ - struct usb_interface_descriptor *idesc; - int idProduct; - - idesc = &us->pusb_intf->cur_altsetting->desc; - idProduct = us->pusb_dev->descriptor.idProduct; - /* The first port is CDROM, - * means the dongle in the single port mode, - * and a switch command is required to be sent. */ - if (idesc && idesc->bInterfaceNumber == 0) { - if ((idProduct == 0x1001) - || (idProduct == 0x1003) - || (idProduct == 0x1004) - || (idProduct >= 0x1401 && idProduct <= 0x1500) - || (idProduct >= 0x1505 && idProduct <= 0x1600) - || (idProduct >= 0x1c02 && idProduct <= 0x2202)) { - return 1; - } - } - return 0; -} - -int usb_stor_huawei_init(struct us_data *us) -{ - int result = 0; - - if (usb_stor_huawei_dongles_pid(us)) { - if (us->pusb_dev->descriptor.idProduct >= 0x1446) - result = usb_stor_huawei_scsi_init(us); - else - result = usb_stor_huawei_feature_init(us); - } - return result; -} diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h index 5376d4fc76f0..529327fbb06b 100644 --- a/drivers/usb/storage/initializers.h +++ b/drivers/usb/storage/initializers.h @@ -46,5 +46,5 @@ int usb_stor_euscsi_init(struct us_data *us); * flash reader */ int usb_stor_ucr61s2b_init(struct us_data *us); -/* This places the HUAWEI usb dongles in multi-port mode */ -int usb_stor_huawei_init(struct us_data *us); +/* This places the HUAWEI E220 devices in multi-port mode */ +int usb_stor_huawei_e220_init(struct us_data *us); diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c index 0fded39e3b3e..fc310f75eada 100644 --- a/drivers/usb/storage/protocol.c +++ b/drivers/usb/storage/protocol.c @@ -58,9 +58,7 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us) { - /* - * Pad the SCSI command with zeros out to 12 bytes. If the - * command already is 12 bytes or longer, leave it alone. + /* Pad the SCSI command with zeros out to 12 bytes * * NOTE: This only works because a scsi_cmnd struct field contains * a unsigned char cmnd[16], so we know we have storage available @@ -68,6 +66,9 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us) for (; srb->cmd_len<12; srb->cmd_len++) srb->cmnd[srb->cmd_len] = 0; + /* set command length to 12 bytes */ + srb->cmd_len = 12; + /* send the command to the transport layer */ usb_stor_invoke_transport(srb, us); } diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index ff32390d61e5..e8ae21b2d387 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -691,9 +691,6 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) int temp_result; struct scsi_eh_save ses; int sense_size = US_SENSE_SIZE; - struct scsi_sense_hdr sshdr; - const u8 *scdd; - u8 fm_ili; /* device supports and needs bigger sense buffer */ if (us->fflags & US_FL_SANE_SENSE) @@ -777,30 +774,32 @@ Retry_Sense: srb->sense_buffer[7] = (US_SENSE_SIZE - 8); } - scsi_normalize_sense(srb->sense_buffer, SCSI_SENSE_BUFFERSIZE, - &sshdr); - US_DEBUGP("-- Result from auto-sense is %d\n", temp_result); US_DEBUGP("-- code: 0x%x, key: 0x%x, ASC: 0x%x, ASCQ: 0x%x\n", - sshdr.response_code, sshdr.sense_key, - sshdr.asc, sshdr.ascq); + srb->sense_buffer[0], + srb->sense_buffer[2] & 0xf, + srb->sense_buffer[12], + srb->sense_buffer[13]); #ifdef CONFIG_USB_STORAGE_DEBUG - usb_stor_show_sense(sshdr.sense_key, sshdr.asc, sshdr.ascq); + usb_stor_show_sense( + srb->sense_buffer[2] & 0xf, + srb->sense_buffer[12], + srb->sense_buffer[13]); #endif /* set the result so the higher layers expect this data */ srb->result = SAM_STAT_CHECK_CONDITION; - scdd = scsi_sense_desc_find(srb->sense_buffer, - SCSI_SENSE_BUFFERSIZE, 4); - fm_ili = (scdd ? scdd[3] : srb->sense_buffer[2]) & 0xA0; - /* We often get empty sense data. This could indicate that * everything worked or that there was an unspecified * problem. We have to decide which. */ - if (sshdr.sense_key == 0 && sshdr.asc == 0 && sshdr.ascq == 0 && - fm_ili == 0) { + if ( /* Filemark 0, ignore EOM, ILI 0, no sense */ + (srb->sense_buffer[2] & 0xaf) == 0 && + /* No ASC or ASCQ */ + srb->sense_buffer[12] == 0 && + srb->sense_buffer[13] == 0) { + /* If things are really okay, then let's show that. * Zero out the sense buffer so the higher layers * won't realize we did an unsolicited auto-sense. @@ -815,10 +814,7 @@ Retry_Sense: */ } else { srb->result = DID_ERROR << 16; - if ((sshdr.response_code & 0x72) == 0x72) - srb->sense_buffer[1] = HARDWARE_ERROR; - else - srb->sense_buffer[2] = HARDWARE_ERROR; + srb->sense_buffer[2] = HARDWARE_ERROR; } } } diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 12640efcf82d..ccff3483eebc 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1004,12 +1004,6 @@ UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9999, USB_SC_8070, USB_PR_CB, NULL, US_FL_NEED_OVERRIDE | US_FL_FIX_INQUIRY ), -/* Submitted by Oleksandr Chumachenko */ -UNUSUAL_DEV( 0x07cf, 0x1167, 0x0100, 0x0100, - "Casio", - "EX-N1 DigitalCamera", - USB_SC_8070, USB_PR_DEVICE, NULL, 0), - /* Submitted by Hartmut Wahl */ UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001, "Samsung", @@ -1515,10 +1509,335 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100, /* Reported by fangxiaozhi * This brings the HUAWEI data card devices into multi-port mode */ -UNUSUAL_VENDOR_INTF(0x12d1, 0x08, 0x06, 0x50, +UNUSUAL_DEV( 0x12d1, 0x1001, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1004, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1401, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1402, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1403, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1404, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1405, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1406, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1407, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1408, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1409, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140A, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140B, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140C, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140D, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140E, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140F, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1410, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1411, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1412, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1413, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1414, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1415, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1416, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1417, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1418, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1419, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141A, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141B, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141C, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141D, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141E, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141F, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1420, 0x0000, 0x0000, "HUAWEI MOBILE", "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_init, + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1421, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1422, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1423, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1424, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1425, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1426, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1427, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1428, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1429, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142A, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142B, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142C, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142D, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142E, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142F, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1430, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1431, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1432, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1433, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1434, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1435, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1436, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1437, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1438, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1439, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143A, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143B, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143C, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143D, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143E, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143F, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, 0), /* Reported by Vilius Bilinkevicius */ -UNUSUAL_DEV( 0x13fe, 0x3600, 0x0100, 0x0100, - "Kingston", - "DT 101 G2", - USB_SC_DEVICE, USB_PR_DEVICE, NULL, - US_FL_BULK_IGNORE_TAG ), - /* Reported by Francesco Foresti */ UNUSUAL_DEV( 0x14cd, 0x6600, 0x0201, 0x0201, "Super Top", @@ -1566,13 +1878,6 @@ UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), -/* Reported by Jesse Feddema */ -UNUSUAL_DEV( 0x177f, 0x0400, 0x0000, 0x0000, - "Yarvik", - "PMP400", - USB_SC_DEVICE, USB_PR_DEVICE, NULL, - US_FL_BULK_IGNORE_TAG | US_FL_MAX_SECTORS_64 ), - /* Reported by Hans de Goede * These Appotech controllers are found in Picture Frames, they provide a * (buggy) emulation of a cdrom drive which contains the windows software @@ -1683,16 +1988,6 @@ UNUSUAL_DEV( 0x4146, 0xba01, 0x0100, 0x0100, "Micro Mini 1GB", USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), -/* - * Nick Bowler - * SCSI stack spams (otherwise harmless) error messages. - */ -UNUSUAL_DEV( 0xc251, 0x4003, 0x0100, 0x0100, - "Keil Software, Inc.", - "V2M MotherBoard", - USB_SC_DEVICE, USB_PR_DEVICE, NULL, - US_FL_NOT_LOCKABLE), - /* Reported by Andrew Simmons */ UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, "DataStor", diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index d582af4a1968..0ca095820f3e 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -120,17 +120,6 @@ MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks"); .useTransport = use_transport, \ } -#define UNUSUAL_VENDOR_INTF(idVendor, cl, sc, pr, \ - vendor_name, product_name, use_protocol, use_transport, \ - init_function, Flags) \ -{ \ - .vendorName = vendor_name, \ - .productName = product_name, \ - .useProtocol = use_protocol, \ - .useTransport = use_transport, \ - .initFunction = init_function, \ -} - static struct us_unusual_dev us_unusual_dev_list[] = { # include "unusual_devs.h" { } /* Terminating entry */ @@ -139,7 +128,6 @@ static struct us_unusual_dev us_unusual_dev_list[] = { #undef UNUSUAL_DEV #undef COMPLIANT_DEV #undef USUAL_DEV -#undef UNUSUAL_VENDOR_INTF #ifdef CONFIG_PM /* Minimal support for suspend and resume */ @@ -800,19 +788,15 @@ static void quiesce_and_remove_host(struct us_data *us) struct Scsi_Host *host = us_to_host(us); /* If the device is really gone, cut short reset delays */ - if (us->pusb_dev->state == USB_STATE_NOTATTACHED) { + if (us->pusb_dev->state == USB_STATE_NOTATTACHED) set_bit(US_FLIDX_DISCONNECTING, &us->dflags); - wake_up(&us->delay_wait); - } - /* Prevent SCSI scanning (if it hasn't started yet) - * or wait for the SCSI-scanning routine to stop. + /* Prevent SCSI-scanning (if it hasn't started yet) + * and wait for the SCSI-scanning thread to stop. */ - cancel_delayed_work_sync(&us->scan_dwork); - - /* Balance autopm calls if scanning was cancelled */ - if (test_bit(US_FLIDX_SCAN_PENDING, &us->dflags)) - usb_autopm_put_interface_no_suspend(us->pusb_intf); + set_bit(US_FLIDX_DONT_SCAN, &us->dflags); + wake_up(&us->delay_wait); + wait_for_completion(&us->scanning_done); /* Removing the host will perform an orderly shutdown: caches * synchronized, disks spun down, etc. @@ -839,28 +823,42 @@ static void release_everything(struct us_data *us) scsi_host_put(us_to_host(us)); } -/* Delayed-work routine to carry out SCSI-device scanning */ -static void usb_stor_scan_dwork(struct work_struct *work) +/* Thread to carry out delayed SCSI-device scanning */ +static int usb_stor_scan_thread(void * __us) { - struct us_data *us = container_of(work, struct us_data, - scan_dwork.work); + struct us_data *us = (struct us_data *)__us; struct device *dev = &us->pusb_intf->dev; - dev_dbg(dev, "starting scan\n"); + dev_dbg(dev, "device found\n"); - /* For bulk-only devices, determine the max LUN value */ - if (us->protocol == USB_PR_BULK && !(us->fflags & US_FL_SINGLE_LUN)) { - mutex_lock(&us->dev_mutex); - us->max_lun = usb_stor_Bulk_max_lun(us); - mutex_unlock(&us->dev_mutex); + set_freezable(); + /* Wait for the timeout to expire or for a disconnect */ + if (delay_use > 0) { + dev_dbg(dev, "waiting for device to settle " + "before scanning\n"); + wait_event_freezable_timeout(us->delay_wait, + test_bit(US_FLIDX_DONT_SCAN, &us->dflags), + delay_use * HZ); } - scsi_scan_host(us_to_host(us)); - dev_dbg(dev, "scan complete\n"); - /* Should we unbind if no devices were detected? */ + /* If the device is still connected, perform the scanning */ + if (!test_bit(US_FLIDX_DONT_SCAN, &us->dflags)) { + + /* For bulk-only devices, determine the max LUN value */ + if (us->protocol == USB_PR_BULK && + !(us->fflags & US_FL_SINGLE_LUN)) { + mutex_lock(&us->dev_mutex); + us->max_lun = usb_stor_Bulk_max_lun(us); + mutex_unlock(&us->dev_mutex); + } + scsi_scan_host(us_to_host(us)); + dev_dbg(dev, "scan complete\n"); + + /* Should we unbind if no devices were detected? */ + } usb_autopm_put_interface(us->pusb_intf); - clear_bit(US_FLIDX_SCAN_PENDING, &us->dflags); + complete_and_exit(&us->scanning_done, 0); } static unsigned int usb_stor_sg_tablesize(struct usb_interface *intf) @@ -907,7 +905,7 @@ int usb_stor_probe1(struct us_data **pus, init_completion(&us->cmnd_ready); init_completion(&(us->notify)); init_waitqueue_head(&us->delay_wait); - INIT_DELAYED_WORK(&us->scan_dwork, usb_stor_scan_dwork); + init_completion(&us->scanning_done); /* Associate the us_data structure with the USB device */ result = associate_dev(us, intf); @@ -938,6 +936,7 @@ EXPORT_SYMBOL_GPL(usb_stor_probe1); /* Second part of general USB mass-storage probing */ int usb_stor_probe2(struct us_data *us) { + struct task_struct *th; int result; struct device *dev = &us->pusb_intf->dev; @@ -978,14 +977,20 @@ int usb_stor_probe2(struct us_data *us) goto BadDevice; } - /* Submit the delayed_work for SCSI-device scanning */ + /* Start up the thread for delayed SCSI-device scanning */ + th = kthread_create(usb_stor_scan_thread, us, "usb-stor-scan"); + if (IS_ERR(th)) { + dev_warn(dev, + "Unable to start the device-scanning thread\n"); + complete(&us->scanning_done); + quiesce_and_remove_host(us); + result = PTR_ERR(th); + goto BadDevice; + } + usb_autopm_get_interface_no_resume(us->pusb_intf); - set_bit(US_FLIDX_SCAN_PENDING, &us->dflags); + wake_up_process(th); - if (delay_use > 0) - dev_dbg(dev, "waiting for device to settle before scanning\n"); - queue_delayed_work(system_freezable_wq, &us->scan_dwork, - delay_use * HZ); return 0; /* We come here if there are any problems */ @@ -1058,7 +1063,6 @@ static struct usb_driver usb_storage_driver = { .id_table = usb_storage_usb_ids, .supports_autosuspend = 1, .soft_unbind = 1, - .no_dynamic_id = 1, }; static int __init usb_stor_init(void) diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 75f70f04f37b..7b0f2113632e 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -47,7 +47,6 @@ #include #include #include -#include #include struct us_data; @@ -73,7 +72,7 @@ struct us_unusual_dev { #define US_FLIDX_DISCONNECTING 3 /* disconnect in progress */ #define US_FLIDX_RESETTING 4 /* device reset in progress */ #define US_FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */ -#define US_FLIDX_SCAN_PENDING 6 /* scanning not yet done */ +#define US_FLIDX_DONT_SCAN 6 /* don't scan (disconnect) */ #define US_FLIDX_REDO_READ10 7 /* redo READ(10) command */ #define US_FLIDX_READ10_WORKED 8 /* previous READ(10) succeeded */ @@ -148,8 +147,8 @@ struct us_data { /* mutual exclusion and synchronization structures */ struct completion cmnd_ready; /* to sleep thread on */ struct completion notify; /* thread begin/end */ - wait_queue_head_t delay_wait; /* wait during reset */ - struct delayed_work scan_dwork; /* for async scanning */ + wait_queue_head_t delay_wait; /* wait during scan, reset */ + struct completion scanning_done; /* wait for scan thread */ /* subdriver information */ void *extra; /* Any extra data */ diff --git a/drivers/usb/storage/usual-tables.c b/drivers/usb/storage/usual-tables.c index a9b5f2e29189..b96927914f89 100644 --- a/drivers/usb/storage/usual-tables.c +++ b/drivers/usb/storage/usual-tables.c @@ -46,20 +46,6 @@ { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ .driver_info = ((useType)<<24) } -/* Define the device is matched with Vendor ID and interface descriptors */ -#define UNUSUAL_VENDOR_INTF(id_vendor, cl, sc, pr, \ - vendorName, productName, useProtocol, useTransport, \ - initFunction, flags) \ -{ \ - .match_flags = USB_DEVICE_ID_MATCH_INT_INFO \ - | USB_DEVICE_ID_MATCH_VENDOR, \ - .idVendor = (id_vendor), \ - .bInterfaceClass = (cl), \ - .bInterfaceSubClass = (sc), \ - .bInterfaceProtocol = (pr), \ - .driver_info = (flags) \ -} - struct usb_device_id usb_storage_usb_ids[] = { # include "unusual_devs.h" { } /* Terminating entry */ @@ -71,7 +57,6 @@ MODULE_DEVICE_TABLE(usb, usb_storage_usb_ids); #undef UNUSUAL_DEV #undef COMPLIANT_DEV #undef USUAL_DEV -#undef UNUSUAL_VENDOR_INTF /* diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c index 86685e994987..2babcd4fbfc1 100644 --- a/drivers/uwb/hwa-rc.c +++ b/drivers/uwb/hwa-rc.c @@ -645,8 +645,7 @@ void hwarc_neep_cb(struct urb *urb) dev_err(dev, "NEEP: URB error %d\n", urb->status); } result = usb_submit_urb(urb, GFP_ATOMIC); - if (result < 0 && result != -ENODEV && result != -EPERM) { - /* ignoring unrecoverable errors */ + if (result < 0) { dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n", result); goto error; diff --git a/drivers/uwb/neh.c b/drivers/uwb/neh.c index 47146c894339..697e56a5bcdd 100644 --- a/drivers/uwb/neh.c +++ b/drivers/uwb/neh.c @@ -106,7 +106,6 @@ struct uwb_rc_neh { u8 evt_type; __le16 evt; u8 context; - u8 completed; uwb_rc_cmd_cb_f cb; void *arg; @@ -409,7 +408,6 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size struct device *dev = &rc->uwb_dev.dev; struct uwb_rc_neh *neh; struct uwb_rceb *notif; - unsigned long flags; if (rceb->bEventContext == 0) { notif = kmalloc(size, GFP_ATOMIC); @@ -423,11 +421,7 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size } else { neh = uwb_rc_neh_lookup(rc, rceb); if (neh) { - spin_lock_irqsave(&rc->neh_lock, flags); - /* to guard against a timeout */ - neh->completed = 1; - del_timer(&neh->timer); - spin_unlock_irqrestore(&rc->neh_lock, flags); + del_timer_sync(&neh->timer); uwb_rc_neh_cb(neh, rceb, size); } else dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n", @@ -573,10 +567,6 @@ static void uwb_rc_neh_timer(unsigned long arg) unsigned long flags; spin_lock_irqsave(&rc->neh_lock, flags); - if (neh->completed) { - spin_unlock_irqrestore(&rc->neh_lock, flags); - return; - } if (neh->context) __uwb_rc_neh_rm(rc, neh); else diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index f27482630ba3..e224a92baa16 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -305,8 +305,7 @@ static void handle_rx(struct vhost_net *net) .hdr.gso_type = VIRTIO_NET_HDR_GSO_NONE }; size_t total_len = 0; - int err, mergeable; - s16 headcount; + int err, headcount, mergeable; size_t vhost_hlen, sock_hlen; size_t vhost_len, sock_len; /* TODO: check that we are running from vhost_worker? */ diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 61047fe31206..ea966b356352 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -217,8 +217,6 @@ static int vhost_worker(void *data) if (work) { __set_current_state(TASK_RUNNING); work->fn(work); - if (need_resched()) - schedule(); } else schedule(); diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 4c85a4b15f97..549b960667c8 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -23,8 +23,6 @@ source "drivers/gpu/drm/Kconfig" source "drivers/gpu/stub/Kconfig" -source "drivers/gpu/ion/Kconfig" - config VGASTATE tristate default n diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index c2ceae4bb6ca..4484c721f0f9 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -1085,7 +1085,7 @@ static int atmel_lcdfb_suspend(struct platform_device *pdev, pm_message_t mesg) */ lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL); - sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_CTR); + sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL); lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0); if (sinfo->atmel_lcdfb_power_control) sinfo->atmel_lcdfb_power_control(0); diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c index 6f54f7436a97..772f6015219a 100644 --- a/drivers/video/backlight/tosa_lcd.c +++ b/drivers/video/backlight/tosa_lcd.c @@ -271,7 +271,7 @@ static int tosa_lcd_resume(struct spi_device *spi) } #else #define tosa_lcd_suspend NULL -#define tosa_lcd_resume NULL +#define tosa_lcd_reume NULL #endif static struct spi_driver tosa_lcd_driver = { diff --git a/drivers/video/carminefb.c b/drivers/video/carminefb.c index cb09aa1fa138..caaa27d4a46a 100644 --- a/drivers/video/carminefb.c +++ b/drivers/video/carminefb.c @@ -32,11 +32,11 @@ #define CARMINEFB_DEFAULT_VIDEO_MODE 1 static unsigned int fb_mode = CARMINEFB_DEFAULT_VIDEO_MODE; -module_param(fb_mode, uint, 0444); +module_param(fb_mode, uint, 444); MODULE_PARM_DESC(fb_mode, "Initial video mode as integer."); static char *fb_mode_str; -module_param(fb_mode_str, charp, 0444); +module_param(fb_mode_str, charp, 444); MODULE_PARM_DESC(fb_mode_str, "Initial video mode in characters."); /* @@ -46,7 +46,7 @@ MODULE_PARM_DESC(fb_mode_str, "Initial video mode in characters."); * 0b010 Display 1 */ static int fb_displays = CARMINE_USE_DISPLAY0 | CARMINE_USE_DISPLAY1; -module_param(fb_displays, int, 0444); +module_param(fb_displays, int, 444); MODULE_PARM_DESC(fb_displays, "Bit mode, which displays are used"); struct carmine_hw { diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index bf9a9b773de0..8745637e4b7e 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -373,15 +373,8 @@ static void fb_flashcursor(struct work_struct *work) struct vc_data *vc = NULL; int c; int mode; - int ret; - - /* FIXME: we should sort out the unbind locking instead */ - /* instead we just fail to flash the cursor if we can't get - * the lock instead of blocking fbcon deinit */ - ret = console_trylock(); - if (ret == 0) - return; + console_lock(); if (ops && ops->currcon != -1) vc = vc_cons[ops->currcon].d; diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 7a41220aebdd..5aac00eb1830 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1651,7 +1651,6 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) if (ret) return -EINVAL; - unlink_framebuffer(fb_info); if (fb_info->pixmap.addr && (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) kfree(fb_info->pixmap.addr); @@ -1659,6 +1658,7 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) registered_fb[i] = NULL; num_registered_fb--; fb_cleanup_device(fb_info); + device_destroy(fb_class, MKDEV(FB_MAJOR, i)); event.info = fb_info; fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); @@ -1667,22 +1667,6 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) return 0; } -int unlink_framebuffer(struct fb_info *fb_info) -{ - int i; - - i = fb_info->node; - if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info) - return -EINVAL; - - if (fb_info->dev) { - device_destroy(fb_class, MKDEV(FB_MAJOR, i)); - fb_info->dev = NULL; - } - return 0; -} -EXPORT_SYMBOL(unlink_framebuffer); - void remove_conflicting_framebuffers(struct apertures_struct *a, const char *name, bool primary) { @@ -1754,6 +1738,8 @@ void fb_set_suspend(struct fb_info *info, int state) { struct fb_event event; + if (!lock_fb_info(info)) + return; event.info = info; if (state) { fb_notifier_call_chain(FB_EVENT_SUSPEND, &event); @@ -1762,6 +1748,7 @@ void fb_set_suspend(struct fb_info *info, int state) info->state = FBINFO_STATE_RUNNING; fb_notifier_call_chain(FB_EVENT_RESUME, &event); } + unlock_fb_info(info); } /** diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index 67afa9c2289d..04251ce89184 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c @@ -399,12 +399,9 @@ static ssize_t store_fbstate(struct device *device, state = simple_strtoul(buf, &last, 0); - if (!lock_fb_info(fb_info)) - return -ENODEV; console_lock(); fb_set_suspend(fb_info, (int)state); console_unlock(); - unlock_fb_info(fb_info); return count; } diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index 2f902900c80d..0b2f2dd41416 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c @@ -365,8 +365,7 @@ static void mxsfb_disable_controller(struct fb_info *fb_info) loop--; } - reg = readl(host->base + LCDC_VDCTRL4); - writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4); + writel(VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4 + REG_CLR); clk_disable(host->clk); diff --git a/drivers/video/offb.c b/drivers/video/offb.c index 3251a0236d56..cb163a5397be 100644 --- a/drivers/video/offb.c +++ b/drivers/video/offb.c @@ -100,32 +100,36 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) { struct offb_par *par = (struct offb_par *) info->par; - - if (info->fix.visual == FB_VISUAL_TRUECOLOR) { - u32 *pal = info->pseudo_palette; - u32 cr = red >> (16 - info->var.red.length); - u32 cg = green >> (16 - info->var.green.length); - u32 cb = blue >> (16 - info->var.blue.length); - u32 value; - - if (regno >= 16) - return -EINVAL; - - value = (cr << info->var.red.offset) | - (cg << info->var.green.offset) | - (cb << info->var.blue.offset); - if (info->var.transp.length > 0) { - u32 mask = (1 << info->var.transp.length) - 1; - mask <<= info->var.transp.offset; - value |= mask; + int i, depth; + u32 *pal = info->pseudo_palette; + + depth = info->var.bits_per_pixel; + if (depth == 16) + depth = (info->var.green.length == 5) ? 15 : 16; + + if (regno > 255 || + (depth == 16 && regno > 63) || + (depth == 15 && regno > 31)) + return 1; + + if (regno < 16) { + switch (depth) { + case 15: + pal[regno] = (regno << 10) | (regno << 5) | regno; + break; + case 16: + pal[regno] = (regno << 11) | (regno << 5) | regno; + break; + case 24: + pal[regno] = (regno << 16) | (regno << 8) | regno; + break; + case 32: + i = (regno << 8) | regno; + pal[regno] = (i << 16) | i; + break; } - pal[regno] = value; - return 0; } - if (regno > 255) - return -EINVAL; - red >>= 8; green >>= 8; blue >>= 8; @@ -377,7 +381,7 @@ static void __init offb_init_fb(const char *name, const char *full_name, int pitch, unsigned long address, int foreign_endian, struct device_node *dp) { - unsigned long res_size = pitch * height; + unsigned long res_size = pitch * height * (depth + 7) / 8; struct offb_par *par = &default_par; unsigned long res_start = address; struct fb_fix_screeninfo *fix; diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index fadd6a0836c7..b0555f4f0a78 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -29,7 +29,6 @@ #include #include #include -#include #include