From 5c3709d255fe3e7b4f7f1cba47780a85b15ae372 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 10 Jan 2013 10:57:01 -0800 Subject: [PATCH] --- yaml --- r: 348659 b: refs/heads/master c: 54b956b903607f8f8878754dd4352da6a54a1da2 h: refs/heads/master i: 348657: bf1f8f275204477851fa6220628cecacaae3f4b9 348655: ed14e33da4d3b9ae3de0f0e005d2ffbbc7c596cf v: v3 --- [refs] | 2 +- trunk/MAINTAINERS | 21 +- trunk/arch/mn10300/Kconfig | 1 - .../arch/powerpc/include/uapi/asm/kvm_para.h | 2 +- trunk/arch/powerpc/kvm/book3s_hv_ras.c | 4 - trunk/arch/s390/include/asm/dma.h | 6 - trunk/arch/s390/include/asm/io.h | 5 - trunk/arch/s390/include/asm/irq.h | 78 +- trunk/arch/s390/include/uapi/asm/unistd.h | 3 +- trunk/arch/s390/kernel/compat_wrapper.S | 6 - trunk/arch/s390/kernel/debug.c | 11 +- trunk/arch/s390/kernel/irq.c | 124 +- trunk/arch/s390/kernel/nmi.c | 2 +- trunk/arch/s390/kernel/perf_cpum_cf.c | 2 +- trunk/arch/s390/kernel/runtime_instr.c | 2 +- trunk/arch/s390/kernel/setup.c | 3 +- trunk/arch/s390/kernel/smp.c | 12 +- trunk/arch/s390/kernel/syscalls.S | 1 - trunk/arch/s390/kernel/time.c | 4 +- trunk/arch/s390/kernel/topology.c | 2 - trunk/arch/s390/mm/fault.c | 2 +- trunk/arch/s390/oprofile/hwsampler.c | 2 +- trunk/arch/s390/pci/pci.c | 33 +- trunk/arch/s390/pci/pci_dma.c | 2 + trunk/arch/sparc/include/uapi/asm/unistd.h | 3 +- trunk/arch/sparc/kernel/pci.c | 12 +- trunk/arch/sparc/kernel/pci_psycho.c | 3 +- trunk/arch/sparc/kernel/pci_sabre.c | 3 +- trunk/arch/sparc/kernel/pci_schizo.c | 5 +- trunk/arch/sparc/kernel/systbls_32.S | 2 +- trunk/arch/sparc/kernel/systbls_64.S | 4 +- trunk/arch/x86/kernel/kvm.c | 12 +- trunk/arch/x86/kvm/x86.c | 24 +- trunk/drivers/gpu/drm/drm_mm.c | 45 +- trunk/drivers/gpu/drm/i915/i915_gem.c | 25 +- trunk/drivers/gpu/drm/i915/intel_display.c | 33 +- trunk/drivers/gpu/drm/i915/intel_lvds.c | 8 + trunk/drivers/gpu/drm/i915/intel_pm.c | 25 +- trunk/drivers/gpu/drm/i915/intel_sprite.c | 10 +- .../gpu/drm/nouveau/core/core/client.c | 4 +- .../gpu/drm/nouveau/core/core/handle.c | 5 +- .../gpu/drm/nouveau/core/engine/disp/nv50.c | 46 +- .../drm/nouveau/core/include/core/client.h | 3 - .../nouveau/core/include/subdev/bios/pll.h | 2 - .../gpu/drm/nouveau/core/subdev/bios/init.c | 1 + .../gpu/drm/nouveau/core/subdev/clock/nvc0.c | 2 - .../gpu/drm/nouveau/core/subdev/fb/nvc0.c | 6 +- .../drm/nouveau/core/subdev/instmem/base.c | 35 +- .../gpu/drm/nouveau/core/subdev/vm/base.c | 4 +- .../gpu/drm/nouveau/nouveau_connector.c | 30 +- .../drivers/gpu/drm/nouveau/nouveau_display.c | 9 + trunk/drivers/gpu/drm/nouveau/nouveau_drm.c | 7 +- trunk/drivers/gpu/drm/nouveau/nouveau_fence.h | 1 - trunk/drivers/gpu/drm/nouveau/nv04_dfp.c | 2 +- trunk/drivers/gpu/drm/nouveau/nv10_fence.c | 8 - trunk/drivers/gpu/drm/nouveau/nv50_fence.c | 1 - trunk/drivers/gpu/drm/radeon/r600_cs.c | 12 +- trunk/drivers/gpu/drm/radeon/radeon_cs.c | 9 +- .../gpu/drm/radeon/radeon_legacy_encoders.c | 8 - trunk/drivers/gpu/drm/udl/udl_connector.c | 17 +- trunk/drivers/hwmon/vexpress.c | 1 - trunk/drivers/misc/mei/amthif.c | 6 +- trunk/drivers/net/ethernet/adi/Kconfig | 1 - .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 30 +- .../ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 2 +- .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 60 +- trunk/drivers/net/ethernet/emulex/benet/be.h | 1 - .../net/ethernet/emulex/benet/be_main.c | 29 +- .../net/ethernet/qlogic/qlge/qlge_main.c | 2 +- trunk/drivers/net/ethernet/xilinx/Kconfig | 2 +- .../net/ethernet/xilinx/xilinx_axienet_main.c | 2 +- trunk/drivers/net/tun.c | 44 +- trunk/drivers/net/wireless/ath/Kconfig | 1 - trunk/drivers/net/wireless/ath/Makefile | 1 - .../drivers/net/wireless/ath/wil6210/Kconfig | 29 - .../drivers/net/wireless/ath/wil6210/Makefile | 13 - .../net/wireless/ath/wil6210/cfg80211.c | 573 --------- .../net/wireless/ath/wil6210/dbg_hexdump.h | 30 - .../net/wireless/ath/wil6210/debugfs.c | 603 --------- .../net/wireless/ath/wil6210/interrupt.c | 471 ------- trunk/drivers/net/wireless/ath/wil6210/main.c | 407 ------ .../drivers/net/wireless/ath/wil6210/netdev.c | 157 --- .../net/wireless/ath/wil6210/pcie_bus.c | 223 ---- trunk/drivers/net/wireless/ath/wil6210/txrx.c | 871 ------------- trunk/drivers/net/wireless/ath/wil6210/txrx.h | 362 ------ .../net/wireless/ath/wil6210/wil6210.h | 363 ------ trunk/drivers/net/wireless/ath/wil6210/wmi.c | 975 -------------- trunk/drivers/net/wireless/ath/wil6210/wmi.h | 1116 ----------------- trunk/drivers/net/wireless/b43/b43.h | 5 - trunk/drivers/net/wireless/b43/main.c | 54 +- trunk/drivers/net/wireless/b43/main.h | 5 +- .../drivers/net/wireless/iwlegacy/3945-mac.c | 2 +- trunk/drivers/net/wireless/iwlwifi/dvm/tx.c | 24 +- trunk/drivers/net/wireless/iwlwifi/pcie/rx.c | 1 - trunk/drivers/net/wireless/mwifiex/cfg80211.c | 2 +- .../drivers/net/wireless/mwifiex/sta_ioctl.c | 21 +- trunk/drivers/net/wireless/mwl8k.c | 4 +- .../wireless/rtlwifi/rtl8192c/phy_common.c | 2 +- .../net/wireless/rtlwifi/rtl8723ae/phy.c | 2 +- trunk/drivers/pci/iov.c | 2 +- trunk/drivers/platform/x86/acer-wmi.c | 60 +- trunk/drivers/platform/x86/asus-laptop.c | 19 +- trunk/drivers/platform/x86/samsung-laptop.c | 10 - trunk/drivers/platform/x86/sony-laptop.c | 15 +- trunk/drivers/rtc/rtc-da9055.c | 2 +- trunk/drivers/s390/block/dasd_diag.c | 2 +- trunk/drivers/s390/block/dasd_eckd.c | 2 +- trunk/drivers/s390/block/dasd_fba.c | 2 +- trunk/drivers/s390/char/con3215.c | 8 +- trunk/drivers/s390/char/raw3270.c | 2 +- trunk/drivers/s390/char/sclp.c | 4 +- trunk/drivers/s390/char/tape_34xx.c | 2 +- trunk/drivers/s390/char/tape_3590.c | 2 +- trunk/drivers/s390/char/vmur.c | 2 +- trunk/drivers/s390/cio/chsc_sch.c | 2 +- trunk/drivers/s390/cio/cio.c | 10 +- trunk/drivers/s390/cio/device.c | 12 +- trunk/drivers/s390/cio/device.h | 5 +- trunk/drivers/s390/cio/eadm_sch.c | 2 +- trunk/drivers/s390/cio/qdio_thinint.c | 2 +- trunk/drivers/s390/crypto/ap_bus.c | 2 +- trunk/drivers/s390/kvm/kvm_virtio.c | 2 +- trunk/drivers/s390/net/claw.c | 2 +- trunk/drivers/s390/net/ctcm_main.c | 2 +- trunk/drivers/s390/net/lcs.c | 2 +- trunk/drivers/video/ssd1307fb.c | 4 +- trunk/fs/exec.c | 3 +- trunk/fs/seq_file.c | 2 +- trunk/include/drm/drm_mm.h | 2 +- trunk/include/linux/audit.h | 4 +- trunk/include/linux/compaction.h | 4 +- trunk/include/linux/cpu_rmap.h | 13 +- trunk/include/linux/init.h | 20 - trunk/include/linux/interrupt.h | 5 + trunk/include/linux/lockdep.h | 3 - trunk/include/linux/mm.h | 1 + trunk/include/linux/netdevice.h | 3 - trunk/include/linux/rbtree_augmented.h | 14 +- trunk/include/linux/rwsem.h | 9 - trunk/include/uapi/linux/audit.h | 2 +- trunk/kernel/audit.c | 40 +- trunk/kernel/audit_tree.c | 26 +- trunk/kernel/audit_watch.c | 2 - trunk/kernel/auditfilter.c | 1 + trunk/kernel/auditsc.c | 20 +- trunk/kernel/rwsem.c | 10 - trunk/kernel/trace/trace.c | 2 - trunk/lib/cpu_rmap.c | 54 +- trunk/lib/rbtree.c | 20 +- trunk/mm/bootmem.c | 24 +- trunk/mm/compaction.c | 98 +- trunk/mm/huge_memory.c | 15 +- trunk/mm/internal.h | 1 + trunk/mm/memblock.c | 3 +- trunk/mm/migrate.c | 14 +- trunk/mm/mmap.c | 2 +- trunk/mm/page_alloc.c | 37 +- trunk/net/core/dev.c | 8 - trunk/net/ipv4/ip_sockglue.c | 2 +- trunk/net/ipv4/tcp.c | 15 +- trunk/net/ipv4/tcp_input.c | 4 +- trunk/net/ipv6/addrconf.c | 27 +- trunk/net/iucv/iucv.c | 2 +- trunk/net/mac80211/cfg.c | 2 - trunk/net/mac80211/chan.c | 38 - trunk/net/mac80211/ibss.c | 9 +- trunk/net/mac80211/ieee80211_i.h | 16 +- trunk/net/mac80211/iface.c | 48 +- trunk/net/mac80211/mesh.c | 8 +- trunk/net/mac80211/mesh.h | 2 +- trunk/net/mac80211/mlme.c | 75 +- trunk/net/mac80211/scan.c | 46 +- trunk/net/mac80211/sta_info.c | 46 +- trunk/net/mac80211/sta_info.h | 3 +- trunk/net/sunrpc/clnt.c | 2 +- trunk/net/sunrpc/sched.c | 3 +- trunk/net/sunrpc/xprt.c | 12 +- trunk/net/wireless/core.c | 3 +- 178 files changed, 762 insertions(+), 7497 deletions(-) delete mode 100644 trunk/drivers/net/wireless/ath/wil6210/Kconfig delete mode 100644 trunk/drivers/net/wireless/ath/wil6210/Makefile delete mode 100644 trunk/drivers/net/wireless/ath/wil6210/cfg80211.c delete mode 100644 trunk/drivers/net/wireless/ath/wil6210/dbg_hexdump.h delete mode 100644 trunk/drivers/net/wireless/ath/wil6210/debugfs.c delete mode 100644 trunk/drivers/net/wireless/ath/wil6210/interrupt.c delete mode 100644 trunk/drivers/net/wireless/ath/wil6210/main.c delete mode 100644 trunk/drivers/net/wireless/ath/wil6210/netdev.c delete mode 100644 trunk/drivers/net/wireless/ath/wil6210/pcie_bus.c delete mode 100644 trunk/drivers/net/wireless/ath/wil6210/txrx.c delete mode 100644 trunk/drivers/net/wireless/ath/wil6210/txrx.h delete mode 100644 trunk/drivers/net/wireless/ath/wil6210/wil6210.h delete mode 100644 trunk/drivers/net/wireless/ath/wil6210/wmi.c delete mode 100644 trunk/drivers/net/wireless/ath/wil6210/wmi.h diff --git a/[refs] b/[refs] index 756f94daf247..4b88fd75950f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f6a0e2ca7b1fe89da4e4b0afa6ba08dc34f1a0f7 +refs/heads/master: 54b956b903607f8f8878754dd4352da6a54a1da2 diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index cd5b31fec01c..915564eda145 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -228,7 +228,7 @@ S: Maintained F: drivers/platform/x86/acerhdf.c ACER WMI LAPTOP EXTRAS -M: "Lee, Chun-Yi" +M: Joey Lee L: platform-driver-x86@vger.kernel.org S: Maintained F: drivers/platform/x86/acer-wmi.c @@ -648,7 +648,7 @@ F: arch/arm/ ARM SUB-ARCHITECTURES L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -S: Maintained +S: MAINTAINED F: arch/arm/mach-*/ F: arch/arm/plat-*/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git @@ -1351,14 +1351,6 @@ W: http://wireless.kernel.org/en/users/Drivers/ath9k S: Supported F: drivers/net/wireless/ath/ath9k/ -WILOCITY WIL6210 WIRELESS DRIVER -M: Vladimir Kondratiev -L: linux-wireless@vger.kernel.org -L: wil6210@qca.qualcomm.com -S: Supported -W: http://wireless.kernel.org/en/users/Drivers/wil6210 -F: drivers/net/wireless/ath/wil6210/ - CARL9170 LINUX COMMUNITY WIRELESS DRIVER M: Christian Lamparter L: linux-wireless@vger.kernel.org @@ -5085,7 +5077,7 @@ S: Maintained F: drivers/media/radio/radio-mr800.c MSI LAPTOP SUPPORT -M: "Lee, Chun-Yi" +M: "Lee, Chun-Yi" L: platform-driver-x86@vger.kernel.org S: Maintained F: drivers/platform/x86/msi-laptop.c @@ -5515,7 +5507,8 @@ M: Benoît Cousson M: Paul Walmsley L: linux-omap@vger.kernel.org S: Maintained -F: arch/arm/mach-omap2/omap_hwmod.* +F: arch/arm/mach-omap2/omap_hwmod.c +F: arch/arm/plat-omap/include/plat/omap_hwmod.h OMAP HWMOD DATA FOR OMAP4-BASED DEVICES M: Benoît Cousson @@ -7341,7 +7334,7 @@ S: Odd Fixes F: drivers/staging/speakup/ STAGING - TI DSP BRIDGE DRIVERS -M: Omar Ramirez Luna +M: Omar Ramirez Luna S: Odd Fixes F: drivers/staging/tidspbridge/ @@ -8533,7 +8526,7 @@ F: Documentation/x86/ F: arch/x86/ X86 PLATFORM DRIVERS -M: Matthew Garrett +M: Matthew Garrett L: platform-driver-x86@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.git S: Maintained diff --git a/trunk/arch/mn10300/Kconfig b/trunk/arch/mn10300/Kconfig index e70001cfa05b..aa03f2e13385 100644 --- a/trunk/arch/mn10300/Kconfig +++ b/trunk/arch/mn10300/Kconfig @@ -6,7 +6,6 @@ config MN10300 select ARCH_WANT_IPC_PARSE_VERSION select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_KGDB - select GENERIC_ATOMIC64 select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER select GENERIC_CLOCKEVENTS select MODULES_USE_ELF_RELA diff --git a/trunk/arch/powerpc/include/uapi/asm/kvm_para.h b/trunk/arch/powerpc/include/uapi/asm/kvm_para.h index e3af3286a068..ed0e0254b47f 100644 --- a/trunk/arch/powerpc/include/uapi/asm/kvm_para.h +++ b/trunk/arch/powerpc/include/uapi/asm/kvm_para.h @@ -78,7 +78,7 @@ struct kvm_vcpu_arch_shared { #define KVM_HCALL_TOKEN(num) _EV_HCALL_TOKEN(EV_KVM_VENDOR_ID, num) -#include +#include #define KVM_FEATURE_MAGIC_PAGE 1 diff --git a/trunk/arch/powerpc/kvm/book3s_hv_ras.c b/trunk/arch/powerpc/kvm/book3s_hv_ras.c index a353c485808c..35f3cf0269b3 100644 --- a/trunk/arch/powerpc/kvm/book3s_hv_ras.c +++ b/trunk/arch/powerpc/kvm/book3s_hv_ras.c @@ -79,9 +79,7 @@ static void flush_tlb_power7(struct kvm_vcpu *vcpu) static long kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu) { unsigned long srr1 = vcpu->arch.shregs.msr; -#ifdef CONFIG_PPC_POWERNV struct opal_machine_check_event *opal_evt; -#endif long handled = 1; if (srr1 & SRR1_MC_LDSTERR) { @@ -119,7 +117,6 @@ static long kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu) handled = 0; } -#ifdef CONFIG_PPC_POWERNV /* * See if OPAL has already handled the condition. * We assume that if the condition is recovered then OPAL @@ -134,7 +131,6 @@ static long kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu) if (handled) opal_evt->in_use = 0; -#endif return handled; } diff --git a/trunk/arch/s390/include/asm/dma.h b/trunk/arch/s390/include/asm/dma.h index bb9bdcd20864..de015d85e3e5 100644 --- a/trunk/arch/s390/include/asm/dma.h +++ b/trunk/arch/s390/include/asm/dma.h @@ -10,10 +10,4 @@ */ #define MAX_DMA_ADDRESS 0x80000000 -#ifdef CONFIG_PCI -extern int isa_dma_bridge_buggy; -#else -#define isa_dma_bridge_buggy (0) -#endif - #endif /* _ASM_S390_DMA_H */ diff --git a/trunk/arch/s390/include/asm/io.h b/trunk/arch/s390/include/asm/io.h index 27cb32185ce1..16c3eb164f4f 100644 --- a/trunk/arch/s390/include/asm/io.h +++ b/trunk/arch/s390/include/asm/io.h @@ -85,11 +85,6 @@ static inline void iounmap(volatile void __iomem *addr) #define __raw_writel zpci_write_u32 #define __raw_writeq zpci_write_u64 -#define readb_relaxed readb -#define readw_relaxed readw -#define readl_relaxed readl -#define readq_relaxed readq - #endif /* CONFIG_PCI */ #include diff --git a/trunk/arch/s390/include/asm/irq.h b/trunk/arch/s390/include/asm/irq.h index 7def77302d63..e6972f85d2b0 100644 --- a/trunk/arch/s390/include/asm/irq.h +++ b/trunk/arch/s390/include/asm/irq.h @@ -2,61 +2,43 @@ #define _ASM_IRQ_H #include -#include -#include #include -enum interruption_main_class { +enum interruption_class { EXTERNAL_INTERRUPT, IO_INTERRUPT, - NR_IRQS -}; - -enum interruption_class { - IRQEXT_CLK, - IRQEXT_EXC, - IRQEXT_EMS, - IRQEXT_TMR, - IRQEXT_TLA, - IRQEXT_PFL, - IRQEXT_DSD, - IRQEXT_VRT, - IRQEXT_SCP, - IRQEXT_IUC, - IRQEXT_CMS, - IRQEXT_CMC, - IRQEXT_CMR, - IRQIO_CIO, - IRQIO_QAI, - IRQIO_DAS, - IRQIO_C15, - IRQIO_C70, - IRQIO_TAP, - IRQIO_VMR, - IRQIO_LCS, - IRQIO_CLW, - IRQIO_CTC, - IRQIO_APB, - IRQIO_ADM, - IRQIO_CSC, - IRQIO_PCI, - IRQIO_MSI, + EXTINT_CLK, + EXTINT_EXC, + EXTINT_EMS, + EXTINT_TMR, + EXTINT_TLA, + EXTINT_PFL, + EXTINT_DSD, + EXTINT_VRT, + EXTINT_SCP, + EXTINT_IUC, + EXTINT_CMS, + EXTINT_CMC, + EXTINT_CMR, + IOINT_CIO, + IOINT_QAI, + IOINT_DAS, + IOINT_C15, + IOINT_C70, + IOINT_TAP, + IOINT_VMR, + IOINT_LCS, + IOINT_CLW, + IOINT_CTC, + IOINT_APB, + IOINT_ADM, + IOINT_CSC, + IOINT_PCI, + IOINT_MSI, NMI_NMI, - CPU_RST, - NR_ARCH_IRQS + NR_IRQS, }; -struct irq_stat { - unsigned int irqs[NR_ARCH_IRQS]; -}; - -DECLARE_PER_CPU_SHARED_ALIGNED(struct irq_stat, irq_stat); - -static __always_inline void inc_irq_stat(enum interruption_class irq) -{ - __get_cpu_var(irq_stat).irqs[irq]++; -} - struct ext_code { unsigned short subcode; unsigned short code; diff --git a/trunk/arch/s390/include/uapi/asm/unistd.h b/trunk/arch/s390/include/uapi/asm/unistd.h index 864f693c237f..63e6078699f1 100644 --- a/trunk/arch/s390/include/uapi/asm/unistd.h +++ b/trunk/arch/s390/include/uapi/asm/unistd.h @@ -279,8 +279,7 @@ #define __NR_process_vm_writev 341 #define __NR_s390_runtime_instr 342 #define __NR_kcmp 343 -#define __NR_finit_module 344 -#define NR_syscalls 345 +#define NR_syscalls 344 /* * There are some system calls that are not present on 64 bit, some diff --git a/trunk/arch/s390/kernel/compat_wrapper.S b/trunk/arch/s390/kernel/compat_wrapper.S index 9b9a805656b5..827e094a2f49 100644 --- a/trunk/arch/s390/kernel/compat_wrapper.S +++ b/trunk/arch/s390/kernel/compat_wrapper.S @@ -1659,9 +1659,3 @@ ENTRY(sys_kcmp_wrapper) llgfr %r5,%r5 # unsigned long llgfr %r6,%r6 # unsigned long jg sys_kcmp - -ENTRY(sys_finit_module_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # const char __user * - lgfr %r4,%r4 # int - jg sys_finit_module diff --git a/trunk/arch/s390/kernel/debug.c b/trunk/arch/s390/kernel/debug.c index 4e8215e0d4b6..ba500d8dc392 100644 --- a/trunk/arch/s390/kernel/debug.c +++ b/trunk/arch/s390/kernel/debug.c @@ -1127,14 +1127,13 @@ debug_register_view(debug_info_t * id, struct debug_view *view) if (i == DEBUG_MAX_VIEWS) { pr_err("Registering view %s/%s would exceed the maximum " "number of views %i\n", id->name, view->name, i); + debugfs_remove(pde); rc = -1; } else { id->views[i] = view; id->debugfs_entries[i] = pde; } spin_unlock_irqrestore(&id->lock, flags); - if (rc) - debugfs_remove(pde); out: return rc; } @@ -1147,9 +1146,9 @@ EXPORT_SYMBOL(debug_register_view); int debug_unregister_view(debug_info_t * id, struct debug_view *view) { - struct dentry *dentry = NULL; + int rc = 0; + int i; unsigned long flags; - int i, rc = 0; if (!id) goto out; @@ -1161,12 +1160,10 @@ debug_unregister_view(debug_info_t * id, struct debug_view *view) if (i == DEBUG_MAX_VIEWS) rc = -1; else { - dentry = id->debugfs_entries[i]; + debugfs_remove(id->debugfs_entries[i]); id->views[i] = NULL; - id->debugfs_entries[i] = NULL; } spin_unlock_irqrestore(&id->lock, flags); - debugfs_remove(dentry); out: return rc; } diff --git a/trunk/arch/s390/kernel/irq.c b/trunk/arch/s390/kernel/irq.c index 9df824ea1667..bf24293970ce 100644 --- a/trunk/arch/s390/kernel/irq.c +++ b/trunk/arch/s390/kernel/irq.c @@ -24,65 +24,43 @@ #include #include "entry.h" -DEFINE_PER_CPU_SHARED_ALIGNED(struct irq_stat, irq_stat); -EXPORT_PER_CPU_SYMBOL_GPL(irq_stat); - struct irq_class { char *name; char *desc; }; -/* - * The list of "main" irq classes on s390. This is the list of interrrupts - * that appear both in /proc/stat ("intr" line) and /proc/interrupts. - * Historically only external and I/O interrupts have been part of /proc/stat. - * We can't add the split external and I/O sub classes since the first field - * in the "intr" line in /proc/stat is supposed to be the sum of all other - * fields. - * Since the external and I/O interrupt fields are already sums we would end - * up with having a sum which accounts each interrupt twice. - */ -static const struct irq_class irqclass_main_desc[NR_IRQS] = { +static const struct irq_class intrclass_names[] = { [EXTERNAL_INTERRUPT] = {.name = "EXT"}, - [IO_INTERRUPT] = {.name = "I/O"} -}; - -/* - * The list of split external and I/O interrupts that appear only in - * /proc/interrupts. - * In addition this list contains non external / I/O events like NMIs. - */ -static const struct irq_class irqclass_sub_desc[NR_ARCH_IRQS] = { - [IRQEXT_CLK] = {.name = "CLK", .desc = "[EXT] Clock Comparator"}, - [IRQEXT_EXC] = {.name = "EXC", .desc = "[EXT] External Call"}, - [IRQEXT_EMS] = {.name = "EMS", .desc = "[EXT] Emergency Signal"}, - [IRQEXT_TMR] = {.name = "TMR", .desc = "[EXT] CPU Timer"}, - [IRQEXT_TLA] = {.name = "TAL", .desc = "[EXT] Timing Alert"}, - [IRQEXT_PFL] = {.name = "PFL", .desc = "[EXT] Pseudo Page Fault"}, - [IRQEXT_DSD] = {.name = "DSD", .desc = "[EXT] DASD Diag"}, - [IRQEXT_VRT] = {.name = "VRT", .desc = "[EXT] Virtio"}, - [IRQEXT_SCP] = {.name = "SCP", .desc = "[EXT] Service Call"}, - [IRQEXT_IUC] = {.name = "IUC", .desc = "[EXT] IUCV"}, - [IRQEXT_CMS] = {.name = "CMS", .desc = "[EXT] CPU-Measurement: Sampling"}, - [IRQEXT_CMC] = {.name = "CMC", .desc = "[EXT] CPU-Measurement: Counter"}, - [IRQEXT_CMR] = {.name = "CMR", .desc = "[EXT] CPU-Measurement: RI"}, - [IRQIO_CIO] = {.name = "CIO", .desc = "[I/O] Common I/O Layer Interrupt"}, - [IRQIO_QAI] = {.name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt"}, - [IRQIO_DAS] = {.name = "DAS", .desc = "[I/O] DASD"}, - [IRQIO_C15] = {.name = "C15", .desc = "[I/O] 3215"}, - [IRQIO_C70] = {.name = "C70", .desc = "[I/O] 3270"}, - [IRQIO_TAP] = {.name = "TAP", .desc = "[I/O] Tape"}, - [IRQIO_VMR] = {.name = "VMR", .desc = "[I/O] Unit Record Devices"}, - [IRQIO_LCS] = {.name = "LCS", .desc = "[I/O] LCS"}, - [IRQIO_CLW] = {.name = "CLW", .desc = "[I/O] CLAW"}, - [IRQIO_CTC] = {.name = "CTC", .desc = "[I/O] CTC"}, - [IRQIO_APB] = {.name = "APB", .desc = "[I/O] AP Bus"}, - [IRQIO_ADM] = {.name = "ADM", .desc = "[I/O] EADM Subchannel"}, - [IRQIO_CSC] = {.name = "CSC", .desc = "[I/O] CHSC Subchannel"}, - [IRQIO_PCI] = {.name = "PCI", .desc = "[I/O] PCI Interrupt" }, - [IRQIO_MSI] = {.name = "MSI", .desc = "[I/O] MSI Interrupt" }, + [IO_INTERRUPT] = {.name = "I/O"}, + [EXTINT_CLK] = {.name = "CLK", .desc = "[EXT] Clock Comparator"}, + [EXTINT_EXC] = {.name = "EXC", .desc = "[EXT] External Call"}, + [EXTINT_EMS] = {.name = "EMS", .desc = "[EXT] Emergency Signal"}, + [EXTINT_TMR] = {.name = "TMR", .desc = "[EXT] CPU Timer"}, + [EXTINT_TLA] = {.name = "TAL", .desc = "[EXT] Timing Alert"}, + [EXTINT_PFL] = {.name = "PFL", .desc = "[EXT] Pseudo Page Fault"}, + [EXTINT_DSD] = {.name = "DSD", .desc = "[EXT] DASD Diag"}, + [EXTINT_VRT] = {.name = "VRT", .desc = "[EXT] Virtio"}, + [EXTINT_SCP] = {.name = "SCP", .desc = "[EXT] Service Call"}, + [EXTINT_IUC] = {.name = "IUC", .desc = "[EXT] IUCV"}, + [EXTINT_CMS] = {.name = "CMS", .desc = "[EXT] CPU-Measurement: Sampling"}, + [EXTINT_CMC] = {.name = "CMC", .desc = "[EXT] CPU-Measurement: Counter"}, + [EXTINT_CMR] = {.name = "CMR", .desc = "[EXT] CPU-Measurement: RI"}, + [IOINT_CIO] = {.name = "CIO", .desc = "[I/O] Common I/O Layer Interrupt"}, + [IOINT_QAI] = {.name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt"}, + [IOINT_DAS] = {.name = "DAS", .desc = "[I/O] DASD"}, + [IOINT_C15] = {.name = "C15", .desc = "[I/O] 3215"}, + [IOINT_C70] = {.name = "C70", .desc = "[I/O] 3270"}, + [IOINT_TAP] = {.name = "TAP", .desc = "[I/O] Tape"}, + [IOINT_VMR] = {.name = "VMR", .desc = "[I/O] Unit Record Devices"}, + [IOINT_LCS] = {.name = "LCS", .desc = "[I/O] LCS"}, + [IOINT_CLW] = {.name = "CLW", .desc = "[I/O] CLAW"}, + [IOINT_CTC] = {.name = "CTC", .desc = "[I/O] CTC"}, + [IOINT_APB] = {.name = "APB", .desc = "[I/O] AP Bus"}, + [IOINT_ADM] = {.name = "ADM", .desc = "[I/O] EADM Subchannel"}, + [IOINT_CSC] = {.name = "CSC", .desc = "[I/O] CHSC Subchannel"}, + [IOINT_PCI] = {.name = "PCI", .desc = "[I/O] PCI Interrupt" }, + [IOINT_MSI] = {.name = "MSI", .desc = "[I/O] MSI Interrupt" }, [NMI_NMI] = {.name = "NMI", .desc = "[NMI] Machine Check"}, - [CPU_RST] = {.name = "RST", .desc = "[CPU] CPU Restart"}, }; /* @@ -90,34 +68,30 @@ static const struct irq_class irqclass_sub_desc[NR_ARCH_IRQS] = { */ int show_interrupts(struct seq_file *p, void *v) { - int irq = *(loff_t *) v; - int cpu; + int i = *(loff_t *) v, j; get_online_cpus(); - if (irq == 0) { + if (i == 0) { seq_puts(p, " "); - for_each_online_cpu(cpu) - seq_printf(p, "CPU%d ", cpu); + for_each_online_cpu(j) + seq_printf(p, "CPU%d ",j); seq_putc(p, '\n'); } - if (irq < NR_IRQS) { - seq_printf(p, "%s: ", irqclass_main_desc[irq].name); - for_each_online_cpu(cpu) - seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[irq]); - seq_putc(p, '\n'); - goto skip_arch_irqs; - } - for (irq = 0; irq < NR_ARCH_IRQS; irq++) { - seq_printf(p, "%s: ", irqclass_sub_desc[irq].name); - for_each_online_cpu(cpu) - seq_printf(p, "%10u ", per_cpu(irq_stat, cpu).irqs[irq]); - if (irqclass_sub_desc[irq].desc) - seq_printf(p, " %s", irqclass_sub_desc[irq].desc); - seq_putc(p, '\n'); - } -skip_arch_irqs: + + if (i < NR_IRQS) { + seq_printf(p, "%s: ", intrclass_names[i].name); +#ifndef CONFIG_SMP + seq_printf(p, "%10u ", kstat_irqs(i)); +#else + for_each_online_cpu(j) + seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); +#endif + if (intrclass_names[i].desc) + seq_printf(p, " %s", intrclass_names[i].desc); + seq_putc(p, '\n'); + } put_online_cpus(); - return 0; + return 0; } /* @@ -248,7 +222,7 @@ void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code, /* Serve timer interrupts first. */ clock_comparator_work(); } - kstat_incr_irqs_this_cpu(EXTERNAL_INTERRUPT, NULL); + kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++; if (ext_code.code != 0x1004) __get_cpu_var(s390_idle).nohz_delay = 1; diff --git a/trunk/arch/s390/kernel/nmi.c b/trunk/arch/s390/kernel/nmi.c index 7918fbea36bb..a6daa5c5cdb0 100644 --- a/trunk/arch/s390/kernel/nmi.c +++ b/trunk/arch/s390/kernel/nmi.c @@ -254,7 +254,7 @@ void notrace s390_do_machine_check(struct pt_regs *regs) int umode; nmi_enter(); - inc_irq_stat(NMI_NMI); + kstat_cpu(smp_processor_id()).irqs[NMI_NMI]++; mci = (struct mci *) &S390_lowcore.mcck_interruption_code; mcck = &__get_cpu_var(cpu_mcck); umode = user_mode(regs); diff --git a/trunk/arch/s390/kernel/perf_cpum_cf.c b/trunk/arch/s390/kernel/perf_cpum_cf.c index 86ec7447e1f5..c4e7269d4a09 100644 --- a/trunk/arch/s390/kernel/perf_cpum_cf.c +++ b/trunk/arch/s390/kernel/perf_cpum_cf.c @@ -229,7 +229,7 @@ static void cpumf_measurement_alert(struct ext_code ext_code, if (!(alert & CPU_MF_INT_CF_MASK)) return; - inc_irq_stat(IRQEXT_CMC); + kstat_cpu(smp_processor_id()).irqs[EXTINT_CMC]++; cpuhw = &__get_cpu_var(cpu_hw_events); /* Measurement alerts are shared and might happen when the PMU diff --git a/trunk/arch/s390/kernel/runtime_instr.c b/trunk/arch/s390/kernel/runtime_instr.c index 077a99389b07..61066f6f71a5 100644 --- a/trunk/arch/s390/kernel/runtime_instr.c +++ b/trunk/arch/s390/kernel/runtime_instr.c @@ -71,7 +71,7 @@ static void runtime_instr_int_handler(struct ext_code ext_code, if (!(param32 & CPU_MF_INT_RI_MASK)) return; - inc_irq_stat(IRQEXT_CMR); + kstat_cpu(smp_processor_id()).irqs[EXTINT_CMR]++; if (!current->thread.ri_cb) return; diff --git a/trunk/arch/s390/kernel/setup.c b/trunk/arch/s390/kernel/setup.c index a5360de85ec7..2568590973ad 100644 --- a/trunk/arch/s390/kernel/setup.c +++ b/trunk/arch/s390/kernel/setup.c @@ -16,7 +16,7 @@ #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include -#include +#include #include #include #include @@ -289,7 +289,6 @@ void machine_power_off(void) * Dummy power off function. */ void (*pm_power_off)(void) = machine_power_off; -EXPORT_SYMBOL_GPL(pm_power_off); static int __init early_parse_mem(char *p) { diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index 7433a2f9e5cc..0b45baa55438 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -433,9 +433,9 @@ static void do_ext_call_interrupt(struct ext_code ext_code, cpu = smp_processor_id(); if (ext_code.code == 0x1202) - inc_irq_stat(IRQEXT_EXC); + kstat_cpu(cpu).irqs[EXTINT_EXC]++; else - inc_irq_stat(IRQEXT_EMS); + kstat_cpu(cpu).irqs[EXTINT_EMS]++; /* * handle bit signal external calls */ @@ -623,10 +623,9 @@ static struct sclp_cpu_info *smp_get_cpu_info(void) return info; } -static int __cpuinit smp_add_present_cpu(int cpu); +static int smp_add_present_cpu(int cpu); -static int __cpuinit __smp_rescan_cpus(struct sclp_cpu_info *info, - int sysfs_add) +static int __smp_rescan_cpus(struct sclp_cpu_info *info, int sysfs_add) { struct pcpu *pcpu; cpumask_t avail; @@ -709,7 +708,6 @@ static void __cpuinit smp_start_secondary(void *cpuvoid) pfault_init(); notify_cpu_starting(smp_processor_id()); set_cpu_online(smp_processor_id(), true); - inc_irq_stat(CPU_RST); local_irq_enable(); /* cpu_idle will call schedule for us */ cpu_idle(); @@ -987,7 +985,7 @@ static int __cpuinit smp_cpu_notify(struct notifier_block *self, return notifier_from_errno(err); } -static int __cpuinit smp_add_present_cpu(int cpu) +static int smp_add_present_cpu(int cpu) { struct cpu *c = &pcpu_devices[cpu].cpu; struct device *s = &c->dev; diff --git a/trunk/arch/s390/kernel/syscalls.S b/trunk/arch/s390/kernel/syscalls.S index 6a6c61f94dd3..48174850f3b0 100644 --- a/trunk/arch/s390/kernel/syscalls.S +++ b/trunk/arch/s390/kernel/syscalls.S @@ -352,4 +352,3 @@ SYSCALL(sys_process_vm_readv,sys_process_vm_readv,compat_sys_process_vm_readv_wr SYSCALL(sys_process_vm_writev,sys_process_vm_writev,compat_sys_process_vm_writev_wrapper) SYSCALL(sys_ni_syscall,sys_s390_runtime_instr,sys_s390_runtime_instr_wrapper) SYSCALL(sys_kcmp,sys_kcmp,sys_kcmp_wrapper) -SYSCALL(sys_finit_module,sys_finit_module,sys_finit_module_wrapper) diff --git a/trunk/arch/s390/kernel/time.c b/trunk/arch/s390/kernel/time.c index aff0e350d776..7fcd690d42c7 100644 --- a/trunk/arch/s390/kernel/time.c +++ b/trunk/arch/s390/kernel/time.c @@ -168,7 +168,7 @@ static void clock_comparator_interrupt(struct ext_code ext_code, unsigned int param32, unsigned long param64) { - inc_irq_stat(IRQEXT_CLK); + kstat_cpu(smp_processor_id()).irqs[EXTINT_CLK]++; if (S390_lowcore.clock_comparator == -1ULL) set_clock_comparator(S390_lowcore.clock_comparator); } @@ -179,7 +179,7 @@ static void stp_timing_alert(struct stp_irq_parm *); static void timing_alert_interrupt(struct ext_code ext_code, unsigned int param32, unsigned long param64) { - inc_irq_stat(IRQEXT_TLA); + kstat_cpu(smp_processor_id()).irqs[EXTINT_TLA]++; if (param32 & 0x00c40000) etr_timing_alert((struct etr_irq_parm *) ¶m32); if (param32 & 0x00038000) diff --git a/trunk/arch/s390/kernel/topology.c b/trunk/arch/s390/kernel/topology.c index 4b2e3e317004..f1aba87cceb8 100644 --- a/trunk/arch/s390/kernel/topology.c +++ b/trunk/arch/s390/kernel/topology.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -43,7 +42,6 @@ static struct mask_info socket_info; static struct mask_info book_info; struct cpu_topology_s390 cpu_topology[NR_CPUS]; -EXPORT_SYMBOL_GPL(cpu_topology); static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu) { diff --git a/trunk/arch/s390/mm/fault.c b/trunk/arch/s390/mm/fault.c index 2fb9e63b8fc4..42601d6e166f 100644 --- a/trunk/arch/s390/mm/fault.c +++ b/trunk/arch/s390/mm/fault.c @@ -569,7 +569,7 @@ static void pfault_interrupt(struct ext_code ext_code, subcode = ext_code.subcode; if ((subcode & 0xff00) != __SUBCODE_MASK) return; - inc_irq_stat(IRQEXT_PFL); + kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++; /* Get the token (= pid of the affected task). */ pid = sizeof(void *) == 4 ? param32 : param64; rcu_read_lock(); diff --git a/trunk/arch/s390/oprofile/hwsampler.c b/trunk/arch/s390/oprofile/hwsampler.c index b5b2916895e0..0cb385da202c 100644 --- a/trunk/arch/s390/oprofile/hwsampler.c +++ b/trunk/arch/s390/oprofile/hwsampler.c @@ -233,7 +233,7 @@ static void hws_ext_handler(struct ext_code ext_code, if (!(param32 & CPU_MF_INT_SF_MASK)) return; - inc_irq_stat(IRQEXT_CMS); + kstat_cpu(smp_processor_id()).irqs[EXTINT_CMS]++; atomic_xchg(&cb->ext_params, atomic_read(&cb->ext_params) | param32); if (hws_wq) diff --git a/trunk/arch/s390/pci/pci.c b/trunk/arch/s390/pci/pci.c index 60e0372545d2..ff49427e9941 100644 --- a/trunk/arch/s390/pci/pci.c +++ b/trunk/arch/s390/pci/pci.c @@ -160,6 +160,35 @@ int pci_proc_domain(struct pci_bus *bus) } EXPORT_SYMBOL_GPL(pci_proc_domain); +/* Store PCI function information block */ +static int zpci_store_fib(struct zpci_dev *zdev, u8 *fc) +{ + struct zpci_fib *fib; + u8 status, cc; + + fib = (void *) get_zeroed_page(GFP_KERNEL); + if (!fib) + return -ENOMEM; + + do { + cc = __stpcifc(zdev->fh, 0, fib, &status); + if (cc == 2) { + msleep(ZPCI_INSN_BUSY_DELAY); + memset(fib, 0, PAGE_SIZE); + } + } while (cc == 2); + + if (cc) + pr_err_once("%s: cc: %u status: %u\n", + __func__, cc, status); + + /* Return PCI function controls */ + *fc = fib->fc; + + free_page((unsigned long) fib); + return (cc) ? -EIO : 0; +} + /* Modify PCI: Register adapter interruptions */ static int zpci_register_airq(struct zpci_dev *zdev, unsigned int aisb, u64 aibv) @@ -440,7 +469,7 @@ static void zpci_irq_handler(void *dont, void *need) int rescan = 0, max = aisb_max; struct zdev_irq_map *imap; - inc_irq_stat(IRQIO_PCI); + kstat_cpu(smp_processor_id()).irqs[IOINT_PCI]++; sbit = start; scan: @@ -452,7 +481,7 @@ static void zpci_irq_handler(void *dont, void *need) /* find vector bit */ imap = bucket->imap[sbit]; for_each_set_bit_left(mbit, &imap->aibv, imap->msi_vecs) { - inc_irq_stat(IRQIO_MSI); + kstat_cpu(smp_processor_id()).irqs[IOINT_MSI]++; clear_bit(63 - mbit, &imap->aibv); spin_lock(&imap->lock); diff --git a/trunk/arch/s390/pci/pci_dma.c b/trunk/arch/s390/pci/pci_dma.c index a547419907c3..6138468b420f 100644 --- a/trunk/arch/s390/pci/pci_dma.c +++ b/trunk/arch/s390/pci/pci_dma.c @@ -13,6 +13,8 @@ #include #include +static enum zpci_ioat_dtype zpci_ioat_dt = ZPCI_IOTA_RTTO; + static struct kmem_cache *dma_region_table_cache; static struct kmem_cache *dma_page_table_cache; diff --git a/trunk/arch/sparc/include/uapi/asm/unistd.h b/trunk/arch/sparc/include/uapi/asm/unistd.h index 62ced589bcf7..cac719d1bc5c 100644 --- a/trunk/arch/sparc/include/uapi/asm/unistd.h +++ b/trunk/arch/sparc/include/uapi/asm/unistd.h @@ -407,9 +407,8 @@ #define __NR_process_vm_writev 339 #define __NR_kern_features 340 #define __NR_kcmp 341 -#define __NR_finit_module 342 -#define NR_syscalls 343 +#define NR_syscalls 342 /* Bitmask values returned from kern_features system call. */ #define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 diff --git a/trunk/arch/sparc/kernel/pci.c b/trunk/arch/sparc/kernel/pci.c index baf4366e2d6a..04bacce76fe6 100644 --- a/trunk/arch/sparc/kernel/pci.c +++ b/trunk/arch/sparc/kernel/pci.c @@ -378,8 +378,7 @@ static void apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p) /* Cook up fake bus resources for SUNW,simba PCI bridges which lack * a proper 'ranges' property. */ -static void apb_fake_ranges(struct pci_dev *dev, - struct pci_bus *bus, +static void apb_fake_ranges(struct pci_dev *dev, struct pci_bus *bus, struct pci_pbm_info *pbm) { struct pci_bus_region region; @@ -404,15 +403,13 @@ static void apb_fake_ranges(struct pci_dev *dev, pcibios_bus_to_resource(dev, res, ®ion); } -static void pci_of_scan_bus(struct pci_pbm_info *pbm, - struct device_node *node, +static void pci_of_scan_bus(struct pci_pbm_info *pbm, struct device_node *node, struct pci_bus *bus); #define GET_64BIT(prop, i) ((((u64) (prop)[(i)]) << 32) | (prop)[(i)+1]) static void of_scan_pci_bridge(struct pci_pbm_info *pbm, - struct device_node *node, - struct pci_dev *dev) + struct device_node *node, struct pci_dev *dev) { struct pci_bus *bus; const u32 *busrange, *ranges; @@ -503,8 +500,7 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm, pci_of_scan_bus(pbm, node, bus); } -static void pci_of_scan_bus(struct pci_pbm_info *pbm, - struct device_node *node, +static void pci_of_scan_bus(struct pci_pbm_info *pbm, struct device_node *node, struct pci_bus *bus) { struct device_node *child; diff --git a/trunk/arch/sparc/kernel/pci_psycho.c b/trunk/arch/sparc/kernel/pci_psycho.c index c647634ead2b..b85238289717 100644 --- a/trunk/arch/sparc/kernel/pci_psycho.c +++ b/trunk/arch/sparc/kernel/pci_psycho.c @@ -366,8 +366,7 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) pci_config_write8(addr, 64); } -static void psycho_scan_bus(struct pci_pbm_info *pbm, - struct device *parent) +static void psycho_scan_bus(struct pci_pbm_info *pbm, struct device *parent) { pbm_config_busmastering(pbm); pbm->is_66mhz_capable = 0; diff --git a/trunk/arch/sparc/kernel/pci_sabre.c b/trunk/arch/sparc/kernel/pci_sabre.c index 6f00d27e8dac..531186d7c9ab 100644 --- a/trunk/arch/sparc/kernel/pci_sabre.c +++ b/trunk/arch/sparc/kernel/pci_sabre.c @@ -442,8 +442,7 @@ static void sabre_scan_bus(struct pci_pbm_info *pbm, struct device *parent) sabre_register_error_handlers(pbm); } -static void sabre_pbm_init(struct pci_pbm_info *pbm, - struct platform_device *op) +static void sabre_pbm_init(struct pci_pbm_info *pbm, struct platform_device *op) { psycho_pbm_init_common(pbm, op, "SABRE", PBM_CHIP_TYPE_SABRE); pbm->pci_afsr = pbm->controller_regs + SABRE_PIOAFSR; diff --git a/trunk/arch/sparc/kernel/pci_schizo.c b/trunk/arch/sparc/kernel/pci_schizo.c index 8f76f23dac38..29e888158ae6 100644 --- a/trunk/arch/sparc/kernel/pci_schizo.c +++ b/trunk/arch/sparc/kernel/pci_schizo.c @@ -1306,9 +1306,8 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) } } -static int schizo_pbm_init(struct pci_pbm_info *pbm, - struct platform_device *op, u32 portid, - int chip_type) +static int schizo_pbm_init(struct pci_pbm_info *pbm, struct platform_device *op, + u32 portid, int chip_type) { const struct linux_prom64_registers *regs; struct device_node *dp = op->dev.of_node; diff --git a/trunk/arch/sparc/kernel/systbls_32.S b/trunk/arch/sparc/kernel/systbls_32.S index 6ac43c36bbbf..5147f574f125 100644 --- a/trunk/arch/sparc/kernel/systbls_32.S +++ b/trunk/arch/sparc/kernel/systbls_32.S @@ -85,4 +85,4 @@ sys_call_table: /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime /*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev -/*340*/ .long sys_ni_syscall, sys_kcmp, sys_finit_module +/*340*/ .long sys_ni_syscall, sys_kcmp diff --git a/trunk/arch/sparc/kernel/systbls_64.S b/trunk/arch/sparc/kernel/systbls_64.S index 1009ecb92678..cdbd9b817751 100644 --- a/trunk/arch/sparc/kernel/systbls_64.S +++ b/trunk/arch/sparc/kernel/systbls_64.S @@ -86,7 +86,7 @@ sys_call_table32: .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev -/*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module +/*340*/ .word sys_kern_features, sys_kcmp #endif /* CONFIG_COMPAT */ @@ -164,4 +164,4 @@ sys_call_table: .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev -/*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module +/*340*/ .word sys_kern_features, sys_kcmp diff --git a/trunk/arch/x86/kernel/kvm.c b/trunk/arch/x86/kernel/kvm.c index 9c2bd8bd4b4c..08b973f64032 100644 --- a/trunk/arch/x86/kernel/kvm.c +++ b/trunk/arch/x86/kernel/kvm.c @@ -43,7 +43,6 @@ #include #include #include -#include static int kvmapf = 1; @@ -122,8 +121,6 @@ void kvm_async_pf_task_wait(u32 token) struct kvm_task_sleep_node n, *e; DEFINE_WAIT(wait); - rcu_irq_enter(); - spin_lock(&b->lock); e = _find_apf_task(b, token); if (e) { @@ -131,8 +128,6 @@ void kvm_async_pf_task_wait(u32 token) hlist_del(&e->link); kfree(e); spin_unlock(&b->lock); - - rcu_irq_exit(); return; } @@ -157,16 +152,13 @@ void kvm_async_pf_task_wait(u32 token) /* * We cannot reschedule. So halt. */ - rcu_irq_exit(); native_safe_halt(); - rcu_irq_enter(); local_irq_disable(); } } if (!n.halted) finish_wait(&n.wq, &wait); - rcu_irq_exit(); return; } EXPORT_SYMBOL_GPL(kvm_async_pf_task_wait); @@ -260,10 +252,10 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code) break; case KVM_PV_REASON_PAGE_NOT_PRESENT: /* page is swapped out by the host. */ - exception_enter(regs); + rcu_irq_enter(); exit_idle(); kvm_async_pf_task_wait((u32)read_cr2()); - exception_exit(regs); + rcu_irq_exit(); break; case KVM_PV_REASON_PAGE_READY: rcu_irq_enter(); diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index c243b81e3c74..76f54461f7cb 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -120,7 +120,7 @@ struct kvm_shared_msrs { }; static struct kvm_shared_msrs_global __read_mostly shared_msrs_global; -static struct kvm_shared_msrs __percpu *shared_msrs; +static DEFINE_PER_CPU(struct kvm_shared_msrs, shared_msrs); struct kvm_stats_debugfs_item debugfs_entries[] = { { "pf_fixed", VCPU_STAT(pf_fixed) }, @@ -191,10 +191,10 @@ static void kvm_on_user_return(struct user_return_notifier *urn) static void shared_msr_update(unsigned slot, u32 msr) { + struct kvm_shared_msrs *smsr; u64 value; - unsigned int cpu = smp_processor_id(); - struct kvm_shared_msrs *smsr = per_cpu_ptr(shared_msrs, cpu); + smsr = &__get_cpu_var(shared_msrs); /* only read, and nobody should modify it at this time, * so don't need lock */ if (slot >= shared_msrs_global.nr) { @@ -226,8 +226,7 @@ static void kvm_shared_msr_cpu_online(void) void kvm_set_shared_msr(unsigned slot, u64 value, u64 mask) { - unsigned int cpu = smp_processor_id(); - struct kvm_shared_msrs *smsr = per_cpu_ptr(shared_msrs, cpu); + struct kvm_shared_msrs *smsr = &__get_cpu_var(shared_msrs); if (((value ^ smsr->values[slot].curr) & mask) == 0) return; @@ -243,8 +242,7 @@ EXPORT_SYMBOL_GPL(kvm_set_shared_msr); static void drop_user_return_notifiers(void *ignore) { - unsigned int cpu = smp_processor_id(); - struct kvm_shared_msrs *smsr = per_cpu_ptr(shared_msrs, cpu); + struct kvm_shared_msrs *smsr = &__get_cpu_var(shared_msrs); if (smsr->registered) kvm_on_user_return(&smsr->urn); @@ -5235,16 +5233,9 @@ int kvm_arch_init(void *opaque) goto out; } - r = -ENOMEM; - shared_msrs = alloc_percpu(struct kvm_shared_msrs); - if (!shared_msrs) { - printk(KERN_ERR "kvm: failed to allocate percpu kvm_shared_msrs\n"); - goto out; - } - r = kvm_mmu_module_init(); if (r) - goto out_free_percpu; + goto out; kvm_set_mmio_spte_mask(); kvm_init_msr_list(); @@ -5267,8 +5258,6 @@ int kvm_arch_init(void *opaque) return 0; -out_free_percpu: - free_percpu(shared_msrs); out: return r; } @@ -5286,7 +5275,6 @@ void kvm_arch_exit(void) #endif kvm_x86_ops = NULL; kvm_mmu_module_exit(); - free_percpu(shared_msrs); } int kvm_emulate_halt(struct kvm_vcpu *vcpu) diff --git a/trunk/drivers/gpu/drm/drm_mm.c b/trunk/drivers/gpu/drm/drm_mm.c index 2aa331499f81..2bf9670ba29b 100644 --- a/trunk/drivers/gpu/drm/drm_mm.c +++ b/trunk/drivers/gpu/drm/drm_mm.c @@ -221,14 +221,12 @@ static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node, BUG_ON(!hole_node->hole_follows || node->allocated); - if (adj_start < start) - adj_start = start; - if (adj_end > end) - adj_end = end; - if (mm->color_adjust) mm->color_adjust(hole_node, color, &adj_start, &adj_end); + if (adj_start < start) + adj_start = start; + if (alignment) { unsigned tmp = adj_start % alignment; if (tmp) @@ -508,7 +506,7 @@ void drm_mm_init_scan(struct drm_mm *mm, mm->scan_size = size; mm->scanned_blocks = 0; mm->scan_hit_start = 0; - mm->scan_hit_end = 0; + mm->scan_hit_size = 0; mm->scan_check_range = 0; mm->prev_scanned_node = NULL; } @@ -535,7 +533,7 @@ void drm_mm_init_scan_with_range(struct drm_mm *mm, mm->scan_size = size; mm->scanned_blocks = 0; mm->scan_hit_start = 0; - mm->scan_hit_end = 0; + mm->scan_hit_size = 0; mm->scan_start = start; mm->scan_end = end; mm->scan_check_range = 1; @@ -554,7 +552,8 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) struct drm_mm *mm = node->mm; struct drm_mm_node *prev_node; unsigned long hole_start, hole_end; - unsigned long adj_start, adj_end; + unsigned long adj_start; + unsigned long adj_end; mm->scanned_blocks++; @@ -571,8 +570,14 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) node->node_list.next = &mm->prev_scanned_node->node_list; mm->prev_scanned_node = node; - adj_start = hole_start = drm_mm_hole_node_start(prev_node); - adj_end = hole_end = drm_mm_hole_node_end(prev_node); + hole_start = drm_mm_hole_node_start(prev_node); + hole_end = drm_mm_hole_node_end(prev_node); + + adj_start = hole_start; + adj_end = hole_end; + + if (mm->color_adjust) + mm->color_adjust(prev_node, mm->scan_color, &adj_start, &adj_end); if (mm->scan_check_range) { if (adj_start < mm->scan_start) @@ -581,14 +586,11 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) adj_end = mm->scan_end; } - if (mm->color_adjust) - mm->color_adjust(prev_node, mm->scan_color, - &adj_start, &adj_end); - if (check_free_hole(adj_start, adj_end, mm->scan_size, mm->scan_alignment)) { mm->scan_hit_start = hole_start; - mm->scan_hit_end = hole_end; + mm->scan_hit_size = hole_end; + return 1; } @@ -624,10 +626,19 @@ int drm_mm_scan_remove_block(struct drm_mm_node *node) node_list); prev_node->hole_follows = node->scanned_preceeds_hole; + INIT_LIST_HEAD(&node->node_list); list_add(&node->node_list, &prev_node->node_list); - return (drm_mm_hole_node_end(node) > mm->scan_hit_start && - node->start < mm->scan_hit_end); + /* Only need to check for containement because start&size for the + * complete resulting free block (not just the desired part) is + * stored. */ + if (node->start >= mm->scan_hit_start && + node->start + node->size + <= mm->scan_hit_start + mm->scan_hit_size) { + return 1; + } + + return 0; } EXPORT_SYMBOL(drm_mm_scan_remove_block); diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index 8febea6daa08..da3c82e301b1 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -1717,8 +1717,7 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj) } static long -__i915_gem_shrink(struct drm_i915_private *dev_priv, long target, - bool purgeable_only) +i915_gem_purge(struct drm_i915_private *dev_priv, long target) { struct drm_i915_gem_object *obj, *next; long count = 0; @@ -1726,7 +1725,7 @@ __i915_gem_shrink(struct drm_i915_private *dev_priv, long target, list_for_each_entry_safe(obj, next, &dev_priv->mm.unbound_list, gtt_list) { - if ((i915_gem_object_is_purgeable(obj) || !purgeable_only) && + if (i915_gem_object_is_purgeable(obj) && i915_gem_object_put_pages(obj) == 0) { count += obj->base.size >> PAGE_SHIFT; if (count >= target) @@ -1737,7 +1736,7 @@ __i915_gem_shrink(struct drm_i915_private *dev_priv, long target, list_for_each_entry_safe(obj, next, &dev_priv->mm.inactive_list, mm_list) { - if ((i915_gem_object_is_purgeable(obj) || !purgeable_only) && + if (i915_gem_object_is_purgeable(obj) && i915_gem_object_unbind(obj) == 0 && i915_gem_object_put_pages(obj) == 0) { count += obj->base.size >> PAGE_SHIFT; @@ -1749,12 +1748,6 @@ __i915_gem_shrink(struct drm_i915_private *dev_priv, long target, return count; } -static long -i915_gem_purge(struct drm_i915_private *dev_priv, long target) -{ - return __i915_gem_shrink(dev_priv, target, true); -} - static void i915_gem_shrink_all(struct drm_i915_private *dev_priv) { @@ -3529,15 +3522,14 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, goto out; } - if (obj->user_pin_count == 0) { + obj->user_pin_count++; + obj->pin_filp = file; + if (obj->user_pin_count == 1) { ret = i915_gem_object_pin(obj, args->alignment, true, false); if (ret) goto out; } - obj->user_pin_count++; - obj->pin_filp = file; - /* XXX - flush the CPU caches for pinned objects * as the X server doesn't manage domains yet */ @@ -4402,9 +4394,6 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) if (nr_to_scan) { nr_to_scan -= i915_gem_purge(dev_priv, nr_to_scan); - if (nr_to_scan > 0) - nr_to_scan -= __i915_gem_shrink(dev_priv, nr_to_scan, - false); if (nr_to_scan > 0) i915_gem_shrink_all(dev_priv); } @@ -4413,7 +4402,7 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) list_for_each_entry(obj, &dev_priv->mm.unbound_list, gtt_list) if (obj->pages_pin_count == 0) cnt += obj->base.size >> PAGE_SHIFT; - list_for_each_entry(obj, &dev_priv->mm.inactive_list, gtt_list) + list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) if (obj->pin_count == 0 && obj->pages_pin_count == 0) cnt += obj->base.size >> PAGE_SHIFT; diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index da1ad9c80bb5..a9fb046b94a1 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -8598,30 +8598,19 @@ int intel_framebuffer_init(struct drm_device *dev, { int ret; - if (obj->tiling_mode == I915_TILING_Y) { - DRM_DEBUG("hardware does not support tiling Y\n"); + if (obj->tiling_mode == I915_TILING_Y) return -EINVAL; - } - if (mode_cmd->pitches[0] & 63) { - DRM_DEBUG("pitch (%d) must be at least 64 byte aligned\n", - mode_cmd->pitches[0]); + if (mode_cmd->pitches[0] & 63) return -EINVAL; - } /* FIXME <= Gen4 stride limits are bit unclear */ - if (mode_cmd->pitches[0] > 32768) { - DRM_DEBUG("pitch (%d) must be at less than 32768\n", - mode_cmd->pitches[0]); + if (mode_cmd->pitches[0] > 32768) return -EINVAL; - } if (obj->tiling_mode != I915_TILING_NONE && - mode_cmd->pitches[0] != obj->stride) { - DRM_DEBUG("pitch (%d) must match tiling stride (%d)\n", - mode_cmd->pitches[0], obj->stride); + mode_cmd->pitches[0] != obj->stride) return -EINVAL; - } /* Reject formats not supported by any plane early. */ switch (mode_cmd->pixel_format) { @@ -8632,10 +8621,8 @@ int intel_framebuffer_init(struct drm_device *dev, break; case DRM_FORMAT_XRGB1555: case DRM_FORMAT_ARGB1555: - if (INTEL_INFO(dev)->gen > 3) { - DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format); + if (INTEL_INFO(dev)->gen > 3) return -EINVAL; - } break; case DRM_FORMAT_XBGR8888: case DRM_FORMAT_ABGR8888: @@ -8643,22 +8630,18 @@ int intel_framebuffer_init(struct drm_device *dev, case DRM_FORMAT_ARGB2101010: case DRM_FORMAT_XBGR2101010: case DRM_FORMAT_ABGR2101010: - if (INTEL_INFO(dev)->gen < 4) { - DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format); + if (INTEL_INFO(dev)->gen < 4) return -EINVAL; - } break; case DRM_FORMAT_YUYV: case DRM_FORMAT_UYVY: case DRM_FORMAT_YVYU: case DRM_FORMAT_VYUY: - if (INTEL_INFO(dev)->gen < 5) { - DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format); + if (INTEL_INFO(dev)->gen < 6) return -EINVAL; - } break; default: - DRM_DEBUG("unsupported pixel format 0x%08x\n", mode_cmd->pixel_format); + DRM_DEBUG_KMS("unsupported pixel format 0x%08x\n", mode_cmd->pixel_format); return -EINVAL; } diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index 17aee74258ad..b9a660a53677 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -774,6 +774,14 @@ static const struct dmi_system_id intel_no_lvds[] = { DMI_MATCH(DMI_BOARD_NAME, "MS-7469"), }, }, + { + .callback = intel_no_lvds_dmi_callback, + .ident = "ZOTAC ZBOXSD-ID12/ID13", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ZOTAC"), + DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"), + }, + }, { .callback = intel_no_lvds_dmi_callback, .ident = "Gigabyte GA-D525TUD", diff --git a/trunk/drivers/gpu/drm/i915/intel_pm.c b/trunk/drivers/gpu/drm/i915/intel_pm.c index e83a11794172..e6f54ffab3ba 100644 --- a/trunk/drivers/gpu/drm/i915/intel_pm.c +++ b/trunk/drivers/gpu/drm/i915/intel_pm.c @@ -44,14 +44,6 @@ * i915.i915_enable_fbc parameter */ -static bool intel_crtc_active(struct drm_crtc *crtc) -{ - /* Be paranoid as we can arrive here with only partial - * state retrieved from the hardware during setup. - */ - return to_intel_crtc(crtc)->active && crtc->fb && crtc->mode.clock; -} - static void i8xx_disable_fbc(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -413,8 +405,9 @@ void intel_update_fbc(struct drm_device *dev) * - going to an unsupported config (interlace, pixel multiply, etc.) */ list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) { - if (intel_crtc_active(tmp_crtc) && - !to_intel_crtc(tmp_crtc)->primary_disabled) { + if (to_intel_crtc(tmp_crtc)->active && + !to_intel_crtc(tmp_crtc)->primary_disabled && + tmp_crtc->fb) { if (crtc) { DRM_DEBUG_KMS("more than one pipe active, disabling compression\n"); dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES; @@ -999,7 +992,7 @@ static struct drm_crtc *single_enabled_crtc(struct drm_device *dev) struct drm_crtc *crtc, *enabled = NULL; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (intel_crtc_active(crtc)) { + if (to_intel_crtc(crtc)->active && crtc->fb) { if (enabled) return NULL; enabled = crtc; @@ -1093,7 +1086,7 @@ static bool g4x_compute_wm0(struct drm_device *dev, int entries, tlb_miss; crtc = intel_get_crtc_for_plane(dev, plane); - if (!intel_crtc_active(crtc)) { + if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) { *cursor_wm = cursor->guard_size; *plane_wm = display->guard_size; return false; @@ -1222,7 +1215,7 @@ static bool vlv_compute_drain_latency(struct drm_device *dev, int entries; crtc = intel_get_crtc_for_plane(dev, plane); - if (!intel_crtc_active(crtc)) + if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) return false; clock = crtc->mode.clock; /* VESA DOT Clock */ @@ -1483,7 +1476,7 @@ static void i9xx_update_wm(struct drm_device *dev) fifo_size = dev_priv->display.get_fifo_size(dev, 0); crtc = intel_get_crtc_for_plane(dev, 0); - if (intel_crtc_active(crtc)) { + if (to_intel_crtc(crtc)->active && crtc->fb) { int cpp = crtc->fb->bits_per_pixel / 8; if (IS_GEN2(dev)) cpp = 4; @@ -1497,7 +1490,7 @@ static void i9xx_update_wm(struct drm_device *dev) fifo_size = dev_priv->display.get_fifo_size(dev, 1); crtc = intel_get_crtc_for_plane(dev, 1); - if (intel_crtc_active(crtc)) { + if (to_intel_crtc(crtc)->active && crtc->fb) { int cpp = crtc->fb->bits_per_pixel / 8; if (IS_GEN2(dev)) cpp = 4; @@ -2051,7 +2044,7 @@ sandybridge_compute_sprite_wm(struct drm_device *dev, int plane, int entries, tlb_miss; crtc = intel_get_crtc_for_plane(dev, plane); - if (!intel_crtc_active(crtc)) { + if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) { *sprite_wm = display->guard_size; return false; } diff --git a/trunk/drivers/gpu/drm/i915/intel_sprite.c b/trunk/drivers/gpu/drm/i915/intel_sprite.c index d7b060e0a231..827dcd4edf1c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sprite.c +++ b/trunk/drivers/gpu/drm/i915/intel_sprite.c @@ -120,10 +120,11 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x); - linear_offset = y * fb->pitches[0] + x * pixel_size; + linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); sprsurf_offset = intel_gen4_compute_offset_xtiled(&x, &y, - pixel_size, fb->pitches[0]); + fb->bits_per_pixel / 8, + fb->pitches[0]); linear_offset -= sprsurf_offset; /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET @@ -285,10 +286,11 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]); I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x); - linear_offset = y * fb->pitches[0] + x * pixel_size; + linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); dvssurf_offset = intel_gen4_compute_offset_xtiled(&x, &y, - pixel_size, fb->pitches[0]); + fb->bits_per_pixel / 8, + fb->pitches[0]); linear_offset -= dvssurf_offset; if (obj->tiling_mode != I915_TILING_NONE) diff --git a/trunk/drivers/gpu/drm/nouveau/core/core/client.c b/trunk/drivers/gpu/drm/nouveau/core/core/client.c index 8bbb58f94a19..c617f0480071 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/core/client.c +++ b/trunk/drivers/gpu/drm/nouveau/core/core/client.c @@ -66,8 +66,10 @@ nouveau_client_create_(const char *name, u64 devname, const char *cfg, ret = nouveau_handle_create(nv_object(client), ~0, ~0, nv_object(client), &client->root); - if (ret) + if (ret) { + nouveau_namedb_destroy(&client->base); return ret; + } /* prevent init/fini being called, os in in charge of this */ atomic_set(&nv_object(client)->usecount, 2); diff --git a/trunk/drivers/gpu/drm/nouveau/core/core/handle.c b/trunk/drivers/gpu/drm/nouveau/core/core/handle.c index 264c2b338ac3..b8d2cbf8a7a7 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/core/handle.c +++ b/trunk/drivers/gpu/drm/nouveau/core/core/handle.c @@ -109,7 +109,7 @@ nouveau_handle_create(struct nouveau_object *parent, u32 _parent, u32 _handle, while (!nv_iclass(namedb, NV_NAMEDB_CLASS)) namedb = namedb->parent; - handle = kzalloc(sizeof(*handle), GFP_KERNEL); + handle = *phandle = kzalloc(sizeof(*handle), GFP_KERNEL); if (!handle) return -ENOMEM; @@ -146,9 +146,6 @@ nouveau_handle_create(struct nouveau_object *parent, u32 _parent, u32 _handle, } hprintk(handle, TRACE, "created\n"); - - *phandle = handle; - return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index ca1a7d76a95b..0f09af135415 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -851,23 +851,20 @@ exec_script(struct nv50_disp_priv *priv, int head, int id) for (i = 0; !(ctrl & (1 << head)) && i < 3; i++) ctrl = nv_rd32(priv, 0x610b5c + (i * 8)); - if (!(ctrl & (1 << head))) { - if (nv_device(priv)->chipset < 0x90 || - nv_device(priv)->chipset == 0x92 || - nv_device(priv)->chipset == 0xa0) { - for (i = 0; !(ctrl & (1 << head)) && i < 2; i++) - ctrl = nv_rd32(priv, 0x610b74 + (i * 8)); - i += 4; - } else { - for (i = 0; !(ctrl & (1 << head)) && i < 4; i++) - ctrl = nv_rd32(priv, 0x610798 + (i * 8)); - i += 4; - } + if (nv_device(priv)->chipset < 0x90 || + nv_device(priv)->chipset == 0x92 || + nv_device(priv)->chipset == 0xa0) { + for (i = 0; !(ctrl & (1 << head)) && i < 2; i++) + ctrl = nv_rd32(priv, 0x610b74 + (i * 8)); + i += 3; + } else { + for (i = 0; !(ctrl & (1 << head)) && i < 4; i++) + ctrl = nv_rd32(priv, 0x610798 + (i * 8)); + i += 3; } if (!(ctrl & (1 << head))) return false; - i--; data = exec_lookup(priv, head, i, ctrl, &dcb, &ver, &hdr, &cnt, &len, &info); if (data) { @@ -901,23 +898,20 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, for (i = 0; !(ctrl & (1 << head)) && i < 3; i++) ctrl = nv_rd32(priv, 0x610b58 + (i * 8)); - if (!(ctrl & (1 << head))) { - if (nv_device(priv)->chipset < 0x90 || - nv_device(priv)->chipset == 0x92 || - nv_device(priv)->chipset == 0xa0) { - for (i = 0; !(ctrl & (1 << head)) && i < 2; i++) - ctrl = nv_rd32(priv, 0x610b70 + (i * 8)); - i += 4; - } else { - for (i = 0; !(ctrl & (1 << head)) && i < 4; i++) - ctrl = nv_rd32(priv, 0x610794 + (i * 8)); - i += 4; - } + if (nv_device(priv)->chipset < 0x90 || + nv_device(priv)->chipset == 0x92 || + nv_device(priv)->chipset == 0xa0) { + for (i = 0; !(ctrl & (1 << head)) && i < 2; i++) + ctrl = nv_rd32(priv, 0x610b70 + (i * 8)); + i += 3; + } else { + for (i = 0; !(ctrl & (1 << head)) && i < 4; i++) + ctrl = nv_rd32(priv, 0x610794 + (i * 8)); + i += 3; } if (!(ctrl & (1 << head))) return 0x0000; - i--; data = exec_lookup(priv, head, i, ctrl, outp, &ver, &hdr, &cnt, &len, &info1); if (!data) diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/core/client.h b/trunk/drivers/gpu/drm/nouveau/core/include/core/client.h index 63acc0346ff2..0193532ceac9 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/core/client.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/core/client.h @@ -36,9 +36,6 @@ nouveau_client(void *obj) int nouveau_client_create_(const char *name, u64 device, const char *cfg, const char *dbg, int, void **); -#define nouveau_client_destroy(p) \ - nouveau_namedb_destroy(&(p)->base) - int nouveau_client_init(struct nouveau_client *); int nouveau_client_fini(struct nouveau_client *, bool suspend); diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h index b2f3d4d0aa49..c345097592f2 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h @@ -38,8 +38,6 @@ enum nvbios_pll_type { PLL_UNK42 = 0x42, PLL_VPLL0 = 0x80, PLL_VPLL1 = 0x81, - PLL_VPLL2 = 0x82, - PLL_VPLL3 = 0x83, PLL_MAX = 0xff }; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c index 690ed438b2ad..2917d552689b 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c @@ -1534,6 +1534,7 @@ init_io(struct nvbios_init *init) mdelay(10); init_wr32(init, 0x614100, 0x10000018); init_wr32(init, 0x614900, 0x10000018); + return; } value = init_rdport(init, port) & mask; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c index 7c9626258a46..f6962c9b6c36 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c @@ -52,8 +52,6 @@ nvc0_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq) switch (info.type) { case PLL_VPLL0: case PLL_VPLL1: - case PLL_VPLL2: - case PLL_VPLL3: nv_mask(priv, info.reg + 0x0c, 0x00000000, 0x00000100); nv_wr32(priv, info.reg + 0x04, (P << 16) | (N << 8) | M); nv_wr32(priv, info.reg + 0x10, fN << 16); diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c index 7606ed15b6fa..306bdf121452 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c @@ -145,14 +145,14 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin, mem->memtype = type; mem->size = size; - mutex_lock(&pfb->base.mutex); + mutex_lock(&mm->mutex); do { if (back) ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r); else ret = nouveau_mm_head(mm, 1, size, ncmin, align, &r); if (ret) { - mutex_unlock(&pfb->base.mutex); + mutex_unlock(&mm->mutex); pfb->ram.put(pfb, &mem); return ret; } @@ -160,7 +160,7 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin, list_add_tail(&r->rl_entry, &mem->regions); size -= r->length; } while (size); - mutex_unlock(&pfb->base.mutex); + mutex_unlock(&mm->mutex); r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry); mem->offset = (u64)r->offset << 12; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c index 6565f3dbbe04..1188227ca6aa 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c @@ -40,21 +40,15 @@ nouveau_instobj_create_(struct nouveau_object *parent, if (ret) return ret; - mutex_lock(&imem->base.mutex); list_add(&iobj->head, &imem->list); - mutex_unlock(&imem->base.mutex); return 0; } void nouveau_instobj_destroy(struct nouveau_instobj *iobj) { - struct nouveau_subdev *subdev = nv_subdev(iobj->base.engine); - - mutex_lock(&subdev->mutex); - list_del(&iobj->head); - mutex_unlock(&subdev->mutex); - + if (iobj->head.prev) + list_del(&iobj->head); return nouveau_object_destroy(&iobj->base); } @@ -94,8 +88,6 @@ nouveau_instmem_init(struct nouveau_instmem *imem) if (ret) return ret; - mutex_lock(&imem->base.mutex); - list_for_each_entry(iobj, &imem->list, head) { if (iobj->suspend) { for (i = 0; i < iobj->size; i += 4) @@ -105,8 +97,6 @@ nouveau_instmem_init(struct nouveau_instmem *imem) } } - mutex_unlock(&imem->base.mutex); - return 0; } @@ -114,26 +104,17 @@ int nouveau_instmem_fini(struct nouveau_instmem *imem, bool suspend) { struct nouveau_instobj *iobj; - int i, ret = 0; + int i; if (suspend) { - mutex_lock(&imem->base.mutex); - list_for_each_entry(iobj, &imem->list, head) { iobj->suspend = vmalloc(iobj->size); - if (!iobj->suspend) { - ret = -ENOMEM; - break; - } - - for (i = 0; i < iobj->size; i += 4) - iobj->suspend[i / 4] = nv_ro32(iobj, i); + if (iobj->suspend) { + for (i = 0; i < iobj->size; i += 4) + iobj->suspend[i / 4] = nv_ro32(iobj, i); + } else + return -ENOMEM; } - - mutex_unlock(&imem->base.mutex); - - if (ret) - return ret; } return nouveau_subdev_fini(&imem->base, suspend); diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/base.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/base.c index 77c67fc970e6..082c11b75acb 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/base.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/base.c @@ -352,7 +352,7 @@ nouveau_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length, u64 mm_length = (offset + length) - mm_offset; int ret; - vm = kzalloc(sizeof(*vm), GFP_KERNEL); + vm = *pvm = kzalloc(sizeof(*vm), GFP_KERNEL); if (!vm) return -ENOMEM; @@ -376,8 +376,6 @@ nouveau_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length, return ret; } - *pvm = vm; - return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c index e620ba8271b4..ac340ba32017 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -127,26 +127,12 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, struct nouveau_encoder **pnv_encoder) { struct drm_device *dev = connector->dev; - struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_gpio *gpio = nouveau_gpio(drm->device); struct nouveau_i2c *i2c = nouveau_i2c(drm->device); - struct nouveau_i2c_port *port = NULL; - int i, panel = -ENODEV; - - /* eDP panels need powering on by us (if the VBIOS doesn't default it - * to on) before doing any AUX channel transactions. LVDS panel power - * is handled by the SOR itself, and not required for LVDS DDC. - */ - if (nv_connector->type == DCB_CONNECTOR_eDP) { - panel = gpio->get(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff); - if (panel == 0) { - gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 1); - msleep(300); - } - } + int i; for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { + struct nouveau_i2c_port *port = NULL; struct nouveau_encoder *nv_encoder; struct drm_mode_object *obj; int id; @@ -164,19 +150,11 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, port = i2c->find(i2c, nv_encoder->dcb->i2c_index); if (port && nv_probe_i2c(port, 0x50)) { *pnv_encoder = nv_encoder; - break; + return port; } - - port = NULL; } - /* eDP panel not detected, restore panel power GPIO to previous - * state to avoid confusing the SOR for other output types. - */ - if (!port && panel == 0) - gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, panel); - - return port; + return NULL; } static struct nouveau_encoder * diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_display.c b/trunk/drivers/gpu/drm/nouveau/nouveau_display.c index 508b00a2ce0d..e4188f24fc75 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_display.c @@ -225,6 +225,15 @@ nouveau_display_init(struct drm_device *dev) if (ret) return ret; + /* power on internal panel if it's not already. the init tables of + * some vbios default this to off for some reason, causing the + * panel to not work after resume + */ + if (gpio && gpio->get(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff) == 0) { + gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 1); + msleep(300); + } + /* enable polling for external displays */ drm_kms_helper_poll_enable(dev); diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c index 8b090f1eb51d..180a45e3b525 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -84,16 +84,11 @@ nouveau_cli_create(struct pci_dev *pdev, const char *name, struct nouveau_cli *cli; int ret; - *pcli = NULL; ret = nouveau_client_create_(name, nouveau_name(pdev), nouveau_config, nouveau_debug, size, pcli); cli = *pcli; - if (ret) { - if (cli) - nouveau_client_destroy(&cli->base); - *pcli = NULL; + if (ret) return ret; - } mutex_init(&cli->mutex); return 0; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_fence.h b/trunk/drivers/gpu/drm/nouveau/nouveau_fence.h index cdb83acdffe2..bedafd1c9539 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_fence.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_fence.h @@ -60,7 +60,6 @@ u32 nv10_fence_read(struct nouveau_channel *); void nv10_fence_context_del(struct nouveau_channel *); void nv10_fence_destroy(struct nouveau_drm *); int nv10_fence_create(struct nouveau_drm *); -void nv17_fence_resume(struct nouveau_drm *drm); int nv50_fence_create(struct nouveau_drm *); int nv84_fence_create(struct nouveau_drm *); diff --git a/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c b/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c index 39ffc07f906b..184cdf806761 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c @@ -505,7 +505,7 @@ static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode) static inline bool is_powersaving_dpms(int mode) { - return mode != DRM_MODE_DPMS_ON && mode != NV_DPMS_CLEARED; + return (mode != DRM_MODE_DPMS_ON); } static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) diff --git a/trunk/drivers/gpu/drm/nouveau/nv10_fence.c b/trunk/drivers/gpu/drm/nouveau/nv10_fence.c index 03017f24d593..7ae7f97a6d4d 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv10_fence.c +++ b/trunk/drivers/gpu/drm/nouveau/nv10_fence.c @@ -162,13 +162,6 @@ nv10_fence_destroy(struct nouveau_drm *drm) kfree(priv); } -void nv17_fence_resume(struct nouveau_drm *drm) -{ - struct nv10_fence_priv *priv = drm->fence; - - nouveau_bo_wr32(priv->bo, 0, priv->sequence); -} - int nv10_fence_create(struct nouveau_drm *drm) { @@ -204,7 +197,6 @@ nv10_fence_create(struct nouveau_drm *drm) if (ret == 0) { nouveau_bo_wr32(priv->bo, 0x000, 0x00000000); priv->base.sync = nv17_fence_sync; - priv->base.resume = nv17_fence_resume; } } diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_fence.c b/trunk/drivers/gpu/drm/nouveau/nv50_fence.c index d889f3ac0d41..c20f2727ea0b 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv50_fence.c +++ b/trunk/drivers/gpu/drm/nouveau/nv50_fence.c @@ -122,7 +122,6 @@ nv50_fence_create(struct nouveau_drm *drm) if (ret == 0) { nouveau_bo_wr32(priv->bo, 0x000, 0x00000000); priv->base.sync = nv17_fence_sync; - priv->base.resume = nv17_fence_resume; } if (ret) diff --git a/trunk/drivers/gpu/drm/radeon/r600_cs.c b/trunk/drivers/gpu/drm/radeon/r600_cs.c index 69ec24ab8d63..03191a56eb44 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_cs.c +++ b/trunk/drivers/gpu/drm/radeon/r600_cs.c @@ -2476,10 +2476,8 @@ static void r600_cs_parser_fini(struct radeon_cs_parser *parser, int error) kfree(parser->relocs); for (i = 0; i < parser->nchunks; i++) { kfree(parser->chunks[i].kdata); - if (parser->rdev && (parser->rdev->flags & RADEON_IS_AGP)) { - kfree(parser->chunks[i].kpage[0]); - kfree(parser->chunks[i].kpage[1]); - } + kfree(parser->chunks[i].kpage[0]); + kfree(parser->chunks[i].kpage[1]); } kfree(parser->chunks); kfree(parser->chunks_array); @@ -2563,16 +2561,16 @@ int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, struct radeon_cs_chunk *relocs_chunk; unsigned idx; - *cs_reloc = NULL; if (p->chunk_relocs_idx == -1) { DRM_ERROR("No relocation chunk !\n"); return -EINVAL; } + *cs_reloc = NULL; relocs_chunk = &p->chunks[p->chunk_relocs_idx]; idx = p->dma_reloc_idx; - if (idx >= p->nrelocs) { + if (idx >= relocs_chunk->length_dw) { DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", - idx, p->nrelocs); + idx, relocs_chunk->length_dw); return -EINVAL; } *cs_reloc = p->relocs_ptr[idx]; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_cs.c b/trunk/drivers/gpu/drm/radeon/radeon_cs.c index 469661fd1903..396baba0141a 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_cs.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_cs.c @@ -279,13 +279,13 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) p->chunks[p->chunk_ib_idx].length_dw); return -EINVAL; } - if (p->rdev && (p->rdev->flags & RADEON_IS_AGP)) { + if ((p->rdev->flags & RADEON_IS_AGP)) { p->chunks[p->chunk_ib_idx].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL); p->chunks[p->chunk_ib_idx].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL); if (p->chunks[p->chunk_ib_idx].kpage[0] == NULL || p->chunks[p->chunk_ib_idx].kpage[1] == NULL) { - kfree(p->chunks[p->chunk_ib_idx].kpage[0]); - kfree(p->chunks[p->chunk_ib_idx].kpage[1]); + kfree(p->chunks[i].kpage[0]); + kfree(p->chunks[i].kpage[1]); return -ENOMEM; } } @@ -583,8 +583,7 @@ static int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx) struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx]; int i; int size = PAGE_SIZE; - bool copy1 = (p->rdev && (p->rdev->flags & RADEON_IS_AGP)) ? - false : true; + bool copy1 = (p->rdev->flags & RADEON_IS_AGP) ? false : true; for (i = ibc->last_copied_page + 1; i < pg_idx; i++) { if (DRM_COPY_FROM_USER(p->ib.ptr + (i * (PAGE_SIZE/4)), diff --git a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 62cd512f5c8d..f5ba2241dacc 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -640,14 +640,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); diff --git a/trunk/drivers/gpu/drm/udl/udl_connector.c b/trunk/drivers/gpu/drm/udl/udl_connector.c index fe5cdbcf2636..512f44add89f 100644 --- a/trunk/drivers/gpu/drm/udl/udl_connector.c +++ b/trunk/drivers/gpu/drm/udl/udl_connector.c @@ -22,17 +22,13 @@ static u8 *udl_get_edid(struct udl_device *udl) { u8 *block; - char *rbuf; + char rbuf[3]; int ret, i; block = kmalloc(EDID_LENGTH, GFP_KERNEL); if (block == NULL) return NULL; - rbuf = kmalloc(2, GFP_KERNEL); - if (rbuf == NULL) - goto error; - for (i = 0; i < EDID_LENGTH; i++) { ret = usb_control_msg(udl->ddev->usbdev, usb_rcvctrlpipe(udl->ddev->usbdev, 0), (0x02), @@ -40,17 +36,16 @@ static u8 *udl_get_edid(struct udl_device *udl) HZ); if (ret < 1) { DRM_ERROR("Read EDID byte %d failed err %x\n", i, ret); + i--; goto error; } block[i] = rbuf[1]; } - kfree(rbuf); return block; error: kfree(block); - kfree(rbuf); return NULL; } @@ -62,14 +57,6 @@ static int udl_get_modes(struct drm_connector *connector) edid = (struct edid *)udl_get_edid(udl); - /* - * We only read the main block, but if the monitor reports extension - * blocks then the drm edid code expects them to be present, so patch - * the extension count to 0. - */ - edid->checksum += edid->extensions; - edid->extensions = 0; - drm_mode_connector_update_edid_property(connector, edid); ret = drm_add_edid_modes(connector, edid); kfree(edid); diff --git a/trunk/drivers/hwmon/vexpress.c b/trunk/drivers/hwmon/vexpress.c index d867e6bb2be1..86d7f6d858b1 100644 --- a/trunk/drivers/hwmon/vexpress.c +++ b/trunk/drivers/hwmon/vexpress.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/misc/mei/amthif.c b/trunk/drivers/misc/mei/amthif.c index e40ffd9502d1..18794aea6062 100644 --- a/trunk/drivers/misc/mei/amthif.c +++ b/trunk/drivers/misc/mei/amthif.c @@ -187,13 +187,13 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, wait_ret = wait_event_interruptible(dev->iamthif_cl.wait, (cb = mei_amthif_find_read_list_entry(dev, file))); - /* Locking again the Mutex */ - mutex_lock(&dev->device_lock); - if (wait_ret) return -ERESTARTSYS; dev_dbg(&dev->pdev->dev, "woke up from sleep\n"); + + /* Locking again the Mutex */ + mutex_lock(&dev->device_lock); } diff --git a/trunk/drivers/net/ethernet/adi/Kconfig b/trunk/drivers/net/ethernet/adi/Kconfig index a9481606bbcd..e49c0eff040b 100644 --- a/trunk/drivers/net/ethernet/adi/Kconfig +++ b/trunk/drivers/net/ethernet/adi/Kconfig @@ -61,7 +61,6 @@ config BFIN_RX_DESC_NUM config BFIN_MAC_USE_HWSTAMP bool "Use IEEE 1588 hwstamp" - depends on BFIN_MAC && BF518 select PTP_1588_CLOCK default y ---help--- diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index f771ddfba646..01588b66a38c 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -80,37 +80,12 @@ static inline void bnx2x_move_fp(struct bnx2x *bp, int from, int to) new_txdata_index = new_max_eth_txqs + FCOE_TXQ_IDX_OFFSET; } - memcpy(&bp->bnx2x_txq[new_txdata_index], - &bp->bnx2x_txq[old_txdata_index], + memcpy(&bp->bnx2x_txq[old_txdata_index], + &bp->bnx2x_txq[new_txdata_index], sizeof(struct bnx2x_fp_txdata)); to_fp->txdata_ptr[0] = &bp->bnx2x_txq[new_txdata_index]; } -/** - * bnx2x_shrink_eth_fp - guarantees fastpath structures stay intact - * - * @bp: driver handle - * @delta: number of eth queues which were not allocated - */ -static void bnx2x_shrink_eth_fp(struct bnx2x *bp, int delta) -{ - int i, cos, old_eth_num = BNX2X_NUM_ETH_QUEUES(bp); - - /* Queue pointer cannot be re-set on an fp-basis, as moving pointer - * backward along the array could cause memory to be overriden - */ - for (cos = 1; cos < bp->max_cos; cos++) { - for (i = 0; i < old_eth_num - delta; i++) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - int new_idx = cos * (old_eth_num - delta) + i; - - memcpy(&bp->bnx2x_txq[new_idx], fp->txdata_ptr[cos], - sizeof(struct bnx2x_fp_txdata)); - fp->txdata_ptr[cos] = &bp->bnx2x_txq[new_idx]; - } - } -} - int load_count[2][3] = { {0} }; /* per-path: 0-common, 1-port0, 2-port1 */ /* free skb in the packet ring at pos idx @@ -3888,7 +3863,6 @@ int bnx2x_alloc_fp_mem(struct bnx2x *bp) int delta = BNX2X_NUM_ETH_QUEUES(bp) - i; WARN_ON(delta < 0); - bnx2x_shrink_eth_fp(bp, delta); if (CNIC_SUPPORT(bp)) /* move non eth FPs next to last eth FP * must be done in that order diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index a427b49a886c..277f17e3c8f8 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -2777,10 +2777,10 @@ static int bnx2x_set_rss_flags(struct bnx2x *bp, struct ethtool_rxnfc *info) } else if ((info->flow_type == UDP_V6_FLOW) && (bp->rss_conf_obj.udp_rss_v6 != udp_rss_requested)) { bp->rss_conf_obj.udp_rss_v6 = udp_rss_requested; + return bnx2x_config_rss_pf(bp, &bp->rss_conf_obj, 0); DP(BNX2X_MSG_ETHTOOL, "rss re-configured, UDP 4-tupple %s\n", udp_rss_requested ? "enabled" : "disabled"); - return bnx2x_config_rss_pf(bp, &bp->rss_conf_obj, 0); } else { return 0; } diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 5523da3afcdc..940ef859dc60 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -127,17 +127,6 @@ MODULE_PARM_DESC(debug, " Default debug msglevel"); struct workqueue_struct *bnx2x_wq; -struct bnx2x_mac_vals { - u32 xmac_addr; - u32 xmac_val; - u32 emac_addr; - u32 emac_val; - u32 umac_addr; - u32 umac_val; - u32 bmac_addr; - u32 bmac_val[2]; -}; - enum bnx2x_board_type { BCM57710 = 0, BCM57711, @@ -9431,19 +9420,12 @@ static inline void bnx2x_undi_int_disable(struct bnx2x *bp) bnx2x_undi_int_disable_e1h(bp); } -static void bnx2x_prev_unload_close_mac(struct bnx2x *bp, - struct bnx2x_mac_vals *vals) +static void bnx2x_prev_unload_close_mac(struct bnx2x *bp) { u32 val, base_addr, offset, mask, reset_reg; bool mac_stopped = false; u8 port = BP_PORT(bp); - /* reset addresses as they also mark which values were changed */ - vals->bmac_addr = 0; - vals->umac_addr = 0; - vals->xmac_addr = 0; - vals->emac_addr = 0; - reset_reg = REG_RD(bp, MISC_REG_RESET_REG_2); if (!CHIP_IS_E3(bp)) { @@ -9465,18 +9447,14 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp, */ wb_data[0] = REG_RD(bp, base_addr + offset); wb_data[1] = REG_RD(bp, base_addr + offset + 0x4); - vals->bmac_addr = base_addr + offset; - vals->bmac_val[0] = wb_data[0]; - vals->bmac_val[1] = wb_data[1]; wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE; - REG_WR(bp, vals->bmac_addr, wb_data[0]); - REG_WR(bp, vals->bmac_addr + 0x4, wb_data[1]); + REG_WR(bp, base_addr + offset, wb_data[0]); + REG_WR(bp, base_addr + offset + 0x4, wb_data[1]); } BNX2X_DEV_INFO("Disable emac Rx\n"); - vals->emac_addr = NIG_REG_NIG_EMAC0_EN + BP_PORT(bp)*4; - vals->emac_val = REG_RD(bp, vals->emac_addr); - REG_WR(bp, vals->emac_addr, 0); + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + BP_PORT(bp)*4, 0); + mac_stopped = true; } else { if (reset_reg & MISC_REGISTERS_RESET_REG_2_XMAC) { @@ -9487,18 +9465,14 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp, val & ~(1 << 1)); REG_WR(bp, base_addr + XMAC_REG_PFC_CTRL_HI, val | (1 << 1)); - vals->xmac_addr = base_addr + XMAC_REG_CTRL; - vals->xmac_val = REG_RD(bp, vals->xmac_addr); - REG_WR(bp, vals->xmac_addr, 0); + REG_WR(bp, base_addr + XMAC_REG_CTRL, 0); mac_stopped = true; } mask = MISC_REGISTERS_RESET_REG_2_UMAC0 << port; if (mask & reset_reg) { BNX2X_DEV_INFO("Disable umac Rx\n"); base_addr = BP_PORT(bp) ? GRCBASE_UMAC1 : GRCBASE_UMAC0; - vals->umac_addr = base_addr + UMAC_REG_COMMAND_CONFIG; - vals->umac_val = REG_RD(bp, vals->umac_addr); - REG_WR(bp, vals->umac_addr, 0); + REG_WR(bp, base_addr + UMAC_REG_COMMAND_CONFIG, 0); mac_stopped = true; } } @@ -9690,16 +9664,12 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp) { u32 reset_reg, tmp_reg = 0, rc; bool prev_undi = false; - struct bnx2x_mac_vals mac_vals; - /* It is possible a previous function received 'common' answer, * but hasn't loaded yet, therefore creating a scenario of * multiple functions receiving 'common' on the same path. */ BNX2X_DEV_INFO("Common unload Flow\n"); - memset(&mac_vals, 0, sizeof(mac_vals)); - if (bnx2x_prev_is_path_marked(bp)) return bnx2x_prev_mcp_done(bp); @@ -9710,10 +9680,7 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp) u32 timer_count = 1000; /* Close the MAC Rx to prevent BRB from filling up */ - bnx2x_prev_unload_close_mac(bp, &mac_vals); - - /* close LLH filters towards the BRB */ - bnx2x_set_rx_filter(&bp->link_params, 0); + bnx2x_prev_unload_close_mac(bp); /* Check if the UNDI driver was previously loaded * UNDI driver initializes CID offset for normal bell to 0x7 @@ -9760,17 +9727,6 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp) /* No packets are in the pipeline, path is ready for reset */ bnx2x_reset_common(bp); - if (mac_vals.xmac_addr) - REG_WR(bp, mac_vals.xmac_addr, mac_vals.xmac_val); - if (mac_vals.umac_addr) - REG_WR(bp, mac_vals.umac_addr, mac_vals.umac_val); - if (mac_vals.emac_addr) - REG_WR(bp, mac_vals.emac_addr, mac_vals.emac_val); - if (mac_vals.bmac_addr) { - REG_WR(bp, mac_vals.bmac_addr, mac_vals.bmac_val[0]); - REG_WR(bp, mac_vals.bmac_addr + 4, mac_vals.bmac_val[1]); - } - rc = bnx2x_prev_mark_path(bp, prev_undi); if (rc) { bnx2x_prev_mcp_done(bp); diff --git a/trunk/drivers/net/ethernet/emulex/benet/be.h b/trunk/drivers/net/ethernet/emulex/benet/be.h index 4eba17b83ba8..3bc1912afba9 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be.h +++ b/trunk/drivers/net/ethernet/emulex/benet/be.h @@ -190,7 +190,6 @@ struct be_eq_obj { u8 idx; /* array index */ u16 tx_budget; - u16 spurious_intr; struct napi_struct napi; struct be_adapter *adapter; } ____cacheline_aligned_in_smp; diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_main.c b/trunk/drivers/net/ethernet/emulex/benet/be_main.c index 5c995700e534..9dca22be8125 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_main.c +++ b/trunk/drivers/net/ethernet/emulex/benet/be_main.c @@ -2026,30 +2026,19 @@ static irqreturn_t be_intx(int irq, void *dev) struct be_adapter *adapter = eqo->adapter; int num_evts = 0; - /* IRQ is not expected when NAPI is scheduled as the EQ - * will not be armed. - * But, this can happen on Lancer INTx where it takes - * a while to de-assert INTx or in BE2 where occasionaly - * an interrupt may be raised even when EQ is unarmed. - * If NAPI is already scheduled, then counting & notifying - * events will orphan them. + /* On Lancer, clear-intr bit of the EQ DB does not work. + * INTx is de-asserted only on notifying num evts. */ - if (napi_schedule_prep(&eqo->napi)) { + if (lancer_chip(adapter)) num_evts = events_get(eqo); - __napi_schedule(&eqo->napi); - if (num_evts) - eqo->spurious_intr = 0; - } - be_eq_notify(adapter, eqo->q.id, false, true, num_evts); - /* Return IRQ_HANDLED only for the the first spurious intr - * after a valid intr to stop the kernel from branding - * this irq as a bad one! + /* The EQ-notify may not de-assert INTx rightaway, causing + * the ISR to be invoked again. So, return HANDLED even when + * num_evts is zero. */ - if (num_evts || eqo->spurious_intr++ == 0) - return IRQ_HANDLED; - else - return IRQ_NONE; + be_eq_notify(adapter, eqo->q.id, false, true, num_evts); + napi_schedule(&eqo->napi); + return IRQ_HANDLED; } static irqreturn_t be_msix(int irq, void *dev) diff --git a/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c index 3e73742024b0..f80cd975daed 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -4678,7 +4678,7 @@ static int qlge_probe(struct pci_dev *pdev, qdev = netdev_priv(ndev); SET_NETDEV_DEV(ndev, &pdev->dev); ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_TSO | NETIF_F_TSO_ECN | + NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN | NETIF_F_HW_VLAN_TX | NETIF_F_RXCSUM; ndev->features = ndev->hw_features | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; diff --git a/trunk/drivers/net/ethernet/xilinx/Kconfig b/trunk/drivers/net/ethernet/xilinx/Kconfig index 122d60c0481b..5778a4ae1164 100644 --- a/trunk/drivers/net/ethernet/xilinx/Kconfig +++ b/trunk/drivers/net/ethernet/xilinx/Kconfig @@ -27,7 +27,7 @@ config XILINX_EMACLITE config XILINX_AXI_EMAC tristate "Xilinx 10/100/1000 AXI Ethernet support" - depends on MICROBLAZE + depends on (PPC32 || MICROBLAZE) select PHYLIB ---help--- This driver supports the 10/100/1000 Ethernet from Xilinx for the diff --git a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 6f47100e58d7..d9f69b82cc4f 100644 --- a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -1590,7 +1590,7 @@ static int axienet_of_probe(struct platform_device *op) lp->rx_irq = irq_of_parse_and_map(np, 1); lp->tx_irq = irq_of_parse_and_map(np, 0); of_node_put(np); - if ((lp->rx_irq <= 0) || (lp->tx_irq <= 0)) { + if ((lp->rx_irq == NO_IRQ) || (lp->tx_irq == NO_IRQ)) { dev_err(&op->dev, "could not determine irqs\n"); ret = -ENOMEM; goto err_iounmap_2; diff --git a/trunk/drivers/net/tun.c b/trunk/drivers/net/tun.c index af372d0957fe..fbd106edbe59 100644 --- a/trunk/drivers/net/tun.c +++ b/trunk/drivers/net/tun.c @@ -404,8 +404,8 @@ static void __tun_detach(struct tun_file *tfile, bool clean) struct tun_struct *tun; struct net_device *dev; - tun = rtnl_dereference(tfile->tun); - + tun = rcu_dereference_protected(tfile->tun, + lockdep_rtnl_is_held()); if (tun) { u16 index = tfile->queue_index; BUG_ON(index >= tun->numqueues); @@ -414,7 +414,8 @@ static void __tun_detach(struct tun_file *tfile, bool clean) rcu_assign_pointer(tun->tfiles[index], tun->tfiles[tun->numqueues - 1]); rcu_assign_pointer(tfile->tun, NULL); - ntfile = rtnl_dereference(tun->tfiles[index]); + ntfile = rcu_dereference_protected(tun->tfiles[index], + lockdep_rtnl_is_held()); ntfile->queue_index = index; --tun->numqueues; @@ -428,10 +429,8 @@ static void __tun_detach(struct tun_file *tfile, bool clean) /* Drop read queue */ skb_queue_purge(&tfile->sk.sk_receive_queue); tun_set_real_num_queues(tun); - } else if (tfile->detached && clean) { + } else if (tfile->detached && clean) tun = tun_enable_queue(tfile); - sock_put(&tfile->sk); - } if (clean) { if (tun && tun->numqueues == 0 && tun->numdisabled == 0 && @@ -459,7 +458,8 @@ static void tun_detach_all(struct net_device *dev) int i, n = tun->numqueues; for (i = 0; i < n; i++) { - tfile = rtnl_dereference(tun->tfiles[i]); + tfile = rcu_dereference_protected(tun->tfiles[i], + lockdep_rtnl_is_held()); BUG_ON(!tfile); wake_up_all(&tfile->wq.wait); rcu_assign_pointer(tfile->tun, NULL); @@ -469,7 +469,8 @@ static void tun_detach_all(struct net_device *dev) synchronize_net(); for (i = 0; i < n; i++) { - tfile = rtnl_dereference(tun->tfiles[i]); + tfile = rcu_dereference_protected(tun->tfiles[i], + lockdep_rtnl_is_held()); /* Drop read queue */ skb_queue_purge(&tfile->sk.sk_receive_queue); sock_put(&tfile->sk); @@ -480,9 +481,6 @@ static void tun_detach_all(struct net_device *dev) sock_put(&tfile->sk); } BUG_ON(tun->numdisabled != 0); - - if (tun->flags & TUN_PERSIST) - module_put(THIS_MODULE); } static int tun_attach(struct tun_struct *tun, struct file *file) @@ -491,7 +489,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file) int err; err = -EINVAL; - if (rtnl_dereference(tfile->tun)) + if (rcu_dereference_protected(tfile->tun, lockdep_rtnl_is_held())) goto out; err = -EBUSY; @@ -1546,9 +1544,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) struct net_device *dev; int err; - if (tfile->detached) - return -EINVAL; - dev = __dev_get_by_name(net, ifr->ifr_name); if (dev) { if (ifr->ifr_flags & IFF_TUN_EXCL) @@ -1743,7 +1738,8 @@ static void tun_detach_filter(struct tun_struct *tun, int n) struct tun_file *tfile; for (i = 0; i < n; i++) { - tfile = rtnl_dereference(tun->tfiles[i]); + tfile = rcu_dereference_protected(tun->tfiles[i], + lockdep_rtnl_is_held()); sk_detach_filter(tfile->socket.sk); } @@ -1756,7 +1752,8 @@ static int tun_attach_filter(struct tun_struct *tun) struct tun_file *tfile; for (i = 0; i < tun->numqueues; i++) { - tfile = rtnl_dereference(tun->tfiles[i]); + tfile = rcu_dereference_protected(tun->tfiles[i], + lockdep_rtnl_is_held()); ret = sk_attach_filter(&tun->fprog, tfile->socket.sk); if (ret) { tun_detach_filter(tun, i); @@ -1774,7 +1771,8 @@ static void tun_set_sndbuf(struct tun_struct *tun) int i; for (i = 0; i < tun->numqueues; i++) { - tfile = rtnl_dereference(tun->tfiles[i]); + tfile = rcu_dereference_protected(tun->tfiles[i], + lockdep_rtnl_is_held()); tfile->socket.sk->sk_sndbuf = tun->sndbuf; } } @@ -1791,10 +1789,13 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr) tun = tfile->detached; if (!tun) ret = -EINVAL; + else if (tun_not_capable(tun)) + ret = -EPERM; else ret = tun_attach(tun, file); } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) { - tun = rtnl_dereference(tfile->tun); + tun = rcu_dereference_protected(tfile->tun, + lockdep_rtnl_is_held()); if (!tun || !(tun->flags & TUN_TAP_MQ)) ret = -EINVAL; else @@ -1879,11 +1880,10 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, /* Disable/Enable persist mode. Keep an extra reference to the * module to prevent the module being unprobed. */ - if (arg && !(tun->flags & TUN_PERSIST)) { + if (arg) { tun->flags |= TUN_PERSIST; __module_get(THIS_MODULE); - } - if (!arg && (tun->flags & TUN_PERSIST)) { + } else { tun->flags &= ~TUN_PERSIST; module_put(THIS_MODULE); } diff --git a/trunk/drivers/net/wireless/ath/Kconfig b/trunk/drivers/net/wireless/ath/Kconfig index 2c02b4e84094..1a67a4f829fe 100644 --- a/trunk/drivers/net/wireless/ath/Kconfig +++ b/trunk/drivers/net/wireless/ath/Kconfig @@ -30,6 +30,5 @@ source "drivers/net/wireless/ath/ath9k/Kconfig" source "drivers/net/wireless/ath/carl9170/Kconfig" source "drivers/net/wireless/ath/ath6kl/Kconfig" source "drivers/net/wireless/ath/ar5523/Kconfig" -source "drivers/net/wireless/ath/wil6210/Kconfig" endif diff --git a/trunk/drivers/net/wireless/ath/Makefile b/trunk/drivers/net/wireless/ath/Makefile index 97b964ded2be..1e18621326dc 100644 --- a/trunk/drivers/net/wireless/ath/Makefile +++ b/trunk/drivers/net/wireless/ath/Makefile @@ -3,7 +3,6 @@ obj-$(CONFIG_ATH9K_HW) += ath9k/ obj-$(CONFIG_CARL9170) += carl9170/ obj-$(CONFIG_ATH6KL) += ath6kl/ obj-$(CONFIG_AR5523) += ar5523/ -obj-$(CONFIG_WIL6210) += wil6210/ obj-$(CONFIG_ATH_COMMON) += ath.o diff --git a/trunk/drivers/net/wireless/ath/wil6210/Kconfig b/trunk/drivers/net/wireless/ath/wil6210/Kconfig deleted file mode 100644 index bac3d98a0cfb..000000000000 --- a/trunk/drivers/net/wireless/ath/wil6210/Kconfig +++ /dev/null @@ -1,29 +0,0 @@ -config WIL6210 - tristate "Wilocity 60g WiFi card wil6210 support" - depends on CFG80211 - depends on PCI - default n - ---help--- - This module adds support for wireless adapter based on - wil6210 chip by Wilocity. It supports operation on the - 60 GHz band, covered by the IEEE802.11ad standard. - - http://wireless.kernel.org/en/users/Drivers/wil6210 - - If you choose to build it as a module, it will be called - wil6210 - -config WIL6210_ISR_COR - bool "Use Clear-On-Read mode for ISR registers for wil6210" - depends on WIL6210 - default y - ---help--- - ISR registers on wil6210 chip may operate in either - COR (Clear-On-Read) or W1C (Write-1-to-Clear) mode. - For production code, use COR (say y); is default since - it saves extra target transaction; - For ISR debug, use W1C (say n); is allows to monitor ISR - registers with debugfs. If COR were used, ISR would - self-clear when accessed for debug purposes, it makes - such monitoring impossible. - Say y unless you debug interrupts diff --git a/trunk/drivers/net/wireless/ath/wil6210/Makefile b/trunk/drivers/net/wireless/ath/wil6210/Makefile deleted file mode 100644 index 9396dc9fe3c5..000000000000 --- a/trunk/drivers/net/wireless/ath/wil6210/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -obj-$(CONFIG_WIL6210) += wil6210.o - -wil6210-objs := main.o -wil6210-objs += netdev.o -wil6210-objs += cfg80211.o -wil6210-objs += pcie_bus.o -wil6210-objs += debugfs.o -wil6210-objs += wmi.o -wil6210-objs += interrupt.o -wil6210-objs += txrx.o - -subdir-ccflags-y += -Werror -subdir-ccflags-y += -D__CHECK_ENDIAN__ diff --git a/trunk/drivers/net/wireless/ath/wil6210/cfg80211.c b/trunk/drivers/net/wireless/ath/wil6210/cfg80211.c deleted file mode 100644 index 116f4e807ae1..000000000000 --- a/trunk/drivers/net/wireless/ath/wil6210/cfg80211.c +++ /dev/null @@ -1,573 +0,0 @@ -/* - * Copyright (c) 2012 Qualcomm Atheros, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wil6210.h" -#include "wmi.h" - -#define CHAN60G(_channel, _flags) { \ - .band = IEEE80211_BAND_60GHZ, \ - .center_freq = 56160 + (2160 * (_channel)), \ - .hw_value = (_channel), \ - .flags = (_flags), \ - .max_antenna_gain = 0, \ - .max_power = 40, \ -} - -static struct ieee80211_channel wil_60ghz_channels[] = { - CHAN60G(1, 0), - CHAN60G(2, 0), - CHAN60G(3, 0), -/* channel 4 not supported yet */ -}; - -static struct ieee80211_supported_band wil_band_60ghz = { - .channels = wil_60ghz_channels, - .n_channels = ARRAY_SIZE(wil_60ghz_channels), - .ht_cap = { - .ht_supported = true, - .cap = 0, /* TODO */ - .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, /* TODO */ - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, /* TODO */ - .mcs = { - /* MCS 1..12 - SC PHY */ - .rx_mask = {0xfe, 0x1f}, /* 1..12 */ - .tx_params = IEEE80211_HT_MCS_TX_DEFINED, /* TODO */ - }, - }, -}; - -static const struct ieee80211_txrx_stypes -wil_mgmt_stypes[NUM_NL80211_IFTYPES] = { - [NL80211_IFTYPE_STATION] = { - .tx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_PROBE_RESP >> 4), - .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4) - }, - [NL80211_IFTYPE_AP] = { - .tx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_PROBE_RESP >> 4), - .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4) - }, - [NL80211_IFTYPE_P2P_CLIENT] = { - .tx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_PROBE_RESP >> 4), - .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4) - }, - [NL80211_IFTYPE_P2P_GO] = { - .tx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_PROBE_RESP >> 4), - .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4) - }, -}; - -static const u32 wil_cipher_suites[] = { - WLAN_CIPHER_SUITE_GCMP, -}; - -int wil_iftype_nl2wmi(enum nl80211_iftype type) -{ - static const struct { - enum nl80211_iftype nl; - enum wmi_network_type wmi; - } __nl2wmi[] = { - {NL80211_IFTYPE_ADHOC, WMI_NETTYPE_ADHOC}, - {NL80211_IFTYPE_STATION, WMI_NETTYPE_INFRA}, - {NL80211_IFTYPE_AP, WMI_NETTYPE_AP}, - {NL80211_IFTYPE_P2P_CLIENT, WMI_NETTYPE_P2P}, - {NL80211_IFTYPE_P2P_GO, WMI_NETTYPE_P2P}, - {NL80211_IFTYPE_MONITOR, WMI_NETTYPE_ADHOC}, /* FIXME */ - }; - uint i; - - for (i = 0; i < ARRAY_SIZE(__nl2wmi); i++) { - if (__nl2wmi[i].nl == type) - return __nl2wmi[i].wmi; - } - - return -EOPNOTSUPP; -} - -static int wil_cfg80211_get_station(struct wiphy *wiphy, - struct net_device *ndev, - u8 *mac, struct station_info *sinfo) -{ - struct wil6210_priv *wil = wiphy_to_wil(wiphy); - int rc; - struct wmi_notify_req_cmd cmd = { - .cid = 0, - .interval_usec = 0, - }; - - if (memcmp(mac, wil->dst_addr[0], ETH_ALEN)) - return -ENOENT; - - /* WMI_NOTIFY_REQ_DONE_EVENTID handler fills wil->stats.bf_mcs */ - rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, &cmd, sizeof(cmd), - WMI_NOTIFY_REQ_DONE_EVENTID, NULL, 0, 20); - if (rc) - return rc; - - sinfo->generation = wil->sinfo_gen; - - sinfo->filled |= STATION_INFO_TX_BITRATE; - sinfo->txrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G; - sinfo->txrate.mcs = wil->stats.bf_mcs; - sinfo->filled |= STATION_INFO_RX_BITRATE; - sinfo->rxrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G; - sinfo->rxrate.mcs = wil->stats.last_mcs_rx; - - if (test_bit(wil_status_fwconnected, &wil->status)) { - sinfo->filled |= STATION_INFO_SIGNAL; - sinfo->signal = 12; /* TODO: provide real value */ - } - - return 0; -} - -static int wil_cfg80211_change_iface(struct wiphy *wiphy, - struct net_device *ndev, - enum nl80211_iftype type, u32 *flags, - struct vif_params *params) -{ - struct wil6210_priv *wil = wiphy_to_wil(wiphy); - struct wireless_dev *wdev = wil->wdev; - - switch (type) { - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_P2P_CLIENT: - case NL80211_IFTYPE_P2P_GO: - break; - case NL80211_IFTYPE_MONITOR: - if (flags) - wil->monitor_flags = *flags; - else - wil->monitor_flags = 0; - - break; - default: - return -EOPNOTSUPP; - } - - wdev->iftype = type; - - return 0; -} - -static int wil_cfg80211_scan(struct wiphy *wiphy, - struct cfg80211_scan_request *request) -{ - struct wil6210_priv *wil = wiphy_to_wil(wiphy); - struct wireless_dev *wdev = wil->wdev; - struct { - struct wmi_start_scan_cmd cmd; - u16 chnl[4]; - } __packed cmd; - uint i, n; - - if (wil->scan_request) { - wil_err(wil, "Already scanning\n"); - return -EAGAIN; - } - - /* check we are client side */ - switch (wdev->iftype) { - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_P2P_CLIENT: - break; - default: - return -EOPNOTSUPP; - - } - - /* FW don't support scan after connection attempt */ - if (test_bit(wil_status_dontscan, &wil->status)) { - wil_err(wil, "Scan after connect attempt not supported\n"); - return -EBUSY; - } - - wil->scan_request = request; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd.num_channels = 0; - n = min(request->n_channels, 4U); - for (i = 0; i < n; i++) { - int ch = request->channels[i]->hw_value; - if (ch == 0) { - wil_err(wil, - "Scan requested for unknown frequency %dMhz\n", - request->channels[i]->center_freq); - continue; - } - /* 0-based channel indexes */ - cmd.cmd.channel_list[cmd.cmd.num_channels++].channel = ch - 1; - wil_dbg(wil, "Scan for ch %d : %d MHz\n", ch, - request->channels[i]->center_freq); - } - - return wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) + - cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0])); -} - -static int wil_cfg80211_connect(struct wiphy *wiphy, - struct net_device *ndev, - struct cfg80211_connect_params *sme) -{ - struct wil6210_priv *wil = wiphy_to_wil(wiphy); - struct cfg80211_bss *bss; - struct wmi_connect_cmd conn; - const u8 *ssid_eid; - const u8 *rsn_eid; - int ch; - int rc = 0; - - bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, - sme->ssid, sme->ssid_len, - WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); - if (!bss) { - wil_err(wil, "Unable to find BSS\n"); - return -ENOENT; - } - - ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID); - if (!ssid_eid) { - wil_err(wil, "No SSID\n"); - rc = -ENOENT; - goto out; - } - - rsn_eid = sme->ie ? - cfg80211_find_ie(WLAN_EID_RSN, sme->ie, sme->ie_len) : - NULL; - if (rsn_eid) { - if (sme->ie_len > WMI_MAX_IE_LEN) { - rc = -ERANGE; - wil_err(wil, "IE too large (%td bytes)\n", - sme->ie_len); - goto out; - } - /* - * For secure assoc, send: - * (1) WMI_DELETE_CIPHER_KEY_CMD - * (2) WMI_SET_APPIE_CMD - */ - rc = wmi_del_cipher_key(wil, 0, bss->bssid); - if (rc) { - wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD failed\n"); - goto out; - } - /* WMI_SET_APPIE_CMD */ - rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie); - if (rc) { - wil_err(wil, "WMI_SET_APPIE_CMD failed\n"); - goto out; - } - } - - /* WMI_CONNECT_CMD */ - memset(&conn, 0, sizeof(conn)); - switch (bss->capability & 0x03) { - case WLAN_CAPABILITY_DMG_TYPE_AP: - conn.network_type = WMI_NETTYPE_INFRA; - break; - case WLAN_CAPABILITY_DMG_TYPE_PBSS: - conn.network_type = WMI_NETTYPE_P2P; - break; - default: - wil_err(wil, "Unsupported BSS type, capability= 0x%04x\n", - bss->capability); - goto out; - } - if (rsn_eid) { - conn.dot11_auth_mode = WMI_AUTH11_SHARED; - conn.auth_mode = WMI_AUTH_WPA2_PSK; - conn.pairwise_crypto_type = WMI_CRYPT_AES_GCMP; - conn.pairwise_crypto_len = 16; - } else { - conn.dot11_auth_mode = WMI_AUTH11_OPEN; - conn.auth_mode = WMI_AUTH_NONE; - } - - conn.ssid_len = min_t(u8, ssid_eid[1], 32); - memcpy(conn.ssid, ssid_eid+2, conn.ssid_len); - - ch = bss->channel->hw_value; - if (ch == 0) { - wil_err(wil, "BSS at unknown frequency %dMhz\n", - bss->channel->center_freq); - rc = -EOPNOTSUPP; - goto out; - } - conn.channel = ch - 1; - - memcpy(conn.bssid, bss->bssid, 6); - memcpy(conn.dst_mac, bss->bssid, 6); - /* - * FW don't support scan after connection attempt - */ - set_bit(wil_status_dontscan, &wil->status); - - rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn)); - if (rc == 0) { - /* Connect can take lots of time */ - mod_timer(&wil->connect_timer, - jiffies + msecs_to_jiffies(2000)); - } - - out: - cfg80211_put_bss(bss); - - return rc; -} - -static int wil_cfg80211_disconnect(struct wiphy *wiphy, - struct net_device *ndev, - u16 reason_code) -{ - int rc; - struct wil6210_priv *wil = wiphy_to_wil(wiphy); - - rc = wmi_send(wil, WMI_DISCONNECT_CMDID, NULL, 0); - - return rc; -} - -static int wil_cfg80211_set_channel(struct wiphy *wiphy, - struct cfg80211_chan_def *chandef) -{ - struct wil6210_priv *wil = wiphy_to_wil(wiphy); - struct wireless_dev *wdev = wil->wdev; - - wdev->preset_chandef = *chandef; - - return 0; -} - -static int wil_cfg80211_add_key(struct wiphy *wiphy, - struct net_device *ndev, - u8 key_index, bool pairwise, - const u8 *mac_addr, - struct key_params *params) -{ - struct wil6210_priv *wil = wiphy_to_wil(wiphy); - - /* group key is not used */ - if (!pairwise) - return 0; - - return wmi_add_cipher_key(wil, key_index, mac_addr, - params->key_len, params->key); -} - -static int wil_cfg80211_del_key(struct wiphy *wiphy, - struct net_device *ndev, - u8 key_index, bool pairwise, - const u8 *mac_addr) -{ - struct wil6210_priv *wil = wiphy_to_wil(wiphy); - - /* group key is not used */ - if (!pairwise) - return 0; - - return wmi_del_cipher_key(wil, key_index, mac_addr); -} - -/* Need to be present or wiphy_new() will WARN */ -static int wil_cfg80211_set_default_key(struct wiphy *wiphy, - struct net_device *ndev, - u8 key_index, bool unicast, - bool multicast) -{ - return 0; -} - -static int wil_cfg80211_start_ap(struct wiphy *wiphy, - struct net_device *ndev, - struct cfg80211_ap_settings *info) -{ - int rc = 0; - struct wil6210_priv *wil = wiphy_to_wil(wiphy); - struct wireless_dev *wdev = ndev->ieee80211_ptr; - struct ieee80211_channel *channel = info->chandef.chan; - struct cfg80211_beacon_data *bcon = &info->beacon; - u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype); - - if (!channel) { - wil_err(wil, "AP: No channel???\n"); - return -EINVAL; - } - - wil_dbg(wil, "AP on Channel %d %d MHz, %s\n", channel->hw_value, - channel->center_freq, info->privacy ? "secure" : "open"); - print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET, - info->ssid, info->ssid_len); - - rc = wil_reset(wil); - if (rc) - return rc; - - rc = wmi_set_ssid(wil, info->ssid_len, info->ssid); - if (rc) - return rc; - - rc = wmi_set_channel(wil, channel->hw_value); - if (rc) - return rc; - - /* MAC address - pre-requisite for other commands */ - wmi_set_mac_address(wil, ndev->dev_addr); - - /* IE's */ - /* bcon 'head IE's are not relevant for 60g band */ - wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->beacon_ies_len, - bcon->beacon_ies); - wmi_set_ie(wil, WMI_FRAME_PROBE_RESP, bcon->proberesp_ies_len, - bcon->proberesp_ies); - wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, bcon->assocresp_ies_len, - bcon->assocresp_ies); - - wil->secure_pcp = info->privacy; - - rc = wmi_set_bcon(wil, info->beacon_interval, wmi_nettype); - if (rc) - return rc; - - /* Rx VRING. After MAC and beacon */ - rc = wil_rx_init(wil); - - netif_carrier_on(ndev); - - return rc; -} - -static int wil_cfg80211_stop_ap(struct wiphy *wiphy, - struct net_device *ndev) -{ - int rc = 0; - struct wil6210_priv *wil = wiphy_to_wil(wiphy); - struct wireless_dev *wdev = ndev->ieee80211_ptr; - u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype); - - /* To stop beaconing, set BI to 0 */ - rc = wmi_set_bcon(wil, 0, wmi_nettype); - - return rc; -} - -static struct cfg80211_ops wil_cfg80211_ops = { - .scan = wil_cfg80211_scan, - .connect = wil_cfg80211_connect, - .disconnect = wil_cfg80211_disconnect, - .change_virtual_intf = wil_cfg80211_change_iface, - .get_station = wil_cfg80211_get_station, - .set_monitor_channel = wil_cfg80211_set_channel, - .add_key = wil_cfg80211_add_key, - .del_key = wil_cfg80211_del_key, - .set_default_key = wil_cfg80211_set_default_key, - /* AP mode */ - .start_ap = wil_cfg80211_start_ap, - .stop_ap = wil_cfg80211_stop_ap, -}; - -static void wil_wiphy_init(struct wiphy *wiphy) -{ - /* TODO: set real value */ - wiphy->max_scan_ssids = 10; - wiphy->max_num_pmkids = 0 /* TODO: */; - wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_MONITOR); - /* TODO: enable P2P when integrated with supplicant: - * BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO) - */ - wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | - WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; - dev_warn(wiphy_dev(wiphy), "%s : flags = 0x%08x\n", - __func__, wiphy->flags); - wiphy->probe_resp_offload = - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P; - - wiphy->bands[IEEE80211_BAND_60GHZ] = &wil_band_60ghz; - - /* TODO: figure this out */ - wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; - - wiphy->cipher_suites = wil_cipher_suites; - wiphy->n_cipher_suites = ARRAY_SIZE(wil_cipher_suites); - wiphy->mgmt_stypes = wil_mgmt_stypes; -} - -struct wireless_dev *wil_cfg80211_init(struct device *dev) -{ - int rc = 0; - struct wireless_dev *wdev; - - wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); - if (!wdev) - return ERR_PTR(-ENOMEM); - - wdev->wiphy = wiphy_new(&wil_cfg80211_ops, - sizeof(struct wil6210_priv)); - if (!wdev->wiphy) { - rc = -ENOMEM; - goto out; - } - - set_wiphy_dev(wdev->wiphy, dev); - wil_wiphy_init(wdev->wiphy); - - rc = wiphy_register(wdev->wiphy); - if (rc < 0) - goto out_failed_reg; - - return wdev; - -out_failed_reg: - wiphy_free(wdev->wiphy); -out: - kfree(wdev); - - return ERR_PTR(rc); -} - -void wil_wdev_free(struct wil6210_priv *wil) -{ - struct wireless_dev *wdev = wil_to_wdev(wil); - - if (!wdev) - return; - - wiphy_unregister(wdev->wiphy); - wiphy_free(wdev->wiphy); - kfree(wdev); -} diff --git a/trunk/drivers/net/wireless/ath/wil6210/dbg_hexdump.h b/trunk/drivers/net/wireless/ath/wil6210/dbg_hexdump.h deleted file mode 100644 index 6a315ba5aa7d..000000000000 --- a/trunk/drivers/net/wireless/ath/wil6210/dbg_hexdump.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef WIL_DBG_HEXDUMP_H_ -#define WIL_DBG_HEXDUMP_H_ - -#if defined(CONFIG_DYNAMIC_DEBUG) -#define wil_dynamic_hex_dump(prefix_str, prefix_type, rowsize, \ - groupsize, buf, len, ascii) \ -do { \ - DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, \ - __builtin_constant_p(prefix_str) ? prefix_str : "hexdump");\ - if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \ - print_hex_dump(KERN_DEBUG, prefix_str, \ - prefix_type, rowsize, groupsize, \ - buf, len, ascii); \ -} while (0) - -#define wil_print_hex_dump_debug(prefix_str, prefix_type, rowsize, \ - groupsize, buf, len, ascii) \ - wil_dynamic_hex_dump(prefix_str, prefix_type, rowsize, \ - groupsize, buf, len, ascii) - -#define print_hex_dump_bytes(prefix_str, prefix_type, buf, len) \ - wil_dynamic_hex_dump(prefix_str, prefix_type, 16, 1, buf, len, true) -#else /* defined(CONFIG_DYNAMIC_DEBUG) */ -#define wil_print_hex_dump_debug(prefix_str, prefix_type, rowsize, \ - groupsize, buf, len, ascii) \ - print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, rowsize, \ - groupsize, buf, len, ascii) -#endif /* defined(CONFIG_DYNAMIC_DEBUG) */ - -#endif /* WIL_DBG_HEXDUMP_H_ */ diff --git a/trunk/drivers/net/wireless/ath/wil6210/debugfs.c b/trunk/drivers/net/wireless/ath/wil6210/debugfs.c deleted file mode 100644 index 65fc9683bfd8..000000000000 --- a/trunk/drivers/net/wireless/ath/wil6210/debugfs.c +++ /dev/null @@ -1,603 +0,0 @@ -/* - * Copyright (c) 2012 Qualcomm Atheros, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include - -#include "wil6210.h" -#include "txrx.h" - -/* Nasty hack. Better have per device instances */ -static u32 mem_addr; -static u32 dbg_txdesc_index; - -static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil, - const char *name, struct vring *vring) -{ - void __iomem *x = wmi_addr(wil, vring->hwtail); - - seq_printf(s, "VRING %s = {\n", name); - seq_printf(s, " pa = 0x%016llx\n", (unsigned long long)vring->pa); - seq_printf(s, " va = 0x%p\n", vring->va); - seq_printf(s, " size = %d\n", vring->size); - seq_printf(s, " swtail = %d\n", vring->swtail); - seq_printf(s, " swhead = %d\n", vring->swhead); - seq_printf(s, " hwtail = [0x%08x] -> ", vring->hwtail); - if (x) - seq_printf(s, "0x%08x\n", ioread32(x)); - else - seq_printf(s, "???\n"); - - if (vring->va && (vring->size < 1025)) { - uint i; - for (i = 0; i < vring->size; i++) { - volatile struct vring_tx_desc *d = &vring->va[i].tx; - if ((i % 64) == 0 && (i != 0)) - seq_printf(s, "\n"); - seq_printf(s, "%s", (d->dma.status & BIT(0)) ? - "S" : (vring->ctx[i] ? "H" : "h")); - } - seq_printf(s, "\n"); - } - seq_printf(s, "}\n"); -} - -static int wil_vring_debugfs_show(struct seq_file *s, void *data) -{ - uint i; - struct wil6210_priv *wil = s->private; - - wil_print_vring(s, wil, "rx", &wil->vring_rx); - - for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) { - struct vring *vring = &(wil->vring_tx[i]); - if (vring->va) { - char name[10]; - snprintf(name, sizeof(name), "tx_%2d", i); - wil_print_vring(s, wil, name, vring); - } - } - - return 0; -} - -static int wil_vring_seq_open(struct inode *inode, struct file *file) -{ - return single_open(file, wil_vring_debugfs_show, inode->i_private); -} - -static const struct file_operations fops_vring = { - .open = wil_vring_seq_open, - .release = single_release, - .read = seq_read, - .llseek = seq_lseek, -}; - -static void wil_print_ring(struct seq_file *s, const char *prefix, - void __iomem *off) -{ - struct wil6210_priv *wil = s->private; - struct wil6210_mbox_ring r; - int rsize; - uint i; - - wil_memcpy_fromio_32(&r, off, sizeof(r)); - wil_mbox_ring_le2cpus(&r); - /* - * we just read memory block from NIC. This memory may be - * garbage. Check validity before using it. - */ - rsize = r.size / sizeof(struct wil6210_mbox_ring_desc); - - seq_printf(s, "ring %s = {\n", prefix); - seq_printf(s, " base = 0x%08x\n", r.base); - seq_printf(s, " size = 0x%04x bytes -> %d entries\n", r.size, rsize); - seq_printf(s, " tail = 0x%08x\n", r.tail); - seq_printf(s, " head = 0x%08x\n", r.head); - seq_printf(s, " entry size = %d\n", r.entry_size); - - if (r.size % sizeof(struct wil6210_mbox_ring_desc)) { - seq_printf(s, " ??? size is not multiple of %zd, garbage?\n", - sizeof(struct wil6210_mbox_ring_desc)); - goto out; - } - - if (!wmi_addr(wil, r.base) || - !wmi_addr(wil, r.tail) || - !wmi_addr(wil, r.head)) { - seq_printf(s, " ??? pointers are garbage?\n"); - goto out; - } - - for (i = 0; i < rsize; i++) { - struct wil6210_mbox_ring_desc d; - struct wil6210_mbox_hdr hdr; - size_t delta = i * sizeof(d); - void __iomem *x = wil->csr + HOSTADDR(r.base) + delta; - - wil_memcpy_fromio_32(&d, x, sizeof(d)); - - seq_printf(s, " [%2x] %s %s%s 0x%08x", i, - d.sync ? "F" : "E", - (r.tail - r.base == delta) ? "t" : " ", - (r.head - r.base == delta) ? "h" : " ", - le32_to_cpu(d.addr)); - if (0 == wmi_read_hdr(wil, d.addr, &hdr)) { - u16 len = le16_to_cpu(hdr.len); - seq_printf(s, " -> %04x %04x %04x %02x\n", - le16_to_cpu(hdr.seq), len, - le16_to_cpu(hdr.type), hdr.flags); - if (len <= MAX_MBOXITEM_SIZE) { - int n = 0; - unsigned char printbuf[16 * 3 + 2]; - unsigned char databuf[MAX_MBOXITEM_SIZE]; - void __iomem *src = wmi_buffer(wil, d.addr) + - sizeof(struct wil6210_mbox_hdr); - /* - * No need to check @src for validity - - * we already validated @d.addr while - * reading header - */ - wil_memcpy_fromio_32(databuf, src, len); - while (n < len) { - int l = min(len - n, 16); - hex_dump_to_buffer(databuf + n, l, - 16, 1, printbuf, - sizeof(printbuf), - false); - seq_printf(s, " : %s\n", printbuf); - n += l; - } - } - } else { - seq_printf(s, "\n"); - } - } - out: - seq_printf(s, "}\n"); -} - -static int wil_mbox_debugfs_show(struct seq_file *s, void *data) -{ - struct wil6210_priv *wil = s->private; - - wil_print_ring(s, "tx", wil->csr + HOST_MBOX + - offsetof(struct wil6210_mbox_ctl, tx)); - wil_print_ring(s, "rx", wil->csr + HOST_MBOX + - offsetof(struct wil6210_mbox_ctl, rx)); - - return 0; -} - -static int wil_mbox_seq_open(struct inode *inode, struct file *file) -{ - return single_open(file, wil_mbox_debugfs_show, inode->i_private); -} - -static const struct file_operations fops_mbox = { - .open = wil_mbox_seq_open, - .release = single_release, - .read = seq_read, - .llseek = seq_lseek, -}; - -static int wil_debugfs_iomem_x32_set(void *data, u64 val) -{ - iowrite32(val, (void __iomem *)data); - wmb(); /* make sure write propagated to HW */ - - return 0; -} - -static int wil_debugfs_iomem_x32_get(void *data, u64 *val) -{ - *val = ioread32((void __iomem *)data); - - return 0; -} - -DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x32, wil_debugfs_iomem_x32_get, - wil_debugfs_iomem_x32_set, "0x%08llx\n"); - -static struct dentry *wil_debugfs_create_iomem_x32(const char *name, - mode_t mode, - struct dentry *parent, - void __iomem *value) -{ - return debugfs_create_file(name, mode, parent, (void * __force)value, - &fops_iomem_x32); -} - -static int wil6210_debugfs_create_ISR(struct wil6210_priv *wil, - const char *name, - struct dentry *parent, u32 off) -{ - struct dentry *d = debugfs_create_dir(name, parent); - - if (IS_ERR_OR_NULL(d)) - return -ENODEV; - - wil_debugfs_create_iomem_x32("ICC", S_IRUGO | S_IWUSR, d, - wil->csr + off); - wil_debugfs_create_iomem_x32("ICR", S_IRUGO | S_IWUSR, d, - wil->csr + off + 4); - wil_debugfs_create_iomem_x32("ICM", S_IRUGO | S_IWUSR, d, - wil->csr + off + 8); - wil_debugfs_create_iomem_x32("ICS", S_IWUSR, d, - wil->csr + off + 12); - wil_debugfs_create_iomem_x32("IMV", S_IRUGO | S_IWUSR, d, - wil->csr + off + 16); - wil_debugfs_create_iomem_x32("IMS", S_IWUSR, d, - wil->csr + off + 20); - wil_debugfs_create_iomem_x32("IMC", S_IWUSR, d, - wil->csr + off + 24); - - return 0; -} - -static int wil6210_debugfs_create_pseudo_ISR(struct wil6210_priv *wil, - struct dentry *parent) -{ - struct dentry *d = debugfs_create_dir("PSEUDO_ISR", parent); - - if (IS_ERR_OR_NULL(d)) - return -ENODEV; - - wil_debugfs_create_iomem_x32("CAUSE", S_IRUGO, d, wil->csr + - HOSTADDR(RGF_DMA_PSEUDO_CAUSE)); - wil_debugfs_create_iomem_x32("MASK_SW", S_IRUGO, d, wil->csr + - HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW)); - wil_debugfs_create_iomem_x32("MASK_FW", S_IRUGO, d, wil->csr + - HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_FW)); - - return 0; -} - -static int wil6210_debugfs_create_ITR_CNT(struct wil6210_priv *wil, - struct dentry *parent) -{ - struct dentry *d = debugfs_create_dir("ITR_CNT", parent); - - if (IS_ERR_OR_NULL(d)) - return -ENODEV; - - wil_debugfs_create_iomem_x32("TRSH", S_IRUGO, d, wil->csr + - HOSTADDR(RGF_DMA_ITR_CNT_TRSH)); - wil_debugfs_create_iomem_x32("DATA", S_IRUGO, d, wil->csr + - HOSTADDR(RGF_DMA_ITR_CNT_DATA)); - wil_debugfs_create_iomem_x32("CTL", S_IRUGO, d, wil->csr + - HOSTADDR(RGF_DMA_ITR_CNT_CRL)); - - return 0; -} - -static int wil_memread_debugfs_show(struct seq_file *s, void *data) -{ - struct wil6210_priv *wil = s->private; - void __iomem *a = wmi_buffer(wil, cpu_to_le32(mem_addr)); - - if (a) - seq_printf(s, "[0x%08x] = 0x%08x\n", mem_addr, ioread32(a)); - else - seq_printf(s, "[0x%08x] = INVALID\n", mem_addr); - - return 0; -} - -static int wil_memread_seq_open(struct inode *inode, struct file *file) -{ - return single_open(file, wil_memread_debugfs_show, inode->i_private); -} - -static const struct file_operations fops_memread = { - .open = wil_memread_seq_open, - .release = single_release, - .read = seq_read, - .llseek = seq_lseek, -}; - -static int wil_default_open(struct inode *inode, struct file *file) -{ - if (inode->i_private) - file->private_data = inode->i_private; - - return 0; -} - -static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - enum { max_count = 4096 }; - struct debugfs_blob_wrapper *blob = file->private_data; - loff_t pos = *ppos; - size_t available = blob->size; - void *buf; - size_t ret; - - if (pos < 0) - return -EINVAL; - - if (pos >= available || !count) - return 0; - - if (count > available - pos) - count = available - pos; - if (count > max_count) - count = max_count; - - buf = kmalloc(count, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - wil_memcpy_fromio_32(buf, (const volatile void __iomem *)blob->data + - pos, count); - - ret = copy_to_user(user_buf, buf, count); - kfree(buf); - if (ret == count) - return -EFAULT; - - count -= ret; - *ppos = pos + count; - - return count; -} - -static const struct file_operations fops_ioblob = { - .read = wil_read_file_ioblob, - .open = wil_default_open, - .llseek = default_llseek, -}; - -static -struct dentry *wil_debugfs_create_ioblob(const char *name, - mode_t mode, - struct dentry *parent, - struct debugfs_blob_wrapper *blob) -{ - return debugfs_create_file(name, mode, parent, blob, &fops_ioblob); -} -/*---reset---*/ -static ssize_t wil_write_file_reset(struct file *file, const char __user *buf, - size_t len, loff_t *ppos) -{ - struct wil6210_priv *wil = file->private_data; - struct net_device *ndev = wil_to_ndev(wil); - - /** - * BUG: - * this code does NOT sync device state with the rest of system - * use with care, debug only!!! - */ - rtnl_lock(); - dev_close(ndev); - ndev->flags &= ~IFF_UP; - rtnl_unlock(); - wil_reset(wil); - - return len; -} - -static const struct file_operations fops_reset = { - .write = wil_write_file_reset, - .open = wil_default_open, -}; -/*---------Tx descriptor------------*/ - -static int wil_txdesc_debugfs_show(struct seq_file *s, void *data) -{ - struct wil6210_priv *wil = s->private; - struct vring *vring = &(wil->vring_tx[0]); - - if (!vring->va) { - seq_printf(s, "No Tx VRING\n"); - return 0; - } - - if (dbg_txdesc_index < vring->size) { - volatile struct vring_tx_desc *d = - &(vring->va[dbg_txdesc_index].tx); - volatile u32 *u = (volatile u32 *)d; - struct sk_buff *skb = vring->ctx[dbg_txdesc_index]; - - seq_printf(s, "Tx[%3d] = {\n", dbg_txdesc_index); - seq_printf(s, " MAC = 0x%08x 0x%08x 0x%08x 0x%08x\n", - u[0], u[1], u[2], u[3]); - seq_printf(s, " DMA = 0x%08x 0x%08x 0x%08x 0x%08x\n", - u[4], u[5], u[6], u[7]); - seq_printf(s, " SKB = %p\n", skb); - - if (skb) { - unsigned char printbuf[16 * 3 + 2]; - int i = 0; - int len = skb_headlen(skb); - void *p = skb->data; - - seq_printf(s, " len = %d\n", len); - - while (i < len) { - int l = min(len - i, 16); - hex_dump_to_buffer(p + i, l, 16, 1, printbuf, - sizeof(printbuf), false); - seq_printf(s, " : %s\n", printbuf); - i += l; - } - } - seq_printf(s, "}\n"); - } else { - seq_printf(s, "TxDesc index (%d) >= size (%d)\n", - dbg_txdesc_index, vring->size); - } - - return 0; -} - -static int wil_txdesc_seq_open(struct inode *inode, struct file *file) -{ - return single_open(file, wil_txdesc_debugfs_show, inode->i_private); -} - -static const struct file_operations fops_txdesc = { - .open = wil_txdesc_seq_open, - .release = single_release, - .read = seq_read, - .llseek = seq_lseek, -}; - -/*---------beamforming------------*/ -static int wil_bf_debugfs_show(struct seq_file *s, void *data) -{ - struct wil6210_priv *wil = s->private; - seq_printf(s, - "TSF : 0x%016llx\n" - "TxMCS : %d\n" - "Sectors(rx:tx) my %2d:%2d peer %2d:%2d\n", - wil->stats.tsf, wil->stats.bf_mcs, - wil->stats.my_rx_sector, wil->stats.my_tx_sector, - wil->stats.peer_rx_sector, wil->stats.peer_tx_sector); - return 0; -} - -static int wil_bf_seq_open(struct inode *inode, struct file *file) -{ - return single_open(file, wil_bf_debugfs_show, inode->i_private); -} - -static const struct file_operations fops_bf = { - .open = wil_bf_seq_open, - .release = single_release, - .read = seq_read, - .llseek = seq_lseek, -}; -/*---------SSID------------*/ -static ssize_t wil_read_file_ssid(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct wil6210_priv *wil = file->private_data; - struct wireless_dev *wdev = wil_to_wdev(wil); - - return simple_read_from_buffer(user_buf, count, ppos, - wdev->ssid, wdev->ssid_len); -} - -static ssize_t wil_write_file_ssid(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct wil6210_priv *wil = file->private_data; - struct wireless_dev *wdev = wil_to_wdev(wil); - struct net_device *ndev = wil_to_ndev(wil); - - if (*ppos != 0) { - wil_err(wil, "Unable to set SSID substring from [%d]\n", - (int)*ppos); - return -EINVAL; - } - - if (count > sizeof(wdev->ssid)) { - wil_err(wil, "SSID too long, len = %d\n", (int)count); - return -EINVAL; - } - if (netif_running(ndev)) { - wil_err(wil, "Unable to change SSID on running interface\n"); - return -EINVAL; - } - - wdev->ssid_len = count; - return simple_write_to_buffer(wdev->ssid, wdev->ssid_len, ppos, - buf, count); -} - -static const struct file_operations fops_ssid = { - .read = wil_read_file_ssid, - .write = wil_write_file_ssid, - .open = wil_default_open, -}; - -/*----------------*/ -int wil6210_debugfs_init(struct wil6210_priv *wil) -{ - struct dentry *dbg = wil->debug = debugfs_create_dir(WIL_NAME, - wil_to_wiphy(wil)->debugfsdir); - - if (IS_ERR_OR_NULL(dbg)) - return -ENODEV; - - debugfs_create_file("mbox", S_IRUGO, dbg, wil, &fops_mbox); - debugfs_create_file("vrings", S_IRUGO, dbg, wil, &fops_vring); - debugfs_create_file("txdesc", S_IRUGO, dbg, wil, &fops_txdesc); - debugfs_create_u32("txdesc_index", S_IRUGO | S_IWUSR, dbg, - &dbg_txdesc_index); - debugfs_create_file("bf", S_IRUGO, dbg, wil, &fops_bf); - debugfs_create_file("ssid", S_IRUGO | S_IWUSR, dbg, wil, &fops_ssid); - debugfs_create_u32("secure_pcp", S_IRUGO | S_IWUSR, dbg, - &wil->secure_pcp); - - wil6210_debugfs_create_ISR(wil, "USER_ICR", dbg, - HOSTADDR(RGF_USER_USER_ICR)); - wil6210_debugfs_create_ISR(wil, "DMA_EP_TX_ICR", dbg, - HOSTADDR(RGF_DMA_EP_TX_ICR)); - wil6210_debugfs_create_ISR(wil, "DMA_EP_RX_ICR", dbg, - HOSTADDR(RGF_DMA_EP_RX_ICR)); - wil6210_debugfs_create_ISR(wil, "DMA_EP_MISC_ICR", dbg, - HOSTADDR(RGF_DMA_EP_MISC_ICR)); - wil6210_debugfs_create_pseudo_ISR(wil, dbg); - wil6210_debugfs_create_ITR_CNT(wil, dbg); - - debugfs_create_u32("mem_addr", S_IRUGO | S_IWUSR, dbg, &mem_addr); - debugfs_create_file("mem_val", S_IRUGO, dbg, wil, &fops_memread); - - debugfs_create_file("reset", S_IWUSR, dbg, wil, &fops_reset); - - wil->rgf_blob.data = (void * __force)wil->csr + 0; - wil->rgf_blob.size = 0xa000; - wil_debugfs_create_ioblob("blob_rgf", S_IRUGO, dbg, &wil->rgf_blob); - - wil->fw_code_blob.data = (void * __force)wil->csr + 0x40000; - wil->fw_code_blob.size = 0x40000; - wil_debugfs_create_ioblob("blob_fw_code", S_IRUGO, dbg, - &wil->fw_code_blob); - - wil->fw_data_blob.data = (void * __force)wil->csr + 0x80000; - wil->fw_data_blob.size = 0x8000; - wil_debugfs_create_ioblob("blob_fw_data", S_IRUGO, dbg, - &wil->fw_data_blob); - - wil->fw_peri_blob.data = (void * __force)wil->csr + 0x88000; - wil->fw_peri_blob.size = 0x18000; - wil_debugfs_create_ioblob("blob_fw_peri", S_IRUGO, dbg, - &wil->fw_peri_blob); - - wil->uc_code_blob.data = (void * __force)wil->csr + 0xa0000; - wil->uc_code_blob.size = 0x10000; - wil_debugfs_create_ioblob("blob_uc_code", S_IRUGO, dbg, - &wil->uc_code_blob); - - wil->uc_data_blob.data = (void * __force)wil->csr + 0xb0000; - wil->uc_data_blob.size = 0x4000; - wil_debugfs_create_ioblob("blob_uc_data", S_IRUGO, dbg, - &wil->uc_data_blob); - - return 0; -} - -void wil6210_debugfs_remove(struct wil6210_priv *wil) -{ - debugfs_remove_recursive(wil->debug); - wil->debug = NULL; -} diff --git a/trunk/drivers/net/wireless/ath/wil6210/interrupt.c b/trunk/drivers/net/wireless/ath/wil6210/interrupt.c deleted file mode 100644 index 38049da71049..000000000000 --- a/trunk/drivers/net/wireless/ath/wil6210/interrupt.c +++ /dev/null @@ -1,471 +0,0 @@ -/* - * Copyright (c) 2012 Qualcomm Atheros, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -#include "wil6210.h" - -/** - * Theory of operation: - * - * There is ISR pseudo-cause register, - * dma_rgf->DMA_RGF.PSEUDO_CAUSE.PSEUDO_CAUSE - * Its bits represents OR'ed bits from 3 real ISR registers: - * TX, RX, and MISC. - * - * Registers may be configured to either "write 1 to clear" or - * "clear on read" mode - * - * When handling interrupt, one have to mask/unmask interrupts for the - * real ISR registers, or hardware may malfunction. - * - */ - -#define WIL6210_IRQ_DISABLE (0xFFFFFFFFUL) -#define WIL6210_IMC_RX BIT_DMA_EP_RX_ICR_RX_DONE -#define WIL6210_IMC_TX (BIT_DMA_EP_TX_ICR_TX_DONE | \ - BIT_DMA_EP_TX_ICR_TX_DONE_N(0)) -#define WIL6210_IMC_MISC (ISR_MISC_FW_READY | ISR_MISC_MBOX_EVT) - -#define WIL6210_IRQ_PSEUDO_MASK (u32)(~(BIT_DMA_PSEUDO_CAUSE_RX | \ - BIT_DMA_PSEUDO_CAUSE_TX | \ - BIT_DMA_PSEUDO_CAUSE_MISC)) - -#if defined(CONFIG_WIL6210_ISR_COR) -/* configure to Clear-On-Read mode */ -#define WIL_ICR_ICC_VALUE (0xFFFFFFFFUL) - -static inline void wil_icr_clear(u32 x, void __iomem *addr) -{ - -} -#else /* defined(CONFIG_WIL6210_ISR_COR) */ -/* configure to Write-1-to-Clear mode */ -#define WIL_ICR_ICC_VALUE (0UL) - -static inline void wil_icr_clear(u32 x, void __iomem *addr) -{ - iowrite32(x, addr); -} -#endif /* defined(CONFIG_WIL6210_ISR_COR) */ - -static inline u32 wil_ioread32_and_clear(void __iomem *addr) -{ - u32 x = ioread32(addr); - - wil_icr_clear(x, addr); - - return x; -} - -static void wil6210_mask_irq_tx(struct wil6210_priv *wil) -{ - iowrite32(WIL6210_IRQ_DISABLE, wil->csr + - HOSTADDR(RGF_DMA_EP_TX_ICR) + - offsetof(struct RGF_ICR, IMS)); -} - -static void wil6210_mask_irq_rx(struct wil6210_priv *wil) -{ - iowrite32(WIL6210_IRQ_DISABLE, wil->csr + - HOSTADDR(RGF_DMA_EP_RX_ICR) + - offsetof(struct RGF_ICR, IMS)); -} - -static void wil6210_mask_irq_misc(struct wil6210_priv *wil) -{ - iowrite32(WIL6210_IRQ_DISABLE, wil->csr + - HOSTADDR(RGF_DMA_EP_MISC_ICR) + - offsetof(struct RGF_ICR, IMS)); -} - -static void wil6210_mask_irq_pseudo(struct wil6210_priv *wil) -{ - wil_dbg_IRQ(wil, "%s()\n", __func__); - - iowrite32(WIL6210_IRQ_DISABLE, wil->csr + - HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW)); - - clear_bit(wil_status_irqen, &wil->status); -} - -static void wil6210_unmask_irq_tx(struct wil6210_priv *wil) -{ - iowrite32(WIL6210_IMC_TX, wil->csr + - HOSTADDR(RGF_DMA_EP_TX_ICR) + - offsetof(struct RGF_ICR, IMC)); -} - -static void wil6210_unmask_irq_rx(struct wil6210_priv *wil) -{ - iowrite32(WIL6210_IMC_RX, wil->csr + - HOSTADDR(RGF_DMA_EP_RX_ICR) + - offsetof(struct RGF_ICR, IMC)); -} - -static void wil6210_unmask_irq_misc(struct wil6210_priv *wil) -{ - iowrite32(WIL6210_IMC_MISC, wil->csr + - HOSTADDR(RGF_DMA_EP_MISC_ICR) + - offsetof(struct RGF_ICR, IMC)); -} - -static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil) -{ - wil_dbg_IRQ(wil, "%s()\n", __func__); - - set_bit(wil_status_irqen, &wil->status); - - iowrite32(WIL6210_IRQ_PSEUDO_MASK, wil->csr + - HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW)); -} - -void wil6210_disable_irq(struct wil6210_priv *wil) -{ - wil_dbg_IRQ(wil, "%s()\n", __func__); - - wil6210_mask_irq_tx(wil); - wil6210_mask_irq_rx(wil); - wil6210_mask_irq_misc(wil); - wil6210_mask_irq_pseudo(wil); -} - -void wil6210_enable_irq(struct wil6210_priv *wil) -{ - wil_dbg_IRQ(wil, "%s()\n", __func__); - - iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_RX_ICR) + - offsetof(struct RGF_ICR, ICC)); - iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_TX_ICR) + - offsetof(struct RGF_ICR, ICC)); - iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) + - offsetof(struct RGF_ICR, ICC)); - - wil6210_unmask_irq_pseudo(wil); - wil6210_unmask_irq_tx(wil); - wil6210_unmask_irq_rx(wil); - wil6210_unmask_irq_misc(wil); -} - -static irqreturn_t wil6210_irq_rx(int irq, void *cookie) -{ - struct wil6210_priv *wil = cookie; - u32 isr = wil_ioread32_and_clear(wil->csr + - HOSTADDR(RGF_DMA_EP_RX_ICR) + - offsetof(struct RGF_ICR, ICR)); - - wil_dbg_IRQ(wil, "ISR RX 0x%08x\n", isr); - - if (!isr) { - wil_err(wil, "spurious IRQ: RX\n"); - return IRQ_NONE; - } - - wil6210_mask_irq_rx(wil); - - if (isr & BIT_DMA_EP_RX_ICR_RX_DONE) { - wil_dbg_IRQ(wil, "RX done\n"); - isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE; - wil_rx_handle(wil); - } - - if (isr) - wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr); - - wil6210_unmask_irq_rx(wil); - - return IRQ_HANDLED; -} - -static irqreturn_t wil6210_irq_tx(int irq, void *cookie) -{ - struct wil6210_priv *wil = cookie; - u32 isr = wil_ioread32_and_clear(wil->csr + - HOSTADDR(RGF_DMA_EP_TX_ICR) + - offsetof(struct RGF_ICR, ICR)); - - wil_dbg_IRQ(wil, "ISR TX 0x%08x\n", isr); - - if (!isr) { - wil_err(wil, "spurious IRQ: TX\n"); - return IRQ_NONE; - } - - wil6210_mask_irq_tx(wil); - - if (isr & BIT_DMA_EP_TX_ICR_TX_DONE) { - uint i; - wil_dbg_IRQ(wil, "TX done\n"); - isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE; - for (i = 0; i < 24; i++) { - u32 mask = BIT_DMA_EP_TX_ICR_TX_DONE_N(i); - if (isr & mask) { - isr &= ~mask; - wil_dbg_IRQ(wil, "TX done(%i)\n", i); - wil_tx_complete(wil, i); - } - } - } - - if (isr) - wil_err(wil, "un-handled TX ISR bits 0x%08x\n", isr); - - wil6210_unmask_irq_tx(wil); - - return IRQ_HANDLED; -} - -static irqreturn_t wil6210_irq_misc(int irq, void *cookie) -{ - struct wil6210_priv *wil = cookie; - u32 isr = wil_ioread32_and_clear(wil->csr + - HOSTADDR(RGF_DMA_EP_MISC_ICR) + - offsetof(struct RGF_ICR, ICR)); - - wil_dbg_IRQ(wil, "ISR MISC 0x%08x\n", isr); - - if (!isr) { - wil_err(wil, "spurious IRQ: MISC\n"); - return IRQ_NONE; - } - - wil6210_mask_irq_misc(wil); - - if (isr & ISR_MISC_FW_READY) { - wil_dbg_IRQ(wil, "IRQ: FW ready\n"); - /** - * Actual FW ready indicated by the - * WMI_FW_READY_EVENTID - */ - isr &= ~ISR_MISC_FW_READY; - } - - wil->isr_misc = isr; - - if (isr) { - return IRQ_WAKE_THREAD; - } else { - wil6210_unmask_irq_misc(wil); - return IRQ_HANDLED; - } -} - -static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie) -{ - struct wil6210_priv *wil = cookie; - u32 isr = wil->isr_misc; - - wil_dbg_IRQ(wil, "Thread ISR MISC 0x%08x\n", isr); - - if (isr & ISR_MISC_MBOX_EVT) { - wil_dbg_IRQ(wil, "MBOX event\n"); - wmi_recv_cmd(wil); - isr &= ~ISR_MISC_MBOX_EVT; - } - - if (isr) - wil_err(wil, "un-handled MISC ISR bits 0x%08x\n", isr); - - wil->isr_misc = 0; - - wil6210_unmask_irq_misc(wil); - - return IRQ_HANDLED; -} - -/** - * thread IRQ handler - */ -static irqreturn_t wil6210_thread_irq(int irq, void *cookie) -{ - struct wil6210_priv *wil = cookie; - - wil_dbg_IRQ(wil, "Thread IRQ\n"); - /* Discover real IRQ cause */ - if (wil->isr_misc) - wil6210_irq_misc_thread(irq, cookie); - - wil6210_unmask_irq_pseudo(wil); - - return IRQ_HANDLED; -} - -/* DEBUG - * There is subtle bug in hardware that causes IRQ to raise when it should be - * masked. It is quite rare and hard to debug. - * - * Catch irq issue if it happens and print all I can. - */ -static int wil6210_debug_irq_mask(struct wil6210_priv *wil, u32 pseudo_cause) -{ - if (!test_bit(wil_status_irqen, &wil->status)) { - u32 icm_rx = wil_ioread32_and_clear(wil->csr + - HOSTADDR(RGF_DMA_EP_RX_ICR) + - offsetof(struct RGF_ICR, ICM)); - u32 icr_rx = wil_ioread32_and_clear(wil->csr + - HOSTADDR(RGF_DMA_EP_RX_ICR) + - offsetof(struct RGF_ICR, ICR)); - u32 imv_rx = ioread32(wil->csr + - HOSTADDR(RGF_DMA_EP_RX_ICR) + - offsetof(struct RGF_ICR, IMV)); - u32 icm_tx = wil_ioread32_and_clear(wil->csr + - HOSTADDR(RGF_DMA_EP_TX_ICR) + - offsetof(struct RGF_ICR, ICM)); - u32 icr_tx = wil_ioread32_and_clear(wil->csr + - HOSTADDR(RGF_DMA_EP_TX_ICR) + - offsetof(struct RGF_ICR, ICR)); - u32 imv_tx = ioread32(wil->csr + - HOSTADDR(RGF_DMA_EP_TX_ICR) + - offsetof(struct RGF_ICR, IMV)); - u32 icm_misc = wil_ioread32_and_clear(wil->csr + - HOSTADDR(RGF_DMA_EP_MISC_ICR) + - offsetof(struct RGF_ICR, ICM)); - u32 icr_misc = wil_ioread32_and_clear(wil->csr + - HOSTADDR(RGF_DMA_EP_MISC_ICR) + - offsetof(struct RGF_ICR, ICR)); - u32 imv_misc = ioread32(wil->csr + - HOSTADDR(RGF_DMA_EP_MISC_ICR) + - offsetof(struct RGF_ICR, IMV)); - wil_err(wil, "IRQ when it should be masked: pseudo 0x%08x\n" - "Rx icm:icr:imv 0x%08x 0x%08x 0x%08x\n" - "Tx icm:icr:imv 0x%08x 0x%08x 0x%08x\n" - "Misc icm:icr:imv 0x%08x 0x%08x 0x%08x\n", - pseudo_cause, - icm_rx, icr_rx, imv_rx, - icm_tx, icr_tx, imv_tx, - icm_misc, icr_misc, imv_misc); - - return -EINVAL; - } - - return 0; -} - -static irqreturn_t wil6210_hardirq(int irq, void *cookie) -{ - irqreturn_t rc = IRQ_HANDLED; - struct wil6210_priv *wil = cookie; - u32 pseudo_cause = ioread32(wil->csr + HOSTADDR(RGF_DMA_PSEUDO_CAUSE)); - - /** - * pseudo_cause is Clear-On-Read, no need to ACK - */ - if ((pseudo_cause == 0) || ((pseudo_cause & 0xff) == 0xff)) - return IRQ_NONE; - - /* FIXME: IRQ mask debug */ - if (wil6210_debug_irq_mask(wil, pseudo_cause)) - return IRQ_NONE; - - wil6210_mask_irq_pseudo(wil); - - /* Discover real IRQ cause - * There are 2 possible phases for every IRQ: - * - hard IRQ handler called right here - * - threaded handler called later - * - * Hard IRQ handler reads and clears ISR. - * - * If threaded handler requested, hard IRQ handler - * returns IRQ_WAKE_THREAD and saves ISR register value - * for the threaded handler use. - * - * voting for wake thread - need at least 1 vote - */ - if ((pseudo_cause & BIT_DMA_PSEUDO_CAUSE_RX) && - (wil6210_irq_rx(irq, cookie) == IRQ_WAKE_THREAD)) - rc = IRQ_WAKE_THREAD; - - if ((pseudo_cause & BIT_DMA_PSEUDO_CAUSE_TX) && - (wil6210_irq_tx(irq, cookie) == IRQ_WAKE_THREAD)) - rc = IRQ_WAKE_THREAD; - - if ((pseudo_cause & BIT_DMA_PSEUDO_CAUSE_MISC) && - (wil6210_irq_misc(irq, cookie) == IRQ_WAKE_THREAD)) - rc = IRQ_WAKE_THREAD; - - /* if thread is requested, it will unmask IRQ */ - if (rc != IRQ_WAKE_THREAD) - wil6210_unmask_irq_pseudo(wil); - - wil_dbg_IRQ(wil, "Hard IRQ 0x%08x\n", pseudo_cause); - - return rc; -} - -static int wil6210_request_3msi(struct wil6210_priv *wil, int irq) -{ - int rc; - /* - * IRQ's are in the following order: - * - Tx - * - Rx - * - Misc - */ - - rc = request_irq(irq, wil6210_irq_tx, IRQF_SHARED, - WIL_NAME"_tx", wil); - if (rc) - return rc; - - rc = request_irq(irq + 1, wil6210_irq_rx, IRQF_SHARED, - WIL_NAME"_rx", wil); - if (rc) - goto free0; - - rc = request_threaded_irq(irq + 2, wil6210_irq_misc, - wil6210_irq_misc_thread, - IRQF_SHARED, WIL_NAME"_misc", wil); - if (rc) - goto free1; - - return 0; - /* error branch */ -free1: - free_irq(irq + 1, wil); -free0: - free_irq(irq, wil); - - return rc; -} - -int wil6210_init_irq(struct wil6210_priv *wil, int irq) -{ - int rc; - if (wil->n_msi == 3) - rc = wil6210_request_3msi(wil, irq); - else - rc = request_threaded_irq(irq, wil6210_hardirq, - wil6210_thread_irq, - wil->n_msi ? 0 : IRQF_SHARED, - WIL_NAME, wil); - if (rc) - return rc; - - wil6210_enable_irq(wil); - - return 0; -} - -void wil6210_fini_irq(struct wil6210_priv *wil, int irq) -{ - wil6210_disable_irq(wil); - free_irq(irq, wil); - if (wil->n_msi == 3) { - free_irq(irq + 1, wil); - free_irq(irq + 2, wil); - } -} diff --git a/trunk/drivers/net/wireless/ath/wil6210/main.c b/trunk/drivers/net/wireless/ath/wil6210/main.c deleted file mode 100644 index 95fcd361322b..000000000000 --- a/trunk/drivers/net/wireless/ath/wil6210/main.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Copyright (c) 2012 Qualcomm Atheros, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wil6210.h" - -/* - * Due to a hardware issue, - * one has to read/write to/from NIC in 32-bit chunks; - * regular memcpy_fromio and siblings will - * not work on 64-bit platform - it uses 64-bit transactions - * - * Force 32-bit transactions to enable NIC on 64-bit platforms - * - * To avoid byte swap on big endian host, __raw_{read|write}l - * should be used - {read|write}l would swap bytes to provide - * little endian on PCI value in host endianness. - */ -void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src, - size_t count) -{ - u32 *d = dst; - const volatile u32 __iomem *s = src; - - /* size_t is unsigned, if (count%4 != 0) it will wrap */ - for (count += 4; count > 4; count -= 4) - *d++ = __raw_readl(s++); -} - -void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, - size_t count) -{ - volatile u32 __iomem *d = dst; - const u32 *s = src; - - for (count += 4; count > 4; count -= 4) - __raw_writel(*s++, d++); -} - -static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid) -{ - uint i; - struct net_device *ndev = wil_to_ndev(wil); - struct wireless_dev *wdev = wil->wdev; - - wil_dbg(wil, "%s()\n", __func__); - - wil_link_off(wil); - clear_bit(wil_status_fwconnected, &wil->status); - - switch (wdev->sme_state) { - case CFG80211_SME_CONNECTED: - cfg80211_disconnected(ndev, WLAN_STATUS_UNSPECIFIED_FAILURE, - NULL, 0, GFP_KERNEL); - break; - case CFG80211_SME_CONNECTING: - cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0, - WLAN_STATUS_UNSPECIFIED_FAILURE, - GFP_KERNEL); - break; - default: - ; - } - - for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) - wil_vring_fini_tx(wil, i); -} - -static void wil_disconnect_worker(struct work_struct *work) -{ - struct wil6210_priv *wil = container_of(work, - struct wil6210_priv, disconnect_worker); - - _wil6210_disconnect(wil, NULL); -} - -static void wil_connect_timer_fn(ulong x) -{ - struct wil6210_priv *wil = (void *)x; - - wil_dbg(wil, "Connect timeout\n"); - - /* reschedule to thread context - disconnect won't - * run from atomic context - */ - schedule_work(&wil->disconnect_worker); -} - -int wil_priv_init(struct wil6210_priv *wil) -{ - wil_dbg(wil, "%s()\n", __func__); - - mutex_init(&wil->mutex); - mutex_init(&wil->wmi_mutex); - - init_completion(&wil->wmi_ready); - - wil->pending_connect_cid = -1; - setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil); - - INIT_WORK(&wil->wmi_connect_worker, wmi_connect_worker); - INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker); - INIT_WORK(&wil->wmi_event_worker, wmi_event_worker); - - INIT_LIST_HEAD(&wil->pending_wmi_ev); - spin_lock_init(&wil->wmi_ev_lock); - - wil->wmi_wq = create_singlethread_workqueue(WIL_NAME"_wmi"); - if (!wil->wmi_wq) - return -EAGAIN; - - wil->wmi_wq_conn = create_singlethread_workqueue(WIL_NAME"_connect"); - if (!wil->wmi_wq_conn) { - destroy_workqueue(wil->wmi_wq); - return -EAGAIN; - } - - /* make shadow copy of registers that should not change on run time */ - wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX, - sizeof(struct wil6210_mbox_ctl)); - wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx); - wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx); - - return 0; -} - -void wil6210_disconnect(struct wil6210_priv *wil, void *bssid) -{ - del_timer_sync(&wil->connect_timer); - _wil6210_disconnect(wil, bssid); -} - -void wil_priv_deinit(struct wil6210_priv *wil) -{ - cancel_work_sync(&wil->disconnect_worker); - wil6210_disconnect(wil, NULL); - wmi_event_flush(wil); - destroy_workqueue(wil->wmi_wq_conn); - destroy_workqueue(wil->wmi_wq); -} - -static void wil_target_reset(struct wil6210_priv *wil) -{ - wil_dbg(wil, "Resetting...\n"); - - /* register write */ -#define W(a, v) iowrite32(v, wil->csr + HOSTADDR(a)) - /* register set = read, OR, write */ -#define S(a, v) iowrite32(ioread32(wil->csr + HOSTADDR(a)) | v, \ - wil->csr + HOSTADDR(a)) - - /* hpal_perst_from_pad_src_n_mask */ - S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(6)); - /* car_perst_rst_src_n_mask */ - S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(7)); - - W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */ - W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */ - - msleep(100); - - W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); - W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F); - W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000170); - W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00); - - msleep(100); - - W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0); - W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0); - W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0); - W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); - - W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001); - W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080); - W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); - - msleep(2000); - - W(RGF_USER_USER_CPU_0, BIT(0)); /* user_cpu_man_de_rst */ - - msleep(2000); - - wil_dbg(wil, "Reset completed\n"); - -#undef W -#undef S -} - -void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r) -{ - le32_to_cpus(&r->base); - le16_to_cpus(&r->entry_size); - le16_to_cpus(&r->size); - le32_to_cpus(&r->tail); - le32_to_cpus(&r->head); -} - -static int wil_wait_for_fw_ready(struct wil6210_priv *wil) -{ - ulong to = msecs_to_jiffies(1000); - ulong left = wait_for_completion_timeout(&wil->wmi_ready, to); - if (0 == left) { - wil_err(wil, "Firmware not ready\n"); - return -ETIME; - } else { - wil_dbg(wil, "FW ready after %d ms\n", - jiffies_to_msecs(to-left)); - } - return 0; -} - -/* - * We reset all the structures, and we reset the UMAC. - * After calling this routine, you're expected to reload - * the firmware. - */ -int wil_reset(struct wil6210_priv *wil) -{ - int rc; - - cancel_work_sync(&wil->disconnect_worker); - wil6210_disconnect(wil, NULL); - - wmi_event_flush(wil); - - flush_workqueue(wil->wmi_wq); - flush_workqueue(wil->wmi_wq_conn); - - wil6210_disable_irq(wil); - wil->status = 0; - - /* TODO: put MAC in reset */ - wil_target_reset(wil); - - /* init after reset */ - wil->pending_connect_cid = -1; - INIT_COMPLETION(wil->wmi_ready); - - /* make shadow copy of registers that should not change on run time */ - wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX, - sizeof(struct wil6210_mbox_ctl)); - wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx); - wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx); - - /* TODO: release MAC reset */ - wil6210_enable_irq(wil); - - /* we just started MAC, wait for FW ready */ - rc = wil_wait_for_fw_ready(wil); - - return rc; -} - - -void wil_link_on(struct wil6210_priv *wil) -{ - struct net_device *ndev = wil_to_ndev(wil); - - wil_dbg(wil, "%s()\n", __func__); - - netif_carrier_on(ndev); - netif_tx_wake_all_queues(ndev); -} - -void wil_link_off(struct wil6210_priv *wil) -{ - struct net_device *ndev = wil_to_ndev(wil); - - wil_dbg(wil, "%s()\n", __func__); - - netif_tx_stop_all_queues(ndev); - netif_carrier_off(ndev); -} - -static int __wil_up(struct wil6210_priv *wil) -{ - struct net_device *ndev = wil_to_ndev(wil); - struct wireless_dev *wdev = wil->wdev; - struct ieee80211_channel *channel = wdev->preset_chandef.chan; - int rc; - int bi; - u16 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype); - - rc = wil_reset(wil); - if (rc) - return rc; - - /* FIXME Firmware works now in PBSS mode(ToDS=0, FromDS=0) */ - wmi_nettype = wil_iftype_nl2wmi(NL80211_IFTYPE_ADHOC); - switch (wdev->iftype) { - case NL80211_IFTYPE_STATION: - wil_dbg(wil, "type: STATION\n"); - bi = 0; - ndev->type = ARPHRD_ETHER; - break; - case NL80211_IFTYPE_AP: - wil_dbg(wil, "type: AP\n"); - bi = 100; - ndev->type = ARPHRD_ETHER; - break; - case NL80211_IFTYPE_P2P_CLIENT: - wil_dbg(wil, "type: P2P_CLIENT\n"); - bi = 0; - ndev->type = ARPHRD_ETHER; - break; - case NL80211_IFTYPE_P2P_GO: - wil_dbg(wil, "type: P2P_GO\n"); - bi = 100; - ndev->type = ARPHRD_ETHER; - break; - case NL80211_IFTYPE_MONITOR: - wil_dbg(wil, "type: Monitor\n"); - bi = 0; - ndev->type = ARPHRD_IEEE80211_RADIOTAP; - /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_RADIOTAP ? */ - break; - default: - return -EOPNOTSUPP; - } - - /* Apply profile in the following order: */ - /* SSID and channel for the AP */ - switch (wdev->iftype) { - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_P2P_GO: - if (wdev->ssid_len == 0) { - wil_err(wil, "SSID not set\n"); - return -EINVAL; - } - wmi_set_ssid(wil, wdev->ssid_len, wdev->ssid); - if (channel) - wmi_set_channel(wil, channel->hw_value); - break; - default: - ; - } - - /* MAC address - pre-requisite for other commands */ - wmi_set_mac_address(wil, ndev->dev_addr); - - /* Set up beaconing if required. */ - rc = wmi_set_bcon(wil, bi, wmi_nettype); - if (rc) - return rc; - - /* Rx VRING. After MAC and beacon */ - wil_rx_init(wil); - - return 0; -} - -int wil_up(struct wil6210_priv *wil) -{ - int rc; - - mutex_lock(&wil->mutex); - rc = __wil_up(wil); - mutex_unlock(&wil->mutex); - - return rc; -} - -static int __wil_down(struct wil6210_priv *wil) -{ - if (wil->scan_request) { - cfg80211_scan_done(wil->scan_request, true); - wil->scan_request = NULL; - } - - wil6210_disconnect(wil, NULL); - wil_rx_fini(wil); - - return 0; -} - -int wil_down(struct wil6210_priv *wil) -{ - int rc; - - mutex_lock(&wil->mutex); - rc = __wil_down(wil); - mutex_unlock(&wil->mutex); - - return rc; -} diff --git a/trunk/drivers/net/wireless/ath/wil6210/netdev.c b/trunk/drivers/net/wireless/ath/wil6210/netdev.c deleted file mode 100644 index 3068b5cb53a7..000000000000 --- a/trunk/drivers/net/wireless/ath/wil6210/netdev.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2012 Qualcomm Atheros, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include - -#include "wil6210.h" - -static int wil_open(struct net_device *ndev) -{ - struct wil6210_priv *wil = ndev_to_wil(ndev); - - return wil_up(wil); -} - -static int wil_stop(struct net_device *ndev) -{ - struct wil6210_priv *wil = ndev_to_wil(ndev); - - return wil_down(wil); -} - -/* - * AC to queue mapping - * - * AC_VO -> queue 3 - * AC_VI -> queue 2 - * AC_BE -> queue 1 - * AC_BK -> queue 0 - */ -static u16 wil_select_queue(struct net_device *ndev, struct sk_buff *skb) -{ - static const u16 wil_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; - struct wil6210_priv *wil = ndev_to_wil(ndev); - u16 rc; - - skb->priority = cfg80211_classify8021d(skb); - - rc = wil_1d_to_queue[skb->priority]; - - wil_dbg_TXRX(wil, "%s() %d -> %d\n", __func__, (int)skb->priority, - (int)rc); - - return rc; -} - -static const struct net_device_ops wil_netdev_ops = { - .ndo_open = wil_open, - .ndo_stop = wil_stop, - .ndo_start_xmit = wil_start_xmit, - .ndo_select_queue = wil_select_queue, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, -}; - -void *wil_if_alloc(struct device *dev, void __iomem *csr) -{ - struct net_device *ndev; - struct wireless_dev *wdev; - struct wil6210_priv *wil; - struct ieee80211_channel *ch; - int rc = 0; - - wdev = wil_cfg80211_init(dev); - if (IS_ERR(wdev)) { - dev_err(dev, "wil_cfg80211_init failed\n"); - return wdev; - } - - wil = wdev_to_wil(wdev); - wil->csr = csr; - wil->wdev = wdev; - - rc = wil_priv_init(wil); - if (rc) { - dev_err(dev, "wil_priv_init failed\n"); - goto out_wdev; - } - - wdev->iftype = NL80211_IFTYPE_STATION; /* TODO */ - /* default monitor channel */ - ch = wdev->wiphy->bands[IEEE80211_BAND_60GHZ]->channels; - cfg80211_chandef_create(&wdev->preset_chandef, ch, NL80211_CHAN_NO_HT); - - ndev = alloc_netdev_mqs(0, "wlan%d", ether_setup, WIL6210_TX_QUEUES, 1); - if (!ndev) { - dev_err(dev, "alloc_netdev_mqs failed\n"); - rc = -ENOMEM; - goto out_priv; - } - - ndev->netdev_ops = &wil_netdev_ops; - ndev->ieee80211_ptr = wdev; - SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); - wdev->netdev = ndev; - - wil_link_off(wil); - - return wil; - - out_priv: - wil_priv_deinit(wil); - - out_wdev: - wil_wdev_free(wil); - - return ERR_PTR(rc); -} - -void wil_if_free(struct wil6210_priv *wil) -{ - struct net_device *ndev = wil_to_ndev(wil); - if (!ndev) - return; - - free_netdev(ndev); - wil_priv_deinit(wil); - wil_wdev_free(wil); -} - -int wil_if_add(struct wil6210_priv *wil) -{ - struct net_device *ndev = wil_to_ndev(wil); - int rc; - - rc = register_netdev(ndev); - if (rc < 0) { - dev_err(&ndev->dev, "Failed to register netdev: %d\n", rc); - return rc; - } - - wil_link_off(wil); - - return 0; -} - -void wil_if_remove(struct wil6210_priv *wil) -{ - struct net_device *ndev = wil_to_ndev(wil); - - unregister_netdev(ndev); -} diff --git a/trunk/drivers/net/wireless/ath/wil6210/pcie_bus.c b/trunk/drivers/net/wireless/ath/wil6210/pcie_bus.c deleted file mode 100644 index 0fc83edd6bad..000000000000 --- a/trunk/drivers/net/wireless/ath/wil6210/pcie_bus.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2012 Qualcomm Atheros, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "wil6210.h" - -static int use_msi = 1; -module_param(use_msi, int, S_IRUGO); -MODULE_PARM_DESC(use_msi, - " Use MSI interrupt: " - "0 - don't, 1 - (default) - single, or 3"); - -/* Bus ops */ -static int wil_if_pcie_enable(struct wil6210_priv *wil) -{ - struct pci_dev *pdev = wil->pdev; - int rc; - - pci_set_master(pdev); - - /* - * how many MSI interrupts to request? - */ - switch (use_msi) { - case 3: - case 1: - case 0: - break; - default: - wil_err(wil, "Invalid use_msi=%d, default to 1\n", - use_msi); - use_msi = 1; - } - wil->n_msi = use_msi; - if (wil->n_msi) { - wil_dbg(wil, "Setup %d MSI interrupts\n", use_msi); - rc = pci_enable_msi_block(pdev, wil->n_msi); - if (rc && (wil->n_msi == 3)) { - wil_err(wil, "3 MSI mode failed, try 1 MSI\n"); - wil->n_msi = 1; - rc = pci_enable_msi_block(pdev, wil->n_msi); - } - if (rc) { - wil_err(wil, "pci_enable_msi failed, use INTx\n"); - wil->n_msi = 0; - } - } else { - wil_dbg(wil, "MSI interrupts disabled, use INTx\n"); - } - - rc = wil6210_init_irq(wil, pdev->irq); - if (rc) - goto stop_master; - - /* need reset here to obtain MAC */ - rc = wil_reset(wil); - if (rc) - goto release_irq; - - return 0; - - release_irq: - wil6210_fini_irq(wil, pdev->irq); - /* safe to call if no MSI */ - pci_disable_msi(pdev); - stop_master: - pci_clear_master(pdev); - return rc; -} - -static int wil_if_pcie_disable(struct wil6210_priv *wil) -{ - struct pci_dev *pdev = wil->pdev; - - pci_clear_master(pdev); - /* disable and release IRQ */ - wil6210_fini_irq(wil, pdev->irq); - /* safe to call if no MSI */ - pci_disable_msi(pdev); - /* TODO: disable HW */ - - return 0; -} - -static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ - struct wil6210_priv *wil; - struct device *dev = &pdev->dev; - void __iomem *csr; - int rc; - - /* check HW */ - dev_info(&pdev->dev, WIL_NAME " device found [%04x:%04x] (rev %x)\n", - (int)pdev->vendor, (int)pdev->device, (int)pdev->revision); - - if (pci_resource_len(pdev, 0) != WIL6210_MEM_SIZE) { - dev_err(&pdev->dev, "Not " WIL_NAME "? " - "BAR0 size is %lu while expecting %lu\n", - (ulong)pci_resource_len(pdev, 0), WIL6210_MEM_SIZE); - return -ENODEV; - } - - rc = pci_enable_device(pdev); - if (rc) { - dev_err(&pdev->dev, "pci_enable_device failed\n"); - return -ENODEV; - } - /* rollback to err_disable_pdev */ - - rc = pci_request_region(pdev, 0, WIL_NAME); - if (rc) { - dev_err(&pdev->dev, "pci_request_region failed\n"); - goto err_disable_pdev; - } - /* rollback to err_release_reg */ - - csr = pci_ioremap_bar(pdev, 0); - if (!csr) { - dev_err(&pdev->dev, "pci_ioremap_bar failed\n"); - rc = -ENODEV; - goto err_release_reg; - } - /* rollback to err_iounmap */ - dev_info(&pdev->dev, "CSR at %pR -> %p\n", &pdev->resource[0], csr); - - wil = wil_if_alloc(dev, csr); - if (IS_ERR(wil)) { - rc = (int)PTR_ERR(wil); - dev_err(dev, "wil_if_alloc failed: %d\n", rc); - goto err_iounmap; - } - /* rollback to if_free */ - - pci_set_drvdata(pdev, wil); - wil->pdev = pdev; - - /* FW should raise IRQ when ready */ - rc = wil_if_pcie_enable(wil); - if (rc) { - wil_err(wil, "Enable device failed\n"); - goto if_free; - } - /* rollback to bus_disable */ - - rc = wil_if_add(wil); - if (rc) { - wil_err(wil, "wil_if_add failed: %d\n", rc); - goto bus_disable; - } - - wil6210_debugfs_init(wil); - - /* check FW is alive */ - wmi_echo(wil); - - return 0; - - bus_disable: - wil_if_pcie_disable(wil); - if_free: - wil_if_free(wil); - err_iounmap: - pci_iounmap(pdev, csr); - err_release_reg: - pci_release_region(pdev, 0); - err_disable_pdev: - pci_disable_device(pdev); - - return rc; -} - -static void wil_pcie_remove(struct pci_dev *pdev) -{ - struct wil6210_priv *wil = pci_get_drvdata(pdev); - - wil6210_debugfs_remove(wil); - wil_if_pcie_disable(wil); - wil_if_remove(wil); - wil_if_free(wil); - pci_iounmap(pdev, wil->csr); - pci_release_region(pdev, 0); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); -} - -static DEFINE_PCI_DEVICE_TABLE(wil6210_pcie_ids) = { - { PCI_DEVICE(0x1ae9, 0x0301) }, - { /* end: all zeroes */ }, -}; -MODULE_DEVICE_TABLE(pci, wil6210_pcie_ids); - -static struct pci_driver wil6210_driver = { - .probe = wil_pcie_probe, - .remove = wil_pcie_remove, - .id_table = wil6210_pcie_ids, - .name = WIL_NAME, -}; - -module_pci_driver(wil6210_driver); - -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_AUTHOR("Qualcomm Atheros "); -MODULE_DESCRIPTION("Driver for 60g WiFi WIL6210 card"); diff --git a/trunk/drivers/net/wireless/ath/wil6210/txrx.c b/trunk/drivers/net/wireless/ath/wil6210/txrx.c deleted file mode 100644 index f29c294413cf..000000000000 --- a/trunk/drivers/net/wireless/ath/wil6210/txrx.c +++ /dev/null @@ -1,871 +0,0 @@ -/* - * Copyright (c) 2012 Qualcomm Atheros, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "wil6210.h" -#include "wmi.h" -#include "txrx.h" - -static bool rtap_include_phy_info; -module_param(rtap_include_phy_info, bool, S_IRUGO); -MODULE_PARM_DESC(rtap_include_phy_info, - " Include PHY info in the radiotap header, default - no"); - -static inline int wil_vring_is_empty(struct vring *vring) -{ - return vring->swhead == vring->swtail; -} - -static inline u32 wil_vring_next_tail(struct vring *vring) -{ - return (vring->swtail + 1) % vring->size; -} - -static inline void wil_vring_advance_head(struct vring *vring, int n) -{ - vring->swhead = (vring->swhead + n) % vring->size; -} - -static inline int wil_vring_is_full(struct vring *vring) -{ - return wil_vring_next_tail(vring) == vring->swhead; -} -/* - * Available space in Tx Vring - */ -static inline int wil_vring_avail_tx(struct vring *vring) -{ - u32 swhead = vring->swhead; - u32 swtail = vring->swtail; - int used = (vring->size + swhead - swtail) % vring->size; - - return vring->size - used - 1; -} - -static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring) -{ - struct device *dev = wil_to_dev(wil); - size_t sz = vring->size * sizeof(vring->va[0]); - uint i; - - BUILD_BUG_ON(sizeof(vring->va[0]) != 32); - - vring->swhead = 0; - vring->swtail = 0; - vring->ctx = kzalloc(vring->size * sizeof(vring->ctx[0]), GFP_KERNEL); - if (!vring->ctx) { - wil_err(wil, "vring_alloc [%d] failed to alloc ctx mem\n", - vring->size); - vring->va = NULL; - return -ENOMEM; - } - /* - * vring->va should be aligned on its size rounded up to power of 2 - * This is granted by the dma_alloc_coherent - */ - vring->va = dma_alloc_coherent(dev, sz, &vring->pa, GFP_KERNEL); - if (!vring->va) { - wil_err(wil, "vring_alloc [%d] failed to alloc DMA mem\n", - vring->size); - kfree(vring->ctx); - vring->ctx = NULL; - return -ENOMEM; - } - /* initially, all descriptors are SW owned - * For Tx and Rx, ownership bit is at the same location, thus - * we can use any - */ - for (i = 0; i < vring->size; i++) { - volatile struct vring_tx_desc *d = &(vring->va[i].tx); - d->dma.status = TX_DMA_STATUS_DU; - } - - wil_dbg(wil, "vring[%d] 0x%p:0x%016llx 0x%p\n", vring->size, - vring->va, (unsigned long long)vring->pa, vring->ctx); - - return 0; -} - -static void wil_vring_free(struct wil6210_priv *wil, struct vring *vring, - int tx) -{ - struct device *dev = wil_to_dev(wil); - size_t sz = vring->size * sizeof(vring->va[0]); - - while (!wil_vring_is_empty(vring)) { - if (tx) { - volatile struct vring_tx_desc *d = - &vring->va[vring->swtail].tx; - dma_addr_t pa = d->dma.addr_low | - ((u64)d->dma.addr_high << 32); - struct sk_buff *skb = vring->ctx[vring->swtail]; - if (skb) { - dma_unmap_single(dev, pa, d->dma.length, - DMA_TO_DEVICE); - dev_kfree_skb_any(skb); - vring->ctx[vring->swtail] = NULL; - } else { - dma_unmap_page(dev, pa, d->dma.length, - DMA_TO_DEVICE); - } - vring->swtail = wil_vring_next_tail(vring); - } else { /* rx */ - volatile struct vring_rx_desc *d = - &vring->va[vring->swtail].rx; - dma_addr_t pa = d->dma.addr_low | - ((u64)d->dma.addr_high << 32); - struct sk_buff *skb = vring->ctx[vring->swhead]; - dma_unmap_single(dev, pa, d->dma.length, - DMA_FROM_DEVICE); - kfree_skb(skb); - wil_vring_advance_head(vring, 1); - } - } - dma_free_coherent(dev, sz, (void *)vring->va, vring->pa); - kfree(vring->ctx); - vring->pa = 0; - vring->va = NULL; - vring->ctx = NULL; -} - -/** - * Allocate one skb for Rx VRING - * - * Safe to call from IRQ - */ -static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring, - u32 i, int headroom) -{ - struct device *dev = wil_to_dev(wil); - unsigned int sz = RX_BUF_LEN; - volatile struct vring_rx_desc *d = &(vring->va[i].rx); - dma_addr_t pa; - - /* TODO align */ - struct sk_buff *skb = dev_alloc_skb(sz + headroom); - if (unlikely(!skb)) - return -ENOMEM; - - skb_reserve(skb, headroom); - skb_put(skb, sz); - - pa = dma_map_single(dev, skb->data, skb->len, DMA_FROM_DEVICE); - if (unlikely(dma_mapping_error(dev, pa))) { - kfree_skb(skb); - return -ENOMEM; - } - - d->dma.d0 = BIT(9) | RX_DMA_D0_CMD_DMA_IT; - d->dma.addr_low = lower_32_bits(pa); - d->dma.addr_high = (u16)upper_32_bits(pa); - /* ip_length don't care */ - /* b11 don't care */ - /* error don't care */ - d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */ - d->dma.length = sz; - vring->ctx[i] = skb; - - return 0; -} - -/** - * Adds radiotap header - * - * Any error indicated as "Bad FCS" - * - * Vendor data for 04:ce:14-1 (Wilocity-1) consists of: - * - Rx descriptor: 32 bytes - * - Phy info - */ -static void wil_rx_add_radiotap_header(struct wil6210_priv *wil, - struct sk_buff *skb, - volatile struct vring_rx_desc *d) -{ - struct wireless_dev *wdev = wil->wdev; - struct wil6210_rtap { - struct ieee80211_radiotap_header rthdr; - /* fields should be in the order of bits in rthdr.it_present */ - /* flags */ - u8 flags; - /* channel */ - __le16 chnl_freq __aligned(2); - __le16 chnl_flags; - /* MCS */ - u8 mcs_present; - u8 mcs_flags; - u8 mcs_index; - } __packed; - struct wil6210_rtap_vendor { - struct wil6210_rtap rtap; - /* vendor */ - u8 vendor_oui[3] __aligned(2); - u8 vendor_ns; - __le16 vendor_skip; - u8 vendor_data[0]; - } __packed; - struct wil6210_rtap_vendor *rtap_vendor; - int rtap_len = sizeof(struct wil6210_rtap); - int phy_length = 0; /* phy info header size, bytes */ - static char phy_data[128]; - struct ieee80211_channel *ch = wdev->preset_chandef.chan; - - if (rtap_include_phy_info) { - rtap_len = sizeof(*rtap_vendor) + sizeof(*d); - /* calculate additional length */ - if (d->dma.status & RX_DMA_STATUS_PHY_INFO) { - /** - * PHY info starts from 8-byte boundary - * there are 8-byte lines, last line may be partially - * written (HW bug), thus FW configures for last line - * to be excessive. Driver skips this last line. - */ - int len = min_t(int, 8 + sizeof(phy_data), - wil_rxdesc_phy_length(d)); - if (len > 8) { - void *p = skb_tail_pointer(skb); - void *pa = PTR_ALIGN(p, 8); - if (skb_tailroom(skb) >= len + (pa - p)) { - phy_length = len - 8; - memcpy(phy_data, pa, phy_length); - } - } - } - rtap_len += phy_length; - } - - if (skb_headroom(skb) < rtap_len && - pskb_expand_head(skb, rtap_len, 0, GFP_ATOMIC)) { - wil_err(wil, "Unable to expand headrom to %d\n", rtap_len); - return; - } - - rtap_vendor = (void *)skb_push(skb, rtap_len); - memset(rtap_vendor, 0, rtap_len); - - rtap_vendor->rtap.rthdr.it_version = PKTHDR_RADIOTAP_VERSION; - rtap_vendor->rtap.rthdr.it_len = cpu_to_le16(rtap_len); - rtap_vendor->rtap.rthdr.it_present = cpu_to_le32( - (1 << IEEE80211_RADIOTAP_FLAGS) | - (1 << IEEE80211_RADIOTAP_CHANNEL) | - (1 << IEEE80211_RADIOTAP_MCS)); - if (d->dma.status & RX_DMA_STATUS_ERROR) - rtap_vendor->rtap.flags |= IEEE80211_RADIOTAP_F_BADFCS; - - rtap_vendor->rtap.chnl_freq = cpu_to_le16(ch ? ch->center_freq : 58320); - rtap_vendor->rtap.chnl_flags = cpu_to_le16(0); - - rtap_vendor->rtap.mcs_present = IEEE80211_RADIOTAP_MCS_HAVE_MCS; - rtap_vendor->rtap.mcs_flags = 0; - rtap_vendor->rtap.mcs_index = wil_rxdesc_mcs(d); - - if (rtap_include_phy_info) { - rtap_vendor->rtap.rthdr.it_present |= cpu_to_le32(1 << - IEEE80211_RADIOTAP_VENDOR_NAMESPACE); - /* OUI for Wilocity 04:ce:14 */ - rtap_vendor->vendor_oui[0] = 0x04; - rtap_vendor->vendor_oui[1] = 0xce; - rtap_vendor->vendor_oui[2] = 0x14; - rtap_vendor->vendor_ns = 1; - /* Rx descriptor + PHY data */ - rtap_vendor->vendor_skip = cpu_to_le16(sizeof(*d) + - phy_length); - memcpy(rtap_vendor->vendor_data, (void *)d, sizeof(*d)); - memcpy(rtap_vendor->vendor_data + sizeof(*d), phy_data, - phy_length); - } -} - -/* - * Fast swap in place between 2 registers - */ -static void wil_swap_u16(u16 *a, u16 *b) -{ - *a ^= *b; - *b ^= *a; - *a ^= *b; -} - -static void wil_swap_ethaddr(void *data) -{ - struct ethhdr *eth = data; - u16 *s = (u16 *)eth->h_source; - u16 *d = (u16 *)eth->h_dest; - - wil_swap_u16(s++, d++); - wil_swap_u16(s++, d++); - wil_swap_u16(s, d); -} - -/** - * reap 1 frame from @swhead - * - * Safe to call from IRQ - */ -static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, - struct vring *vring) -{ - struct device *dev = wil_to_dev(wil); - struct net_device *ndev = wil_to_ndev(wil); - volatile struct vring_rx_desc *d; - struct sk_buff *skb; - dma_addr_t pa; - unsigned int sz = RX_BUF_LEN; - u8 ftype; - u8 ds_bits; - - if (wil_vring_is_empty(vring)) - return NULL; - - d = &(vring->va[vring->swhead].rx); - if (!(d->dma.status & RX_DMA_STATUS_DU)) { - /* it is not error, we just reached end of Rx done area */ - return NULL; - } - - pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32); - skb = vring->ctx[vring->swhead]; - dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE); - skb_trim(skb, d->dma.length); - - wil->stats.last_mcs_rx = wil_rxdesc_mcs(d); - - /* use radiotap header only if required */ - if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) - wil_rx_add_radiotap_header(wil, skb, d); - - wil_dbg_TXRX(wil, "Rx[%3d] : %d bytes\n", vring->swhead, d->dma.length); - wil_hex_dump_TXRX("Rx ", DUMP_PREFIX_NONE, 32, 4, - (const void *)d, sizeof(*d), false); - - wil_vring_advance_head(vring, 1); - - /* no extra checks if in sniffer mode */ - if (ndev->type != ARPHRD_ETHER) - return skb; - /* - * Non-data frames may be delivered through Rx DMA channel (ex: BAR) - * Driver should recognize it by frame type, that is found - * in Rx descriptor. If type is not data, it is 802.11 frame as is - */ - ftype = wil_rxdesc_ftype(d) << 2; - if (ftype != IEEE80211_FTYPE_DATA) { - wil_dbg_TXRX(wil, "Non-data frame ftype 0x%08x\n", ftype); - /* TODO: process it */ - kfree_skb(skb); - return NULL; - } - - if (skb->len < ETH_HLEN) { - wil_err(wil, "Short frame, len = %d\n", skb->len); - /* TODO: process it (i.e. BAR) */ - kfree_skb(skb); - return NULL; - } - - ds_bits = wil_rxdesc_ds_bits(d); - if (ds_bits == 1) { - /* - * HW bug - in ToDS mode, i.e. Rx on AP side, - * addresses get swapped - */ - wil_swap_ethaddr(skb->data); - } - - return skb; -} - -/** - * allocate and fill up to @count buffers in rx ring - * buffers posted at @swtail - */ -static int wil_rx_refill(struct wil6210_priv *wil, int count) -{ - struct net_device *ndev = wil_to_ndev(wil); - struct vring *v = &wil->vring_rx; - u32 next_tail; - int rc = 0; - int headroom = ndev->type == ARPHRD_IEEE80211_RADIOTAP ? - WIL6210_RTAP_SIZE : 0; - - for (; next_tail = wil_vring_next_tail(v), - (next_tail != v->swhead) && (count-- > 0); - v->swtail = next_tail) { - rc = wil_vring_alloc_skb(wil, v, v->swtail, headroom); - if (rc) { - wil_err(wil, "Error %d in wil_rx_refill[%d]\n", - rc, v->swtail); - break; - } - } - iowrite32(v->swtail, wil->csr + HOSTADDR(v->hwtail)); - - return rc; -} - -/* - * Pass Rx packet to the netif. Update statistics. - */ -static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) -{ - int rc; - unsigned int len = skb->len; - - if (in_interrupt()) - rc = netif_rx(skb); - else - rc = netif_rx_ni(skb); - - if (likely(rc == NET_RX_SUCCESS)) { - ndev->stats.rx_packets++; - ndev->stats.rx_bytes += len; - - } else { - ndev->stats.rx_dropped++; - } -} - -/** - * Proceed all completed skb's from Rx VRING - * - * Safe to call from IRQ - */ -void wil_rx_handle(struct wil6210_priv *wil) -{ - struct net_device *ndev = wil_to_ndev(wil); - struct vring *v = &wil->vring_rx; - struct sk_buff *skb; - - if (!v->va) { - wil_err(wil, "Rx IRQ while Rx not yet initialized\n"); - return; - } - wil_dbg_TXRX(wil, "%s()\n", __func__); - while (NULL != (skb = wil_vring_reap_rx(wil, v))) { - wil_hex_dump_TXRX("Rx ", DUMP_PREFIX_OFFSET, 16, 1, - skb->data, skb_headlen(skb), false); - - skb_orphan(skb); - - if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) { - skb->dev = ndev; - skb_reset_mac_header(skb); - skb->ip_summed = CHECKSUM_UNNECESSARY; - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = htons(ETH_P_802_2); - - } else { - skb->protocol = eth_type_trans(skb, ndev); - } - - wil_netif_rx_any(skb, ndev); - } - wil_rx_refill(wil, v->size); -} - -int wil_rx_init(struct wil6210_priv *wil) -{ - struct net_device *ndev = wil_to_ndev(wil); - struct wireless_dev *wdev = wil->wdev; - struct vring *vring = &wil->vring_rx; - int rc; - struct wmi_cfg_rx_chain_cmd cmd = { - .action = WMI_RX_CHAIN_ADD, - .rx_sw_ring = { - .max_mpdu_size = cpu_to_le16(RX_BUF_LEN), - }, - .mid = 0, /* TODO - what is it? */ - .decap_trans_type = WMI_DECAP_TYPE_802_3, - }; - struct { - struct wil6210_mbox_hdr_wmi wmi; - struct wmi_cfg_rx_chain_done_event evt; - } __packed evt; - - vring->size = WIL6210_RX_RING_SIZE; - rc = wil_vring_alloc(wil, vring); - if (rc) - return rc; - - cmd.rx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); - cmd.rx_sw_ring.ring_size = cpu_to_le16(vring->size); - if (wdev->iftype == NL80211_IFTYPE_MONITOR) { - struct ieee80211_channel *ch = wdev->preset_chandef.chan; - - cmd.sniffer_cfg.mode = cpu_to_le32(WMI_SNIFFER_ON); - if (ch) - cmd.sniffer_cfg.channel = ch->hw_value - 1; - cmd.sniffer_cfg.phy_info_mode = - cpu_to_le32(ndev->type == ARPHRD_IEEE80211_RADIOTAP); - cmd.sniffer_cfg.phy_support = - cpu_to_le32((wil->monitor_flags & MONITOR_FLAG_CONTROL) - ? WMI_SNIFFER_CP : WMI_SNIFFER_DP); - } - /* typical time for secure PCP is 840ms */ - rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd), - WMI_CFG_RX_CHAIN_DONE_EVENTID, &evt, sizeof(evt), 2000); - if (rc) - goto err_free; - - vring->hwtail = le32_to_cpu(evt.evt.rx_ring_tail_ptr); - - wil_dbg(wil, "Rx init: status %d tail 0x%08x\n", - le32_to_cpu(evt.evt.status), vring->hwtail); - - rc = wil_rx_refill(wil, vring->size); - if (rc) - goto err_free; - - return 0; - err_free: - wil_vring_free(wil, vring, 0); - - return rc; -} - -void wil_rx_fini(struct wil6210_priv *wil) -{ - struct vring *vring = &wil->vring_rx; - - if (vring->va) { - int rc; - struct wmi_cfg_rx_chain_cmd cmd = { - .action = cpu_to_le32(WMI_RX_CHAIN_DEL), - .rx_sw_ring = { - .max_mpdu_size = cpu_to_le16(RX_BUF_LEN), - }, - }; - struct { - struct wil6210_mbox_hdr_wmi wmi; - struct wmi_cfg_rx_chain_done_event cfg; - } __packed wmi_rx_cfg_reply; - - rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd), - WMI_CFG_RX_CHAIN_DONE_EVENTID, - &wmi_rx_cfg_reply, sizeof(wmi_rx_cfg_reply), - 100); - wil_vring_free(wil, vring, 0); - } -} - -int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, - int cid, int tid) -{ - int rc; - struct wmi_vring_cfg_cmd cmd = { - .action = cpu_to_le32(WMI_VRING_CMD_ADD), - .vring_cfg = { - .tx_sw_ring = { - .max_mpdu_size = cpu_to_le16(TX_BUF_LEN), - }, - .ringid = id, - .cidxtid = (cid & 0xf) | ((tid & 0xf) << 4), - .encap_trans_type = WMI_VRING_ENC_TYPE_802_3, - .mac_ctrl = 0, - .to_resolution = 0, - .agg_max_wsize = 16, - .schd_params = { - .priority = cpu_to_le16(0), - .timeslot_us = cpu_to_le16(0xfff), - }, - }, - }; - struct { - struct wil6210_mbox_hdr_wmi wmi; - struct wmi_vring_cfg_done_event cmd; - } __packed reply; - struct vring *vring = &wil->vring_tx[id]; - - if (vring->va) { - wil_err(wil, "Tx ring [%d] already allocated\n", id); - rc = -EINVAL; - goto out; - } - - vring->size = size; - rc = wil_vring_alloc(wil, vring); - if (rc) - goto out; - - cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); - cmd.vring_cfg.tx_sw_ring.ring_size = cpu_to_le16(vring->size); - - rc = wmi_call(wil, WMI_VRING_CFG_CMDID, &cmd, sizeof(cmd), - WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100); - if (rc) - goto out_free; - - if (reply.cmd.status != WMI_VRING_CFG_SUCCESS) { - wil_err(wil, "Tx config failed, status 0x%02x\n", - reply.cmd.status); - goto out_free; - } - vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr); - - return 0; - out_free: - wil_vring_free(wil, vring, 1); - out: - - return rc; -} - -void wil_vring_fini_tx(struct wil6210_priv *wil, int id) -{ - struct vring *vring = &wil->vring_tx[id]; - - if (!vring->va) - return; - - wil_vring_free(wil, vring, 1); -} - -static struct vring *wil_find_tx_vring(struct wil6210_priv *wil, - struct sk_buff *skb) -{ - struct vring *v = &wil->vring_tx[0]; - - if (v->va) - return v; - - return NULL; -} - -static int wil_tx_desc_map(volatile struct vring_tx_desc *d, - dma_addr_t pa, u32 len) -{ - d->dma.addr_low = lower_32_bits(pa); - d->dma.addr_high = (u16)upper_32_bits(pa); - d->dma.ip_length = 0; - /* 0..6: mac_length; 7:ip_version 0-IP6 1-IP4*/ - d->dma.b11 = 0/*14 | BIT(7)*/; - d->dma.error = 0; - d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */ - d->dma.length = len; - d->dma.d0 = 0; - d->mac.d[0] = 0; - d->mac.d[1] = 0; - d->mac.d[2] = 0; - d->mac.ucode_cmd = 0; - /* use dst index 0 */ - d->mac.d[1] |= BIT(MAC_CFG_DESC_TX_1_DST_INDEX_EN_POS) | - (0 << MAC_CFG_DESC_TX_1_DST_INDEX_POS); - /* translation type: 0 - bypass; 1 - 802.3; 2 - native wifi */ - d->mac.d[2] = BIT(MAC_CFG_DESC_TX_2_SNAP_HDR_INSERTION_EN_POS) | - (1 << MAC_CFG_DESC_TX_2_L2_TRANSLATION_TYPE_POS); - - return 0; -} - -static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, - struct sk_buff *skb) -{ - struct device *dev = wil_to_dev(wil); - volatile struct vring_tx_desc *d; - u32 swhead = vring->swhead; - int avail = wil_vring_avail_tx(vring); - int nr_frags = skb_shinfo(skb)->nr_frags; - uint f; - int vring_index = vring - wil->vring_tx; - uint i = swhead; - dma_addr_t pa; - - wil_dbg_TXRX(wil, "%s()\n", __func__); - - if (avail < vring->size/8) - netif_tx_stop_all_queues(wil_to_ndev(wil)); - if (avail < 1 + nr_frags) { - wil_err(wil, "Tx ring full. No space for %d fragments\n", - 1 + nr_frags); - return -ENOMEM; - } - d = &(vring->va[i].tx); - - /* FIXME FW can accept only unicast frames for the peer */ - memcpy(skb->data, wil->dst_addr[vring_index], ETH_ALEN); - - pa = dma_map_single(dev, skb->data, - skb_headlen(skb), DMA_TO_DEVICE); - - wil_dbg_TXRX(wil, "Tx skb %d bytes %p -> %#08llx\n", skb_headlen(skb), - skb->data, (unsigned long long)pa); - wil_hex_dump_TXRX("Tx ", DUMP_PREFIX_OFFSET, 16, 1, - skb->data, skb_headlen(skb), false); - - if (unlikely(dma_mapping_error(dev, pa))) - return -EINVAL; - /* 1-st segment */ - wil_tx_desc_map(d, pa, skb_headlen(skb)); - d->mac.d[2] |= ((nr_frags + 1) << - MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS); - /* middle segments */ - for (f = 0; f < nr_frags; f++) { - const struct skb_frag_struct *frag = - &skb_shinfo(skb)->frags[f]; - int len = skb_frag_size(frag); - i = (swhead + f + 1) % vring->size; - d = &(vring->va[i].tx); - pa = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag), - DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(dev, pa))) - goto dma_error; - wil_tx_desc_map(d, pa, len); - vring->ctx[i] = NULL; - } - /* for the last seg only */ - d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_EOP_POS); - d->dma.d0 |= BIT(9); /* BUG: undocumented bit */ - d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS); - d->dma.d0 |= (vring_index << DMA_CFG_DESC_TX_0_QID_POS); - - wil_hex_dump_TXRX("Tx ", DUMP_PREFIX_NONE, 32, 4, - (const void *)d, sizeof(*d), false); - - /* advance swhead */ - wil_vring_advance_head(vring, nr_frags + 1); - wil_dbg_TXRX(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead); - iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail)); - /* hold reference to skb - * to prevent skb release before accounting - * in case of immediate "tx done" - */ - vring->ctx[i] = skb_get(skb); - - return 0; - dma_error: - /* unmap what we have mapped */ - /* Note: increment @f to operate with positive index */ - for (f++; f > 0; f--) { - i = (swhead + f) % vring->size; - d = &(vring->va[i].tx); - d->dma.status = TX_DMA_STATUS_DU; - pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32); - if (vring->ctx[i]) - dma_unmap_single(dev, pa, d->dma.length, DMA_TO_DEVICE); - else - dma_unmap_page(dev, pa, d->dma.length, DMA_TO_DEVICE); - } - - return -EINVAL; -} - - -netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) -{ - struct wil6210_priv *wil = ndev_to_wil(ndev); - struct vring *vring; - int rc; - - wil_dbg_TXRX(wil, "%s()\n", __func__); - if (!test_bit(wil_status_fwready, &wil->status)) { - wil_err(wil, "FW not ready\n"); - goto drop; - } - if (!test_bit(wil_status_fwconnected, &wil->status)) { - wil_err(wil, "FW not connected\n"); - goto drop; - } - if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) { - wil_err(wil, "Xmit in monitor mode not supported\n"); - goto drop; - } - if (skb->protocol == cpu_to_be16(ETH_P_PAE)) { - rc = wmi_tx_eapol(wil, skb); - } else { - /* find vring */ - vring = wil_find_tx_vring(wil, skb); - if (!vring) { - wil_err(wil, "No Tx VRING available\n"); - goto drop; - } - /* set up vring entry */ - rc = wil_tx_vring(wil, vring, skb); - } - switch (rc) { - case 0: - ndev->stats.tx_packets++; - ndev->stats.tx_bytes += skb->len; - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - case -ENOMEM: - return NETDEV_TX_BUSY; - default: - ; /* goto drop; */ - break; - } - drop: - netif_tx_stop_all_queues(ndev); - ndev->stats.tx_dropped++; - dev_kfree_skb_any(skb); - - return NET_XMIT_DROP; -} - -/** - * Clean up transmitted skb's from the Tx VRING - * - * Safe to call from IRQ - */ -void wil_tx_complete(struct wil6210_priv *wil, int ringid) -{ - struct device *dev = wil_to_dev(wil); - struct vring *vring = &wil->vring_tx[ringid]; - - if (!vring->va) { - wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid); - return; - } - - wil_dbg_TXRX(wil, "%s(%d)\n", __func__, ringid); - - while (!wil_vring_is_empty(vring)) { - volatile struct vring_tx_desc *d = &vring->va[vring->swtail].tx; - dma_addr_t pa; - struct sk_buff *skb; - if (!(d->dma.status & TX_DMA_STATUS_DU)) - break; - - wil_dbg_TXRX(wil, - "Tx[%3d] : %d bytes, status 0x%02x err 0x%02x\n", - vring->swtail, d->dma.length, d->dma.status, - d->dma.error); - wil_hex_dump_TXRX("TxC ", DUMP_PREFIX_NONE, 32, 4, - (const void *)d, sizeof(*d), false); - - pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32); - skb = vring->ctx[vring->swtail]; - if (skb) { - dma_unmap_single(dev, pa, d->dma.length, DMA_TO_DEVICE); - dev_kfree_skb_any(skb); - vring->ctx[vring->swtail] = NULL; - } else { - dma_unmap_page(dev, pa, d->dma.length, DMA_TO_DEVICE); - } - d->dma.addr_low = 0; - d->dma.addr_high = 0; - d->dma.length = 0; - d->dma.status = TX_DMA_STATUS_DU; - vring->swtail = wil_vring_next_tail(vring); - } - if (wil_vring_avail_tx(vring) > vring->size/4) - netif_tx_wake_all_queues(wil_to_ndev(wil)); -} diff --git a/trunk/drivers/net/wireless/ath/wil6210/txrx.h b/trunk/drivers/net/wireless/ath/wil6210/txrx.h deleted file mode 100644 index 45a61f597c5c..000000000000 --- a/trunk/drivers/net/wireless/ath/wil6210/txrx.h +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright (c) 2012 Qualcomm Atheros, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef WIL6210_TXRX_H -#define WIL6210_TXRX_H - -#define BUF_SW_OWNED (1) -#define BUF_HW_OWNED (0) - -/* size of max. Rx packet */ -#define RX_BUF_LEN (2048) -#define TX_BUF_LEN (2048) -/* how many bytes to reserve for rtap header? */ -#define WIL6210_RTAP_SIZE (128) - -/* Tx/Rx path */ -/* - * Tx descriptor - MAC part - * [dword 0] - * bit 0.. 9 : lifetime_expiry_value:10 - * bit 10 : interrup_en:1 - * bit 11 : status_en:1 - * bit 12..13 : txss_override:2 - * bit 14 : timestamp_insertion:1 - * bit 15 : duration_preserve:1 - * bit 16..21 : reserved0:6 - * bit 22..26 : mcs_index:5 - * bit 27 : mcs_en:1 - * bit 28..29 : reserved1:2 - * bit 30 : reserved2:1 - * bit 31 : sn_preserved:1 - * [dword 1] - * bit 0.. 3 : pkt_mode:4 - * bit 4 : pkt_mode_en:1 - * bit 5.. 7 : reserved0:3 - * bit 8..13 : reserved1:6 - * bit 14 : reserved2:1 - * bit 15 : ack_policy_en:1 - * bit 16..19 : dst_index:4 - * bit 20 : dst_index_en:1 - * bit 21..22 : ack_policy:2 - * bit 23 : lifetime_en:1 - * bit 24..30 : max_retry:7 - * bit 31 : max_retry_en:1 - * [dword 2] - * bit 0.. 7 : num_of_descriptors:8 - * bit 8..17 : reserved:10 - * bit 18..19 : l2_translation_type:2 - * bit 20 : snap_hdr_insertion_en:1 - * bit 21 : vlan_removal_en:1 - * bit 22..31 : reserved0:10 - * [dword 3] - * bit 0.. 31: ucode_cmd:32 - */ -struct vring_tx_mac { - u32 d[3]; - u32 ucode_cmd; -} __packed; - -/* TX MAC Dword 0 */ -#define MAC_CFG_DESC_TX_0_LIFETIME_EXPIRY_VALUE_POS 0 -#define MAC_CFG_DESC_TX_0_LIFETIME_EXPIRY_VALUE_LEN 10 -#define MAC_CFG_DESC_TX_0_LIFETIME_EXPIRY_VALUE_MSK 0x3FF - -#define MAC_CFG_DESC_TX_0_INTERRUP_EN_POS 10 -#define MAC_CFG_DESC_TX_0_INTERRUP_EN_LEN 1 -#define MAC_CFG_DESC_TX_0_INTERRUP_EN_MSK 0x400 - -#define MAC_CFG_DESC_TX_0_STATUS_EN_POS 11 -#define MAC_CFG_DESC_TX_0_STATUS_EN_LEN 1 -#define MAC_CFG_DESC_TX_0_STATUS_EN_MSK 0x800 - -#define MAC_CFG_DESC_TX_0_TXSS_OVERRIDE_POS 12 -#define MAC_CFG_DESC_TX_0_TXSS_OVERRIDE_LEN 2 -#define MAC_CFG_DESC_TX_0_TXSS_OVERRIDE_MSK 0x3000 - -#define MAC_CFG_DESC_TX_0_TIMESTAMP_INSERTION_POS 14 -#define MAC_CFG_DESC_TX_0_TIMESTAMP_INSERTION_LEN 1 -#define MAC_CFG_DESC_TX_0_TIMESTAMP_INSERTION_MSK 0x4000 - -#define MAC_CFG_DESC_TX_0_DURATION_PRESERVE_POS 15 -#define MAC_CFG_DESC_TX_0_DURATION_PRESERVE_LEN 1 -#define MAC_CFG_DESC_TX_0_DURATION_PRESERVE_MSK 0x8000 - -#define MAC_CFG_DESC_TX_0_MCS_INDEX_POS 22 -#define MAC_CFG_DESC_TX_0_MCS_INDEX_LEN 5 -#define MAC_CFG_DESC_TX_0_MCS_INDEX_MSK 0x7C00000 - -#define MAC_CFG_DESC_TX_0_MCS_EN_POS 27 -#define MAC_CFG_DESC_TX_0_MCS_EN_LEN 1 -#define MAC_CFG_DESC_TX_0_MCS_EN_MSK 0x8000000 - -#define MAC_CFG_DESC_TX_0_SN_PRESERVED_POS 31 -#define MAC_CFG_DESC_TX_0_SN_PRESERVED_LEN 1 -#define MAC_CFG_DESC_TX_0_SN_PRESERVED_MSK 0x80000000 - -/* TX MAC Dword 1 */ -#define MAC_CFG_DESC_TX_1_PKT_MODE_POS 0 -#define MAC_CFG_DESC_TX_1_PKT_MODE_LEN 4 -#define MAC_CFG_DESC_TX_1_PKT_MODE_MSK 0xF - -#define MAC_CFG_DESC_TX_1_PKT_MODE_EN_POS 4 -#define MAC_CFG_DESC_TX_1_PKT_MODE_EN_LEN 1 -#define MAC_CFG_DESC_TX_1_PKT_MODE_EN_MSK 0x10 - -#define MAC_CFG_DESC_TX_1_ACK_POLICY_EN_POS 15 -#define MAC_CFG_DESC_TX_1_ACK_POLICY_EN_LEN 1 -#define MAC_CFG_DESC_TX_1_ACK_POLICY_EN_MSK 0x8000 - -#define MAC_CFG_DESC_TX_1_DST_INDEX_POS 16 -#define MAC_CFG_DESC_TX_1_DST_INDEX_LEN 4 -#define MAC_CFG_DESC_TX_1_DST_INDEX_MSK 0xF0000 - -#define MAC_CFG_DESC_TX_1_DST_INDEX_EN_POS 20 -#define MAC_CFG_DESC_TX_1_DST_INDEX_EN_LEN 1 -#define MAC_CFG_DESC_TX_1_DST_INDEX_EN_MSK 0x100000 - -#define MAC_CFG_DESC_TX_1_ACK_POLICY_POS 21 -#define MAC_CFG_DESC_TX_1_ACK_POLICY_LEN 2 -#define MAC_CFG_DESC_TX_1_ACK_POLICY_MSK 0x600000 - -#define MAC_CFG_DESC_TX_1_LIFETIME_EN_POS 23 -#define MAC_CFG_DESC_TX_1_LIFETIME_EN_LEN 1 -#define MAC_CFG_DESC_TX_1_LIFETIME_EN_MSK 0x800000 - -#define MAC_CFG_DESC_TX_1_MAX_RETRY_POS 24 -#define MAC_CFG_DESC_TX_1_MAX_RETRY_LEN 7 -#define MAC_CFG_DESC_TX_1_MAX_RETRY_MSK 0x7F000000 - -#define MAC_CFG_DESC_TX_1_MAX_RETRY_EN_POS 31 -#define MAC_CFG_DESC_TX_1_MAX_RETRY_EN_LEN 1 -#define MAC_CFG_DESC_TX_1_MAX_RETRY_EN_MSK 0x80000000 - -/* TX MAC Dword 2 */ -#define MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS 0 -#define MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_LEN 8 -#define MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_MSK 0xFF - -#define MAC_CFG_DESC_TX_2_RESERVED_POS 8 -#define MAC_CFG_DESC_TX_2_RESERVED_LEN 10 -#define MAC_CFG_DESC_TX_2_RESERVED_MSK 0x3FF00 - -#define MAC_CFG_DESC_TX_2_L2_TRANSLATION_TYPE_POS 18 -#define MAC_CFG_DESC_TX_2_L2_TRANSLATION_TYPE_LEN 2 -#define MAC_CFG_DESC_TX_2_L2_TRANSLATION_TYPE_MSK 0xC0000 - -#define MAC_CFG_DESC_TX_2_SNAP_HDR_INSERTION_EN_POS 20 -#define MAC_CFG_DESC_TX_2_SNAP_HDR_INSERTION_EN_LEN 1 -#define MAC_CFG_DESC_TX_2_SNAP_HDR_INSERTION_EN_MSK 0x100000 - -#define MAC_CFG_DESC_TX_2_VLAN_REMOVAL_EN_POS 21 -#define MAC_CFG_DESC_TX_2_VLAN_REMOVAL_EN_LEN 1 -#define MAC_CFG_DESC_TX_2_VLAN_REMOVAL_EN_MSK 0x200000 - -/* TX MAC Dword 3 */ -#define MAC_CFG_DESC_TX_3_UCODE_CMD_POS 0 -#define MAC_CFG_DESC_TX_3_UCODE_CMD_LEN 32 -#define MAC_CFG_DESC_TX_3_UCODE_CMD_MSK 0xFFFFFFFF - -/* TX DMA Dword 0 */ -#define DMA_CFG_DESC_TX_0_L4_LENGTH_POS 0 -#define DMA_CFG_DESC_TX_0_L4_LENGTH_LEN 8 -#define DMA_CFG_DESC_TX_0_L4_LENGTH_MSK 0xFF - -#define DMA_CFG_DESC_TX_0_CMD_EOP_POS 8 -#define DMA_CFG_DESC_TX_0_CMD_EOP_LEN 1 -#define DMA_CFG_DESC_TX_0_CMD_EOP_MSK 0x100 - -#define DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS 10 -#define DMA_CFG_DESC_TX_0_CMD_DMA_IT_LEN 1 -#define DMA_CFG_DESC_TX_0_CMD_DMA_IT_MSK 0x400 - -#define DMA_CFG_DESC_TX_0_SEGMENT_BUF_DETAILS_POS 11 -#define DMA_CFG_DESC_TX_0_SEGMENT_BUF_DETAILS_LEN 2 -#define DMA_CFG_DESC_TX_0_SEGMENT_BUF_DETAILS_MSK 0x1800 - -#define DMA_CFG_DESC_TX_0_TCP_SEG_EN_POS 13 -#define DMA_CFG_DESC_TX_0_TCP_SEG_EN_LEN 1 -#define DMA_CFG_DESC_TX_0_TCP_SEG_EN_MSK 0x2000 - -#define DMA_CFG_DESC_TX_0_IPV4_CHECKSUM_EN_POS 14 -#define DMA_CFG_DESC_TX_0_IPV4_CHECKSUM_EN_LEN 1 -#define DMA_CFG_DESC_TX_0_IPV4_CHECKSUM_EN_MSK 0x4000 - -#define DMA_CFG_DESC_TX_0_TCP_UDP_CHECKSUM_EN_POS 15 -#define DMA_CFG_DESC_TX_0_TCP_UDP_CHECKSUM_EN_LEN 1 -#define DMA_CFG_DESC_TX_0_TCP_UDP_CHECKSUM_EN_MSK 0x8000 - -#define DMA_CFG_DESC_TX_0_QID_POS 16 -#define DMA_CFG_DESC_TX_0_QID_LEN 5 -#define DMA_CFG_DESC_TX_0_QID_MSK 0x1F0000 - -#define DMA_CFG_DESC_TX_0_PSEUDO_HEADER_CALC_EN_POS 21 -#define DMA_CFG_DESC_TX_0_PSEUDO_HEADER_CALC_EN_LEN 1 -#define DMA_CFG_DESC_TX_0_PSEUDO_HEADER_CALC_EN_MSK 0x200000 - -#define DMA_CFG_DESC_TX_0_L4_TYPE_POS 30 -#define DMA_CFG_DESC_TX_0_L4_TYPE_LEN 2 -#define DMA_CFG_DESC_TX_0_L4_TYPE_MSK 0xC0000000 - - -#define TX_DMA_STATUS_DU BIT(0) - -struct vring_tx_dma { - u32 d0; - u32 addr_low; - u16 addr_high; - u8 ip_length; - u8 b11; /* 0..6: mac_length; 7:ip_version */ - u8 error; /* 0..2: err; 3..7: reserved; */ - u8 status; /* 0: used; 1..7; reserved */ - u16 length; -} __packed; - -/* - * Rx descriptor - MAC part - * [dword 0] - * bit 0.. 3 : tid:4 The QoS (b3-0) TID Field - * bit 4.. 6 : connection_id:3 :The Source index that was found during - * Parsing the TA. This field is used to define the source of the packet - * bit 7 : reserved:1 - * bit 8.. 9 : mac_id:2 : The MAC virtual Ring number (always zero) - * bit 10..11 : frame_type:2 : The FC Control (b3-2) - MPDU Type - * (management, data, control and extension) - * bit 12..15 : frame_subtype:4 : The FC Control (b7-4) - Frame Subtype - * bit 16..27 : seq_number:12 The received Sequence number field - * bit 28..31 : extended:4 extended subtype - * [dword 1] - * bit 0.. 3 : reserved - * bit 4.. 5 : key_id:2 - * bit 6 : decrypt_bypass:1 - * bit 7 : security:1 - * bit 8.. 9 : ds_bits:2 - * bit 10 : a_msdu_present:1 from qos header - * bit 11 : a_msdu_type:1 from qos header - * bit 12 : a_mpdu:1 part of AMPDU aggregation - * bit 13 : broadcast:1 - * bit 14 : mutlicast:1 - * bit 15 : reserved:1 - * bit 16..20 : rx_mac_qid:5 The Queue Identifier that the packet - * is received from - * bit 21..24 : mcs:4 - * bit 25..28 : mic_icr:4 - * bit 29..31 : reserved:3 - * [dword 2] - * bit 0.. 2 : time_slot:3 The timeslot that the MPDU is received - * bit 3 : fc_protocol_ver:1 The FC Control (b0) - Protocol Version - * bit 4 : fc_order:1 The FC Control (b15) -Order - * bit 5.. 7 : qos_ack_policy:3 The QoS (b6-5) ack policy Field - * bit 8 : esop:1 The QoS (b4) ESOP field - * bit 9 : qos_rdg_more_ppdu:1 The QoS (b9) RDG field - * bit 10..14 : qos_reserved:5 The QoS (b14-10) Reserved field - * bit 15 : qos_ac_constraint:1 - * bit 16..31 : pn_15_0:16 low 2 bytes of PN - * [dword 3] - * bit 0..31 : pn_47_16:32 high 4 bytes of PN - */ -struct vring_rx_mac { - u32 d0; - u32 d1; - u16 w4; - u16 pn_15_0; - u32 pn_47_16; -} __packed; - -/* - * Rx descriptor - DMA part - * [dword 0] - * bit 0.. 7 : l4_length:8 layer 4 length - * bit 8.. 9 : reserved:2 - * bit 10 : cmd_dma_it:1 - * bit 11..15 : reserved:5 - * bit 16..29 : phy_info_length:14 - * bit 30..31 : l4_type:2 valid if the L4I bit is set in the status field - * [dword 1] - * bit 0..31 : addr_low:32 The payload buffer low address - * [dword 2] - * bit 0..15 : addr_high:16 The payload buffer high address - * bit 16..23 : ip_length:8 - * bit 24..30 : mac_length:7 - * bit 31 : ip_version:1 - * [dword 3] - * [byte 12] error - * [byte 13] status - * bit 0 : du:1 - * bit 1 : eop:1 - * bit 2 : error:1 - * bit 3 : mi:1 - * bit 4 : l3_identified:1 - * bit 5 : l4_identified:1 - * bit 6 : phy_info_included:1 - * bit 7 : reserved:1 - * [word 7] length - * - */ - -#define RX_DMA_D0_CMD_DMA_IT BIT(10) - -#define RX_DMA_STATUS_DU BIT(0) -#define RX_DMA_STATUS_ERROR BIT(2) -#define RX_DMA_STATUS_PHY_INFO BIT(6) - -struct vring_rx_dma { - u32 d0; - u32 addr_low; - u16 addr_high; - u8 ip_length; - u8 b11; - u8 error; - u8 status; - u16 length; -} __packed; - -struct vring_tx_desc { - struct vring_tx_mac mac; - struct vring_tx_dma dma; -} __packed; - -struct vring_rx_desc { - struct vring_rx_mac mac; - struct vring_rx_dma dma; -} __packed; - -union vring_desc { - struct vring_tx_desc tx; - struct vring_rx_desc rx; -} __packed; - -static inline int wil_rxdesc_phy_length(volatile struct vring_rx_desc *d) -{ - return WIL_GET_BITS(d->dma.d0, 16, 29); -} - -static inline int wil_rxdesc_mcs(volatile struct vring_rx_desc *d) -{ - return WIL_GET_BITS(d->mac.d1, 21, 24); -} - -static inline int wil_rxdesc_ds_bits(volatile struct vring_rx_desc *d) -{ - return WIL_GET_BITS(d->mac.d1, 8, 9); -} - -static inline int wil_rxdesc_ftype(volatile struct vring_rx_desc *d) -{ - return WIL_GET_BITS(d->mac.d0, 10, 11); -} - -#endif /* WIL6210_TXRX_H */ diff --git a/trunk/drivers/net/wireless/ath/wil6210/wil6210.h b/trunk/drivers/net/wireless/ath/wil6210/wil6210.h deleted file mode 100644 index 9bcfffa4006c..000000000000 --- a/trunk/drivers/net/wireless/ath/wil6210/wil6210.h +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Copyright (c) 2012 Qualcomm Atheros, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __WIL6210_H__ -#define __WIL6210_H__ - -#include -#include -#include - -#include "dbg_hexdump.h" - -#define WIL_NAME "wil6210" - -/** - * extract bits [@b0:@b1] (inclusive) from the value @x - * it should be @b0 <= @b1, or result is incorrect - */ -static inline u32 WIL_GET_BITS(u32 x, int b0, int b1) -{ - return (x >> b0) & ((1 << (b1 - b0 + 1)) - 1); -} - -#define WIL6210_MEM_SIZE (2*1024*1024UL) - -#define WIL6210_TX_QUEUES (4) - -#define WIL6210_RX_RING_SIZE (128) -#define WIL6210_TX_RING_SIZE (128) -#define WIL6210_MAX_TX_RINGS (24) - -/* Hardware definitions begin */ - -/* - * Mapping - * RGF File | Host addr | FW addr - * | | - * user_rgf | 0x000000 | 0x880000 - * dma_rgf | 0x001000 | 0x881000 - * pcie_rgf | 0x002000 | 0x882000 - * | | - */ - -/* Where various structures placed in host address space */ -#define WIL6210_FW_HOST_OFF (0x880000UL) - -#define HOSTADDR(fwaddr) (fwaddr - WIL6210_FW_HOST_OFF) - -/* - * Interrupt control registers block - * - * each interrupt controlled by the same bit in all registers - */ -struct RGF_ICR { - u32 ICC; /* Cause Control, RW: 0 - W1C, 1 - COR */ - u32 ICR; /* Cause, W1C/COR depending on ICC */ - u32 ICM; /* Cause masked (ICR & ~IMV), W1C/COR depending on ICC */ - u32 ICS; /* Cause Set, WO */ - u32 IMV; /* Mask, RW+S/C */ - u32 IMS; /* Mask Set, write 1 to set */ - u32 IMC; /* Mask Clear, write 1 to clear */ -} __packed; - -/* registers - FW addresses */ -#define RGF_USER_USER_SCRATCH_PAD (0x8802bc) -#define RGF_USER_USER_ICR (0x880b4c) /* struct RGF_ICR */ - #define BIT_USER_USER_ICR_SW_INT_2 BIT(18) -#define RGF_USER_CLKS_CTL_SW_RST_MASK_0 (0x880b14) -#define RGF_USER_MAC_CPU_0 (0x8801fc) -#define RGF_USER_USER_CPU_0 (0x8801e0) -#define RGF_USER_CLKS_CTL_SW_RST_VEC_0 (0x880b04) -#define RGF_USER_CLKS_CTL_SW_RST_VEC_1 (0x880b08) -#define RGF_USER_CLKS_CTL_SW_RST_VEC_2 (0x880b0c) -#define RGF_USER_CLKS_CTL_SW_RST_VEC_3 (0x880b10) - -#define RGF_DMA_PSEUDO_CAUSE (0x881c68) -#define RGF_DMA_PSEUDO_CAUSE_MASK_SW (0x881c6c) -#define RGF_DMA_PSEUDO_CAUSE_MASK_FW (0x881c70) - #define BIT_DMA_PSEUDO_CAUSE_RX BIT(0) - #define BIT_DMA_PSEUDO_CAUSE_TX BIT(1) - #define BIT_DMA_PSEUDO_CAUSE_MISC BIT(2) - -#define RGF_DMA_EP_TX_ICR (0x881bb4) /* struct RGF_ICR */ - #define BIT_DMA_EP_TX_ICR_TX_DONE BIT(0) - #define BIT_DMA_EP_TX_ICR_TX_DONE_N(n) BIT(n+1) /* n = [0..23] */ -#define RGF_DMA_EP_RX_ICR (0x881bd0) /* struct RGF_ICR */ - #define BIT_DMA_EP_RX_ICR_RX_DONE BIT(0) -#define RGF_DMA_EP_MISC_ICR (0x881bec) /* struct RGF_ICR */ - #define BIT_DMA_EP_MISC_ICR_RX_HTRSH BIT(0) - #define BIT_DMA_EP_MISC_ICR_TX_NO_ACT BIT(1) - #define BIT_DMA_EP_MISC_ICR_FW_INT0 BIT(28) - #define BIT_DMA_EP_MISC_ICR_FW_INT1 BIT(29) - -/* Interrupt moderation control */ -#define RGF_DMA_ITR_CNT_TRSH (0x881c5c) -#define RGF_DMA_ITR_CNT_DATA (0x881c60) -#define RGF_DMA_ITR_CNT_CRL (0x881C64) - #define BIT_DMA_ITR_CNT_CRL_EN BIT(0) - #define BIT_DMA_ITR_CNT_CRL_EXT_TICK BIT(1) - #define BIT_DMA_ITR_CNT_CRL_FOREVER BIT(2) - #define BIT_DMA_ITR_CNT_CRL_CLR BIT(3) - #define BIT_DMA_ITR_CNT_CRL_REACH_TRSH BIT(4) - -/* popular locations */ -#define HOST_MBOX HOSTADDR(RGF_USER_USER_SCRATCH_PAD) -#define HOST_SW_INT (HOSTADDR(RGF_USER_USER_ICR) + \ - offsetof(struct RGF_ICR, ICS)) -#define SW_INT_MBOX BIT_USER_USER_ICR_SW_INT_2 - -/* ISR register bits */ -#define ISR_MISC_FW_READY BIT_DMA_EP_MISC_ICR_FW_INT0 -#define ISR_MISC_MBOX_EVT BIT_DMA_EP_MISC_ICR_FW_INT1 - -/* Hardware definitions end */ - -struct wil6210_mbox_ring { - u32 base; - u16 entry_size; /* max. size of mbox entry, incl. all headers */ - u16 size; - u32 tail; - u32 head; -} __packed; - -struct wil6210_mbox_ring_desc { - __le32 sync; - __le32 addr; -} __packed; - -/* at HOST_OFF_WIL6210_MBOX_CTL */ -struct wil6210_mbox_ctl { - struct wil6210_mbox_ring tx; - struct wil6210_mbox_ring rx; -} __packed; - -struct wil6210_mbox_hdr { - __le16 seq; - __le16 len; /* payload, bytes after this header */ - __le16 type; - u8 flags; - u8 reserved; -} __packed; - -#define WIL_MBOX_HDR_TYPE_WMI (0) - -/* max. value for wil6210_mbox_hdr.len */ -#define MAX_MBOXITEM_SIZE (240) - -struct wil6210_mbox_hdr_wmi { - u8 reserved0[2]; - __le16 id; - __le16 info1; /* bits [0..3] - device_id, rest - unused */ - u8 reserved1[2]; -} __packed; - -struct pending_wmi_event { - struct list_head list; - struct { - struct wil6210_mbox_hdr hdr; - struct wil6210_mbox_hdr_wmi wmi; - u8 data[0]; - } __packed event; -}; - -union vring_desc; - -struct vring { - dma_addr_t pa; - volatile union vring_desc *va; /* vring_desc[size], WriteBack by DMA */ - u16 size; /* number of vring_desc elements */ - u32 swtail; - u32 swhead; - u32 hwtail; /* write here to inform hw */ - void **ctx; /* void *ctx[size] - software context */ -}; - -enum { /* for wil6210_priv.status */ - wil_status_fwready = 0, - wil_status_fwconnected, - wil_status_dontscan, - wil_status_irqen, /* FIXME: interrupts enabled - for debug */ -}; - -struct pci_dev; - -struct wil6210_stats { - u64 tsf; - u32 snr; - u16 last_mcs_rx; - u16 bf_mcs; /* last BF, used for Tx */ - u16 my_rx_sector; - u16 my_tx_sector; - u16 peer_rx_sector; - u16 peer_tx_sector; -}; - -struct wil6210_priv { - struct pci_dev *pdev; - int n_msi; - struct wireless_dev *wdev; - void __iomem *csr; - ulong status; - /* profile */ - u32 monitor_flags; - u32 secure_pcp; /* create secure PCP? */ - int sinfo_gen; - /* cached ISR registers */ - u32 isr_misc; - /* mailbox related */ - struct mutex wmi_mutex; - struct wil6210_mbox_ctl mbox_ctl; - struct completion wmi_ready; - u16 wmi_seq; - u16 reply_id; /**< wait for this WMI event */ - void *reply_buf; - u16 reply_size; - struct workqueue_struct *wmi_wq; /* for deferred calls */ - struct work_struct wmi_event_worker; - struct workqueue_struct *wmi_wq_conn; /* for connect worker */ - struct work_struct wmi_connect_worker; - struct work_struct disconnect_worker; - struct timer_list connect_timer; - int pending_connect_cid; - struct list_head pending_wmi_ev; - /* - * protect pending_wmi_ev - * - fill in IRQ from wil6210_irq_misc, - * - consumed in thread by wmi_event_worker - */ - spinlock_t wmi_ev_lock; - /* DMA related */ - struct vring vring_rx; - struct vring vring_tx[WIL6210_MAX_TX_RINGS]; - u8 dst_addr[WIL6210_MAX_TX_RINGS][ETH_ALEN]; - /* scan */ - struct cfg80211_scan_request *scan_request; - - struct mutex mutex; /* for wil6210_priv access in wil_{up|down} */ - /* statistics */ - struct wil6210_stats stats; - /* debugfs */ - struct dentry *debug; - struct debugfs_blob_wrapper fw_code_blob; - struct debugfs_blob_wrapper fw_data_blob; - struct debugfs_blob_wrapper fw_peri_blob; - struct debugfs_blob_wrapper uc_code_blob; - struct debugfs_blob_wrapper uc_data_blob; - struct debugfs_blob_wrapper rgf_blob; -}; - -#define wil_to_wiphy(i) (i->wdev->wiphy) -#define wil_to_dev(i) (wiphy_dev(wil_to_wiphy(i))) -#define wiphy_to_wil(w) (struct wil6210_priv *)(wiphy_priv(w)) -#define wil_to_wdev(i) (i->wdev) -#define wdev_to_wil(w) (struct wil6210_priv *)(wdev_priv(w)) -#define wil_to_ndev(i) (wil_to_wdev(i)->netdev) -#define ndev_to_wil(n) (wdev_to_wil(n->ieee80211_ptr)) - -#define wil_dbg(wil, fmt, arg...) netdev_dbg(wil_to_ndev(wil), fmt, ##arg) -#define wil_info(wil, fmt, arg...) netdev_info(wil_to_ndev(wil), fmt, ##arg) -#define wil_err(wil, fmt, arg...) netdev_err(wil_to_ndev(wil), fmt, ##arg) - -#define wil_dbg_IRQ(wil, fmt, arg...) wil_dbg(wil, "DBG[ IRQ]" fmt, ##arg) -#define wil_dbg_TXRX(wil, fmt, arg...) wil_dbg(wil, "DBG[TXRX]" fmt, ##arg) -#define wil_dbg_WMI(wil, fmt, arg...) wil_dbg(wil, "DBG[ WMI]" fmt, ##arg) - -#define wil_hex_dump_TXRX(prefix_str, prefix_type, rowsize, \ - groupsize, buf, len, ascii) \ - wil_print_hex_dump_debug("DBG[TXRX]" prefix_str,\ - prefix_type, rowsize, \ - groupsize, buf, len, ascii) - -#define wil_hex_dump_WMI(prefix_str, prefix_type, rowsize, \ - groupsize, buf, len, ascii) \ - wil_print_hex_dump_debug("DBG[ WMI]" prefix_str,\ - prefix_type, rowsize, \ - groupsize, buf, len, ascii) - -void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src, - size_t count); -void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, - size_t count); - -void *wil_if_alloc(struct device *dev, void __iomem *csr); -void wil_if_free(struct wil6210_priv *wil); -int wil_if_add(struct wil6210_priv *wil); -void wil_if_remove(struct wil6210_priv *wil); -int wil_priv_init(struct wil6210_priv *wil); -void wil_priv_deinit(struct wil6210_priv *wil); -int wil_reset(struct wil6210_priv *wil); -void wil_link_on(struct wil6210_priv *wil); -void wil_link_off(struct wil6210_priv *wil); -int wil_up(struct wil6210_priv *wil); -int wil_down(struct wil6210_priv *wil); -void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r); - -void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr); -void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr); -int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr, - struct wil6210_mbox_hdr *hdr); -int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len); -void wmi_recv_cmd(struct wil6210_priv *wil); -int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len, - u16 reply_id, void *reply, u8 reply_size, int to_msec); -void wmi_connect_worker(struct work_struct *work); -void wmi_event_worker(struct work_struct *work); -void wmi_event_flush(struct wil6210_priv *wil); -int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid); -int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid); -int wmi_set_channel(struct wil6210_priv *wil, int channel); -int wmi_get_channel(struct wil6210_priv *wil, int *channel); -int wmi_tx_eapol(struct wil6210_priv *wil, struct sk_buff *skb); -int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index, - const void *mac_addr); -int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index, - const void *mac_addr, int key_len, const void *key); -int wmi_echo(struct wil6210_priv *wil); -int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie); - -int wil6210_init_irq(struct wil6210_priv *wil, int irq); -void wil6210_fini_irq(struct wil6210_priv *wil, int irq); -void wil6210_disable_irq(struct wil6210_priv *wil); -void wil6210_enable_irq(struct wil6210_priv *wil); - -int wil6210_debugfs_init(struct wil6210_priv *wil); -void wil6210_debugfs_remove(struct wil6210_priv *wil); - -struct wireless_dev *wil_cfg80211_init(struct device *dev); -void wil_wdev_free(struct wil6210_priv *wil); - -int wmi_set_mac_address(struct wil6210_priv *wil, void *addr); -int wmi_set_bcon(struct wil6210_priv *wil, int bi, u8 wmi_nettype); -void wil6210_disconnect(struct wil6210_priv *wil, void *bssid); - -int wil_rx_init(struct wil6210_priv *wil); -void wil_rx_fini(struct wil6210_priv *wil); - -/* TX API */ -int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, - int cid, int tid); -void wil_vring_fini_tx(struct wil6210_priv *wil, int id); - -netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev); -void wil_tx_complete(struct wil6210_priv *wil, int ringid); - -/* RX API */ -void wil_rx_handle(struct wil6210_priv *wil); - -int wil_iftype_nl2wmi(enum nl80211_iftype type); - -#endif /* __WIL6210_H__ */ diff --git a/trunk/drivers/net/wireless/ath/wil6210/wmi.c b/trunk/drivers/net/wireless/ath/wil6210/wmi.c deleted file mode 100644 index 12915f6e7617..000000000000 --- a/trunk/drivers/net/wireless/ath/wil6210/wmi.c +++ /dev/null @@ -1,975 +0,0 @@ -/* - * Copyright (c) 2012 Qualcomm Atheros, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include - -#include "wil6210.h" -#include "wmi.h" - -/** - * WMI event receiving - theory of operations - * - * When firmware about to report WMI event, it fills memory area - * in the mailbox and raises misc. IRQ. Thread interrupt handler invoked for - * the misc IRQ, function @wmi_recv_cmd called by thread IRQ handler. - * - * @wmi_recv_cmd reads event, allocates memory chunk and attaches it to the - * event list @wil->pending_wmi_ev. Then, work queue @wil->wmi_wq wakes up - * and handles events within the @wmi_event_worker. Every event get detached - * from list, processed and deleted. - * - * Purpose for this mechanism is to release IRQ thread; otherwise, - * if WMI event handling involves another WMI command flow, this 2-nd flow - * won't be completed because of blocked IRQ thread. - */ - -/** - * Addressing - theory of operations - * - * There are several buses present on the WIL6210 card. - * Same memory areas are visible at different address on - * the different busses. There are 3 main bus masters: - * - MAC CPU (ucode) - * - User CPU (firmware) - * - AHB (host) - * - * On the PCI bus, there is one BAR (BAR0) of 2Mb size, exposing - * AHB addresses starting from 0x880000 - * - * Internally, firmware uses addresses that allows faster access but - * are invisible from the host. To read from these addresses, alternative - * AHB address must be used. - * - * Memory mapping - * Linker address PCI/Host address - * 0x880000 .. 0xa80000 2Mb BAR0 - * 0x800000 .. 0x807000 0x900000 .. 0x907000 28k DCCM - * 0x840000 .. 0x857000 0x908000 .. 0x91f000 92k PERIPH - */ - -/** - * @fw_mapping provides memory remapping table - */ -static const struct { - u32 from; /* linker address - from, inclusive */ - u32 to; /* linker address - to, exclusive */ - u32 host; /* PCI/Host address - BAR0 + 0x880000 */ -} fw_mapping[] = { - {0x000000, 0x040000, 0x8c0000}, /* FW code RAM 256k */ - {0x800000, 0x808000, 0x900000}, /* FW data RAM 32k */ - {0x840000, 0x860000, 0x908000}, /* peripheral data RAM 128k/96k used */ - {0x880000, 0x88a000, 0x880000}, /* various RGF */ - {0x8c0000, 0x932000, 0x8c0000}, /* trivial mapping for upper area */ - /* - * 920000..930000 ucode code RAM - * 930000..932000 ucode data RAM - */ -}; - -/** - * return AHB address for given firmware/ucode internal (linker) address - * @x - internal address - * If address have no valid AHB mapping, return 0 - */ -static u32 wmi_addr_remap(u32 x) -{ - uint i; - - for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) { - if ((x >= fw_mapping[i].from) && (x < fw_mapping[i].to)) - return x + fw_mapping[i].host - fw_mapping[i].from; - } - - return 0; -} - -/** - * Check address validity for WMI buffer; remap if needed - * @ptr - internal (linker) fw/ucode address - * - * Valid buffer should be DWORD aligned - * - * return address for accessing buffer from the host; - * if buffer is not valid, return NULL. - */ -void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr_) -{ - u32 off; - u32 ptr = le32_to_cpu(ptr_); - - if (ptr % 4) - return NULL; - - ptr = wmi_addr_remap(ptr); - if (ptr < WIL6210_FW_HOST_OFF) - return NULL; - - off = HOSTADDR(ptr); - if (off > WIL6210_MEM_SIZE - 4) - return NULL; - - return wil->csr + off; -} - -/** - * Check address validity - */ -void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr) -{ - u32 off; - - if (ptr % 4) - return NULL; - - if (ptr < WIL6210_FW_HOST_OFF) - return NULL; - - off = HOSTADDR(ptr); - if (off > WIL6210_MEM_SIZE - 4) - return NULL; - - return wil->csr + off; -} - -int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr, - struct wil6210_mbox_hdr *hdr) -{ - void __iomem *src = wmi_buffer(wil, ptr); - if (!src) - return -EINVAL; - - wil_memcpy_fromio_32(hdr, src, sizeof(*hdr)); - - return 0; -} - -static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) -{ - struct { - struct wil6210_mbox_hdr hdr; - struct wil6210_mbox_hdr_wmi wmi; - } __packed cmd = { - .hdr = { - .type = WIL_MBOX_HDR_TYPE_WMI, - .flags = 0, - .len = cpu_to_le16(sizeof(cmd.wmi) + len), - }, - .wmi = { - .id = cpu_to_le16(cmdid), - .info1 = 0, - }, - }; - struct wil6210_mbox_ring *r = &wil->mbox_ctl.tx; - struct wil6210_mbox_ring_desc d_head; - u32 next_head; - void __iomem *dst; - void __iomem *head = wmi_addr(wil, r->head); - uint retry; - - if (sizeof(cmd) + len > r->entry_size) { - wil_err(wil, "WMI size too large: %d bytes, max is %d\n", - (int)(sizeof(cmd) + len), r->entry_size); - return -ERANGE; - - } - - might_sleep(); - - if (!test_bit(wil_status_fwready, &wil->status)) { - wil_err(wil, "FW not ready\n"); - return -EAGAIN; - } - - if (!head) { - wil_err(wil, "WMI head is garbage: 0x%08x\n", r->head); - return -EINVAL; - } - /* read Tx head till it is not busy */ - for (retry = 5; retry > 0; retry--) { - wil_memcpy_fromio_32(&d_head, head, sizeof(d_head)); - if (d_head.sync == 0) - break; - msleep(20); - } - if (d_head.sync != 0) { - wil_err(wil, "WMI head busy\n"); - return -EBUSY; - } - /* next head */ - next_head = r->base + ((r->head - r->base + sizeof(d_head)) % r->size); - wil_dbg_WMI(wil, "Head 0x%08x -> 0x%08x\n", r->head, next_head); - /* wait till FW finish with previous command */ - for (retry = 5; retry > 0; retry--) { - r->tail = ioread32(wil->csr + HOST_MBOX + - offsetof(struct wil6210_mbox_ctl, tx.tail)); - if (next_head != r->tail) - break; - msleep(20); - } - if (next_head == r->tail) { - wil_err(wil, "WMI ring full\n"); - return -EBUSY; - } - dst = wmi_buffer(wil, d_head.addr); - if (!dst) { - wil_err(wil, "invalid WMI buffer: 0x%08x\n", - le32_to_cpu(d_head.addr)); - return -EINVAL; - } - cmd.hdr.seq = cpu_to_le16(++wil->wmi_seq); - /* set command */ - wil_dbg_WMI(wil, "WMI command 0x%04x [%d]\n", cmdid, len); - wil_hex_dump_WMI("Cmd ", DUMP_PREFIX_OFFSET, 16, 1, &cmd, - sizeof(cmd), true); - wil_hex_dump_WMI("cmd ", DUMP_PREFIX_OFFSET, 16, 1, buf, - len, true); - wil_memcpy_toio_32(dst, &cmd, sizeof(cmd)); - wil_memcpy_toio_32(dst + sizeof(cmd), buf, len); - /* mark entry as full */ - iowrite32(1, wil->csr + HOSTADDR(r->head) + - offsetof(struct wil6210_mbox_ring_desc, sync)); - /* advance next ptr */ - iowrite32(r->head = next_head, wil->csr + HOST_MBOX + - offsetof(struct wil6210_mbox_ctl, tx.head)); - - /* interrupt to FW */ - iowrite32(SW_INT_MBOX, wil->csr + HOST_SW_INT); - - return 0; -} - -int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) -{ - int rc; - - mutex_lock(&wil->wmi_mutex); - rc = __wmi_send(wil, cmdid, buf, len); - mutex_unlock(&wil->wmi_mutex); - - return rc; -} - -/*=== Event handlers ===*/ -static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len) -{ - struct net_device *ndev = wil_to_ndev(wil); - struct wireless_dev *wdev = wil->wdev; - struct wmi_ready_event *evt = d; - u32 ver = le32_to_cpu(evt->sw_version); - - wil_dbg_WMI(wil, "FW ver. %d; MAC %pM\n", ver, evt->mac); - - if (!is_valid_ether_addr(ndev->dev_addr)) { - memcpy(ndev->dev_addr, evt->mac, ETH_ALEN); - memcpy(ndev->perm_addr, evt->mac, ETH_ALEN); - } - snprintf(wdev->wiphy->fw_version, sizeof(wdev->wiphy->fw_version), - "%d", ver); -} - -static void wmi_evt_fw_ready(struct wil6210_priv *wil, int id, void *d, - int len) -{ - wil_dbg_WMI(wil, "WMI: FW ready\n"); - - set_bit(wil_status_fwready, &wil->status); - /* reuse wmi_ready for the firmware ready indication */ - complete(&wil->wmi_ready); -} - -static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len) -{ - struct wmi_rx_mgmt_packet_event *data = d; - struct wiphy *wiphy = wil_to_wiphy(wil); - struct ieee80211_mgmt *rx_mgmt_frame = - (struct ieee80211_mgmt *)data->payload; - int ch_no = data->info.channel+1; - u32 freq = ieee80211_channel_to_frequency(ch_no, - IEEE80211_BAND_60GHZ); - struct ieee80211_channel *channel = ieee80211_get_channel(wiphy, freq); - /* TODO convert LE to CPU */ - s32 signal = 0; /* TODO */ - __le16 fc = rx_mgmt_frame->frame_control; - u32 d_len = le32_to_cpu(data->info.len); - u16 d_status = le16_to_cpu(data->info.status); - - wil_dbg_WMI(wil, "MGMT: channel %d MCS %d SNR %d\n", - data->info.channel, data->info.mcs, data->info.snr); - wil_dbg_WMI(wil, "status 0x%04x len %d stype %04x\n", d_status, d_len, - le16_to_cpu(data->info.stype)); - wil_dbg_WMI(wil, "qid %d mid %d cid %d\n", - data->info.qid, data->info.mid, data->info.cid); - - if (!channel) { - wil_err(wil, "Frame on unsupported channel\n"); - return; - } - - if (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc)) { - struct cfg80211_bss *bss; - u64 tsf = le64_to_cpu(rx_mgmt_frame->u.beacon.timestamp); - u16 cap = le16_to_cpu(rx_mgmt_frame->u.beacon.capab_info); - u16 bi = le16_to_cpu(rx_mgmt_frame->u.beacon.beacon_int); - const u8 *ie_buf = rx_mgmt_frame->u.beacon.variable; - size_t ie_len = d_len - offsetof(struct ieee80211_mgmt, - u.beacon.variable); - wil_dbg_WMI(wil, "Capability info : 0x%04x\n", cap); - - bss = cfg80211_inform_bss(wiphy, channel, rx_mgmt_frame->bssid, - tsf, cap, bi, ie_buf, ie_len, - signal, GFP_KERNEL); - if (bss) { - wil_dbg_WMI(wil, "Added BSS %pM\n", - rx_mgmt_frame->bssid); - cfg80211_put_bss(bss); - } else { - wil_err(wil, "cfg80211_inform_bss() failed\n"); - } - } -} - -static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id, - void *d, int len) -{ - if (wil->scan_request) { - struct wmi_scan_complete_event *data = d; - bool aborted = (data->status != 0); - - wil_dbg_WMI(wil, "SCAN_COMPLETE(0x%08x)\n", data->status); - cfg80211_scan_done(wil->scan_request, aborted); - wil->scan_request = NULL; - } else { - wil_err(wil, "SCAN_COMPLETE while not scanning\n"); - } -} - -static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len) -{ - struct net_device *ndev = wil_to_ndev(wil); - struct wireless_dev *wdev = wil->wdev; - struct wmi_connect_event *evt = d; - int ch; /* channel number */ - struct station_info sinfo; - u8 *assoc_req_ie, *assoc_resp_ie; - size_t assoc_req_ielen, assoc_resp_ielen; - /* capinfo(u16) + listen_interval(u16) + IEs */ - const size_t assoc_req_ie_offset = sizeof(u16) * 2; - /* capinfo(u16) + status_code(u16) + associd(u16) + IEs */ - const size_t assoc_resp_ie_offset = sizeof(u16) * 3; - - if (len < sizeof(*evt)) { - wil_err(wil, "Connect event too short : %d bytes\n", len); - return; - } - if (len != sizeof(*evt) + evt->beacon_ie_len + evt->assoc_req_len + - evt->assoc_resp_len) { - wil_err(wil, - "Connect event corrupted : %d != %d + %d + %d + %d\n", - len, (int)sizeof(*evt), evt->beacon_ie_len, - evt->assoc_req_len, evt->assoc_resp_len); - return; - } - ch = evt->channel + 1; - wil_dbg_WMI(wil, "Connect %pM channel [%d] cid %d\n", - evt->bssid, ch, evt->cid); - wil_hex_dump_WMI("connect AI : ", DUMP_PREFIX_OFFSET, 16, 1, - evt->assoc_info, len - sizeof(*evt), true); - - /* figure out IE's */ - assoc_req_ie = &evt->assoc_info[evt->beacon_ie_len + - assoc_req_ie_offset]; - assoc_req_ielen = evt->assoc_req_len - assoc_req_ie_offset; - if (evt->assoc_req_len <= assoc_req_ie_offset) { - assoc_req_ie = NULL; - assoc_req_ielen = 0; - } - - assoc_resp_ie = &evt->assoc_info[evt->beacon_ie_len + - evt->assoc_req_len + - assoc_resp_ie_offset]; - assoc_resp_ielen = evt->assoc_resp_len - assoc_resp_ie_offset; - if (evt->assoc_resp_len <= assoc_resp_ie_offset) { - assoc_resp_ie = NULL; - assoc_resp_ielen = 0; - } - - if ((wdev->iftype == NL80211_IFTYPE_STATION) || - (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) { - if (wdev->sme_state != CFG80211_SME_CONNECTING) { - wil_err(wil, "Not in connecting state\n"); - return; - } - del_timer_sync(&wil->connect_timer); - cfg80211_connect_result(ndev, evt->bssid, - assoc_req_ie, assoc_req_ielen, - assoc_resp_ie, assoc_resp_ielen, - WLAN_STATUS_SUCCESS, GFP_KERNEL); - - } else if ((wdev->iftype == NL80211_IFTYPE_AP) || - (wdev->iftype == NL80211_IFTYPE_P2P_GO)) { - memset(&sinfo, 0, sizeof(sinfo)); - - sinfo.generation = wil->sinfo_gen++; - - if (assoc_req_ie) { - sinfo.assoc_req_ies = assoc_req_ie; - sinfo.assoc_req_ies_len = assoc_req_ielen; - sinfo.filled |= STATION_INFO_ASSOC_REQ_IES; - } - - cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL); - } - set_bit(wil_status_fwconnected, &wil->status); - - /* FIXME FW can transmit only ucast frames to peer */ - /* FIXME real ring_id instead of hard coded 0 */ - memcpy(wil->dst_addr[0], evt->bssid, ETH_ALEN); - - wil->pending_connect_cid = evt->cid; - queue_work(wil->wmi_wq_conn, &wil->wmi_connect_worker); -} - -static void wmi_evt_disconnect(struct wil6210_priv *wil, int id, - void *d, int len) -{ - struct wmi_disconnect_event *evt = d; - - wil_dbg_WMI(wil, "Disconnect %pM reason %d proto %d wmi\n", - evt->bssid, - evt->protocol_reason_status, evt->disconnect_reason); - - wil->sinfo_gen++; - - wil6210_disconnect(wil, evt->bssid); - clear_bit(wil_status_dontscan, &wil->status); -} - -static void wmi_evt_notify(struct wil6210_priv *wil, int id, void *d, int len) -{ - struct wmi_notify_req_done_event *evt = d; - - if (len < sizeof(*evt)) { - wil_err(wil, "Short NOTIFY event\n"); - return; - } - - wil->stats.tsf = le64_to_cpu(evt->tsf); - wil->stats.snr = le32_to_cpu(evt->snr_val); - wil->stats.bf_mcs = le16_to_cpu(evt->bf_mcs); - wil->stats.my_rx_sector = le16_to_cpu(evt->my_rx_sector); - wil->stats.my_tx_sector = le16_to_cpu(evt->my_tx_sector); - wil->stats.peer_rx_sector = le16_to_cpu(evt->other_rx_sector); - wil->stats.peer_tx_sector = le16_to_cpu(evt->other_tx_sector); - wil_dbg_WMI(wil, "Link status, MCS %d TSF 0x%016llx\n" - "BF status 0x%08x SNR 0x%08x\n" - "Tx Tpt %d goodput %d Rx goodput %d\n" - "Sectors(rx:tx) my %d:%d peer %d:%d\n", - wil->stats.bf_mcs, wil->stats.tsf, evt->status, - wil->stats.snr, le32_to_cpu(evt->tx_tpt), - le32_to_cpu(evt->tx_goodput), le32_to_cpu(evt->rx_goodput), - wil->stats.my_rx_sector, wil->stats.my_tx_sector, - wil->stats.peer_rx_sector, wil->stats.peer_tx_sector); -} - -/* - * Firmware reports EAPOL frame using WME event. - * Reconstruct Ethernet frame and deliver it via normal Rx - */ -static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id, - void *d, int len) -{ - struct net_device *ndev = wil_to_ndev(wil); - struct wmi_eapol_rx_event *evt = d; - u16 eapol_len = le16_to_cpu(evt->eapol_len); - int sz = eapol_len + ETH_HLEN; - struct sk_buff *skb; - struct ethhdr *eth; - - wil_dbg_WMI(wil, "EAPOL len %d from %pM\n", eapol_len, - evt->src_mac); - - if (eapol_len > 196) { /* TODO: revisit size limit */ - wil_err(wil, "EAPOL too large\n"); - return; - } - - skb = alloc_skb(sz, GFP_KERNEL); - if (!skb) { - wil_err(wil, "Failed to allocate skb\n"); - return; - } - eth = (struct ethhdr *)skb_put(skb, ETH_HLEN); - memcpy(eth->h_dest, ndev->dev_addr, ETH_ALEN); - memcpy(eth->h_source, evt->src_mac, ETH_ALEN); - eth->h_proto = cpu_to_be16(ETH_P_PAE); - memcpy(skb_put(skb, eapol_len), evt->eapol, eapol_len); - skb->protocol = eth_type_trans(skb, ndev); - if (likely(netif_rx_ni(skb) == NET_RX_SUCCESS)) { - ndev->stats.rx_packets++; - ndev->stats.rx_bytes += skb->len; - } else { - ndev->stats.rx_dropped++; - } -} - -static const struct { - int eventid; - void (*handler)(struct wil6210_priv *wil, int eventid, - void *data, int data_len); -} wmi_evt_handlers[] = { - {WMI_READY_EVENTID, wmi_evt_ready}, - {WMI_FW_READY_EVENTID, wmi_evt_fw_ready}, - {WMI_RX_MGMT_PACKET_EVENTID, wmi_evt_rx_mgmt}, - {WMI_SCAN_COMPLETE_EVENTID, wmi_evt_scan_complete}, - {WMI_CONNECT_EVENTID, wmi_evt_connect}, - {WMI_DISCONNECT_EVENTID, wmi_evt_disconnect}, - {WMI_NOTIFY_REQ_DONE_EVENTID, wmi_evt_notify}, - {WMI_EAPOL_RX_EVENTID, wmi_evt_eapol_rx}, -}; - -/* - * Run in IRQ context - * Extract WMI command from mailbox. Queue it to the @wil->pending_wmi_ev - * that will be eventually handled by the @wmi_event_worker in the thread - * context of thread "wil6210_wmi" - */ -void wmi_recv_cmd(struct wil6210_priv *wil) -{ - struct wil6210_mbox_ring_desc d_tail; - struct wil6210_mbox_hdr hdr; - struct wil6210_mbox_ring *r = &wil->mbox_ctl.rx; - struct pending_wmi_event *evt; - u8 *cmd; - void __iomem *src; - ulong flags; - - for (;;) { - u16 len; - - r->head = ioread32(wil->csr + HOST_MBOX + - offsetof(struct wil6210_mbox_ctl, rx.head)); - if (r->tail == r->head) - return; - - /* read cmd from tail */ - wil_memcpy_fromio_32(&d_tail, wil->csr + HOSTADDR(r->tail), - sizeof(struct wil6210_mbox_ring_desc)); - if (d_tail.sync == 0) { - wil_err(wil, "Mbox evt not owned by FW?\n"); - return; - } - - if (0 != wmi_read_hdr(wil, d_tail.addr, &hdr)) { - wil_err(wil, "Mbox evt at 0x%08x?\n", - le32_to_cpu(d_tail.addr)); - return; - } - - len = le16_to_cpu(hdr.len); - src = wmi_buffer(wil, d_tail.addr) + - sizeof(struct wil6210_mbox_hdr); - evt = kmalloc(ALIGN(offsetof(struct pending_wmi_event, - event.wmi) + len, 4), - GFP_KERNEL); - if (!evt) { - wil_err(wil, "kmalloc for WMI event (%d) failed\n", - len); - return; - } - evt->event.hdr = hdr; - cmd = (void *)&evt->event.wmi; - wil_memcpy_fromio_32(cmd, src, len); - /* mark entry as empty */ - iowrite32(0, wil->csr + HOSTADDR(r->tail) + - offsetof(struct wil6210_mbox_ring_desc, sync)); - /* indicate */ - wil_dbg_WMI(wil, "Mbox evt %04x %04x %04x %02x\n", - le16_to_cpu(hdr.seq), len, le16_to_cpu(hdr.type), - hdr.flags); - if ((hdr.type == WIL_MBOX_HDR_TYPE_WMI) && - (len >= sizeof(struct wil6210_mbox_hdr_wmi))) { - wil_dbg_WMI(wil, "WMI event 0x%04x\n", - evt->event.wmi.id); - } - wil_hex_dump_WMI("evt ", DUMP_PREFIX_OFFSET, 16, 1, - &evt->event.hdr, sizeof(hdr) + len, true); - - /* advance tail */ - r->tail = r->base + ((r->tail - r->base + - sizeof(struct wil6210_mbox_ring_desc)) % r->size); - iowrite32(r->tail, wil->csr + HOST_MBOX + - offsetof(struct wil6210_mbox_ctl, rx.tail)); - - /* add to the pending list */ - spin_lock_irqsave(&wil->wmi_ev_lock, flags); - list_add_tail(&evt->list, &wil->pending_wmi_ev); - spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); - { - int q = queue_work(wil->wmi_wq, - &wil->wmi_event_worker); - wil_dbg_WMI(wil, "queue_work -> %d\n", q); - } - } -} - -int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len, - u16 reply_id, void *reply, u8 reply_size, int to_msec) -{ - int rc; - int remain; - - mutex_lock(&wil->wmi_mutex); - - rc = __wmi_send(wil, cmdid, buf, len); - if (rc) - goto out; - - wil->reply_id = reply_id; - wil->reply_buf = reply; - wil->reply_size = reply_size; - remain = wait_for_completion_timeout(&wil->wmi_ready, - msecs_to_jiffies(to_msec)); - if (0 == remain) { - wil_err(wil, "wmi_call(0x%04x->0x%04x) timeout %d msec\n", - cmdid, reply_id, to_msec); - rc = -ETIME; - } else { - wil_dbg_WMI(wil, - "wmi_call(0x%04x->0x%04x) completed in %d msec\n", - cmdid, reply_id, - to_msec - jiffies_to_msecs(remain)); - } - wil->reply_id = 0; - wil->reply_buf = NULL; - wil->reply_size = 0; - out: - mutex_unlock(&wil->wmi_mutex); - - return rc; -} - -int wmi_echo(struct wil6210_priv *wil) -{ - struct wmi_echo_cmd cmd = { - .value = cpu_to_le32(0x12345678), - }; - - return wmi_call(wil, WMI_ECHO_CMDID, &cmd, sizeof(cmd), - WMI_ECHO_RSP_EVENTID, NULL, 0, 20); -} - -int wmi_set_mac_address(struct wil6210_priv *wil, void *addr) -{ - struct wmi_set_mac_address_cmd cmd; - - memcpy(cmd.mac, addr, ETH_ALEN); - - wil_dbg_WMI(wil, "Set MAC %pM\n", addr); - - return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, &cmd, sizeof(cmd)); -} - -int wmi_set_bcon(struct wil6210_priv *wil, int bi, u8 wmi_nettype) -{ - struct wmi_bcon_ctrl_cmd cmd = { - .bcon_interval = cpu_to_le16(bi), - .network_type = wmi_nettype, - .disable_sec_offload = 1, - }; - - if (!wil->secure_pcp) - cmd.disable_sec = 1; - - return wmi_send(wil, WMI_BCON_CTRL_CMDID, &cmd, sizeof(cmd)); -} - -int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid) -{ - struct wmi_set_ssid_cmd cmd = { - .ssid_len = cpu_to_le32(ssid_len), - }; - - if (ssid_len > sizeof(cmd.ssid)) - return -EINVAL; - - memcpy(cmd.ssid, ssid, ssid_len); - - return wmi_send(wil, WMI_SET_SSID_CMDID, &cmd, sizeof(cmd)); -} - -int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid) -{ - int rc; - struct { - struct wil6210_mbox_hdr_wmi wmi; - struct wmi_set_ssid_cmd cmd; - } __packed reply; - int len; /* reply.cmd.ssid_len in CPU order */ - - rc = wmi_call(wil, WMI_GET_SSID_CMDID, NULL, 0, WMI_GET_SSID_EVENTID, - &reply, sizeof(reply), 20); - if (rc) - return rc; - - len = le32_to_cpu(reply.cmd.ssid_len); - if (len > sizeof(reply.cmd.ssid)) - return -EINVAL; - - *ssid_len = len; - memcpy(ssid, reply.cmd.ssid, len); - - return 0; -} - -int wmi_set_channel(struct wil6210_priv *wil, int channel) -{ - struct wmi_set_pcp_channel_cmd cmd = { - .channel = channel - 1, - }; - - return wmi_send(wil, WMI_SET_PCP_CHANNEL_CMDID, &cmd, sizeof(cmd)); -} - -int wmi_get_channel(struct wil6210_priv *wil, int *channel) -{ - int rc; - struct { - struct wil6210_mbox_hdr_wmi wmi; - struct wmi_set_pcp_channel_cmd cmd; - } __packed reply; - - rc = wmi_call(wil, WMI_GET_PCP_CHANNEL_CMDID, NULL, 0, - WMI_GET_PCP_CHANNEL_EVENTID, &reply, sizeof(reply), 20); - if (rc) - return rc; - - if (reply.cmd.channel > 3) - return -EINVAL; - - *channel = reply.cmd.channel + 1; - - return 0; -} - -int wmi_tx_eapol(struct wil6210_priv *wil, struct sk_buff *skb) -{ - struct wmi_eapol_tx_cmd *cmd; - struct ethhdr *eth; - u16 eapol_len = skb->len - ETH_HLEN; - void *eapol = skb->data + ETH_HLEN; - uint i; - int rc; - - skb_set_mac_header(skb, 0); - eth = eth_hdr(skb); - wil_dbg_WMI(wil, "EAPOL %d bytes to %pM\n", eapol_len, eth->h_dest); - for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) { - if (memcmp(wil->dst_addr[i], eth->h_dest, ETH_ALEN) == 0) - goto found_dest; - } - - return -EINVAL; - - found_dest: - /* find out eapol data & len */ - cmd = kzalloc(sizeof(*cmd) + eapol_len, GFP_KERNEL); - if (!cmd) - return -EINVAL; - - memcpy(cmd->dst_mac, eth->h_dest, ETH_ALEN); - cmd->eapol_len = cpu_to_le16(eapol_len); - memcpy(cmd->eapol, eapol, eapol_len); - rc = wmi_send(wil, WMI_EAPOL_TX_CMDID, cmd, sizeof(*cmd) + eapol_len); - kfree(cmd); - - return rc; -} - -int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index, - const void *mac_addr) -{ - struct wmi_delete_cipher_key_cmd cmd = { - .key_index = key_index, - }; - - if (mac_addr) - memcpy(cmd.mac, mac_addr, WMI_MAC_LEN); - - return wmi_send(wil, WMI_DELETE_CIPHER_KEY_CMDID, &cmd, sizeof(cmd)); -} - -int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index, - const void *mac_addr, int key_len, const void *key) -{ - struct wmi_add_cipher_key_cmd cmd = { - .key_index = key_index, - .key_usage = WMI_KEY_USE_PAIRWISE, - .key_len = key_len, - }; - - if (!key || (key_len > sizeof(cmd.key))) - return -EINVAL; - - memcpy(cmd.key, key, key_len); - if (mac_addr) - memcpy(cmd.mac, mac_addr, WMI_MAC_LEN); - - return wmi_send(wil, WMI_ADD_CIPHER_KEY_CMDID, &cmd, sizeof(cmd)); -} - -int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie) -{ - int rc; - u16 len = sizeof(struct wmi_set_appie_cmd) + ie_len; - struct wmi_set_appie_cmd *cmd = kzalloc(len, GFP_KERNEL); - if (!cmd) { - wil_err(wil, "kmalloc(%d) failed\n", len); - return -ENOMEM; - } - - cmd->mgmt_frm_type = type; - /* BUG: FW API define ieLen as u8. Will fix FW */ - cmd->ie_len = cpu_to_le16(ie_len); - memcpy(cmd->ie_info, ie, ie_len); - rc = wmi_send(wil, WMI_SET_APPIE_CMDID, &cmd, len); - kfree(cmd); - - return rc; -} - -void wmi_event_flush(struct wil6210_priv *wil) -{ - struct pending_wmi_event *evt, *t; - - wil_dbg_WMI(wil, "%s()\n", __func__); - - list_for_each_entry_safe(evt, t, &wil->pending_wmi_ev, list) { - list_del(&evt->list); - kfree(evt); - } -} - -static bool wmi_evt_call_handler(struct wil6210_priv *wil, int id, - void *d, int len) -{ - uint i; - - for (i = 0; i < ARRAY_SIZE(wmi_evt_handlers); i++) { - if (wmi_evt_handlers[i].eventid == id) { - wmi_evt_handlers[i].handler(wil, id, d, len); - return true; - } - } - - return false; -} - -static void wmi_event_handle(struct wil6210_priv *wil, - struct wil6210_mbox_hdr *hdr) -{ - u16 len = le16_to_cpu(hdr->len); - - if ((hdr->type == WIL_MBOX_HDR_TYPE_WMI) && - (len >= sizeof(struct wil6210_mbox_hdr_wmi))) { - struct wil6210_mbox_hdr_wmi *wmi = (void *)(&hdr[1]); - void *evt_data = (void *)(&wmi[1]); - u16 id = le16_to_cpu(wmi->id); - /* check if someone waits for this event */ - if (wil->reply_id && wil->reply_id == id) { - if (wil->reply_buf) { - memcpy(wil->reply_buf, wmi, - min(len, wil->reply_size)); - } else { - wmi_evt_call_handler(wil, id, evt_data, - len - sizeof(*wmi)); - } - wil_dbg_WMI(wil, "Complete WMI 0x%04x\n", id); - complete(&wil->wmi_ready); - return; - } - /* unsolicited event */ - /* search for handler */ - if (!wmi_evt_call_handler(wil, id, evt_data, - len - sizeof(*wmi))) { - wil_err(wil, "Unhandled event 0x%04x\n", id); - } - } else { - wil_err(wil, "Unknown event type\n"); - print_hex_dump(KERN_ERR, "evt?? ", DUMP_PREFIX_OFFSET, 16, 1, - hdr, sizeof(*hdr) + len, true); - } -} - -/* - * Retrieve next WMI event from the pending list - */ -static struct list_head *next_wmi_ev(struct wil6210_priv *wil) -{ - ulong flags; - struct list_head *ret = NULL; - - spin_lock_irqsave(&wil->wmi_ev_lock, flags); - - if (!list_empty(&wil->pending_wmi_ev)) { - ret = wil->pending_wmi_ev.next; - list_del(ret); - } - - spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); - - return ret; -} - -/* - * Handler for the WMI events - */ -void wmi_event_worker(struct work_struct *work) -{ - struct wil6210_priv *wil = container_of(work, struct wil6210_priv, - wmi_event_worker); - struct pending_wmi_event *evt; - struct list_head *lh; - - while ((lh = next_wmi_ev(wil)) != NULL) { - evt = list_entry(lh, struct pending_wmi_event, list); - wmi_event_handle(wil, &evt->event.hdr); - kfree(evt); - } -} - -void wmi_connect_worker(struct work_struct *work) -{ - int rc; - struct wil6210_priv *wil = container_of(work, struct wil6210_priv, - wmi_connect_worker); - - if (wil->pending_connect_cid < 0) { - wil_err(wil, "No connection pending\n"); - return; - } - - wil_dbg_WMI(wil, "Configure for connection CID %d\n", - wil->pending_connect_cid); - - rc = wil_vring_init_tx(wil, 0, WIL6210_TX_RING_SIZE, - wil->pending_connect_cid, 0); - wil->pending_connect_cid = -1; - if (rc == 0) - wil_link_on(wil); -} diff --git a/trunk/drivers/net/wireless/ath/wil6210/wmi.h b/trunk/drivers/net/wireless/ath/wil6210/wmi.h deleted file mode 100644 index 3bbf87572b07..000000000000 --- a/trunk/drivers/net/wireless/ath/wil6210/wmi.h +++ /dev/null @@ -1,1116 +0,0 @@ -/* - * Copyright (c) 2012 Qualcomm Atheros, Inc. - * Copyright (c) 2006-2012 Wilocity . - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * This file contains the definitions of the WMI protocol specified in the - * Wireless Module Interface (WMI) for the Wilocity - * MARLON 60 Gigabit wireless solution. - * It includes definitions of all the commands and events. - * Commands are messages from the host to the WM. - * Events are messages from the WM to the host. - */ - -#ifndef __WILOCITY_WMI_H__ -#define __WILOCITY_WMI_H__ - -/* General */ - -#define WMI_MAC_LEN (6) -#define WMI_PROX_RANGE_NUM (3) - -/* List of Commands */ -enum wmi_command_id { - WMI_CONNECT_CMDID = 0x0001, - WMI_DISCONNECT_CMDID = 0x0003, - WMI_START_SCAN_CMDID = 0x0007, - WMI_SET_BSS_FILTER_CMDID = 0x0009, - WMI_SET_PROBED_SSID_CMDID = 0x000a, - WMI_SET_LISTEN_INT_CMDID = 0x000b, - WMI_BCON_CTRL_CMDID = 0x000f, - WMI_ADD_CIPHER_KEY_CMDID = 0x0016, - WMI_DELETE_CIPHER_KEY_CMDID = 0x0017, - WMI_SET_APPIE_CMDID = 0x003f, - WMI_GET_APPIE_CMDID = 0x0040, - WMI_SET_WSC_STATUS_CMDID = 0x0041, - WMI_PXMT_RANGE_CFG_CMDID = 0x0042, - WMI_PXMT_SNR2_RANGE_CFG_CMDID = 0x0043, - WMI_FAST_MEM_ACC_MODE_CMDID = 0x0300, - WMI_MEM_READ_CMDID = 0x0800, - WMI_MEM_WR_CMDID = 0x0801, - WMI_ECHO_CMDID = 0x0803, - WMI_DEEP_ECHO_CMDID = 0x0804, - WMI_CONFIG_MAC_CMDID = 0x0805, - WMI_CONFIG_PHY_DEBUG_CMDID = 0x0806, - WMI_ADD_STATION_CMDID = 0x0807, - WMI_ADD_DEBUG_TX_PCKT_CMDID = 0x0808, - WMI_PHY_GET_STATISTICS_CMDID = 0x0809, - WMI_FS_TUNE_CMDID = 0x080a, - WMI_CORR_MEASURE_CMDID = 0x080b, - WMI_TEMP_SENSE_CMDID = 0x080e, - WMI_DC_CALIB_CMDID = 0x080f, - WMI_SEND_TONE_CMDID = 0x0810, - WMI_IQ_TX_CALIB_CMDID = 0x0811, - WMI_IQ_RX_CALIB_CMDID = 0x0812, - WMI_SET_UCODE_IDLE_CMDID = 0x0813, - WMI_SET_WORK_MODE_CMDID = 0x0815, - WMI_LO_LEAKAGE_CALIB_CMDID = 0x0816, - WMI_MARLON_R_ACTIVATE_CMDID = 0x0817, - WMI_MARLON_R_READ_CMDID = 0x0818, - WMI_MARLON_R_WRITE_CMDID = 0x0819, - WMI_MARLON_R_TXRX_SEL_CMDID = 0x081a, - MAC_IO_STATIC_PARAMS_CMDID = 0x081b, - MAC_IO_DYNAMIC_PARAMS_CMDID = 0x081c, - WMI_SILENT_RSSI_CALIB_CMDID = 0x081d, - WMI_CFG_RX_CHAIN_CMDID = 0x0820, - WMI_VRING_CFG_CMDID = 0x0821, - WMI_RX_ON_CMDID = 0x0822, - WMI_VRING_BA_EN_CMDID = 0x0823, - WMI_VRING_BA_DIS_CMDID = 0x0824, - WMI_RCP_ADDBA_RESP_CMDID = 0x0825, - WMI_RCP_DELBA_CMDID = 0x0826, - WMI_SET_SSID_CMDID = 0x0827, - WMI_GET_SSID_CMDID = 0x0828, - WMI_SET_PCP_CHANNEL_CMDID = 0x0829, - WMI_GET_PCP_CHANNEL_CMDID = 0x082a, - WMI_SW_TX_REQ_CMDID = 0x082b, - WMI_RX_OFF_CMDID = 0x082c, - WMI_READ_MAC_RXQ_CMDID = 0x0830, - WMI_READ_MAC_TXQ_CMDID = 0x0831, - WMI_WRITE_MAC_RXQ_CMDID = 0x0832, - WMI_WRITE_MAC_TXQ_CMDID = 0x0833, - WMI_WRITE_MAC_XQ_FIELD_CMDID = 0x0834, - WMI_MLME_PUSH_CMDID = 0x0835, - WMI_BEAMFORMING_MGMT_CMDID = 0x0836, - WMI_BF_TXSS_MGMT_CMDID = 0x0837, - WMI_BF_SM_MGMT_CMDID = 0x0838, - WMI_BF_RXSS_MGMT_CMDID = 0x0839, - WMI_SET_SECTORS_CMDID = 0x0849, - WMI_MAINTAIN_PAUSE_CMDID = 0x0850, - WMI_MAINTAIN_RESUME_CMDID = 0x0851, - WMI_RS_MGMT_CMDID = 0x0852, - WMI_RF_MGMT_CMDID = 0x0853, - /* Performance monitoring commands */ - WMI_BF_CTRL_CMDID = 0x0862, - WMI_NOTIFY_REQ_CMDID = 0x0863, - WMI_GET_STATUS_CMDID = 0x0864, - WMI_UNIT_TEST_CMDID = 0x0900, - WMI_HICCUP_CMDID = 0x0901, - WMI_FLASH_READ_CMDID = 0x0902, - WMI_FLASH_WRITE_CMDID = 0x0903, - WMI_SECURITY_UNIT_TEST_CMDID = 0x0904, - - WMI_SET_MAC_ADDRESS_CMDID = 0xf003, - WMI_ABORT_SCAN_CMDID = 0xf007, - WMI_SET_PMK_CMDID = 0xf028, - - WMI_SET_PROMISCUOUS_MODE_CMDID = 0xf041, - WMI_GET_PMK_CMDID = 0xf048, - WMI_SET_PASSPHRASE_CMDID = 0xf049, - WMI_SEND_ASSOC_RES_CMDID = 0xf04a, - WMI_SET_ASSOC_REQ_RELAY_CMDID = 0xf04b, - WMI_EAPOL_TX_CMDID = 0xf04c, - WMI_MAC_ADDR_REQ_CMDID = 0xf04d, - WMI_FW_VER_CMDID = 0xf04e, -}; - -/* - * Commands data structures - */ - -/* - * Frame Types - */ -enum wmi_mgmt_frame_type { - WMI_FRAME_BEACON = 0, - WMI_FRAME_PROBE_REQ = 1, - WMI_FRAME_PROBE_RESP = 2, - WMI_FRAME_ASSOC_REQ = 3, - WMI_FRAME_ASSOC_RESP = 4, - WMI_NUM_MGMT_FRAME, -}; - -/* - * WMI_CONNECT_CMDID - */ -enum wmi_network_type { - WMI_NETTYPE_INFRA = 0x01, - WMI_NETTYPE_ADHOC = 0x02, - WMI_NETTYPE_ADHOC_CREATOR = 0x04, - WMI_NETTYPE_AP = 0x10, - WMI_NETTYPE_P2P = 0x20, - WMI_NETTYPE_WBE = 0x40, /* PCIE over 60g */ -}; - -enum wmi_dot11_auth_mode { - WMI_AUTH11_OPEN = 0x01, - WMI_AUTH11_SHARED = 0x02, - WMI_AUTH11_LEAP = 0x04, - WMI_AUTH11_WSC = 0x08, -}; - -enum wmi_auth_mode { - WMI_AUTH_NONE = 0x01, - WMI_AUTH_WPA = 0x02, - WMI_AUTH_WPA2 = 0x04, - WMI_AUTH_WPA_PSK = 0x08, - WMI_AUTH_WPA2_PSK = 0x10, - WMI_AUTH_WPA_CCKM = 0x20, - WMI_AUTH_WPA2_CCKM = 0x40, -}; - -enum wmi_crypto_type { - WMI_CRYPT_NONE = 0x01, - WMI_CRYPT_WEP = 0x02, - WMI_CRYPT_TKIP = 0x04, - WMI_CRYPT_AES = 0x08, - WMI_CRYPT_AES_GCMP = 0x20, -}; - - -enum wmi_connect_ctrl_flag_bits { - WMI_CONNECT_ASSOC_POLICY_USER = 0x0001, - WMI_CONNECT_SEND_REASSOC = 0x0002, - WMI_CONNECT_IGNORE_WPAx_GROUP_CIPHER = 0x0004, - WMI_CONNECT_PROFILE_MATCH_DONE = 0x0008, - WMI_CONNECT_IGNORE_AAC_BEACON = 0x0010, - WMI_CONNECT_CSA_FOLLOW_BSS = 0x0020, - WMI_CONNECT_DO_WPA_OFFLOAD = 0x0040, - WMI_CONNECT_DO_NOT_DEAUTH = 0x0080, -}; - -#define WMI_MAX_SSID_LEN (32) - -struct wmi_connect_cmd { - u8 network_type; - u8 dot11_auth_mode; - u8 auth_mode; - u8 pairwise_crypto_type; - u8 pairwise_crypto_len; - u8 group_crypto_type; - u8 group_crypto_len; - u8 ssid_len; - u8 ssid[WMI_MAX_SSID_LEN]; - u8 channel; - u8 reserved0; - u8 bssid[WMI_MAC_LEN]; - __le32 ctrl_flags; - u8 dst_mac[WMI_MAC_LEN]; - u8 reserved1[2]; -} __packed; - - -/* - * WMI_RECONNECT_CMDID - */ -struct wmi_reconnect_cmd { - u8 channel; /* hint */ - u8 reserved; - u8 bssid[WMI_MAC_LEN]; /* mandatory if set */ -} __packed; - - -/* - * WMI_SET_PMK_CMDID - */ - -#define WMI_MIN_KEY_INDEX (0) -#define WMI_MAX_KEY_INDEX (3) -#define WMI_MAX_KEY_LEN (32) -#define WMI_PASSPHRASE_LEN (64) -#define WMI_PMK_LEN (32) - -struct wmi_set_pmk_cmd { - u8 pmk[WMI_PMK_LEN]; -} __packed; - - -/* - * WMI_SET_PASSPHRASE_CMDID - */ -struct wmi_set_passphrase_cmd { - u8 ssid[WMI_MAX_SSID_LEN]; - u8 passphrase[WMI_PASSPHRASE_LEN]; - u8 ssid_len; - u8 passphrase_len; -} __packed; - -/* - * WMI_ADD_CIPHER_KEY_CMDID - */ -enum wmi_key_usage { - WMI_KEY_USE_PAIRWISE = 0, - WMI_KEY_USE_GROUP = 1, - WMI_KEY_USE_TX = 2, /* default Tx Key - Static WEP only */ -}; - -struct wmi_add_cipher_key_cmd { - u8 key_index; - u8 key_type; - u8 key_usage; /* enum wmi_key_usage */ - u8 key_len; - u8 key_rsc[8]; /* key replay sequence counter */ - u8 key[WMI_MAX_KEY_LEN]; - u8 key_op_ctrl; /* Additional Key Control information */ - u8 mac[WMI_MAC_LEN]; -} __packed; - -/* - * WMI_DELETE_CIPHER_KEY_CMDID - */ -struct wmi_delete_cipher_key_cmd { - u8 key_index; - u8 mac[WMI_MAC_LEN]; -} __packed; - - -/* - * WMI_START_SCAN_CMDID - * - * Start L1 scan operation - * - * Returned events: - * - WMI_RX_MGMT_PACKET_EVENTID - for every probe resp. - * - WMI_SCAN_COMPLETE_EVENTID - */ -enum wmi_scan_type { - WMI_LONG_SCAN = 0, - WMI_SHORT_SCAN = 1, -}; - -struct wmi_start_scan_cmd { - u8 reserved[8]; - __le32 home_dwell_time; /* Max duration in the home channel(ms) */ - __le32 force_scan_interval; /* Time interval between scans (ms)*/ - u8 scan_type; /* wmi_scan_type */ - u8 num_channels; /* how many channels follow */ - struct { - u8 channel; - u8 reserved; - } channel_list[0]; /* channels ID's */ - /* 0 - 58320 MHz */ - /* 1 - 60480 MHz */ - /* 2 - 62640 MHz */ -} __packed; - -/* - * WMI_SET_PROBED_SSID_CMDID - */ -#define MAX_PROBED_SSID_INDEX (15) - -enum wmi_ssid_flag { - WMI_SSID_FLAG_DISABLE = 0, /* disables entry */ - WMI_SSID_FLAG_SPECIFIC = 1, /* probes specified ssid */ - WMI_SSID_FLAG_ANY = 2, /* probes for any ssid */ -}; - -struct wmi_probed_ssid_cmd { - u8 entry_index; /* 0 to MAX_PROBED_SSID_INDEX */ - u8 flag; /* enum wmi_ssid_flag */ - u8 ssid_len; - u8 ssid[WMI_MAX_SSID_LEN]; -} __packed; - -/* - * WMI_SET_APPIE_CMDID - * Add Application specified IE to a management frame - */ -struct wmi_set_appie_cmd { - u8 mgmt_frm_type; /* enum wmi_mgmt_frame_type */ - u8 reserved; - __le16 ie_len; /* Length of the IE to be added to MGMT frame */ - u8 ie_info[0]; -} __packed; - -#define WMI_MAX_IE_LEN (1024) - -struct wmi_pxmt_range_cfg_cmd { - u8 dst_mac[WMI_MAC_LEN]; - __le16 range; -} __packed; - -struct wmi_pxmt_snr2_range_cfg_cmd { - s8 snr2range_arr[WMI_PROX_RANGE_NUM-1]; -} __packed; - -/* - * WMI_RF_MGMT_CMDID - */ -enum wmi_rf_mgmt_type { - WMI_RF_MGMT_W_DISABLE = 0, - WMI_RF_MGMT_W_ENABLE = 1, - WMI_RF_MGMT_GET_STATUS = 2, -}; - -struct wmi_rf_mgmt_cmd { - __le32 rf_mgmt_type; -} __packed; - -/* - * WMI_SET_SSID_CMDID - */ -struct wmi_set_ssid_cmd { - __le32 ssid_len; - u8 ssid[WMI_MAX_SSID_LEN]; -} __packed; - -/* - * WMI_SET_PCP_CHANNEL_CMDID - */ -struct wmi_set_pcp_channel_cmd { - u8 channel; - u8 reserved[3]; -} __packed; - -/* - * WMI_BCON_CTRL_CMDID - */ -struct wmi_bcon_ctrl_cmd { - __le16 bcon_interval; - __le16 frag_num; - __le64 ss_mask; - u8 network_type; - u8 reserved; - u8 disable_sec_offload; - u8 disable_sec; -} __packed; - -/* - * WMI_SW_TX_REQ_CMDID - */ -struct wmi_sw_tx_req_cmd { - u8 dst_mac[WMI_MAC_LEN]; - __le16 len; - u8 payload[0]; -} __packed; - -/* - * WMI_VRING_CFG_CMDID - */ - -struct wmi_sw_ring_cfg { - __le64 ring_mem_base; - __le16 ring_size; - __le16 max_mpdu_size; -} __packed; - -struct wmi_vring_cfg_schd { - __le16 priority; - __le16 timeslot_us; -} __packed; - -enum wmi_vring_cfg_encap_trans_type { - WMI_VRING_ENC_TYPE_802_3 = 0, - WMI_VRING_ENC_TYPE_NATIVE_WIFI = 1, -}; - -enum wmi_vring_cfg_ds_cfg { - WMI_VRING_DS_PBSS = 0, - WMI_VRING_DS_STATION = 1, - WMI_VRING_DS_AP = 2, - WMI_VRING_DS_ADDR4 = 3, -}; - -enum wmi_vring_cfg_nwifi_ds_trans_type { - WMI_NWIFI_TX_TRANS_MODE_NO = 0, - WMI_NWIFI_TX_TRANS_MODE_AP2PBSS = 1, - WMI_NWIFI_TX_TRANS_MODE_STA2PBSS = 2, -}; - -enum wmi_vring_cfg_schd_params_priority { - WMI_SCH_PRIO_REGULAR = 0, - WMI_SCH_PRIO_HIGH = 1, -}; - -struct wmi_vring_cfg { - struct wmi_sw_ring_cfg tx_sw_ring; - u8 ringid; /* 0-23 vrings */ - - #define CIDXTID_CID_POS (0) - #define CIDXTID_CID_LEN (4) - #define CIDXTID_CID_MSK (0xF) - #define CIDXTID_TID_POS (4) - #define CIDXTID_TID_LEN (4) - #define CIDXTID_TID_MSK (0xF0) - u8 cidxtid; - - u8 encap_trans_type; - u8 ds_cfg; /* 802.3 DS cfg */ - u8 nwifi_ds_trans_type; - - #define VRING_CFG_MAC_CTRL_LIFETIME_EN_POS (0) - #define VRING_CFG_MAC_CTRL_LIFETIME_EN_LEN (1) - #define VRING_CFG_MAC_CTRL_LIFETIME_EN_MSK (0x1) - #define VRING_CFG_MAC_CTRL_AGGR_EN_POS (1) - #define VRING_CFG_MAC_CTRL_AGGR_EN_LEN (1) - #define VRING_CFG_MAC_CTRL_AGGR_EN_MSK (0x2) - u8 mac_ctrl; - - #define VRING_CFG_TO_RESOLUTION_VALUE_POS (0) - #define VRING_CFG_TO_RESOLUTION_VALUE_LEN (6) - #define VRING_CFG_TO_RESOLUTION_VALUE_MSK (0x3F) - u8 to_resolution; - u8 agg_max_wsize; - struct wmi_vring_cfg_schd schd_params; -} __packed; - -enum wmi_vring_cfg_cmd_action { - WMI_VRING_CMD_ADD = 0, - WMI_VRING_CMD_MODIFY = 1, - WMI_VRING_CMD_DELETE = 2, -}; - -struct wmi_vring_cfg_cmd { - __le32 action; - struct wmi_vring_cfg vring_cfg; -} __packed; - -/* - * WMI_VRING_BA_EN_CMDID - */ -struct wmi_vring_ba_en_cmd { - u8 ringid; - u8 agg_max_wsize; - __le16 ba_timeout; -} __packed; - -/* - * WMI_VRING_BA_DIS_CMDID - */ -struct wmi_vring_ba_dis_cmd { - u8 ringid; - u8 reserved; - __le16 reason; -} __packed; - -/* - * WMI_NOTIFY_REQ_CMDID - */ -struct wmi_notify_req_cmd { - u8 cid; - u8 reserved[3]; - __le32 interval_usec; -} __packed; - -/* - * WMI_CFG_RX_CHAIN_CMDID - */ -enum wmi_sniffer_cfg_mode { - WMI_SNIFFER_OFF = 0, - WMI_SNIFFER_ON = 1, -}; - -enum wmi_sniffer_cfg_phy_info_mode { - WMI_SNIFFER_PHY_INFO_DISABLED = 0, - WMI_SNIFFER_PHY_INFO_ENABLED = 1, -}; - -enum wmi_sniffer_cfg_phy_support { - WMI_SNIFFER_CP = 0, - WMI_SNIFFER_DP = 1, - WMI_SNIFFER_BOTH_PHYS = 2, -}; - -struct wmi_sniffer_cfg { - __le32 mode; /* enum wmi_sniffer_cfg_mode */ - __le32 phy_info_mode; /* enum wmi_sniffer_cfg_phy_info_mode */ - __le32 phy_support; /* enum wmi_sniffer_cfg_phy_support */ - u8 channel; - u8 reserved[3]; -} __packed; - -enum wmi_cfg_rx_chain_cmd_action { - WMI_RX_CHAIN_ADD = 0, - WMI_RX_CHAIN_DEL = 1, -}; - -enum wmi_cfg_rx_chain_cmd_decap_trans_type { - WMI_DECAP_TYPE_802_3 = 0, - WMI_DECAP_TYPE_NATIVE_WIFI = 1, -}; - -enum wmi_cfg_rx_chain_cmd_nwifi_ds_trans_type { - WMI_NWIFI_RX_TRANS_MODE_NO = 0, - WMI_NWIFI_RX_TRANS_MODE_PBSS2AP = 1, - WMI_NWIFI_RX_TRANS_MODE_PBSS2STA = 2, -}; - -struct wmi_cfg_rx_chain_cmd { - __le32 action; - struct wmi_sw_ring_cfg rx_sw_ring; - u8 mid; - u8 decap_trans_type; - - #define L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_POS (0) - #define L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_LEN (1) - #define L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_MSK (0x1) - u8 l2_802_3_offload_ctrl; - - #define L2_NWIFI_OFFLOAD_CTRL_REMOVE_QOS_POS (0) - #define L2_NWIFI_OFFLOAD_CTRL_REMOVE_QOS_LEN (1) - #define L2_NWIFI_OFFLOAD_CTRL_REMOVE_QOS_MSK (0x1) - #define L2_NWIFI_OFFLOAD_CTRL_REMOVE_PN_POS (1) - #define L2_NWIFI_OFFLOAD_CTRL_REMOVE_PN_LEN (1) - #define L2_NWIFI_OFFLOAD_CTRL_REMOVE_PN_MSK (0x2) - u8 l2_nwifi_offload_ctrl; - - u8 vlan_id; - u8 nwifi_ds_trans_type; - - #define L3_L4_CTRL_IPV4_CHECKSUM_EN_POS (0) - #define L3_L4_CTRL_IPV4_CHECKSUM_EN_LEN (1) - #define L3_L4_CTRL_IPV4_CHECKSUM_EN_MSK (0x1) - #define L3_L4_CTRL_TCPIP_CHECKSUM_EN_POS (1) - #define L3_L4_CTRL_TCPIP_CHECKSUM_EN_LEN (1) - #define L3_L4_CTRL_TCPIP_CHECKSUM_EN_MSK (0x2) - u8 l3_l4_ctrl; - - #define RING_CTRL_OVERRIDE_PREFETCH_THRSH_POS (0) - #define RING_CTRL_OVERRIDE_PREFETCH_THRSH_LEN (1) - #define RING_CTRL_OVERRIDE_PREFETCH_THRSH_MSK (0x1) - #define RING_CTRL_OVERRIDE_WB_THRSH_POS (1) - #define RING_CTRL_OVERRIDE_WB_THRSH_LEN (1) - #define RING_CTRL_OVERRIDE_WB_THRSH_MSK (0x2) - #define RING_CTRL_OVERRIDE_ITR_THRSH_POS (2) - #define RING_CTRL_OVERRIDE_ITR_THRSH_LEN (1) - #define RING_CTRL_OVERRIDE_ITR_THRSH_MSK (0x4) - #define RING_CTRL_OVERRIDE_HOST_THRSH_POS (3) - #define RING_CTRL_OVERRIDE_HOST_THRSH_LEN (1) - #define RING_CTRL_OVERRIDE_HOST_THRSH_MSK (0x8) - u8 ring_ctrl; - - __le16 prefetch_thrsh; - __le16 wb_thrsh; - __le32 itr_value; - __le16 host_thrsh; - u8 reserved[2]; - struct wmi_sniffer_cfg sniffer_cfg; -} __packed; - -/* - * WMI_RCP_ADDBA_RESP_CMDID - */ -struct wmi_rcp_addba_resp_cmd { - - #define CIDXTID_CID_POS (0) - #define CIDXTID_CID_LEN (4) - #define CIDXTID_CID_MSK (0xF) - #define CIDXTID_TID_POS (4) - #define CIDXTID_TID_LEN (4) - #define CIDXTID_TID_MSK (0xF0) - u8 cidxtid; - - u8 dialog_token; - __le16 status_code; - __le16 ba_param_set; /* ieee80211_ba_parameterset field to send */ - __le16 ba_timeout; -} __packed; - -/* - * WMI_RCP_DELBA_CMDID - */ -struct wmi_rcp_delba_cmd { - - #define CIDXTID_CID_POS (0) - #define CIDXTID_CID_LEN (4) - #define CIDXTID_CID_MSK (0xF) - #define CIDXTID_TID_POS (4) - #define CIDXTID_TID_LEN (4) - #define CIDXTID_TID_MSK (0xF0) - u8 cidxtid; - - u8 reserved; - __le16 reason; -} __packed; - -/* - * WMI_RCP_ADDBA_REQ_CMDID - */ -struct wmi_rcp_addba_req_cmd { - - #define CIDXTID_CID_POS (0) - #define CIDXTID_CID_LEN (4) - #define CIDXTID_CID_MSK (0xF) - #define CIDXTID_TID_POS (4) - #define CIDXTID_TID_LEN (4) - #define CIDXTID_TID_MSK (0xF0) - u8 cidxtid; - - u8 dialog_token; - /* ieee80211_ba_parameterset field as it received */ - __le16 ba_param_set; - __le16 ba_timeout; - /* ieee80211_ba_seqstrl field as it received */ - __le16 ba_seq_ctrl; -} __packed; - -/* - * WMI_SET_MAC_ADDRESS_CMDID - */ -struct wmi_set_mac_address_cmd { - u8 mac[WMI_MAC_LEN]; - u8 reserved[2]; -} __packed; - - -/* -* WMI_EAPOL_TX_CMDID -*/ -struct wmi_eapol_tx_cmd { - u8 dst_mac[WMI_MAC_LEN]; - __le16 eapol_len; - u8 eapol[0]; -} __packed; - -/* - * WMI_ECHO_CMDID - * - * Check FW is alive - * - * WMI_DEEP_ECHO_CMDID - * - * Check FW and ucode are alive - * - * Returned event: WMI_ECHO_RSP_EVENTID - * same event for both commands - */ -struct wmi_echo_cmd { - __le32 value; -} __packed; - -/* - * WMI Events - */ - -/* - * List of Events (target to host) - */ -enum wmi_event_id { - WMI_IMM_RSP_EVENTID = 0x0000, - WMI_READY_EVENTID = 0x1001, - WMI_CONNECT_EVENTID = 0x1002, - WMI_DISCONNECT_EVENTID = 0x1003, - WMI_SCAN_COMPLETE_EVENTID = 0x100a, - WMI_REPORT_STATISTICS_EVENTID = 0x100b, - WMI_RD_MEM_RSP_EVENTID = 0x1800, - WMI_FW_READY_EVENTID = 0x1801, - WMI_EXIT_FAST_MEM_ACC_MODE_EVENTID = 0x0200, - WMI_ECHO_RSP_EVENTID = 0x1803, - WMI_CONFIG_MAC_DONE_EVENTID = 0x1805, - WMI_CONFIG_PHY_DEBUG_DONE_EVENTID = 0x1806, - WMI_ADD_STATION_DONE_EVENTID = 0x1807, - WMI_ADD_DEBUG_TX_PCKT_DONE_EVENTID = 0x1808, - WMI_PHY_GET_STATISTICS_EVENTID = 0x1809, - WMI_FS_TUNE_DONE_EVENTID = 0x180a, - WMI_CORR_MEASURE_DONE_EVENTID = 0x180b, - WMI_TEMP_SENSE_DONE_EVENTID = 0x180e, - WMI_DC_CALIB_DONE_EVENTID = 0x180f, - WMI_IQ_TX_CALIB_DONE_EVENTID = 0x1811, - WMI_IQ_RX_CALIB_DONE_EVENTID = 0x1812, - WMI_SET_WORK_MODE_DONE_EVENTID = 0x1815, - WMI_LO_LEAKAGE_CALIB_DONE_EVENTID = 0x1816, - WMI_MARLON_R_ACTIVATE_DONE_EVENTID = 0x1817, - WMI_MARLON_R_READ_DONE_EVENTID = 0x1818, - WMI_MARLON_R_WRITE_DONE_EVENTID = 0x1819, - WMI_MARLON_R_TXRX_SEL_DONE_EVENTID = 0x181a, - WMI_SILENT_RSSI_CALIB_DONE_EVENTID = 0x181d, - - WMI_CFG_RX_CHAIN_DONE_EVENTID = 0x1820, - WMI_VRING_CFG_DONE_EVENTID = 0x1821, - WMI_RX_ON_DONE_EVENTID = 0x1822, - WMI_BA_STATUS_EVENTID = 0x1823, - WMI_RCP_ADDBA_REQ_EVENTID = 0x1824, - WMI_ADDBA_RESP_SENT_EVENTID = 0x1825, - WMI_DELBA_EVENTID = 0x1826, - WMI_GET_SSID_EVENTID = 0x1828, - WMI_GET_PCP_CHANNEL_EVENTID = 0x182a, - WMI_SW_TX_COMPLETE_EVENTID = 0x182b, - WMI_RX_OFF_DONE_EVENTID = 0x182c, - - WMI_READ_MAC_RXQ_EVENTID = 0x1830, - WMI_READ_MAC_TXQ_EVENTID = 0x1831, - WMI_WRITE_MAC_RXQ_EVENTID = 0x1832, - WMI_WRITE_MAC_TXQ_EVENTID = 0x1833, - WMI_WRITE_MAC_XQ_FIELD_EVENTID = 0x1834, - - WMI_BEAFORMING_MGMT_DONE_EVENTID = 0x1836, - WMI_BF_TXSS_MGMT_DONE_EVENTID = 0x1837, - WMI_BF_RXSS_MGMT_DONE_EVENTID = 0x1839, - WMI_RS_MGMT_DONE_EVENTID = 0x1852, - WMI_RF_MGMT_STATUS_EVENTID = 0x1853, - WMI_BF_SM_MGMT_DONE_EVENTID = 0x1838, - WMI_RX_MGMT_PACKET_EVENTID = 0x1840, - - /* Performance monitoring events */ - WMI_DATA_PORT_OPEN_EVENTID = 0x1860, - WMI_WBE_LINKDOWN_EVENTID = 0x1861, - - WMI_BF_CTRL_DONE_EVENTID = 0x1862, - WMI_NOTIFY_REQ_DONE_EVENTID = 0x1863, - WMI_GET_STATUS_DONE_EVENTID = 0x1864, - - WMI_UNIT_TEST_EVENTID = 0x1900, - WMI_FLASH_READ_DONE_EVENTID = 0x1902, - WMI_FLASH_WRITE_DONE_EVENTID = 0x1903, - - WMI_SET_CHANNEL_EVENTID = 0x9000, - WMI_ASSOC_REQ_EVENTID = 0x9001, - WMI_EAPOL_RX_EVENTID = 0x9002, - WMI_MAC_ADDR_RESP_EVENTID = 0x9003, - WMI_FW_VER_EVENTID = 0x9004, -}; - -/* - * Events data structures - */ - -/* - * WMI_RF_MGMT_STATUS_EVENTID - */ -enum wmi_rf_status { - WMI_RF_ENABLED = 0, - WMI_RF_DISABLED_HW = 1, - WMI_RF_DISABLED_SW = 2, - WMI_RF_DISABLED_HW_SW = 3, -}; - -struct wmi_rf_mgmt_status_event { - __le32 rf_status; -} __packed; - -/* - * WMI_GET_STATUS_DONE_EVENTID - */ -struct wmi_get_status_done_event { - __le32 is_associated; - u8 cid; - u8 reserved0[3]; - u8 bssid[WMI_MAC_LEN]; - u8 channel; - u8 reserved1; - u8 network_type; - u8 reserved2[3]; - __le32 ssid_len; - u8 ssid[WMI_MAX_SSID_LEN]; - __le32 rf_status; - __le32 is_secured; -} __packed; - -/* - * WMI_FW_VER_EVENTID - */ -struct wmi_fw_ver_event { - u8 major; - u8 minor; - __le16 subminor; - __le16 build; -} __packed; - -/* -* WMI_MAC_ADDR_RESP_EVENTID -*/ -struct wmi_mac_addr_resp_event { - u8 mac[WMI_MAC_LEN]; - u8 auth_mode; - u8 crypt_mode; - __le32 offload_mode; -} __packed; - -/* -* WMI_EAPOL_RX_EVENTID -*/ -struct wmi_eapol_rx_event { - u8 src_mac[WMI_MAC_LEN]; - __le16 eapol_len; - u8 eapol[0]; -} __packed; - -/* -* WMI_READY_EVENTID -*/ -enum wmi_phy_capability { - WMI_11A_CAPABILITY = 1, - WMI_11G_CAPABILITY = 2, - WMI_11AG_CAPABILITY = 3, - WMI_11NA_CAPABILITY = 4, - WMI_11NG_CAPABILITY = 5, - WMI_11NAG_CAPABILITY = 6, - WMI_11AD_CAPABILITY = 7, - WMI_11N_CAPABILITY_OFFSET = WMI_11NA_CAPABILITY - WMI_11A_CAPABILITY, -}; - -struct wmi_ready_event { - __le32 sw_version; - __le32 abi_version; - u8 mac[WMI_MAC_LEN]; - u8 phy_capability; /* enum wmi_phy_capability */ - u8 reserved; -} __packed; - -/* - * WMI_NOTIFY_REQ_DONE_EVENTID - */ -struct wmi_notify_req_done_event { - __le32 status; - __le64 tsf; - __le32 snr_val; - __le32 tx_tpt; - __le32 tx_goodput; - __le32 rx_goodput; - __le16 bf_mcs; - __le16 my_rx_sector; - __le16 my_tx_sector; - __le16 other_rx_sector; - __le16 other_tx_sector; - __le16 range; -} __packed; - -/* - * WMI_CONNECT_EVENTID - */ -struct wmi_connect_event { - u8 channel; - u8 reserved0; - u8 bssid[WMI_MAC_LEN]; - __le16 listen_interval; - __le16 beacon_interval; - u8 network_type; - u8 reserved1[3]; - u8 beacon_ie_len; - u8 assoc_req_len; - u8 assoc_resp_len; - u8 cid; - u8 reserved2[3]; - u8 assoc_info[0]; -} __packed; - -/* - * WMI_DISCONNECT_EVENTID - */ -enum wmi_disconnect_reason { - WMI_DIS_REASON_NO_NETWORK_AVAIL = 1, - WMI_DIS_REASON_LOST_LINK = 2, /* bmiss */ - WMI_DIS_REASON_DISCONNECT_CMD = 3, - WMI_DIS_REASON_BSS_DISCONNECTED = 4, - WMI_DIS_REASON_AUTH_FAILED = 5, - WMI_DIS_REASON_ASSOC_FAILED = 6, - WMI_DIS_REASON_NO_RESOURCES_AVAIL = 7, - WMI_DIS_REASON_CSERV_DISCONNECT = 8, - WMI_DIS_REASON_INVALID_PROFILE = 10, - WMI_DIS_REASON_DOT11H_CHANNEL_SWITCH = 11, - WMI_DIS_REASON_PROFILE_MISMATCH = 12, - WMI_DIS_REASON_CONNECTION_EVICTED = 13, - WMI_DIS_REASON_IBSS_MERGE = 14, -}; - -struct wmi_disconnect_event { - __le16 protocol_reason_status; /* reason code, see 802.11 spec. */ - u8 bssid[WMI_MAC_LEN]; /* set if known */ - u8 disconnect_reason; /* see wmi_disconnect_reason_e */ - u8 assoc_resp_len; - u8 assoc_info[0]; -} __packed; - -/* - * WMI_SCAN_COMPLETE_EVENTID - */ -struct wmi_scan_complete_event { - __le32 status; -} __packed; - -/* - * WMI_BA_STATUS_EVENTID - */ -enum wmi_vring_ba_status { - WMI_BA_AGREED = 0, - WMI_BA_NON_AGREED = 1, -}; - -struct wmi_vring_ba_status_event { - __le16 status; - u8 reserved[2]; - u8 ringid; - u8 agg_wsize; - __le16 ba_timeout; -} __packed; - -/* - * WMI_DELBA_EVENTID - */ -struct wmi_delba_event { - - #define CIDXTID_CID_POS (0) - #define CIDXTID_CID_LEN (4) - #define CIDXTID_CID_MSK (0xF) - #define CIDXTID_TID_POS (4) - #define CIDXTID_TID_LEN (4) - #define CIDXTID_TID_MSK (0xF0) - u8 cidxtid; - - u8 from_initiator; - __le16 reason; -} __packed; - -/* - * WMI_VRING_CFG_DONE_EVENTID - */ -enum wmi_vring_cfg_done_event_status { - WMI_VRING_CFG_SUCCESS = 0, - WMI_VRING_CFG_FAILURE = 1, -}; - -struct wmi_vring_cfg_done_event { - u8 ringid; - u8 status; - u8 reserved[2]; - __le32 tx_vring_tail_ptr; -} __packed; - -/* - * WMI_ADDBA_RESP_SENT_EVENTID - */ -enum wmi_rcp_addba_resp_sent_event_status { - WMI_ADDBA_SUCCESS = 0, - WMI_ADDBA_FAIL = 1, -}; - -struct wmi_rcp_addba_resp_sent_event { - - #define CIDXTID_CID_POS (0) - #define CIDXTID_CID_LEN (4) - #define CIDXTID_CID_MSK (0xF) - #define CIDXTID_TID_POS (4) - #define CIDXTID_TID_LEN (4) - #define CIDXTID_TID_MSK (0xF0) - u8 cidxtid; - - u8 reserved; - __le16 status; -} __packed; - -/* - * WMI_RCP_ADDBA_REQ_EVENTID - */ -struct wmi_rcp_addba_req_event { - - #define CIDXTID_CID_POS (0) - #define CIDXTID_CID_LEN (4) - #define CIDXTID_CID_MSK (0xF) - #define CIDXTID_TID_POS (4) - #define CIDXTID_TID_LEN (4) - #define CIDXTID_TID_MSK (0xF0) - u8 cidxtid; - - u8 dialog_token; - __le16 ba_param_set; /* ieee80211_ba_parameterset as it received */ - __le16 ba_timeout; - __le16 ba_seq_ctrl; /* ieee80211_ba_seqstrl field as it received */ -} __packed; - -/* - * WMI_CFG_RX_CHAIN_DONE_EVENTID - */ -enum wmi_cfg_rx_chain_done_event_status { - WMI_CFG_RX_CHAIN_SUCCESS = 1, -}; - -struct wmi_cfg_rx_chain_done_event { - __le32 rx_ring_tail_ptr; /* Rx V-Ring Tail pointer */ - __le32 status; -} __packed; - -/* - * WMI_WBE_LINKDOWN_EVENTID - */ -enum wmi_wbe_link_down_event_reason { - WMI_WBE_REASON_USER_REQUEST = 0, - WMI_WBE_REASON_RX_DISASSOC = 1, - WMI_WBE_REASON_BAD_PHY_LINK = 2, -}; - -struct wmi_wbe_link_down_event { - u8 cid; - u8 reserved[3]; - __le32 reason; -} __packed; - -/* - * WMI_DATA_PORT_OPEN_EVENTID - */ -struct wmi_data_port_open_event { - u8 cid; - u8 reserved[3]; -} __packed; - -/* - * WMI_GET_PCP_CHANNEL_EVENTID - */ -struct wmi_get_pcp_channel_event { - u8 channel; - u8 reserved[3]; -} __packed; - -/* - * WMI_SW_TX_COMPLETE_EVENTID - */ -enum wmi_sw_tx_status { - WMI_TX_SW_STATUS_SUCCESS = 0, - WMI_TX_SW_STATUS_FAILED_NO_RESOURCES = 1, - WMI_TX_SW_STATUS_FAILED_TX = 2, -}; - -struct wmi_sw_tx_complete_event { - u8 status; /* enum wmi_sw_tx_status */ - u8 reserved[3]; -} __packed; - -/* - * WMI_GET_SSID_EVENTID - */ -struct wmi_get_ssid_event { - __le32 ssid_len; - u8 ssid[WMI_MAX_SSID_LEN]; -} __packed; - -/* - * WMI_RX_MGMT_PACKET_EVENTID - */ -struct wmi_rx_mgmt_info { - u8 mcs; - s8 snr; - __le16 range; - __le16 stype; - __le16 status; - __le32 len; - u8 qid; - u8 mid; - u8 cid; - u8 channel; /* From Radio MNGR */ -} __packed; - -struct wmi_rx_mgmt_packet_event { - struct wmi_rx_mgmt_info info; - u8 payload[0]; -} __packed; - -/* - * WMI_ECHO_RSP_EVENTID - */ -struct wmi_echo_event { - __le32 echoed_value; -} __packed; - -#endif /* __WILOCITY_WMI_H__ */ diff --git a/trunk/drivers/net/wireless/b43/b43.h b/trunk/drivers/net/wireless/b43/b43.h index 10e288d470e7..b298e5d68be2 100644 --- a/trunk/drivers/net/wireless/b43/b43.h +++ b/trunk/drivers/net/wireless/b43/b43.h @@ -7,7 +7,6 @@ #include #include #include -#include #include #include "debugfs.h" @@ -723,10 +722,6 @@ enum b43_firmware_file_type { struct b43_request_fw_context { /* The device we are requesting the fw for. */ struct b43_wldev *dev; - /* a completion event structure needed if this call is asynchronous */ - struct completion fw_load_complete; - /* a pointer to the firmware object */ - const struct firmware *blob; /* The type of firmware to request. */ enum b43_firmware_file_type req_type; /* Error messages for each firmware type. */ diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index 806e34c19281..16ab280359bd 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -2088,18 +2088,11 @@ static void b43_print_fw_helptext(struct b43_wl *wl, bool error) b43warn(wl, text); } -static void b43_fw_cb(const struct firmware *firmware, void *context) -{ - struct b43_request_fw_context *ctx = context; - - ctx->blob = firmware; - complete(&ctx->fw_load_complete); -} - int b43_do_request_fw(struct b43_request_fw_context *ctx, const char *name, - struct b43_firmware_file *fw, bool async) + struct b43_firmware_file *fw) { + const struct firmware *blob; struct b43_fw_header *hdr; u32 size; int err; @@ -2138,31 +2131,11 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx, B43_WARN_ON(1); return -ENOSYS; } - if (async) { - /* do this part asynchronously */ - init_completion(&ctx->fw_load_complete); - err = request_firmware_nowait(THIS_MODULE, 1, ctx->fwname, - ctx->dev->dev->dev, GFP_KERNEL, - ctx, b43_fw_cb); - if (err < 0) { - pr_err("Unable to load firmware\n"); - return err; - } - /* stall here until fw ready */ - wait_for_completion(&ctx->fw_load_complete); - if (ctx->blob) - goto fw_ready; - /* On some ARM systems, the async request will fail, but the next sync - * request works. For this reason, we dall through here - */ - } - err = request_firmware(&ctx->blob, ctx->fwname, - ctx->dev->dev->dev); + err = request_firmware(&blob, ctx->fwname, ctx->dev->dev->dev); if (err == -ENOENT) { snprintf(ctx->errors[ctx->req_type], sizeof(ctx->errors[ctx->req_type]), - "Firmware file \"%s\" not found\n", - ctx->fwname); + "Firmware file \"%s\" not found\n", ctx->fwname); return err; } else if (err) { snprintf(ctx->errors[ctx->req_type], @@ -2171,15 +2144,14 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx, ctx->fwname, err); return err; } -fw_ready: - if (ctx->blob->size < sizeof(struct b43_fw_header)) + if (blob->size < sizeof(struct b43_fw_header)) goto err_format; - hdr = (struct b43_fw_header *)(ctx->blob->data); + hdr = (struct b43_fw_header *)(blob->data); switch (hdr->type) { case B43_FW_TYPE_UCODE: case B43_FW_TYPE_PCM: size = be32_to_cpu(hdr->size); - if (size != ctx->blob->size - sizeof(struct b43_fw_header)) + if (size != blob->size - sizeof(struct b43_fw_header)) goto err_format; /* fallthrough */ case B43_FW_TYPE_IV: @@ -2190,7 +2162,7 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx, goto err_format; } - fw->data = ctx->blob; + fw->data = blob; fw->filename = name; fw->type = ctx->req_type; @@ -2200,7 +2172,7 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx, snprintf(ctx->errors[ctx->req_type], sizeof(ctx->errors[ctx->req_type]), "Firmware file \"%s\" format error.\n", ctx->fwname); - release_firmware(ctx->blob); + release_firmware(blob); return -EPROTO; } @@ -2251,7 +2223,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) goto err_no_ucode; } } - err = b43_do_request_fw(ctx, filename, &fw->ucode, true); + err = b43_do_request_fw(ctx, filename, &fw->ucode); if (err) goto err_load; @@ -2263,7 +2235,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) else goto err_no_pcm; fw->pcm_request_failed = false; - err = b43_do_request_fw(ctx, filename, &fw->pcm, false); + err = b43_do_request_fw(ctx, filename, &fw->pcm); if (err == -ENOENT) { /* We did not find a PCM file? Not fatal, but * core rev <= 10 must do without hwcrypto then. */ @@ -2324,7 +2296,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) default: goto err_no_initvals; } - err = b43_do_request_fw(ctx, filename, &fw->initvals, false); + err = b43_do_request_fw(ctx, filename, &fw->initvals); if (err) goto err_load; @@ -2383,7 +2355,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) default: goto err_no_initvals; } - err = b43_do_request_fw(ctx, filename, &fw->initvals_band, false); + err = b43_do_request_fw(ctx, filename, &fw->initvals_band); if (err) goto err_load; diff --git a/trunk/drivers/net/wireless/b43/main.h b/trunk/drivers/net/wireless/b43/main.h index abac25ee958d..8c684cd33529 100644 --- a/trunk/drivers/net/wireless/b43/main.h +++ b/trunk/drivers/net/wireless/b43/main.h @@ -137,8 +137,9 @@ void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on); struct b43_request_fw_context; -int b43_do_request_fw(struct b43_request_fw_context *ctx, const char *name, - struct b43_firmware_file *fw, bool async); +int b43_do_request_fw(struct b43_request_fw_context *ctx, + const char *name, + struct b43_firmware_file *fw); void b43_do_release_fw(struct b43_firmware_file *fw); #endif /* B43_MAIN_H_ */ diff --git a/trunk/drivers/net/wireless/iwlegacy/3945-mac.c b/trunk/drivers/net/wireless/iwlegacy/3945-mac.c index 3726cd6fcd75..d604b4036a76 100644 --- a/trunk/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/trunk/drivers/net/wireless/iwlegacy/3945-mac.c @@ -3273,7 +3273,7 @@ il3945_store_measurement(struct device *d, struct device_attribute *attr, if (count) { char *p = buffer; - strlcpy(buffer, buf, sizeof(buffer)); + strncpy(buffer, buf, min(sizeof(buffer), count)); channel = simple_strtoul(p, NULL, 0); if (channel) params.channel = channel; diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c b/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c index a790599fe2c2..da21328ca8ed 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -1151,6 +1151,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, next_reclaimed = ssn; } + if (tid != IWL_TID_NON_QOS) { + priv->tid_data[sta_id][tid].next_reclaimed = + next_reclaimed; + IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n", + next_reclaimed); + } + iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs); iwlagn_check_ratid_empty(priv, sta_id, tid); @@ -1201,28 +1208,11 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, if (!is_agg) iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); - /* - * W/A for FW bug - the seq_ctl isn't updated when the - * queues are flushed. Fetch it from the packet itself - */ - if (!is_agg && status == TX_STATUS_FAIL_FIFO_FLUSHED) { - next_reclaimed = le16_to_cpu(hdr->seq_ctrl); - next_reclaimed = - SEQ_TO_SN(next_reclaimed + 0x10); - } - is_offchannel_skb = (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN); freed++; } - if (tid != IWL_TID_NON_QOS) { - priv->tid_data[sta_id][tid].next_reclaimed = - next_reclaimed; - IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n", - next_reclaimed); - } - WARN_ON(!is_agg && freed != 1); /* diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c b/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c index 8389cd38338b..dad4c4aad91f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -1166,7 +1166,6 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data) else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && !trans_pcie->inta) iwl_enable_interrupts(trans); - return IRQ_HANDLED; none: /* re-enable interrupts here since we don't have anything to service. */ diff --git a/trunk/drivers/net/wireless/mwifiex/cfg80211.c b/trunk/drivers/net/wireless/mwifiex/cfg80211.c index efe525be27dd..a875499f8945 100644 --- a/trunk/drivers/net/wireless/mwifiex/cfg80211.c +++ b/trunk/drivers/net/wireless/mwifiex/cfg80211.c @@ -1709,7 +1709,7 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv, NL80211_CHAN_NO_HT) config_bands |= BAND_GN; } else { - if (cfg80211_get_chandef_type(¶ms->chandef) == + if (cfg80211_get_chandef_type(¶ms->chandef) != NL80211_CHAN_NO_HT) config_bands = BAND_A; else diff --git a/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c b/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c index 60e88b58039d..cb682561c438 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -56,6 +56,7 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, */ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter) { + bool cancel_flag = false; int status; struct cmd_ctrl_node *cmd_queued; @@ -69,11 +70,14 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter) atomic_inc(&adapter->cmd_pending); /* Wait for completion */ - status = wait_event_interruptible(adapter->cmd_wait_q.wait, - *(cmd_queued->condition)); - if (status) { - dev_err(adapter->dev, "cmd_wait_q terminated: %d\n", status); - return status; + wait_event_interruptible(adapter->cmd_wait_q.wait, + *(cmd_queued->condition)); + if (!*(cmd_queued->condition)) + cancel_flag = true; + + if (cancel_flag) { + mwifiex_cancel_pending_ioctl(adapter); + dev_dbg(adapter->dev, "cmd cancel\n"); } status = adapter->cmd_wait_q.status; @@ -492,11 +496,8 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) return false; } - if (wait_event_interruptible(adapter->hs_activate_wait_q, - adapter->hs_activate_wait_q_woken)) { - dev_err(adapter->dev, "hs_activate_wait_q terminated\n"); - return false; - } + wait_event_interruptible(adapter->hs_activate_wait_q, + adapter->hs_activate_wait_q_woken); return true; } diff --git a/trunk/drivers/net/wireless/mwl8k.c b/trunk/drivers/net/wireless/mwl8k.c index 83564d36e801..f221b95b90b3 100644 --- a/trunk/drivers/net/wireless/mwl8k.c +++ b/trunk/drivers/net/wireless/mwl8k.c @@ -4250,11 +4250,9 @@ static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw, p->amsdu_enabled = 0; rc = mwl8k_post_cmd(hw, &cmd->header); - if (!rc) - rc = p->station_id; kfree(cmd); - return rc; + return rc ? rc : p->station_id; } static int mwl8k_cmd_update_stadb_del(struct ieee80211_hw *hw, diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index 246e5352f2e1..1d5d3604e3e0 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -692,7 +692,7 @@ u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { rtl92c_phy_sw_chnl_callback(hw); RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - "sw_chnl_inprogress false schedule workitem\n"); + "sw_chnl_inprogress false schdule workitem\n"); rtlphy->sw_chnl_inprogress = false; } else { RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c index 3d8536bb0d2b..39cc7938eedf 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c @@ -1106,7 +1106,7 @@ u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw) if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { rtl8723ae_phy_sw_chnl_callback(hw); RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - "sw_chnl_inprogress false schedule workitem\n"); + "sw_chnl_inprogress false schdule workitem\n"); rtlphy->sw_chnl_inprogress = false; } else { RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, diff --git a/trunk/drivers/pci/iov.c b/trunk/drivers/pci/iov.c index c18e5bf444fa..bafd2bbcaf65 100644 --- a/trunk/drivers/pci/iov.c +++ b/trunk/drivers/pci/iov.c @@ -739,7 +739,7 @@ EXPORT_SYMBOL_GPL(pci_num_vf); /** * pci_sriov_set_totalvfs -- reduce the TotalVFs available * @dev: the PCI PF device - * @numvfs: number that should be used for TotalVFs supported + * numvfs: number that should be used for TotalVFs supported * * Should be called from PF driver's probe routine with * device's mutex held. diff --git a/trunk/drivers/platform/x86/acer-wmi.c b/trunk/drivers/platform/x86/acer-wmi.c index afed7018a2b5..06f4eb7ab87e 100644 --- a/trunk/drivers/platform/x86/acer-wmi.c +++ b/trunk/drivers/platform/x86/acer-wmi.c @@ -125,11 +125,8 @@ static const struct key_entry acer_wmi_keymap[] = { {KE_IGNORE, 0x63, {KEY_BRIGHTNESSDOWN} }, {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */ {KE_IGNORE, 0x81, {KEY_SLEEP} }, - {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad Toggle */ - {KE_KEY, KEY_TOUCHPAD_ON, {KEY_TOUCHPAD_ON} }, - {KE_KEY, KEY_TOUCHPAD_OFF, {KEY_TOUCHPAD_OFF} }, + {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad On/Off */ {KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} }, - {KE_KEY, 0x85, {KEY_TOUCHPAD_TOGGLE} }, {KE_END, 0} }; @@ -150,7 +147,6 @@ struct event_return_value { #define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */ #define ACER_WMID3_GDS_WIMAX (1<<7) /* WiMAX */ #define ACER_WMID3_GDS_BLUETOOTH (1<<11) /* BT */ -#define ACER_WMID3_GDS_TOUCHPAD (1<<1) /* Touchpad */ struct lm_input_params { u8 function_num; /* Function Number */ @@ -879,7 +875,7 @@ WMI_execute_u32(u32 method_id, u32 in, u32 *out) struct acpi_buffer input = { (acpi_size) sizeof(u32), (void *)(&in) }; struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; - u32 tmp = 0; + u32 tmp; acpi_status status; status = wmi_evaluate_method(WMID_GUID1, 1, method_id, &input, &result); @@ -888,14 +884,14 @@ WMI_execute_u32(u32 method_id, u32 in, u32 *out) return status; obj = (union acpi_object *) result.pointer; - if (obj) { - if (obj->type == ACPI_TYPE_BUFFER && - (obj->buffer.length == sizeof(u32) || - obj->buffer.length == sizeof(u64))) { - tmp = *((u32 *) obj->buffer.pointer); - } else if (obj->type == ACPI_TYPE_INTEGER) { - tmp = (u32) obj->integer.value; - } + if (obj && obj->type == ACPI_TYPE_BUFFER && + (obj->buffer.length == sizeof(u32) || + obj->buffer.length == sizeof(u64))) { + tmp = *((u32 *) obj->buffer.pointer); + } else if (obj->type == ACPI_TYPE_INTEGER) { + tmp = (u32) obj->integer.value; + } else { + tmp = 0; } if (out) @@ -1197,14 +1193,12 @@ static acpi_status WMID_set_capabilities(void) return status; obj = (union acpi_object *) out.pointer; - if (obj) { - if (obj->type == ACPI_TYPE_BUFFER && - (obj->buffer.length == sizeof(u32) || - obj->buffer.length == sizeof(u64))) { - devices = *((u32 *) obj->buffer.pointer); - } else if (obj->type == ACPI_TYPE_INTEGER) { - devices = (u32) obj->integer.value; - } + if (obj && obj->type == ACPI_TYPE_BUFFER && + (obj->buffer.length == sizeof(u32) || + obj->buffer.length == sizeof(u64))) { + devices = *((u32 *) obj->buffer.pointer); + } else if (obj->type == ACPI_TYPE_INTEGER) { + devices = (u32) obj->integer.value; } else { kfree(out.pointer); return AE_ERROR; @@ -1682,7 +1676,6 @@ static void acer_wmi_notify(u32 value, void *context) acpi_status status; u16 device_state; const struct key_entry *key; - u32 scancode; status = wmi_get_event_data(value, &response); if (status != AE_OK) { @@ -1719,7 +1712,6 @@ static void acer_wmi_notify(u32 value, void *context) pr_warn("Unknown key number - 0x%x\n", return_value.key_num); } else { - scancode = return_value.key_num; switch (key->keycode) { case KEY_WLAN: case KEY_BLUETOOTH: @@ -1733,11 +1725,9 @@ static void acer_wmi_notify(u32 value, void *context) rfkill_set_sw_state(bluetooth_rfkill, !(device_state & ACER_WMID3_GDS_BLUETOOTH)); break; - case KEY_TOUCHPAD_TOGGLE: - scancode = (device_state & ACER_WMID3_GDS_TOUCHPAD) ? - KEY_TOUCHPAD_ON : KEY_TOUCHPAD_OFF; } - sparse_keymap_report_event(acer_wmi_input_dev, scancode, 1, true); + sparse_keymap_report_entry(acer_wmi_input_dev, key, + 1, true); } break; case WMID_ACCEL_EVENT: @@ -1956,14 +1946,12 @@ static u32 get_wmid_devices(void) return 0; obj = (union acpi_object *) out.pointer; - if (obj) { - if (obj->type == ACPI_TYPE_BUFFER && - (obj->buffer.length == sizeof(u32) || - obj->buffer.length == sizeof(u64))) { - devices = *((u32 *) obj->buffer.pointer); - } else if (obj->type == ACPI_TYPE_INTEGER) { - devices = (u32) obj->integer.value; - } + if (obj && obj->type == ACPI_TYPE_BUFFER && + (obj->buffer.length == sizeof(u32) || + obj->buffer.length == sizeof(u64))) { + devices = *((u32 *) obj->buffer.pointer); + } else if (obj->type == ACPI_TYPE_INTEGER) { + devices = (u32) obj->integer.value; } kfree(out.pointer); diff --git a/trunk/drivers/platform/x86/asus-laptop.c b/trunk/drivers/platform/x86/asus-laptop.c index fcde4e528819..ec1d3bc2dbe2 100644 --- a/trunk/drivers/platform/x86/asus-laptop.c +++ b/trunk/drivers/platform/x86/asus-laptop.c @@ -860,10 +860,8 @@ static ssize_t show_infos(struct device *dev, /* * The HWRS method return informations about the hardware. * 0x80 bit is for WLAN, 0x100 for Bluetooth. - * 0x40 for WWAN, 0x10 for WIMAX. * The significance of others is yet to be found. - * We don't currently use this for device detection, and it - * takes several seconds to run on some systems. + * If we don't find the method, we assume the device are present. */ rv = acpi_evaluate_integer(asus->handle, "HWRS", NULL, &temp); if (!ACPI_FAILURE(rv)) @@ -1684,7 +1682,7 @@ static int asus_laptop_get_info(struct asus_laptop *asus) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *model = NULL; - unsigned long long bsts_result; + unsigned long long bsts_result, hwrs_result; char *string = NULL; acpi_status status; @@ -1743,9 +1741,20 @@ static int asus_laptop_get_info(struct asus_laptop *asus) return -ENOMEM; } - if (string) + if (*string) pr_notice(" %s model detected\n", string); + /* + * The HWRS method return informations about the hardware. + * 0x80 bit is for WLAN, 0x100 for Bluetooth, + * 0x40 for WWAN, 0x10 for WIMAX. + * The significance of others is yet to be found. + */ + status = + acpi_evaluate_integer(asus->handle, "HWRS", NULL, &hwrs_result); + if (!ACPI_FAILURE(status)) + pr_notice(" HWRS returned %x", (int)hwrs_result); + if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL)) asus->have_rsts = true; diff --git a/trunk/drivers/platform/x86/samsung-laptop.c b/trunk/drivers/platform/x86/samsung-laptop.c index 71623a2ff3e8..dd90d15f5210 100644 --- a/trunk/drivers/platform/x86/samsung-laptop.c +++ b/trunk/drivers/platform/x86/samsung-laptop.c @@ -1523,16 +1523,6 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .driver_data = &samsung_broken_acpi_video, }, - { - .callback = samsung_dmi_matched, - .ident = "N250P", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "N250P"), - DMI_MATCH(DMI_BOARD_NAME, "N250P"), - }, - .driver_data = &samsung_broken_acpi_video, - }, { }, }; MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); diff --git a/trunk/drivers/platform/x86/sony-laptop.c b/trunk/drivers/platform/x86/sony-laptop.c index b8ad71f7863f..daaddec68def 100644 --- a/trunk/drivers/platform/x86/sony-laptop.c +++ b/trunk/drivers/platform/x86/sony-laptop.c @@ -786,29 +786,28 @@ static int sony_nc_int_call(acpi_handle handle, char *name, int *value, static int sony_nc_buffer_call(acpi_handle handle, char *name, u64 *value, void *buffer, size_t buflen) { - int ret = 0; size_t len = len; union acpi_object *object = __call_snc_method(handle, name, value); if (!object) return -EINVAL; - if (object->type == ACPI_TYPE_BUFFER) { + if (object->type == ACPI_TYPE_BUFFER) len = MIN(buflen, object->buffer.length); - memcpy(buffer, object->buffer.pointer, len); - } else if (object->type == ACPI_TYPE_INTEGER) { + else if (object->type == ACPI_TYPE_INTEGER) len = MIN(buflen, sizeof(object->integer.value)); - memcpy(buffer, &object->integer.value, len); - } else { + else { pr_warn("Invalid acpi_object: expected 0x%x got 0x%x\n", ACPI_TYPE_BUFFER, object->type); - ret = -EINVAL; + kfree(object); + return -EINVAL; } + memcpy(buffer, object->buffer.pointer, len); kfree(object); - return ret; + return 0; } struct sony_nc_handles { diff --git a/trunk/drivers/rtc/rtc-da9055.c b/trunk/drivers/rtc/rtc-da9055.c index 8f0dcfedb83c..96bafc5c3bf8 100644 --- a/trunk/drivers/rtc/rtc-da9055.c +++ b/trunk/drivers/rtc/rtc-da9055.c @@ -227,7 +227,7 @@ static const struct rtc_class_ops da9055_rtc_ops = { .alarm_irq_enable = da9055_rtc_alarm_irq_enable, }; -static int da9055_rtc_device_init(struct da9055 *da9055, +static int __init da9055_rtc_device_init(struct da9055 *da9055, struct da9055_pdata *pdata) { int ret; diff --git a/trunk/drivers/s390/block/dasd_diag.c b/trunk/drivers/s390/block/dasd_diag.c index 704488d0f819..9bd5da36f99e 100644 --- a/trunk/drivers/s390/block/dasd_diag.c +++ b/trunk/drivers/s390/block/dasd_diag.c @@ -248,7 +248,7 @@ static void dasd_ext_handler(struct ext_code ext_code, default: return; } - inc_irq_stat(IRQEXT_DSD); + kstat_cpu(smp_processor_id()).irqs[EXTINT_DSD]++; if (!ip) { /* no intparm: unsolicited interrupt */ DBF_EVENT(DBF_NOTICE, "%s", "caught unsolicited " "interrupt"); diff --git a/trunk/drivers/s390/block/dasd_eckd.c b/trunk/drivers/s390/block/dasd_eckd.c index e37bc1620d14..806fe912d6e7 100644 --- a/trunk/drivers/s390/block/dasd_eckd.c +++ b/trunk/drivers/s390/block/dasd_eckd.c @@ -4274,7 +4274,7 @@ static struct ccw_driver dasd_eckd_driver = { .thaw = dasd_generic_restore_device, .restore = dasd_generic_restore_device, .uc_handler = dasd_generic_uc_handler, - .int_class = IRQIO_DAS, + .int_class = IOINT_DAS, }; /* diff --git a/trunk/drivers/s390/block/dasd_fba.c b/trunk/drivers/s390/block/dasd_fba.c index 414698584344..eb748507c7fa 100644 --- a/trunk/drivers/s390/block/dasd_fba.c +++ b/trunk/drivers/s390/block/dasd_fba.c @@ -78,7 +78,7 @@ static struct ccw_driver dasd_fba_driver = { .freeze = dasd_generic_pm_freeze, .thaw = dasd_generic_restore_device, .restore = dasd_generic_restore_device, - .int_class = IRQIO_DAS, + .int_class = IOINT_DAS, }; static void diff --git a/trunk/drivers/s390/char/con3215.c b/trunk/drivers/s390/char/con3215.c index 33b7141a182f..40084501c31b 100644 --- a/trunk/drivers/s390/char/con3215.c +++ b/trunk/drivers/s390/char/con3215.c @@ -44,7 +44,6 @@ #define RAW3215_NR_CCWS 3 #define RAW3215_TIMEOUT HZ/10 /* time for delayed output */ -#define RAW3215_FIXED 1 /* 3215 console device is not be freed */ #define RAW3215_WORKING 4 /* set if a request is being worked on */ #define RAW3215_THROTTLED 8 /* set if reading is disabled */ #define RAW3215_STOPPED 16 /* set if writing is disabled */ @@ -631,8 +630,7 @@ static void raw3215_shutdown(struct raw3215_info *raw) DECLARE_WAITQUEUE(wait, current); unsigned long flags; - if (!(raw->port.flags & ASYNC_INITIALIZED) || - (raw->flags & RAW3215_FIXED)) + if (!(raw->port.flags & ASYNC_INITIALIZED)) return; /* Wait for outstanding requests, then free irq */ spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); @@ -807,7 +805,7 @@ static struct ccw_driver raw3215_ccw_driver = { .freeze = &raw3215_pm_stop, .thaw = &raw3215_pm_start, .restore = &raw3215_pm_start, - .int_class = IRQIO_C15, + .int_class = IOINT_C15, }; #ifdef CONFIG_TN3215_CONSOLE @@ -929,8 +927,6 @@ static int __init con3215_init(void) dev_set_drvdata(&cdev->dev, raw); cdev->handler = raw3215_irq; - raw->flags |= RAW3215_FIXED; - /* Request the console irq */ if (raw3215_startup(raw) != 0) { raw3215_free_info(raw); diff --git a/trunk/drivers/s390/char/raw3270.c b/trunk/drivers/s390/char/raw3270.c index 9a6c140c5f07..f3b8bb84faf2 100644 --- a/trunk/drivers/s390/char/raw3270.c +++ b/trunk/drivers/s390/char/raw3270.c @@ -1396,7 +1396,7 @@ static struct ccw_driver raw3270_ccw_driver = { .freeze = &raw3270_pm_stop, .thaw = &raw3270_pm_start, .restore = &raw3270_pm_start, - .int_class = IRQIO_C70, + .int_class = IOINT_C70, }; static int diff --git a/trunk/drivers/s390/char/sclp.c b/trunk/drivers/s390/char/sclp.c index 12c16a65dd25..4fa21f7e2308 100644 --- a/trunk/drivers/s390/char/sclp.c +++ b/trunk/drivers/s390/char/sclp.c @@ -400,7 +400,7 @@ static void sclp_interrupt_handler(struct ext_code ext_code, u32 finished_sccb; u32 evbuf_pending; - inc_irq_stat(IRQEXT_SCP); + kstat_cpu(smp_processor_id()).irqs[EXTINT_SCP]++; spin_lock(&sclp_lock); finished_sccb = param32 & 0xfffffff8; evbuf_pending = param32 & 0x3; @@ -813,7 +813,7 @@ static void sclp_check_handler(struct ext_code ext_code, { u32 finished_sccb; - inc_irq_stat(IRQEXT_SCP); + kstat_cpu(smp_processor_id()).irqs[EXTINT_SCP]++; finished_sccb = param32 & 0xfffffff8; /* Is this the interrupt we are waiting for? */ if (finished_sccb == 0) diff --git a/trunk/drivers/s390/char/tape_34xx.c b/trunk/drivers/s390/char/tape_34xx.c index 9aa79702b370..6ae929c024ae 100644 --- a/trunk/drivers/s390/char/tape_34xx.c +++ b/trunk/drivers/s390/char/tape_34xx.c @@ -1193,7 +1193,7 @@ static struct ccw_driver tape_34xx_driver = { .set_online = tape_34xx_online, .set_offline = tape_generic_offline, .freeze = tape_generic_pm_suspend, - .int_class = IRQIO_TAP, + .int_class = IOINT_TAP, }; static int diff --git a/trunk/drivers/s390/char/tape_3590.c b/trunk/drivers/s390/char/tape_3590.c index 327cb19ad0b0..1b0eb49f739c 100644 --- a/trunk/drivers/s390/char/tape_3590.c +++ b/trunk/drivers/s390/char/tape_3590.c @@ -1656,7 +1656,7 @@ static struct ccw_driver tape_3590_driver = { .set_offline = tape_generic_offline, .set_online = tape_3590_online, .freeze = tape_generic_pm_suspend, - .int_class = IRQIO_TAP, + .int_class = IOINT_TAP, }; /* diff --git a/trunk/drivers/s390/char/vmur.c b/trunk/drivers/s390/char/vmur.c index 483f72ba030d..73bef0bd394c 100644 --- a/trunk/drivers/s390/char/vmur.c +++ b/trunk/drivers/s390/char/vmur.c @@ -74,7 +74,7 @@ static struct ccw_driver ur_driver = { .set_online = ur_set_online, .set_offline = ur_set_offline, .freeze = ur_pm_suspend, - .int_class = IRQIO_VMR, + .int_class = IOINT_VMR, }; static DEFINE_MUTEX(vmur_mutex); diff --git a/trunk/drivers/s390/cio/chsc_sch.c b/trunk/drivers/s390/cio/chsc_sch.c index facdf809113f..8f9a1a384496 100644 --- a/trunk/drivers/s390/cio/chsc_sch.c +++ b/trunk/drivers/s390/cio/chsc_sch.c @@ -58,7 +58,7 @@ static void chsc_subchannel_irq(struct subchannel *sch) CHSC_LOG(4, "irb"); CHSC_LOG_HEX(4, irb, sizeof(*irb)); - inc_irq_stat(IRQIO_CSC); + kstat_cpu(smp_processor_id()).irqs[IOINT_CSC]++; /* Copy irb to provided request and set done. */ if (!request) { diff --git a/trunk/drivers/s390/cio/cio.c b/trunk/drivers/s390/cio/cio.c index c8faf6230b0f..8e927b9f285f 100644 --- a/trunk/drivers/s390/cio/cio.c +++ b/trunk/drivers/s390/cio/cio.c @@ -611,7 +611,7 @@ void __irq_entry do_IRQ(struct pt_regs *regs) tpi_info = (struct tpi_info *)&S390_lowcore.subchannel_id; irb = (struct irb *)&S390_lowcore.irb; do { - kstat_incr_irqs_this_cpu(IO_INTERRUPT, NULL); + kstat_cpu(smp_processor_id()).irqs[IO_INTERRUPT]++; if (tpi_info->adapter_IO) { do_adapter_IO(tpi_info->isc); continue; @@ -619,7 +619,7 @@ void __irq_entry do_IRQ(struct pt_regs *regs) sch = (struct subchannel *)(unsigned long)tpi_info->intparm; if (!sch) { /* Clear pending interrupt condition. */ - inc_irq_stat(IRQIO_CIO); + kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; tsch(tpi_info->schid, irb); continue; } @@ -633,9 +633,9 @@ void __irq_entry do_IRQ(struct pt_regs *regs) if (sch->driver && sch->driver->irq) sch->driver->irq(sch); else - inc_irq_stat(IRQIO_CIO); + kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; } else - inc_irq_stat(IRQIO_CIO); + kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; spin_unlock(sch->lock); /* * Are more interrupts pending? @@ -678,7 +678,7 @@ static void cio_tsch(struct subchannel *sch) if (sch->driver && sch->driver->irq) sch->driver->irq(sch); else - inc_irq_stat(IRQIO_CIO); + kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; if (!irq_context) { irq_exit(); _local_bh_enable(); diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index 7cd5c6812ac7..6995cff44636 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -758,7 +758,7 @@ static int io_subchannel_initialize_dev(struct subchannel *sch, struct ccw_device *cdev) { cdev->private->cdev = cdev; - cdev->private->int_class = IRQIO_CIO; + cdev->private->int_class = IOINT_CIO; atomic_set(&cdev->private->onoff, 0); cdev->dev.parent = &sch->dev; cdev->dev.release = ccw_device_release; @@ -1023,7 +1023,7 @@ static void io_subchannel_irq(struct subchannel *sch) if (cdev) dev_fsm_event(cdev, DEV_EVENT_INTERRUPT); else - inc_irq_stat(IRQIO_CIO); + kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; } void io_subchannel_init_config(struct subchannel *sch) @@ -1634,7 +1634,7 @@ ccw_device_probe_console(void) memset(&console_private, 0, sizeof(struct ccw_device_private)); console_cdev.private = &console_private; console_private.cdev = &console_cdev; - console_private.int_class = IRQIO_CIO; + console_private.int_class = IOINT_CIO; ret = ccw_device_console_enable(&console_cdev, sch); if (ret) { cio_release_console(); @@ -1715,13 +1715,13 @@ ccw_device_probe (struct device *dev) if (cdrv->int_class != 0) cdev->private->int_class = cdrv->int_class; else - cdev->private->int_class = IRQIO_CIO; + cdev->private->int_class = IOINT_CIO; ret = cdrv->probe ? cdrv->probe(cdev) : -ENODEV; if (ret) { cdev->drv = NULL; - cdev->private->int_class = IRQIO_CIO; + cdev->private->int_class = IOINT_CIO; return ret; } @@ -1755,7 +1755,7 @@ ccw_device_remove (struct device *dev) } ccw_device_set_timeout(cdev, 0); cdev->drv = NULL; - cdev->private->int_class = IRQIO_CIO; + cdev->private->int_class = IOINT_CIO; return 0; } diff --git a/trunk/drivers/s390/cio/device.h b/trunk/drivers/s390/cio/device.h index 7d4ecb65db00..2e575cff9845 100644 --- a/trunk/drivers/s390/cio/device.h +++ b/trunk/drivers/s390/cio/device.h @@ -61,10 +61,11 @@ dev_fsm_event(struct ccw_device *cdev, enum dev_event dev_event) if (dev_event == DEV_EVENT_INTERRUPT) { if (state == DEV_STATE_ONLINE) - inc_irq_stat(cdev->private->int_class); + kstat_cpu(smp_processor_id()). + irqs[cdev->private->int_class]++; else if (state != DEV_STATE_CMFCHANGE && state != DEV_STATE_CMFUPDATE) - inc_irq_stat(IRQIO_CIO); + kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; } dev_jumptable[state][dev_event](cdev, dev_event); } diff --git a/trunk/drivers/s390/cio/eadm_sch.c b/trunk/drivers/s390/cio/eadm_sch.c index d9eddcba7e88..6c9673400464 100644 --- a/trunk/drivers/s390/cio/eadm_sch.c +++ b/trunk/drivers/s390/cio/eadm_sch.c @@ -139,7 +139,7 @@ static void eadm_subchannel_irq(struct subchannel *sch) EADM_LOG(6, "irq"); EADM_LOG_HEX(6, irb, sizeof(*irb)); - inc_irq_stat(IRQIO_ADM); + kstat_cpu(smp_processor_id()).irqs[IOINT_ADM]++; if ((scsw->stctl & (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)) && scsw->eswf == 1 && irb->esw.eadm.erw.r) diff --git a/trunk/drivers/s390/cio/qdio_thinint.c b/trunk/drivers/s390/cio/qdio_thinint.c index bde5255200dc..bdb394b066fc 100644 --- a/trunk/drivers/s390/cio/qdio_thinint.c +++ b/trunk/drivers/s390/cio/qdio_thinint.c @@ -182,7 +182,7 @@ static void tiqdio_thinint_handler(void *alsi, void *data) struct qdio_q *q; last_ai_time = S390_lowcore.int_clock; - inc_irq_stat(IRQIO_QAI); + kstat_cpu(smp_processor_id()).irqs[IOINT_QAI]++; /* protect tiq_list entries, only changed in activate or shutdown */ rcu_read_lock(); diff --git a/trunk/drivers/s390/crypto/ap_bus.c b/trunk/drivers/s390/crypto/ap_bus.c index b8b340ac5332..7b865a7300e6 100644 --- a/trunk/drivers/s390/crypto/ap_bus.c +++ b/trunk/drivers/s390/crypto/ap_bus.c @@ -1272,7 +1272,7 @@ static int ap_probe_device_type(struct ap_device *ap_dev) static void ap_interrupt_handler(void *unused1, void *unused2) { - inc_irq_stat(IRQIO_APB); + kstat_cpu(smp_processor_id()).irqs[IOINT_APB]++; tasklet_schedule(&ap_tasklet); } diff --git a/trunk/drivers/s390/kvm/kvm_virtio.c b/trunk/drivers/s390/kvm/kvm_virtio.c index 8491111aec12..7dabef624da3 100644 --- a/trunk/drivers/s390/kvm/kvm_virtio.c +++ b/trunk/drivers/s390/kvm/kvm_virtio.c @@ -392,7 +392,7 @@ static void kvm_extint_handler(struct ext_code ext_code, if ((ext_code.subcode & 0xff00) != VIRTIO_SUBCODE_64) return; - inc_irq_stat(IRQEXT_VRT); + kstat_cpu(smp_processor_id()).irqs[EXTINT_VRT]++; /* The LSB might be overloaded, we have to mask it */ vq = (struct virtqueue *)(param64 & ~1UL); diff --git a/trunk/drivers/s390/net/claw.c b/trunk/drivers/s390/net/claw.c index 83bc9c5fa0c1..5c70a6599578 100644 --- a/trunk/drivers/s390/net/claw.c +++ b/trunk/drivers/s390/net/claw.c @@ -282,7 +282,7 @@ static struct ccw_driver claw_ccw_driver = { .ids = claw_ids, .probe = ccwgroup_probe_ccwdev, .remove = ccwgroup_remove_ccwdev, - .int_class = IRQIO_CLW, + .int_class = IOINT_CLW, }; static ssize_t claw_driver_group_store(struct device_driver *ddrv, diff --git a/trunk/drivers/s390/net/ctcm_main.c b/trunk/drivers/s390/net/ctcm_main.c index 676f12049a36..817b68925ddd 100644 --- a/trunk/drivers/s390/net/ctcm_main.c +++ b/trunk/drivers/s390/net/ctcm_main.c @@ -1755,7 +1755,7 @@ static struct ccw_driver ctcm_ccw_driver = { .ids = ctcm_ids, .probe = ccwgroup_probe_ccwdev, .remove = ccwgroup_remove_ccwdev, - .int_class = IRQIO_CTC, + .int_class = IOINT_CTC, }; static struct ccwgroup_driver ctcm_group_driver = { diff --git a/trunk/drivers/s390/net/lcs.c b/trunk/drivers/s390/net/lcs.c index c645dc9e98af..2ca0f1dd7a00 100644 --- a/trunk/drivers/s390/net/lcs.c +++ b/trunk/drivers/s390/net/lcs.c @@ -2384,7 +2384,7 @@ static struct ccw_driver lcs_ccw_driver = { .ids = lcs_ids, .probe = ccwgroup_probe_ccwdev, .remove = ccwgroup_remove_ccwdev, - .int_class = IRQIO_LCS, + .int_class = IOINT_LCS, }; /** diff --git a/trunk/drivers/video/ssd1307fb.c b/trunk/drivers/video/ssd1307fb.c index 395cb6a8d8f3..4d99dd7a6831 100644 --- a/trunk/drivers/video/ssd1307fb.c +++ b/trunk/drivers/video/ssd1307fb.c @@ -145,8 +145,8 @@ static void ssd1307fb_update_display(struct ssd1307fb_par *par) u32 page_length = SSD1307FB_WIDTH * i; u32 index = page_length + (SSD1307FB_WIDTH * k + j) / 8; u8 byte = *(vmem + index); - u8 bit = byte & (1 << (j % 8)); - bit = bit >> (j % 8); + u8 bit = byte & (1 << (7 - (j % 8))); + bit = bit >> (7 - (j % 8)); buf |= bit << k; } ssd1307fb_write_data(par->client, buf); diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 20df02c1cc70..18c45cac368f 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -434,9 +434,8 @@ static int count(struct user_arg_ptr argv, int max) if (IS_ERR(p)) return -EFAULT; - if (i >= max) + if (i++ >= max) return -E2BIG; - ++i; if (fatal_signal_pending(current)) return -ERESTARTNOHAND; diff --git a/trunk/fs/seq_file.c b/trunk/fs/seq_file.c index f2bc3dfd0b88..9d863fb501f9 100644 --- a/trunk/fs/seq_file.c +++ b/trunk/fs/seq_file.c @@ -296,7 +296,7 @@ EXPORT_SYMBOL(seq_read); * seq_lseek - ->llseek() method for sequential files. * @file: the file in question * @offset: new position - * @whence: 0 for absolute, 1 for relative position + * @origin: 0 for absolute, 1 for relative position * * Ready-made ->f_op->llseek() */ diff --git a/trunk/include/drm/drm_mm.h b/trunk/include/drm/drm_mm.h index 3527fb3f75bb..0f4a366f6fa6 100644 --- a/trunk/include/drm/drm_mm.h +++ b/trunk/include/drm/drm_mm.h @@ -70,7 +70,7 @@ struct drm_mm { unsigned long scan_color; unsigned long scan_size; unsigned long scan_hit_start; - unsigned long scan_hit_end; + unsigned scan_hit_size; unsigned scanned_blocks; unsigned long scan_start; unsigned long scan_end; diff --git a/trunk/include/linux/audit.h b/trunk/include/linux/audit.h index 5a6d718adf34..bce729afbcf9 100644 --- a/trunk/include/linux/audit.h +++ b/trunk/include/linux/audit.h @@ -24,7 +24,6 @@ #define _LINUX_AUDIT_H_ #include -#include #include struct audit_sig_info { @@ -158,8 +157,7 @@ void audit_core_dumps(long signr); static inline void audit_seccomp(unsigned long syscall, long signr, int code) { - /* Force a record to be reported if a signal was delivered. */ - if (signr || unlikely(!audit_dummy_context())) + if (unlikely(!audit_dummy_context())) __audit_seccomp(syscall, signr, code); } diff --git a/trunk/include/linux/compaction.h b/trunk/include/linux/compaction.h index cc7bddeaf553..6ecb6dc2f303 100644 --- a/trunk/include/linux/compaction.h +++ b/trunk/include/linux/compaction.h @@ -22,7 +22,7 @@ extern int sysctl_extfrag_handler(struct ctl_table *table, int write, extern int fragmentation_index(struct zone *zone, unsigned int order); extern unsigned long try_to_compact_pages(struct zonelist *zonelist, int order, gfp_t gfp_mask, nodemask_t *mask, - bool sync, bool *contended); + bool sync, bool *contended, struct page **page); extern int compact_pgdat(pg_data_t *pgdat, int order); extern void reset_isolation_suitable(pg_data_t *pgdat); extern unsigned long compaction_suitable(struct zone *zone, int order); @@ -75,7 +75,7 @@ static inline bool compaction_restarting(struct zone *zone, int order) #else static inline unsigned long try_to_compact_pages(struct zonelist *zonelist, int order, gfp_t gfp_mask, nodemask_t *nodemask, - bool sync, bool *contended) + bool sync, bool *contended, struct page **page) { return COMPACT_CONTINUE; } diff --git a/trunk/include/linux/cpu_rmap.h b/trunk/include/linux/cpu_rmap.h index 1739510d8994..ac3bbb5b9502 100644 --- a/trunk/include/linux/cpu_rmap.h +++ b/trunk/include/linux/cpu_rmap.h @@ -13,11 +13,9 @@ #include #include #include -#include /** * struct cpu_rmap - CPU affinity reverse-map - * @refcount: kref for object * @size: Number of objects to be reverse-mapped * @used: Number of objects added * @obj: Pointer to array of object pointers @@ -25,7 +23,6 @@ * based on affinity masks */ struct cpu_rmap { - struct kref refcount; u16 size, used; void **obj; struct { @@ -36,7 +33,15 @@ struct cpu_rmap { #define CPU_RMAP_DIST_INF 0xffff extern struct cpu_rmap *alloc_cpu_rmap(unsigned int size, gfp_t flags); -extern int cpu_rmap_put(struct cpu_rmap *rmap); + +/** + * free_cpu_rmap - free CPU affinity reverse-map + * @rmap: Reverse-map allocated with alloc_cpu_rmap(), or %NULL + */ +static inline void free_cpu_rmap(struct cpu_rmap *rmap) +{ + kfree(rmap); +} extern int cpu_rmap_add(struct cpu_rmap *rmap, void *obj); extern int cpu_rmap_update(struct cpu_rmap *rmap, u16 index, diff --git a/trunk/include/linux/init.h b/trunk/include/linux/init.h index a799273714ac..10ed4f436458 100644 --- a/trunk/include/linux/init.h +++ b/trunk/include/linux/init.h @@ -93,14 +93,6 @@ #define __exit __section(.exit.text) __exitused __cold notrace -/* Used for HOTPLUG, but that is always enabled now, so just make them noops */ -#define __devinit -#define __devinitdata -#define __devinitconst -#define __devexit -#define __devexitdata -#define __devexitconst - /* Used for HOTPLUG_CPU */ #define __cpuinit __section(.cpuinit.text) __cold notrace #define __cpuinitdata __section(.cpuinit.data) @@ -337,18 +329,6 @@ void __init parse_early_options(char *cmdline); #define __INITRODATA_OR_MODULE __INITRODATA #endif /*CONFIG_MODULES*/ -/* Functions marked as __devexit may be discarded at kernel link time, depending - on config options. Newer versions of binutils detect references from - retained sections to discarded sections and flag an error. Pointers to - __devexit functions must use __devexit_p(function_name), the wrapper will - insert either the function_name or NULL, depending on the config options. - */ -#if defined(MODULE) || defined(CONFIG_HOTPLUG) -#define __devexit_p(x) x -#else -#define __devexit_p(x) NULL -#endif - #ifdef MODULE #define __exit_p(x) x #else diff --git a/trunk/include/linux/interrupt.h b/trunk/include/linux/interrupt.h index 5fa5afeeb759..5e4e6170f43a 100644 --- a/trunk/include/linux/interrupt.h +++ b/trunk/include/linux/interrupt.h @@ -268,6 +268,11 @@ struct irq_affinity_notify { extern int irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify); +static inline void irq_run_affinity_notifiers(void) +{ + flush_scheduled_work(); +} + #else /* CONFIG_SMP */ static inline int irq_set_affinity(unsigned int irq, const struct cpumask *m) diff --git a/trunk/include/linux/lockdep.h b/trunk/include/linux/lockdep.h index 2bca44b0893c..00e46376e28f 100644 --- a/trunk/include/linux/lockdep.h +++ b/trunk/include/linux/lockdep.h @@ -524,17 +524,14 @@ static inline void print_irqtrace_events(struct task_struct *curr) #ifdef CONFIG_DEBUG_LOCK_ALLOC # ifdef CONFIG_PROVE_LOCKING # define rwsem_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, NULL, i) -# define rwsem_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 2, n, i) # define rwsem_acquire_read(l, s, t, i) lock_acquire(l, s, t, 1, 2, NULL, i) # else # define rwsem_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, NULL, i) -# define rwsem_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 1, n, i) # define rwsem_acquire_read(l, s, t, i) lock_acquire(l, s, t, 1, 1, NULL, i) # endif # define rwsem_release(l, n, i) lock_release(l, n, i) #else # define rwsem_acquire(l, s, t, i) do { } while (0) -# define rwsem_acquire_nest(l, s, t, n, i) do { } while (0) # define rwsem_acquire_read(l, s, t, i) do { } while (0) # define rwsem_release(l, n, i) do { } while (0) #endif diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index 66e2f7c61e5c..63204078f72b 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -455,6 +455,7 @@ void put_pages_list(struct list_head *pages); void split_page(struct page *page, unsigned int order); int split_free_page(struct page *page); +int capture_free_page(struct page *page, int alloc_order, int migratetype); /* * Compound pages have a destructor function. Provide a diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index 9ef07d0868b6..c599e4782d45 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -60,9 +60,6 @@ struct wireless_dev; #define SET_ETHTOOL_OPS(netdev,ops) \ ( (netdev)->ethtool_ops = (ops) ) -extern void netdev_set_default_ethtool_ops(struct net_device *dev, - const struct ethtool_ops *ops); - /* hardware address assignment types */ #define NET_ADDR_PERM 0 /* address is permanent (default) */ #define NET_ADDR_RANDOM 1 /* address is generated randomly */ diff --git a/trunk/include/linux/rbtree_augmented.h b/trunk/include/linux/rbtree_augmented.h index fea49b5da12a..2ac60c9cf644 100644 --- a/trunk/include/linux/rbtree_augmented.h +++ b/trunk/include/linux/rbtree_augmented.h @@ -123,9 +123,9 @@ __rb_change_child(struct rb_node *old, struct rb_node *new, extern void __rb_erase_color(struct rb_node *parent, struct rb_root *root, void (*augment_rotate)(struct rb_node *old, struct rb_node *new)); -static __always_inline struct rb_node * -__rb_erase_augmented(struct rb_node *node, struct rb_root *root, - const struct rb_augment_callbacks *augment) +static __always_inline void +rb_erase_augmented(struct rb_node *node, struct rb_root *root, + const struct rb_augment_callbacks *augment) { struct rb_node *child = node->rb_right, *tmp = node->rb_left; struct rb_node *parent, *rebalance; @@ -217,14 +217,6 @@ __rb_erase_augmented(struct rb_node *node, struct rb_root *root, } augment->propagate(tmp, NULL); - return rebalance; -} - -static __always_inline void -rb_erase_augmented(struct rb_node *node, struct rb_root *root, - const struct rb_augment_callbacks *augment) -{ - struct rb_node *rebalance = __rb_erase_augmented(node, root, augment); if (rebalance) __rb_erase_color(rebalance, root, augment->rotate); } diff --git a/trunk/include/linux/rwsem.h b/trunk/include/linux/rwsem.h index 413cc11e414a..54bd7cd7ecbd 100644 --- a/trunk/include/linux/rwsem.h +++ b/trunk/include/linux/rwsem.h @@ -125,17 +125,8 @@ extern void downgrade_write(struct rw_semaphore *sem); */ extern void down_read_nested(struct rw_semaphore *sem, int subclass); extern void down_write_nested(struct rw_semaphore *sem, int subclass); -extern void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map *nest_lock); - -# define down_write_nest_lock(sem, nest_lock) \ -do { \ - typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \ - _down_write_nest_lock(sem, &(nest_lock)->dep_map); \ -} while (0); - #else # define down_read_nested(sem, subclass) down_read(sem) -# define down_write_nest_lock(sem, nest_lock) down_read(sem) # define down_write_nested(sem, subclass) down_write(sem) #endif diff --git a/trunk/include/uapi/linux/audit.h b/trunk/include/uapi/linux/audit.h index 9f096f1c0907..76352ac45f24 100644 --- a/trunk/include/uapi/linux/audit.h +++ b/trunk/include/uapi/linux/audit.h @@ -26,6 +26,7 @@ #include #include +#include /* The netlink messages for the audit system is divided into blocks: * 1000 - 1099 are for commanding the audit system @@ -105,7 +106,6 @@ #define AUDIT_MMAP 1323 /* Record showing descriptor and flags in mmap */ #define AUDIT_NETFILTER_PKT 1324 /* Packets traversing netfilter chains */ #define AUDIT_NETFILTER_CFG 1325 /* Netfilter chain modifications */ -#define AUDIT_SECCOMP 1326 /* Secure Computing event */ #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ diff --git a/trunk/kernel/audit.c b/trunk/kernel/audit.c index d596e5355f15..40414e9143db 100644 --- a/trunk/kernel/audit.c +++ b/trunk/kernel/audit.c @@ -272,8 +272,6 @@ static int audit_log_config_change(char *function_name, int new, int old, int rc = 0; ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); - if (unlikely(!ab)) - return rc; audit_log_format(ab, "%s=%d old=%d auid=%u ses=%u", function_name, new, old, from_kuid(&init_user_ns, loginuid), sessionid); if (sid) { @@ -621,8 +619,6 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, } *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); - if (unlikely(!*ab)) - return rc; audit_log_format(*ab, "pid=%d uid=%u auid=%u ses=%u", task_tgid_vnr(current), from_kuid(&init_user_ns, current_uid()), @@ -1101,23 +1097,6 @@ static inline void audit_get_stamp(struct audit_context *ctx, } } -/* - * Wait for auditd to drain the queue a little - */ -static void wait_for_auditd(unsigned long sleep_time) -{ - DECLARE_WAITQUEUE(wait, current); - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&audit_backlog_wait, &wait); - - if (audit_backlog_limit && - skb_queue_len(&audit_skb_queue) > audit_backlog_limit) - schedule_timeout(sleep_time); - - __set_current_state(TASK_RUNNING); - remove_wait_queue(&audit_backlog_wait, &wait); -} - /* Obtain an audit buffer. This routine does locking to obtain the * audit buffer, but then no locking is required for calls to * audit_log_*format. If the tsk is a task that is currently in a @@ -1163,13 +1142,20 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, while (audit_backlog_limit && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) { - if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time) { - unsigned long sleep_time; + if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time + && time_before(jiffies, timeout_start + audit_backlog_wait_time)) { - sleep_time = timeout_start + audit_backlog_wait_time - - jiffies; - if ((long)sleep_time > 0) - wait_for_auditd(sleep_time); + /* Wait for auditd to drain the queue a little */ + DECLARE_WAITQUEUE(wait, current); + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&audit_backlog_wait, &wait); + + if (audit_backlog_limit && + skb_queue_len(&audit_skb_queue) > audit_backlog_limit) + schedule_timeout(timeout_start + audit_backlog_wait_time - jiffies); + + __set_current_state(TASK_RUNNING); + remove_wait_queue(&audit_backlog_wait, &wait); continue; } if (audit_rate_check() && printk_ratelimit()) diff --git a/trunk/kernel/audit_tree.c b/trunk/kernel/audit_tree.c index 642a89c4f3d6..e81175ef25f8 100644 --- a/trunk/kernel/audit_tree.c +++ b/trunk/kernel/audit_tree.c @@ -449,26 +449,11 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) return 0; } -static void audit_log_remove_rule(struct audit_krule *rule) -{ - struct audit_buffer *ab; - - ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); - if (unlikely(!ab)) - return; - audit_log_format(ab, "op="); - audit_log_string(ab, "remove rule"); - audit_log_format(ab, " dir="); - audit_log_untrustedstring(ab, rule->tree->pathname); - audit_log_key(ab, rule->filterkey); - audit_log_format(ab, " list=%d res=1", rule->listnr); - audit_log_end(ab); -} - static void kill_rules(struct audit_tree *tree) { struct audit_krule *rule, *next; struct audit_entry *entry; + struct audit_buffer *ab; list_for_each_entry_safe(rule, next, &tree->rules, rlist) { entry = container_of(rule, struct audit_entry, rule); @@ -476,7 +461,14 @@ static void kill_rules(struct audit_tree *tree) list_del_init(&rule->rlist); if (rule->tree) { /* not a half-baked one */ - audit_log_remove_rule(rule); + ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); + audit_log_format(ab, "op="); + audit_log_string(ab, "remove rule"); + audit_log_format(ab, " dir="); + audit_log_untrustedstring(ab, rule->tree->pathname); + audit_log_key(ab, rule->filterkey); + audit_log_format(ab, " list=%d res=1", rule->listnr); + audit_log_end(ab); rule->tree = NULL; list_del_rcu(&entry->list); list_del(&entry->rule.list); diff --git a/trunk/kernel/audit_watch.c b/trunk/kernel/audit_watch.c index 22831c4d369c..4a599f699adc 100644 --- a/trunk/kernel/audit_watch.c +++ b/trunk/kernel/audit_watch.c @@ -240,8 +240,6 @@ static void audit_watch_log_rule_change(struct audit_krule *r, struct audit_watc if (audit_enabled) { struct audit_buffer *ab; ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE); - if (unlikely(!ab)) - return; audit_log_format(ab, "auid=%u ses=%u op=", from_kuid(&init_user_ns, audit_get_loginuid(current)), audit_get_sessionid(current)); diff --git a/trunk/kernel/auditfilter.c b/trunk/kernel/auditfilter.c index f9fc54bbe06f..7f19f23d38a3 100644 --- a/trunk/kernel/auditfilter.c +++ b/trunk/kernel/auditfilter.c @@ -1144,6 +1144,7 @@ static void audit_log_rule_change(kuid_t loginuid, u32 sessionid, u32 sid, * audit_receive_filter - apply all rules to the specified message type * @type: audit message type * @pid: target pid for netlink audit messages + * @uid: target uid for netlink audit messages * @seq: netlink audit message sequence (serial) number * @data: payload data * @datasz: size of payload data diff --git a/trunk/kernel/auditsc.c b/trunk/kernel/auditsc.c index a371f857a0a9..e37e6a12c5e3 100644 --- a/trunk/kernel/auditsc.c +++ b/trunk/kernel/auditsc.c @@ -1464,14 +1464,14 @@ static void show_special(struct audit_context *context, int *call_panic) audit_log_end(ab); ab = audit_log_start(context, GFP_KERNEL, AUDIT_IPC_SET_PERM); - if (unlikely(!ab)) - return; audit_log_format(ab, "qbytes=%lx ouid=%u ogid=%u mode=%#ho", context->ipc.qbytes, context->ipc.perm_uid, context->ipc.perm_gid, context->ipc.perm_mode); + if (!ab) + return; } break; } case AUDIT_MQ_OPEN: { @@ -2675,7 +2675,7 @@ void __audit_mmap_fd(int fd, int flags) context->type = AUDIT_MMAP; } -static void audit_log_task(struct audit_buffer *ab) +static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr) { kuid_t auid, uid; kgid_t gid; @@ -2693,11 +2693,6 @@ static void audit_log_task(struct audit_buffer *ab) audit_log_task_context(ab); audit_log_format(ab, " pid=%d comm=", current->pid); audit_log_untrustedstring(ab, current->comm); -} - -static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr) -{ - audit_log_task(ab); audit_log_format(ab, " reason="); audit_log_string(ab, reason); audit_log_format(ab, " sig=%ld", signr); @@ -2720,8 +2715,6 @@ void audit_core_dumps(long signr) return; ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); - if (unlikely(!ab)) - return; audit_log_abend(ab, "memory violation", signr); audit_log_end(ab); } @@ -2730,11 +2723,8 @@ void __audit_seccomp(unsigned long syscall, long signr, int code) { struct audit_buffer *ab; - ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_SECCOMP); - if (unlikely(!ab)) - return; - audit_log_task(ab); - audit_log_format(ab, " sig=%ld", signr); + ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); + audit_log_abend(ab, "seccomp", signr); audit_log_format(ab, " syscall=%ld", syscall); audit_log_format(ab, " compat=%d", is_compat_task()); audit_log_format(ab, " ip=0x%lx", KSTK_EIP(current)); diff --git a/trunk/kernel/rwsem.c b/trunk/kernel/rwsem.c index b3c6c3fcd847..6850f53e02d8 100644 --- a/trunk/kernel/rwsem.c +++ b/trunk/kernel/rwsem.c @@ -116,16 +116,6 @@ void down_read_nested(struct rw_semaphore *sem, int subclass) EXPORT_SYMBOL(down_read_nested); -void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map *nest) -{ - might_sleep(); - rwsem_acquire_nest(&sem->dep_map, 0, 0, nest, _RET_IP_); - - LOCK_CONTENDED(sem, __down_write_trylock, __down_write); -} - -EXPORT_SYMBOL(_down_write_nest_lock); - void down_write_nested(struct rw_semaphore *sem, int subclass) { might_sleep(); diff --git a/trunk/kernel/trace/trace.c b/trunk/kernel/trace/trace.c index 1bbfa0446507..e5125677efa0 100644 --- a/trunk/kernel/trace/trace.c +++ b/trunk/kernel/trace/trace.c @@ -2899,8 +2899,6 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf, if (copy_from_user(&buf, ubuf, cnt)) return -EFAULT; - buf[cnt] = 0; - trace_set_options(buf); *ppos += cnt; diff --git a/trunk/lib/cpu_rmap.c b/trunk/lib/cpu_rmap.c index 5fbed5caba6e..145dec5267c9 100644 --- a/trunk/lib/cpu_rmap.c +++ b/trunk/lib/cpu_rmap.c @@ -45,7 +45,6 @@ struct cpu_rmap *alloc_cpu_rmap(unsigned int size, gfp_t flags) if (!rmap) return NULL; - kref_init(&rmap->refcount); rmap->obj = (void **)((char *)rmap + obj_offset); /* Initially assign CPUs to objects on a rota, since we have @@ -64,35 +63,6 @@ struct cpu_rmap *alloc_cpu_rmap(unsigned int size, gfp_t flags) } EXPORT_SYMBOL(alloc_cpu_rmap); -/** - * cpu_rmap_release - internal reclaiming helper called from kref_put - * @ref: kref to struct cpu_rmap - */ -static void cpu_rmap_release(struct kref *ref) -{ - struct cpu_rmap *rmap = container_of(ref, struct cpu_rmap, refcount); - kfree(rmap); -} - -/** - * cpu_rmap_get - internal helper to get new ref on a cpu_rmap - * @rmap: reverse-map allocated with alloc_cpu_rmap() - */ -static inline void cpu_rmap_get(struct cpu_rmap *rmap) -{ - kref_get(&rmap->refcount); -} - -/** - * cpu_rmap_put - release ref on a cpu_rmap - * @rmap: reverse-map allocated with alloc_cpu_rmap() - */ -int cpu_rmap_put(struct cpu_rmap *rmap) -{ - return kref_put(&rmap->refcount, cpu_rmap_release); -} -EXPORT_SYMBOL(cpu_rmap_put); - /* Reevaluate nearest object for given CPU, comparing with the given * neighbours at the given distance. */ @@ -227,7 +197,8 @@ struct irq_glue { * free_irq_cpu_rmap - free a CPU affinity reverse-map used for IRQs * @rmap: Reverse-map allocated with alloc_irq_cpu_map(), or %NULL * - * Must be called in process context, before freeing the IRQs. + * Must be called in process context, before freeing the IRQs, and + * without holding any locks required by global workqueue items. */ void free_irq_cpu_rmap(struct cpu_rmap *rmap) { @@ -241,18 +212,12 @@ void free_irq_cpu_rmap(struct cpu_rmap *rmap) glue = rmap->obj[index]; irq_set_affinity_notifier(glue->notify.irq, NULL); } + irq_run_affinity_notifiers(); - cpu_rmap_put(rmap); + kfree(rmap); } EXPORT_SYMBOL(free_irq_cpu_rmap); -/** - * irq_cpu_rmap_notify - callback for IRQ subsystem when IRQ affinity updated - * @notify: struct irq_affinity_notify passed by irq/manage.c - * @mask: cpu mask for new SMP affinity - * - * This is executed in workqueue context. - */ static void irq_cpu_rmap_notify(struct irq_affinity_notify *notify, const cpumask_t *mask) { @@ -265,16 +230,10 @@ irq_cpu_rmap_notify(struct irq_affinity_notify *notify, const cpumask_t *mask) pr_warning("irq_cpu_rmap_notify: update failed: %d\n", rc); } -/** - * irq_cpu_rmap_release - reclaiming callback for IRQ subsystem - * @ref: kref to struct irq_affinity_notify passed by irq/manage.c - */ static void irq_cpu_rmap_release(struct kref *ref) { struct irq_glue *glue = container_of(ref, struct irq_glue, notify.kref); - - cpu_rmap_put(glue->rmap); kfree(glue); } @@ -299,13 +258,10 @@ int irq_cpu_rmap_add(struct cpu_rmap *rmap, int irq) glue->notify.notify = irq_cpu_rmap_notify; glue->notify.release = irq_cpu_rmap_release; glue->rmap = rmap; - cpu_rmap_get(rmap); glue->index = cpu_rmap_add(rmap, glue); rc = irq_set_affinity_notifier(irq, &glue->notify); - if (rc) { - cpu_rmap_put(glue->rmap); + if (rc) kfree(glue); - } return rc; } EXPORT_SYMBOL(irq_cpu_rmap_add); diff --git a/trunk/lib/rbtree.c b/trunk/lib/rbtree.c index c0e31fe2fabf..4f56a11d67fa 100644 --- a/trunk/lib/rbtree.c +++ b/trunk/lib/rbtree.c @@ -194,12 +194,8 @@ __rb_insert(struct rb_node *node, struct rb_root *root, } } -/* - * Inline version for rb_erase() use - we want to be able to inline - * and eliminate the dummy_rotate callback there - */ -static __always_inline void -____rb_erase_color(struct rb_node *parent, struct rb_root *root, +__always_inline void +__rb_erase_color(struct rb_node *parent, struct rb_root *root, void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) { struct rb_node *node = NULL, *sibling, *tmp1, *tmp2; @@ -359,13 +355,6 @@ ____rb_erase_color(struct rb_node *parent, struct rb_root *root, } } } - -/* Non-inline version for rb_erase_augmented() use */ -void __rb_erase_color(struct rb_node *parent, struct rb_root *root, - void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) -{ - ____rb_erase_color(parent, root, augment_rotate); -} EXPORT_SYMBOL(__rb_erase_color); /* @@ -391,10 +380,7 @@ EXPORT_SYMBOL(rb_insert_color); void rb_erase(struct rb_node *node, struct rb_root *root) { - struct rb_node *rebalance; - rebalance = __rb_erase_augmented(node, root, &dummy_callbacks); - if (rebalance) - ____rb_erase_color(rebalance, root, dummy_rotate); + rb_erase_augmented(node, root, &dummy_callbacks); } EXPORT_SYMBOL(rb_erase); diff --git a/trunk/mm/bootmem.c b/trunk/mm/bootmem.c index b93376c39b61..1324cd74faec 100644 --- a/trunk/mm/bootmem.c +++ b/trunk/mm/bootmem.c @@ -185,23 +185,10 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) while (start < end) { unsigned long *map, idx, vec; - unsigned shift; map = bdata->node_bootmem_map; idx = start - bdata->node_min_pfn; - shift = idx & (BITS_PER_LONG - 1); - /* - * vec holds at most BITS_PER_LONG map bits, - * bit 0 corresponds to start. - */ vec = ~map[idx / BITS_PER_LONG]; - - if (shift) { - vec >>= shift; - if (end - start >= BITS_PER_LONG) - vec |= ~map[idx / BITS_PER_LONG + 1] << - (BITS_PER_LONG - shift); - } /* * If we have a properly aligned and fully unreserved * BITS_PER_LONG block of pages in front of us, free @@ -214,18 +201,19 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) count += BITS_PER_LONG; start += BITS_PER_LONG; } else { - unsigned long cur = start; + unsigned long off = 0; - start = ALIGN(start + 1, BITS_PER_LONG); - while (vec && cur != start) { + vec >>= start & (BITS_PER_LONG - 1); + while (vec) { if (vec & 1) { - page = pfn_to_page(cur); + page = pfn_to_page(start + off); __free_pages_bootmem(page, 0); count++; } vec >>= 1; - ++cur; + off++; } + start = ALIGN(start + 1, BITS_PER_LONG); } } diff --git a/trunk/mm/compaction.c b/trunk/mm/compaction.c index c62bd063d766..6b807e466497 100644 --- a/trunk/mm/compaction.c +++ b/trunk/mm/compaction.c @@ -816,7 +816,6 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone, static int compact_finished(struct zone *zone, struct compact_control *cc) { - unsigned int order; unsigned long watermark; if (fatal_signal_pending(current)) @@ -851,16 +850,22 @@ static int compact_finished(struct zone *zone, return COMPACT_CONTINUE; /* Direct compactor: Is a suitable page free? */ - for (order = cc->order; order < MAX_ORDER; order++) { - struct free_area *area = &zone->free_area[order]; - - /* Job done if page is free of the right migratetype */ - if (!list_empty(&area->free_list[cc->migratetype])) - return COMPACT_PARTIAL; - - /* Job done if allocation would set block type */ - if (cc->order >= pageblock_order && area->nr_free) + if (cc->page) { + /* Was a suitable page captured? */ + if (*cc->page) return COMPACT_PARTIAL; + } else { + unsigned int order; + for (order = cc->order; order < MAX_ORDER; order++) { + struct free_area *area = &zone->free_area[cc->order]; + /* Job done if page is free of the right migratetype */ + if (!list_empty(&area->free_list[cc->migratetype])) + return COMPACT_PARTIAL; + + /* Job done if allocation would set block type */ + if (cc->order >= pageblock_order && area->nr_free) + return COMPACT_PARTIAL; + } } return COMPACT_CONTINUE; @@ -916,6 +921,60 @@ unsigned long compaction_suitable(struct zone *zone, int order) return COMPACT_CONTINUE; } +static void compact_capture_page(struct compact_control *cc) +{ + unsigned long flags; + int mtype, mtype_low, mtype_high; + + if (!cc->page || *cc->page) + return; + + /* + * For MIGRATE_MOVABLE allocations we capture a suitable page ASAP + * regardless of the migratetype of the freelist is is captured from. + * This is fine because the order for a high-order MIGRATE_MOVABLE + * allocation is typically at least a pageblock size and overall + * fragmentation is not impaired. Other allocation types must + * capture pages from their own migratelist because otherwise they + * could pollute other pageblocks like MIGRATE_MOVABLE with + * difficult to move pages and making fragmentation worse overall. + */ + if (cc->migratetype == MIGRATE_MOVABLE) { + mtype_low = 0; + mtype_high = MIGRATE_PCPTYPES; + } else { + mtype_low = cc->migratetype; + mtype_high = cc->migratetype + 1; + } + + /* Speculatively examine the free lists without zone lock */ + for (mtype = mtype_low; mtype < mtype_high; mtype++) { + int order; + for (order = cc->order; order < MAX_ORDER; order++) { + struct page *page; + struct free_area *area; + area = &(cc->zone->free_area[order]); + if (list_empty(&area->free_list[mtype])) + continue; + + /* Take the lock and attempt capture of the page */ + if (!compact_trylock_irqsave(&cc->zone->lock, &flags, cc)) + return; + if (!list_empty(&area->free_list[mtype])) { + page = list_entry(area->free_list[mtype].next, + struct page, lru); + if (capture_free_page(page, cc->order, mtype)) { + spin_unlock_irqrestore(&cc->zone->lock, + flags); + *cc->page = page; + return; + } + } + spin_unlock_irqrestore(&cc->zone->lock, flags); + } + } +} + static int compact_zone(struct zone *zone, struct compact_control *cc) { int ret; @@ -995,6 +1054,9 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) goto out; } } + + /* Capture a page now if it is a suitable size */ + compact_capture_page(cc); } out: @@ -1007,7 +1069,8 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) static unsigned long compact_zone_order(struct zone *zone, int order, gfp_t gfp_mask, - bool sync, bool *contended) + bool sync, bool *contended, + struct page **page) { unsigned long ret; struct compact_control cc = { @@ -1017,6 +1080,7 @@ static unsigned long compact_zone_order(struct zone *zone, .migratetype = allocflags_to_migratetype(gfp_mask), .zone = zone, .sync = sync, + .page = page, }; INIT_LIST_HEAD(&cc.freepages); INIT_LIST_HEAD(&cc.migratepages); @@ -1046,7 +1110,7 @@ int sysctl_extfrag_threshold = 500; */ unsigned long try_to_compact_pages(struct zonelist *zonelist, int order, gfp_t gfp_mask, nodemask_t *nodemask, - bool sync, bool *contended) + bool sync, bool *contended, struct page **page) { enum zone_type high_zoneidx = gfp_zone(gfp_mask); int may_enter_fs = gfp_mask & __GFP_FS; @@ -1072,7 +1136,7 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist, int status; status = compact_zone_order(zone, order, gfp_mask, sync, - contended); + contended, page); rc = max(status, rc); /* If a normal allocation would succeed, stop compacting */ @@ -1128,6 +1192,7 @@ int compact_pgdat(pg_data_t *pgdat, int order) struct compact_control cc = { .order = order, .sync = false, + .page = NULL, }; return __compact_pgdat(pgdat, &cc); @@ -1138,13 +1203,14 @@ static int compact_node(int nid) struct compact_control cc = { .order = -1, .sync = true, + .page = NULL, }; return __compact_pgdat(NODE_DATA(nid), &cc); } /* Compact all nodes in the system */ -static void compact_nodes(void) +static int compact_nodes(void) { int nid; @@ -1153,6 +1219,8 @@ static void compact_nodes(void) for_each_online_node(nid) compact_node(nid); + + return COMPACT_COMPLETE; } /* The written value is actually unused, all memory is compacted */ @@ -1163,7 +1231,7 @@ int sysctl_compaction_handler(struct ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) { if (write) - compact_nodes(); + return compact_nodes(); return 0; } diff --git a/trunk/mm/huge_memory.c b/trunk/mm/huge_memory.c index 6001ee6347a9..9e894edc7811 100644 --- a/trunk/mm/huge_memory.c +++ b/trunk/mm/huge_memory.c @@ -1819,19 +1819,9 @@ int split_huge_page(struct page *page) BUG_ON(is_huge_zero_pfn(page_to_pfn(page))); BUG_ON(!PageAnon(page)); - - /* - * The caller does not necessarily hold an mmap_sem that would prevent - * the anon_vma disappearing so we first we take a reference to it - * and then lock the anon_vma for write. This is similar to - * page_lock_anon_vma_read except the write lock is taken to serialise - * against parallel split or collapse operations. - */ - anon_vma = page_get_anon_vma(page); + anon_vma = page_lock_anon_vma_read(page); if (!anon_vma) goto out; - anon_vma_lock_write(anon_vma); - ret = 0; if (!PageCompound(page)) goto out_unlock; @@ -1842,8 +1832,7 @@ int split_huge_page(struct page *page) BUG_ON(PageCompound(page)); out_unlock: - anon_vma_unlock(anon_vma); - put_anon_vma(anon_vma); + page_unlock_anon_vma_read(anon_vma); out: return ret; } diff --git a/trunk/mm/internal.h b/trunk/mm/internal.h index 9ba21100ebf3..d597f94cc205 100644 --- a/trunk/mm/internal.h +++ b/trunk/mm/internal.h @@ -135,6 +135,7 @@ struct compact_control { int migratetype; /* MOVABLE, RECLAIMABLE etc */ struct zone *zone; bool contended; /* True if a lock was contended */ + struct page **page; /* Page captured of requested size */ }; unsigned long diff --git a/trunk/mm/memblock.c b/trunk/mm/memblock.c index 88adc8afb610..625905523c2a 100644 --- a/trunk/mm/memblock.c +++ b/trunk/mm/memblock.c @@ -314,8 +314,7 @@ static void __init_memblock memblock_merge_regions(struct memblock_type *type) } this->size += next->size; - /* move forward from next + 1, index of which is i + 2 */ - memmove(next, next + 1, (type->cnt - (i + 2)) * sizeof(*next)); + memmove(next, next + 1, (type->cnt - (i + 1)) * sizeof(*next)); type->cnt--; } } diff --git a/trunk/mm/migrate.c b/trunk/mm/migrate.c index c38778610aa8..3b676b0c5c3e 100644 --- a/trunk/mm/migrate.c +++ b/trunk/mm/migrate.c @@ -1679,21 +1679,9 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm, page_xchg_last_nid(new_page, page_last_nid(page)); isolated = numamigrate_isolate_page(pgdat, page); - - /* - * Failing to isolate or a GUP pin prevents migration. The expected - * page count is 2. 1 for anonymous pages without a mapping and 1 - * for the callers pin. If the page was isolated, the page will - * need to be put back on the LRU. - */ - if (!isolated || page_count(page) != 2) { + if (!isolated) { count_vm_events(PGMIGRATE_FAIL, HPAGE_PMD_NR); put_page(new_page); - if (isolated) { - putback_lru_page(page); - isolated = 0; - goto out; - } goto out_keep_locked; } diff --git a/trunk/mm/mmap.c b/trunk/mm/mmap.c index 35730ee9d515..f54b235f29a9 100644 --- a/trunk/mm/mmap.c +++ b/trunk/mm/mmap.c @@ -2886,7 +2886,7 @@ static void vm_lock_anon_vma(struct mm_struct *mm, struct anon_vma *anon_vma) * The LSB of head.next can't change from under us * because we hold the mm_all_locks_mutex. */ - down_write_nest_lock(&anon_vma->root->rwsem, &mm->mmap_sem); + down_write(&anon_vma->root->rwsem); /* * We can safely modify head.next after taking the * anon_vma->root->rwsem. If some other vma in this mm shares diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index df2022ff0c8a..bc6cc0e913bd 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -1384,8 +1384,14 @@ void split_page(struct page *page, unsigned int order) set_page_refcounted(page + i); } -static int __isolate_free_page(struct page *page, unsigned int order) +/* + * Similar to the split_page family of functions except that the page + * required at the given order and being isolated now to prevent races + * with parallel allocators + */ +int capture_free_page(struct page *page, int alloc_order, int migratetype) { + unsigned int order; unsigned long watermark; struct zone *zone; int mt; @@ -1393,6 +1399,7 @@ static int __isolate_free_page(struct page *page, unsigned int order) BUG_ON(!PageBuddy(page)); zone = page_zone(page); + order = page_order(page); mt = get_pageblock_migratetype(page); if (mt != MIGRATE_ISOLATE) { @@ -1401,7 +1408,7 @@ static int __isolate_free_page(struct page *page, unsigned int order) if (!zone_watermark_ok(zone, 0, watermark, 0, 0)) return 0; - __mod_zone_freepage_state(zone, -(1UL << order), mt); + __mod_zone_freepage_state(zone, -(1UL << alloc_order), mt); } /* Remove page from free list */ @@ -1409,7 +1416,11 @@ static int __isolate_free_page(struct page *page, unsigned int order) zone->free_area[order].nr_free--; rmv_page_order(page); - /* Set the pageblock if the isolated page is at least a pageblock */ + if (alloc_order != order) + expand(zone, page, alloc_order, order, + &zone->free_area[order], migratetype); + + /* Set the pageblock if the captured page is at least a pageblock */ if (order >= pageblock_order - 1) { struct page *endpage = page + (1 << order) - 1; for (; page < endpage; page += pageblock_nr_pages) { @@ -1420,7 +1431,7 @@ static int __isolate_free_page(struct page *page, unsigned int order) } } - return 1UL << order; + return 1UL << alloc_order; } /* @@ -1438,9 +1449,10 @@ int split_free_page(struct page *page) unsigned int order; int nr_pages; + BUG_ON(!PageBuddy(page)); order = page_order(page); - nr_pages = __isolate_free_page(page, order); + nr_pages = capture_free_page(page, order, 0); if (!nr_pages) return 0; @@ -2124,6 +2136,8 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, bool *contended_compaction, bool *deferred_compaction, unsigned long *did_some_progress) { + struct page *page = NULL; + if (!order) return NULL; @@ -2135,12 +2149,16 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, current->flags |= PF_MEMALLOC; *did_some_progress = try_to_compact_pages(zonelist, order, gfp_mask, nodemask, sync_migration, - contended_compaction); + contended_compaction, &page); current->flags &= ~PF_MEMALLOC; - if (*did_some_progress != COMPACT_SKIPPED) { - struct page *page; + /* If compaction captured a page, prep and use it */ + if (page) { + prep_new_page(page, order, gfp_mask); + goto got_page; + } + if (*did_some_progress != COMPACT_SKIPPED) { /* Page migration frees to the PCP lists but we want merging */ drain_pages(get_cpu()); put_cpu(); @@ -2150,6 +2168,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, alloc_flags & ~ALLOC_NO_WATERMARKS, preferred_zone, migratetype); if (page) { +got_page: preferred_zone->compact_blockskip_flush = false; preferred_zone->compact_considered = 0; preferred_zone->compact_defer_shift = 0; @@ -5585,7 +5604,7 @@ static inline int pfn_to_bitidx(struct zone *zone, unsigned long pfn) pfn &= (PAGES_PER_SECTION-1); return (pfn >> pageblock_order) * NR_PAGEBLOCK_BITS; #else - pfn = pfn - round_down(zone->zone_start_pfn, pageblock_nr_pages); + pfn = pfn - zone->zone_start_pfn; return (pfn >> pageblock_order) * NR_PAGEBLOCK_BITS; #endif /* CONFIG_SPARSEMEM */ } diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index f64e439b4a00..515473ee52cb 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -6121,14 +6121,6 @@ struct netdev_queue *dev_ingress_queue_create(struct net_device *dev) static const struct ethtool_ops default_ethtool_ops; -void netdev_set_default_ethtool_ops(struct net_device *dev, - const struct ethtool_ops *ops) -{ - if (dev->ethtool_ops == &default_ethtool_ops) - dev->ethtool_ops = ops; -} -EXPORT_SYMBOL_GPL(netdev_set_default_ethtool_ops); - /** * alloc_netdev_mqs - allocate network device * @sizeof_priv: size of private data to allocate space for diff --git a/trunk/net/ipv4/ip_sockglue.c b/trunk/net/ipv4/ip_sockglue.c index d9c4f113d709..3c9d20880283 100644 --- a/trunk/net/ipv4/ip_sockglue.c +++ b/trunk/net/ipv4/ip_sockglue.c @@ -590,7 +590,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, case IP_TTL: if (optlen < 1) goto e_inval; - if (val != -1 && (val < 1 || val > 255)) + if (val != -1 && (val < 0 || val > 255)) goto e_inval; inet->uc_ttl = val; break; diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index 2aa69c8ae60c..1ca253635f7a 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -1428,12 +1428,12 @@ static void tcp_service_net_dma(struct sock *sk, bool wait) } #endif -static struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) +static inline struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) { struct sk_buff *skb; u32 offset; - while ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) { + skb_queue_walk(&sk->sk_receive_queue, skb) { offset = seq - TCP_SKB_CB(skb)->seq; if (tcp_hdr(skb)->syn) offset--; @@ -1441,11 +1441,6 @@ static struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) *off = offset; return skb; } - /* This looks weird, but this can happen if TCP collapsing - * splitted a fat GRO packet, while we released socket lock - * in skb_splice_bits() - */ - sk_eat_skb(sk, skb, false); } return NULL; } @@ -1487,7 +1482,7 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, break; } used = recv_actor(desc, skb, offset, len); - if (used <= 0) { + if (used < 0) { if (!copied) copied = used; break; @@ -1525,10 +1520,8 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, tcp_rcv_space_adjust(sk); /* Clean up data we have read: This will do ACK frames. */ - if (copied > 0) { - tcp_recv_skb(sk, seq, &offset); + if (copied > 0) tcp_cleanup_rbuf(sk, copied); - } return copied; } EXPORT_SYMBOL(tcp_read_sock); diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 18f97ca76b00..a28e4db8a952 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -5543,7 +5543,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, if (len < (th->doff << 2) || tcp_checksum_complete_user(sk, skb)) goto csum_error; - if (!th->ack && !th->rst) + if (!th->ack) goto discard; /* @@ -5988,7 +5988,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, goto discard; } - if (!th->ack && !th->rst) + if (!th->ack) goto discard; if (!tcp_validate_incoming(sk, skb, th, 0)) diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index 420e56326384..408cac4ae00a 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -154,11 +154,6 @@ static void addrconf_type_change(struct net_device *dev, unsigned long event); static int addrconf_ifdown(struct net_device *dev, int how); -static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx, - int plen, - const struct net_device *dev, - u32 flags, u32 noflags); - static void addrconf_dad_start(struct inet6_ifaddr *ifp); static void addrconf_dad_timer(unsigned long data); static void addrconf_dad_completed(struct inet6_ifaddr *ifp); @@ -255,6 +250,12 @@ static inline bool addrconf_qdisc_ok(const struct net_device *dev) return !qdisc_tx_is_noop(dev); } +/* Check if a route is valid prefix route */ +static inline int addrconf_is_prefix_route(const struct rt6_info *rt) +{ + return (rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0; +} + static void addrconf_del_timer(struct inet6_ifaddr *ifp) { if (del_timer(&ifp->timer)) @@ -940,15 +941,17 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) if ((ifp->flags & IFA_F_PERMANENT) && onlink < 1) { struct in6_addr prefix; struct rt6_info *rt; + struct net *net = dev_net(ifp->idev->dev); + struct flowi6 fl6 = {}; ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); + fl6.flowi6_oif = ifp->idev->dev->ifindex; + fl6.daddr = prefix; + rt = (struct rt6_info *)ip6_route_lookup(net, &fl6, + RT6_LOOKUP_F_IFACE); - rt = addrconf_get_prefix_route(&prefix, - ifp->prefix_len, - ifp->idev->dev, - 0, RTF_GATEWAY | RTF_DEFAULT); - - if (rt) { + if (rt != net->ipv6.ip6_null_entry && + addrconf_is_prefix_route(rt)) { if (onlink == 0) { ip6_del_rt(rt); rt = NULL; @@ -1874,7 +1877,7 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx, continue; if ((rt->rt6i_flags & flags) != flags) continue; - if ((rt->rt6i_flags & noflags) != 0) + if ((noflags != 0) && ((rt->rt6i_flags & flags) != 0)) continue; dst_hold(&rt->dst); break; diff --git a/trunk/net/iucv/iucv.c b/trunk/net/iucv/iucv.c index df082508362d..3ad1f9db5f8b 100644 --- a/trunk/net/iucv/iucv.c +++ b/trunk/net/iucv/iucv.c @@ -1806,7 +1806,7 @@ static void iucv_external_interrupt(struct ext_code ext_code, struct iucv_irq_data *p; struct iucv_irq_list *work; - inc_irq_stat(IRQEXT_IUC); + kstat_cpu(smp_processor_id()).irqs[EXTINT_IUC]++; p = iucv_irq_data[smp_processor_id()]; if (p->ippathid >= iucv_max_pathid) { WARN_ON(p->ippathid >= iucv_max_pathid); diff --git a/trunk/net/mac80211/cfg.c b/trunk/net/mac80211/cfg.c index 47e0aca614b7..5c61677487cf 100644 --- a/trunk/net/mac80211/cfg.c +++ b/trunk/net/mac80211/cfg.c @@ -1009,8 +1009,6 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) if (old_probe_resp) kfree_rcu(old_probe_resp, rcu_head); - list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) - sta_info_flush(local, vlan); sta_info_flush(local, sdata); ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); diff --git a/trunk/net/mac80211/chan.c b/trunk/net/mac80211/chan.c index 80e55527504b..53f03120db55 100644 --- a/trunk/net/mac80211/chan.c +++ b/trunk/net/mac80211/chan.c @@ -4,7 +4,6 @@ #include #include -#include #include #include "ieee80211_i.h" #include "driver-ops.h" @@ -198,15 +197,6 @@ static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) ctx = container_of(conf, struct ieee80211_chanctx, conf); - if (sdata->vif.type == NL80211_IFTYPE_AP) { - struct ieee80211_sub_if_data *vlan; - - /* for the VLAN list */ - ASSERT_RTNL(); - list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) - rcu_assign_pointer(vlan->vif.chanctx_conf, NULL); - } - ieee80211_unassign_vif_chanctx(sdata, ctx); if (ctx->refcount == 0) ieee80211_free_chanctx(local, ctx); @@ -326,15 +316,6 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, goto out; } - if (sdata->vif.type == NL80211_IFTYPE_AP) { - struct ieee80211_sub_if_data *vlan; - - /* for the VLAN list */ - ASSERT_RTNL(); - list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) - rcu_assign_pointer(vlan->vif.chanctx_conf, &ctx->conf); - } - ieee80211_recalc_smps_chanctx(local, ctx); out: mutex_unlock(&local->chanctx_mtx); @@ -350,25 +331,6 @@ void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) mutex_unlock(&sdata->local->chanctx_mtx); } -void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata) -{ - struct ieee80211_local *local = sdata->local; - struct ieee80211_sub_if_data *ap; - struct ieee80211_chanctx_conf *conf; - - if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->bss)) - return; - - ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); - - mutex_lock(&local->chanctx_mtx); - - conf = rcu_dereference_protected(ap->vif.chanctx_conf, - lockdep_is_held(&local->chanctx_mtx)); - rcu_assign_pointer(sdata->vif.chanctx_conf, conf); - mutex_unlock(&local->chanctx_mtx); -} - void ieee80211_iter_chan_contexts_atomic( struct ieee80211_hw *hw, void (*iter)(struct ieee80211_hw *hw, diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index 6b7644e818d8..8881fc77fb13 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -703,8 +703,8 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) sdata_info(sdata, "No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n"); - ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len, - NULL); + ieee80211_request_internal_scan(sdata, + ifibss->ssid, ifibss->ssid_len, NULL); } static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) @@ -802,8 +802,9 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) IEEE80211_SCAN_INTERVAL)) { sdata_info(sdata, "Trigger new scan to find an IBSS to join\n"); - ieee80211_request_ibss_scan(sdata, ifibss->ssid, - ifibss->ssid_len, chan); + ieee80211_request_internal_scan(sdata, + ifibss->ssid, ifibss->ssid_len, + ifibss->fixed_channel ? ifibss->channel : NULL); } else { int interval = IEEE80211_SCAN_INTERVAL; diff --git a/trunk/net/mac80211/ieee80211_i.h b/trunk/net/mac80211/ieee80211_i.h index 8563b9a5cac3..42d0d0267730 100644 --- a/trunk/net/mac80211/ieee80211_i.h +++ b/trunk/net/mac80211/ieee80211_i.h @@ -92,6 +92,8 @@ struct ieee80211_bss { u32 device_ts; + u8 dtim_period; + bool wmm_used; bool uapsd_supported; @@ -138,6 +140,7 @@ enum ieee80211_bss_corrupt_data_flags { /** * enum ieee80211_valid_data_flags - BSS valid data flags + * @IEEE80211_BSS_VALID_DTIM: DTIM data was gathered from non-corrupt IE * @IEEE80211_BSS_VALID_WMM: WMM/UAPSD data was gathered from non-corrupt IE * @IEEE80211_BSS_VALID_RATES: Supported rates were gathered from non-corrupt IE * @IEEE80211_BSS_VALID_ERP: ERP flag was gathered from non-corrupt IE @@ -148,6 +151,7 @@ enum ieee80211_bss_corrupt_data_flags { * beacon/probe response. */ enum ieee80211_bss_valid_data_flags { + IEEE80211_BSS_VALID_DTIM = BIT(0), IEEE80211_BSS_VALID_WMM = BIT(1), IEEE80211_BSS_VALID_RATES = BIT(2), IEEE80211_BSS_VALID_ERP = BIT(3) @@ -436,7 +440,6 @@ struct ieee80211_if_managed { unsigned long timers_running; /* used for quiesce/restart */ bool powersave; /* powersave requested for this iface */ bool broken_ap; /* AP is broken -- turn off powersave */ - u8 dtim_period; enum ieee80211_smps_mode req_smps, /* requested smps mode */ driver_smps_mode; /* smps mode request */ @@ -770,10 +773,6 @@ struct ieee80211_sub_if_data { u32 mntr_flags; } u; - spinlock_t cleanup_stations_lock; - struct list_head cleanup_stations; - struct work_struct cleanup_stations_wk; - #ifdef CONFIG_MAC80211_DEBUGFS struct { struct dentry *dir; @@ -1330,9 +1329,9 @@ void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, /* scan/BSS handling */ void ieee80211_scan_work(struct work_struct *work); -int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, - const u8 *ssid, u8 ssid_len, - struct ieee80211_channel *chan); +int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, + const u8 *ssid, u8 ssid_len, + struct ieee80211_channel *chan); int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, struct cfg80211_scan_request *req); void ieee80211_scan_cancel(struct ieee80211_local *local); @@ -1629,7 +1628,6 @@ ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, const struct cfg80211_chan_def *chandef, enum ieee80211_chanctx_mode mode); void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata); -void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata); void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, struct ieee80211_chanctx *chanctx); diff --git a/trunk/net/mac80211/iface.c b/trunk/net/mac80211/iface.c index 8be854e86cd9..09a80b55cf5a 100644 --- a/trunk/net/mac80211/iface.c +++ b/trunk/net/mac80211/iface.c @@ -207,8 +207,17 @@ void ieee80211_recalc_idle(struct ieee80211_local *local) static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) { - if (new_mtu < 256 || new_mtu > IEEE80211_MAX_DATA_LEN) + int meshhdrlen; + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + meshhdrlen = (sdata->vif.type == NL80211_IFTYPE_MESH_POINT) ? 5 : 0; + + /* FIX: what would be proper limits for MTU? + * This interface uses 802.3 frames. */ + if (new_mtu < 256 || + new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6 - meshhdrlen) { return -EINVAL; + } dev->mtu = new_mtu; return 0; @@ -577,13 +586,11 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) switch (sdata->vif.type) { case NL80211_IFTYPE_AP_VLAN: - /* no need to tell driver, but set carrier and chanctx */ - if (rtnl_dereference(sdata->bss->beacon)) { - ieee80211_vif_vlan_copy_chanctx(sdata); + /* no need to tell driver, but set carrier */ + if (rtnl_dereference(sdata->bss->beacon)) netif_carrier_on(dev); - } else { + else netif_carrier_off(dev); - } break; case NL80211_IFTYPE_MONITOR: if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) { @@ -832,7 +839,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, switch (sdata->vif.type) { case NL80211_IFTYPE_AP_VLAN: list_del(&sdata->u.vlan.list); - rcu_assign_pointer(sdata->vif.chanctx_conf, NULL); /* no need to tell driver */ break; case NL80211_IFTYPE_MONITOR: @@ -859,11 +865,20 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, cancel_work_sync(&sdata->work); /* * When we get here, the interface is marked down. - * Call synchronize_rcu() to wait for the RX path + * Call rcu_barrier() to wait both for the RX path * should it be using the interface and enqueuing - * frames at this very time on another CPU. + * frames at this very time on another CPU, and + * for the sta free call_rcu callbacks. + */ + rcu_barrier(); + + /* + * free_sta_rcu() enqueues a work for the actual + * sta cleanup, so we need to flush it while + * sdata is still valid. */ - synchronize_rcu(); + flush_workqueue(local->workqueue); + skb_queue_purge(&sdata->skb_queue); /* @@ -1483,15 +1498,6 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, mutex_unlock(&local->iflist_mtx); } -static void ieee80211_cleanup_sdata_stas_wk(struct work_struct *wk) -{ - struct ieee80211_sub_if_data *sdata; - - sdata = container_of(wk, struct ieee80211_sub_if_data, cleanup_stations_wk); - - ieee80211_cleanup_sdata_stas(sdata); -} - int ieee80211_if_add(struct ieee80211_local *local, const char *name, struct wireless_dev **new_wdev, enum nl80211_iftype type, struct vif_params *params) @@ -1567,10 +1573,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, INIT_LIST_HEAD(&sdata->key_list); - spin_lock_init(&sdata->cleanup_stations_lock); - INIT_LIST_HEAD(&sdata->cleanup_stations); - INIT_WORK(&sdata->cleanup_stations_wk, ieee80211_cleanup_sdata_stas_wk); - for (i = 0; i < IEEE80211_NUM_BANDS; i++) { struct ieee80211_supported_band *sband; sband = local->hw.wiphy->bands[i]; diff --git a/trunk/net/mac80211/mesh.c b/trunk/net/mac80211/mesh.c index 649ad513547f..1bf03f9ff3ba 100644 --- a/trunk/net/mac80211/mesh.c +++ b/trunk/net/mac80211/mesh.c @@ -163,7 +163,7 @@ int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) return -ENOMEM; sdata->u.mesh.rmc->idx_mask = RMC_BUCKETS - 1; for (i = 0; i < RMC_BUCKETS; i++) - INIT_LIST_HEAD(&sdata->u.mesh.rmc->bucket[i]); + INIT_LIST_HEAD(&sdata->u.mesh.rmc->bucket[i].list); return 0; } @@ -177,7 +177,7 @@ void mesh_rmc_free(struct ieee80211_sub_if_data *sdata) return; for (i = 0; i < RMC_BUCKETS; i++) - list_for_each_entry_safe(p, n, &rmc->bucket[i], list) { + list_for_each_entry_safe(p, n, &rmc->bucket[i].list, list) { list_del(&p->list); kmem_cache_free(rm_cache, p); } @@ -210,7 +210,7 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr, /* Don't care about endianness since only match matters */ memcpy(&seqnum, &mesh_hdr->seqnum, sizeof(mesh_hdr->seqnum)); idx = le32_to_cpu(mesh_hdr->seqnum) & rmc->idx_mask; - list_for_each_entry_safe(p, n, &rmc->bucket[idx], list) { + list_for_each_entry_safe(p, n, &rmc->bucket[idx].list, list) { ++entries; if (time_after(jiffies, p->exp_time) || (entries == RMC_QUEUE_MAX_LEN)) { @@ -229,7 +229,7 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr, p->seqnum = seqnum; p->exp_time = jiffies + RMC_TIMEOUT; memcpy(p->sa, sa, ETH_ALEN); - list_add(&p->list, &rmc->bucket[idx]); + list_add(&p->list, &rmc->bucket[idx].list); return 0; } diff --git a/trunk/net/mac80211/mesh.h b/trunk/net/mac80211/mesh.h index 84c28c6101cd..7c9215fb2ac8 100644 --- a/trunk/net/mac80211/mesh.h +++ b/trunk/net/mac80211/mesh.h @@ -184,7 +184,7 @@ struct rmc_entry { }; struct mesh_rmc { - struct list_head bucket[RMC_BUCKETS]; + struct rmc_entry bucket[RMC_BUCKETS]; u32 idx_mask; }; diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index a3552929a21d..7753a9ca98a6 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -1074,8 +1074,12 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) if (beaconint_us > latency) { local->ps_sdata = NULL; } else { + struct ieee80211_bss *bss; int maxslp = 1; - u8 dtimper = found->u.mgd.dtim_period; + u8 dtimper; + + bss = (void *)found->u.mgd.associated->priv; + dtimper = bss->dtim_period; /* If the TIM IE is invalid, pretend the value is 1 */ if (!dtimper) @@ -1406,17 +1410,10 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, ieee80211_led_assoc(local, 1); - if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) { - /* - * If the AP is buggy we may get here with no DTIM period - * known, so assume it's 1 which is the only safe assumption - * in that case, although if the TIM IE is broken powersave - * probably just won't work at all. - */ - bss_conf->dtim_period = sdata->u.mgd.dtim_period ?: 1; - } else { + if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) + bss_conf->dtim_period = bss->dtim_period; + else bss_conf->dtim_period = 0; - } bss_conf->assoc = 1; @@ -1565,8 +1562,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, sdata->u.mgd.timers_running = 0; - sdata->vif.bss_conf.dtim_period = 0; - ifmgd->flags = 0; ieee80211_vif_release_channel(sdata); } @@ -2378,18 +2373,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, struct ieee80211_channel *channel; bool need_ps = false; - if ((sdata->u.mgd.associated && - ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) || - (sdata->u.mgd.assoc_data && - ether_addr_equal(mgmt->bssid, - sdata->u.mgd.assoc_data->bss->bssid))) { + if (sdata->u.mgd.associated && + ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) { + bss = (void *)sdata->u.mgd.associated->priv; /* not previously set so we may need to recalc */ - need_ps = sdata->u.mgd.associated && !sdata->u.mgd.dtim_period; - - if (elems->tim && !elems->parse_error) { - struct ieee80211_tim_ie *tim_ie = elems->tim; - sdata->u.mgd.dtim_period = tim_ie->dtim_period; - } + need_ps = !bss->dtim_period; } if (elems->ds_params && elems->ds_params_len == 1) @@ -3908,41 +3896,20 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, /* kick off associate process */ ifmgd->assoc_data = assoc_data; - ifmgd->dtim_period = 0; err = ieee80211_prep_connection(sdata, req->bss, true); if (err) goto err_clear; - if (sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) { - const struct cfg80211_bss_ies *beacon_ies; - - rcu_read_lock(); - beacon_ies = rcu_dereference(req->bss->beacon_ies); - if (!beacon_ies) { - /* - * Wait up to one beacon interval ... - * should this be more if we miss one? - */ - sdata_info(sdata, "waiting for beacon from %pM\n", - ifmgd->bssid); - assoc_data->timeout = - TU_TO_EXP_TIME(req->bss->beacon_interval); - } else { - const u8 *tim_ie = cfg80211_find_ie(WLAN_EID_TIM, - beacon_ies->data, - beacon_ies->len); - if (tim_ie && tim_ie[1] >= - sizeof(struct ieee80211_tim_ie)) { - const struct ieee80211_tim_ie *tim; - tim = (void *)(tim_ie + 2); - ifmgd->dtim_period = tim->dtim_period; - } - assoc_data->have_beacon = true; - assoc_data->sent_assoc = false; - assoc_data->timeout = jiffies; - } - rcu_read_unlock(); + if (!bss->dtim_period && + sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) { + /* + * Wait up to one beacon interval ... + * should this be more if we miss one? + */ + sdata_info(sdata, "waiting for beacon from %pM\n", + ifmgd->bssid); + assoc_data->timeout = TU_TO_EXP_TIME(req->bss->beacon_interval); } else { assoc_data->have_beacon = true; assoc_data->sent_assoc = false; diff --git a/trunk/net/mac80211/scan.c b/trunk/net/mac80211/scan.c index d59fc6818b1c..8ed83dcc149f 100644 --- a/trunk/net/mac80211/scan.c +++ b/trunk/net/mac80211/scan.c @@ -113,6 +113,18 @@ ieee80211_bss_info_update(struct ieee80211_local *local, bss->valid_data |= IEEE80211_BSS_VALID_ERP; } + if (elems->tim && (!elems->parse_error || + !(bss->valid_data & IEEE80211_BSS_VALID_DTIM))) { + struct ieee80211_tim_ie *tim_ie = elems->tim; + bss->dtim_period = tim_ie->dtim_period; + if (!elems->parse_error) + bss->valid_data |= IEEE80211_BSS_VALID_DTIM; + } + + /* If the beacon had no TIM IE, or it was invalid, use 1 */ + if (beacon && !bss->dtim_period) + bss->dtim_period = 1; + /* replace old supported rates if we get new values */ if (!elems->parse_error || !(bss->valid_data & IEEE80211_BSS_VALID_RATES)) { @@ -820,9 +832,9 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, return res; } -int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, - const u8 *ssid, u8 ssid_len, - struct ieee80211_channel *chan) +int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, + const u8 *ssid, u8 ssid_len, + struct ieee80211_channel *chan) { struct ieee80211_local *local = sdata->local; int ret = -EBUSY; @@ -836,36 +848,22 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, /* fill internal scan request */ if (!chan) { - int i, max_n; - int n_ch = 0; + int i, nchan = 0; for (band = 0; band < IEEE80211_NUM_BANDS; band++) { if (!local->hw.wiphy->bands[band]) continue; - - max_n = local->hw.wiphy->bands[band]->n_channels; - for (i = 0; i < max_n; i++) { - struct ieee80211_channel *tmp_ch = + for (i = 0; + i < local->hw.wiphy->bands[band]->n_channels; + i++) { + local->int_scan_req->channels[nchan] = &local->hw.wiphy->bands[band]->channels[i]; - - if (tmp_ch->flags & (IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_DISABLED)) - continue; - - local->int_scan_req->channels[n_ch] = tmp_ch; - n_ch++; + nchan++; } } - if (WARN_ON_ONCE(n_ch == 0)) - goto unlock; - - local->int_scan_req->n_channels = n_ch; + local->int_scan_req->n_channels = nchan; } else { - if (WARN_ON_ONCE(chan->flags & (IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_DISABLED))) - goto unlock; - local->int_scan_req->channels[0] = chan; local->int_scan_req->n_channels = 1; } diff --git a/trunk/net/mac80211/sta_info.c b/trunk/net/mac80211/sta_info.c index ca9fde198188..f3e502502fee 100644 --- a/trunk/net/mac80211/sta_info.c +++ b/trunk/net/mac80211/sta_info.c @@ -91,8 +91,9 @@ static int sta_info_hash_del(struct ieee80211_local *local, return -ENOENT; } -static void cleanup_single_sta(struct sta_info *sta) +static void free_sta_work(struct work_struct *wk) { + struct sta_info *sta = container_of(wk, struct sta_info, free_sta_wk); int ac, i; struct tid_ampdu_tx *tid_tx; struct ieee80211_sub_if_data *sdata = sta->sdata; @@ -152,35 +153,11 @@ static void cleanup_single_sta(struct sta_info *sta) sta_info_free(local, sta); } -void ieee80211_cleanup_sdata_stas(struct ieee80211_sub_if_data *sdata) -{ - struct sta_info *sta; - - spin_lock_bh(&sdata->cleanup_stations_lock); - while (!list_empty(&sdata->cleanup_stations)) { - sta = list_first_entry(&sdata->cleanup_stations, - struct sta_info, list); - list_del(&sta->list); - spin_unlock_bh(&sdata->cleanup_stations_lock); - - cleanup_single_sta(sta); - - spin_lock_bh(&sdata->cleanup_stations_lock); - } - - spin_unlock_bh(&sdata->cleanup_stations_lock); -} - static void free_sta_rcu(struct rcu_head *h) { struct sta_info *sta = container_of(h, struct sta_info, rcu_head); - struct ieee80211_sub_if_data *sdata = sta->sdata; - spin_lock(&sdata->cleanup_stations_lock); - list_add_tail(&sta->list, &sdata->cleanup_stations); - spin_unlock(&sdata->cleanup_stations_lock); - - ieee80211_queue_work(&sdata->local->hw, &sdata->cleanup_stations_wk); + ieee80211_queue_work(&sta->local->hw, &sta->free_sta_wk); } /* protected by RCU */ @@ -333,6 +310,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, spin_lock_init(&sta->lock); INIT_WORK(&sta->drv_unblock_wk, sta_unblock); + INIT_WORK(&sta->free_sta_wk, free_sta_work); INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); mutex_init(&sta->ampdu_mlme.mtx); @@ -884,7 +862,7 @@ void sta_info_init(struct ieee80211_local *local) void sta_info_stop(struct ieee80211_local *local) { - del_timer_sync(&local->sta_cleanup); + del_timer(&local->sta_cleanup); sta_info_flush(local, NULL); } @@ -913,20 +891,6 @@ int sta_info_flush(struct ieee80211_local *local, } mutex_unlock(&local->sta_mtx); - rcu_barrier(); - - if (sdata) { - ieee80211_cleanup_sdata_stas(sdata); - cancel_work_sync(&sdata->cleanup_stations_wk); - } else { - mutex_lock(&local->iflist_mtx); - list_for_each_entry(sdata, &local->interfaces, list) { - ieee80211_cleanup_sdata_stas(sdata); - cancel_work_sync(&sdata->cleanup_stations_wk); - } - mutex_unlock(&local->iflist_mtx); - } - return ret; } diff --git a/trunk/net/mac80211/sta_info.h b/trunk/net/mac80211/sta_info.h index 37c1889afd3a..1489bca9ea97 100644 --- a/trunk/net/mac80211/sta_info.h +++ b/trunk/net/mac80211/sta_info.h @@ -299,6 +299,7 @@ struct sta_info { spinlock_t lock; struct work_struct drv_unblock_wk; + struct work_struct free_sta_wk; u16 listen_interval; @@ -562,6 +563,4 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta); void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta); void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta); -void ieee80211_cleanup_sdata_stas(struct ieee80211_sub_if_data *sdata); - #endif /* STA_INFO_H */ diff --git a/trunk/net/sunrpc/clnt.c b/trunk/net/sunrpc/clnt.c index 507b5e84fbdb..1915ffe598e3 100644 --- a/trunk/net/sunrpc/clnt.c +++ b/trunk/net/sunrpc/clnt.c @@ -555,7 +555,7 @@ EXPORT_SYMBOL_GPL(rpc_clone_client); * rpc_clone_client_set_auth - Clone an RPC client structure and set its auth * * @clnt: RPC client whose parameters are copied - * @flavor: security flavor for new client + * @auth: security flavor for new client * * Returns a fresh RPC client or an ERR_PTR. */ diff --git a/trunk/net/sunrpc/sched.c b/trunk/net/sunrpc/sched.c index bfa31714581f..b4133bd13915 100644 --- a/trunk/net/sunrpc/sched.c +++ b/trunk/net/sunrpc/sched.c @@ -972,7 +972,8 @@ static void rpc_async_release(struct work_struct *work) static void rpc_release_resources_task(struct rpc_task *task) { - xprt_release(task); + if (task->tk_rqstp) + xprt_release(task); if (task->tk_msg.rpc_cred) { put_rpccred(task->tk_msg.rpc_cred); task->tk_msg.rpc_cred = NULL; diff --git a/trunk/net/sunrpc/xprt.c b/trunk/net/sunrpc/xprt.c index 33811db8788a..bd462a532acf 100644 --- a/trunk/net/sunrpc/xprt.c +++ b/trunk/net/sunrpc/xprt.c @@ -1136,18 +1136,10 @@ static void xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt) void xprt_release(struct rpc_task *task) { struct rpc_xprt *xprt; - struct rpc_rqst *req = task->tk_rqstp; + struct rpc_rqst *req; - if (req == NULL) { - if (task->tk_client) { - rcu_read_lock(); - xprt = rcu_dereference(task->tk_client->cl_xprt); - if (xprt->snd_task == task) - xprt_release_write(xprt, task); - rcu_read_unlock(); - } + if (!(req = task->tk_rqstp)) return; - } xprt = req->rq_xprt; if (task->tk_ops->rpc_count_stats != NULL) diff --git a/trunk/net/wireless/core.c b/trunk/net/wireless/core.c index b677eab55b68..14d990400354 100644 --- a/trunk/net/wireless/core.c +++ b/trunk/net/wireless/core.c @@ -866,7 +866,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, /* allow mac80211 to determine the timeout */ wdev->ps_timeout = -1; - netdev_set_default_ethtool_ops(dev, &cfg80211_ethtool_ops); + if (!dev->ethtool_ops) + dev->ethtool_ops = &cfg80211_ethtool_ops; if ((wdev->iftype == NL80211_IFTYPE_STATION || wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||